ffmpeg-devel
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
October 2025
- 50 participants
- 205 discussions
[PATCH v2] ogg/vorbis: implement header packet skip in chained ogg bitstreams.
by Romain Beauxis 01 Oct '25
by Romain Beauxis 01 Oct '25
01 Oct '25
This is a redo of 574f634e49847e2225ee50013afebf0de03ef013 using a flat
memory storage for the extradata.
PR review comments addressed:
* Use flat memory bytestream
* Re-use existing xiph extradata layout
---
libavcodec/vorbisdec.c | 42 ++++++++---
libavformat/oggparsevorbis.c | 83 +++++++++++++++++++++-
tests/ref/fate/ogg-vorbis-chained-meta.txt | 3 -
3 files changed, 114 insertions(+), 14 deletions(-)
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index adbd726183..84879462a1 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1778,11 +1778,40 @@ static int vorbis_decode_frame(AVCodecContext *avctx, AVFrame *frame,
GetBitContext *gb = &vc->gb;
float *channel_ptrs[255];
int i, len, ret;
+ size_t new_extradata_size;
+ const uint8_t *new_extradata;
+ const uint8_t *header_start[3];
+ int header_len[3] = {0, 0, 0};
+ const uint8_t *header;
+ int header_size = 0;
+ const uint8_t *comment;
+ int comment_size = 0;
+ const uint8_t *setup;
+ int setup_size = 0;
ff_dlog(NULL, "packet length %d \n", buf_size);
- if (*buf == 1 && buf_size > 7) {
- if ((ret = init_get_bits8(gb, buf + 1, buf_size - 1)) < 0)
+ new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
+ &new_extradata_size);
+
+ if (new_extradata) {
+ ret = avpriv_split_xiph_headers(new_extradata, new_extradata_size,
+ 30, header_start, header_len);
+ if (ret < 0)
+ return ret;
+
+ header = header_start[0];
+ header_size = header_len[0];
+
+ comment = header_start[1];
+ comment_size = header_len[1];
+
+ setup = header_start[2];
+ setup_size = header_len[2];
+ }
+
+ if (header_size > 7 && *header == 1) {
+ if ((ret = init_get_bits8(gb, header + 1, header_size - 1)) < 0)
return ret;
vorbis_free(vc);
@@ -1801,16 +1830,14 @@ static int vorbis_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
avctx->sample_rate = vc->audio_samplerate;
- return buf_size;
}
- if (*buf == 3 && buf_size > 7) {
+ if (comment_size > 7 && *comment == 3) {
av_log(avctx, AV_LOG_DEBUG, "Ignoring comment header\n");
- return buf_size;
}
- if (*buf == 5 && buf_size > 7 && vc->channel_residues && !vc->modes) {
- if ((ret = init_get_bits8(gb, buf + 1, buf_size - 1)) < 0)
+ if (setup_size > 7 && *setup == 5 && vc->channel_residues && !vc->modes) {
+ if ((ret = init_get_bits8(gb, setup + 1, setup_size - 1)) < 0)
return ret;
if ((ret = vorbis_parse_setup_hdr(vc))) {
@@ -1818,7 +1845,6 @@ static int vorbis_decode_frame(AVCodecContext *avctx, AVFrame *frame,
vorbis_free(vc);
return ret;
}
- return buf_size;
}
if (!vc->channel_residues || !vc->modes) {
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 62cc2da6de..7859ec5a51 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -215,6 +215,12 @@ struct oggvorbis_private {
AVVorbisParseContext *vp;
int64_t final_pts;
int final_duration;
+ uint8_t *header;
+ int header_size;
+ uint8_t *comment;
+ int comment_size;
+ uint8_t *setup;
+ int setup_size;
};
static int fixup_vorbis_headers(AVFormatContext *as,
@@ -260,6 +266,10 @@ static void vorbis_cleanup(AVFormatContext *s, int idx)
av_vorbis_parse_free(&priv->vp);
for (i = 0; i < 3; i++)
av_freep(&priv->packet[i]);
+
+ av_freep(&priv->header);
+ av_freep(&priv->comment);
+ av_freep(&priv->setup);
}
}
@@ -434,6 +444,9 @@ static int vorbis_packet(AVFormatContext *s, int idx)
struct ogg_stream *os = ogg->streams + idx;
struct oggvorbis_private *priv = os->private;
int duration, flags = 0;
+ int skip_packet = 0;
+ int ret, new_extradata_size;
+ PutByteContext pb;
if (!priv->vp)
return AVERROR_INVALIDDATA;
@@ -496,10 +509,50 @@ static int vorbis_packet(AVFormatContext *s, int idx)
if (duration < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
- } else if (flags & VORBIS_FLAG_COMMENT) {
- vorbis_update_metadata(s, idx);
+ }
+
+ if (flags & VORBIS_FLAG_HEADER) {
+ ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
+ if (ret < 0)
+ return ret;
+
+ ret = av_reallocp(&priv->header, os->psize);
+ if (ret < 0)
+ return ret;
+
+ memcpy(priv->header, os->buf + os->pstart, os->psize);
+ priv->header_size = os->psize;
+
+ skip_packet = 1;
+ }
+
+ if (flags & VORBIS_FLAG_COMMENT) {
+ ret = vorbis_update_metadata(s, idx);
+ if (ret < 0)
+ return ret;
+
+ ret = av_reallocp(&priv->comment, os->psize);
+ if (ret < 0)
+ return ret;
+
+ memcpy(priv->comment, os->buf + os->pstart, os->psize);
+ priv->comment_size = os->psize;
+
flags = 0;
+ skip_packet = 1;
+ }
+
+ if (flags & VORBIS_FLAG_SETUP) {
+ ret = av_reallocp(&priv->setup, os->psize);
+ if (ret < 0)
+ return ret;
+
+ memcpy(priv->setup, os->buf + os->pstart, os->psize);
+ priv->setup_size = os->psize;
+
+ skip_packet = 1;
}
+
os->pduration = duration;
}
@@ -521,7 +574,31 @@ static int vorbis_packet(AVFormatContext *s, int idx)
priv->final_duration += os->pduration;
}
- return 0;
+ if (priv->header && priv->comment && priv->setup) {
+ new_extradata_size = priv->header_size + priv->comment_size + priv->setup_size + 6;
+
+ ret = av_reallocp(&os->new_extradata, new_extradata_size);
+ if (ret < 0)
+ return ret;
+
+ os->new_extradata_size = new_extradata_size;
+ bytestream2_init_writer(&pb, os->new_extradata, new_extradata_size);
+ bytestream2_put_be16(&pb, priv->header_size);
+ bytestream2_put_buffer(&pb, priv->header, priv->header_size);
+ bytestream2_put_be16(&pb, priv->comment_size);
+ bytestream2_put_buffer(&pb, priv->comment, priv->comment_size);
+ bytestream2_put_be16(&pb, priv->setup_size);
+ bytestream2_put_buffer(&pb, priv->setup, priv->setup_size);
+
+ av_freep(&priv->header);
+ priv->header_size = 0;
+ av_freep(&priv->comment);
+ priv->comment_size = 0;
+ av_freep(&priv->setup);
+ priv->comment_size = 0;
+ }
+
+ return skip_packet;
}
const struct ogg_codec ff_vorbis_codec = {
diff --git a/tests/ref/fate/ogg-vorbis-chained-meta.txt b/tests/ref/fate/ogg-vorbis-chained-meta.txt
index b7a97c90e2..1206f86c1f 100644
--- a/tests/ref/fate/ogg-vorbis-chained-meta.txt
+++ b/tests/ref/fate/ogg-vorbis-chained-meta.txt
@@ -6,10 +6,7 @@ Stream ID: 0, frame PTS: 128, metadata: N/A
Stream ID: 0, packet PTS: 704, packet DTS: 704
Stream ID: 0, frame PTS: 704, metadata: N/A
Stream ID: 0, packet PTS: 0, packet DTS: 0
-Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
-Stream ID: 0, packet PTS: 0, packet DTS: 0
-Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, frame PTS: 0, metadata: N/A
Stream ID: 0, packet PTS: 128, packet DTS: 128
Stream ID: 0, frame PTS: 128, metadata: N/A
--
2.39.5 (Apple Git-154)
5
32
[PATCH] Don't reset last{pts,dts} on new sequentialized ogg streams. (PR #20637)
by toots 01 Oct '25
by toots 01 Oct '25
01 Oct '25
PR #20637 opened by toots
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20637
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20637.patch
This fixes PTS/DTS discontinuity on sequentialized ogg streams.
From 98c89233807a1efae0ebaa1cb9ae4ff6c09b8969 Mon Sep 17 00:00:00 2001
From: Romain Beauxis <romain.beauxis(a)gmail.com>
Date: Mon, 4 Aug 2025 09:00:28 -0500
Subject: [PATCH 1/6] ogg/vorbis: implement header packet skip in chained ogg
bitstreams.
---
doc/APIchanges | 4 +
libavformat/oggparsevorbis.c | 85 +++++++++++++++++++++-
tests/ref/fate/ogg-vorbis-chained-meta.txt | 3 -
3 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/doc/APIchanges b/doc/APIchanges
index 9d629f766f..6e7f5d2037 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,10 @@ The last version increases of all libraries were on 2025-03-28
API changes, most recent first:
+2025-08-xx - xxxxxxxxxx - lavf 62.6.100 - oggparsevorbis.h oggparseopus.h oggparseflac.h
+ Drop header packets from secondary chained ogg/{flac, opus, vorbis} streams
+ from demuxer output.
+
2025-09-xx - xxxxxxxxxx - lavu 60.13.100 - hwcontext_d3d12va.h
Add resource_flags and heap_flags to AVD3D12VADeviceContext
Add heap_flags to AVD3D12VAFramesContext
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 62cc2da6de..1af2f21a82 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -215,6 +215,12 @@ struct oggvorbis_private {
AVVorbisParseContext *vp;
int64_t final_pts;
int final_duration;
+ uint8_t *header;
+ int header_size;
+ uint8_t *comment;
+ int comment_size;
+ uint8_t *setup;
+ int setup_size;
};
static int fixup_vorbis_headers(AVFormatContext *as,
@@ -260,6 +266,10 @@ static void vorbis_cleanup(AVFormatContext *s, int idx)
av_vorbis_parse_free(&priv->vp);
for (i = 0; i < 3; i++)
av_freep(&priv->packet[i]);
+
+ av_freep(&priv->header);
+ av_freep(&priv->comment);
+ av_freep(&priv->setup);
}
}
@@ -434,6 +444,9 @@ static int vorbis_packet(AVFormatContext *s, int idx)
struct ogg_stream *os = ogg->streams + idx;
struct oggvorbis_private *priv = os->private;
int duration, flags = 0;
+ int skip_packet = 0;
+ int ret, new_extradata_size;
+ PutByteContext pb;
if (!priv->vp)
return AVERROR_INVALIDDATA;
@@ -496,10 +509,50 @@ static int vorbis_packet(AVFormatContext *s, int idx)
if (duration < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
- } else if (flags & VORBIS_FLAG_COMMENT) {
- vorbis_update_metadata(s, idx);
- flags = 0;
}
+
+ if (flags & VORBIS_FLAG_HEADER) {
+ ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
+ if (ret < 0)
+ return ret;
+
+ ret = av_reallocp(&priv->header, os->psize);
+ if (ret < 0)
+ return ret;
+
+ memcpy(priv->header, os->buf + os->pstart, os->psize);
+ priv->header_size = os->psize;
+
+ skip_packet = 1;
+ }
+
+ if (flags & VORBIS_FLAG_COMMENT) {
+ ret = vorbis_update_metadata(s, idx);
+ if (ret < 0)
+ return ret;
+
+ ret = av_reallocp(&priv->comment, os->psize);
+ if (ret < 0)
+ return ret;
+
+ memcpy(priv->comment, os->buf + os->pstart, os->psize);
+ priv->comment_size = os->psize;
+
+ flags = 0;
+ skip_packet = 1;
+ }
+
+ if (flags & VORBIS_FLAG_SETUP) {
+ ret = av_reallocp(&priv->setup, os->psize);
+ if (ret < 0)
+ return ret;
+
+ memcpy(priv->setup, os->buf + os->pstart, os->psize);
+ priv->setup_size = os->psize;
+
+ skip_packet = 1;
+ }
+
os->pduration = duration;
}
@@ -521,7 +574,31 @@ static int vorbis_packet(AVFormatContext *s, int idx)
priv->final_duration += os->pduration;
}
- return 0;
+ if (priv->header && priv->comment && priv->setup) {
+ new_extradata_size = priv->header_size + priv->comment_size + priv->setup_size + 6;
+
+ ret = av_reallocp(&os->new_extradata, new_extradata_size);
+ if (ret < 0)
+ return ret;
+
+ os->new_extradata_size = new_extradata_size;
+ bytestream2_init_writer(&pb, os->new_extradata, new_extradata_size);
+ bytestream2_put_be16(&pb, priv->header_size);
+ bytestream2_put_buffer(&pb, priv->header, priv->header_size);
+ bytestream2_put_be16(&pb, priv->comment_size);
+ bytestream2_put_buffer(&pb, priv->comment, priv->comment_size);
+ bytestream2_put_be16(&pb, priv->setup_size);
+ bytestream2_put_buffer(&pb, priv->setup, priv->setup_size);
+
+ av_freep(&priv->header);
+ priv->header_size = 0;
+ av_freep(&priv->comment);
+ priv->comment_size = 0;
+ av_freep(&priv->setup);
+ priv->setup_size = 0;
+ }
+
+ return skip_packet;
}
const struct ogg_codec ff_vorbis_codec = {
diff --git a/tests/ref/fate/ogg-vorbis-chained-meta.txt b/tests/ref/fate/ogg-vorbis-chained-meta.txt
index b7a97c90e2..1206f86c1f 100644
--- a/tests/ref/fate/ogg-vorbis-chained-meta.txt
+++ b/tests/ref/fate/ogg-vorbis-chained-meta.txt
@@ -6,10 +6,7 @@ Stream ID: 0, frame PTS: 128, metadata: N/A
Stream ID: 0, packet PTS: 704, packet DTS: 704
Stream ID: 0, frame PTS: 704, metadata: N/A
Stream ID: 0, packet PTS: 0, packet DTS: 0
-Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
-Stream ID: 0, packet PTS: 0, packet DTS: 0
-Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, frame PTS: 0, metadata: N/A
Stream ID: 0, packet PTS: 128, packet DTS: 128
Stream ID: 0, frame PTS: 128, metadata: N/A
--
2.49.1
From cc31466a5016d3e4b2cfe2858fb84601a318c857 Mon Sep 17 00:00:00 2001
From: Romain Beauxis <romain.beauxis(a)gmail.com>
Date: Tue, 18 Feb 2025 22:32:03 -0600
Subject: [PATCH 2/6] libavformat/oggdec.h, libavformat/oggparsevorbis.c:
Factor out vorbis metadata update mechanism.
---
libavformat/oggdec.h | 14 ++++++++++++++
libavformat/oggparsevorbis.c | 25 +++++++++++++++++--------
2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index 256a17c5e3..6776782ddf 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -160,6 +160,20 @@ int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m,
int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st,
const uint8_t *buf, int size);
+/**
+ * Parse Vorbis comments, add metadata to an AVStream
+ *
+ * This function also attaches the metadata to the next decoded
+ * packet as AV_PKT_DATA_METADATA_UPDATE
+ *
+ * @note The buffer will be temporarily modified by this function,
+ * so it needs to be writable. Furthermore it must be padded
+ * by a single byte (not counted in size).
+ * All changes will have been reverted upon return.
+ */
+int ff_vorbis_update_metadata(AVFormatContext *s, AVStream *st,
+ const uint8_t *buf, int size);
+
static inline int
ogg_find_stream (struct ogg * ogg, int serial)
{
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 1af2f21a82..7c4f7624f8 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -273,20 +273,16 @@ static void vorbis_cleanup(AVFormatContext *s, int idx)
}
}
-static int vorbis_update_metadata(AVFormatContext *s, int idx)
+int ff_vorbis_update_metadata(AVFormatContext *s, AVStream *st,
+ const uint8_t *buf, int size)
{
struct ogg *ogg = s->priv_data;
- struct ogg_stream *os = ogg->streams + idx;
- AVStream *st = s->streams[idx];
+ struct ogg_stream *os = ogg->streams + st->index;
int ret;
- if (os->psize <= 8)
- return 0;
-
/* New metadata packet; release old data. */
av_dict_free(&st->metadata);
- ret = ff_vorbis_stream_comment(s, st, os->buf + os->pstart + 7,
- os->psize - 8);
+ ret = ff_vorbis_stream_comment(s, st, buf, size);
if (ret < 0)
return ret;
@@ -359,6 +355,19 @@ static int vorbis_parse_header(AVFormatContext *s, AVStream *st,
return 1;
}
+static int vorbis_update_metadata(AVFormatContext *s, int idx)
+{
+ struct ogg *ogg = s->priv_data;
+ struct ogg_stream *os = ogg->streams + idx;
+ AVStream *st = s->streams[idx];
+
+ if (os->psize <= 8)
+ return 0;
+
+ return ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 7,
+ os->psize - 8);
+}
+
static int vorbis_header(AVFormatContext *s, int idx)
{
struct ogg *ogg = s->priv_data;
--
2.49.1
From 18b8507cb606d95f440df239485dd75df6b33678 Mon Sep 17 00:00:00 2001
From: Romain Beauxis <romain.beauxis(a)gmail.com>
Date: Fri, 14 Feb 2025 09:39:45 -0600
Subject: [PATCH 3/6] libavformat/oggdec.c: Use AV_PKT_DATA_STRINGS_METADATA to
pass metadata updates.
---
libavformat/oggdec.c | 2 +-
libavformat/oggdec.h | 2 +-
tests/ref/fate/ogg-vorbis-chained-meta.txt | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 9dc2c62035..9f3a92a5ea 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -880,7 +880,7 @@ retry:
}
if (os->new_metadata) {
- ret = av_packet_add_side_data(pkt, AV_PKT_DATA_METADATA_UPDATE,
+ ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
os->new_metadata, os->new_metadata_size);
if (ret < 0)
return ret;
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index 6776782ddf..b051b651e3 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -164,7 +164,7 @@ int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st,
* Parse Vorbis comments, add metadata to an AVStream
*
* This function also attaches the metadata to the next decoded
- * packet as AV_PKT_DATA_METADATA_UPDATE
+ * packet as AV_PKT_DATA_STRINGS_METADATA
*
* @note The buffer will be temporarily modified by this function,
* so it needs to be writable. Furthermore it must be padded
diff --git a/tests/ref/fate/ogg-vorbis-chained-meta.txt b/tests/ref/fate/ogg-vorbis-chained-meta.txt
index 1206f86c1f..60d9aeb9fa 100644
--- a/tests/ref/fate/ogg-vorbis-chained-meta.txt
+++ b/tests/ref/fate/ogg-vorbis-chained-meta.txt
@@ -7,7 +7,7 @@ Stream ID: 0, packet PTS: 704, packet DTS: 704
Stream ID: 0, frame PTS: 704, metadata: N/A
Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
-Stream ID: 0, frame PTS: 0, metadata: N/A
+Stream ID: 0, frame PTS: 0, metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
Stream ID: 0, packet PTS: 128, packet DTS: 128
Stream ID: 0, frame PTS: 128, metadata: N/A
Stream ID: 0, packet PTS: 704, packet DTS: 704
--
2.49.1
From 1787d758be0fef7f030104a7b14e12c67e24181a Mon Sep 17 00:00:00 2001
From: Romain Beauxis <romain.beauxis(a)gmail.com>
Date: Tue, 4 Feb 2025 07:03:49 -0500
Subject: [PATCH 4/6] libavformat/oggparseflac.c: Parse ogg/flac comments in
new ogg packets, add them to ogg stream new_metadata.
---
libavformat/oggparseflac.c | 7 +++++++
tests/ref/fate/ogg-flac-chained-meta.txt | 3 ++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
index d66b85b09e..e81e4021a1 100644
--- a/libavformat/oggparseflac.c
+++ b/libavformat/oggparseflac.c
@@ -85,6 +85,8 @@ flac_packet (AVFormatContext * s, int idx)
{
struct ogg *ogg = s->priv_data;
struct ogg_stream *os = ogg->streams + idx;
+ AVStream *st = s->streams[idx];
+ int ret;
if (os->psize > OGG_FLAC_MAGIC_SIZE &&
!memcmp(
@@ -95,6 +97,11 @@ flac_packet (AVFormatContext * s, int idx)
if (os->psize > 0 &&
((os->buf[os->pstart] & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT)) {
+ ret = ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 4,
+ os->psize - 4);
+ if (ret < 0)
+ return ret;
+
return 1;
}
diff --git a/tests/ref/fate/ogg-flac-chained-meta.txt b/tests/ref/fate/ogg-flac-chained-meta.txt
index 28e22aa29e..5abf37dcee 100644
--- a/tests/ref/fate/ogg-flac-chained-meta.txt
+++ b/tests/ref/fate/ogg-flac-chained-meta.txt
@@ -5,6 +5,7 @@ Stream ID: 0, frame PTS: 0, metadata: N/A
Stream ID: 0, packet PTS: 4608, packet DTS: 4608
Stream ID: 0, frame PTS: 4608, metadata: N/A
Stream ID: 0, packet PTS: 0, packet DTS: 0
-Stream ID: 0, frame PTS: 0, metadata: N/A
+Stream ID: 0, new metadata: encoder=Lavc61.19.100 flac:title=Second Stream
+Stream ID: 0, frame PTS: 0, metadata: encoder=Lavc61.19.100 flac:title=Second Stream
Stream ID: 0, packet PTS: 4608, packet DTS: 4608
Stream ID: 0, frame PTS: 4608, metadata: N/A
--
2.49.1
From ccfe1e3ba86a95c8c80455b1c7864b291b928dcb Mon Sep 17 00:00:00 2001
From: Romain Beauxis <romain.beauxis(a)gmail.com>
Date: Mon, 10 Feb 2025 11:48:03 -0600
Subject: [PATCH 5/6] libavformat/oggparseopus.c: Parse comments from secondary
chained streams header packet.
---
libavformat/oggparseopus.c | 5 +++++
tests/ref/fate/ogg-opus-chained-meta.txt | 3 ++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c
index 65b93b4053..ae4ff22c53 100644
--- a/libavformat/oggparseopus.c
+++ b/libavformat/oggparseopus.c
@@ -154,6 +154,11 @@ static int opus_packet(AVFormatContext *avf, int idx)
}
if (os->psize > 8 && !memcmp(packet, "OpusTags", 8)) {
+ ret = ff_vorbis_update_metadata(avf, st, os->buf + os->pstart + 8,
+ os->psize - 8);
+ if (ret < 0)
+ return ret;
+
priv->need_comments = 0;
return 1;
}
diff --git a/tests/ref/fate/ogg-opus-chained-meta.txt b/tests/ref/fate/ogg-opus-chained-meta.txt
index addc41c1eb..aad9b83700 100644
--- a/tests/ref/fate/ogg-opus-chained-meta.txt
+++ b/tests/ref/fate/ogg-opus-chained-meta.txt
@@ -13,7 +13,8 @@ Stream ID: 0, frame PTS: 3528, metadata: N/A
Stream ID: 0, packet PTS: 4488, packet DTS: 4488
Stream ID: 0, frame PTS: 4488, metadata: N/A
Stream ID: 0, packet PTS: -312, packet DTS: -312
-Stream ID: 0, frame PTS: -312, metadata: N/A
+Stream ID: 0, new metadata: encoder=Lavc61.19.100 libopus:title=Second Stream
+Stream ID: 0, frame PTS: -312, metadata: encoder=Lavc61.19.100 libopus:title=Second Stream
Stream ID: 0, packet PTS: 648, packet DTS: 648
Stream ID: 0, frame PTS: 648, metadata: N/A
Stream ID: 0, packet PTS: 1608, packet DTS: 1608
--
2.49.1
From 0d75fa2fcc76601c80f26e53f97b6c17d64643d8 Mon Sep 17 00:00:00 2001
From: Romain Beauxis <romain.beauxis(a)gmail.com>
Date: Tue, 30 Sep 2025 20:23:04 -0500
Subject: [PATCH 6/6] Don't reset last{pts,dts} on new sequentialized ogg
streams.
This fixes PTS/DTS discontinuity on sequentialized ogg streams.
---
libavformat/oggdec.c | 2 --
tests/ref/fate/ogg-flac-chained-meta.txt | 8 ++++----
tests/ref/fate/ogg-opus-chained-meta.txt | 24 +++++++++++-----------
tests/ref/fate/ogg-vorbis-chained-meta.txt | 12 +++++------
4 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 9f3a92a5ea..28a22fac9f 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -235,8 +235,6 @@ static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic,
os->serial = serial;
os->codec = codec;
os->serial = serial;
- os->lastpts = 0;
- os->lastdts = 0;
os->start_trimming = 0;
os->end_trimming = 0;
diff --git a/tests/ref/fate/ogg-flac-chained-meta.txt b/tests/ref/fate/ogg-flac-chained-meta.txt
index 5abf37dcee..877b3f3173 100644
--- a/tests/ref/fate/ogg-flac-chained-meta.txt
+++ b/tests/ref/fate/ogg-flac-chained-meta.txt
@@ -4,8 +4,8 @@ Stream ID: 0, new metadata: encoder=Lavc61.19.100 flac:title=First Stream
Stream ID: 0, frame PTS: 0, metadata: N/A
Stream ID: 0, packet PTS: 4608, packet DTS: 4608
Stream ID: 0, frame PTS: 4608, metadata: N/A
-Stream ID: 0, packet PTS: 0, packet DTS: 0
+Stream ID: 0, packet PTS: 8820, packet DTS: 8820
Stream ID: 0, new metadata: encoder=Lavc61.19.100 flac:title=Second Stream
-Stream ID: 0, frame PTS: 0, metadata: encoder=Lavc61.19.100 flac:title=Second Stream
-Stream ID: 0, packet PTS: 4608, packet DTS: 4608
-Stream ID: 0, frame PTS: 4608, metadata: N/A
+Stream ID: 0, frame PTS: 8820, metadata: encoder=Lavc61.19.100 flac:title=Second Stream
+Stream ID: 0, packet PTS: 13428, packet DTS: 13428
+Stream ID: 0, frame PTS: 13428, metadata: N/A
diff --git a/tests/ref/fate/ogg-opus-chained-meta.txt b/tests/ref/fate/ogg-opus-chained-meta.txt
index aad9b83700..5c2b9d0d44 100644
--- a/tests/ref/fate/ogg-opus-chained-meta.txt
+++ b/tests/ref/fate/ogg-opus-chained-meta.txt
@@ -12,16 +12,16 @@ Stream ID: 0, packet PTS: 3528, packet DTS: 3528
Stream ID: 0, frame PTS: 3528, metadata: N/A
Stream ID: 0, packet PTS: 4488, packet DTS: 4488
Stream ID: 0, frame PTS: 4488, metadata: N/A
-Stream ID: 0, packet PTS: -312, packet DTS: -312
+Stream ID: 0, packet PTS: 4800, packet DTS: 4800
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libopus:title=Second Stream
-Stream ID: 0, frame PTS: -312, metadata: encoder=Lavc61.19.100 libopus:title=Second Stream
-Stream ID: 0, packet PTS: 648, packet DTS: 648
-Stream ID: 0, frame PTS: 648, metadata: N/A
-Stream ID: 0, packet PTS: 1608, packet DTS: 1608
-Stream ID: 0, frame PTS: 1608, metadata: N/A
-Stream ID: 0, packet PTS: 2568, packet DTS: 2568
-Stream ID: 0, frame PTS: 2568, metadata: N/A
-Stream ID: 0, packet PTS: 3528, packet DTS: 3528
-Stream ID: 0, frame PTS: 3528, metadata: N/A
-Stream ID: 0, packet PTS: 4488, packet DTS: 4488
-Stream ID: 0, frame PTS: 4488, metadata: N/A
+Stream ID: 0, frame PTS: 4800, metadata: encoder=Lavc61.19.100 libopus:title=Second Stream
+Stream ID: 0, packet PTS: 5760, packet DTS: 5760
+Stream ID: 0, frame PTS: 5760, metadata: N/A
+Stream ID: 0, packet PTS: 6720, packet DTS: 6720
+Stream ID: 0, frame PTS: 6720, metadata: N/A
+Stream ID: 0, packet PTS: 7680, packet DTS: 7680
+Stream ID: 0, frame PTS: 7680, metadata: N/A
+Stream ID: 0, packet PTS: 8640, packet DTS: 8640
+Stream ID: 0, frame PTS: 8640, metadata: N/A
+Stream ID: 0, packet PTS: 9600, packet DTS: 9600
+Stream ID: 0, frame PTS: 9600, metadata: N/A
diff --git a/tests/ref/fate/ogg-vorbis-chained-meta.txt b/tests/ref/fate/ogg-vorbis-chained-meta.txt
index 60d9aeb9fa..5ec756663d 100644
--- a/tests/ref/fate/ogg-vorbis-chained-meta.txt
+++ b/tests/ref/fate/ogg-vorbis-chained-meta.txt
@@ -5,10 +5,10 @@ Stream ID: 0, packet PTS: 128, packet DTS: 128
Stream ID: 0, frame PTS: 128, metadata: N/A
Stream ID: 0, packet PTS: 704, packet DTS: 704
Stream ID: 0, frame PTS: 704, metadata: N/A
-Stream ID: 0, packet PTS: 0, packet DTS: 0
+Stream ID: 0, packet PTS: 1323, packet DTS: 1323
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
-Stream ID: 0, frame PTS: 0, metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
-Stream ID: 0, packet PTS: 128, packet DTS: 128
-Stream ID: 0, frame PTS: 128, metadata: N/A
-Stream ID: 0, packet PTS: 704, packet DTS: 704
-Stream ID: 0, frame PTS: 704, metadata: N/A
+Stream ID: 0, frame PTS: 1323, metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
+Stream ID: 0, packet PTS: 1451, packet DTS: 1451
+Stream ID: 0, frame PTS: 1451, metadata: N/A
+Stream ID: 0, packet PTS: 2027, packet DTS: 2027
+Stream ID: 0, frame PTS: 2027, metadata: N/A
--
2.49.1
1
0
01 Oct '25
PR #20636 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20636
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20636.patch
From 0c2f259863bea7908422a5ae43ec380fce1f8135 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
Date: Wed, 1 Oct 2025 13:42:09 +0200
Subject: [PATCH 1/2] tests/checkasm/llviddsp: Use the same width for each
cpuflag
Otherwise the benchmark numbers would be incomparable nonsense.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
---
tests/checkasm/llviddsp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/checkasm/llviddsp.c b/tests/checkasm/llviddsp.c
index 9f8de65df4..0552e98106 100644
--- a/tests/checkasm/llviddsp.c
+++ b/tests/checkasm/llviddsp.c
@@ -195,9 +195,13 @@ static void check_add_gradient_pred(LLVidDSPContext *c, int w) {
void checkasm_check_llviddsp(void)
{
LLVidDSPContext c;
- int width = 16 * av_clip(rnd(), 16, 128);
+ static int saved_width = 0;
+ int width = saved_width;
int accRnd = rnd() & 0xFF;
+ if (!width)
+ saved_width = width = 16 * av_clip(rnd(), 16, 128);
+
ff_llviddsp_init(&c);
check_add_bytes(&c, width);
--
2.49.1
From 412776390c42ed6088752a314ec515792239055d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
Date: Wed, 1 Oct 2025 10:46:39 +0200
Subject: [PATCH 2/2] avcodec/x86/h263_loopfilter: Port loop filter to SSE2
Old benchmarks:
h263dsp.h_loop_filter_c: 41.2 ( 1.00x)
h263dsp.h_loop_filter_mmx: 39.5 ( 1.04x)
h263dsp.v_loop_filter_c: 43.5 ( 1.00x)
h263dsp.v_loop_filter_mmx: 16.9 ( 2.57x)
New benchmarks:
h263dsp.h_loop_filter_c: 41.6 ( 1.00x)
h263dsp.h_loop_filter_sse2: 28.2 ( 1.48x)
h263dsp.v_loop_filter_c: 42.4 ( 1.00x)
h263dsp.v_loop_filter_sse2: 15.1 ( 2.81x)
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
---
libavcodec/x86/constants.c | 2 +-
libavcodec/x86/constants.h | 2 +-
libavcodec/x86/h263_loopfilter.asm | 167 ++++++++++++-----------------
libavcodec/x86/h263dsp_init.c | 10 +-
tests/checkasm/h263dsp.c | 2 +-
5 files changed, 78 insertions(+), 105 deletions(-)
diff --git a/libavcodec/x86/constants.c b/libavcodec/x86/constants.c
index c5f3c6428e..1e2f5990e4 100644
--- a/libavcodec/x86/constants.c
+++ b/libavcodec/x86/constants.c
@@ -75,7 +75,7 @@ DECLARE_ALIGNED(32, const ymm_reg, ff_pb_80) = { 0x8080808080808080ULL, 0x808
0x8080808080808080ULL, 0x8080808080808080ULL };
DECLARE_ALIGNED(32, const ymm_reg, ff_pb_FE) = { 0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL,
0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL };
-DECLARE_ALIGNED(8, const uint64_t, ff_pb_FC) = 0xFCFCFCFCFCFCFCFCULL;
+DECLARE_ALIGNED(16, const xmm_reg, ff_pb_FC) = { 0xFCFCFCFCFCFCFCFCULL, 0xFCFCFCFCFCFCFCFCULL };
DECLARE_ALIGNED(16, const xmm_reg, ff_ps_neg) = { 0x8000000080000000ULL, 0x8000000080000000ULL };
diff --git a/libavcodec/x86/constants.h b/libavcodec/x86/constants.h
index 4a55adb5b3..7d0bd975b9 100644
--- a/libavcodec/x86/constants.h
+++ b/libavcodec/x86/constants.h
@@ -56,8 +56,8 @@ extern const ymm_reg ff_pb_1;
extern const ymm_reg ff_pb_2;
extern const ymm_reg ff_pb_3;
extern const ymm_reg ff_pb_80;
+extern const xmm_reg ff_pb_FC;
extern const ymm_reg ff_pb_FE;
-extern const uint64_t ff_pb_FC;
extern const xmm_reg ff_ps_neg;
diff --git a/libavcodec/x86/h263_loopfilter.asm b/libavcodec/x86/h263_loopfilter.asm
index 77c8cf154d..ebe76f01af 100644
--- a/libavcodec/x86/h263_loopfilter.asm
+++ b/libavcodec/x86/h263_loopfilter.asm
@@ -1,5 +1,5 @@
;******************************************************************************
-;* MMX-optimized H.263 loop filter
+;* SSE2-optimized H.263 loop filter
;* Copyright (c) 2003-2013 Michael Niedermayer
;* Copyright (c) 2013 Daniel Kang
;*
@@ -22,7 +22,6 @@
%include "libavutil/x86/x86util.asm"
-SECTION_RODATA
cextern pb_FC
cextern h263_loop_filter_strength
@@ -30,60 +29,45 @@ SECTION .text
%macro H263_LOOP_FILTER 5
pxor m7, m7
- mova m0, [%1]
- mova m1, [%1]
- mova m2, [%4]
- mova m3, [%4]
+ movq m0, [%1]
+ movq m6, [%4]
+ mova m5, m0
punpcklbw m0, m7
- punpckhbw m1, m7
+ punpcklbw m6, m7
+ psubw m0, m6
+ movq m2, [%2]
+ movq m1, [%3]
+ mova m3, m2
+ mova m4, m1
punpcklbw m2, m7
- punpckhbw m3, m7
- psubw m0, m2
- psubw m1, m3
- mova m2, [%2]
- mova m3, [%2]
- mova m4, [%3]
- mova m5, [%3]
- punpcklbw m2, m7
- punpckhbw m3, m7
- punpcklbw m4, m7
- punpckhbw m5, m7
- psubw m4, m2
- psubw m5, m3
- psllw m4, 2
- psllw m5, 2
- paddw m4, m0
- paddw m5, m1
+ punpcklbw m1, m7
+ psubw m1, m2
+ psllw m1, 2
+ paddw m1, m0
pxor m6, m6
- pcmpgtw m6, m4
- pcmpgtw m7, m5
- pxor m4, m6
- pxor m5, m7
- psubw m4, m6
- psubw m5, m7
- psrlw m4, 3
- psrlw m5, 3
- packuswb m4, m5
+ pcmpgtw m6, m1
+ pxor m1, m6
+ psubw m1, m6
+ psrlw m1, 3
+ packuswb m1, m7
packsswb m6, m7
- pxor m7, m7
movd m2, %5
punpcklbw m2, m2
punpcklbw m2, m2
punpcklbw m2, m2
- psubusb m2, m4
- mova m3, m2
- psubusb m3, m4
- psubb m2, m3
- mova m3, [%2]
- mova m4, [%3]
+ psubusb m2, m1
+ mova m7, m2
+ psubusb m7, m1
+ psubb m2, m7
pxor m3, m6
pxor m4, m6
paddusb m3, m2
psubusb m4, m2
+ pxor m7, m7
pxor m3, m6
pxor m4, m6
paddusb m2, m2
- packsswb m0, m1
+ packsswb m0, m7
pcmpgtb m7, m0
pxor m0, m7
psubb m0, m7
@@ -94,22 +78,20 @@ SECTION .text
psrlw m1, 2
pxor m1, m7
psubb m1, m7
- mova m5, [%1]
- mova m6, [%4]
+ movq m6, [%4]
psubb m5, m1
paddb m6, m1
%endmacro
-INIT_MMX mmx
-; void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale)
-cglobal h263_v_loop_filter, 3,5
+INIT_XMM sse2
+; void ff_h263_v_loop_filter_sse2(uint8_t *src, int stride, int qscale)
+cglobal h263_v_loop_filter, 3,5,8
movsxdifnidn r1, r1d
movsxdifnidn r2, r2d
- lea r4, [h263_loop_filter_strength]
- movzx r3d, BYTE [r4+r2]
- movsx r2, r3b
- shl r2, 1
+ lea r3, [h263_loop_filter_strength]
+ movzx r2d, BYTE [r3+r2]
+ shl r2d, 1
mov r3, r0
sub r3, r1
@@ -117,73 +99,64 @@ cglobal h263_v_loop_filter, 3,5
sub r4, r1
H263_LOOP_FILTER r4, r3, r0, r0+r1, r2d
- mova [r3], m3
- mova [r0], m4
- mova [r4], m5
- mova [r0+r1], m6
+ movq [r3], m3
+ movq [r0], m4
+ movq [r4], m5
+ movq [r0+r1], m6
RET
%macro TRANSPOSE4X4 2
- movd m0, [%1]
- movd m1, [%1+r1]
- movd m2, [%1+r1*2]
- movd m3, [%1+r3]
- punpcklbw m0, m1
- punpcklbw m2, m3
- mova m1, m0
- punpcklwd m0, m2
- punpckhwd m1, m2
- movd [%2+ 0], m0
- punpckhdq m0, m0
- movd [%2+ 8], m0
- movd [%2+16], m1
- punpckhdq m1, m1
- movd [%2+24], m1
+ movd %1, [%2]
+ movd m2, [%2+r1]
+ movd m3, [%2+r1*2]
+ movd m4, [%2+r3]
+ punpcklbw %1, m2
+ punpcklbw m3, m4
+ punpcklwd %1, m3
%endmacro
-; void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale)
-INIT_MMX mmx
-cglobal h263_h_loop_filter, 3,5,0,32
+; void ff_h263_h_loop_filter_sse2(uint8_t *src, int stride, int qscale)
+INIT_XMM sse2
+cglobal h263_h_loop_filter, 3,5,8,32
movsxdifnidn r1, r1d
movsxdifnidn r2, r2d
lea r4, [h263_loop_filter_strength]
- movzx r3d, BYTE [r4+r2]
- movsx r2, r3b
- shl r2, 1
+ movzx r2d, BYTE [r4+r2]
+ shl r2d, 1
sub r0, 2
lea r3, [r1*3]
-
- TRANSPOSE4X4 r0, rsp
lea r4, [r0+r1*4]
- TRANSPOSE4X4 r4, rsp+4
+
+ TRANSPOSE4X4 m0, r0
+ TRANSPOSE4X4 m1, r4
+ mova m2, m0
+ punpckldq m0, m1
+ mova [rsp], m0
+ punpckhdq m2, m1
+ mova [rsp+16], m2
H263_LOOP_FILTER rsp, rsp+8, rsp+16, rsp+24, r2d
- mova m1, m5
- mova m0, m4
punpcklbw m5, m3
punpcklbw m4, m6
- punpckhbw m1, m3
- punpckhbw m0, m6
- mova m3, m5
- mova m6, m1
+ mova m0, m5
punpcklwd m5, m4
- punpcklwd m1, m0
- punpckhwd m3, m4
- punpckhwd m6, m0
+ punpckhwd m0, m4
movd [r0], m5
+ movd [r4], m0
+ pshufd m1, m5, 0x1
+ pshufd m2, m0, 0x1
+ movd [r0+r1*1], m1
+ movd [r4+r1*1], m2
punpckhdq m5, m5
- movd [r0+r1*1], m5
- movd [r0+r1*2], m3
- punpckhdq m3, m3
- movd [r0+r3], m3
- movd [r4], m1
- punpckhdq m1, m1
- movd [r4+r1*1], m1
- movd [r4+r1*2], m6
- punpckhdq m6, m6
- movd [r4+r3], m6
+ punpckhdq m0, m0
+ movd [r0+r1*2], m5
+ movd [r4+r1*2], m0
+ punpckhdq m5, m5
+ punpckhdq m0, m0
+ movd [r0+r3], m5
+ movd [r4+r3], m0
RET
diff --git a/libavcodec/x86/h263dsp_init.c b/libavcodec/x86/h263dsp_init.c
index ab81063233..3dd5d132e5 100644
--- a/libavcodec/x86/h263dsp_init.c
+++ b/libavcodec/x86/h263dsp_init.c
@@ -25,15 +25,15 @@
#include "libavutil/x86/cpu.h"
#include "libavcodec/h263dsp.h"
-void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
-void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+void ff_h263_h_loop_filter_sse2(uint8_t *src, int stride, int qscale);
+void ff_h263_v_loop_filter_sse2(uint8_t *src, int stride, int qscale);
av_cold void ff_h263dsp_init_x86(H263DSPContext *c)
{
int cpu_flags = av_get_cpu_flags();
- if (EXTERNAL_MMX(cpu_flags)) {
- c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
- c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
+ if (EXTERNAL_SSE2(cpu_flags)) {
+ c->h263_h_loop_filter = ff_h263_h_loop_filter_sse2;
+ c->h263_v_loop_filter = ff_h263_v_loop_filter_sse2;
}
}
diff --git a/tests/checkasm/h263dsp.c b/tests/checkasm/h263dsp.c
index 2d0957a90b..f99d376adc 100644
--- a/tests/checkasm/h263dsp.c
+++ b/tests/checkasm/h263dsp.c
@@ -34,7 +34,7 @@ static void check_loop_filter(char dim, filter func)
LOCAL_ALIGNED_16(uint8_t, buf1, [32 * 32]);
int qscale = rnd() % 32;
- declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *, int, int);
+ declare_func(void, uint8_t *, int, int);
for (size_t y = 0; y < 32; y++)
for (size_t x = 0; x < 32; x++)
--
2.49.1
1
0
PR #20635 opened by Marvin Scholz (ePirat)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20635
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20635.patch
Backports #20541 and #20542 to 8.0 and I would also ideally like to backport those to 7.1 if there are no objections.
From 09a6b6e981d5fea72182002ed94e93c24dee6b37 Mon Sep 17 00:00:00 2001
From: Marvin Scholz <epirat07(a)gmail.com>
Date: Thu, 22 May 2025 20:14:49 +0200
Subject: [PATCH 1/3] avformat/http: Handle IPv6 Zone ID in hostname
When using a literal IPv6 address as hostname, it can contain a Zone ID
especially in the case of link-local addresses. Sending this to the
server in the Host header is not useful to the server and in some cases
servers refuse such requests.
To prevent any such issues, strip the Zone ID from the address if it's
an IPv6 address. This also removes it for the Cookies lookup.
Based on a patch by: Daniel N Pettersson <danielnp(a)axis.com>
(cherry picked from commit 5cb6d2221a6d4c07453b6c301ecfcaed48402680)
Signed-off-by: Marvin Scholz <epirat07(a)gmail.com>
---
libavformat/http.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/libavformat/http.c b/libavformat/http.c
index 0d4077512b..49d750b512 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -24,6 +24,7 @@
#include "config.h"
#include "config_components.h"
+#include <string.h>
#include <time.h>
#if CONFIG_ZLIB
#include <zlib.h>
@@ -214,7 +215,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
char *env_http_proxy, *env_no_proxy;
char *hashmark;
- char hostname[1024], hoststr[1024], proto[10];
+ char hostname[1024], hoststr[1024], proto[10], tmp_host[1024];
char auth[1024], proxyauth[1024] = "";
char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1];
char buf[1024], urlbuf[MAX_URL_SIZE];
@@ -224,7 +225,14 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
av_url_split(proto, sizeof(proto), auth, sizeof(auth),
hostname, sizeof(hostname), &port,
path1, sizeof(path1), s->location);
- ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
+
+ av_strlcpy(tmp_host, hostname, sizeof(tmp_host));
+ // In case of an IPv6 address, we need to strip the Zone ID,
+ // if any. We do it at the first % sign, as percent encoding
+ // can be used in the Zone ID itself.
+ if (strchr(tmp_host, ':'))
+ tmp_host[strcspn(tmp_host, "%")] = '\0';
+ ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, tmp_host, port, NULL);
env_http_proxy = getenv_utf8("http_proxy");
proxy_path = s->http_proxy ? s->http_proxy : env_http_proxy;
--
2.49.1
From 624219121ea6cc21cfb2ca0b377b71642c14ff52 Mon Sep 17 00:00:00 2001
From: Marvin Scholz <epirat07(a)gmail.com>
Date: Fri, 22 Aug 2025 16:50:34 +0200
Subject: [PATCH 2/3] avformat/rtsp: do not log invalid values
When reading fails the first time, ch would be uninitialized and
printed in the log message. Instead check for an error early and
log it properly.
(cherry picked from commit 2ed47ab72509bbee60288d245a0aebb7eb05e41a)
Signed-off-by: Marvin Scholz <epirat07(a)gmail.com>
---
libavformat/rtsp.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 10355b89b8..13507d1858 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1239,9 +1239,12 @@ start:
q = buf;
for (;;) {
ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
+ if (ret != 1) {
+ ret = (ret < 0) ? ret : AVERROR(EIO);
+ av_log(s, AV_LOG_WARNING, "Failed reading RTSP data: %s\n", av_err2str(ret));
+ return ret;
+ }
av_log(s, AV_LOG_TRACE, "ret=%d c=%02x [%c]\n", ret, ch, ch);
- if (ret != 1)
- return ret < 0 ? ret : AVERROR(EIO);
if (ch == '\n')
break;
if (ch == '$' && q == buf) {
--
2.49.1
From aab883b4959b4ffee7a9edc7cf742863ce63f422 Mon Sep 17 00:00:00 2001
From: Marvin Scholz <epirat07(a)gmail.com>
Date: Fri, 22 Aug 2025 21:41:26 +0200
Subject: [PATCH 3/3] avformat/rtsp: fix leading space in RTSP reason
When parsing the RTSP message reason, the whole remainder
after parsing the status code was used, which would lead to
a leading space in the parsed reason string.
(cherry picked from commit e63e040f0cef2d6af2fb57aefa6250fc450fa049)
Signed-off-by: Marvin Scholz <epirat07(a)gmail.com>
---
libavformat/rtsp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 13507d1858..d601d63a89 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1274,6 +1274,7 @@ start:
if (!strncmp(buf1, "RTSP/", 5)) {
get_word(buf1, sizeof(buf1), &p);
reply->status_code = atoi(buf1);
+ p += strspn(p, SPACE_CHARS);
av_strlcpy(reply->reason, p, sizeof(reply->reason));
} else {
av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method
--
2.49.1
1
0
PR #20634 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20634
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20634.patch
From f2717889b4bff014ad8d00a98dc94761ed56c325 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
Date: Wed, 1 Oct 2025 07:56:49 +0200
Subject: [PATCH 1/2] avfilter/blend_modes: Use stride in bytes
The blend functions currently convert strides from bytes to elements
of the type by using the stride /= sizeof(pixel) idiom. Yet this has
several drawbacks:
1. It invokes undefined behavior that happens to work when stride is
negative: size_t is typically the unsigned type of ptrdiff_t and
therefore the division will be performed as size_t, i.e. use logical
right shifts, making stride very big when sizeof(pixel) is > 1. This
works, because pointer to pixel for accesses entails an implicit
factor of sizeof(pixel) so that everything is correct modulo SIZE_MAX.
Yet this is UB and UBSan complains about it.
2. It makes the compiler emit actual shifts/ands to discard the low bits
shifted away.
3. There may be systems where alignof(uint16_t) or alignof(float) is
strictly smaller than their sizeof, so that the stride (in bytes) is
not guaranteed to be multiple of these sizeofs. In this case, dividing
by sizeof(pixel) is simply wrong.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
---
libavfilter/blend_modes.c | 16 ++++++----------
libavfilter/vf_blend_init.h | 16 ++++++----------
2 files changed, 12 insertions(+), 20 deletions(-)
diff --git a/libavfilter/blend_modes.c b/libavfilter/blend_modes.c
index 9b1e78b146..35e365996c 100644
--- a/libavfilter/blend_modes.c
+++ b/libavfilter/blend_modes.c
@@ -92,22 +92,18 @@ static void fn0(NAME)(const uint8_t *_top, ptrdiff_t top_linesize, \
ptrdiff_t width, ptrdiff_t height, \
FilterParams *param, SliceParams *sliceparam) \
{ \
- const PIXEL *top = (const PIXEL *)_top; \
- const PIXEL *bottom = (const PIXEL *)_bottom; \
- PIXEL *dst = (PIXEL *)_dst; \
const float opacity = param->opacity; \
\
- dst_linesize /= sizeof(PIXEL); \
- top_linesize /= sizeof(PIXEL); \
- bottom_linesize /= sizeof(PIXEL); \
- \
for (int i = 0; i < height; i++) { \
+ const PIXEL *top = (const PIXEL *)_top; \
+ const PIXEL *bottom = (const PIXEL *)_bottom; \
+ PIXEL *dst = (PIXEL *)_dst; \
for (int j = 0; j < width; j++) { \
dst[j] = top[j] + ((EXPR)-top[j]) * opacity; \
} \
- dst += dst_linesize; \
- top += top_linesize; \
- bottom += bottom_linesize; \
+ _dst += dst_linesize; \
+ _top += top_linesize; \
+ _bottom += bottom_linesize; \
} \
}
diff --git a/libavfilter/vf_blend_init.h b/libavfilter/vf_blend_init.h
index 98d440fe67..7f66796e3e 100644
--- a/libavfilter/vf_blend_init.h
+++ b/libavfilter/vf_blend_init.h
@@ -82,22 +82,18 @@ static void blend_normal_##name(const uint8_t *_top, ptrdiff_t top_linesize,
ptrdiff_t width, ptrdiff_t height, \
FilterParams *param, SliceParams *sliceparam) \
{ \
- const type *top = (const type*)_top; \
- const type *bottom = (const type*)_bottom; \
- type *dst = (type*)_dst; \
const float opacity = param->opacity; \
\
- dst_linesize /= sizeof(type); \
- top_linesize /= sizeof(type); \
- bottom_linesize /= sizeof(type); \
- \
for (int i = 0; i < height; i++) { \
+ const type *top = (const type*)_top; \
+ const type *bottom = (const type*)_bottom; \
+ type *dst = (type*)_dst; \
for (int j = 0; j < width; j++) { \
dst[j] = top[j] * opacity + bottom[j] * (1.f - opacity); \
} \
- dst += dst_linesize; \
- top += top_linesize; \
- bottom += bottom_linesize; \
+ _dst += dst_linesize; \
+ _top += top_linesize; \
+ _bottom += bottom_linesize; \
} \
}
--
2.49.1
From 5c4166f5a2def849a19d698d463af5f8a403f822 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
Date: Wed, 1 Oct 2025 08:27:14 +0200
Subject: [PATCH 2/2] avfilter/blend_modes: Don't build duplicate functions
Some of the blend mode functions only depend on the underlying type
and therefore need only one version for 9, 10, 12, 14, 16 bits.
This saved 35104B with GCC and 26880B with Clang.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt(a)outlook.com>
---
libavfilter/blend_modes.c | 29 +++++++++++++++++++----------
libavfilter/vf_blend_init.h | 20 ++++++++++----------
2 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/libavfilter/blend_modes.c b/libavfilter/blend_modes.c
index 35e365996c..fff9864a04 100644
--- a/libavfilter/blend_modes.c
+++ b/libavfilter/blend_modes.c
@@ -34,16 +34,21 @@
#define MAX 255
#define HALF 128
#define CLIP(x) (av_clip_uint8(x))
+#define BUILD_TYPE_SPECIFIC_FUNCS
#elif DEPTH == 32
#define PIXEL float
#define MAX 1.f
#define HALF 0.5f
#define CLIP(x) (x)
+#define BUILD_TYPE_SPECIFIC_FUNCS
#else
#define PIXEL uint16_t
#define MAX ((1 << DEPTH) - 1)
#define HALF (1 << (DEPTH - 1))
#define CLIP(x) ((int)av_clip_uintp2(x, DEPTH))
+#if DEPTH == 16
+#define BUILD_TYPE_SPECIFIC_FUNCS
+#endif
#endif
#undef MULTIPLY
@@ -109,13 +114,10 @@ static void fn0(NAME)(const uint8_t *_top, ptrdiff_t top_linesize, \
fn(addition, FFMIN(MAX, A + B))
fn(grainmerge, CLIP(A + B - HALF))
-fn(average, (A + B) / 2)
-fn(subtract, FFMAX(0, A - B))
fn(multiply, MULTIPLY(1, A, B))
fn(multiply128,CLIP((A - HALF) * B / MDIV + HALF))
fn(negation, MAX - FFABS(MAX - A - B))
fn(extremity, FFABS(MAX - A - B))
-fn(difference, FFABS(A - B))
fn(grainextract, CLIP(HALF + A - B))
fn(screen, SCREEN(1, A, B))
fn(overlay, (A < HALF) ? MULTIPLY(2, A, B) : SCREEN(2, A, B))
@@ -123,8 +125,6 @@ fn(hardlight, (B < HALF) ? MULTIPLY(2, B, A) : SCREEN(2, B, A))
fn(hardmix, (A < (MAX - B)) ? 0: MAX)
fn(heat, (A == 0) ? 0 : MAX - FFMIN(((MAX - B) * (MAX - B)) / A, MAX))
fn(freeze, (B == 0) ? 0 : MAX - FFMIN(((MAX - A) * (MAX - A)) / B, MAX))
-fn(darken, FFMIN(A, B))
-fn(lighten, FFMAX(A, B))
fn(divide, CLIP(B == 0 ? MAX : MAX * A / B))
fn(dodge, DODGE(A, B))
fn(burn, BURN(A, B))
@@ -134,15 +134,24 @@ fn(pinlight, (B < HALF) ? FFMIN(A, 2 * B) : FFMAX(A, 2 * (B - HALF)))
fn(phoenix, FFMIN(A, B) - FFMAX(A, B) + MAX)
fn(reflect, (B == MAX) ? B : FFMIN(MAX, (A * A / (MAX - B))))
fn(glow, (A == MAX) ? A : FFMIN(MAX, (B * B / (MAX - A))))
-fn(and, INT2FLOAT(FLOAT2INT(A) & FLOAT2INT(B)))
-fn(or, INT2FLOAT(FLOAT2INT(A) | FLOAT2INT(B)))
-fn(xor, INT2FLOAT(FLOAT2INT(A) ^ FLOAT2INT(B)))
fn(vividlight, (A < HALF) ? BURN(2 * A, B) : DODGE(2 * (A - HALF), B))
fn(linearlight,CLIP((B < HALF) ? B + 2 * A - MAX : B + 2 * (A - HALF)))
fn(softdifference,CLIP((A > B) ? (B == MAX) ? 0 : (A - B) * MAX / (MAX - B) : (B == 0) ? 0 : (B - A) * MAX / B))
-fn(geometric, GEOMETRIC(A, B))
-fn(harmonic, A == 0 && B == 0 ? 0 : 2LL * A * B / (A + B))
fn(bleach, (MAX - B) + (MAX - A) - MAX)
fn(stain, 2 * MAX - A - B)
fn(interpolate,LRINTF(MAX * (2 - cosf(A * M_PI / MAX) - cosf(B * M_PI / MAX)) * 0.25f))
fn(hardoverlay,A == MAX ? MAX : FFMIN(MAX, MAX * B / (2 * MAX - 2 * A) * (A > HALF) + 2 * A * B / MAX * (A <= HALF)))
+
+#ifdef BUILD_TYPE_SPECIFIC_FUNCS
+fn(average, (A + B) / 2)
+fn(subtract, FFMAX(0, A - B))
+fn(difference, FFABS(A - B))
+fn(darken, FFMIN(A, B))
+fn(lighten, FFMAX(A, B))
+fn(and, INT2FLOAT(FLOAT2INT(A) & FLOAT2INT(B)))
+fn(or, INT2FLOAT(FLOAT2INT(A) | FLOAT2INT(B)))
+fn(xor, INT2FLOAT(FLOAT2INT(A) ^ FLOAT2INT(B)))
+fn(geometric, GEOMETRIC(A, B))
+fn(harmonic, A == 0 && B == 0 ? 0 : 2LL * A * B / (A + B))
+#undef BUILD_TYPE_SPECIFIC_FUNCS
+#endif
\ No newline at end of file
diff --git a/libavfilter/vf_blend_init.h b/libavfilter/vf_blend_init.h
index 7f66796e3e..297ca0514f 100644
--- a/libavfilter/vf_blend_init.h
+++ b/libavfilter/vf_blend_init.h
@@ -107,11 +107,11 @@ static av_cold void init_blend_func_##depth##_##nbits##bit(FilterParams *param)
switch (param->mode) { \
case BLEND_ADDITION: param->blend = blend_addition_##depth##bit; break; \
case BLEND_GRAINMERGE: param->blend = blend_grainmerge_##depth##bit; break; \
- case BLEND_AND: param->blend = blend_and_##depth##bit; break; \
- case BLEND_AVERAGE: param->blend = blend_average_##depth##bit; break; \
+ case BLEND_AND: param->blend = blend_and_##nbits##bit; break; \
+ case BLEND_AVERAGE: param->blend = blend_average_##nbits##bit; break; \
case BLEND_BURN: param->blend = blend_burn_##depth##bit; break; \
- case BLEND_DARKEN: param->blend = blend_darken_##depth##bit; break; \
- case BLEND_DIFFERENCE: param->blend = blend_difference_##depth##bit; break; \
+ case BLEND_DARKEN: param->blend = blend_darken_##nbits##bit; break; \
+ case BLEND_DIFFERENCE: param->blend = blend_difference_##nbits##bit; break; \
case BLEND_GRAINEXTRACT: param->blend = blend_grainextract_##depth##bit; break; \
case BLEND_DIVIDE: param->blend = blend_divide_##depth##bit; break; \
case BLEND_DODGE: param->blend = blend_dodge_##depth##bit; break; \
@@ -122,25 +122,25 @@ static av_cold void init_blend_func_##depth##_##nbits##bit(FilterParams *param)
case BLEND_HARDLIGHT: param->blend = blend_hardlight_##depth##bit; break; \
case BLEND_HARDMIX: param->blend = blend_hardmix_##depth##bit; break; \
case BLEND_HEAT: param->blend = blend_heat_##depth##bit; break; \
- case BLEND_LIGHTEN: param->blend = blend_lighten_##depth##bit; break; \
+ case BLEND_LIGHTEN: param->blend = blend_lighten_##nbits##bit; break; \
case BLEND_LINEARLIGHT: param->blend = blend_linearlight_##depth##bit; break; \
case BLEND_MULTIPLY: param->blend = blend_multiply_##depth##bit; break; \
case BLEND_MULTIPLY128: param->blend = blend_multiply128_##depth##bit; break; \
case BLEND_NEGATION: param->blend = blend_negation_##depth##bit; break; \
case BLEND_NORMAL: param->blend = blend_normal_##nbits##bit; break; \
- case BLEND_OR: param->blend = blend_or_##depth##bit; break; \
+ case BLEND_OR: param->blend = blend_or_##nbits##bit; break; \
case BLEND_OVERLAY: param->blend = blend_overlay_##depth##bit; break; \
case BLEND_PHOENIX: param->blend = blend_phoenix_##depth##bit; break; \
case BLEND_PINLIGHT: param->blend = blend_pinlight_##depth##bit; break; \
case BLEND_REFLECT: param->blend = blend_reflect_##depth##bit; break; \
case BLEND_SCREEN: param->blend = blend_screen_##depth##bit; break; \
case BLEND_SOFTLIGHT: param->blend = blend_softlight_##depth##bit; break; \
- case BLEND_SUBTRACT: param->blend = blend_subtract_##depth##bit; break; \
+ case BLEND_SUBTRACT: param->blend = blend_subtract_##nbits##bit; break; \
case BLEND_VIVIDLIGHT: param->blend = blend_vividlight_##depth##bit; break; \
- case BLEND_XOR: param->blend = blend_xor_##depth##bit; break; \
+ case BLEND_XOR: param->blend = blend_xor_##nbits##bit; break; \
case BLEND_SOFTDIFFERENCE:param->blend=blend_softdifference_##depth##bit;break; \
- case BLEND_GEOMETRIC: param->blend = blend_geometric_##depth##bit; break; \
- case BLEND_HARMONIC: param->blend = blend_harmonic_##depth##bit; break; \
+ case BLEND_GEOMETRIC: param->blend = blend_geometric_##nbits##bit; break; \
+ case BLEND_HARMONIC: param->blend = blend_harmonic_##nbits##bit; break; \
case BLEND_BLEACH: param->blend = blend_bleach_##depth##bit; break; \
case BLEND_STAIN: param->blend = blend_stain_##depth##bit; break; \
case BLEND_INTERPOLATE: param->blend = blend_interpolate_##depth##bit; break; \
--
2.49.1
1
0