[FFmpeg-cvslog] avformat/mov: add an offset to IAMF streams
James Almer
git at videolan.org
Sat Feb 8 00:44:44 EET 2025
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Fri Dec 20 12:57:48 2024 -0300| [a8f23745074acd8a1934e3653caebd5a0ba05c6f] | committer: James Almer
avformat/mov: add an offset to IAMF streams
Using audio_substream_id for AVStream ids is not ideal give that in containers
like mp4, the IAMF structure is opaque to the outside and other streams may
share such id values.
Signed-off-by: James Almer <jamrial at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a8f23745074acd8a1934e3653caebd5a0ba05c6f
---
libavformat/iamf_reader.c | 12 ++++----
libavformat/iamf_reader.h | 2 +-
libavformat/iamfdec.c | 2 +-
libavformat/isom.h | 1 +
libavformat/mov.c | 29 ++++++++++++++++++-
libavformat/version.h | 2 +-
tests/ref/fate/mov-mp4-iamf-7_1_4-video-last | 42 ++++++++++++++--------------
7 files changed, 59 insertions(+), 31 deletions(-)
diff --git a/libavformat/iamf_reader.c b/libavformat/iamf_reader.c
index d331e1315e..5cbe89ca68 100644
--- a/libavformat/iamf_reader.c
+++ b/libavformat/iamf_reader.c
@@ -31,10 +31,10 @@
#include "iamf_parse.h"
#include "iamf_reader.h"
-static AVStream *find_stream_by_id(AVFormatContext *s, int id)
+static AVStream *find_stream_by_id(AVFormatContext *s, int id, int stream_id_offset)
{
for (int i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->id == id)
+ if (s->streams[i]->id == id + stream_id_offset)
return s->streams[i];
av_log(s, AV_LOG_ERROR, "Invalid stream id %d\n", id);
@@ -45,7 +45,7 @@ static int audio_frame_obu(AVFormatContext *s, const IAMFDemuxContext *c,
AVIOContext *pb, AVPacket *pkt,
int len, enum IAMF_OBU_Type type,
unsigned skip_samples, unsigned discard_padding,
- int id_in_bitstream)
+ int stream_id_offset, int id_in_bitstream)
{
AVStream *st;
int ret, audio_substream_id;
@@ -59,7 +59,7 @@ static int audio_frame_obu(AVFormatContext *s, const IAMFDemuxContext *c,
} else
audio_substream_id = type - IAMF_OBU_IA_AUDIO_FRAME_ID0;
- st = find_stream_by_id(s, audio_substream_id);
+ st = find_stream_by_id(s, audio_substream_id, stream_id_offset);
if (!st)
return AVERROR_INVALIDDATA;
@@ -277,7 +277,7 @@ fail:
}
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c,
- AVIOContext *pb, int max_size, AVPacket *pkt)
+ AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt)
{
int read = 0;
@@ -308,7 +308,7 @@ int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c,
read += len;
if (type >= IAMF_OBU_IA_AUDIO_FRAME && type <= IAMF_OBU_IA_AUDIO_FRAME_ID17) {
ret = audio_frame_obu(s, c, pb, pkt, obu_size, type,
- skip_samples, discard_padding,
+ skip_samples, discard_padding, stream_id_offset,
type == IAMF_OBU_IA_AUDIO_FRAME);
if (ret < 0)
return ret;
diff --git a/libavformat/iamf_reader.h b/libavformat/iamf_reader.h
index ecb92d485a..279739cde9 100644
--- a/libavformat/iamf_reader.h
+++ b/libavformat/iamf_reader.h
@@ -42,7 +42,7 @@ typedef struct IAMFDemuxContext {
} IAMFDemuxContext;
int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c,
- AVIOContext *pb, int max_size, AVPacket *pkt);
+ AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt);
void ff_iamf_read_deinit(IAMFDemuxContext *c);
diff --git a/libavformat/iamfdec.c b/libavformat/iamfdec.c
index e1a913dd1c..0f273bdd43 100644
--- a/libavformat/iamfdec.c
+++ b/libavformat/iamfdec.c
@@ -187,7 +187,7 @@ static int iamf_read_packet(AVFormatContext *s, AVPacket *pkt)
IAMFDemuxContext *const c = s->priv_data;
int ret;
- ret = ff_iamf_read_packet(s, c, s->pb, INT_MAX, pkt);
+ ret = ff_iamf_read_packet(s, c, s->pb, INT_MAX, 0, pkt);
if (ret < 0)
return ret;
diff --git a/libavformat/isom.h b/libavformat/isom.h
index ccdead7192..10f882806e 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -283,6 +283,7 @@ typedef struct MOVStreamContext {
} cenc;
struct IAMFDemuxContext *iamf;
+ int iamf_stream_offset;
} MOVStreamContext;
typedef struct HEIFItem {
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 9a388bf723..61f3b4c6a2 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -10426,6 +10426,30 @@ static int mov_parse_lcevc_streams(AVFormatContext *s)
return 0;
}
+static void fix_stream_ids(AVFormatContext *s)
+{
+ int highest_id = 0;
+
+ for (int i = 0; i < s->nb_streams; i++) {
+ const AVStream *st = s->streams[i];
+ const MOVStreamContext *sc = st->priv_data;
+ if (!sc->iamf)
+ highest_id = FFMAX(highest_id, st->id);
+ }
+ highest_id += !highest_id;
+ for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) {
+ AVStreamGroup *stg = s->stream_groups[i];
+ if (stg->type != AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT)
+ continue;
+ for (int j = 0; j < stg->nb_streams; j++) {
+ AVStream *st = stg->streams[j];
+ MOVStreamContext *sc = st->priv_data;
+ st->id += highest_id;
+ sc->iamf_stream_offset = highest_id;
+ }
+ }
+}
+
static int mov_read_header(AVFormatContext *s)
{
MOVContext *mov = s->priv_data;
@@ -10649,6 +10673,9 @@ static int mov_read_header(AVFormatContext *s)
break;
}
}
+
+ fix_stream_ids(s);
+
ff_configure_buffers_for_index(s, AV_TIME_BASE);
for (i = 0; i < mov->frag_index.nb_items; i++)
@@ -10933,7 +10960,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
pos = pkt->pos; flags = pkt->flags;
duration = pkt->duration;
while (!ret && size > 0) {
- ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt);
+ ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt);
if (ret < 0) {
if (should_retry(sc->pb, ret))
mov_current_sample_dec(sc);
diff --git a/libavformat/version.h b/libavformat/version.h
index 067277b10f..6ffdf61b43 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
#include "version_major.h"
#define LIBAVFORMAT_VERSION_MINOR 9
-#define LIBAVFORMAT_VERSION_MICRO 106
+#define LIBAVFORMAT_VERSION_MICRO 107
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
diff --git a/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last b/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last
index 35e8b9b0ab..ede4a40025 100644
--- a/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last
+++ b/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last
@@ -210,7 +210,7 @@ TAG:handler_name=SoundHandler
TAG:vendor_id=[0][0][0][0]
[STREAM]
index=0
-id=0x1
+id=0x9
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -233,7 +233,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=1
-id=0x2
+id=0xa
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -256,7 +256,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=2
-id=0x3
+id=0xb
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -279,7 +279,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=3
-id=0x4
+id=0xc
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -302,7 +302,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=4
-id=0x5
+id=0xd
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -325,7 +325,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=5
-id=0x6
+id=0xe
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -348,7 +348,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=6
-id=0x7
+id=0xf
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -468,7 +468,7 @@ TAG:handler_name=SoundHandler
TAG:vendor_id=[0][0][0][0]
[STREAM]
index=0
-id=0x1
+id=0x9
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -491,7 +491,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=1
-id=0x2
+id=0xa
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -514,7 +514,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=2
-id=0x3
+id=0xb
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -537,7 +537,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=3
-id=0x4
+id=0xc
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -560,7 +560,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=4
-id=0x5
+id=0xd
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -583,7 +583,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=5
-id=0x6
+id=0xe
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -606,7 +606,7 @@ DISPOSITION:multilayer=0
[/STREAM]
[STREAM]
index=6
-id=0x7
+id=0xf
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -630,31 +630,31 @@ DISPOSITION:multilayer=0
[/STREAM_GROUP]
[STREAM]
index=0
-id=0x1
+id=0x9
[/STREAM]
[STREAM]
index=1
-id=0x2
+id=0xa
[/STREAM]
[STREAM]
index=2
-id=0x3
+id=0xb
[/STREAM]
[STREAM]
index=3
-id=0x4
+id=0xc
[/STREAM]
[STREAM]
index=4
-id=0x5
+id=0xd
[/STREAM]
[STREAM]
index=5
-id=0x6
+id=0xe
[/STREAM]
[STREAM]
index=6
-id=0x7
+id=0xf
[/STREAM]
[STREAM]
index=7
More information about the ffmpeg-cvslog
mailing list