History

avformat/mov: add support for Immersive Audio Model and Formats in ISOBMFF

James Almer committed 2 years ago

Commit fe637161 parent 9ba327e3 files · +290 −17Browse files

Showing the changes to libavformat (2 of 3 files). Show all

Unified · Split

2 files
  1. libavformat/isom.h +3 −0
  2. libavformat/mov.c +286 −16
libavformat/isom.h+3−0
@@ -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 index172 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
269typedef struct HEIFItem {272typedef struct HEIFItem {
libavformat/mov.c+286−16
@@ -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
842static 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;
1013fail:
1014 av_dict_free(&metadata);
1015
1016 return ret;
1017}
1018
839static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)1019static 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 search1511 // If the stream is referenced by any sidx, limit the search
1332 // to fragments that referenced this stream in the sidx1512 // 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
4776static 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
4593static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)4820static 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 ID5768 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
8667static int mov_read_close(AVFormatContext *s)8913static 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 else9549 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)) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t