]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/encode.c
avcodec/alsdec: Discard frames for which no channel could be decoded
[ffmpeg] / libavcodec / encode.c
index d9761515aa84e2ccdf5040fdabd6fb9af310bc4f..9ed2cf0f5908b72772094d6aa21046edc3418d31 100644 (file)
@@ -135,7 +135,6 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
 
     if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) {
         av_packet_unref(avpkt);
-        av_init_packet(avpkt);
         return 0;
     }
 
@@ -175,8 +174,14 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
                 goto end;
             }
         } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
-            if (frame->nb_samples < avctx->frame_size &&
-                !avctx->internal->last_audio_frame) {
+            /* if we already got an undersized frame, that must have been the last */
+            if (avctx->internal->last_audio_frame) {
+                av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame (avcodec_encode_audio2)\n", avctx->frame_size);
+                ret = AVERROR(EINVAL);
+                goto end;
+            }
+
+            if (frame->nb_samples < avctx->frame_size) {
                 ret = pad_last_frame(avctx, &padded_frame, frame);
                 if (ret < 0)
                     goto end;
@@ -235,13 +240,12 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
             if (ret >= 0)
                 avpkt->data = avpkt->buf->data;
         }
-
-        avctx->frame_number++;
+        if (frame)
+            avctx->frame_number++;
     }
 
     if (ret < 0 || !*got_packet_ptr) {
         av_packet_unref(avpkt);
-        av_init_packet(avpkt);
         goto end;
     }
 
@@ -282,8 +286,6 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
 
     if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) {
         av_packet_unref(avpkt);
-        av_init_packet(avpkt);
-        avpkt->size = 0;
         return 0;
     }
 
@@ -333,7 +335,8 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
                 avpkt->data = avpkt->buf->data;
         }
 
-        avctx->frame_number++;
+        if (frame)
+            avctx->frame_number++;
     }
 
     if (ret < 0 || !*got_packet_ptr)
@@ -425,9 +428,15 @@ int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *
         return AVERROR(EINVAL);
 
     if (avctx->codec->receive_packet) {
+        int ret;
         if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))
             return AVERROR_EOF;
-        return avctx->codec->receive_packet(avctx, avpkt);
+        ret = avctx->codec->receive_packet(avctx, avpkt);
+        if (!ret)
+            // Encoders must always return ref-counted buffers.
+            // Side-data only packets have no data and can be not ref-counted.
+            av_assert0(!avpkt->data || avpkt->buf);
+        return ret;
     }
 
     // Emulation via old API.