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