心肌炎有什么症状和表现| pe什么材质| 痛风用什么消炎药最好| 鲶鱼效应是什么意思| 吃什么补血快| 女娲用什么补天| 生理期为什么会肚子疼| peek是什么材料| 甘草有什么功效| 负离子什么意思| 多巴胺是什么| 615是什么星座| 黑色代表什么| 人见人爱是什么意思| 靖国神社是什么| 乘风破浪是什么生肖| 测怀孕的试纸叫什么| 铁什么时候吃| pcp是什么意思| 射手属于什么象星座| 狗的胡须有什么用| 操姓氏读什么| 奶奶的妹妹叫什么| 贾乃亮演过什么电视剧| 喝什么养胃最好| 吃力不讨好是什么意思| 女人手脚发热吃什么药| 龙猫吃什么| 褪黑素有什么副作用| 补给是什么意思| 长期喝奶粉有什么好处| 转奶是什么意思| ft什么意思| 淋巴结肿大是什么原因引起的| 违和是什么意思| 日昳是什么意思| osprey是什么牌子| rh血型阴性是什么意思| 威五行属什么| 三个龙念什么| 什么是消炎药| 老年人吃饭老是噎着是什么原因| 间接胆红素偏高吃什么药| 阴道口瘙痒是什么原因| 晚上喝什么茶好| 阴吹是什么意思| 绿五行属什么| 三聚磷酸钠是什么东西| 女生自慰什么感觉| 地屈孕酮片什么时候吃| 吃什么容易长高| 疱疹是什么原因引起| 宫颈癌早期什么症状| 铁锈是什么颜色的| 便溏是什么意思| jk什么意思| 打车费计入什么科目| 胎心不稳定是什么原因| 生育保险是什么意思| 地中海贫血有什么影响| 孩子嗓子疼吃什么药| a型血的人容易得什么病| 生不逢时什么意思| 为什么医院不推荐钡餐检查| pv是什么材质| 男生生理期是什么表现| 双相情感障碍什么意思| 梦见小猫崽是什么意思| scr是什么意思| 场记是做什么的| 12岁属什么| 伤口不容易愈合是什么原因| 眼睛疲劳用什么眼药水好| 早上起床有眼屎是什么原因| 胃病忌什么| 双重所有格是什么意思| 鸢是什么意思| 三个大是什么字| 6月初三是什么日子| 为什么叫五七干校| 嘿咻是什么意思| 芝麻开花节节高是什么意思| 倒班什么意思| 闹心是什么原因导致的| 若叶青汁有什么功效| 南瓜什么季节成熟| 老鼠为什么不碰粘鼠板| s925银是什么意思| 谐星是什么意思| 颈椎退行性病变是什么意思| 日金念什么| 沙棘原浆有什么作用| 左脸上长痘痘是什么原因| cnv是什么意思| 豆工念什么| 白芷炖肉起什么作用| 猫有什么品种| 外耳道耵聍什么意思| 软饭是什么意思| ace什么意思| 午夜梦回是什么意思| 为什么医生不推荐特立帕肽呢| N医学上是什么意思| 走马观花是什么生肖| 复诊是什么意思| 重度脂肪肝吃什么药| qs认证是什么意思| 浮躁是什么意思| 白细胞高是什么原因引起的| 休克疗法是什么意思| 尿钙是什么意思| 苦丁茶有什么作用和功效| 儿童便秘吃什么最快排便| 洗澡用什么香皂好| 什么榴莲最好吃| 便秘是什么原因引起的| 属猴女和什么属相最配| 田童念什么| 电解水是什么水| 业障是什么意思| 高血压1级是什么意思| 鲁迅的真名叫什么| 做爱时间短吃什么药| 舌头两边疼是什么原因| 处女女和什么星座最配| 麝香是什么味道| 避孕药叫什么| 麦冬不能和什么一起吃| 做月子要注意什么| 果子狸携带什么病毒| 结膜水肿用什么眼药水| 心脏不好吃什么药最好| 梦见狮子是什么预兆| 儿童掉头发什么原因| 拉不出来屎是什么原因| 非洲人吃什么主食| 尿多是什么原因| 黄水疮是什么原因引起的| 左侧卵巢囊性回声是什么意思| 下身痒是什么原因| 肠炎吃什么药效果最好| 三氧化硫常温下是什么状态| 肝功能八项检查什么| advil是什么药| 7.12什么星座| ua是什么意思| 外阴白斑是什么引起的| 小肚子疼是什么情况| 中药一般什么时候喝最好| 怕热易出汗是什么原因| 眩晕症什么症状| 以至于是什么意思| 乙肝需要检查什么项目| 什么是夜盲症| 什么是腱鞘炎| napoleon是什么酒| 肝囊肿是什么| 担心是什么意思| 二氧化碳是什么意思| 长白毛是什么原因| 棕色短裤配什么颜色上衣| 一什么冰箱| 什么是普洱茶| 梦见打碎碗是什么预兆| 岗位性质指的是什么| 生日当天忌穿什么颜色| 市辖区是什么意思| 常喝三七粉有什么好处| 左甲状腺是什么病| 缝纫机油是什么油| 时间是什么| 罗马棉是什么面料| 孩子为什么不听话| 独立户口需要什么条件办理| 手胀是什么原因| 网球肘用什么方法能彻底治好呢| 什么的眼光| gr是什么元素| 术后吃什么| 维生素c阳性是什么意思| 随大流什么意思| 花木兰代表什么生肖| 1310是什么意思| 红花泡水喝有什么功效和作用| 油边是什么肉| 橙子什么季节成熟| 肌酐高吃什么药好| 胆结石吃什么药| 慰劳是什么意思| 什么是袖珍人| 蜂蜜的波美度是什么意思| 什么文什么字| 炖鸡肉放什么调料| 请多指教是什么意思| 地图舌吃什么药| 子宫切除后要注意什么| 固本培元是什么意思| 诸葛亮号什么| 孕妇胃疼吃什么药| 早上起床腰酸痛是什么原因| 黄痰黄鼻涕吃什么药| rv是什么品牌| 放下是什么意思| 胎儿宫内缺氧孕妇有什么症状| 50岁用什么牌子化妆品好| 什么叫安全期| 6月18号是什么日子| 身体怕热是什么原因| 拍黄瓜什么意思| 什么是科学| 气血不足吃什么好食补| 包虫病是什么病| 清明是什么季节| 肩胛骨麻麻的什么原因| 乳头瘤病毒是什么病| 腔梗是什么意思| 清五行属什么| 医保卡是什么样子的图| 维生素什么牌子好| 脱水是什么意思| 鼍是什么动物| 卫戍部队是什么意思| 为什么叫白俄罗斯| 什么是职业病| 年上年下是什么意思| 今天是什么节日吗| 什么是微量元素| 什么的毛主席| qt是什么| 常识是什么意思| 内化是什么意思| 516是什么意思| 莳花弄草是什么意思| 缠腰蛇是什么症状图片| 甲减是什么原因引起的| 3月28号是什么星座| 凤尾鱼为什么突然就死| 拔完罐需要注意什么| 乐极生悲是什么意思| 总放屁还特别臭是什么原因| 喝羊奶有什么好处| 觉是什么偏旁| clinic是什么意思| 天德是什么意思| 窝沟封闭是什么| dep是什么意思| 软下疳是什么症状| 早上5点是什么时辰| 风水轮流转什么意思| 大男子主义的男人喜欢什么样的女人| 血小板低什么症状| 心脑血管疾病吃什么药| 什么可以吃| 乔字五行属什么| 利率是什么| 回声结节什么意思| 宫颈管短是什么意思| 什么游戏最赚钱| 利口酒是什么酒| 中学为体西学为用是什么意思| 打粉是什么意思| 好运是什么生肖| 风情万种的意思是什么| 为什么会得白癜风| 百度
avformat/movenc: allow storing more than one extradata buffer per track
authorJames Almer <jamrial@gmail.com>
Sun, 27 Jul 2025 21:10:37 +0000 (18:10 -0300)
committerJames Almer <jamrial@gmail.com>
Wed, 30 Jul 2025 19:48:14 +0000 (16:48 -0300)
This is in preparation for a following change

