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@gmail.com>
(cherry picked from commit a8f2374507)
This commit is contained in:
James Almer
2024-12-20 12:57:48 -03:00
parent f1cbd81e9e
commit 3157e62866
7 changed files with 59 additions and 31 deletions

View File

@@ -30,10 +30,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);
@@ -44,7 +44,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;
@@ -58,7 +58,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;
@@ -276,7 +276,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;
@@ -306,7 +306,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;

View File

@@ -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);

View File

@@ -165,7 +165,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;

View File

@@ -267,6 +267,7 @@ typedef struct MOVStreamContext {
} cenc;
struct IAMFDemuxContext *iamf;
int iamf_stream_offset;
} MOVStreamContext;
typedef struct HEIFItem {

View File

@@ -9551,6 +9551,30 @@ static int mov_parse_tiles(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;
@@ -9812,6 +9836,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++)
@@ -10101,7 +10128,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);

View File

@@ -32,7 +32,7 @@
#include "version_major.h"
#define LIBAVFORMAT_VERSION_MINOR 1
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_MICRO 101
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \

View File

@@ -209,7 +209,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
@@ -231,7 +231,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=1
id=0x2
id=0xa
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -253,7 +253,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=2
id=0x3
id=0xb
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -275,7 +275,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=3
id=0x4
id=0xc
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -297,7 +297,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=4
id=0x5
id=0xd
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -319,7 +319,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=5
id=0x6
id=0xe
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -341,7 +341,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=6
id=0x7
id=0xf
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -459,7 +459,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
@@ -481,7 +481,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=1
id=0x2
id=0xa
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -503,7 +503,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=2
id=0x3
id=0xb
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -525,7 +525,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=3
id=0x4
id=0xc
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -547,7 +547,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=4
id=0x5
id=0xd
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -569,7 +569,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=5
id=0x6
id=0xe
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -591,7 +591,7 @@ DISPOSITION:still_image=0
[/STREAM]
[STREAM]
index=6
id=0x7
id=0xf
DISPOSITION:default=0
DISPOSITION:dub=0
DISPOSITION:original=0
@@ -614,31 +614,31 @@ DISPOSITION:still_image=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