]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/utils.c
tests/api-flac-test: ensure the frame is writable before writing to it
[ffmpeg] / libavcodec / utils.c
index 45295dd3cedfdb068e32e790c20e701a0da0e3bc..b8a8c0ac2e639c08164a656f19792c0ecfde8a86 100644 (file)
@@ -50,7 +50,6 @@
 #include "thread.h"
 #include "frame_thread_encoder.h"
 #include "internal.h"
-#include "packet_internal.h"
 #include "put_bits.h"
 #include "raw.h"
 #include "bytestream.h"
@@ -513,7 +512,14 @@ static int64_t get_bit_rate(AVCodecContext *ctx)
         break;
     case AVMEDIA_TYPE_AUDIO:
         bits_per_sample = av_get_bits_per_sample(ctx->codec_id);
-        bit_rate = bits_per_sample ? ctx->sample_rate * (int64_t)ctx->channels * bits_per_sample : ctx->bit_rate;
+        if (bits_per_sample) {
+            bit_rate = ctx->sample_rate * (int64_t)ctx->channels;
+            if (bit_rate > INT64_MAX / bits_per_sample) {
+                bit_rate = 0;
+            } else
+                bit_rate *= bits_per_sample;
+        } else
+            bit_rate = ctx->bit_rate;
         break;
     default:
         bit_rate = 0;
@@ -535,18 +541,6 @@ static void ff_unlock_avcodec(const AVCodec *codec)
         ff_mutex_unlock(&codec_mutex);
 }
 
-int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
-{
-    int ret = 0;
-
-    ff_unlock_avcodec(codec);
-
-    ret = avcodec_open2(avctx, codec, options);
-
-    ff_lock_avcodec(avctx, codec);
-    return ret;
-}
-
 int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
 {
     int ret = 0;
@@ -585,18 +579,24 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
     }
     avctx->internal = avci;
 
+#if FF_API_OLD_ENCDEC
     avci->to_free = av_frame_alloc();
     avci->compat_decode_frame = av_frame_alloc();
     avci->compat_encode_packet = av_packet_alloc();
+    if (!avci->to_free || !avci->compat_decode_frame || !avci->compat_encode_packet) {
+        ret = AVERROR(ENOMEM);
+        goto free_and_end;
+    }
+#endif
     avci->buffer_frame = av_frame_alloc();
     avci->buffer_pkt = av_packet_alloc();
     avci->es.in_frame = av_frame_alloc();
     avci->ds.in_pkt = av_packet_alloc();
     avci->last_pkt_props = av_packet_alloc();
-    if (!avci->compat_decode_frame || !avci->compat_encode_packet ||
-        !avci->buffer_frame || !avci->buffer_pkt          ||
+    avci->pkt_props = av_fifo_alloc(sizeof(*avci->last_pkt_props));
+    if (!avci->buffer_frame || !avci->buffer_pkt          ||
         !avci->es.in_frame  || !avci->ds.in_pkt           ||
-        !avci->to_free      || !avci->last_pkt_props) {
+        !avci->last_pkt_props || !avci->pkt_props) {
         ret = AVERROR(ENOMEM);
         goto free_and_end;
     }
@@ -1070,12 +1070,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
     av_freep(&avctx->priv_data);
     av_freep(&avctx->subtitle_header);
 
+#if FF_API_OLD_ENCDEC
     av_frame_free(&avci->to_free);
     av_frame_free(&avci->compat_decode_frame);
-    av_frame_free(&avci->buffer_frame);
     av_packet_free(&avci->compat_encode_packet);
+#endif
+    av_frame_free(&avci->buffer_frame);
     av_packet_free(&avci->buffer_pkt);
     av_packet_free(&avci->last_pkt_props);
+    av_fifo_freep(&avci->pkt_props);
 
     av_packet_free(&avci->ds.in_pkt);
     av_frame_free(&avci->es.in_frame);
@@ -1111,13 +1114,20 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
     avci->draining_done = 0;
     avci->nb_draining_errors = 0;
     av_frame_unref(avci->buffer_frame);
+#if FF_API_OLD_ENCDEC
     av_frame_unref(avci->compat_decode_frame);
     av_packet_unref(avci->compat_encode_packet);
+#endif
     av_packet_unref(avci->buffer_pkt);
 
     av_packet_unref(avci->last_pkt_props);
-    avpriv_packet_list_free(&avci->pkt_props,
-                            &avci->pkt_props_tail);
+    while (av_fifo_size(avci->pkt_props) >= sizeof(*avci->last_pkt_props)) {
+        av_fifo_generic_read(avci->pkt_props,
+                             avci->last_pkt_props, sizeof(*avci->last_pkt_props),
+                             NULL);
+        av_packet_unref(avci->last_pkt_props);
+    }
+    av_fifo_reset(avci->pkt_props);
 
     av_frame_unref(avci->es.in_frame);
     av_packet_unref(avci->ds.in_pkt);
@@ -1133,8 +1143,12 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
     if (av_codec_is_decoder(avctx->codec))
         av_bsf_flush(avci->bsf);
 
+#if FF_API_OLD_ENCDEC
+FF_DISABLE_DEPRECATION_WARNINGS
     if (!avctx->refcounted_frames)
         av_frame_unref(avci->to_free);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 }
 
 void avsubtitle_free(AVSubtitle *sub)