Signed-off-by: James Almer <jamrial@gmail.com>
libavformat/movenc.c
libavformat/movenc.h

index bb0af118633a60d3e83533917e69750344ef221b..96fb31655d45735655a6ea59d8103afd5f0d3638 100644 (file)
@@ -654,8 +654,8 @@ static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
  */
 static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
 {
-    avio_write(pb, track->par->extradata, track->par->extradata_size);
-    return track->par->extradata_size;
+    avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
+    return track->extradata_size[track->last_stsd_index];
 }
 
 static int mov_write_enda_tag(AVIOContext *pb)
@@ -749,7 +749,8 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
 {
     struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
     int64_t pos = avio_tell(pb);
-    int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
+    int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
+                                    5 + track->extradata_size[track->last_stsd_index] : 0;
 
     avio_wb32(pb, 0); // size
     ffio_wfourcc(pb, "esds");
@@ -784,10 +785,11 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
     avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
     avio_wb32(pb, bit_rates.avg_bit_rate);
 
-    if (track->vos_len) {
+    if (track->extradata_size[track->last_stsd_index]) {
         // DecoderSpecific info descriptor
-        put_descr(pb, 0x05, track->vos_len);
-        avio_write(pb, track->vos_data, track->vos_len);
+        put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
+        avio_write(pb, track->extradata[track->last_stsd_index],
+                   track->extradata_size[track->last_stsd_index]);
     }
 
     // SL descriptor
@@ -844,13 +846,13 @@ static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb24(pb, 0); /* flags */
 
     /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
-    if (track->par->extradata_size != FLAC_STREAMINFO_SIZE)
+    if (track->extradata_size[track->last_stsd_index] != FLAC_STREAMINFO_SIZE)
         return AVERROR_INVALIDDATA;
 
     /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
     avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
-    avio_wb24(pb, track->par->extradata_size); /* Length */
-    avio_write(pb, track->par->extradata, track->par->extradata_size); /* BlockData[Length] */
+    avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
+    avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
 
     return update_size(pb, pos);
 }
@@ -862,28 +864,28 @@ static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "dOps");
     avio_w8(pb, 0); /* Version */
