Showing the changes to libavformat (2 of 3 files). Show all
Unified · Split
| @@ -168,6 +168,7 @@ typedef struct MOVStreamContext { · 167 unmodified lines | |||
| 168 | AVIOContext *pb; | 168 | AVIOContext *pb; |
| 169 | int refcount; | 169 | int refcount; |
| 170 | int pb_is_copied; | 170 | int pb_is_copied; |
| 171 | int id; ///< AVStream id | ||
| 171 | int ffindex; ///< AVStream index | 172 | int ffindex; ///< AVStream index |
| 172 | int next_chunk; | 173 | int next_chunk; |
| 173 | unsigned int chunk_count; | 174 | unsigned int chunk_count; |
| @@ -264,6 +265,8 @@ typedef struct MOVStreamContext { · 90 unmodified lines | |||
| 264 | AVEncryptionInfo *default_encrypted_sample; | 265 | AVEncryptionInfo *default_encrypted_sample; |
| 265 | MOVEncryptionIndex *encryption_index; | 266 | MOVEncryptionIndex *encryption_index; |
| 266 | } cenc; | 267 | } cenc; |
| 268 | |||
| 269 | struct IAMFDemuxContext *iamf; | ||
| 267 | } MOVStreamContext; | 270 | } MOVStreamContext; |
| 268 | 271 | ||
| 269 | typedef struct HEIFItem { | 272 | typedef struct HEIFItem { |
| @@ -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)) { |