summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2023-02-15 14:08:28 +0100
committerPaul B Mahol <onemda@gmail.com>2023-02-15 14:16:49 +0100
commit83a2007f40fdf70e3eb49bd5be6a46c8d223b3df (patch)
tree5c5e85a509a62c51dc6ac118061124bd6a7ff46e
parentcb350367660032e2e47fa379a3f119ddf60eb029 (diff)
avcodec/rka: fix decoding uncorrelated stereo
-rw-r--r--libavcodec/rka.c57
1 files 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;