On Thursday 11 June 2015 05:05:48 am Michael Niedermayer wrote: > Fixes Ticket2758
> + if (avctx->bits_per_coded_sample != 16) { > + avpriv_request_sample(avctx, "Unsupported sample size\n"); 24bit sample is available: http://samples.ffmpeg.org/DVD-Audio/ats.AOB Attached is a variant of my patch from years ago, the lavc part is a revert of an earlier codec removal. This should be a separate codec imo because remuxing to mpeg-ts will fail badly iirc. Carl Eugen
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 4aeb57a..f261ce7 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -359,6 +359,7 @@ enum AVCodecID { AV_CODEC_ID_PCM_S24LE_PLANAR = MKBETAG(24,'P','S','P'), AV_CODEC_ID_PCM_S32LE_PLANAR = MKBETAG(32,'P','S','P'), AV_CODEC_ID_PCM_S16BE_PLANAR = MKBETAG('P','S','P',16), + AV_CODEC_ID_PCM_AOB = MKBETAG('P','A','O','B'), /* various ADPCM codecs */ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 0a4ad0b..3549a66 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -302,6 +302,17 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* we process 40-bit blocks per channel for LXF */ samples_per_block = 2; sample_size = 5; + } else if (avctx->codec_id == AV_CODEC_ID_PCM_AOB) { + if (avctx->bits_per_coded_sample != 20 && + avctx->bits_per_coded_sample != 24) { + av_log(avctx, AV_LOG_ERROR, + "PCM DVD unsupported sample depth %i\n", + avctx->bits_per_coded_sample); + return AVERROR(EINVAL); + } + /* 2 samples are interleaved per block in PCM_DVD */ + samples_per_block = 2; + sample_size = avctx->bits_per_coded_sample * 2 / 8; } if (sample_size == 0) { @@ -459,6 +470,37 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, samples += 2; } break; + case AV_CODEC_ID_PCM_AOB: + { + const uint8_t *src8; + dst_int32_t = (int32_t *)frame->data[0]; + n /= avctx->channels; + switch (avctx->bits_per_coded_sample) { + case 20: + while (n--) { + c = avctx->channels; + src8 = src + 4 * c; + while (c--) { + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8 & 0xf0) << 8); + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ & 0x0f) << 12); + } + src = src8; + } + break; + case 24: + while (n--) { + c = avctx->channels; + src8 = src + 4 * c; + while (c--) { + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); + } + src = src8; + } + break; + } + break; + } case AV_CODEC_ID_PCM_LXF: { int i; @@ -541,6 +583,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ /* Note: Do not forget to add new entries to the Makefile as well. */ PCM_CODEC (PCM_ALAW, AV_SAMPLE_FMT_S16, pcm_alaw, "PCM A-law / G.711 A-law"); +PCM_DECODER(PCM_AOB, AV_SAMPLE_FMT_S32, pcm_aob, "PCM signed 20|24-bit big-endian"); PCM_CODEC (PCM_F32BE, AV_SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian"); PCM_CODEC (PCM_F32LE, AV_SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian"); PCM_CODEC (PCM_F64BE, AV_SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian"); diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index edb134f..6d6c9a9 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -611,7 +611,52 @@ skip: found: if (st->discard >= AVDISCARD_ALL) goto skip; - if (startcode >= 0xa0 && startcode <= 0xaf) { + if (av_match_ext(s->filename, "aob") && lpcm_header_len > 8 && startcode == 0xa0) { + // DVD-A LPCM audio + int sample_rates[] = { 48000, 96000, 192000, + 0, 0, 0, 0, 0, + 44100, 88200, 176400, + 0, 0, 0, 0, 0 }; + avio_skip(s->pb, 2); // Pointer to start of audio frame + avio_skip(s->pb, 1); // Unknown + switch (avio_r8(s->pb) >> 4) { + case 2: + st->codec->codec_id = AV_CODEC_ID_PCM_AOB; + st->codec->bits_per_coded_sample = 24; + break; + case 1: + st->codec->codec_id = AV_CODEC_ID_PCM_AOB; + st->codec->bits_per_coded_sample = 20; + break; + case 0: + st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; + st->codec->bits_per_coded_sample = 16; + break; + default: + len -= 4; + goto skip; + } + st->codec->sample_rate = sample_rates[avio_r8(s->pb) >> 4]; + len -= 5; + if (!st->codec->sample_rate) + goto skip; + avio_skip(s->pb, 1); // Unknown + switch (avio_r8(s->pb)) { + case 0: + st->codec->channels = 1; + st->codec->channel_layout = AV_CH_LAYOUT_MONO; + break; + case 1: + st->codec->channels = 2; + st->codec->channel_layout = AV_CH_LAYOUT_STEREO; + break; + default: + avpriv_request_sample(s, "Multichannel DVD-A LPCM audio"); + return AVERROR_PATCHWELCOME; + } + avio_skip(s->pb, lpcm_header_len - 7); + len -= lpcm_header_len - 5; + } else if (startcode >= 0xa0 && startcode <= 0xaf) { if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) { if (len < 6) goto skip;
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel