| @@ -2048,14 +2048,6 @@ static void flush_encoders(void) | |||||
| av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); | 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); | encode_audio_frame(os, ost, audio_buf, frame_bytes); | ||||
| } else { | } else { | ||||
| /* flush encoder with NULL frames until it is done | /* flush encoder with NULL frames until it is done | ||||
| @@ -13,6 +13,12 @@ libavutil: 2011-04-18 | |||||
| API changes, most recent first: | 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 | 2012-xx-xx - xxxxxxx - lavc 54.13.0 - avcodec.h | ||||
| Add sample_rate and channel_layout fields to AVFrame. | 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. | * @param[in] frame AVFrame containing the raw audio data to be encoded. | ||||
| * May be NULL when flushing an encoder that has the | * May be NULL when flushing an encoder that has the | ||||
| * CODEC_CAP_DELAY capability set. | * 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 | * If CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame | ||||
| * can have any number of samples. | * 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 | * @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 | * output packet is non-empty, and to 0 if it is | ||||
| * empty. If the function returns an error, the | * empty. If the function returns an error, the | ||||
| @@ -70,6 +70,12 @@ typedef struct AVCodecInternal { | |||||
| */ | */ | ||||
| int sample_count; | int sample_count; | ||||
| #endif | #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; | } AVCodecInternal; | ||||
| struct AVCodecDefault { | 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, | int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, | ||||
| AVPacket *avpkt, | AVPacket *avpkt, | ||||
| const AVFrame *frame, | const AVFrame *frame, | ||||
| int *got_packet_ptr) | int *got_packet_ptr) | ||||
| { | { | ||||
| AVFrame *padded_frame = NULL; | |||||
| int ret; | int ret; | ||||
| int user_packet = !!avpkt->data; | 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) | if (frame->nb_samples > avctx->frame_size) | ||||
| return AVERROR(EINVAL); | return AVERROR(EINVAL); | ||||
| } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) { | } 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) | if (frame->nb_samples != avctx->frame_size) | ||||
| return AVERROR(EINVAL); | return AVERROR(EINVAL); | ||||
| } | } | ||||
| @@ -919,6 +976,13 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, | |||||
| here to simplify things */ | here to simplify things */ | ||||
| avpkt->flags |= AV_PKT_FLAG_KEY; | 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; | return ret; | ||||
| } | } | ||||
| @@ -28,7 +28,7 @@ | |||||
| #define LIBAVCODEC_VERSION_MAJOR 54 | #define LIBAVCODEC_VERSION_MAJOR 54 | ||||
| #define LIBAVCODEC_VERSION_MINOR 13 | #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, \ | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | ||||
| LIBAVCODEC_VERSION_MINOR, \ | LIBAVCODEC_VERSION_MINOR, \ | ||||