1/* 2 * LPCM codecs for PCM format found in Blu-ray PCM streams 3 * Copyright (c) 2009, 2013 Christian Schmidt 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * PCM codec for Blu-ray PCM audio tracks 25 */ 26 27#include "libavutil/channel_layout.h" 28#include "avcodec.h" 29#include "bytestream.h" 30#include "codec_internal.h" 31#include "internal.h" 32 33/* 34 * Channel Mapping according to 35 * Blu-ray Disc Read-Only Format Version 1 36 * Part 3: Audio Visual Basic Specifications 37 * mono M1 X 38 * stereo L R 39 * 3/0 L R C X 40 * 2/1 L R S X 41 * 3/1 L R C S 42 * 2/2 L R LS RS 43 * 3/2 L R C LS RS X 44 * 3/2+lfe L R C LS RS lfe 45 * 3/4 L R C LS Rls Rrs RS X 46 * 3/4+lfe L R C LS Rls Rrs RS lfe 47 */ 48 49/** 50 * Parse the header of a LPCM frame read from a Blu-ray MPEG-TS stream 51 * @param avctx the codec context 52 * @param header pointer to the first four bytes of the data packet 53 */ 54static int pcm_bluray_parse_header(AVCodecContext *avctx, 55 const uint8_t *header) 56{ 57 static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; 58 static const AVChannelLayout channel_layouts[16] = { 59 { 0 }, AV_CHANNEL_LAYOUT_MONO, { 0 }, 60 AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_SURROUND, AV_CHANNEL_LAYOUT_2_1, 61 AV_CHANNEL_LAYOUT_4POINT0, AV_CHANNEL_LAYOUT_2_2, AV_CHANNEL_LAYOUT_5POINT0, 62 AV_CHANNEL_LAYOUT_5POINT1, AV_CHANNEL_LAYOUT_7POINT0, AV_CHANNEL_LAYOUT_7POINT1, 63 { 0 }, { 0 }, { 0 }, { 0 }, 64 }; 65 uint8_t channel_layout = header[2] >> 4; 66 67 if (avctx->debug & FF_DEBUG_PICT_INFO) 68 ff_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n", 69 header[0], header[1], header[2], header[3]); 70 71 /* get the sample depth and derive the sample format from it */ 72 avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; 73 if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) { 74 av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample); 75 return AVERROR_INVALIDDATA; 76 } 77 avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 78 : AV_SAMPLE_FMT_S32; 79 if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) 80 avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; 81 82 /* get the sample rate. Not all values are used. */ 83 switch (header[2] & 0x0f) { 84 case 1: 85 avctx->sample_rate = 48000; 86 break; 87 case 4: 88 avctx->sample_rate = 96000; 89 break; 90 case 5: 91 avctx->sample_rate = 192000; 92 break; 93 default: 94 avctx->sample_rate = 0; 95 av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n", 96 header[2] & 0x0f); 97 return AVERROR_INVALIDDATA; 98 } 99 100 /* 101 * get the channel number (and mapping). Not all values are used. 102 * It must be noted that the number of channels in the MPEG stream can 103 * differ from the actual meaningful number, e.g. mono audio still has two 104 * channels, one being empty. 105 */ 106 av_channel_layout_uninit(&avctx->ch_layout); 107 avctx->ch_layout = channel_layouts[channel_layout]; 108 if (!avctx->ch_layout.nb_channels) { 109 av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n", 110 channel_layout); 111 return AVERROR_INVALIDDATA; 112 } 113 114 avctx->bit_rate = FFALIGN(avctx->ch_layout.nb_channels, 2) * avctx->sample_rate * 115 avctx->bits_per_coded_sample; 116 117 if (avctx->debug & FF_DEBUG_PICT_INFO) 118 ff_dlog(avctx, 119 "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n", 120 avctx->ch_layout.nb_channels, avctx->bits_per_coded_sample, 121 avctx->sample_rate, avctx->bit_rate); 122 return 0; 123} 124 125static int pcm_bluray_decode_frame(AVCodecContext *avctx, AVFrame *frame, 126 int *got_frame_ptr, AVPacket *avpkt) 127{ 128 const uint8_t *src = avpkt->data; 129 int buf_size = avpkt->size; 130 GetByteContext gb; 131 int num_source_channels, channel, retval; 132 int sample_size, samples; 133 int16_t *dst16; 134 int32_t *dst32; 135 136 if (buf_size < 4) { 137 av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); 138 return AVERROR_INVALIDDATA; 139 } 140 141 if ((retval = pcm_bluray_parse_header(avctx, src))) 142 return retval; 143 src += 4; 144 buf_size -= 4; 145 146 bytestream2_init(&gb, src, buf_size); 147 148 /* There's always an even number of channels in the source */ 149 num_source_channels = FFALIGN(avctx->ch_layout.nb_channels, 2); 150 sample_size = (num_source_channels * 151 (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; 152 samples = buf_size / sample_size; 153 154 /* get output buffer */ 155 frame->nb_samples = samples; 156 if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) 157 return retval; 158 dst16 = (int16_t *)frame->data[0]; 159 dst32 = (int32_t *)frame->data[0]; 160 161 if (samples) { 162 switch (avctx->ch_layout.u.mask) { 163 /* cases with same number of source and coded channels */ 164 case AV_CH_LAYOUT_STEREO: 165 case AV_CH_LAYOUT_4POINT0: 166 case AV_CH_LAYOUT_2_2: 167 samples *= num_source_channels; 168 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { 169#if HAVE_BIGENDIAN 170 bytestream2_get_buffer(&gb, dst16, buf_size); 171#else 172 do { 173 *dst16++ = bytestream2_get_be16u(&gb); 174 } while (--samples); 175#endif 176 } else { 177 do { 178 *dst32++ = bytestream2_get_be24u(&gb) << 8; 179 } while (--samples); 180 } 181 break; 182 /* cases where number of source channels = coded channels + 1 */ 183 case AV_CH_LAYOUT_MONO: 184 case AV_CH_LAYOUT_SURROUND: 185 case AV_CH_LAYOUT_2_1: 186 case AV_CH_LAYOUT_5POINT0: 187 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { 188 do { 189#if HAVE_BIGENDIAN 190 bytestream2_get_buffer(&gb, dst16, avctx->ch_layout.nb_channels * 2); 191 dst16 += avctx->ch_layout.nb_channels; 192#else 193 channel = avctx->ch_layout.nb_channels; 194 do { 195 *dst16++ = bytestream2_get_be16u(&gb); 196 } while (--channel); 197#endif 198 bytestream2_skip(&gb, 2); 199 } while (--samples); 200 } else { 201 do { 202 channel = avctx->ch_layout.nb_channels; 203 do { 204 *dst32++ = bytestream2_get_be24u(&gb) << 8; 205 } while (--channel); 206 bytestream2_skip(&gb, 3); 207 } while (--samples); 208 } 209 break; 210 /* remapping: L, R, C, LBack, RBack, LF */ 211 case AV_CH_LAYOUT_5POINT1: 212 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { 213 do { 214 dst16[0] = bytestream2_get_be16u(&gb); 215 dst16[1] = bytestream2_get_be16u(&gb); 216 dst16[2] = bytestream2_get_be16u(&gb); 217 dst16[4] = bytestream2_get_be16u(&gb); 218 dst16[5] = bytestream2_get_be16u(&gb); 219 dst16[3] = bytestream2_get_be16u(&gb); 220 dst16 += 6; 221 } while (--samples); 222 } else { 223 do { 224 dst32[0] = bytestream2_get_be24u(&gb) << 8; 225 dst32[1] = bytestream2_get_be24u(&gb) << 8; 226 dst32[2] = bytestream2_get_be24u(&gb) << 8; 227 dst32[4] = bytestream2_get_be24u(&gb) << 8; 228 dst32[5] = bytestream2_get_be24u(&gb) << 8; 229 dst32[3] = bytestream2_get_be24u(&gb) << 8; 230 dst32 += 6; 231 } while (--samples); 232 } 233 break; 234 /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */ 235 case AV_CH_LAYOUT_7POINT0: 236 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { 237 do { 238 dst16[0] = bytestream2_get_be16u(&gb); 239 dst16[1] = bytestream2_get_be16u(&gb); 240 dst16[2] = bytestream2_get_be16u(&gb); 241 dst16[5] = bytestream2_get_be16u(&gb); 242 dst16[3] = bytestream2_get_be16u(&gb); 243 dst16[4] = bytestream2_get_be16u(&gb); 244 dst16[6] = bytestream2_get_be16u(&gb); 245 dst16 += 7; 246 bytestream2_skip(&gb, 2); 247 } while (--samples); 248 } else { 249 do { 250 dst32[0] = bytestream2_get_be24u(&gb) << 8; 251 dst32[1] = bytestream2_get_be24u(&gb) << 8; 252 dst32[2] = bytestream2_get_be24u(&gb) << 8; 253 dst32[5] = bytestream2_get_be24u(&gb) << 8; 254 dst32[3] = bytestream2_get_be24u(&gb) << 8; 255 dst32[4] = bytestream2_get_be24u(&gb) << 8; 256 dst32[6] = bytestream2_get_be24u(&gb) << 8; 257 dst32 += 7; 258 bytestream2_skip(&gb, 3); 259 } while (--samples); 260 } 261 break; 262 /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */ 263 case AV_CH_LAYOUT_7POINT1: 264 if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { 265 do { 266 dst16[0] = bytestream2_get_be16u(&gb); 267 dst16[1] = bytestream2_get_be16u(&gb); 268 dst16[2] = bytestream2_get_be16u(&gb); 269 dst16[6] = bytestream2_get_be16u(&gb); 270 dst16[4] = bytestream2_get_be16u(&gb); 271 dst16[5] = bytestream2_get_be16u(&gb); 272 dst16[7] = bytestream2_get_be16u(&gb); 273 dst16[3] = bytestream2_get_be16u(&gb); 274 dst16 += 8; 275 } while (--samples); 276 } else { 277 do { 278 dst32[0] = bytestream2_get_be24u(&gb) << 8; 279 dst32[1] = bytestream2_get_be24u(&gb) << 8; 280 dst32[2] = bytestream2_get_be24u(&gb) << 8; 281 dst32[6] = bytestream2_get_be24u(&gb) << 8; 282 dst32[4] = bytestream2_get_be24u(&gb) << 8; 283 dst32[5] = bytestream2_get_be24u(&gb) << 8; 284 dst32[7] = bytestream2_get_be24u(&gb) << 8; 285 dst32[3] = bytestream2_get_be24u(&gb) << 8; 286 dst32 += 8; 287 } while (--samples); 288 } 289 break; 290 } 291 } 292 293 *got_frame_ptr = 1; 294 295 retval = bytestream2_tell(&gb); 296 if (avctx->debug & FF_DEBUG_BITSTREAM) 297 ff_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", 298 retval, buf_size); 299 return retval + 4; 300} 301 302const FFCodec ff_pcm_bluray_decoder = { 303 .p.name = "pcm_bluray", 304 .p.long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"), 305 .p.type = AVMEDIA_TYPE_AUDIO, 306 .p.id = AV_CODEC_ID_PCM_BLURAY, 307 FF_CODEC_DECODE_CB(pcm_bluray_decode_frame), 308 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, 309 .p.sample_fmts = (const enum AVSampleFormat[]){ 310 AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE 311 }, 312}; 313