|
|
|
@ -119,17 +119,30 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int pcm_bluray_decode_frame(AVCodecContext *avctx, |
|
|
|
|
void *data, |
|
|
|
|
int *data_size, |
|
|
|
|
AVPacket *avpkt) |
|
|
|
|
typedef struct PCMBRDecode { |
|
|
|
|
AVFrame frame; |
|
|
|
|
} PCMBRDecode; |
|
|
|
|
|
|
|
|
|
static av_cold int pcm_bluray_decode_init(AVCodecContext * avctx) |
|
|
|
|
{ |
|
|
|
|
PCMBRDecode *s = avctx->priv_data; |
|
|
|
|
|
|
|
|
|
avcodec_get_frame_defaults(&s->frame); |
|
|
|
|
avctx->coded_frame = &s->frame; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
int *got_frame_ptr, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
|
const uint8_t *src = avpkt->data; |
|
|
|
|
int buf_size = avpkt->size; |
|
|
|
|
PCMBRDecode *s = avctx->priv_data; |
|
|
|
|
int num_source_channels, channel, retval; |
|
|
|
|
int sample_size, samples, output_size; |
|
|
|
|
int16_t *dst16 = data; |
|
|
|
|
int32_t *dst32 = data; |
|
|
|
|
int sample_size, samples; |
|
|
|
|
int16_t *dst16; |
|
|
|
|
int32_t *dst32; |
|
|
|
|
|
|
|
|
|
if (buf_size < 4) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); |
|
|
|
@ -146,15 +159,14 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, |
|
|
|
|
sample_size = (num_source_channels * avctx->bits_per_coded_sample) >> 3; |
|
|
|
|
samples = buf_size / sample_size; |
|
|
|
|
|
|
|
|
|
output_size = samples * avctx->channels * |
|
|
|
|
(avctx->sample_fmt == AV_SAMPLE_FMT_S32 ? 4 : 2); |
|
|
|
|
if (output_size > *data_size) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, |
|
|
|
|
"Insufficient output buffer space (%d bytes, needed %d bytes)\n", |
|
|
|
|
*data_size, output_size); |
|
|
|
|
return -1; |
|
|
|
|
/* get output buffer */ |
|
|
|
|
s->frame.nb_samples = samples; |
|
|
|
|
if ((retval = avctx->get_buffer(avctx, &s->frame)) < 0) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
|
|
|
|
return retval; |
|
|
|
|
} |
|
|
|
|
*data_size = output_size; |
|
|
|
|
dst16 = (int16_t *)s->frame.data[0]; |
|
|
|
|
dst32 = (int32_t *)s->frame.data[0]; |
|
|
|
|
|
|
|
|
|
if (samples) { |
|
|
|
|
switch (avctx->channel_layout) { |
|
|
|
@ -165,7 +177,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, |
|
|
|
|
samples *= num_source_channels; |
|
|
|
|
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { |
|
|
|
|
#if HAVE_BIGENDIAN |
|
|
|
|
memcpy(dst16, src, output_size); |
|
|
|
|
memcpy(dst16, src, buf_size); |
|
|
|
|
#else |
|
|
|
|
do { |
|
|
|
|
*dst16++ = bytestream_get_be16(&src); |
|
|
|
@ -289,10 +301,13 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*got_frame_ptr = 1; |
|
|
|
|
*(AVFrame *)data = s->frame; |
|
|
|
|
|
|
|
|
|
retval = src - avpkt->data; |
|
|
|
|
if (avctx->debug & FF_DEBUG_BITSTREAM) |
|
|
|
|
av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", |
|
|
|
|
retval, *data_size); |
|
|
|
|
retval, buf_size); |
|
|
|
|
return retval; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -300,7 +315,10 @@ AVCodec ff_pcm_bluray_decoder = { |
|
|
|
|
.name = "pcm_bluray", |
|
|
|
|
.type = AVMEDIA_TYPE_AUDIO, |
|
|
|
|
.id = CODEC_ID_PCM_BLURAY, |
|
|
|
|
.priv_data_size = sizeof(PCMBRDecode), |
|
|
|
|
.init = pcm_bluray_decode_init, |
|
|
|
|
.decode = pcm_bluray_decode_frame, |
|
|
|
|
.capabilities = CODEC_CAP_DR1, |
|
|
|
|
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, |
|
|
|
|
AV_SAMPLE_FMT_NONE}, |
|
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"), |
|
|
|
|