summaryrefslogtreecommitdiff
path: root/libavcodec/wmaprodec.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-09-03 00:46:29 +0200
committerPaul B Mahol <onemda@gmail.com>2021-09-03 00:51:10 +0200
commit646afae00f3a18218dbf691cbc41e1be3cf0e3d8 (patch)
treecf39d85881bd764d3750f3466e439e775b17a7c5 /libavcodec/wmaprodec.c
parenta4101dca6c91cbcbd1bfa0d6fa68ee14737db9b1 (diff)
downloadffmpeg-646afae00f3a18218dbf691cbc41e1be3cf0e3d8.tar.gz
avcodec/wmaprodec: unbreak xma >2 channel decoding after last change
Diffstat (limited to 'libavcodec/wmaprodec.c')
-rw-r--r--libavcodec/wmaprodec.c55
1 files 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]);
}