[FFmpeg-cvslog] avcodec/wmaprodec: unbreak xma >2 channel decoding after last change

Paul B Mahol git at videolan.org
Fri Sep 3 01:51:20 EEST 2021


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Sep  3 00:46:29 2021 +0200| [646afae00f3a18218dbf691cbc41e1be3cf0e3d8] | committer: Paul B Mahol

avcodec/wmaprodec: unbreak xma >2 channel decoding after last change

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=646afae00f3a18218dbf691cbc41e1be3cf0e3d8
---

 libavcodec/wmaprodec.c | 55 +++++++++++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 30 deletions(-)

diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 14a48db45a..97ad8782c2 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -249,7 +249,7 @@ typedef struct XMADecodeCtx {
     AVFrame *frames[XMA_MAX_STREAMS];
     int current_stream;
     int num_streams;
-    AVAudioFifo *samples[2][XMA_MAX_CHANNELS];
+    AVAudioFifo *samples[2][XMA_MAX_STREAMS];
     int start_channel[XMA_MAX_STREAMS];
     int trim_start, trim_end;
 } XMADecodeCtx;
@@ -1829,7 +1829,7 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data,
     XMADecodeCtx *s = avctx->priv_data;
     int got_stream_frame_ptr = 0;
     AVFrame *frame = data;
-    int i, ret, eof;
+    int i, ret, eof = 1;
 
     if (!s->frames[s->current_stream]->data[0]) {
         avctx->internal->skip_samples = 64;
@@ -1846,22 +1846,21 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data,
     /* decode current stream packet */
     ret = decode_packet(avctx, &s->xma[s->current_stream], s->frames[s->current_stream],
                         &got_stream_frame_ptr, avpkt);
-    eof = s->xma[s->current_stream].eof_done;
-    if (s->xma[s->current_stream].trim_start)
-        s->trim_start = s->xma[s->current_stream].trim_start;
-    if (s->xma[s->current_stream].trim_end)
-        s->trim_end = s->xma[s->current_stream].trim_end;
+
+    if (s->xma[0].trim_start)
+        s->trim_start = s->xma[0].trim_start;
+    if (s->xma[0].trim_end)
+        s->trim_end = s->xma[0].trim_end;
 
     /* copy stream samples (1/2ch) to sample buffer (Nch) */
     if (got_stream_frame_ptr) {
-        int start_ch = s->start_channel[s->current_stream];
         const int nb_samples = s->frames[s->current_stream]->nb_samples;
         void *left[1] = { s->frames[s->current_stream]->extended_data[0] };
         void *right[1] = { s->frames[s->current_stream]->extended_data[1] };
 
-        av_audio_fifo_write(s->samples[0][start_ch + 0], left, nb_samples);
+        av_audio_fifo_write(s->samples[0][s->current_stream], left, nb_samples);
         if (s->xma[s->current_stream].nb_channels > 1)
-            av_audio_fifo_write(s->samples[1][start_ch + 1], right, nb_samples);
+            av_audio_fifo_write(s->samples[1][s->current_stream], right, nb_samples);
     } else if (ret < 0) {
         s->current_stream = 0;
         return ret;
@@ -1892,37 +1891,33 @@ static int xma_decode_packet(AVCodecContext *avctx, void *data,
         }
 
         /* all other streams skip next packet */
-        for (i = 0; i < s->num_streams; i++)
-            s->xma[i].skip_packets = FFMAX(0, s->xma[i].skip_packets - 1);
-
         for (i = 0; i < s->num_streams; i++) {
-            int start_ch = s->start_channel[s->current_stream];
-
-            nb_samples = FFMIN(nb_samples, av_audio_fifo_size(s->samples[0][start_ch]));
+            eof &= s->xma[i].eof_done;
+            s->xma[i].skip_packets = FFMAX(0, s->xma[i].skip_packets - 1);
+            nb_samples = FFMIN(nb_samples, av_audio_fifo_size(s->samples[0][i]));
         }
 
         /* copy samples from buffer to output if possible */
-        if (nb_samples > 4096 || eof) {
+        if (nb_samples > 8192 || eof || !avpkt->size) {
             int bret;
 
-            if (eof) {
-                nb_samples -= FFMIN(nb_samples, s->trim_end + s->trim_start - 128 - 64);
+            if (!avpkt->size) {
+                nb_samples -= s->trim_end + s->trim_start - 128 - 64;
                 s->trim_end = s->trim_start = 0;
             }
+
             frame->nb_samples = nb_samples;
-            if (frame->nb_samples <= 0)
-                return ret;
             if ((bret = ff_get_buffer(avctx, frame, 0)) < 0)
                 return bret;
 
             for (i = 0; i < s->num_streams; i++) {
-                const int start_ch = s->start_channel[s->current_stream];
-                void *left[1] = { frame->extended_data[0] };
-                void *right[1] = { frame->extended_data[1] };
+                const int start_ch = s->start_channel[i];
+                void *left[1] = { frame->extended_data[start_ch + 0] };
+                void *right[1] = { frame->extended_data[start_ch + 1] };
 
-                av_audio_fifo_read(s->samples[0][start_ch + 0], left, nb_samples);
-                if (s->xma[s->current_stream].nb_channels > 1)
-                    av_audio_fifo_read(s->samples[1][start_ch + 1], right, nb_samples);
+                av_audio_fifo_read(s->samples[0][i], left, nb_samples);
+                if (s->xma[i].nb_channels > 1)
+                    av_audio_fifo_read(s->samples[1][i], right, nb_samples);
             }
 
             *got_frame_ptr = 1;
@@ -1986,7 +1981,7 @@ static av_cold int xma_decode_init(AVCodecContext *avctx)
     if (start_channels != avctx->channels)
         return AVERROR_INVALIDDATA;
 
-    for (int i = 0; i < XMA_MAX_CHANNELS; i++) {
+    for (int i = 0; i < XMA_MAX_STREAMS; i++) {
         s->samples[0][i] = av_audio_fifo_alloc(avctx->sample_fmt, 1, 64 * 512);
         s->samples[1][i] = av_audio_fifo_alloc(avctx->sample_fmt, 1, 64 * 512);
         if (!s->samples[0][i] || !s->samples[1][i])
@@ -2007,7 +2002,7 @@ static av_cold int xma_decode_end(AVCodecContext *avctx)
     }
     s->num_streams = 0;
 
-    for (i = 0; i < XMA_MAX_CHANNELS; i++) {
+    for (i = 0; i < XMA_MAX_STREAMS; i++) {
         av_audio_fifo_free(s->samples[0][i]);
         av_audio_fifo_free(s->samples[1][i]);
     }
@@ -2045,7 +2040,7 @@ static void xma_flush(AVCodecContext *avctx)
     XMADecodeCtx *s = avctx->priv_data;
     int i;
 
-    for (i = 0; i < XMA_MAX_CHANNELS; i++) {
+    for (i = 0; i < XMA_MAX_STREAMS; i++) {
         av_audio_fifo_reset(s->samples[0][i]);
         av_audio_fifo_reset(s->samples[1][i]);
     }



More information about the ffmpeg-cvslog mailing list