libavcodec/mlp_parser.c
Go to the documentation of this file.
00001 /*
00002  * MLP parser
00003  * Copyright (c) 2007 Ian Caulfield
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include <stdint.h>
00028 
00029 #include "libavutil/crc.h"
00030 #include "libavutil/audioconvert.h"
00031 #include "get_bits.h"
00032 #include "parser.h"
00033 #include "mlp_parser.h"
00034 #include "mlp.h"
00035 
00036 static const uint8_t mlp_quants[16] = {
00037     16, 20, 24, 0, 0, 0, 0, 0,
00038      0,  0,  0, 0, 0, 0, 0, 0,
00039 };
00040 
00041 static const uint8_t mlp_channels[32] = {
00042     1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
00043     5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00044 };
00045 
00046 const uint64_t ff_mlp_layout[32] = {
00047     AV_CH_LAYOUT_MONO,
00048     AV_CH_LAYOUT_STEREO,
00049     AV_CH_LAYOUT_2_1,
00050     AV_CH_LAYOUT_QUAD,
00051     AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
00052     AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY,
00053     AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,
00054     AV_CH_LAYOUT_SURROUND,
00055     AV_CH_LAYOUT_4POINT0,
00056     AV_CH_LAYOUT_5POINT0_BACK,
00057     AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY,
00058     AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,
00059     AV_CH_LAYOUT_5POINT1_BACK,
00060     AV_CH_LAYOUT_4POINT0,
00061     AV_CH_LAYOUT_5POINT0_BACK,
00062     AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY,
00063     AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,
00064     AV_CH_LAYOUT_5POINT1_BACK,
00065     AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,
00066     AV_CH_LAYOUT_5POINT0_BACK,
00067     AV_CH_LAYOUT_5POINT1_BACK,
00068     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00069 };
00070 
00071 static const uint8_t thd_chancount[13] = {
00072 //  LR    C   LFE  LRs LRvh  LRc LRrs  Cs   Ts  LRsd  LRw  Cvh  LFE2
00073      2,   1,   1,   2,   2,   2,   2,   1,   1,   2,   2,   1,   1
00074 };
00075 
00076 static const uint64_t thd_layout[13] = {
00077     AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT,                     // LR
00078     AV_CH_FRONT_CENTER,                                     // C
00079     AV_CH_LOW_FREQUENCY,                                    // LFE
00080     AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,                       // LRs
00081     AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT,             // LRvh
00082     AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRc
00083     AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,                       // LRrs
00084     AV_CH_BACK_CENTER,                                      // Cs
00085     AV_CH_TOP_CENTER,                                       // Ts
00086     AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,                       // LRsd - TODO: Surround Direct
00087     AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRw  - TODO: Wide
00088     AV_CH_TOP_FRONT_CENTER,                                 // Cvh
00089     AV_CH_LOW_FREQUENCY                                     // LFE2
00090 };
00091 
00092 static int mlp_samplerate(int in)
00093 {
00094     if (in == 0xF)
00095         return 0;
00096 
00097     return (in & 8 ? 44100 : 48000) << (in & 7) ;
00098 }
00099 
00100 static int truehd_channels(int chanmap)
00101 {
00102     int channels = 0, i;
00103 
00104     for (i = 0; i < 13; i++)
00105         channels += thd_chancount[i] * ((chanmap >> i) & 1);
00106 
00107     return channels;
00108 }
00109 
00110 uint64_t ff_truehd_layout(int chanmap)
00111 {
00112     int layout = 0, i;
00113 
00114     for (i = 0; i < 13; i++)
00115         layout |= thd_layout[i] * ((chanmap >> i) & 1);
00116 
00117     return layout;
00118 }
00119 
00126 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
00127 {
00128     int ratebits;
00129     uint16_t checksum;
00130 
00131     assert(get_bits_count(gb) == 0);
00132 
00133     if (gb->size_in_bits < 28 << 3) {
00134         av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
00135         return -1;
00136     }
00137 
00138     checksum = ff_mlp_checksum16(gb->buffer, 26);
00139     if (checksum != AV_RL16(gb->buffer+26)) {
00140         av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n");
00141         return AVERROR_INVALIDDATA;
00142     }
00143 
00144     if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */
00145         return AVERROR_INVALIDDATA;
00146 
00147     mh->stream_type = get_bits(gb, 8);
00148 
00149     if (mh->stream_type == 0xbb) {
00150         mh->group1_bits = mlp_quants[get_bits(gb, 4)];
00151         mh->group2_bits = mlp_quants[get_bits(gb, 4)];
00152 
00153         ratebits = get_bits(gb, 4);
00154         mh->group1_samplerate = mlp_samplerate(ratebits);
00155         mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4));
00156 
00157         skip_bits(gb, 11);
00158 
00159         mh->channels_mlp = get_bits(gb, 5);
00160     } else if (mh->stream_type == 0xba) {
00161         mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere?
00162         mh->group2_bits = 0;
00163 
00164         ratebits = get_bits(gb, 4);
00165         mh->group1_samplerate = mlp_samplerate(ratebits);
00166         mh->group2_samplerate = 0;
00167 
00168         skip_bits(gb, 8);
00169 
00170         mh->channels_thd_stream1 = get_bits(gb, 5);
00171 
00172         skip_bits(gb, 2);
00173 
00174         mh->channels_thd_stream2 = get_bits(gb, 13);
00175     } else
00176         return AVERROR_INVALIDDATA;
00177 
00178     mh->access_unit_size = 40 << (ratebits & 7);
00179     mh->access_unit_size_pow2 = 64 << (ratebits & 7);
00180 
00181     skip_bits_long(gb, 48);
00182 
00183     mh->is_vbr = get_bits1(gb);
00184 
00185     mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4;
00186 
00187     mh->num_substreams = get_bits(gb, 4);
00188 
00189     skip_bits_long(gb, 4 + 11 * 8);
00190 
00191     return 0;
00192 }
00193 
00194 typedef struct MLPParseContext
00195 {
00196     ParseContext pc;
00197 
00198     int bytes_left;
00199 
00200     int in_sync;
00201 
00202     int num_substreams;
00203 } MLPParseContext;
00204 
00205 static av_cold int mlp_init(AVCodecParserContext *s)
00206 {
00207     ff_mlp_init_crc();
00208     return 0;
00209 }
00210 
00211 static int mlp_parse(AVCodecParserContext *s,
00212                      AVCodecContext *avctx,
00213                      const uint8_t **poutbuf, int *poutbuf_size,
00214                      const uint8_t *buf, int buf_size)
00215 {
00216     MLPParseContext *mp = s->priv_data;
00217     int sync_present;
00218     uint8_t parity_bits;
00219     int next;
00220     int i, p = 0;
00221 
00222     *poutbuf_size = 0;
00223     if (buf_size == 0)
00224         return 0;
00225 
00226     if (!mp->in_sync) {
00227         // Not in sync - find a major sync header
00228 
00229         for (i = 0; i < buf_size; i++) {
00230             mp->pc.state = (mp->pc.state << 8) | buf[i];
00231             if ((mp->pc.state & 0xfffffffe) == 0xf8726fba &&
00232                 // ignore if we do not have the data for the start of header
00233                 mp->pc.index + i >= 7) {
00234                 mp->in_sync = 1;
00235                 mp->bytes_left = 0;
00236                 break;
00237             }
00238         }
00239 
00240         if (!mp->in_sync) {
00241             ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
00242             return buf_size;
00243         }
00244 
00245         ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size);
00246 
00247         return i - 7;
00248     }
00249 
00250     if (mp->bytes_left == 0) {
00251         // Find length of this packet
00252 
00253         /* Copy overread bytes from last frame into buffer. */
00254         for(; mp->pc.overread>0; mp->pc.overread--) {
00255             mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++];
00256         }
00257 
00258         if (mp->pc.index + buf_size < 2) {
00259             ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
00260             return buf_size;
00261         }
00262 
00263         mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
00264                        |  (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
00265         mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
00266         if (mp->bytes_left <= 0) { // prevent infinite loop
00267             goto lost_sync;
00268         }
00269         mp->bytes_left -= mp->pc.index;
00270     }
00271 
00272     next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
00273 
00274     if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
00275         mp->bytes_left -= buf_size;
00276         return buf_size;
00277     }
00278 
00279     mp->bytes_left = 0;
00280 
00281     sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
00282 
00283     if (!sync_present) {
00284         /* The first nibble of a frame is a parity check of the 4-byte
00285          * access unit header and all the 2- or 4-byte substream headers. */
00286         // Only check when this isn't a sync frame - syncs have a checksum.
00287 
00288         parity_bits = 0;
00289         for (i = -1; i < mp->num_substreams; i++) {
00290             parity_bits ^= buf[p++];
00291             parity_bits ^= buf[p++];
00292 
00293             if (i < 0 || buf[p-2] & 0x80) {
00294                 parity_bits ^= buf[p++];
00295                 parity_bits ^= buf[p++];
00296             }
00297         }
00298 
00299         if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
00300             av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
00301             goto lost_sync;
00302         }
00303     } else {
00304         GetBitContext gb;
00305         MLPHeaderInfo mh;
00306 
00307         init_get_bits(&gb, buf + 4, (buf_size - 4) << 3);
00308         if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0)
00309             goto lost_sync;
00310 
00311         avctx->bits_per_raw_sample = mh.group1_bits;
00312         if (avctx->bits_per_raw_sample > 16)
00313             avctx->sample_fmt = AV_SAMPLE_FMT_S32;
00314         else
00315             avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00316         avctx->sample_rate = mh.group1_samplerate;
00317         avctx->frame_size = mh.access_unit_size;
00318 
00319         if (mh.stream_type == 0xbb) {
00320             /* MLP stream */
00321             avctx->channels = mlp_channels[mh.channels_mlp];
00322             avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
00323         } else { /* mh.stream_type == 0xba */
00324             /* TrueHD stream */
00325             if (mh.channels_thd_stream2) {
00326                 avctx->channels = truehd_channels(mh.channels_thd_stream2);
00327                 avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
00328             } else {
00329                 avctx->channels = truehd_channels(mh.channels_thd_stream1);
00330                 avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
00331             }
00332         }
00333 
00334         if (!mh.is_vbr) /* Stream is CBR */
00335             avctx->bit_rate = mh.peak_bitrate;
00336 
00337         mp->num_substreams = mh.num_substreams;
00338     }
00339 
00340     *poutbuf = buf;
00341     *poutbuf_size = buf_size;
00342 
00343     return next;
00344 
00345 lost_sync:
00346     mp->in_sync = 0;
00347     return 1;
00348 }
00349 
00350 AVCodecParser ff_mlp_parser = {
00351     .codec_ids      = { CODEC_ID_MLP, CODEC_ID_TRUEHD },
00352     .priv_data_size = sizeof(MLPParseContext),
00353     .parser_init    = mlp_init,
00354     .parser_parse   = mlp_parse,
00355     .parser_close   = ff_parse_close,
00356 };