Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
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".

  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