avcodec/qoadec: add support for midstream sample rate/layout changes
This commit is contained in:
parent
5230257ea1
commit
0a13178de8
@ -34,7 +34,7 @@ typedef struct QOAChannel {
|
|||||||
} QOAChannel;
|
} QOAChannel;
|
||||||
|
|
||||||
typedef struct QOAContext {
|
typedef struct QOAContext {
|
||||||
QOAChannel *ch;
|
QOAChannel ch[256];
|
||||||
} QOAContext;
|
} QOAContext;
|
||||||
|
|
||||||
static const int16_t qoa_dequant_tab[16][8] = {
|
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)
|
static av_cold int qoa_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
QOAContext *s = avctx->priv_data;
|
|
||||||
|
|
||||||
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,17 +85,26 @@ static int qoa_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
|||||||
int *got_frame_ptr, AVPacket *avpkt)
|
int *got_frame_ptr, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
QOAContext *s = avctx->priv_data;
|
QOAContext *s = avctx->priv_data;
|
||||||
int ret, frame_size, nb_channels;
|
int ret, frame_size, nb_channels, sample_rate;
|
||||||
GetByteContext gb;
|
GetByteContext gb;
|
||||||
int16_t *samples;
|
int16_t *samples;
|
||||||
|
|
||||||
bytestream2_init(&gb, avpkt->data, avpkt->size);
|
bytestream2_init(&gb, avpkt->data, avpkt->size);
|
||||||
|
|
||||||
nb_channels = bytestream2_get_byte(&gb);
|
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;
|
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->nb_samples = bytestream2_get_be16(&gb);
|
||||||
frame_size = bytestream2_get_be16(&gb);
|
frame_size = bytestream2_get_be16(&gb);
|
||||||
if (frame_size > avpkt->size)
|
if (frame_size > avpkt->size)
|
||||||
@ -152,13 +155,6 @@ static int qoa_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
|||||||
return avpkt->size;
|
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 = {
|
const FFCodec ff_qoa_decoder = {
|
||||||
.p.name = "qoa",
|
.p.name = "qoa",
|
||||||
CODEC_LONG_NAME("QOA (Quite OK Audio)"),
|
CODEC_LONG_NAME("QOA (Quite OK Audio)"),
|
||||||
@ -167,7 +163,6 @@ const FFCodec ff_qoa_decoder = {
|
|||||||
.priv_data_size = sizeof(QOAContext),
|
.priv_data_size = sizeof(QOAContext),
|
||||||
.init = qoa_decode_init,
|
.init = qoa_decode_init,
|
||||||
FF_CODEC_DECODE_CB(qoa_decode_frame),
|
FF_CODEC_DECODE_CB(qoa_decode_frame),
|
||||||
.close = qoa_decode_end,
|
|
||||||
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
|
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
|
||||||
AV_CODEC_CAP_DR1,
|
AV_CODEC_CAP_DR1,
|
||||||
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
|
.p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user