From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Subject: [FFmpeg-devel] [PATCH 2/6] avformat/matroskaenc: Avoid swapping codecpar->extradata temporarily Date: Tue, 21 Jun 2022 04:34:14 +0200 Message-ID: <DB6PR0101MB2214BBE7E74F9C2FB2BDA39B8FB39@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com> (raw) In-Reply-To: <DB6PR0101MB2214886E62B7920390D6D89F8FB39@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com> 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.) Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavformat/matroskaenc.c | 82 ++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index b4756832eb..93d10332a4 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -990,7 +990,8 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, } static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, - const AVCodecParameters *par) + const AVCodecParameters *par, + const uint8_t *extradata, int extradata_size) { const uint8_t *header_start[3]; int header_len[3]; @@ -1002,7 +1003,7 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, else first_header_size = 42; - err = avpriv_split_xiph_headers(par->extradata, par->extradata_size, + err = avpriv_split_xiph_headers(extradata, extradata_size, first_header_size, header_start, header_len); if (err < 0) { av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); @@ -1020,22 +1021,23 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, } #if CONFIG_MATROSKA_MUXER -static int put_wv_codecpriv(AVIOContext *pb, const AVCodecParameters *par) +static int put_wv_codecpriv(AVIOContext *pb, const uint8_t *extradata, int extradata_size) { - if (par->extradata && par->extradata_size == 2) - avio_write(pb, par->extradata, 2); + if (extradata && extradata_size == 2) + avio_write(pb, extradata, 2); else avio_wl16(pb, 0x410); // fallback to the most recent version return 0; } static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb, - const AVCodecParameters *par) + const AVCodecParameters *par, + const uint8_t *extradata, int extradata_size) { int write_comment = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE && !(par->ch_layout.u.mask & ~0x3ffffULL) && !ff_flac_is_native_layout(par->ch_layout.u.mask)); - int ret = ff_flac_write_header(pb, par->extradata, par->extradata_size, + int ret = ff_flac_write_header(pb, extradata, extradata_size, !write_comment); if (ret < 0) @@ -1101,43 +1103,45 @@ static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv, static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, const AVCodecParameters *par, + const uint8_t *extradata, + int extradata_size, unsigned *size_to_reserve) { switch (par->codec_id) { case AV_CODEC_ID_VORBIS: case AV_CODEC_ID_THEORA: - return put_xiph_codecpriv(s, dyn_cp, par); + return put_xiph_codecpriv(s, dyn_cp, par, extradata, extradata_size); case AV_CODEC_ID_AV1: - if (par->extradata_size) - return ff_isom_write_av1c(dyn_cp, par->extradata, - par->extradata_size, 1); + if (extradata_size) + return ff_isom_write_av1c(dyn_cp, extradata, + extradata_size, 1); else *size_to_reserve = 4 + 3; break; #if CONFIG_MATROSKA_MUXER case AV_CODEC_ID_FLAC: - return put_flac_codecpriv(s, dyn_cp, par); + return put_flac_codecpriv(s, dyn_cp, par, extradata, extradata_size); case AV_CODEC_ID_WAVPACK: - return put_wv_codecpriv(dyn_cp, par); + return put_wv_codecpriv(dyn_cp, extradata, extradata_size); case AV_CODEC_ID_H264: - return ff_isom_write_avcc(dyn_cp, par->extradata, - par->extradata_size); + return ff_isom_write_avcc(dyn_cp, extradata, + extradata_size); case AV_CODEC_ID_HEVC: - return ff_isom_write_hvcc(dyn_cp, par->extradata, - par->extradata_size, 0); + return ff_isom_write_hvcc(dyn_cp, extradata, + extradata_size, 0); case AV_CODEC_ID_ALAC: - if (par->extradata_size < 36) { + if (extradata_size < 36) { av_log(s, AV_LOG_ERROR, "Invalid extradata found, ALAC expects a 36-byte " "QuickTime atom."); return AVERROR_INVALIDDATA; } else - avio_write(dyn_cp, par->extradata + 12, - par->extradata_size - 12); + avio_write(dyn_cp, extradata + 12, + extradata_size - 12); break; case AV_CODEC_ID_AAC: - if (par->extradata_size) - avio_write(dyn_cp, par->extradata, par->extradata_size); + if (extradata_size) + avio_write(dyn_cp, extradata, extradata_size); else *size_to_reserve = 4 + MAX_PCE_SIZE + 2; break; @@ -1146,8 +1150,8 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn if (CONFIG_MATROSKA_MUXER && par->codec_id == AV_CODEC_ID_PRORES && ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == AV_CODEC_ID_PRORES) { avio_wl32(dyn_cp, par->codec_tag); - } else if (par->extradata_size && par->codec_id != AV_CODEC_ID_TTA) - avio_write(dyn_cp, par->extradata, par->extradata_size); + } else if (extradata_size && par->codec_id != AV_CODEC_ID_TTA) + avio_write(dyn_cp, extradata, extradata_size); } return 0; @@ -1155,6 +1159,7 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, AVCodecParameters *par, + const uint8_t *extradata, int extradata_size, int native_id, int qt_id, uint8_t **codecpriv, int *codecpriv_size, unsigned *size_to_reserve) @@ -1165,7 +1170,9 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, *size_to_reserve = 0; if (native_id) { - ret = mkv_assemble_native_codecprivate(s, dyn_cp, par, size_to_reserve); + ret = mkv_assemble_native_codecprivate(s, dyn_cp, par, + extradata, extradata_size, + size_to_reserve); if (ret < 0) return ret; #if CONFIG_MATROSKA_MUXER @@ -1175,13 +1182,13 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, par->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags, par->codec_id); if ( ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag) == par->codec_id - && (!par->extradata_size || ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(par->extradata + 4)) != par->codec_id) + && (!extradata_size || ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(extradata + 4)) != par->codec_id) ) { - avio_wb32(dyn_cp, 0x5a + par->extradata_size); + avio_wb32(dyn_cp, 0x5a + extradata_size); avio_wl32(dyn_cp, par->codec_tag); ffio_fill(dyn_cp, 0, 0x5a - 8); } - avio_write(dyn_cp, par->extradata, par->extradata_size); + avio_write(dyn_cp, extradata, extradata_size); } else { if (!ff_codec_get_tag(ff_codec_bmp_tags, par->codec_id)) 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, return AVERROR(EINVAL); } + /* If vfw extradata updates are supported, this will have + * to be updated to pass extradata(_size) explicitly. */ ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb); } } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -1209,6 +1218,7 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, if (!par->codec_tag) par->codec_tag = tag; + /* Same comment as for ff_put_bmp_header applies here. */ ff_put_wav_header(s, dyn_cp, par, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX); #endif } @@ -1221,6 +1231,7 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, AVCodecParameters *par, + const uint8_t *extradata, int extradata_size, int native_id, int qt_id, AVIOContext *pb) { AVIOContext *const dyn_bc = mkv->tmp_bc; @@ -1228,7 +1239,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, unsigned size_to_reserve; int ret, codecpriv_size; - ret = mkv_assemble_codecprivate(s, dyn_bc, par, native_id, qt_id, + ret = mkv_assemble_codecprivate(s, dyn_bc, par, extradata, extradata_size, + native_id, qt_id, &codecpriv, &codecpriv_size, &size_to_reserve); if (ret < 0) goto end; @@ -1851,7 +1863,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, if (!IS_WEBM(mkv) || par->codec_id != AV_CODEC_ID_WEBVTT) { track->codecpriv_offset = avio_tell(pb); - ret = mkv_write_codecprivate(s, mkv, par, native_id, qt_id, pb); + ret = mkv_write_codecprivate(s, mkv, par, par->extradata, par->extradata_size, + native_id, qt_id, pb); if (ret < 0) return ret; } @@ -2644,7 +2657,8 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) return ret; memcpy(par->extradata, side_data, side_data_size); avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET); - mkv_write_codecprivate(s, mkv, par, 1, 0, mkv->track.bc); + mkv_write_codecprivate(s, mkv, par, side_data, side_data_size, + 1, 0, mkv->track.bc); filler = MAX_PCE_SIZE + 2 + 4 - (avio_tell(mkv->track.bc) - track->codecpriv_offset); if (filler) put_ebml_void(mkv->track.bc, filler); @@ -2659,16 +2673,14 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) break; case AV_CODEC_ID_FLAC: if (side_data_size && mkv->track.bc) { - uint8_t *old_extradata = par->extradata; if (side_data_size != par->extradata_size) { av_log(s, AV_LOG_ERROR, "Invalid FLAC STREAMINFO metadata for output stream %d\n", pkt->stream_index); return AVERROR(EINVAL); } - par->extradata = side_data; avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET); - mkv_write_codecprivate(s, mkv, par, 1, 0, mkv->track.bc); - par->extradata = old_extradata; + mkv_write_codecprivate(s, mkv, par, side_data, side_data_size, + 1, 0, mkv->track.bc); } break; #endif -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-06-21 2:34 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-06-21 2:30 [FFmpeg-devel] [PATCH 1/6] avformat/matroskaenc: Split assembling CodecPrivate from writing it Andreas Rheinhardt 2022-06-21 2:34 ` Andreas Rheinhardt [this message] 2022-06-21 2:34 ` [FFmpeg-devel] [PATCH 3/6] avformat/matroskaenc: Split updating " Andreas Rheinhardt 2022-06-21 15:22 ` Michael Niedermayer 2022-06-21 21:45 ` Andreas Rheinhardt 2022-06-21 2:34 ` [FFmpeg-devel] [PATCH 4/6] avcodec/av1: Add upper bound for the size of a sane sequence header Andreas Rheinhardt 2022-06-21 2:34 ` [FFmpeg-devel] [PATCH 5/6] avformat/matroskaenc: Improve handling of AV1 extradata Andreas Rheinhardt 2022-06-21 2:34 ` [FFmpeg-devel] [PATCH 6/6] avformat/matroskaenc: Fix outdated comment Andreas Rheinhardt 2022-06-21 3:22 ` [FFmpeg-devel] [PATCH 7/7] avformat/matroskaenc: Reuse dynamic buffer Andreas Rheinhardt 2022-06-24 9:50 ` [FFmpeg-devel] [PATCH 1/6] avformat/matroskaenc: Split assembling CodecPrivate from writing it Andreas Rheinhardt
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=DB6PR0101MB2214BBE7E74F9C2FB2BDA39B8FB39@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com \ --to=andreas.rheinhardt@outlook.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git