Patches attached.

- Andreas
From 312fa0762798ea2207a29fde378f451e693b5981 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinha...@outlook.com>
Date: Wed, 9 Apr 2025 14:23:32 +0200
Subject: [PATCH 1/2] avcodec/h261dec: Export key frame information

Implements ticket #8343.

Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com>
---
 libavcodec/h261dec.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 1f57c9f8fe..840414cafc 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -25,7 +25,6 @@
  * H.261 decoder.
  */
 
-#include "libavutil/avassert.h"
 #include "libavutil/thread.h"
 #include "avcodec.h"
 #include "codec_internal.h"
@@ -458,7 +457,7 @@ intra:
  * Decode the H.261 picture header.
  * @return <0 if no startcode found
  */
-static int h261_decode_picture_header(H261DecContext *h)
+static int h261_decode_picture_header(H261DecContext *h, int *is_key)
 {
     MpegEncContext *const s = &h->s;
     int format, i;
@@ -482,7 +481,7 @@ static int h261_decode_picture_header(H261DecContext *h)
     /* PTYPE starts here */
     skip_bits1(&s->gb); /* split screen off */
     skip_bits1(&s->gb); /* camera  off */
-    skip_bits1(&s->gb); /* freeze picture release off */
+    *is_key = get_bits1(&s->gb); /* freeze picture release off */
 
     format = get_bits1(&s->gb);
 
@@ -545,7 +544,7 @@ static int h261_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     MpegEncContext *s  = &h->s;
-    int ret;
+    int ret, is_key;
 
     ff_dlog(avctx, "*****frame %"PRId64" size=%d\n", avctx->frame_num, buf_size);
     ff_dlog(avctx, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
@@ -554,7 +553,7 @@ static int h261_decode_frame(AVCodecContext *avctx, AVFrame *pict,
 
     init_get_bits(&s->gb, buf, buf_size * 8);
 
-    ret = h261_decode_picture_header(h);
+    ret = h261_decode_picture_header(h, &is_key);
 
     /* skip if the header was thrashed */
     if (ret < 0) {
@@ -575,7 +574,7 @@ static int h261_decode_frame(AVCodecContext *avctx, AVFrame *pict,
             return ret;
     }
 
-    if ((avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) ||
+    if ((avctx->skip_frame >= AVDISCARD_NONINTRA && !is_key) ||
          avctx->skip_frame >= AVDISCARD_ALL)
         return buf_size;
 
@@ -595,7 +594,10 @@ static int h261_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     }
     ff_mpv_frame_end(s);
 
-    av_assert0(s->pict_type == s->cur_pic.ptr->f->pict_type);
+    if (is_key) {
+        s->cur_pic.ptr->f->pict_type = AV_PICTURE_TYPE_I;
+        s->cur_pic.ptr->f->flags    |= AV_FRAME_FLAG_KEY;
+    }
 
     if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
         return ret;
-- 
2.45.2

From d341d45fc7ebdd8cfc46d40ab1f0af4faa4e563b Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinha...@outlook.com>
Date: Wed, 9 Apr 2025 14:39:37 +0200
Subject: [PATCH 2/2] avcodec/h261dec: Set pict_type during init

Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com>
---
 libavcodec/h261dec.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 840414cafc..146f979a5e 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -88,6 +88,12 @@ static av_cold int h261_decode_init(AVCodecContext *avctx)
 
     avctx->framerate = (AVRational) { 30000, 1001 };
 
+    /* The H.261 analog of intra/key frames is setting the freeze picture release flag,
+     * but this does not guarantee that the frame uses intra-only encoding,
+     * so we still need to allocate dummy frames. So set pict_type to P here
+     * for all frames and override it after having decoded the frame. */
+    s->pict_type = AV_PICTURE_TYPE_P;
+
     s->private_ctx = &h->common;
     // set defaults
     ret = ff_mpv_decode_init(s, avctx);
@@ -501,11 +507,6 @@ static int h261_decode_picture_header(H261DecContext *h, int *is_key)
     if (skip_1stop_8data_bits(&s->gb) < 0)
         return AVERROR_INVALIDDATA;
 
-    /* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first
-     * frame, the codec crashes if it does not contain all I-blocks
-     * (e.g. when a packet is lost). */
-    s->pict_type = AV_PICTURE_TYPE_P;
-
     h->gob_number = 0;
     return 0;
 }
-- 
2.45.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to