@@ -1174,14 +1188,24 @@ av_cold int avcodec_close(AVCodecContext *avctx)
             avctx->codec->close(avctx);
         avctx->internal->byte_buffer_size = 0;
         av_freep(&avctx->internal->byte_buffer);
+#if FF_API_OLD_ENCDEC
         av_frame_free(&avctx->internal->to_free);
         av_frame_free(&avctx->internal->compat_decode_frame);
-        av_frame_free(&avctx->internal->buffer_frame);
         av_packet_free(&avctx->internal->compat_encode_packet);
+#endif
+        av_frame_free(&avctx->internal->buffer_frame);
         av_packet_free(&avctx->internal->buffer_pkt);
+        av_packet_unref(avctx->internal->last_pkt_props);
+        while (av_fifo_size(avctx->internal->pkt_props) >=
+               sizeof(*avctx->internal->last_pkt_props)) {
+            av_fifo_generic_read(avctx->internal->pkt_props,
+                                 avctx->internal->last_pkt_props,
+                                 sizeof(*avctx->internal->last_pkt_props),
+                                 NULL);
+            av_packet_unref(avctx->internal->last_pkt_props);
+        }
         av_packet_free(&avctx->internal->last_pkt_props);
-        avpriv_packet_list_free(&avctx->internal->pkt_props,
-                                &avctx->internal->pkt_props_tail);
+        av_fifo_freep(&avctx->internal->pkt_props);
 
         av_packet_free(&avctx->internal->ds.in_pkt);
         av_frame_free(&avctx->internal->es.in_frame);
@@ -1537,6 +1561,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
     case AV_CODEC_ID_PCM_VIDC:
     case AV_CODEC_ID_PCM_S8:
     case AV_CODEC_ID_PCM_S8_PLANAR:
+    case AV_CODEC_ID_PCM_SGA:
     case AV_CODEC_ID_PCM_U8:
     case AV_CODEC_ID_SDX2_DPCM:
     case AV_CODEC_ID_DERF_DPCM:
@@ -1658,14 +1683,10 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
             return 256 * sr / 245;
         else if (id == AV_CODEC_ID_DST)
             return 588 * sr / 44100;
-
-        if (ch > 0) {
-            /* calc from sample rate and channels */
-            if (id == AV_CODEC_ID_BINKAUDIO_DCT) {
-                if (sr / 22050 > 22)
-                    return 0;
-                return (480 << (sr / 22050)) / ch;
-            }
+        else if (id == AV_CODEC_ID_BINKAUDIO_DCT) {
+            if (sr / 22050 > 22)
+                return 0;
+            return (480 << (sr / 22050));
         }
 
         if (id == AV_CODEC_ID_MP3)
@@ -1715,7 +1736,10 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
                 return frame_bytes / (9 * ch) * 16;
             case AV_CODEC_ID_ADPCM_PSX:
             case AV_CODEC_ID_ADPCM_DTK:
-                return frame_bytes / (16 * ch) * 28;
+                frame_bytes /= 16 * ch;
+                if (frame_bytes > INT_MAX / 28)
+                    return 0;
+                return frame_bytes * 28;
             case AV_CODEC_ID_ADPCM_4XM:
             case AV_CODEC_ID_ADPCM_IMA_DAT4:
             case AV_CODEC_ID_ADPCM_IMA_ISS: