diff mbox series

[FFmpeg-devel,2/3] avcodec/decode: add an internal codec flag to signal a decoder sets all output frame properties

Message ID 20210618220213.52768-2-jamrial@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,1/3] avcodec/decode: fetch packets from the pkt_props FIFO on every frame returned
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

James Almer June 18, 2021, 10:02 p.m. UTC
Decoders like cuviddec ignore and overwrite all the properties set by the generic
code as derived from AVCodecInternal.last_pkt_props. This flag ensures libavcodec
will not store and potentially queue input packets that ultimately will not be used.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/decode.c   | 21 ++++++++++++++-------
 libavcodec/internal.h |  5 +++++
 2 files changed, 19 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 44f0b11546..68acf0cf8f 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -233,9 +233,11 @@  int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
     if (ret < 0)
         return ret;
 
-    ret = extract_packet_props(avctx->internal, pkt);
-    if (ret < 0)
-        goto finish;
+    if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
+        ret = extract_packet_props(avctx->internal, pkt);
+        if (ret < 0)
+            goto finish;
+    }
 
     ret = apply_param_change(avctx, pkt);
     if (ret < 0)
@@ -487,11 +489,13 @@  static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame,
 
         pkt->data                += consumed;
         pkt->size                -= consumed;
-        avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment.
         pkt->pts                  = AV_NOPTS_VALUE;
         pkt->dts                  = AV_NOPTS_VALUE;
-        avci->last_pkt_props->pts = AV_NOPTS_VALUE;
-        avci->last_pkt_props->dts = AV_NOPTS_VALUE;
+        if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
+            avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment.
+            avci->last_pkt_props->pts = AV_NOPTS_VALUE;
+            avci->last_pkt_props->dts = AV_NOPTS_VALUE;
+        }
     }
 
     if (got_frame)
@@ -533,7 +537,8 @@  static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
     if (ret == AVERROR_EOF)
         avci->draining_done = 1;
 
-    if (IS_EMPTY(avci->last_pkt_props) && av_fifo_size(avci->pkt_props) >= sizeof(*avci->last_pkt_props))
+    if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS) &&
+        IS_EMPTY(avci->last_pkt_props) && 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);
 
@@ -1494,6 +1499,7 @@  int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
         { AV_PKT_DATA_S12M_TIMECODE,              AV_FRAME_DATA_S12M_TIMECODE },
     };
 
+    if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
     frame->pts = pkt->pts;
     frame->pkt_pos      = pkt->pos;
     frame->pkt_duration = pkt->duration;
@@ -1519,6 +1525,7 @@  int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
     } else {
         frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
     }
+    }
     frame->reordered_opaque = avctx->reordered_opaque;
 
     if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED)
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 975ec0ba30..586819cd1b 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -78,6 +78,11 @@ 
  * Codec handles avctx->thread_count == 0 (auto) internally.
  */
 #define FF_CODEC_CAP_AUTO_THREADS           (1 << 7)
+/**
+ * Codec handles output frame properties internally instead of letting the
+ * internal logic derive them from AVCodecInternal.last_pkt_props.
+ */
+#define FF_CODEC_CAP_SETS_FRAME_PROPS       (1 << 8)
 
 /**
  * AVCodec.codec_tags termination value