lavc: pad last audio frame with silence when needed.

This commit is contained in:
Anton Khirnov
2012-05-07 13:55:03 +02:00
parent 6d7f617700
commit a5117a2444
6 changed files with 80 additions and 16 deletions

View File

@@ -857,11 +857,58 @@ int ff_alloc_packet(AVPacket *avpkt, int size)
}
}
/**
* Pad last frame with silence.
*/
static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
{
AVFrame *frame = NULL;
uint8_t *buf = NULL;
int ret;
if (!(frame = avcodec_alloc_frame()))
return AVERROR(ENOMEM);
*frame = *src;
if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels,
s->frame_size, s->sample_fmt, 0)) < 0)
goto fail;
if (!(buf = av_malloc(ret))) {
ret = AVERROR(ENOMEM);
goto fail;
}
frame->nb_samples = s->frame_size;
if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt,
buf, ret, 0)) < 0)
goto fail;
if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
src->nb_samples, s->channels, s->sample_fmt)) < 0)
goto fail;
if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples,
frame->nb_samples - src->nb_samples,
s->channels, s->sample_fmt)) < 0)
goto fail;
*dst = frame;
return 0;
fail:
if (frame->extended_data != frame->data)
av_freep(&frame->extended_data);
av_freep(&buf);
av_freep(&frame);
return ret;
}
int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
AVPacket *avpkt,
const AVFrame *frame,
int *got_packet_ptr)
{
AVFrame *padded_frame = NULL;
int ret;
int user_packet = !!avpkt->data;
@@ -879,6 +926,16 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
if (frame->nb_samples > avctx->frame_size)
return AVERROR(EINVAL);
} else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
if (frame->nb_samples < avctx->frame_size &&
!avctx->internal->last_audio_frame) {
ret = pad_last_frame(avctx, &padded_frame, frame);
if (ret < 0)
return ret;
frame = padded_frame;
avctx->internal->last_audio_frame = 1;
}
if (frame->nb_samples != avctx->frame_size)
return AVERROR(EINVAL);
}
@@ -919,6 +976,13 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
here to simplify things */
avpkt->flags |= AV_PKT_FLAG_KEY;
if (padded_frame) {
av_freep(&padded_frame->data[0]);
if (padded_frame->extended_data != padded_frame->data)
av_freep(&padded_frame->extended_data);
av_freep(&padded_frame);
}
return ret;
}