From: James Almer via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: James Almer <code@ffmpeg.org>
Subject: [FFmpeg-devel] [PATCH] avformat/demux: pass new extradata to the parser (PR #20745)
Date: Fri, 24 Oct 2025 17:18:22 -0000
Message-ID: <176132630270.25.14665566471023796367@7d278768979e> (raw)
PR #20745 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20745
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20745.patch
Fixes parsing errors in files like the sample provided here, which while technically harmless for decoding scenarios, should still not happen.
>From 18ca5461f58d92ffa6c32032b6fefab92fe93db1 Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Fri, 24 Oct 2025 13:34:43 -0300
Subject: [PATCH 1/5] avcodec/parser: add a flush mechanism
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/avcodec.h | 3 +++
libavcodec/parser.c | 35 +++++++++++++++++++++++++++++++++++
libavcodec/parser.h | 1 +
3 files changed, 39 insertions(+)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 83a4e56e22..1d08523728 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2743,6 +2743,7 @@ typedef struct AVCodecParser {
const uint8_t *buf, int buf_size);
void (*parser_close)(AVCodecParserContext *s);
int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
+ void (*parser_flush)(AVCodecParserContext *s);
} AVCodecParser;
/**
@@ -2796,6 +2797,8 @@ int av_parser_parse2(AVCodecParserContext *s,
int64_t pts, int64_t dts,
int64_t pos);
+void av_parser_flush(AVCodecParserContext *s);
+
void av_parser_close(AVCodecParserContext *s);
/**
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index af966766ee..5ad5e127c3 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -191,6 +191,28 @@ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx,
return index;
}
+av_cold void av_parser_flush(AVCodecParserContext *s)
+{
+ if (s->parser->parser_flush)
+ s->parser->parser_flush(s);
+
+ s->pict_type = AV_PICTURE_TYPE_I;
+ s->fetch_timestamp = 1;
+ s->key_frame = -1;
+ s->dts_sync_point = INT_MIN;
+ s->dts_ref_dts_delta = INT_MIN;
+ s->pts_dts_delta = INT_MIN;
+ s->format = -1;
+
+ s->flags &= ~PARSER_FLAG_FETCHED_OFFSET;
+
+ memset(s->cur_frame_end, 0, sizeof(s->cur_frame_end));
+ memset(s->cur_frame_pts, 0, sizeof(s->cur_frame_pts));
+ memset(s->cur_frame_pos, 0, sizeof(s->cur_frame_pos));
+ s->cur_offset = 0;
+ s->cur_frame_start_index = 0;
+}
+
av_cold void av_parser_close(AVCodecParserContext *s)
{
if (s) {
@@ -288,6 +310,19 @@ int ff_combine_frame(ParseContext *pc, int next,
return 0;
}
+av_cold void ff_parse_flush(AVCodecParserContext *s)
+{
+ ParseContext *pc = s->priv_data;
+
+ pc->index = 0;
+ pc->last_index = 0;
+ pc->overread_index = 0;
+ pc->state = 0;
+ pc->frame_start_found = 0;
+ pc->overread = 0;
+ pc->state64 = 0;
+}
+
av_cold void ff_parse_close(AVCodecParserContext *s)
{
ParseContext *pc = s->priv_data;
diff --git a/libavcodec/parser.h b/libavcodec/parser.h
index 2cee5ae4ff..a9ce63336b 100644
--- a/libavcodec/parser.h
+++ b/libavcodec/parser.h
@@ -45,6 +45,7 @@ typedef struct ParseContext{
* AVERROR(ENOMEM) if there was a memory allocation error
*/
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size);
+void ff_parse_flush(AVCodecParserContext *s);
void ff_parse_close(AVCodecParserContext *s);
/**
--
2.49.1
>From aa8653894129f336c5ff675a3cf3e2ae1a426c05 Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Fri, 24 Oct 2025 13:35:08 -0300
Subject: [PATCH 2/5] avcodec/av1_parser: add a flush callback
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/av1_parser.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libavcodec/av1_parser.c b/libavcodec/av1_parser.c
index ed6e1b61ad..c89a5f3b2c 100644
--- a/libavcodec/av1_parser.c
+++ b/libavcodec/av1_parser.c
@@ -201,6 +201,16 @@ static av_cold int av1_parser_init(AVCodecParserContext *ctx)
return 0;
}
+static av_cold void av1_parser_flush(AVCodecParserContext *ctx)
+{
+ AV1ParseContext *s = ctx->priv_data;
+
+ s->parsed_extradata = 0;
+
+ ff_cbs_fragment_reset(&s->temporal_unit);
+ ff_parse_flush(s);
+}
+
static av_cold void av1_parser_close(AVCodecParserContext *ctx)
{
AV1ParseContext *s = ctx->priv_data;
@@ -214,5 +224,6 @@ const AVCodecParser ff_av1_parser = {
.priv_data_size = sizeof(AV1ParseContext),
.parser_init = av1_parser_init,
.parser_close = av1_parser_close,
+ .parser_flush = av1_parser_flush,
.parser_parse = av1_parser_parse,
};
--
2.49.1
>From 1510f56d50f5ec771013cb6eb95e747ae017f8a0 Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Fri, 24 Oct 2025 13:35:17 -0300
Subject: [PATCH 3/5] avcodec/h264_parser: add a flush callback
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/h264_parser.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 722cbcb42f..5526807520 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -661,6 +661,16 @@ static int h264_parse(AVCodecParserContext *s,
return next;
}
+static av_cold void h264_flush(AVCodecParserContext *s)
+{
+ H264ParseContext *p = s->priv_data;
+
+ p->got_first = 0;
+ ff_h264_sei_uninit(&p->sei);
+ ff_h264_ps_uninit(&p->ps);
+ ff_parse_flush(s);
+}
+
static av_cold void h264_close(AVCodecParserContext *s)
{
H264ParseContext *p = s->priv_data;
@@ -687,5 +697,6 @@ const AVCodecParser ff_h264_parser = {
.priv_data_size = sizeof(H264ParseContext),
.parser_init = init,
.parser_parse = h264_parse,
+ .parser_flush = h264_flush,
.parser_close = h264_close,
};
--
2.49.1
>From 507895a3b256c62657617a4e07d18345a7814d92 Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Fri, 24 Oct 2025 13:35:29 -0300
Subject: [PATCH 4/5] avcodec/hevc/parser: add a flush callback
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/hevc/parser.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/libavcodec/hevc/parser.c b/libavcodec/hevc/parser.c
index 16b40e2b10..d7be923169 100644
--- a/libavcodec/hevc/parser.c
+++ b/libavcodec/hevc/parser.c
@@ -341,6 +341,17 @@ static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,
return next;
}
+static void hevc_parser_flush(AVCodecParserContext *s)
+{
+ HEVCParserContext *ctx = s->priv_data;
+
+ ctx->parsed_extradata = 0;
+
+ ff_hevc_ps_uninit(&ctx->ps);
+ ff_hevc_reset_sei(&ctx->sei);
+ ff_parse_flush(s);
+}
+
static void hevc_parser_close(AVCodecParserContext *s)
{
HEVCParserContext *ctx = s->priv_data;
@@ -357,4 +368,5 @@ const AVCodecParser ff_hevc_parser = {
.priv_data_size = sizeof(HEVCParserContext),
.parser_parse = hevc_parse,
.parser_close = hevc_parser_close,
+ .parser_flush = hevc_parser_flush,
};
--
2.49.1
>From 344c8cc1d82662985124040e4a2b1b1b342d88af Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Fri, 24 Oct 2025 13:40:29 -0300
Subject: [PATCH 5/5] avformat/demux: pass new extradata to the parser
The parser API doesn't work with packets, only raw data, so in order for it to
be made aware of new extradata propagated through packet side data we need to
pass it in some other form, namely, replacing the main extradata and ensuring
it will be parsed by forcing a flush.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavformat/demux.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/libavformat/demux.c b/libavformat/demux.c
index 374a84cda5..fa8730ee86 100644
--- a/libavformat/demux.c
+++ b/libavformat/demux.c
@@ -1167,7 +1167,10 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
AVPacket *out_pkt = si->parse_pkt;
AVStream *st = s->streams[stream_index];
FFStream *const sti = ffstream(st);
+ AVPacketSideData *sd = NULL;
const uint8_t *data = pkt->data;
+ const uint8_t *extradata = sti->avctx->extradata;
+ int extradata_size = sti->avctx->extradata_size;
int size = pkt->size;
int ret = 0, got_output = flush;
@@ -1184,6 +1187,17 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
}
}
+ if (pkt->side_data_elems)
+ sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems,
+ AV_PKT_DATA_NEW_EXTRADATA);
+ if (sd) {
+ av_assert1(size && !flush);
+
+ av_parser_flush(sti->parser);
+ sti->avctx->extradata = sd->data;
+ sti->avctx->extradata_size = sd->size;
+ }
+
while (size > 0 || (flush && got_output)) {
int64_t next_pts = pkt->pts;
int64_t next_dts = pkt->dts;
@@ -1277,6 +1291,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
}
fail:
+ if (sd) {
+ sti->avctx->extradata = extradata;
+ sti->avctx->extradata_size = extradata_size;
+ }
+
if (ret < 0)
av_packet_unref(out_pkt);
av_packet_unref(pkt);
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
reply other threads:[~2025-10-24 17:18 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=176132630270.25.14665566471023796367@7d278768979e \
--to=ffmpeg-devel@ffmpeg.org \
--cc=code@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git