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
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.
* @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
*/
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 {
}
}
+/**
+ * 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;
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);
}
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;
}
#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, \