00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "libavutil/audioconvert.h"
00028 #include "avcodec.h"
00029 #include "internal.h"
00030 #include "bytestream.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00053 static int pcm_bluray_parse_header(AVCodecContext *avctx,
00054 const uint8_t *header)
00055 {
00056 static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 };
00057 static const uint32_t channel_layouts[16] = {
00058 0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND,
00059 AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0,
00060 AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0, AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0
00061 };
00062 static const uint8_t channels[16] = {
00063 0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0
00064 };
00065 uint8_t channel_layout = header[2] >> 4;
00066
00067 if (avctx->debug & FF_DEBUG_PICT_INFO)
00068 av_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n",
00069 header[0], header[1], header[2], header[3]);
00070
00071
00072 avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6];
00073 if (!avctx->bits_per_coded_sample) {
00074 av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (0)\n");
00075 return -1;
00076 }
00077 avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 :
00078 AV_SAMPLE_FMT_S32;
00079
00080
00081 switch (header[2] & 0x0f) {
00082 case 1:
00083 avctx->sample_rate = 48000;
00084 break;
00085 case 4:
00086 avctx->sample_rate = 96000;
00087 break;
00088 case 5:
00089 avctx->sample_rate = 192000;
00090 break;
00091 default:
00092 avctx->sample_rate = 0;
00093 av_log(avctx, AV_LOG_ERROR, "unsupported sample rate (%d)\n",
00094 header[2] & 0x0f);
00095 return -1;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 avctx->channel_layout = channel_layouts[channel_layout];
00105 avctx->channels = channels[channel_layout];
00106 if (!avctx->channels) {
00107 av_log(avctx, AV_LOG_ERROR, "unsupported channel configuration (%d)\n",
00108 channel_layout);
00109 return -1;
00110 }
00111
00112 avctx->bit_rate = avctx->channels * avctx->sample_rate *
00113 avctx->bits_per_coded_sample;
00114
00115 if (avctx->debug & FF_DEBUG_PICT_INFO)
00116 av_dlog(avctx,
00117 "pcm_bluray_parse_header: %d channels, %d bits per sample, %d kHz, %d kbit\n",
00118 avctx->channels, avctx->bits_per_coded_sample,
00119 avctx->sample_rate, avctx->bit_rate);
00120 return 0;
00121 }
00122
00123 typedef struct PCMBRDecode {
00124 AVFrame frame;
00125 } PCMBRDecode;
00126
00127 static av_cold int pcm_bluray_decode_init(AVCodecContext * avctx)
00128 {
00129 PCMBRDecode *s = avctx->priv_data;
00130
00131 avcodec_get_frame_defaults(&s->frame);
00132 avctx->coded_frame = &s->frame;
00133
00134 return 0;
00135 }
00136
00137 static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
00138 int *got_frame_ptr, AVPacket *avpkt)
00139 {
00140 const uint8_t *src = avpkt->data;
00141 int buf_size = avpkt->size;
00142 PCMBRDecode *s = avctx->priv_data;
00143 int num_source_channels, channel, retval;
00144 int sample_size, samples;
00145 int16_t *dst16;
00146 int32_t *dst32;
00147
00148 if (buf_size < 4) {
00149 av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
00150 return -1;
00151 }
00152
00153 if (pcm_bluray_parse_header(avctx, src))
00154 return -1;
00155 src += 4;
00156 buf_size -= 4;
00157
00158
00159 num_source_channels = FFALIGN(avctx->channels, 2);
00160 sample_size = (num_source_channels * (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
00161 samples = buf_size / sample_size;
00162
00163
00164 s->frame.nb_samples = samples;
00165 if ((retval = ff_get_buffer(avctx, &s->frame)) < 0) {
00166 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00167 return retval;
00168 }
00169 dst16 = (int16_t *)s->frame.data[0];
00170 dst32 = (int32_t *)s->frame.data[0];
00171
00172 if (samples) {
00173 switch (avctx->channel_layout) {
00174
00175 case AV_CH_LAYOUT_STEREO:
00176 case AV_CH_LAYOUT_4POINT0:
00177 case AV_CH_LAYOUT_2_2:
00178 samples *= num_source_channels;
00179 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
00180 #if HAVE_BIGENDIAN
00181 memcpy(dst16, src, buf_size);
00182 #else
00183 do {
00184 *dst16++ = bytestream_get_be16(&src);
00185 } while (--samples);
00186 #endif
00187 } else {
00188 do {
00189 *dst32++ = bytestream_get_be24(&src) << 8;
00190 } while (--samples);
00191 }
00192 break;
00193
00194 case AV_CH_LAYOUT_MONO:
00195 case AV_CH_LAYOUT_SURROUND:
00196 case AV_CH_LAYOUT_2_1:
00197 case AV_CH_LAYOUT_5POINT0:
00198 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
00199 do {
00200 #if HAVE_BIGENDIAN
00201 memcpy(dst16, src, avctx->channels * 2);
00202 dst16 += avctx->channels;
00203 src += sample_size;
00204 #else
00205 channel = avctx->channels;
00206 do {
00207 *dst16++ = bytestream_get_be16(&src);
00208 } while (--channel);
00209 src += 2;
00210 #endif
00211 } while (--samples);
00212 } else {
00213 do {
00214 channel = avctx->channels;
00215 do {
00216 *dst32++ = bytestream_get_be24(&src) << 8;
00217 } while (--channel);
00218 src += 3;
00219 } while (--samples);
00220 }
00221 break;
00222
00223 case AV_CH_LAYOUT_5POINT1:
00224 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
00225 do {
00226 dst16[0] = bytestream_get_be16(&src);
00227 dst16[1] = bytestream_get_be16(&src);
00228 dst16[2] = bytestream_get_be16(&src);
00229 dst16[4] = bytestream_get_be16(&src);
00230 dst16[5] = bytestream_get_be16(&src);
00231 dst16[3] = bytestream_get_be16(&src);
00232 dst16 += 6;
00233 } while (--samples);
00234 } else {
00235 do {
00236 dst32[0] = bytestream_get_be24(&src) << 8;
00237 dst32[1] = bytestream_get_be24(&src) << 8;
00238 dst32[2] = bytestream_get_be24(&src) << 8;
00239 dst32[4] = bytestream_get_be24(&src) << 8;
00240 dst32[5] = bytestream_get_be24(&src) << 8;
00241 dst32[3] = bytestream_get_be24(&src) << 8;
00242 dst32 += 6;
00243 } while (--samples);
00244 }
00245 break;
00246
00247 case AV_CH_LAYOUT_7POINT0:
00248 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
00249 do {
00250 dst16[0] = bytestream_get_be16(&src);
00251 dst16[1] = bytestream_get_be16(&src);
00252 dst16[2] = bytestream_get_be16(&src);
00253 dst16[5] = bytestream_get_be16(&src);
00254 dst16[3] = bytestream_get_be16(&src);
00255 dst16[4] = bytestream_get_be16(&src);
00256 dst16[6] = bytestream_get_be16(&src);
00257 dst16 += 7;
00258 src += 2;
00259 } while (--samples);
00260 } else {
00261 do {
00262 dst32[0] = bytestream_get_be24(&src) << 8;
00263 dst32[1] = bytestream_get_be24(&src) << 8;
00264 dst32[2] = bytestream_get_be24(&src) << 8;
00265 dst32[5] = bytestream_get_be24(&src) << 8;
00266 dst32[3] = bytestream_get_be24(&src) << 8;
00267 dst32[4] = bytestream_get_be24(&src) << 8;
00268 dst32[6] = bytestream_get_be24(&src) << 8;
00269 dst32 += 7;
00270 src += 3;
00271 } while (--samples);
00272 }
00273 break;
00274
00275 case AV_CH_LAYOUT_7POINT1:
00276 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
00277 do {
00278 dst16[0] = bytestream_get_be16(&src);
00279 dst16[1] = bytestream_get_be16(&src);
00280 dst16[2] = bytestream_get_be16(&src);
00281 dst16[6] = bytestream_get_be16(&src);
00282 dst16[4] = bytestream_get_be16(&src);
00283 dst16[5] = bytestream_get_be16(&src);
00284 dst16[7] = bytestream_get_be16(&src);
00285 dst16[3] = bytestream_get_be16(&src);
00286 dst16 += 8;
00287 } while (--samples);
00288 } else {
00289 do {
00290 dst32[0] = bytestream_get_be24(&src) << 8;
00291 dst32[1] = bytestream_get_be24(&src) << 8;
00292 dst32[2] = bytestream_get_be24(&src) << 8;
00293 dst32[6] = bytestream_get_be24(&src) << 8;
00294 dst32[4] = bytestream_get_be24(&src) << 8;
00295 dst32[5] = bytestream_get_be24(&src) << 8;
00296 dst32[7] = bytestream_get_be24(&src) << 8;
00297 dst32[3] = bytestream_get_be24(&src) << 8;
00298 dst32 += 8;
00299 } while (--samples);
00300 }
00301 break;
00302 }
00303 }
00304
00305 *got_frame_ptr = 1;
00306 *(AVFrame *)data = s->frame;
00307
00308 retval = src - avpkt->data;
00309 if (avctx->debug & FF_DEBUG_BITSTREAM)
00310 av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
00311 retval, buf_size);
00312 return retval;
00313 }
00314
00315 AVCodec ff_pcm_bluray_decoder = {
00316 .name = "pcm_bluray",
00317 .type = AVMEDIA_TYPE_AUDIO,
00318 .id = CODEC_ID_PCM_BLURAY,
00319 .priv_data_size = sizeof(PCMBRDecode),
00320 .init = pcm_bluray_decode_init,
00321 .decode = pcm_bluray_decode_frame,
00322 .capabilities = CODEC_CAP_DR1,
00323 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
00324 AV_SAMPLE_FMT_NONE},
00325 .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
00326 };