+ }
+
+ /* check for valid frame size */
+ if (frame) {
+ nb_samples = frame->nb_samples;
+ if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
+ if (nb_samples > avctx->frame_size)
+ return AVERROR(EINVAL);
+ } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
+ if (nb_samples != avctx->frame_size)
+ return AVERROR(EINVAL);
+ }
+ } else {
+ nb_samples = avctx->frame_size;
+ }
+
+ if (avctx->codec->encode2) {
+ *got_packet_ptr = 0;
+ ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
+ if (!ret && *got_packet_ptr &&
+ !(avctx->codec->capabilities & CODEC_CAP_DELAY)) {
+ avpkt->pts = frame->pts;
+ avpkt->duration = av_rescale_q(frame->nb_samples,
+ (AVRational){ 1, avctx->sample_rate },
+ avctx->time_base);
+ }
+ } else {
+ /* for compatibility with encoders not supporting encode2(), we need to
+ allocate a packet buffer if the user has not provided one or check
+ the size otherwise */
+ int fs_tmp = 0;
+ int buf_size = avpkt->size;
+ if (!user_packet) {
+ if (avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) {
+ av_assert0(av_get_bits_per_sample(avctx->codec_id) != 0);
+ if (!frame)
+ return AVERROR(EINVAL);
+ buf_size = nb_samples * avctx->channels *
+ av_get_bits_per_sample(avctx->codec_id) / 8;
+ } else {
+ /* this is a guess as to the required size.
+ if an encoder needs more than this, it should probably
+ implement encode2() */
+ buf_size = 2 * avctx->frame_size * avctx->channels *
+ av_get_bytes_per_sample(avctx->sample_fmt);
+ buf_size += FF_MIN_BUFFER_SIZE;
+ }
+ }
+ if ((ret = ff_alloc_packet(avpkt, buf_size)))
+ return ret;
+
+ /* Encoders using AVCodec.encode() that support
+ CODEC_CAP_SMALL_LAST_FRAME require avctx->frame_size to be set to
+ the smaller size when encoding the last frame.
+ This code can be removed once all encoders supporting
+ CODEC_CAP_SMALL_LAST_FRAME use encode2() */
+ if ((avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) &&
+ nb_samples < avctx->frame_size) {
+ fs_tmp = avctx->frame_size;
+ avctx->frame_size = nb_samples;
+ }
+
+ /* encode the frame */
+ ret = avctx->codec->encode(avctx, avpkt->data, avpkt->size,
+ frame ? frame->data[0] : NULL);
+ if (ret >= 0) {
+ if (!ret) {
+ /* no output. if the packet data was allocated by libavcodec,
+ free it */
+ if (!user_packet)
+ av_freep(&avpkt->data);
+ } else {
+ if (avctx->coded_frame)
+ avpkt->pts = avctx->coded_frame->pts;
+ /* Set duration for final small packet. This can be removed
+ once all encoders supporting CODEC_CAP_SMALL_LAST_FRAME use
+ encode2() */
+ if (fs_tmp) {
+ avpkt->duration = av_rescale_q(avctx->frame_size,
+ (AVRational){ 1, avctx->sample_rate },
+ avctx->time_base);
+ }
+ }
+ avpkt->size = ret;
+ *got_packet_ptr = (ret > 0);
+ ret = 0;
+ }
+
+ if (fs_tmp)
+ avctx->frame_size = fs_tmp;
+ }
+ if (!ret)
+ avctx->frame_number++;
+
+ /* NOTE: if we add any audio encoders which output non-keyframe packets,
+ this needs to be moved to the encoders, but for now we can do it
+ here to simplify things */
+ avpkt->flags |= AV_PKT_FLAG_KEY;
+
+ return ret;