-    if (track->par->extradata_size < 19) {
+    if (track->extradata_size[track->last_stsd_index] < 19) {
         av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
         return AVERROR_INVALIDDATA;
     }
     /* extradata contains an Ogg OpusHead, other than byte-ordering and
        OpusHead's preceeding magic/version, OpusSpecificBox is currently
        identical. */
-    channels = AV_RB8(track->par->extradata + 9);
-    channel_map = AV_RB8(track->par->extradata + 18);
+    channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
+    channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
 
     avio_w8(pb, channels); /* OuputChannelCount */
-    avio_wb16(pb, AV_RL16(track->par->extradata + 10)); /* PreSkip */
-    avio_wb32(pb, AV_RL32(track->par->extradata + 12)); /* InputSampleRate */
-    avio_wb16(pb, AV_RL16(track->par->extradata + 16)); /* OutputGain */
+    avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
+    avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
+    avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
     avio_w8(pb, channel_map); /* ChannelMappingFamily */
     /* Write the rest of the header out without byte-swapping. */
     if (channel_map) {
-        if (track->par->extradata_size < 21 + channels) {
+        if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
             av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
             return AVERROR_INVALIDDATA;
         }
-        avio_write(pb, track->par->extradata + 19, 2 + channels); /* ChannelMappingTable */
+        avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
     }
 
     return update_size(pb, pos);
@@ -896,23 +898,23 @@ static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "dmlp");
 
