[FFmpeg-devel] [PATCH 02/10] lavc: deprecate AV_CODEC_(FLAG|CAP)_TRUNCATED

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Mon Sep 13 16:53:28 EEST 2021


From: Anton Khirnov <anton at khirnov.net>

It is supported only by a few decoders (h263, h263p, mpeg(1|2|)video
and mpeg4) and is entirely redundant with parsers. Furthermore, using
it leads to missing frames, as flushing the decoder at the end does not
work properly.

Co-authored-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
Anton's earlier patch is here:
https://ffmpeg.org/pipermail/ffmpeg-devel/2021-March/277365.html

 doc/APIchanges             |  4 ++++
 libavcodec/avcodec.h       |  4 ++++
 libavcodec/codec.h         |  5 +++++
 libavcodec/decode.c        |  4 ++++
 libavcodec/h263dec.c       | 18 ++++++++++++++++--
 libavcodec/mpeg12dec.c     | 28 +++++++++++++++++++++++-----
 libavcodec/mpeg4videodec.c |  6 ++++--
 libavcodec/mpegvideo.c     |  6 ++++++
 libavcodec/mpegvideo.h     |  2 ++
 libavcodec/options_table.h |  4 +++-
 libavcodec/pthread.c       |  2 ++
 libavcodec/version.h       |  3 +++
 12 files changed, 76 insertions(+), 10 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index d03e3233ba..cffab2059f 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@ libavutil:     2021-04-27
 
 API changes, most recent first:
 
+2021-09-xx - xxxxxxxxxx - lavc 59.x.100 - avcodec.h codec.h
+  Deprecate AV_CODEC_FLAG_TRUNCATED and AV_CODEC_CAP_TRUNCATED,
+  as they are redundant with parsers.
+
 2021-09-08 - xxxxxxxxxx - lavu 57.5.100 - hwcontext_d3d11va.h
   Add AVD3D11VAFramesContext.texture_infos
 
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index ffd58c333f..1b70a08980 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -245,11 +245,15 @@ typedef struct RcOverride{
  * error[?] variables will be set during encoding.
  */
 #define AV_CODEC_FLAG_PSNR            (1 << 15)
+#if FF_API_FLAG_TRUNCATED
 /**
  * Input bitstream might be truncated at a random location
  * instead of only at frame boundaries.
+ *
+ * @deprecated use codec parsers for packetizing input
  */
 #define AV_CODEC_FLAG_TRUNCATED       (1 << 16)
+#endif
 /**
  * Use interlaced DCT.
  */
diff --git a/libavcodec/codec.h b/libavcodec/codec.h
index 8f12705066..a8147ec21f 100644
--- a/libavcodec/codec.h
+++ b/libavcodec/codec.h
@@ -50,7 +50,12 @@
  * avcodec_default_get_buffer2 or avcodec_default_get_encode_buffer.
  */
 #define AV_CODEC_CAP_DR1                 (1 <<  1)
+#if FF_API_FLAG_TRUNCATED
+/**
+ * @deprecated Use parsers to always send proper frames.
+ */
 #define AV_CODEC_CAP_TRUNCATED           (1 <<  3)
+#endif
 /**
  * Encoder or decoder requires flushing with NULL input at the end in order to
  * give the complete and correct output.
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 643f9d6a30..023dd3c0b2 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -455,7 +455,11 @@ static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame,
     if (!got_frame)
         av_frame_unref(frame);
 
+#if FF_API_FLAG_TRUNCATED
     if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED))
+#else
+    if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO)
+#endif
         ret = pkt->size;
 
 #if FF_API_AVCTX_TIMEBASE
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index d7ae8a0727..2682a7f43a 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -33,12 +33,16 @@
 #include "error_resilience.h"
 #include "flv.h"
 #include "h263.h"
+#if FF_API_FLAG_TRUNCATED
 #include "h263_parser.h"
+#endif
 #include "hwconfig.h"
 #include "internal.h"
 #include "mpeg_er.h"
 #include "mpeg4video.h"
+#if FF_API_FLAG_TRUNCATED
 #include "mpeg4video_parser.h"
+#endif
 #include "mpegutils.h"
 #include "mpegvideo.h"
 #include "msmpeg4.h"
@@ -170,12 +174,14 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size)
         /* We would have to scan through the whole buf to handle the weird
          * reordering ... */
         return buf_size;
+#if FF_API_FLAG_TRUNCATED
     } else if (s->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
         pos -= s->parse_context.last_index;
         // padding is not really read so this might be -1
         if (pos < 0)
             pos = 0;
         return pos;
+#endif
     } else {
         // avoid infinite loops (maybe not needed...)
         if (pos == 0)
@@ -441,6 +447,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return 0;
     }
 
+#if FF_API_FLAG_TRUNCATED
     if (s->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
         int next;
 
@@ -460,6 +467,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              &buf_size) < 0)
             return buf_size;
     }
+#endif
 
 retry:
     if (s->divx_packed && s->bitstream_buffer_size) {
@@ -768,7 +776,10 @@ const AVCodec ff_h263_decoder = {
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-                      AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
+#if FF_API_FLAG_TRUNCATED
+                      AV_CODEC_CAP_TRUNCATED |
+#endif
+                      AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
@@ -786,7 +797,10 @@ const AVCodec ff_h263p_decoder = {
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-                      AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
+#if FF_API_FLAG_TRUNCATED
+                      AV_CODEC_CAP_TRUNCATED |
+#endif
+                      AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush          = ff_mpeg_flush,
     .max_lowres     = 3,
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 49d865853b..01a7a3fc19 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -1265,10 +1265,14 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
         (s1->save_progressive_seq != s->progressive_sequence && FFALIGN(s->height, 16) != FFALIGN(s->height, 32)) ||
         0) {
         if (s1->mpeg_enc_ctx_allocated) {
+#if FF_API_FLAG_TRUNCATED
             ParseContext pc = s->parse_context;
             s->parse_context.buffer = 0;
             ff_mpv_common_end(s);
             s->parse_context = pc;
+#else
+            ff_mpv_common_end(s);
+#endif
             s1->mpeg_enc_ctx_allocated = 0;
         }
 
@@ -2504,7 +2508,11 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
             if (avctx->err_recognition & AV_EF_EXPLODE && s2->er.error_count)
                 return AVERROR_INVALIDDATA;
 
+#if FF_API_FLAG_TRUNCATED
             return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
+#else
+            return FFMAX(0, buf_ptr - buf);
+#endif
         }
 
         input_size = buf_end - buf_ptr;
@@ -2812,6 +2820,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data,
         return buf_size;
     }
 
+#if FF_API_FLAG_TRUNCATED
     if (s2->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
         int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf,
                                            buf_size, NULL);
@@ -2820,6 +2829,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data,
                              (const uint8_t **) &buf, &buf_size) < 0)
             return buf_size;
     }
