History

avformat/matroskaenc: Avoid swapping codecpar->extradata temporarily

Instead pass extradata and extradata_size explicitly. (It is not perfect, as ff_put_(wav|bmp)_header() still uses the extradata embedded in codecpar, but this is not an issue as long as their CodecPrivate isn't updated.)

Andreas Rheinhardt committed 4 years ago

Commit 3a00a1a1 parent 1056f9a1 file · +47 −35Browse files

Unified · Split

libavformat/matroskaenc.c+47−35
@@ -990,7 +990,8 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, · 989 unmodified lines
990}990}
991 991
992static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb,992static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb,
993 const AVCodecParameters *par)993 const AVCodecParameters *par,
994 const uint8_t *extradata, int extradata_size)
994{995{
995 const uint8_t *header_start[3];996 const uint8_t *header_start[3];
996 int header_len[3];997 int header_len[3];
@@ -1002,7 +1003,7 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, · 5 unmodified lines
1002 else1003 else
1003 first_header_size = 42;1004 first_header_size = 42;
1004 1005
1005 err = avpriv_split_xiph_headers(par->extradata, par->extradata_size,1006 err = avpriv_split_xiph_headers(extradata, extradata_size,
1006 first_header_size, header_start, header_len);1007 first_header_size, header_start, header_len);
1007 if (err < 0) {1008 if (err < 0) {
1008 av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");1009 av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
@@ -1020,22 +1021,23 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, · 11 unmodified lines
1020}1021}
1021 1022
1022#if CONFIG_MATROSKA_MUXER1023#if CONFIG_MATROSKA_MUXER
1023static int put_wv_codecpriv(AVIOContext *pb, const AVCodecParameters *par)1024static int put_wv_codecpriv(AVIOContext *pb, const uint8_t *extradata, int extradata_size)
1024{1025{
1025 if (par->extradata && par->extradata_size == 2)1026 if (extradata && extradata_size == 2)
1026 avio_write(pb, par->extradata, 2);1027 avio_write(pb, extradata, 2);
1027 else1028 else
1028 avio_wl16(pb, 0x410); // fallback to the most recent version1029 avio_wl16(pb, 0x410); // fallback to the most recent version
1029 return 0;1030 return 0;
1030}1031}
1031 1032
1032static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb,1033static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb,
1033 const AVCodecParameters *par)1034 const AVCodecParameters *par,
1035 const uint8_t *extradata, int extradata_size)
1034{1036{
1035 int write_comment = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&1037 int write_comment = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
1036 !(par->ch_layout.u.mask & ~0x3ffffULL) &&1038 !(par->ch_layout.u.mask & ~0x3ffffULL) &&
1037 !ff_flac_is_native_layout(par->ch_layout.u.mask));1039 !ff_flac_is_native_layout(par->ch_layout.u.mask));
1038 int ret = ff_flac_write_header(pb, par->extradata, par->extradata_size,1040 int ret = ff_flac_write_header(pb, extradata, extradata_size,
1039 !write_comment);1041 !write_comment);
1040 1042
1041 if (ret < 0)1043 if (ret < 0)
@@ -1101,43 +1103,45 @@ static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv, · 59 unmodified lines
1101 1103
1102static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp,1104static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp,
1103 const AVCodecParameters *par,1105 const AVCodecParameters *par,
1106 const uint8_t *extradata,
1107 int extradata_size,
1104 unsigned *size_to_reserve)1108 unsigned *size_to_reserve)
1105{1109{
1106 switch (par->codec_id) {1110 switch (par->codec_id) {
1107 case AV_CODEC_ID_VORBIS:1111 case AV_CODEC_ID_VORBIS:
1108 case AV_CODEC_ID_THEORA:1112 case AV_CODEC_ID_THEORA:
1109 return put_xiph_codecpriv(s, dyn_cp, par);1113 return put_xiph_codecpriv(s, dyn_cp, par, extradata, extradata_size);
1110 case AV_CODEC_ID_AV1:1114 case AV_CODEC_ID_AV1:
1111 if (par->extradata_size)1115 if (extradata_size)
1112 return ff_isom_write_av1c(dyn_cp, par->extradata,1116 return ff_isom_write_av1c(dyn_cp, extradata,
1113 par->extradata_size, 1);1117 extradata_size, 1);
1114 else1118 else
1115 *size_to_reserve = 4 + 3;1119 *size_to_reserve = 4 + 3;
1116 break;1120 break;
1117#if CONFIG_MATROSKA_MUXER1121#if CONFIG_MATROSKA_MUXER
1118 case AV_CODEC_ID_FLAC:1122 case AV_CODEC_ID_FLAC:
1119 return put_flac_codecpriv(s, dyn_cp, par);1123 return put_flac_codecpriv(s, dyn_cp, par, extradata, extradata_size);
1120 case AV_CODEC_ID_WAVPACK:1124 case AV_CODEC_ID_WAVPACK:
1121 return put_wv_codecpriv(dyn_cp, par);1125 return put_wv_codecpriv(dyn_cp, extradata, extradata_size);
1122 case AV_CODEC_ID_H264:1126 case AV_CODEC_ID_H264:
1123 return ff_isom_write_avcc(dyn_cp, par->extradata,1127 return ff_isom_write_avcc(dyn_cp, extradata,
1124 par->extradata_size);1128 extradata_size);
1125 case AV_CODEC_ID_HEVC:1129 case AV_CODEC_ID_HEVC:
1126 return ff_isom_write_hvcc(dyn_cp, par->extradata,1130 return ff_isom_write_hvcc(dyn_cp, extradata,
1127 par->extradata_size, 0);1131 extradata_size, 0);
1128 case AV_CODEC_ID_ALAC:1132 case AV_CODEC_ID_ALAC:
1129 if (par->extradata_size < 36) {1133 if (extradata_size < 36) {
1130 av_log(s, AV_LOG_ERROR,1134 av_log(s, AV_LOG_ERROR,
1131 "Invalid extradata found, ALAC expects a 36-byte "1135 "Invalid extradata found, ALAC expects a 36-byte "
1132 "QuickTime atom.");1136 "QuickTime atom.");
1133 return AVERROR_INVALIDDATA;1137 return AVERROR_INVALIDDATA;
1134 } else1138 } else
1135 avio_write(dyn_cp, par->extradata + 12,1139 avio_write(dyn_cp, extradata + 12,
1136 par->extradata_size - 12);1140 extradata_size - 12);
1137 break;1141 break;
1138 case AV_CODEC_ID_AAC:1142 case AV_CODEC_ID_AAC:
1139 if (par->extradata_size)1143 if (extradata_size)
1140 avio_write(dyn_cp, par->extradata, par->extradata_size);1144 avio_write(dyn_cp, extradata, extradata_size);
1141 else1145 else
1142 *size_to_reserve = 4 + MAX_PCE_SIZE + 2;1146 *size_to_reserve = 4 + MAX_PCE_SIZE + 2;
1143 break;1147 break;
@@ -1146,8 +1150,8 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn · 2 unmodified lines
1146 if (CONFIG_MATROSKA_MUXER && par->codec_id == AV_CODEC_ID_PRORES &&1150 if (CONFIG_MATROSKA_MUXER && par->codec_id == AV_CODEC_ID_PRORES &&
1147 ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == AV_CODEC_ID_PRORES) {1151 ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == AV_CODEC_ID_PRORES) {
1148 avio_wl32(dyn_cp, par->codec_tag);1152 avio_wl32(dyn_cp, par->codec_tag);
1149 } else if (par->extradata_size && par->codec_id != AV_CODEC_ID_TTA)1153 } else if (extradata_size && par->codec_id != AV_CODEC_ID_TTA)
1150 avio_write(dyn_cp, par->extradata, par->extradata_size);1154 avio_write(dyn_cp, extradata, extradata_size);
1151 }1155 }
1152 1156
1153 return 0;1157 return 0;
@@ -1155,6 +1159,7 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn · 1 unmodified line
1155 1159
1156static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp,1160static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp,
1157 AVCodecParameters *par,1161 AVCodecParameters *par,
1162 const uint8_t *extradata, int extradata_size,
1158 int native_id, int qt_id,1163 int native_id, int qt_id,
1159 uint8_t **codecpriv, int *codecpriv_size,1164 uint8_t **codecpriv, int *codecpriv_size,
1160 unsigned *size_to_reserve)1165 unsigned *size_to_reserve)
@@ -1165,7 +1170,9 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, · 4 unmodified lines
1165 *size_to_reserve = 0;1170 *size_to_reserve = 0;
1166 1171
1167 if (native_id) {1172 if (native_id) {
1168 ret = mkv_assemble_native_codecprivate(s, dyn_cp, par, size_to_reserve);1173 ret = mkv_assemble_native_codecprivate(s, dyn_cp, par,
1174 extradata, extradata_size,
1175 size_to_reserve);
1169 if (ret < 0)1176 if (ret < 0)
1170 return ret;1177 return ret;
1171#if CONFIG_MATROSKA_MUXER1178#if CONFIG_MATROSKA_MUXER
@@ -1175,13 +1182,13 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, · 3 unmodified lines
1175 par->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags,1182 par->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags,
1176 par->codec_id);1183 par->codec_id);
1177 if ( ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == par->codec_id1184 if ( ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == par->codec_id
1178 && (!par->extradata_size || ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(par->extradata + 4)) != par->codec_id)1185 && (!extradata_size || ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(extradata + 4)) != par->codec_id)
1179 ) {1186 ) {
1180 avio_wb32(dyn_cp, 0x5a + par->extradata_size);1187 avio_wb32(dyn_cp, 0x5a + extradata_size);
1181 avio_wl32(dyn_cp, par->codec_tag);1188 avio_wl32(dyn_cp, par->codec_tag);
1182 ffio_fill(dyn_cp, 0, 0x5a - 8);1189 ffio_fill(dyn_cp, 0, 0x5a - 8);
1183 }1190 }
1184 avio_write(dyn_cp, par->extradata, par->extradata_size);1191 avio_write(dyn_cp, extradata, extradata_size);
1185 } else {1192 } else {
1186 if (!ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id))1193 if (!ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id))
1187 av_log(s, AV_LOG_WARNING, "codec %s is not supported by this format\n",1194 av_log(s, AV_LOG_WARNING, "codec %s is not supported by this format\n",
@@ -1196,6 +1203,8 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, · 8 unmodified lines
1196 return AVERROR(EINVAL);1203 return AVERROR(EINVAL);
1197 }1204 }
1198 1205
1206 /* If vfw extradata updates are supported, this will have
1207 * to be updated to pass extradata(_size) explicitly. */
1199 ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb);1208 ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb);
1200 }1209 }
1201 } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {1210 } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -1209,6 +1218,7 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, · 7 unmodified lines
1209 if (!par->codec_tag)1218 if (!par->codec_tag)
1210 par->codec_tag = tag;1219 par->codec_tag = tag;
1211 1220
1221 /* Same comment as for ff_put_bmp_header applies here. */
1212 ff_put_wav_header(s, dyn_cp, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX);1222 ff_put_wav_header(s, dyn_cp, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX);
1213#endif1223#endif
1214 }1224 }
@@ -1221,6 +1231,7 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, · 6 unmodified lines
1221 1231
1222static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv,1232static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv,
1223 AVCodecParameters *par,1233 AVCodecParameters *par,
1234 const uint8_t *extradata, int extradata_size,
1224 int native_id, int qt_id, AVIOContext *pb)1235 int native_id, int qt_id, AVIOContext *pb)
1225{1236{
1226 AVIOContext *const dyn_bc = mkv->tmp_bc;1237 AVIOContext *const dyn_bc = mkv->tmp_bc;
@@ -1228,7 +1239,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, · 1 unmodified line
1228 unsigned size_to_reserve;1239 unsigned size_to_reserve;
1229 int ret, codecpriv_size;1240 int ret, codecpriv_size;
1230 1241
1231 ret = mkv_assemble_codecprivate(s, dyn_bc, par, native_id, qt_id,1242 ret = mkv_assemble_codecprivate(s, dyn_bc, par, extradata, extradata_size,
1243 native_id, qt_id,
1232 &codecpriv, &codecpriv_size, &size_to_reserve);1244 &codecpriv, &codecpriv_size, &size_to_reserve);
1233 if (ret < 0)1245 if (ret < 0)
1234 goto end;1246 goto end;
@@ -1851,7 +1863,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, · 616 unmodified lines
1851 1863
1852 if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT) {1864 if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT) {
1853 track->codecpriv_offset = avio_tell(pb);1865 track->codecpriv_offset = avio_tell(pb);
1854 ret = mkv_write_codecprivate(s, mkv, par, native_id, qt_id, pb);1866 ret = mkv_write_codecprivate(s, mkv, par, par->extradata, par->extradata_size,
1867 native_id, qt_id, pb);
1855 if (ret < 0)1868 if (ret < 0)
1856 return ret;1869 return ret;
1857 }1870 }
@@ -2644,7 +2657,8 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) · 786 unmodified lines
2644 return ret;2657 return ret;
2645 memcpy(par->extradata, side_data, side_data_size);2658 memcpy(par->extradata, side_data, side_data_size);
2646 avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);2659 avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
2647 mkv_write_codecprivate(s, mkv, par, 1, 0, mkv->track.bc);2660 mkv_write_codecprivate(s, mkv, par, side_data, side_data_size,
2661 1, 0, mkv->track.bc);
2648 filler = MAX_PCE_SIZE + 2 + 4 - (avio_tell(mkv->track.bc) - track->codecpriv_offset);2662 filler = MAX_PCE_SIZE + 2 + 4 - (avio_tell(mkv->track.bc) - track->codecpriv_offset);
2649 if (filler)2663 if (filler)
2650 put_ebml_void(mkv->track.bc, filler);2664 put_ebml_void(mkv->track.bc, filler);
@@ -2659,16 +2673,14 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) · 8 unmodified lines
2659 break;2673 break;
2660 case AV_CODEC_ID_FLAC:2674 case AV_CODEC_ID_FLAC:
2661 if (side_data_size && mkv->track.bc) {2675 if (side_data_size && mkv->track.bc) {
2662 uint8_t *old_extradata = par->extradata;
2663 if (side_data_size != par->extradata_size) {2676 if (side_data_size != par->extradata_size) {
2664 av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n",2677 av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n",
2665 pkt->stream_index);2678 pkt->stream_index);
2666 return AVERROR(EINVAL);2679 return AVERROR(EINVAL);
2667 }2680 }
2668 par->extradata = side_data;
2669 avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);2681 avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
2670 mkv_write_codecprivate(s, mkv, par, 1, 0, mkv->track.bc);2682 mkv_write_codecprivate(s, mkv, par, side_data, side_data_size,
2671 par->extradata = old_extradata;2683 1, 0, mkv->track.bc);
2672 }2684 }
2673 break;2685 break;
2674#endif2686#endif

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