-    if (track->vos_len < 20) {
+    if (track->extradata_size[track->last_stsd_index] < 20) {
         av_log(s, AV_LOG_ERROR,
                "Cannot write moov atom before TrueHD packets."
                " Set the delay_moov flag to fix this.\n");
         return AVERROR(EINVAL);
     }
 
-    length = (AV_RB16(track->vos_data) & 0xFFF) * 2;
-    if (length < 20 || length > track->vos_len)
+    length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
+    if (length < 20 || length > track->extradata_size[track->last_stsd_index])
         return AVERROR_INVALIDDATA;
 
     // Only TrueHD is supported
-    if (AV_RB32(track->vos_data + 4) != 0xF8726FBA)
+    if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
         return AVERROR_INVALIDDATA;
 
-    avio_wb32(pb, AV_RB32(track->vos_data + 8)); /* format_info */
-    avio_wb16(pb, AV_RB16(track->vos_data + 18) << 1); /* peak_data_rate */
+    avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
+    avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
     avio_wb32(pb, 0); /* reserved */
 
     return update_size(pb, pos);
@@ -1078,7 +1080,8 @@ static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
 {
     uint8_t *unescaped;
-    const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
+    const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
+                                        track->extradata_size[track->last_stsd_index];
     int unescaped_size, seq_found = 0;
     int level = 0, interlace = 0;
     int packet_seq   = track->vc1_info.packet_seq;
@@ -1095,10 +1098,10 @@ static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
                "dvc1 atom. Set the delay_moov flag to fix this.\n");
     }
 
-    unescaped = av_mallocz(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
+    unescaped = av_mallocz(track->extradata_size[track->last_stsd_index] + AV_INPUT_BUFFER_PADDING_SIZE);
     if (!unescaped)
         return AVERROR(ENOMEM);
-    start = find_next_marker(track->vos_data, end);
+    start = find_next_marker(track->extradata[track->last_stsd_index], end);
     for (next = start; next < end; start = next) {
         GetBitContext gb;
         int size;
@@ -1166,20 +1169,22 @@ static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
     if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
         return ret;
 
-    avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
+    avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
     ffio_wfourcc(pb, "dvc1");
     avio_write(pb, buf, sizeof(buf));
-    avio_write(pb, track->vos_data, track->vos_len);
+    avio_write(pb, track->extradata[track->last_stsd_index],
+               track->extradata_size[track->last_stsd_index]);
 
     return 0;
 }
 
 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
 {
-    avio_wb32(pb, track->vos_len + 8);
+    avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
     ffio_wfourcc(pb, "glbl");
-    avio_write(pb, track->vos_data, track->vos_len);
-    return 8 + track->vos_len;
+    avio_write(pb, track->extradata[track->last_stsd_index],
+               track->extradata_size[track->last_stsd_index]);
+    return 8 + track->extradata_size[track->last_stsd_index];
 }
 
 /**
@@ -1476,7 +1481,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
         if (ret < 0)
             return ret;
         ret = mov_write_pcmc_tag(s, pb, track);
-    } else if (track->vos_len > 0)
+    } else if (track->extradata_size[track->last_stsd_index] > 0)
         ret = mov_write_glbl_tag(pb, track);
 
     if (ret < 0)
@@ -1523,7 +1528,8 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
 
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "av1C");
-    ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != MODE_AVIF);
+    ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
+                       track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
     return update_size(pb, pos);
 }
 
@@ -1533,7 +1539,8 @@ static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
 
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "avcC");
-    ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
+    ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
+                       track->extradata_size[track->last_stsd_index]);
     return update_size(pb, pos);
 }
 
@@ -1565,7 +1572,8 @@ static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "av3c");
-    mov_write_av3c(pb, track->vos_data, track->vos_len);
+    mov_write_av3c(pb, track->extradata[track->last_stsd_index],
+                   track->extradata_size[track->last_stsd_index]);
     return update_size(pb, pos);
 }
 
@@ -1575,7 +1583,8 @@ static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
 
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "vpcC");
-    ff_isom_write_vpcc(s, pb, track->vos_data, track->vos_len, track->par);
+    ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
+                       track->extradata_size[track->last_stsd_index], track->par);
     return update_size(pb, pos);
 }
 
@@ -1586,9 +1595,11 @@ static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "hvcC");
     if (track->tag == MKTAG('h','v','c','1'))
-        ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 1, s);
+        ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
+                           track->extradata_size[track->last_stsd_index], 1, s);
     else
-        ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 0, s);
+        ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
+                           track->extradata_size[track->last_stsd_index], 0, s);
     return update_size(pb, pos);
 }
 
@@ -1600,9 +1611,11 @@ static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
     avio_wb32(pb, 0);
     ffio_wfourcc(pb, "lhvC");
     if (track->tag == MKTAG('h','v','c','1'))
-        ret = ff_isom_write_lhvc(pb, track->vos_data, track->vos_len, 1, s);
+        ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
+                                 track->extradata_size[track->last_stsd_index], 1, s);
     else
-        ret = ff_isom_write_lhvc(pb, track->vos_data, track->vos_len, 0, s);
+        ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
+                                 track->extradata_size[track->last_stsd_index], 0, s);
 
     if (ret < 0) {
         avio_seek(pb, pos, SEEK_SET);
@@ -1620,9 +1633,11 @@ static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "evcC");
 
     if (track->tag == MKTAG('e','v','c','1'))
-        ff_isom_write_evcc(pb, track->vos_data, track->vos_len, 1);
+        ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
+                           track->extradata_size[track->last_stsd_index], 1);
     else
-        ff_isom_write_evcc(pb, track->vos_data, track->vos_len, 0);
+        ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
+                           track->extradata_size[track->last_stsd_index], 0);
 
     return update_size(pb, pos);
 }
@@ -1638,9 +1653,11 @@ static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb24(pb, 0); /* flags */
 
     if (track->tag == MKTAG('v','v','c','1'))
-        ff_isom_write_vvcc(pb, track->vos_data, track->vos_len, 1);
+        ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
+                           track->extradata_size[track->last_stsd_index], 1);
     else