+#endif
 
     s2->codec_tag = avpriv_toupper4(avctx->codec_tag);
     if (s->mpeg_enc_ctx_allocated == 0 && (   s2->codec_tag == AV_RL32("VCR2")
@@ -2896,8 +2906,10 @@ const AVCodec ff_mpeg1video_decoder = {
     .close                 = mpeg_decode_end,
     .decode                = mpeg_decode_frame,
     .capabilities          = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-                             AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
-                             AV_CODEC_CAP_SLICE_THREADS,
+#if FF_API_FLAG_TRUNCATED
+                             AV_CODEC_CAP_TRUNCATED |
+#endif
+                             AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE |
                              FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush                 = flush,
@@ -2930,8 +2942,10 @@ const AVCodec ff_mpeg2video_decoder = {
     .close          = mpeg_decode_end,
     .decode         = mpeg_decode_frame,
     .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-                      AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
-                      AV_CODEC_CAP_SLICE_THREADS,
+#if FF_API_FLAG_TRUNCATED
+                      AV_CODEC_CAP_TRUNCATED |
+#endif
+                      AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush          = flush,
@@ -2976,7 +2990,11 @@ const AVCodec ff_mpegvideo_decoder = {
     .init           = mpeg_decode_init,
     .close          = mpeg_decode_end,
     .decode         = mpeg_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
+    .capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
+#if FF_API_FLAG_TRUNCATED
+                      AV_CODEC_CAP_TRUNCATED |
+#endif
+                      AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                       FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
     .flush          = flush,
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index fcab975a9c..34b050db28 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3590,8 +3590,10 @@ const AVCodec ff_mpeg4_decoder = {
     .close                 = ff_h263_decode_end,
     .decode                = ff_h263_decode_frame,
     .capabilities          = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
-                             AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
-                             AV_CODEC_CAP_FRAME_THREADS,
+#if FF_API_FLAG_TRUNCATED
+                             AV_CODEC_CAP_TRUNCATED |
+#endif
+                             AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal         = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
                              FF_CODEC_CAP_ALLOCATE_PROGRESS,
     .flush                 = ff_mpeg_flush,
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 5de0719f83..5383f9dead 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -974,7 +974,9 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
     if ((ret = init_context_frame(s)))
         goto fail;
 
+#if FF_API_FLAG_TRUNCATED
     s->parse_context.state = -1;
+#endif
 
     s->context_initialized = 1;
     memset(s->thread_context, 0, sizeof(s->thread_context));
@@ -1119,8 +1121,10 @@ void ff_mpv_common_end(MpegEncContext *s)
     if (s->slice_context_count > 1)
         s->slice_context_count = 1;
 
+#if FF_API_FLAG_TRUNCATED
     av_freep(&s->parse_context.buffer);
     s->parse_context.buffer_size = 0;
+#endif
 
     av_freep(&s->bitstream_buffer);
     s->allocated_bitstream_buffer_size = 0;
@@ -2315,12 +2319,14 @@ void ff_mpeg_flush(AVCodecContext *avctx){
     s->mb_x= s->mb_y= 0;
     s->closed_gop= 0;
 
+#if FF_API_FLAG_TRUNCATED
     s->parse_context.state= -1;
     s->parse_context.frame_start_found= 0;
     s->parse_context.overread= 0;
     s->parse_context.overread_index= 0;
     s->parse_context.index= 0;
     s->parse_context.last_index= 0;
+#endif
     s->bitstream_buffer_size=0;
     s->pp_time=0;
 }
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 9f8d80df3d..8dfa904577 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -347,7 +347,9 @@ typedef struct MpegEncContext {
     int mb_num_left;                 ///< number of MBs left in this video packet (for partitioned Slices only)
     int next_p_frame_damaged;        ///< set if the next p frame is damaged, to avoid showing trashed B-frames
 
+#if FF_API_FLAG_TRUNCATED
     ParseContext parse_context;
+#endif
 
     /* H.263 specific */
     int gob_index;
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index ae42b65b7b..e740112d6a 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -59,7 +59,9 @@ static const AVOption avcodec_options[] = {
 {"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
 {"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
 {"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
-{"truncated", "Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D, "flags"},
+#if FF_API_FLAG_TRUNCATED
+{"truncated", "(Deprecated, use parsers instead.) Input bitstream might be randomly truncated", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_TRUNCATED }, INT_MIN, INT_MAX, V|D | AV_OPT_FLAG_DEPRECATED, "flags"},
+#endif
 {"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
 {"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
 {"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index e7bad19f8b..5adc3c43a3 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -48,7 +48,9 @@
 static void validate_thread_parameters(AVCodecContext *avctx)
 {
     int frame_threading_supported = (avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)
+#if FF_API_FLAG_TRUNCATED
                                 && !(avctx->flags  & AV_CODEC_FLAG_TRUNCATED)
+#endif
                                 && !(avctx->flags  & AV_CODEC_FLAG_LOW_DELAY)
                                 && !(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS);
     if (avctx->thread_count == 1) {
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 4b4fe543ab..bb70d4d152 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -81,5 +81,8 @@
 #ifndef FF_API_MPEGVIDEO_OPTS
 #define FF_API_MPEGVIDEO_OPTS      (LIBAVCODEC_VERSION_MAJOR < 60)
 #endif
+#ifndef FF_API_FLAG_TRUNCATED
+#define FF_API_FLAG_TRUNCATED      (LIBAVCODEC_VERSION_MAJOR < 60)
+#endif
 
 #endif /* AVCODEC_VERSION_H */
-- 
2.30.2



More information about the ffmpeg-devel mailing list