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 04/20] avformat/matroskadec: Redo handling extradata allocation
Date: Mon,  4 Sep 2023 13:27:43 +0200
Message-ID: <AS8P250MB074422E739036D97D081CA6D8FE9A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <AS8P250MB0744314AD7A516CFC71F61BF8FE9A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM>

Up until now, matroska_parse_tracks() has two main ways
to set AVCodecParameters.extradata: A generic way via CodecPrivate
(possibly with an offset) and by allocating a buffer manually;
the pointer to this buffer is stored in a stack pointer.

In particular, the latter method is problematic, as the buffer
needs to be freed manually in case of error (currently there
are no error conditions between the place where it is set
to AVCodecParameters.extradata).

Most of these buffers are very small (<= 22B), so replace
the pointer to an allocated buffer with a stack buffer
and set the extradata directly for the one place where
the buffer may not be small.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/matroskadec.c | 60 ++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 33 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index fd28ff8ab2..50a159460d 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -2501,6 +2501,10 @@ static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID *
     return 0;
 }
 
+#define AAC_MAX_EXTRADATA_SIZE     5
+#define TTA_EXTRADATA_SIZE        22
+#define WAVPACK_EXTRADATA_SIZE     2
+
 static int matroska_parse_tracks(AVFormatContext *s)
 {
     MatroskaDemuxContext *matroska = s->priv_data;
@@ -2514,8 +2518,10 @@ static int matroska_parse_tracks(AVFormatContext *s)
         EbmlList *encodings_list = &track->encodings;
         MatroskaTrackEncoding *encodings = encodings_list->elem;
         AVCodecParameters *par;
-        uint8_t *extradata = NULL;
-        int extradata_size = 0;
+        uint8_t extradata[FFMAX3(AAC_MAX_EXTRADATA_SIZE,
+                                 TTA_EXTRADATA_SIZE,
+                                 WAVPACK_EXTRADATA_SIZE)];
+        int extradata_size = 0; // > 0 means that the extradata buffer is used
         int extradata_offset = 0;
         uint32_t fourcc = 0;
         FFIOContext b;
@@ -2795,9 +2801,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
         } else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) {
             int profile = matroska_aac_profile(track->codec_id);
             int sri     = matroska_aac_sri(track->audio.samplerate);
-            extradata   = av_mallocz(5 + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!extradata)
-                return AVERROR(ENOMEM);
+
             extradata[0] = (profile << 3) | ((sri & 0x0E) >> 1);
             extradata[1] = ((sri & 0x01) << 7) | (track->audio.channels << 3);
             if (strstr(track->codec_id, "SBR")) {
@@ -2812,15 +2816,13 @@ static int matroska_parse_tracks(AVFormatContext *s)
             /* Only ALAC's magic cookie is stored in Matroska's track headers.
              * Create the "atom size", "tag", and "tag version" fields the
              * decoder expects manually. */
-            extradata_size = 12 + track->codec_priv.size;
-            extradata      = av_mallocz(extradata_size +
-                                        AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!extradata)
-                return AVERROR(ENOMEM);
-            AV_WB32(extradata, extradata_size);
-            memcpy(&extradata[4], "alac", 4);
-            AV_WB32(&extradata[8], 0);
-            memcpy(&extradata[12], track->codec_priv.data,
+            ret = ff_alloc_extradata(par, 12 + track->codec_priv.size);
+            if (ret < 0)
+                return ret;
+            AV_WB32(par->extradata, par->extradata_size);
+            AV_WB32(&par->extradata[4], MKBETAG('a', 'l', 'a', 'c'));
+            AV_WB32(&par->extradata[8], 0);
+            memcpy(&par->extradata[12], track->codec_priv.data,
                    track->codec_priv.size);
         } else if (codec_id == AV_CODEC_ID_TTA) {
             uint8_t *ptr;
@@ -2837,10 +2839,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
             }
             if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX)
                 return AVERROR_INVALIDDATA;
-            extradata_size = 22;
-            extradata      = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!extradata)
-                return AVERROR(ENOMEM);
+            extradata_size = TTA_EXTRADATA_SIZE;
             ptr = extradata;
             bytestream_put_be32(&ptr, AV_RB32("TTA1"));
             bytestream_put_le16(&ptr, 1);
