diff mbox series

[FFmpeg-devel,2/5] avformat/smacker: Create audio streams immediately

Message ID 20200329111325.2686-2-andreas.rheinhardt@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,1/5] avformat/smacker: Read extradata directly into extradata | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Andreas Rheinhardt March 29, 2020, 11:13 a.m. UTC
The Smacker demuxer currently parses several fields that indicate
how many audio streams a file contains. This data is parsed and stored
into arrays in the demuxer's context and although the data is used only
to initialize the audio streams, it is kept for the whole lifetime of
the demuxer.

This has been changed: The data is used directly to create
the audio streams and no longer kept at all.

This also simplifies error handling in case adding a new stream fails:
Several arrays which until now have been allocated between parsing the
data determining how many audio streams to create and actually creating
them would need to be freed in this case. Now the streams are created
first, so freeing is no longer an issue.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavformat/smacker.c | 82 ++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 43 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index 4db3ec326f..b08f7bb4e6 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -51,8 +51,6 @@  typedef struct SmackerContext {
     uint32_t flags;
     uint32_t audio[7];
     uint32_t treesize;
-    uint8_t  aflags[7];
-    uint32_t rates[7];
     uint32_t pad;
     /* frame info */
     uint32_t *frm_size;
@@ -107,7 +105,7 @@  static int smacker_read_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
     SmackerContext *smk = s->priv_data;
-    AVStream *st, *ast[7];
+    AVStream *st;
     int i, ret;
     int tbase;
 
@@ -153,9 +151,45 @@  static int smacker_read_header(AVFormatContext *s)
     if ((ret = ffio_read_size(pb, st->codecpar->extradata, 16)) < 0)
         return ret;
 
+    /* handle possible audio streams */
     for(i = 0; i < 7; i++) {
-        smk->rates[i]  = avio_rl24(pb);
-        smk->aflags[i] = avio_r8(pb);
+        uint32_t rate = avio_rl24(pb);
+        uint8_t aflag = avio_r8(pb);
+
+        smk->indexes[i] = -1;
+
+        if (rate) {
+            AVStream *ast = avformat_new_stream(s, NULL);
+            if (!ast)
+                return AVERROR(ENOMEM);
+
+            smk->indexes[i] = ast->index;
+            ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+            if (aflag & SMK_AUD_BINKAUD) {
+                ast->codecpar->codec_id  = AV_CODEC_ID_BINKAUDIO_RDFT;
+            } else if (aflag & SMK_AUD_USEDCT) {
+                ast->codecpar->codec_id  = AV_CODEC_ID_BINKAUDIO_DCT;
+            } else if (aflag & SMK_AUD_PACKED) {
+                ast->codecpar->codec_id  = AV_CODEC_ID_SMACKAUDIO;
+                ast->codecpar->codec_tag = MKTAG('S', 'M', 'K', 'A');
+            } else {
+                ast->codecpar->codec_id  = AV_CODEC_ID_PCM_U8;
+            }
+            if (aflag & SMK_AUD_STEREO) {
+                ast->codecpar->channels       = 2;
+                ast->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else {
+                ast->codecpar->channels       = 1;
+                ast->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
+            }
+            ast->codecpar->sample_rate = rate;
+            ast->codecpar->bits_per_coded_sample = (aflag & SMK_AUD_16BITS) ? 16 : 8;
+            if (ast->codecpar->bits_per_coded_sample == 16 &&
+                ast->codecpar->codec_id == AV_CODEC_ID_PCM_U8)
+                ast->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
+            avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate
+                    * ast->codecpar->channels * ast->codecpar->bits_per_coded_sample / 8);
+        }
     }
     smk->pad = avio_rl32(pb);
     /* setup data */
@@ -194,44 +228,6 @@  static int smacker_read_header(AVFormatContext *s)
     av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1);
     avpriv_set_pts_info(st, 33, smk->pts_inc, tbase);
     st->duration = smk->frames;
-    /* handle possible audio streams */
-    for(i = 0; i < 7; i++) {
-        smk->indexes[i] = -1;
-        if (smk->rates[i]) {
-            ast[i] = avformat_new_stream(s, NULL);
-            if (!ast[i]) {
-                av_freep(&smk->frm_size);
-                av_freep(&smk->frm_flags);
-                return AVERROR(ENOMEM);
-            }
-            smk->indexes[i] = ast[i]->index;
-            ast[i]->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
-            if (smk->aflags[i] & SMK_AUD_BINKAUD) {
-                ast[i]->codecpar->codec_id = AV_CODEC_ID_BINKAUDIO_RDFT;
-            } else if (smk->aflags[i] & SMK_AUD_USEDCT) {
-                ast[i]->codecpar->codec_id = AV_CODEC_ID_BINKAUDIO_DCT;
-            } else if (smk->aflags[i] & SMK_AUD_PACKED){
-                ast[i]->codecpar->codec_id = AV_CODEC_ID_SMACKAUDIO;
-                ast[i]->codecpar->codec_tag = MKTAG('S', 'M', 'K', 'A');
-            } else {
-                ast[i]->codecpar->codec_id = AV_CODEC_ID_PCM_U8;
-            }
-            if (smk->aflags[i] & SMK_AUD_STEREO) {
-                ast[i]->codecpar->channels       = 2;
-                ast[i]->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
-            } else {
-                ast[i]->codecpar->channels       = 1;
-                ast[i]->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
-            }
-            ast[i]->codecpar->sample_rate = smk->rates[i];
-            ast[i]->codecpar->bits_per_coded_sample = (smk->aflags[i] & SMK_AUD_16BITS) ? 16 : 8;
-            if(ast[i]->codecpar->bits_per_coded_sample == 16 && ast[i]->codecpar->codec_id == AV_CODEC_ID_PCM_U8)
-                ast[i]->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
-            avpriv_set_pts_info(ast[i], 64, 1, ast[i]->codecpar->sample_rate
-                    * ast[i]->codecpar->channels * ast[i]->codecpar->bits_per_coded_sample / 8);
-        }
-    }
-
 
     /* load trees to extradata, they will be unpacked by decoder */
     ret = avio_read(pb, st->codecpar->extradata + 16, st->codecpar->extradata_size - 16);