| @@ -2048,14 +2048,6 @@ static void flush_encoders(void) | |||
| av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); | |||
| /* pad last frame with silence if needed */ | |||
| if (!(enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME)) { | |||
| frame_bytes = enc->frame_size * enc->channels * | |||
| av_get_bytes_per_sample(enc->sample_fmt); | |||
| if (allocated_audio_buf_size < frame_bytes) | |||
| exit_program(1); | |||
| generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); | |||
| } | |||
| encode_audio_frame(os, ost, audio_buf, frame_bytes); | |||
| } else { | |||
| /* flush encoder with NULL frames until it is done | |||
| @@ -13,6 +13,12 @@ libavutil: 2011-04-18 | |||
| API changes, most recent first: | |||
| 2012-xx-xx - xxxxxxx - lavc 54.13.1 | |||
| For audio formats with fixed frame size, the last frame | |||
| no longer needs to be padded with silence, libavcodec | |||
| will handle this internally (effectively all encoders | |||
| behave as if they had CODEC_CAP_SMALL_LAST_FRAME set). | |||
| 2012-xx-xx - xxxxxxx - lavc 54.13.0 - avcodec.h | |||
| Add sample_rate and channel_layout fields to AVFrame. | |||
| @@ -3860,15 +3860,11 @@ int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx, | |||
| * @param[in] frame AVFrame containing the raw audio data to be encoded. | |||
| * May be NULL when flushing an encoder that has the | |||
| * CODEC_CAP_DELAY capability set. | |||
| * There are 2 codec capabilities that affect the allowed | |||
| * values of frame->nb_samples. | |||
| * If CODEC_CAP_SMALL_LAST_FRAME is set, then only the final | |||
| * frame may be smaller than avctx->frame_size, and all other | |||
| * frames must be equal to avctx->frame_size. | |||
| * If CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame | |||
| * can have any number of samples. | |||
| * If neither is set, frame->nb_samples must be equal to | |||
| * avctx->frame_size for all frames. | |||
| * If it is not set, frame->nb_samples must be equal to | |||
| * avctx->frame_size for all frames except the last. | |||
| * The final frame may be smaller than avctx->frame_size. | |||
| * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the | |||
| * output packet is non-empty, and to 0 if it is | |||
| * empty. If the function returns an error, the | |||
| @@ -70,6 +70,12 @@ typedef struct AVCodecInternal { | |||
| */ | |||
| int sample_count; | |||
| #endif | |||
| /** | |||
| * An audio frame with less than required samples has been submitted and | |||
| * padded with silence. Reject all subsequent frames. | |||
| */ | |||
| int last_audio_frame; | |||
| } AVCodecInternal; | |||
| struct AVCodecDefault { | |||
| @@ -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; | |||
| } | |||
| @@ -28,7 +28,7 @@ | |||
| #define LIBAVCODEC_VERSION_MAJOR 54 | |||
| #define LIBAVCODEC_VERSION_MINOR 13 | |||
| #define LIBAVCODEC_VERSION_MICRO 0 | |||
| #define LIBAVCODEC_VERSION_MICRO 1 | |||
| #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | |||
| LIBAVCODEC_VERSION_MINOR, \ | |||