1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

pcm: convert to new channel layout API

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
Anton Khirnov
2013-05-07 07:20:32 +02:00
committed by James Almer
parent d2a360c139
commit ac0d207a1a
6 changed files with 94 additions and 69 deletions

View File

@@ -54,14 +54,12 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx,
const uint8_t *header) const uint8_t *header)
{ {
static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 };
static const uint32_t channel_layouts[16] = { static const AVChannelLayout channel_layouts[16] = {
0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, { 0 }, AV_CHANNEL_LAYOUT_MONO, { 0 },
AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2, AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_SURROUND, AV_CHANNEL_LAYOUT_2_1,
AV_CH_LAYOUT_5POINT0, AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0, AV_CHANNEL_LAYOUT_4POINT0, AV_CHANNEL_LAYOUT_2_2, AV_CHANNEL_LAYOUT_5POINT0,
AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0 AV_CHANNEL_LAYOUT_5POINT1, AV_CHANNEL_LAYOUT_7POINT0, AV_CHANNEL_LAYOUT_7POINT1,
}; { 0 }, { 0 }, { 0 }, { 0 },
static const uint8_t channels[16] = {
0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0
}; };
uint8_t channel_layout = header[2] >> 4; uint8_t channel_layout = header[2] >> 4;
@@ -104,21 +102,21 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx,
* differ from the actual meaningful number, e.g. mono audio still has two * differ from the actual meaningful number, e.g. mono audio still has two
* channels, one being empty. * channels, one being empty.
*/ */
avctx->channel_layout = channel_layouts[channel_layout]; av_channel_layout_uninit(&avctx->ch_layout);
avctx->channels = channels[channel_layout]; avctx->ch_layout = channel_layouts[channel_layout];
if (!avctx->channels) { if (!avctx->ch_layout.nb_channels) {
av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n", av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n",
channel_layout); channel_layout);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
avctx->bit_rate = FFALIGN(avctx->channels, 2) * avctx->sample_rate * avctx->bit_rate = FFALIGN(avctx->ch_layout.nb_channels, 2) * avctx->sample_rate *
avctx->bits_per_coded_sample; avctx->bits_per_coded_sample;
if (avctx->debug & FF_DEBUG_PICT_INFO) if (avctx->debug & FF_DEBUG_PICT_INFO)
ff_dlog(avctx, ff_dlog(avctx,
"pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n",
avctx->channels, avctx->bits_per_coded_sample, avctx->ch_layout.nb_channels, avctx->bits_per_coded_sample,
avctx->sample_rate, avctx->bit_rate); avctx->sample_rate, avctx->bit_rate);
return 0; return 0;
} }
@@ -148,7 +146,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
bytestream2_init(&gb, src, buf_size); bytestream2_init(&gb, src, buf_size);
/* There's always an even number of channels in the source */ /* There's always an even number of channels in the source */
num_source_channels = FFALIGN(avctx->channels, 2); num_source_channels = FFALIGN(avctx->ch_layout.nb_channels, 2);
sample_size = (num_source_channels * sample_size = (num_source_channels *
(avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
samples = buf_size / sample_size; samples = buf_size / sample_size;
@@ -161,7 +159,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
dst32 = (int32_t *)frame->data[0]; dst32 = (int32_t *)frame->data[0];
if (samples) { if (samples) {
switch (avctx->channel_layout) { switch (avctx->ch_layout.u.mask) {
/* cases with same number of source and coded channels */ /* cases with same number of source and coded channels */
case AV_CH_LAYOUT_STEREO: case AV_CH_LAYOUT_STEREO:
case AV_CH_LAYOUT_4POINT0: case AV_CH_LAYOUT_4POINT0:
@@ -189,10 +187,10 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
do { do {
#if HAVE_BIGENDIAN #if HAVE_BIGENDIAN
bytestream2_get_buffer(&gb, dst16, avctx->channels * 2); bytestream2_get_buffer(&gb, dst16, avctx->ch_layout.nb_channels * 2);
dst16 += avctx->channels; dst16 += avctx->ch_layout.nb_channels;
#else #else
channel = avctx->channels; channel = avctx->ch_layout.nb_channels;
do { do {
*dst16++ = bytestream2_get_be16u(&gb); *dst16++ = bytestream2_get_be16u(&gb);
} while (--channel); } while (--channel);
@@ -201,7 +199,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
} while (--samples); } while (--samples);
} else { } else {
do { do {
channel = avctx->channels; channel = avctx->ch_layout.nb_channels;
do { do {
*dst32++ = bytestream2_get_be24u(&gb) << 8; *dst32++ = bytestream2_get_be24u(&gb) << 8;
} while (--channel); } while (--channel);

View File

@@ -61,7 +61,7 @@ static av_cold int pcm_bluray_encode_init(AVCodecContext *avctx)
return AVERROR_BUG; return AVERROR_BUG;
} }
switch (avctx->channel_layout) { switch (avctx->ch_layout.u.mask) {
case AV_CH_LAYOUT_MONO: case AV_CH_LAYOUT_MONO:
ch_layout = 1; ch_layout = 1;
break; break;
@@ -112,7 +112,7 @@ static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
PutByteContext pb; PutByteContext pb;
int ret; int ret;
num_dest_channels = FFALIGN(avctx->channels, 2); num_dest_channels = FFALIGN(avctx->ch_layout.nb_channels, 2);
sample_size = (num_dest_channels * sample_size = (num_dest_channels *
(avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
samples = frame->nb_samples; samples = frame->nb_samples;
@@ -130,7 +130,7 @@ static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
bytestream2_init_writer(&pb, avpkt->data + 4, avpkt->size - 4); bytestream2_init_writer(&pb, avpkt->data + 4, avpkt->size - 4);
switch (avctx->channel_layout) { switch (avctx->ch_layout.u.mask) {
/* cases with same number of source and coded channels */ /* cases with same number of source and coded channels */
case AV_CH_LAYOUT_STEREO: case AV_CH_LAYOUT_STEREO:
case AV_CH_LAYOUT_4POINT0: case AV_CH_LAYOUT_4POINT0:
@@ -158,10 +158,10 @@ static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
do { do {
#if HAVE_BIGENDIAN #if HAVE_BIGENDIAN
bytestream2_put_bufferu(&pb, (const uint8_t *)src16, avctx->channels * 2); bytestream2_put_bufferu(&pb, (const uint8_t *)src16, avctx->ch_layout.nb_channels * 2);
src16 += avctx->channels; src16 += avctx->ch_layout.nb_channels;
#else #else
channel = avctx->channels; channel = avctx->ch_layout.nb_channels;
do { do {
bytestream2_put_be16u(&pb, *src16++); bytestream2_put_be16u(&pb, *src16++);
} while (--channel); } while (--channel);
@@ -170,7 +170,7 @@ static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
} while (--samples); } while (--samples);
} else { } else {
do { do {
channel = avctx->channels; channel = avctx->ch_layout.nb_channels;
do { do {
bytestream2_put_be24u(&pb, (*src32++) >> 8); bytestream2_put_be24u(&pb, (*src32++) >> 8);
} while (--channel); } while (--channel);
@@ -278,6 +278,7 @@ const AVCodec ff_pcm_bluray_encoder = {
.init = pcm_bluray_encode_init, .init = pcm_bluray_encode_init,
.encode2 = pcm_bluray_encode_frame, .encode2 = pcm_bluray_encode_frame,
.supported_samplerates = (const int[]) { 48000, 96000, 192000, 0 }, .supported_samplerates = (const int[]) { 48000, 96000, 192000, 0 },
#if FF_API_OLD_CHANNEL_LAYOUT
.channel_layouts = (const uint64_t[]) { .channel_layouts = (const uint64_t[]) {
AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO,
@@ -290,6 +291,19 @@ const AVCodec ff_pcm_bluray_encoder = {
AV_CH_LAYOUT_7POINT0, AV_CH_LAYOUT_7POINT0,
AV_CH_LAYOUT_7POINT1, AV_CH_LAYOUT_7POINT1,
0 }, 0 },
#endif
.ch_layouts = (const AVChannelLayout[]) {
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
AV_CHANNEL_LAYOUT_SURROUND,
AV_CHANNEL_LAYOUT_2_1,
AV_CHANNEL_LAYOUT_4POINT0,
AV_CHANNEL_LAYOUT_2_2,
AV_CHANNEL_LAYOUT_5POINT0,
AV_CHANNEL_LAYOUT_5POINT1,
AV_CHANNEL_LAYOUT_7POINT0,
AV_CHANNEL_LAYOUT_7POINT1,
{ 0 } },
.sample_fmts = (const enum AVSampleFormat[]) { .sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE },
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,

View File

@@ -55,6 +55,7 @@ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
static const uint32_t frequencies[4] = { 48000, 96000, 44100, 32000 }; static const uint32_t frequencies[4] = { 48000, 96000, 44100, 32000 };
PCMDVDContext *s = avctx->priv_data; PCMDVDContext *s = avctx->priv_data;
int header_int = (header[0] & 0xe0) | (header[1] << 8) | (header[2] << 16); int header_int = (header[0] & 0xe0) | (header[1] << 8) | (header[2] << 16);
int channels;
/* early exit if the header didn't change apart from the frame number */ /* early exit if the header didn't change apart from the frame number */
if (s->last_header == header_int) if (s->last_header == header_int)
@@ -89,9 +90,12 @@ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
avctx->sample_rate = frequencies[header[1] >> 4 & 3]; avctx->sample_rate = frequencies[header[1] >> 4 & 3];
/* get the number of channels */ /* get the number of channels */
avctx->channels = 1 + (header[1] & 7); channels = 1 + (header[1] & 7);
av_channel_layout_uninit(&avctx->ch_layout);
av_channel_layout_default(&avctx->ch_layout, channels);
/* calculate the bitrate */ /* calculate the bitrate */
avctx->bit_rate = avctx->channels * avctx->bit_rate = channels *
avctx->sample_rate * avctx->sample_rate *
avctx->bits_per_coded_sample; avctx->bits_per_coded_sample;
@@ -100,15 +104,15 @@ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
* needed to complete a set of samples for each channel. */ * needed to complete a set of samples for each channel. */
if (avctx->bits_per_coded_sample == 16) { if (avctx->bits_per_coded_sample == 16) {
s->samples_per_block = 1; s->samples_per_block = 1;
s->block_size = avctx->channels * 2; s->block_size = channels * 2;
} else { } else {
switch (avctx->channels) { switch (channels) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
/* one group has all the samples needed */ /* one group has all the samples needed */
s->block_size = 4 * avctx->bits_per_coded_sample / 8; s->block_size = 4 * avctx->bits_per_coded_sample / 8;
s->samples_per_block = 4 / avctx->channels; s->samples_per_block = 4 / channels;
s->groups_per_block = 1; s->groups_per_block = 1;
break; break;
case 8: case 8:
@@ -118,11 +122,11 @@ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
s->groups_per_block = 2; s->groups_per_block = 2;
break; break;
default: default:
/* need avctx->channels groups */ /* need channels groups */
s->block_size = 4 * avctx->channels * s->block_size = 4 * channels *
avctx->bits_per_coded_sample / 8; avctx->bits_per_coded_sample / 8;
s->samples_per_block = 4; s->samples_per_block = 4;
s->groups_per_block = avctx->channels; s->groups_per_block = channels;
break; break;
} }
} }
@@ -130,7 +134,7 @@ static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
if (avctx->debug & FF_DEBUG_PICT_INFO) if (avctx->debug & FF_DEBUG_PICT_INFO)
ff_dlog(avctx, ff_dlog(avctx,
"pcm_dvd_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", "pcm_dvd_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n",
avctx->channels, avctx->bits_per_coded_sample, avctx->ch_layout.nb_channels, avctx->bits_per_coded_sample,
avctx->sample_rate, avctx->bit_rate); avctx->sample_rate, avctx->bit_rate);
s->last_header = header_int; s->last_header = header_int;
@@ -155,7 +159,7 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src,
bytestream2_get_buffer(&gb, dst16, blocks * s->block_size); bytestream2_get_buffer(&gb, dst16, blocks * s->block_size);
dst16 += blocks * s->block_size / 2; dst16 += blocks * s->block_size / 2;
#else #else
int samples = blocks * avctx->channels; int samples = blocks * avctx->ch_layout.nb_channels;
do { do {
*dst16++ = bytestream2_get_be16u(&gb); *dst16++ = bytestream2_get_be16u(&gb);
} while (--samples); } while (--samples);
@@ -163,7 +167,7 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src,
return dst16; return dst16;
} }
case 20: case 20:
if (avctx->channels == 1) { if (avctx->ch_layout.nb_channels == 1) {
do { do {
for (i = 2; i; i--) { for (i = 2; i; i--) {
dst32[0] = bytestream2_get_be16u(&gb) << 16; dst32[0] = bytestream2_get_be16u(&gb) << 16;
@@ -191,7 +195,7 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src,
} }
return dst32; return dst32;
case 24: case 24:
if (avctx->channels == 1) { if (avctx->ch_layout.nb_channels == 1) {
do { do {
for (i = 2; i; i--) { for (i = 2; i; i--) {
dst32[0] = bytestream2_get_be16u(&gb) << 16; dst32[0] = bytestream2_get_be16u(&gb) << 16;

View File

@@ -60,7 +60,7 @@ static av_cold int pcm_dvd_encode_init(AVCodecContext *avctx)
} }
avctx->bits_per_coded_sample = 16 + quant * 4; avctx->bits_per_coded_sample = 16 + quant * 4;
avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8; avctx->block_align = avctx->ch_layout.nb_channels * avctx->bits_per_coded_sample / 8;
avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate; avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate;
if (avctx->bit_rate > 9800000) { if (avctx->bit_rate > 9800000) {
av_log(avctx, AV_LOG_ERROR, "Too big bitrate: reduce sample rate, bitdepth or channels.\n"); av_log(avctx, AV_LOG_ERROR, "Too big bitrate: reduce sample rate, bitdepth or channels.\n");
@@ -69,16 +69,16 @@ static av_cold int pcm_dvd_encode_init(AVCodecContext *avctx)
if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) { if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
s->samples_per_block = 1; s->samples_per_block = 1;
s->block_size = avctx->channels * 2; s->block_size = avctx->ch_layout.nb_channels * 2;
frame_size = 2008 / s->block_size; frame_size = 2008 / s->block_size;
} else { } else {
switch (avctx->channels) { switch (avctx->ch_layout.nb_channels) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
/* one group has all the samples needed */ /* one group has all the samples needed */
s->block_size = 4 * avctx->bits_per_coded_sample / 8; s->block_size = 4 * avctx->bits_per_coded_sample / 8;
s->samples_per_block = 4 / avctx->channels; s->samples_per_block = 4 / avctx->ch_layout.nb_channels;
s->groups_per_block = 1; s->groups_per_block = 1;
break; break;
case 8: case 8:
@@ -88,11 +88,11 @@ static av_cold int pcm_dvd_encode_init(AVCodecContext *avctx)
s->groups_per_block = 2; s->groups_per_block = 2;
break; break;
default: default:
/* need avctx->channels groups */ /* need avctx->ch_layout.nb_channels groups */
s->block_size = 4 * avctx->channels * s->block_size = 4 * avctx->ch_layout.nb_channels *
avctx->bits_per_coded_sample / 8; avctx->bits_per_coded_sample / 8;
s->samples_per_block = 4; s->samples_per_block = 4;
s->groups_per_block = avctx->channels; s->groups_per_block = avctx->ch_layout.nb_channels;
break; break;
} }
@@ -100,7 +100,7 @@ static av_cold int pcm_dvd_encode_init(AVCodecContext *avctx)
} }
s->header[0] = 0x0c; s->header[0] = 0x0c;
s->header[1] = (quant << 6) | (freq << 4) | (avctx->channels - 1); s->header[1] = (quant << 6) | (freq << 4) | (avctx->ch_layout.nb_channels - 1);
s->header[2] = 0x80; s->header[2] = 0x80;
if (!avctx->frame_size) if (!avctx->frame_size)
@@ -113,7 +113,7 @@ static int pcm_dvd_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr) const AVFrame *frame, int *got_packet_ptr)
{ {
PCMDVDContext *s = avctx->priv_data; PCMDVDContext *s = avctx->priv_data;
int samples = frame->nb_samples * avctx->channels; int samples = frame->nb_samples * avctx->ch_layout.nb_channels;
int64_t pkt_size = (frame->nb_samples / s->samples_per_block) * s->block_size + 3; int64_t pkt_size = (frame->nb_samples / s->samples_per_block) * s->block_size + 3;
int blocks = (pkt_size - 3) / s->block_size; int blocks = (pkt_size - 3) / s->block_size;
const int16_t *src16; const int16_t *src16;
@@ -138,7 +138,7 @@ static int pcm_dvd_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
} while (--samples); } while (--samples);
break; break;
case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_S32:
if (avctx->channels == 1) { if (avctx->ch_layout.nb_channels == 1) {
do { do {
for (int i = 2; i; i--) { for (int i = 2; i; i--) {
bytestream2_put_be16(&pb, src32[0] >> 16); bytestream2_put_be16(&pb, src32[0] >> 16);
@@ -181,11 +181,18 @@ const AVCodec ff_pcm_dvd_encoder = {
.init = pcm_dvd_encode_init, .init = pcm_dvd_encode_init,
.encode2 = pcm_dvd_encode_frame, .encode2 = pcm_dvd_encode_frame,
.supported_samplerates = (const int[]) { 48000, 96000, 0}, .supported_samplerates = (const int[]) { 48000, 96000, 0},
#if FF_API_OLD_CHANNEL_LAYOUT
.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_5POINT1,
AV_CH_LAYOUT_7POINT1, AV_CH_LAYOUT_7POINT1,
0 }, 0 },
#endif
.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
AV_CHANNEL_LAYOUT_5POINT1,
AV_CHANNEL_LAYOUT_7POINT1,
{ 0 } },
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32,
AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE },

View File

@@ -56,7 +56,7 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx)
#endif #endif
avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8; avctx->block_align = avctx->ch_layout.nb_channels * avctx->bits_per_coded_sample / 8;
avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate; avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate;
return 0; return 0;
@@ -80,8 +80,8 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx)
} }
#define ENCODE_PLANAR(type, endian, dst, n, shift, offset) \ #define ENCODE_PLANAR(type, endian, dst, n, shift, offset) \
n /= avctx->channels; \ n /= avctx->ch_layout.nb_channels; \
for (c = 0; c < avctx->channels; c++) { \ for (c = 0; c < avctx->ch_layout.nb_channels; c++) { \
int i; \ int i; \
samples_ ## type = (const type *) frame->extended_data[c]; \ samples_ ## type = (const type *) frame->extended_data[c]; \
for (i = n; i > 0; i--) { \ for (i = n; i > 0; i--) { \
@@ -104,7 +104,7 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const uint32_t *samples_uint32_t; const uint32_t *samples_uint32_t;
sample_size = av_get_bits_per_sample(avctx->codec->id) / 8; sample_size = av_get_bits_per_sample(avctx->codec->id) / 8;
n = frame->nb_samples * avctx->channels; n = frame->nb_samples * avctx->ch_layout.nb_channels;
samples = (const short *)frame->data[0]; samples = (const short *)frame->data[0];
if ((ret = ff_get_encode_buffer(avctx, avpkt, n * sample_size, 0)) < 0) if ((ret = ff_get_encode_buffer(avctx, avpkt, n * sample_size, 0)) < 0)
@@ -207,8 +207,8 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
case AV_CODEC_ID_PCM_S16LE_PLANAR: case AV_CODEC_ID_PCM_S16LE_PLANAR:
case AV_CODEC_ID_PCM_S32LE_PLANAR: case AV_CODEC_ID_PCM_S32LE_PLANAR:
#endif /* HAVE_BIGENDIAN */ #endif /* HAVE_BIGENDIAN */
n /= avctx->channels; n /= avctx->ch_layout.nb_channels;
for (c = 0; c < avctx->channels; c++) { for (c = 0; c < avctx->ch_layout.nb_channels; c++) {
const uint8_t *src = frame->extended_data[c]; const uint8_t *src = frame->extended_data[c];
bytestream_put_buffer(&dst, src, n * sample_size); bytestream_put_buffer(&dst, src, n * sample_size);
} }
@@ -252,7 +252,7 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
AVFloatDSPContext *fdsp; AVFloatDSPContext *fdsp;
int i; int i;
if (avctx->channels <= 0) { if (avctx->ch_layout.nb_channels <= 0) {
av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
@@ -312,8 +312,8 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
} }
#define DECODE_PLANAR(size, endian, src, dst, n, shift, offset) \ #define DECODE_PLANAR(size, endian, src, dst, n, shift, offset) \
n /= avctx->channels; \ n /= channels; \
for (c = 0; c < avctx->channels; c++) { \ for (c = 0; c < avctx->ch_layout.nb_channels; c++) { \
int i; \ int i; \
dst = frame->extended_data[c]; \ dst = frame->extended_data[c]; \
for (i = n; i > 0; i--) { \ for (i = n; i > 0; i--) { \
@@ -330,6 +330,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
int buf_size = avpkt->size; int buf_size = avpkt->size;
PCMDecode *s = avctx->priv_data; PCMDecode *s = avctx->priv_data;
AVFrame *frame = data; AVFrame *frame = data;
int channels = avctx->ch_layout.nb_channels;
int sample_size, c, n, ret, samples_per_block; int sample_size, c, n, ret, samples_per_block;
uint8_t *samples; uint8_t *samples;
int32_t *dst_int32_t; int32_t *dst_int32_t;
@@ -349,7 +350,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if (avctx->channels == 0) { if (channels == 0) {
av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
@@ -359,7 +360,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
n = avctx->channels * sample_size; n = channels * sample_size;
if (n && buf_size % n) { if (n && buf_size % n) {
if (buf_size < n) { if (buf_size < n) {
@@ -374,7 +375,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
n = buf_size / sample_size; n = buf_size / sample_size;
/* get output buffer */ /* get output buffer */
frame->nb_samples = n * samples_per_block / avctx->channels; frame->nb_samples = n * samples_per_block / channels;
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret; return ret;
samples = frame->data[0]; samples = frame->data[0];
@@ -429,8 +430,8 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
} }
break; break;
case AV_CODEC_ID_PCM_S8_PLANAR: case AV_CODEC_ID_PCM_S8_PLANAR:
n /= avctx->channels; n /= avctx->ch_layout.nb_channels;
for (c = 0; c < avctx->channels; c++) { for (c = 0; c < avctx->ch_layout.nb_channels; c++) {
int i; int i;
samples = frame->extended_data[c]; samples = frame->extended_data[c];
for (i = n; i > 0; i--) for (i = n; i > 0; i--)
@@ -494,8 +495,8 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
case AV_CODEC_ID_PCM_S16LE_PLANAR: case AV_CODEC_ID_PCM_S16LE_PLANAR:
case AV_CODEC_ID_PCM_S32LE_PLANAR: case AV_CODEC_ID_PCM_S32LE_PLANAR:
#endif /* HAVE_BIGENDIAN */ #endif /* HAVE_BIGENDIAN */
n /= avctx->channels; n /= avctx->ch_layout.nb_channels;
for (c = 0; c < avctx->channels; c++) { for (c = 0; c < avctx->ch_layout.nb_channels; c++) {
samples = frame->extended_data[c]; samples = frame->extended_data[c];
bytestream_get_buffer(&src, samples, n * sample_size); bytestream_get_buffer(&src, samples, n * sample_size);
} }
@@ -511,8 +512,8 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
case AV_CODEC_ID_PCM_LXF: case AV_CODEC_ID_PCM_LXF:
{ {
int i; int i;
n /= avctx->channels; n /= channels;
for (c = 0; c < avctx->channels; c++) { for (c = 0; c < channels; c++) {
dst_int32_t = (int32_t *)frame->extended_data[c]; dst_int32_t = (int32_t *)frame->extended_data[c];
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
// extract low 20 bits and expand to 32 bits // extract low 20 bits and expand to 32 bits
@@ -540,7 +541,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
avctx->codec_id == AV_CODEC_ID_PCM_F24LE) { avctx->codec_id == AV_CODEC_ID_PCM_F24LE) {
s->vector_fmul_scalar((float *)frame->extended_data[0], s->vector_fmul_scalar((float *)frame->extended_data[0],
(const float *)frame->extended_data[0], (const float *)frame->extended_data[0],
s->scale, FFALIGN(frame->nb_samples * avctx->channels, 4)); s->scale, FFALIGN(frame->nb_samples * avctx->ch_layout.nb_channels, 4));
emms_c(); emms_c();
} }

View File

@@ -42,11 +42,12 @@ static int init(AVBSFContext *ctx)
AVRational sr = av_make_q(ctx->par_in->sample_rate, 1); AVRational sr = av_make_q(ctx->par_in->sample_rate, 1);
int64_t min_samples; int64_t min_samples;
if (ctx->par_in->channels <= 0 || ctx->par_in->sample_rate <= 0) if (ctx->par_in->ch_layout.nb_channels <= 0 || ctx->par_in->sample_rate <= 0)
return AVERROR(EINVAL); return AVERROR(EINVAL);
ctx->time_base_out = av_inv_q(sr); ctx->time_base_out = av_inv_q(sr);
s->sample_size = ctx->par_in->channels * av_get_bits_per_sample(ctx->par_in->codec_id) / 8; s->sample_size = ctx->par_in->ch_layout.nb_channels *
av_get_bits_per_sample(ctx->par_in->codec_id) / 8;
if (s->frame_rate.num) { if (s->frame_rate.num) {
min_samples = av_rescale_q_rnd(1, sr, s->frame_rate, AV_ROUND_DOWN); min_samples = av_rescale_q_rnd(1, sr, s->frame_rate, AV_ROUND_DOWN);