-        ff_isom_write_vvcc(pb, track->vos_data, track->vos_len, 0);
+        ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
+                           track->extradata_size[track->last_stsd_index], 0);
     return update_size(pb, pos);
 }
 
@@ -1666,11 +1683,11 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
     int cid;
     int display_width = track->par->width;
 
-    if (track->vos_data && track->vos_len > 0x29) {
-        if (ff_dnxhd_parse_header_prefix(track->vos_data) != 0) {
+    if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
+        if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
             /* looks like a DNxHD bit stream */
-            interlaced = (track->vos_data[5] & 2);
-            cid = AV_RB32(track->vos_data + 0x28);
+            interlaced = (track->extradata[track->last_stsd_index][5] & 2);
+            cid = AV_RB32(track->extradata[track->last_stsd_index] + 0x28);
         } else {
             av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
             return 0;
@@ -1745,9 +1762,9 @@ static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
 {
     avio_wb32(pb, 12);
     ffio_wfourcc(pb, "DpxE");
-    if (track->par->extradata_size >= 12 &&
-        !memcmp(&track->par->extradata[4], "DpxE", 4)) {
-        avio_wb32(pb, track->par->extradata[11]);
+    if (track->extradata_size[track->last_stsd_index] >= 12 &&
+        !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
+        avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
     } else {
         avio_wb32(pb, 1);
     }
@@ -2158,8 +2175,8 @@ static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack
                    track->track_id);
             return AVERROR(EINVAL);
         }
-    } else if (track->par->extradata_size)
-        avio_write(pb, track->par->extradata, track->par->extradata_size);
+    } else if (track->extradata_size[track->last_stsd_index])
+        avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
 
     if (mov->write_btrt &&
             ((ret = mov_write_btrt_tag(pb, track)) < 0))
@@ -2788,7 +2805,7 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
         mov_write_vpcc_tag(mov->fc, pb, track);
     } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
         mov_write_av1c_tag(pb, track);
-    } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
+    } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
         mov_write_dvc1_tag(pb, track);
     else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
              track->par->codec_id == AV_CODEC_ID_VP6A) {
@@ -2799,7 +2816,7 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
             mov_write_dpxe_tag(pb, track);
     } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
         mov_write_av3c_tag(pb, track);
-    } else if (track->vos_len > 0)
+    } else if (track->extradata_size[track->last_stsd_index] > 0)
         mov_write_glbl_tag(pb, track);
 
     if (track->par->codec_id != AV_CODEC_ID_H264 &&
@@ -3037,6 +3054,7 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
     ffio_wfourcc(pb, "stsd");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, 1); /* entry count */
+
     if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
         ret = mov_write_video_tag(s, pb, mov, track);
     else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
