summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2023-12-02 16:40:36 +0100
committerPaul B Mahol <onemda@gmail.com>2023-12-02 16:51:00 +0100
commit0a13178de81b805bf6b2f3998c7e316cd20a428d (patch)
treeceeb92cbaa2498ad986321fe289a168d9f24672f
parent5230257ea18e1d3761ee6b0549d56a3ca817f301 (diff)
avcodec/qoadec: add support for midstream sample rate/layout changes
-rw-r--r--libavcodec/qoadec.c31
1 files changed, 13 insertions, 18 deletions
diff --git a/libavcodec/qoadec.c b/libavcodec/qoadec.c
index 9b2abae833..443f42a527 100644
--- a/libavcodec/qoadec.c
+++ b/libavcodec/qoadec.c
@@ -34,7 +34,7 @@ typedef struct QOAChannel {
} QOAChannel;
typedef struct QOAContext {
- QOAChannel *ch;
+ QOAChannel ch[256];
} QOAContext;
static const int16_t qoa_dequant_tab[16][8] = {
@@ -58,14 +58,8 @@ static const int16_t qoa_dequant_tab[16][8] = {
static av_cold int qoa_decode_init(AVCodecContext *avctx)
{
- QOAContext *s = avctx->priv_data;
-
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- s->ch = av_calloc(avctx->ch_layout.nb_channels, sizeof(*s->ch));
- if (!s->ch)
- return AVERROR(ENOMEM);
-
return 0;
}
@@ -91,17 +85,26 @@ static int qoa_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int *got_frame_ptr, AVPacket *avpkt)
{
QOAContext *s = avctx->priv_data;
- int ret, frame_size, nb_channels;
+ int ret, frame_size, nb_channels, sample_rate;
GetByteContext gb;
int16_t *samples;
bytestream2_init(&gb, avpkt->data, avpkt->size);
nb_channels = bytestream2_get_byte(&gb);
- if (avctx->ch_layout.nb_channels != nb_channels)
+ sample_rate = bytestream2_get_be24(&gb);
+ if (!sample_rate || !nb_channels)
return AVERROR_INVALIDDATA;
- avctx->sample_rate = bytestream2_get_be24(&gb);
+ if (nb_channels != avctx->ch_layout.nb_channels) {
+ av_channel_layout_uninit(&avctx->ch_layout);
+ av_channel_layout_default(&avctx->ch_layout, nb_channels);
+ if ((ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout)) < 0)
+ return ret;
+ }
+
+ frame->sample_rate = avctx->sample_rate = sample_rate;
+
frame->nb_samples = bytestream2_get_be16(&gb);
frame_size = bytestream2_get_be16(&gb);
if (frame_size > avpkt->size)
@@ -152,13 +155,6 @@ static int qoa_decode_frame(AVCodecContext *avctx, AVFrame *frame,
return avpkt->size;
}
-static av_cold int qoa_decode_end(AVCodecContext *avctx)
-{
- QOAContext *s = avctx->priv_data;
- av_freep(&s->ch);
- return 0;
-}
-
const FFCodec ff_qoa_decoder = {
.p.name = "qoa",
CODEC_LONG_NAME("QOA (Quite OK Audio)"),
@@ -167,7 +163,6 @@ const FFCodec ff_qoa_decoder = {
.priv_data_size = sizeof(QOAContext),
.init = qoa_decode_init,
FF_CODEC_DECODE_CB(qoa_decode_frame),
- .close = qoa_decode_end,
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
AV_CODEC_CAP_DR1,
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,