| @@ -2434,6 +2434,30 @@ static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 2433 unmodified lines |
| 2434 | return 0; | 2434 | return 0; |
| 2435 | } | 2435 | } |
| 2436 | | 2436 | |
| | 2437 | static int mov_read_sbas(MOVContext* c, AVIOContext* pb, MOVAtom atom) |
| | 2438 | { |
| | 2439 | AVStream* st; |
| | 2440 | MOVStreamContext* sc; |
| | 2441 | |
| | 2442 | if (c->fc->nb_streams < 1) |
| | 2443 | return 0; |
| | 2444 | |
| | 2445 | /* For SBAS this should be fine - though beware if someone implements a |
| | 2446 | * tref atom processor that doesn't drop down to default then this may |
| | 2447 | * be lost. */ |
| | 2448 | if (atom.size > 4) { |
| | 2449 | av_log(c->fc, AV_LOG_ERROR, "Only a single tref of type sbas is supported\n"); |
| | 2450 | return AVERROR_PATCHWELCOME; |
| | 2451 | } |
| | 2452 | |
| | 2453 | st = c->fc->streams[c->fc->nb_streams - 1]; |
| | 2454 | sc = st->priv_data; |
| | 2455 | sc->tref_id = avio_rb32(pb); |
| | 2456 | sc->tref_flags |= MOV_TREF_FLAG_ENHANCEMENT; |
| | 2457 | |
| | 2458 | return 0; |
| | 2459 | } |
| | 2460 | |
| 2437 | /** | 2461 | /** |
| 2438 | * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself, | 2462 | * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself, |
| 2439 | * but can have extradata appended at the end after the 40 bytes belonging | 2463 | * but can have extradata appended at the end after the 40 bytes belonging |
| @@ -4995,6 +5019,8 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 2555 unmodified lines |
| 4995 | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; | 5019 | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; |
| 4996 | sc->ffindex = st->index; | 5020 | sc->ffindex = st->index; |
| 4997 | c->trak_index = st->index; | 5021 | c->trak_index = st->index; |
| | 5022 | sc->tref_flags = 0; |
| | 5023 | sc->tref_id = -1; |
| 4998 | sc->refcount = 1; | 5024 | sc->refcount = 1; |
| 4999 | | 5025 | |
| 5000 | if ((ret = mov_read_default(c, pb, atom)) < 0) | 5026 | if ((ret = mov_read_default(c, pb, atom)) < 0) |
| @@ -9052,6 +9078,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { · 4051 unmodified lines |
| 9052 | { MKTAG('a','v','c','C'), mov_read_glbl }, | 9078 | { MKTAG('a','v','c','C'), mov_read_glbl }, |
| 9053 | { MKTAG('p','a','s','p'), mov_read_pasp }, | 9079 | { MKTAG('p','a','s','p'), mov_read_pasp }, |
| 9054 | { MKTAG('c','l','a','p'), mov_read_clap }, | 9080 | { MKTAG('c','l','a','p'), mov_read_clap }, |
| | 9081 | { MKTAG('s','b','a','s'), mov_read_sbas }, |
| 9055 | { MKTAG('s','i','d','x'), mov_read_sidx }, | 9082 | { MKTAG('s','i','d','x'), mov_read_sidx }, |
| 9056 | { MKTAG('s','t','b','l'), mov_read_default }, | 9083 | { MKTAG('s','t','b','l'), mov_read_default }, |
| 9057 | { MKTAG('s','t','c','o'), mov_read_stco }, | 9084 | { MKTAG('s','t','c','o'), mov_read_stco }, |
| @@ -9132,6 +9159,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { · 74 unmodified lines |
| 9132 | { MKTAG('i','i','n','f'), mov_read_iinf }, | 9159 | { MKTAG('i','i','n','f'), mov_read_iinf }, |
| 9133 | { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */ | 9160 | { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */ |
| 9134 | { MKTAG('l','h','v','C'), mov_read_lhvc }, | 9161 | { MKTAG('l','h','v','C'), mov_read_lhvc }, |
| | 9162 | { MKTAG('l','v','c','C'), mov_read_glbl }, |
| 9135 | #if CONFIG_IAMFDEC | 9163 | #if CONFIG_IAMFDEC |
| 9136 | { MKTAG('i','a','c','b'), mov_read_iacb }, | 9164 | { MKTAG('i','a','c','b'), mov_read_iacb }, |
| 9137 | #endif | 9165 | #endif |
| @@ -10029,6 +10057,21 @@ static int mov_parse_tiles(AVFormatContext *s) · 891 unmodified lines |
| 10029 | return 0; | 10057 | return 0; |
| 10030 | } | 10058 | } |
| 10031 | | 10059 | |
| | 10060 | static AVStream *mov_find_reference_track(AVFormatContext *s, AVStream *st, |
| | 10061 | int first_index) |
| | 10062 | { |
| | 10063 | MOVStreamContext *sc = st->priv_data; |
| | 10064 | |
| | 10065 | if (sc->tref_id < 0) |
| | 10066 | return NULL; |
| | 10067 | |
| | 10068 | for (int i = first_index; i < s->nb_streams; i++) |
| | 10069 | if (s->streams[i]->id == sc->tref_id) |
| | 10070 | return s->streams[i]; |
| | 10071 | |
| | 10072 | return NULL; |
| | 10073 | } |
| | 10074 | |
| 10032 | static int mov_read_header(AVFormatContext *s) | 10075 | static int mov_read_header(AVFormatContext *s) |
| 10033 | { | 10076 | { |
| 10034 | MOVContext *mov = s->priv_data; | 10077 | MOVContext *mov = s->priv_data; |
| @@ -10154,6 +10197,50 @@ static int mov_read_header(AVFormatContext *s) · 119 unmodified lines |
| 10154 | } | 10197 | } |
| 10155 | export_orphan_timecode(s); | 10198 | export_orphan_timecode(s); |
| 10156 | | 10199 | |
| | 10200 | /* Create LCEVC stream groups. */ |
| | 10201 | for (i = 0; i < s->nb_streams; i++) { |
| | 10202 | AVStreamGroup *stg; |
| | 10203 | AVStream *st = s->streams[i]; |
| | 10204 | AVStream *st_base; |
| | 10205 | MOVStreamContext *sc = st->priv_data; |
| | 10206 | |
| | 10207 | /* Find an enhancement stream. */ |
| | 10208 | if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC || |
| | 10209 | !(sc->tref_flags & MOV_TREF_FLAG_ENHANCEMENT)) |
| | 10210 | continue; |
| | 10211 | |
| | 10212 | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; |
| | 10213 | |
| | 10214 | stg = avformat_stream_group_create(s, AV_STREAM_GROUP_PARAMS_LCEVC, NULL); |
| | 10215 | if (!stg) |
| | 10216 | return AVERROR(ENOMEM); |
| | 10217 | |
| | 10218 | stg->id = st->id; |
| | 10219 | stg->params.lcevc->width = st->codecpar->width; |
| | 10220 | stg->params.lcevc->height = st->codecpar->height; |
| | 10221 | st->codecpar->width = 0; |
| | 10222 | st->codecpar->height = 0; |
| | 10223 | |
| | 10224 | j = 0; |
| | 10225 | while (st_base = mov_find_reference_track(s, st, j)) { |
| | 10226 | err = avformat_stream_group_add_stream(stg, st_base); |
| | 10227 | if (err < 0) |
| | 10228 | return err; |
| | 10229 | |
| | 10230 | j = st_base->index + 1; |
| | 10231 | } |
| | 10232 | if (!j) { |
| | 10233 | av_log(s, AV_LOG_ERROR, "Failed to find base stream for enhancement stream\n"); |
| | 10234 | return AVERROR_INVALIDDATA; |
| | 10235 | } |
| | 10236 | |
| | 10237 | err = avformat_stream_group_add_stream(stg, st); |
| | 10238 | if (err < 0) |
| | 10239 | return err; |
| | 10240 | |
| | 10241 | stg->params.lcevc->lcevc_index = stg->nb_streams; |
| | 10242 | } |
| | 10243 | |
| 10157 | for (i = 0; i < s->nb_streams; i++) { | 10244 | for (i = 0; i < s->nb_streams; i++) { |
| 10158 | AVStream *st = s->streams[i]; | 10245 | AVStream *st = s->streams[i]; |
| 10159 | FFStream *const sti = ffstream(st); | 10246 | FFStream *const sti = ffstream(st); |