@@ -5253,19 +5271,19 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat
         if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
             if (track->par->codec_id == AV_CODEC_ID_H264) {
                 uint8_t *ptr;
-                int size = track->par->extradata_size;
-                if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
+                int size = track->extradata_size[track->last_stsd_index];
+                if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
                                                    &size)) {
                     param_write_hex(pb, "CodecPrivateData",
-                                    ptr ? ptr : track->par->extradata,
+                                    ptr ? ptr : track->extradata[track->last_stsd_index],
                                     size);
                     av_free(ptr);
                 }
                 param_write_string(pb, "FourCC", "H264");
             } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
                 param_write_string(pb, "FourCC", "WVC1");
-                param_write_hex(pb, "CodecPrivateData", track->par->extradata,
-                                track->par->extradata_size);
+                param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
+                                track->extradata_size[track->last_stsd_index]);
             }
             param_write_int(pb, "MaxWidth", track->par->width);
             param_write_int(pb, "MaxHeight", track->par->height);
@@ -5286,8 +5304,8 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat
             } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
                 param_write_string(pb, "FourCC", "WMAP");
             }
-            param_write_hex(pb, "CodecPrivateData", track->par->extradata,
-                            track->par->extradata_size);
+            param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
+                            track->extradata_size[track->last_stsd_index]);
             param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
                                                              track->par->codec_id));
             param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
@@ -6713,17 +6731,15 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     }
 
     /* copy extradata if it exists */
-    if (trk->vos_len == 0 && par->extradata_size > 0 &&
+    if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
         !TAG_IS_AVCI(trk->tag) &&
         (par->codec_id != AV_CODEC_ID_DNXHD)) {
-        trk->vos_len  = par->extradata_size;
-        trk->vos_data = av_malloc(trk->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
-        if (!trk->vos_data) {
+        trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
+        if (!trk->extradata[0]) {
             ret = AVERROR(ENOMEM);
             goto err;
         }
-        memcpy(trk->vos_data, par->extradata, trk->vos_len);
-        memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+        trk->extradata_size[0] = par->extradata_size;
     }
 
     if ((par->codec_id == AV_CODEC_ID_DNXHD ||
@@ -6732,17 +6748,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
          par->codec_id == AV_CODEC_ID_VVC ||
          par->codec_id == AV_CODEC_ID_VP9 ||
          par->codec_id == AV_CODEC_ID_EVC ||
-         par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->vos_len &&
+         par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
          !TAG_IS_AVCI(trk->tag)) {
         /* copy frame to create needed atoms */
-        trk->vos_len  = size;
-        trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
-        if (!trk->vos_data) {
+        trk->extradata_size[0]  = size;
+        trk->extradata[0] = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
+        if (!trk->extradata[0]) {
             ret = AVERROR(ENOMEM);
             goto err;
         }
-        memcpy(trk->vos_data, pkt->data, size);
-        memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+        memcpy(trk->extradata[0], pkt->data, size);
+        memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     }
 
     if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
@@ -6755,7 +6771,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
         }
         av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
     }
-    if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
+    if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
+        *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
         /* from x264 or from bytestream H.264 */
         /* NAL reformatting needed */
         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
@@ -6775,8 +6792,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
                 size = ff_nal_parse_units(pb, pkt->data, pkt->size);
             }
         }
-    } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
-               (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
+    } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
+               (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
         /* extradata is Annex B, assume the bitstream is too and convert it */
         int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
@@ -6796,8 +6813,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
                 size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
             }
         }
