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.)
Showing the changes to libavformat (1 of 1 file). Show all
Unified · Split
| @@ -990,7 +990,8 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, · 989 unmodified lines | |||
| 990 | } | 990 | } |
| 991 | 991 | ||
| 992 | static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, | 992 | static 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 | else | 1003 | 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_MUXER | 1023 | #if CONFIG_MATROSKA_MUXER |
| 1023 | static int put_wv_codecpriv(AVIOContext *pb, const AVCodecParameters *par) | 1024 | static 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 | else | 1028 | else |
| 1028 | avio_wl16(pb, 0x410); // fallback to the most recent version | 1029 | avio_wl16(pb, 0x410); // fallback to the most recent version |
| 1029 | return 0; | 1030 | return 0; |
| 1030 | } | 1031 | } |
| 1031 | 1032 | ||
| 1032 | static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb, | 1033 | static 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 | ||
| 1102 | static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, | 1104 | static 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 | else | 1118 | else |
| 1115 | *size_to_reserve = 4 + 3; | 1119 | *size_to_reserve = 4 + 3; |
| 1116 | break; | 1120 | break; |
| 1117 | #if CONFIG_MATROSKA_MUXER | 1121 | #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 | } else | 1138 | } 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 | else | 1145 | 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 | ||
| 1156 | static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, | 1160 | static 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_MUXER | 1178 | #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_id | 1184 | 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 | #endif | 1223 | #endif |
| 1214 | } | 1224 | } |
| @@ -1221,6 +1231,7 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, · 6 unmodified lines | |||
| 1221 | 1231 | ||
| 1222 | static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, | 1232 | static 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 | #endif | 2686 | #endif |