• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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_SIDE_LEFT|AV_CH_SIDE_RIGHT,                       // LRc
00083     AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,                       // LRrs
00084     AV_CH_BACK_CENTER,                                      // Cs
00085     AV_CH_TOP_BACK_CENTER,                                  // Ts
00086     AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,                       // LRsd
00087     AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRw
00088     AV_CH_TOP_BACK_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 int64_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 -1;
00142     }
00143 
00144     if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */
00145         return -1;
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 -1;
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         mp->bytes_left -= mp->pc.index;
00267     }
00268 
00269     next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
00270 
00271     if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
00272         mp->bytes_left -= buf_size;
00273         return buf_size;
00274     }
00275 
00276     mp->bytes_left = 0;
00277 
00278     sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
00279 
00280     if (!sync_present) {
00281         /* The first nibble of a frame is a parity check of the 4-byte
00282          * access unit header and all the 2- or 4-byte substream headers. */
00283         // Only check when this isn't a sync frame - syncs have a checksum.
00284 
00285         parity_bits = 0;
00286         for (i = -1; i < mp->num_substreams; i++) {
00287             parity_bits ^= buf[p++];
00288             parity_bits ^= buf[p++];
00289 
00290             if (i < 0 || buf[p-2] & 0x80) {
00291                 parity_bits ^= buf[p++];
00292                 parity_bits ^= buf[p++];
00293             }
00294         }
00295 
00296         if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
00297             av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
00298             goto lost_sync;
00299         }
00300     } else {
00301         GetBitContext gb;
00302         MLPHeaderInfo mh;
00303 
00304         init_get_bits(&gb, buf + 4, (buf_size - 4) << 3);
00305         if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0)
00306             goto lost_sync;
00307 
00308         avctx->bits_per_raw_sample = mh.group1_bits;
00309         if (avctx->bits_per_raw_sample > 16)
00310             avctx->sample_fmt = AV_SAMPLE_FMT_S32;
00311         else
00312             avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00313         avctx->sample_rate = mh.group1_samplerate;
00314         avctx->frame_size = mh.access_unit_size;
00315 
00316         if (mh.stream_type == 0xbb) {
00317             /* MLP stream */
00318             avctx->channels = mlp_channels[mh.channels_mlp];
00319             avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
00320         } else { /* mh.stream_type == 0xba */
00321             /* TrueHD stream */
00322             if (mh.channels_thd_stream2) {
00323                 avctx->channels = truehd_channels(mh.channels_thd_stream2);
00324                 avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
00325             } else {
00326                 avctx->channels = truehd_channels(mh.channels_thd_stream1);
00327                 avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
00328             }
00329         }
00330 
00331         if (!mh.is_vbr) /* Stream is CBR */
00332             avctx->bit_rate = mh.peak_bitrate;
00333 
00334         mp->num_substreams = mh.num_substreams;
00335     }
00336 
00337     *poutbuf = buf;
00338     *poutbuf_size = buf_size;
00339 
00340     return next;
00341 
00342 lost_sync:
00343     mp->in_sync = 0;
00344     return 1;
00345 }
00346 
00347 AVCodecParser ff_mlp_parser = {
00348     { CODEC_ID_MLP, CODEC_ID_TRUEHD },
00349     sizeof(MLPParseContext),
00350     mlp_init,
00351     mlp_parse,
00352     ff_parse_close,
00353 };

Generated on Fri Feb 22 2013 07:24:27 for FFmpeg by  doxygen 1.7.1