-    } else if (par->codec_id == AV_CODEC_ID_VVC && trk->vos_len > 6 &&
-             (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
+    } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
+             (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
         /* extradata is Annex B, assume the bitstream is too and convert it */
         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
             ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
@@ -6854,11 +6871,13 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
         avio_write(s->pb, pkt->data, pkt->size);
     } else {
         if (trk->cenc.aes_ctr) {
-            if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
-                int nal_size_length = (par->extradata[4] & 0x3) + 1;
+            uint8_t *extradata = trk->extradata[trk->last_stsd_index];
+            int extradata_size = trk->extradata_size[trk->last_stsd_index];
+            if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
+                int nal_size_length = (extradata[4] & 0x3) + 1;
                 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
-            } else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) {
-                int nal_size_length = (par->extradata[21] & 0x3) + 1;
+            } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
+                int nal_size_length = (extradata[21] & 0x3) + 1;
                 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
             } else if(par->codec_id == AV_CODEC_ID_VVC) {
                 ret = AVERROR_PATCHWELCOME;
@@ -7050,16 +7069,14 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
             trk->par->codec_id == AV_CODEC_ID_FLAC) {
         size_t side_size;
         uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
-        if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
-            void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
+        /* Overwrite extradata only on flush packets or when no extradata was available during init */
+        if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
+            void *newextra = av_memdup(side, side_size);
             if (!newextra)
                 return AVERROR(ENOMEM);
-            av_free(par->extradata);
-            par->extradata = newextra;
-            memcpy(par->extradata, side, side_size);
-            par->extradata_size = side_size;
-            if (!pkt->size) // Flush packet
-                mov->need_rewrite_extradata = 1;
+            av_free(trk->extradata[trk->last_stsd_index]);
+            trk->extradata[trk->last_stsd_index] = newextra;
+            trk->extradata_size[trk->last_stsd_index] = side_size;
         }
     }
 
@@ -7398,6 +7415,11 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
         return ret;
     memcpy(track->par->extradata, stub_header, sizeof(stub_header));
 
+    track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
+    if (!track->extradata[0])
+        return AVERROR(ENOMEM);
+    track->extradata_size[0] = sizeof(stub_header);
+
     pkt->stream_index = tracknum;
     pkt->flags = AV_PKT_FLAG_KEY;
 
@@ -7569,8 +7591,9 @@ static void mov_free(AVFormatContext *s)
             av_packet_free(&info->pkt);
             av_freep(&track->eac3_priv);
         }
-        if (track->vos_len)
-            av_freep(&track->vos_data);
+        for (int j = 0; j < track->stsd_count; j++)
+            av_freep(&track->extradata[j]);
+        av_freep(&track->extradata);
 
         ff_mov_cenc_free(&track->cenc);
         ffio_free_dyn_buf(&track->mdat_buf);
@@ -7612,7 +7635,7 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
     int i, width = 720, height = 480;
     int have_palette = 0, have_size = 0;
     uint32_t palette[16];
-    char *cur = st->codecpar->extradata;
+    char *cur = track->extradata[track->last_stsd_index];
 
     while (cur && *cur) {
         if (strncmp("palette:", cur, 8) == 0) {
@@ -7641,14 +7664,14 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
         cur += strspn(cur, "\n\r");
     }
     if (have_palette) {
-        track->vos_data = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
-        if (!track->vos_data)
+        track->extradata[track->last_stsd_index] = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
+        if (!track->extradata[track->last_stsd_index])
             return AVERROR(ENOMEM);
         for (i = 0; i < 16; i++) {
-            AV_WB32(track->vos_data + i * 4, palette[i]);
+            AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
         }
-        memset(track->vos_data + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-        track->vos_len = 16 * 4;
+        memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+        track->extradata_size[track->last_stsd_index] = 16 * 4;
     }
     st->codecpar->width = width;
     st->codecpar->height = track->height = height;
@@ -7963,6 +7986,16 @@ static int mov_init(AVFormatContext *s)
     if (!mov->tracks)
         return AVERROR(ENOMEM);
 
+    for (i = 0; i < mov->nb_tracks; i++) {
+        MOVTrack *track = &mov->tracks[i];
+
+        track->stsd_count     = 1;
+        track->extradata      = av_calloc(track->stsd_count, sizeof(*track->extradata));
+        track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
+        if (!track->extradata || !track->extradata_size)
+            return AVERROR(ENOMEM);
+    }
+
     if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
         if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
             mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;
@@ -8240,13 +8273,16 @@ static int mov_write_header(AVFormatContext *s)
             if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
                 mov_create_dvd_sub_decoder_specific_info(track, st);
             else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
-                track->vos_len  = st->codecpar->extradata_size;
-                track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
-                if (!track->vos_data) {
+                track->extradata_size[track->last_stsd_index]  = st->codecpar->extradata_size;
+                track->extradata[track->last_stsd_index] =
+                    av_malloc(track->extradata_size[track->last_stsd_index] + AV_INPUT_BUFFER_PADDING_SIZE);
+                if (!track->extradata[track->last_stsd_index]) {
                     return AVERROR(ENOMEM);
                 }
-                memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
-                memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+                memcpy(track->extradata[track->last_stsd_index],
+                       st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
+                memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
+                       0, AV_INPUT_BUFFER_PADDING_SIZE);
             }
         }
 
@@ -8467,22 +8503,6 @@ static int mov_write_trailer(AVFormatContext *s)
     int i;
     int64_t moov_pos;
 
-    if (mov->need_rewrite_extradata) {
-        for (i = 0; i < mov->nb_streams; i++) {
-            MOVTrack *track = &mov->tracks[i];
-            AVCodecParameters *par = track->par;
-
-            track->vos_len  = par->extradata_size;
-            av_freep(&track->vos_data);
-            track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!track->vos_data)
-                return AVERROR(ENOMEM);
-            memcpy(track->vos_data, par->extradata, track->vos_len);
-            memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-        }
-        mov->need_rewrite_extradata = 0;
-    }
-
     /*
      * Before actually writing the trailer, make sure that there are no
      * dangling subtitles, that need a terminating sample.
index 2b81d38982625a01546d9460c76256186201d31a..4c20571e67fb6a9e8bc6773b64c2257298e8a6b4 100644 (file)
@@ -90,6 +90,13 @@ typedef struct MOVTrack {
     uint64_t    time;
     int64_t     track_duration;
     int         last_sample_is_subtitle_end;
+
+    /* multiple stsd */
+    int         stsd_count;
+    int         last_stsd_index;
+    uint8_t     **extradata;
+    int         *extradata_size;
+
     long        sample_count;
     long        sample_size;
     long        chunkCount;
