[FFmpeg-cvslog] avcodec/rka: fix decoding uncorrelated stereo

Paul B Mahol git at videolan.org
Wed Feb 15 15:17:41 EET 2023


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Feb 15 14:08:28 2023 +0100| [83a2007f40fdf70e3eb49bd5be6a46c8d223b3df] | committer: Paul B Mahol

avcodec/rka: fix decoding uncorrelated stereo

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

 libavcodec/rka.c | 57 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/libavcodec/rka.c b/libavcodec/rka.c
index 8719325a9e..da4ca52f35 100644
--- a/libavcodec/rka.c
+++ b/libavcodec/rka.c
@@ -90,6 +90,7 @@ typedef struct RKAContext {
     int bps;
     int align;
     int channels;
+    int correlated;
     int frame_samples;
     int last_nb_samples;
     uint32_t total_nb_samples;
@@ -156,6 +157,7 @@ static av_cold int rka_decode_init(AVCodecContext *avctx)
     s->samples_left = s->total_nb_samples = (AV_RL32(avctx->extradata + 4)) / s->align;
     s->frame_samples = 131072 / s->align;
     s->last_nb_samples = s->total_nb_samples % s->frame_samples;
+    s->correlated = avctx->extradata[15] & 1;
 
     cmode = avctx->extradata[14] & 0xf;
     if ((avctx->extradata[15] & 4) != 0)
@@ -859,7 +861,7 @@ static int rka_decode_frame(AVCodecContext *avctx, AVFrame *frame,
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
-    if (s->channels == 2) {
+    if (s->channels == 2 && s->correlated) {
         int16_t *l16 = (int16_t *)frame->extended_data[0];
         int16_t *r16 = (int16_t *)frame->extended_data[1];
         uint8_t *l8 = frame->extended_data[0];
@@ -908,35 +910,38 @@ static int rka_decode_frame(AVCodecContext *avctx, AVFrame *frame,
             n += ret;
         }
     } else {
-        int16_t *m16 = (int16_t *)frame->data[0];
-        uint8_t *m8 = frame->data[0];
-
         for (int n = 0; n < frame->nb_samples;) {
-            ret = decode_ch_samples(avctx, &s->ch[0]);
-            if (ret == 0) {
-                frame->nb_samples = n;
-                break;
-            }
-            if (ret < 0 || n + ret > frame->nb_samples)
-                return AVERROR_INVALIDDATA;
-
-            switch (avctx->sample_fmt) {
-            case AV_SAMPLE_FMT_S16P:
-                for (int i = 0; i < ret; i++) {
-                    int m = s->ch[0].buf0[2560 + i];
-
-                    m16[n + i] = m;
+            for (int ch = 0; ch < s->channels; ch++) {
+                int16_t *m16 = (int16_t *)frame->data[ch];
+                uint8_t *m8 = frame->data[ch];
+
+                ret = decode_ch_samples(avctx, &s->ch[ch]);
+                if (ret == 0) {
+                    frame->nb_samples = n;
+                    break;
                 }
-                break;
-            case AV_SAMPLE_FMT_U8P:
-                for (int i = 0; i < ret; i++) {
-                    int m = s->ch[0].buf0[2560 + i];
 
-                    m8[n + i] = m + 0x7f;
+                if (ret < 0 || n + ret > frame->nb_samples)
+                    return AVERROR_INVALIDDATA;
+
+                switch (avctx->sample_fmt) {
+                case AV_SAMPLE_FMT_S16P:
+                    for (int i = 0; i < ret; i++) {
+                        int m = s->ch[ch].buf0[2560 + i];
+
+                        m16[n + i] = m;
+                    }
+                    break;
+                case AV_SAMPLE_FMT_U8P:
+                    for (int i = 0; i < ret; i++) {
+                        int m = s->ch[ch].buf0[2560 + i];
+
+                        m8[n + i] = m + 0x7f;
+                    }
+                    break;
+                default:
+                    return AVERROR_INVALIDDATA;
                 }
-                break;
-            default:
-                return AVERROR_INVALIDDATA;
             }
 
             n += ret;



More information about the ffmpeg-cvslog mailing list