| @@ -58,6 +58,8 @@ · 57 unmodified lines |
| 58 | #include "internal.h" | 58 | #include "internal.h" |
| 59 | #include "avio_internal.h" | 59 | #include "avio_internal.h" |
| 60 | #include "demux.h" | 60 | #include "demux.h" |
| | 61 | #include "iamf_parse.h" |
| | 62 | #include "iamf_reader.h" |
| 61 | #include "dovi_isom.h" | 63 | #include "dovi_isom.h" |
| 62 | #include "riff.h" | 64 | #include "riff.h" |
| 63 | #include "isom.h" | 65 | #include "isom.h" |
| @@ -212,6 +214,7 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) · 148 unmodified lines |
| 212 | } | 214 | } |
| 213 | st = c->fc->streams[c->fc->nb_streams - 1]; | 215 | st = c->fc->streams[c->fc->nb_streams - 1]; |
| 214 | st->priv_data = sc; | 216 | st->priv_data = sc; |
| | 217 | sc->id = st->id; |
| 215 | sc->refcount = 1; | 218 | sc->refcount = 1; |
| 216 | | 219 | |
| 217 | if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) { | 220 | if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) { |
| @@ -836,6 +839,183 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 618 unmodified lines |
| 836 | return 0; | 839 | return 0; |
| 837 | } | 840 | } |
| 838 | | 841 | |
| | 842 | static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
| | 843 | { |
| | 844 | AVStream *st; |
| | 845 | MOVStreamContext *sc; |
| | 846 | FFIOContext b; |
| | 847 | AVIOContext *descriptor_pb; |
| | 848 | AVDictionary *metadata; |
| | 849 | IAMFContext *iamf; |
| | 850 | int64_t start_time, duration; |
| | 851 | unsigned descriptors_size; |
| | 852 | int nb_frames, disposition; |
| | 853 | int version, ret; |
| | 854 | |
| | 855 | if (atom.size < 5) |
| | 856 | return AVERROR_INVALIDDATA; |
| | 857 | |
| | 858 | if (c->fc->nb_streams < 1) |
| | 859 | return 0; |
| | 860 | |
| | 861 | version = avio_r8(pb); |
| | 862 | if (version != 1) { |
| | 863 | av_log(c->fc, AV_LOG_ERROR, "%s configurationVersion %d", |
| | 864 | version < 1 ? "invalid" : "unsupported", version); |
| | 865 | return AVERROR_INVALIDDATA; |
| | 866 | } |
| | 867 | |
| | 868 | descriptors_size = ffio_read_leb(pb); |
| | 869 | if (!descriptors_size || descriptors_size > INT_MAX) |
| | 870 | return AVERROR_INVALIDDATA; |
| | 871 | |
| | 872 | st = c->fc->streams[c->fc->nb_streams - 1]; |
| | 873 | sc = st->priv_data; |
| | 874 | |
| | 875 | sc->iamf = av_mallocz(sizeof(*sc->iamf)); |
| | 876 | if (!sc->iamf) |
| | 877 | return AVERROR(ENOMEM); |
| | 878 | iamf = &sc->iamf->iamf; |
| | 879 | |
| | 880 | st->codecpar->extradata = av_malloc(descriptors_size); |
| | 881 | if (!st->codecpar->extradata) |
| | 882 | return AVERROR(ENOMEM); |
| | 883 | st->codecpar->extradata_size = descriptors_size; |
| | 884 | |
| | 885 | ret = avio_read(pb, st->codecpar->extradata, descriptors_size); |
| | 886 | if (ret != descriptors_size) |
| | 887 | return ret < 0 ? ret : AVERROR_INVALIDDATA; |
| | 888 | |
| | 889 | ffio_init_read_context(&b, st->codecpar->extradata, descriptors_size); |
| | 890 | descriptor_pb = &b.pub; |
| | 891 | |
| | 892 | ret = ff_iamfdec_read_descriptors(iamf, descriptor_pb, descriptors_size, c->fc); |
| | 893 | if (ret < 0) |
| | 894 | return ret; |
| | 895 | |
| | 896 | metadata = st->metadata; |
| | 897 | st->metadata = NULL; |
| | 898 | start_time = st->start_time; |
| | 899 | nb_frames = st->nb_frames; |
| | 900 | duration = st->duration; |
| | 901 | disposition = st->disposition; |
| | 902 | |
| | 903 | for (int i = 0; i < iamf->nb_audio_elements; i++) { |
| | 904 | IAMFAudioElement *audio_element = iamf->audio_elements[i]; |
| | 905 | AVStreamGroup *stg = |
| | 906 | avformat_stream_group_create(c->fc, AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT, NULL); |
| | 907 | |
| | 908 | if (!stg) { |
| | 909 | ret = AVERROR(ENOMEM); |
| | 910 | goto fail; |
| | 911 | } |
| | 912 | |
| | 913 | av_iamf_audio_element_free(&stg->params.iamf_audio_element); |
| | 914 | stg->id = audio_element->audio_element_id; |
| | 915 | /* Transfer ownership */ |
| | 916 | stg->params.iamf_audio_element = audio_element->element; |
| | 917 | audio_element->element = NULL; |
| | 918 | |
| | 919 | for (int j = 0; j < audio_element->nb_substreams; j++) { |
| | 920 | IAMFSubStream *substream = &audio_element->substreams[j]; |
| | 921 | AVStream *stream; |
| | 922 | |
| | 923 | if (!i && !j) { |
| | 924 | if (audio_element->layers[0].substream_count != 1) |
| | 925 | st->disposition &= ~AV_DISPOSITION_DEFAULT; |
| | 926 | stream = st; |
| | 927 | } else |
| | 928 | stream = avformat_new_stream(c->fc, NULL); |
| | 929 | if (!stream) { |
| | 930 | ret = AVERROR(ENOMEM); |
| | 931 | goto fail; |
| | 932 | } |
| | 933 | |
| | 934 | stream->start_time = start_time; |
| | 935 | stream->nb_frames = nb_frames; |
| | 936 | stream->duration = duration; |
| | 937 | stream->disposition = disposition; |
| | 938 | if (stream != st) { |
| | 939 | stream->priv_data = sc; |
| | 940 | sc->refcount++; |
| | 941 | } |
| | 942 | |
| | 943 | if (i || j) { |
| | 944 | stream->disposition |= AV_DISPOSITION_DEPENDENT; |
| | 945 | if (audio_element->layers[0].substream_count == 1) |
| | 946 | stream->disposition &= ~AV_DISPOSITION_DEFAULT; |
| | 947 | } |
| | 948 | |
| | 949 | ret = avcodec_parameters_copy(stream->codecpar, substream->codecpar); |
| | 950 | if (ret < 0) |
| | 951 | goto fail; |
| | 952 | |
| | 953 | stream->id = substream->audio_substream_id; |
| | 954 | |
| | 955 | avpriv_set_pts_info(st, 64, 1, sc->time_scale); |
| | 956 | |
| | 957 | ret = avformat_stream_group_add_stream(stg, stream); |
| | 958 | if (ret < 0) |
| | 959 | goto fail; |
| | 960 | } |
| | 961 | |
| | 962 | ret = av_dict_copy(&stg->metadata, metadata, 0); |
| | 963 | if (ret < 0) |
| | 964 | goto fail; |
| | 965 | } |
| | 966 | |
| | 967 | for (int i = 0; i < iamf->nb_mix_presentations; i++) { |
| | 968 | IAMFMixPresentation *mix_presentation = iamf->mix_presentations[i]; |
| | 969 | const AVIAMFMixPresentation *mix = mix_presentation->cmix; |
| | 970 | AVStreamGroup *stg = |
| | 971 | avformat_stream_group_create(c->fc, AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION, NULL); |
| | 972 | |
| | 973 | if (!stg) { |
| | 974 | ret = AVERROR(ENOMEM); |
| | 975 | goto fail; |
| | 976 | } |
| | 977 | |
| | 978 | av_iamf_mix_presentation_free(&stg->params.iamf_mix_presentation); |
| | 979 | stg->id = mix_presentation->mix_presentation_id; |
| | 980 | /* Transfer ownership */ |
| | 981 | stg->params.iamf_mix_presentation = mix_presentation->mix; |
| | 982 | mix_presentation->mix = NULL; |
| | 983 | |
| | 984 | for (int j = 0; j < mix->nb_submixes; j++) { |
| | 985 | const AVIAMFSubmix *submix = mix->submixes[j]; |
| | 986 | |
| | 987 | for (int k = 0; k < submix->nb_elements; k++) { |
| | 988 | const AVIAMFSubmixElement *submix_element = submix->elements[k]; |
| | 989 | const AVStreamGroup *audio_element = NULL; |
| | 990 | |
| | 991 | for (int l = 0; l < c->fc->nb_stream_groups; l++) |
| | 992 | if (c->fc->stream_groups[l]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT && |
| | 993 | c->fc->stream_groups[l]->id == submix_element->audio_element_id) { |
| | 994 | audio_element = c->fc->stream_groups[l]; |
| | 995 | break; |
| | 996 | } |
| | 997 | av_assert0(audio_element); |
| | 998 | |
| | 999 | for (int l = 0; l < audio_element->nb_streams; l++) { |
| | 1000 | ret = avformat_stream_group_add_stream(stg, audio_element->streams[l]); |
| | 1001 | if (ret < 0 && ret != AVERROR(EEXIST)) |
| | 1002 | goto fail; |
| | 1003 | } |
| | 1004 | } |
| | 1005 | } |
| | 1006 | |
| | 1007 | ret = av_dict_copy(&stg->metadata, metadata, 0); |
| | 1008 | if (ret < 0) |
| | 1009 | goto fail; |
| | 1010 | } |
| | 1011 | |
| | 1012 | ret = 0; |
| | 1013 | fail: |
| | 1014 | av_dict_free(&metadata); |
| | 1015 | |
| | 1016 | return ret; |
| | 1017 | } |
| | 1018 | |
| 839 | static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) | 1019 | static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
| 840 | { | 1020 | { |
| 841 | AVStream *st; | 1021 | AVStream *st; |
| @@ -1331,7 +1511,7 @@ static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, · 489 unmodified lines |
| 1331 | // If the stream is referenced by any sidx, limit the search | 1511 | // If the stream is referenced by any sidx, limit the search |
| 1332 | // to fragments that referenced this stream in the sidx | 1512 | // to fragments that referenced this stream in the sidx |
| 1333 | if (sc->has_sidx) { | 1513 | if (sc->has_sidx) { |
| 1334 | frag_stream_info = get_frag_stream_info(frag_index, index, dst_st->id); | 1514 | frag_stream_info = get_frag_stream_info(frag_index, index, sc->id); |
| 1335 | if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) | 1515 | if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) |
| 1336 | return frag_stream_info->sidx_pts; | 1516 | return frag_stream_info->sidx_pts; |
| 1337 | if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE) | 1517 | if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE) |
| @@ -1342,9 +1522,11 @@ static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, · 4 unmodified lines |
| 1342 | for (i = 0; i < frag_index->item[index].nb_stream_info; i++) { | 1522 | for (i = 0; i < frag_index->item[index].nb_stream_info; i++) { |
| 1343 | AVStream *frag_stream = NULL; | 1523 | AVStream *frag_stream = NULL; |
| 1344 | frag_stream_info = &frag_index->item[index].stream_info[i]; | 1524 | frag_stream_info = &frag_index->item[index].stream_info[i]; |
| 1345 | for (j = 0; j < s->nb_streams; j++) | 1525 | for (j = 0; j < s->nb_streams; j++) { |
| 1346 | if (s->streams[j]->id == frag_stream_info->id) | 1526 | MOVStreamContext *sc2 = s->streams[j]->priv_data; |
| | 1527 | if (sc2->id == frag_stream_info->id) |
| 1347 | frag_stream = s->streams[j]; | 1528 | frag_stream = s->streams[j]; |
| | 1529 | } |
| 1348 | if (!frag_stream) { | 1530 | if (!frag_stream) { |
| 1349 | av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n"); | 1531 | av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n"); |
| 1350 | continue; | 1532 | continue; |
| @@ -1410,12 +1592,13 @@ static int update_frag_index(MOVContext *c, int64_t offset) · 59 unmodified lines |
| 1410 | | 1592 | |
| 1411 | for (i = 0; i < c->fc->nb_streams; i++) { | 1593 | for (i = 0; i < c->fc->nb_streams; i++) { |
| 1412 | // Avoid building frag index if streams lack track id. | 1594 | // Avoid building frag index if streams lack track id. |
| 1413 | if (c->fc->streams[i]->id < 0) { | 1595 | MOVStreamContext *sc = c->fc->streams[i]->priv_data; |
| | 1596 | if (sc->id < 0) { |
| 1414 | av_free(frag_stream_info); | 1597 | av_free(frag_stream_info); |
| 1415 | return AVERROR_INVALIDDATA; | 1598 | return AVERROR_INVALIDDATA; |
| 1416 | } | 1599 | } |
| 1417 | | 1600 | |
| 1418 | frag_stream_info[i].id = c->fc->streams[i]->id; | 1601 | frag_stream_info[i].id = sc->id; |
| 1419 | frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE; | 1602 | frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE; |
| 1420 | frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE; | 1603 | frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE; |
| 1421 | frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE; | 1604 | frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE; |
| @@ -3210,7 +3393,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 1788 unmodified lines |
| 3210 | "All samples in data stream index:id [%d:%d] have zero " | 3393 | "All samples in data stream index:id [%d:%d] have zero " |
| 3211 | "duration, stream set to be discarded by default. Override " | 3394 | "duration, stream set to be discarded by default. Override " |
| 3212 | "using AVStream->discard or -discard for ffmpeg command.\n", | 3395 | "using AVStream->discard or -discard for ffmpeg command.\n", |
| 3213 | st->index, st->id); | 3396 | st->index, sc->id); |
| 3214 | st->discard = AVDISCARD_ALL; | 3397 | st->discard = AVDISCARD_ALL; |
| 3215 | } | 3398 | } |
| 3216 | sc->track_end = duration; | 3399 | sc->track_end = duration; |
| @@ -4590,6 +4773,50 @@ static void fix_timescale(MOVContext *c, MOVStreamContext *sc) · 1373 unmodified lines |
| 4590 | } | 4773 | } |
| 4591 | } | 4774 | } |
| 4592 | | 4775 | |
| | 4776 | static int mov_update_iamf_streams(MOVContext *c, const AVStream *st) |
| | 4777 | { |
| | 4778 | const MOVStreamContext *sc = st->priv_data; |
| | 4779 | const IAMFContext *iamf = &sc->iamf->iamf; |
| | 4780 | |
| | 4781 | for (int i = 0; i < iamf->nb_audio_elements; i++) { |
| | 4782 | const AVStreamGroup *stg = NULL; |
| | 4783 | |
| | 4784 | for (int j = 0; j < c->fc->nb_stream_groups; j++) |
| | 4785 | if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id) |
| | 4786 | stg = c->fc->stream_groups[j]; |
| | 4787 | av_assert0(stg); |
| | 4788 | |
| | 4789 | for (int j = 0; j < stg->nb_streams; j++) { |
| | 4790 | const FFStream *sti = cffstream(st); |
| | 4791 | AVStream *out = stg->streams[j]; |
| | 4792 | FFStream *out_sti = ffstream(stg->streams[j]); |
| | 4793 | |
| | 4794 | out->codecpar->bit_rate = 0; |
| | 4795 | |
| | 4796 | if (out == st) |
| | 4797 | continue; |
| | 4798 | |
| | 4799 | out->time_base = st->time_base; |
| | 4800 | out->start_time = st->start_time; |
| | 4801 | out->duration = st->duration; |
| | 4802 | out->nb_frames = st->nb_frames; |
| | 4803 | out->discard = st->discard; |
| | 4804 | |
| | 4805 | av_assert0(!out_sti->index_entries); |
| | 4806 | out_sti->index_entries = av_malloc(sti->index_entries_allocated_size); |
| | 4807 | if (!out_sti->index_entries) |
| | 4808 | return AVERROR(ENOMEM); |
| | 4809 | |
| | 4810 | out_sti->index_entries_allocated_size = sti->index_entries_allocated_size; |
| | 4811 | out_sti->nb_index_entries = sti->nb_index_entries; |
| | 4812 | out_sti->skip_samples = sti->skip_samples; |
| | 4813 | memcpy(out_sti->index_entries, sti->index_entries, sti->index_entries_allocated_size); |
| | 4814 | } |
| | 4815 | } |
| | 4816 | |
| | 4817 | return 0; |
| | 4818 | } |
| | 4819 | |
| 4593 | static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) | 4820 | static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
| 4594 | { | 4821 | { |
| 4595 | AVStream *st; | 4822 | AVStream *st; |
| @@ -4670,6 +4897,12 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 74 unmodified lines |
| 4670 | | 4897 | |
| 4671 | mov_build_index(c, st); | 4898 | mov_build_index(c, st); |
| 4672 | | 4899 | |
| | 4900 | if (sc->iamf) { |
| | 4901 | ret = mov_update_iamf_streams(c, st); |
| | 4902 | if (ret < 0) |
| | 4903 | return ret; |
| | 4904 | } |
| | 4905 | |
| 4673 | if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { | 4906 | if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { |
| 4674 | MOVDref *dref = &sc->drefs[sc->dref_id - 1]; | 4907 | MOVDref *dref = &sc->drefs[sc->dref_id - 1]; |
| 4675 | if (c->enable_drefs) { | 4908 | if (c->enable_drefs) { |
| @@ -4902,6 +5135,7 @@ static int heif_add_stream(MOVContext *c, HEIFItem *item) · 226 unmodified lines |
| 4902 | st->priv_data = sc; | 5135 | st->priv_data = sc; |
| 4903 | st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; | 5136 | st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; |
| 4904 | st->codecpar->codec_id = mov_codec_id(st, item->type); | 5137 | st->codecpar->codec_id = mov_codec_id(st, item->type); |
| | 5138 | sc->id = st->id; |
| 4905 | sc->ffindex = st->index; | 5139 | sc->ffindex = st->index; |
| 4906 | c->trak_index = st->index; | 5140 | c->trak_index = st->index; |
| 4907 | st->avg_frame_rate.num = st->avg_frame_rate.den = 1; | 5141 | st->avg_frame_rate.num = st->avg_frame_rate.den = 1; |
| @@ -5000,6 +5234,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 92 unmodified lines |
| 5000 | avio_rb32(pb); /* modification time */ | 5234 | avio_rb32(pb); /* modification time */ |
| 5001 | } | 5235 | } |
| 5002 | st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/ | 5236 | st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/ |
| | 5237 | sc->id = st->id; |
| 5003 | avio_rb32(pb); /* reserved */ | 5238 | avio_rb32(pb); /* reserved */ |
| 5004 | | 5239 | |
| 5005 | /* highlevel (considering edits) duration in movie timebase */ | 5240 | /* highlevel (considering edits) duration in movie timebase */ |
| @@ -5174,7 +5409,8 @@ static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 168 unmodified lines |
| 5174 | int64_t base_media_decode_time; | 5409 | int64_t base_media_decode_time; |
| 5175 | | 5410 | |
| 5176 | for (i = 0; i < c->fc->nb_streams; i++) { | 5411 | for (i = 0; i < c->fc->nb_streams; i++) { |
| 5177 | if (c->fc->streams[i]->id == frag->track_id) { | 5412 | sc = c->fc->streams[i]->priv_data; |
| | 5413 | if (sc->id == frag->track_id) { |
| 5178 | st = c->fc->streams[i]; | 5414 | st = c->fc->streams[i]; |
| 5179 | break; | 5415 | break; |
| 5180 | } | 5416 | } |
| @@ -5227,7 +5463,8 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 46 unmodified lines |
| 5227 | } | 5463 | } |
| 5228 | | 5464 | |
| 5229 | for (i = 0; i < c->fc->nb_streams; i++) { | 5465 | for (i = 0; i < c->fc->nb_streams; i++) { |
| 5230 | if (c->fc->streams[i]->id == frag->track_id) { | 5466 | sc = c->fc->streams[i]->priv_data; |
| | 5467 | if (sc->id == frag->track_id) { |
| 5231 | st = c->fc->streams[i]; | 5468 | st = c->fc->streams[i]; |
| 5232 | sti = ffstream(st); | 5469 | sti = ffstream(st); |
| 5233 | break; | 5470 | break; |
| @@ -5530,7 +5767,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 296 unmodified lines |
| 5530 | | 5767 | |
| 5531 | track_id = avio_rb32(pb); // Reference ID | 5768 | track_id = avio_rb32(pb); // Reference ID |
| 5532 | for (i = 0; i < c->fc->nb_streams; i++) { | 5769 | for (i = 0; i < c->fc->nb_streams; i++) { |
| 5533 | if (c->fc->streams[i]->id == track_id) { | 5770 | sc = c->fc->streams[i]->priv_data; |
| | 5771 | if (sc->id == track_id) { |
| 5534 | st = c->fc->streams[i]; | 5772 | st = c->fc->streams[i]; |
| 5535 | break; | 5773 | break; |
| 5536 | } | 5774 | } |
| @@ -6447,7 +6685,8 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry · 910 unmodified lines |
| 6447 | frag_stream_info = get_current_frag_stream_info(&c->frag_index); | 6685 | frag_stream_info = get_current_frag_stream_info(&c->frag_index); |
| 6448 | if (frag_stream_info) { | 6686 | if (frag_stream_info) { |
| 6449 | for (i = 0; i < c->fc->nb_streams; i++) { | 6687 | for (i = 0; i < c->fc->nb_streams; i++) { |
| 6450 | if (c->fc->streams[i]->id == frag_stream_info->id) { | 6688 | *sc = c->fc->streams[i]->priv_data; |
| | 6689 | if ((*sc)->id == frag_stream_info->id) { |
| 6451 | st = c->fc->streams[i]; | 6690 | st = c->fc->streams[i]; |
| 6452 | break; | 6691 | break; |
| 6453 | } | 6692 | } |
| @@ -7391,7 +7630,7 @@ static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPa · 937 unmodified lines |
| 7391 | AVEncryptionInfo *encrypted_sample; | 7630 | AVEncryptionInfo *encrypted_sample; |
| 7392 | int encrypted_index, ret; | 7631 | int encrypted_index, ret; |
| 7393 | | 7632 | |
| 7394 | frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, st->id); | 7633 | frag_stream_info = get_frag_stream_info_from_pkt(&mov->frag_index, pkt, sc->id); |
| 7395 | encrypted_index = current_index; | 7634 | encrypted_index = current_index; |
| 7396 | encryption_index = NULL; | 7635 | encryption_index = NULL; |
| 7397 | if (frag_stream_info) { | 7636 | if (frag_stream_info) { |
| @@ -8194,6 +8433,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { · 796 unmodified lines |
| 8194 | { MKTAG('i','p','r','p'), mov_read_iprp }, | 8433 | { MKTAG('i','p','r','p'), mov_read_iprp }, |
| 8195 | { MKTAG('i','i','n','f'), mov_read_iinf }, | 8434 | { MKTAG('i','i','n','f'), mov_read_iinf }, |
| 8196 | { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */ | 8435 | { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */ |
| | 8436 | { MKTAG('i','a','c','b'), mov_read_iacb }, |
| 8197 | { 0, NULL } | 8437 | { 0, NULL } |
| 8198 | }; | 8438 | }; |
| 8199 | | 8439 | |
| @@ -8425,11 +8665,13 @@ static void mov_read_chapters(AVFormatContext *s) · 225 unmodified lines |
| 8425 | AVStream *st = NULL; | 8665 | AVStream *st = NULL; |
| 8426 | FFStream *sti = NULL; | 8666 | FFStream *sti = NULL; |
| 8427 | chapter_track = mov->chapter_tracks[j]; | 8667 | chapter_track = mov->chapter_tracks[j]; |
| 8428 | for (i = 0; i < s->nb_streams; i++) | 8668 | for (i = 0; i < s->nb_streams; i++) { |
| 8429 | if (s->streams[i]->id == chapter_track) { | 8669 | sc = mov->fc->streams[i]->priv_data; |
| | 8670 | if (sc->id == chapter_track) { |
| 8430 | st = s->streams[i]; | 8671 | st = s->streams[i]; |
| 8431 | break; | 8672 | break; |
| 8432 | } | 8673 | } |
| | 8674 | } |
| 8433 | if (!st) { | 8675 | if (!st) { |
| 8434 | av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); | 8676 | av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); |
| 8435 | continue; | 8677 | continue; |
| @@ -8662,6 +8904,10 @@ static void mov_free_stream_context(AVFormatContext *s, AVStream *st) · 226 unmodified lines |
| 8662 | av_freep(&sc->mastering); | 8904 | av_freep(&sc->mastering); |
| 8663 | av_freep(&sc->coll); | 8905 | av_freep(&sc->coll); |
| 8664 | av_freep(&sc->ambient); | 8906 | av_freep(&sc->ambient); |
| | 8907 | |
| | 8908 | if (sc->iamf) |
| | 8909 | ff_iamf_read_deinit(sc->iamf); |
| | 8910 | av_freep(&sc->iamf); |
| 8665 | } | 8911 | } |
| 8666 | | 8912 | |
| 8667 | static int mov_read_close(AVFormatContext *s) | 8913 | static int mov_read_close(AVFormatContext *s) |
| @@ -8916,9 +9162,11 @@ static int mov_read_header(AVFormatContext *s) · 248 unmodified lines |
| 8916 | AVDictionaryEntry *tcr; | 9162 | AVDictionaryEntry *tcr; |
| 8917 | int tmcd_st_id = -1; | 9163 | int tmcd_st_id = -1; |
| 8918 | | 9164 | |
| 8919 | for (j = 0; j < s->nb_streams; j++) | 9165 | for (j = 0; j < s->nb_streams; j++) { |
| 8920 | if (s->streams[j]->id == sc->timecode_track) | 9166 | MOVStreamContext *sc2 = s->streams[j]->priv_data; |
| | 9167 | if (sc2->id == sc->timecode_track) |
| 8921 | tmcd_st_id = j; | 9168 | tmcd_st_id = j; |
| | 9169 | } |
| 8922 | | 9170 | |
| 8923 | if (tmcd_st_id < 0 || tmcd_st_id == i) | 9171 | if (tmcd_st_id < 0 || tmcd_st_id == i) |
| 8924 | continue; | 9172 | continue; |
| @@ -9298,7 +9546,29 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) · 373 unmodified lines |
| 9298 | | 9546 | |
| 9299 | if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8) | 9547 | if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8) |
| 9300 | ret = get_eia608_packet(sc->pb, pkt, sample->size); | 9548 | ret = get_eia608_packet(sc->pb, pkt, sample->size); |
| 9301 | else | 9549 | else if (sc->iamf) { |
| | 9550 | int64_t pts, dts, pos, duration; |
| | 9551 | int flags, size = sample->size; |
| | 9552 | ret = mov_finalize_packet(s, st, sample, current_index, pkt); |
| | 9553 | pts = pkt->pts; dts = pkt->dts; |
| | 9554 | pos = pkt->pos; flags = pkt->flags; |
| | 9555 | duration = pkt->duration; |
| | 9556 | while (!ret && size > 0) { |
| | 9557 | ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt); |
| | 9558 | if (ret < 0) { |
| | 9559 | if (should_retry(sc->pb, ret)) |
| | 9560 | mov_current_sample_dec(sc); |
| | 9561 | return ret; |
| | 9562 | } |
| | 9563 | size -= ret; |
| | 9564 | pkt->pts = pts; pkt->dts = dts; |
| | 9565 | pkt->pos = pos; pkt->flags |= flags; |
| | 9566 | pkt->duration = duration; |
| | 9567 | ret = ff_buffer_packet(s, pkt); |
| | 9568 | } |
| | 9569 | if (!ret) |
| | 9570 | return FFERROR_REDO; |
| | 9571 | } else |
| 9302 | ret = av_get_packet(sc->pb, pkt, sample->size); | 9572 | ret = av_get_packet(sc->pb, pkt, sample->size); |
| 9303 | if (ret < 0) { | 9573 | if (ret < 0) { |
| 9304 | if (should_retry(sc->pb, ret)) { | 9574 | if (should_retry(sc->pb, ret)) { |