@@ -111,8 +118,6 @@ typedef struct MOVTrack {
     int mono_as_fc;
     int multichannel_as_mono;
 
-    int         vos_len;
-    uint8_t     *vos_data;
     MOVIentry   *cluster;
     MOVIentry   *cluster_written;
     unsigned    cluster_capacity;
@@ -245,8 +250,6 @@ typedef struct MOVMuxContext {
     uint8_t *encryption_kid;
     int encryption_kid_len;
 
-    int need_rewrite_extradata;
-
     int use_stream_ids_as_track_ids;
     int track_ids_ok;
     int write_btrt;
为什么前壁容易生男孩 懿怎么读 什么意思 神经外科主要看什么病 左氧氟沙星的功效是什么 o是什么牌子
莓茶是什么茶 经常的近义词是什么 天才是指什么生肖 ra医学上是什么意思 病毒性心肌炎吃什么药
上海月薪三万什么水平 尿毒症小便有什么症状 葡萄都有什么品种 野鸡大学是什么意思 93属什么生肖
便血是什么样的 顺子是什么意思 月经期适合吃什么水果 陈宝莲为什么自杀 大土土什么字
清关是什么意思hcv8jop7ns1r.cn 张家界地貌属于什么地貌hcv9jop8ns2r.cn 鸟在家里做窝预示什么hcv8jop6ns9r.cn 火眼是什么症状hcv9jop8ns3r.cn 牙龈有点发黑是什么原因hcv9jop2ns8r.cn
舌头疼吃什么药好得快hcv8jop7ns0r.cn 教师节唱什么歌hcv9jop6ns3r.cn 黄芪泡水喝有什么作用hcv8jop8ns9r.cn 犯太岁是什么意思啊hcv7jop7ns2r.cn hbalc是什么意思hcv9jop6ns8r.cn
中性粒细胞比率偏低是什么意思hcv8jop6ns3r.cn 龙跟什么生肖配对最好hcv9jop0ns9r.cn 性腺六项是查什么的hcv9jop6ns4r.cn 美国现在是什么时间hcv8jop5ns9r.cn 痣发痒是什么原因hcv9jop2ns4r.cn
吃什么食物可以降低胆固醇hcv8jop9ns8r.cn 过敏是什么意思hcv9jop1ns9r.cn 自己买什么药可以打胎hcv8jop7ns7r.cn 增加免疫力吃什么好hcv9jop6ns6r.cn 阿托品是什么药hcv9jop6ns7r.cn
百度