@@ -2910,10 +2909,7 @@ static int matroska_parse_tracks(AVFormatContext *s)
         } else if (codec_id == AV_CODEC_ID_WAVPACK && track->codec_priv.size < 2) {
             av_log(matroska->ctx, AV_LOG_INFO, "Assuming WavPack version 4.10 "
                    "in absence of valid CodecPrivate.\n");
-            extradata_size = 2;
-            extradata = av_mallocz(2 + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!extradata)
-                return AVERROR(ENOMEM);
+            extradata_size = WAVPACK_EXTRADATA_SIZE;
             AV_WL16(extradata, 0x410);
         } else if (codec_id == AV_CODEC_ID_PRORES && track->codec_priv.size == 4) {
             fourcc = AV_RL32(track->codec_priv.data);
@@ -2959,17 +2955,15 @@ static int matroska_parse_tracks(AVFormatContext *s)
 
         par->codec_id = codec_id;
 
-        if (!par->extradata) {
-            if (extradata) {
-                par->extradata      = extradata;
-                par->extradata_size = extradata_size;
-            } else if (track->codec_priv.data && track->codec_priv.size > 0) {
-                if (ff_alloc_extradata(par, track->codec_priv.size))
-                    return AVERROR(ENOMEM);
-                memcpy(par->extradata,
-                       track->codec_priv.data + extradata_offset,
-                       track->codec_priv.size);
-            }
+        if (!par->extradata && (extradata_size > 0 || track->codec_priv.size > 0)) {
+            const uint8_t *src = extradata_size > 0 ? extradata :
+                                     track->codec_priv.data + extradata_offset;
+            unsigned extra_size = extradata_size > 0 ? extradata_size :
+                                                       track->codec_priv.size;
+            ret = ff_alloc_extradata(par, extra_size);
+            if (ret < 0)
+                return ret;
+            memcpy(par->extradata, src, extra_size);
         }
 
         if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
-- 
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".

  parent reply	other threads:[~2023-09-04 11:28 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-04 11:26 [FFmpeg-devel] [PATCH 01/20] fate/matroska: Add test for remuxing non-rotation displaymatrix Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 02/20] avformat/matroskadec: Set several stream parameters earlier Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 03/20] avformat/matroskadec: Use dedicated pointer for access to codecpar Andreas Rheinhardt
2023-09-04 11:27 ` Andreas Rheinhardt [this message]
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 05/20] avformat/matroskadec: Set AVCodecParameters earlier Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 06/20] avformat/matroskdec: Factor audio parsing out of matroska_parse_tracks() Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 07/20] avformat/matroskadec: Remove redundant checks Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 08/20] avformat/matroskadec: Reindent after the previous commit Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 09/20] avformat/matroskadec: Factor video parsing out of matroska_parse_tracks() Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 10/20] avformat/matroskadec: Reindent after the previous commit Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 11/20] avformat/matroskadec: Move reading color space to a better place Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 12/20] avformat/matroskadec: Avoid clobbering CodecPrivate size Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 13/20] avformat/matroskadec: Use av_dict_set_int() where appropriate Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 14/20] avformat/matroskadec: Factor parsing subtitle codecs out Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 15/20] avformat/matroskadec: Factor generic parsing of video tracks out Andreas Rheinhardt
2023-09-04 11:46   ` James Almer
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 16/20] avformat/matroskadec: Reindent after the previous commit Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 17/20] avformat/matroskadec: Factor generic parsing of audio tracks out Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 18/20] avformat/matroskdec: Reindent after the previous commit Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 19/20] avformat/matroskadec: Move WEBVTT code to mkv_parse_subtitle_codec() Andreas Rheinhardt
2023-09-04 11:27 ` [FFmpeg-devel] [PATCH 20/20] avformat/matroskadec: Factor parsing content encodings out Andreas Rheinhardt
2023-09-06  9:37 ` [FFmpeg-devel] [PATCH 01/20] fate/matroska: Add test for remuxing non-rotation displaymatrix 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=AS8P250MB074422E739036D97D081CA6D8FE9A@AS8P250MB0744.EURP250.PROD.OUTLOOK.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