This is an automated email from the git hooks/post-receive script.
Git pushed a commit to branch master
in repository ffmpeg.
The following commit(s) were added to refs/heads/master by this push:
new 883e8a6336 avcodec/libopenh264dec: implement flush callback
883e8a6336 is described below
commit 883e8a6336b2651f7be79a6a9aa5f3cc22937948
Author: Scott Kidder <[email protected]>
AuthorDate: Wed May 20 17:17:24 2026 -0700
Commit: Timo Rothenpieler <[email protected]>
CommitDate: Mon Aug 3 11:08:57 2026 +0000
avcodec/libopenh264dec: implement flush callback
Cisco's ISVCDecoder retains DPB and reference state across
avcodec_flush_buffers(), causing the next IDR to be accepted but
subsequent P-frames to fail decode after a seek or loop. Cisco's
API does not expose a non-destructive reset; tear down and rebuild
the decoder via the existing close/init callbacks.
The .flush callback is void and cannot report a re-init failure, so
svc_decode_frame() guards against a NULL decoder left behind by a
failed re-init. svc_decode_init() now also tears the decoder back
down on an Initialize() failure so that path leaves the same clean
NULL state the guard expects and does not leak the ISVCDecoder.
Signed-off-by: Scott Kidder <[email protected]>
---
libavcodec/libopenh264dec.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c
index b6a9bba2dc..c9b2459653 100644
--- a/libavcodec/libopenh264dec.c
+++ b/libavcodec/libopenh264dec.c
@@ -42,12 +42,22 @@ static av_cold int svc_decode_close(AVCodecContext *avctx)
{
SVCContext *s = avctx->priv_data;
- if (s->decoder)
+ if (s->decoder) {
WelsDestroyDecoder(s->decoder);
+ s->decoder = NULL;
+ }
return 0;
}
+static av_cold int svc_decode_init(AVCodecContext *avctx);
+
+static void svc_decode_flush(AVCodecContext *avctx)
+{
+ svc_decode_close(avctx);
+ svc_decode_init(avctx);
+}
+
static av_cold int svc_decode_init(AVCodecContext *avctx)
{
SVCContext *s = avctx->priv_data;
@@ -75,6 +85,7 @@ static av_cold int svc_decode_init(AVCodecContext *avctx)
if ((*s->decoder)->Initialize(s->decoder, ¶m) != cmResultSuccess) {
av_log(avctx, AV_LOG_ERROR, "Initialize failed\n");
+ svc_decode_close(avctx);
return AVERROR_UNKNOWN;
}
@@ -95,6 +106,15 @@ static int svc_decode_frame(AVCodecContext *avctx, AVFrame
*avframe,
int opt;
#endif
+ /* svc_decode_flush() tears the decoder down and re-initializes it. If that
+ * re-init failed (e.g. WelsCreateDecoder/Initialize OOM) s->decoder is
left
+ * NULL; the void flush callback cannot report this, so guard here to turn
a
+ * NULL dereference into a recoverable error. */
+ if (!s->decoder) {
+ av_log(avctx, AV_LOG_ERROR, "decoder not initialized\n");
+ return AVERROR(EINVAL);
+ }
+
if (!avpkt->data) {
#if OPENH264_VER_AT_LEAST(1, 9)
int end_of_stream = 1;
@@ -162,6 +182,7 @@ const FFCodec ff_libopenh264_decoder = {
.init = svc_decode_init,
FF_CODEC_DECODE_CB(svc_decode_frame),
.close = svc_decode_close,
+ .flush = svc_decode_flush,
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_SETS_PKT_DTS |
FF_CODEC_CAP_INIT_CLEANUP,
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]