mlp.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:16k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mlp.c: packetize MLP/TrueHD audio
  3.  *****************************************************************************
  4.  * Copyright (C) 2008 Laurent Aimar
  5.  * $Id: 85a7b6bee61dc29a69e9a2eab428363fa241146a $
  6.  *
  7.  * Authors: Laurent Aimar < fenrir _AT videolan _DOT_ org >
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_codec.h>
  32. #include <vlc_aout.h>
  33. #include <vlc_block_helper.h>
  34. #include <vlc_bits.h>
  35. #include <assert.h>
  36. /*****************************************************************************
  37.  * Module descriptor
  38.  *****************************************************************************/
  39. static int  Open ( vlc_object_t * );
  40. static void Close( vlc_object_t * );
  41. vlc_module_begin ()
  42.     set_category( CAT_SOUT )
  43.     set_subcategory( SUBCAT_SOUT_PACKETIZER )
  44.     set_description( N_("MLP/TrueHD parser") )
  45.     set_capability( "packetizer", 50 )
  46.     set_callbacks( Open, Close )
  47. vlc_module_end ()
  48. /*****************************************************************************
  49.  *
  50.  *****************************************************************************/
  51. typedef struct
  52. {
  53.     int i_type;
  54.     int i_rate;
  55.     int i_channels;
  56.     int i_channels_conf;
  57.     int i_samples;
  58.     bool b_vbr;
  59.     int  i_bitrate;
  60.     int  i_substreams;
  61. } mlp_header_t;
  62. struct decoder_sys_t
  63. {
  64.     /*
  65.      * Input properties
  66.      */
  67.     int i_state;
  68.     block_bytestream_t bytestream;
  69.     /*
  70.      * Common properties
  71.      */
  72.     audio_date_t   end_date;
  73.     mtime_t i_pts;
  74.     int i_frame_size;
  75.     bool         b_mlp;
  76.     mlp_header_t mlp;
  77. };
  78. enum {
  79.     STATE_NOSYNC,
  80.     STATE_SYNC,
  81.     STATE_HEADER,
  82.     STATE_NEXT_SYNC,
  83.     STATE_GET_DATA,
  84.     STATE_SEND_DATA
  85. };
  86. #define MLP_MAX_SUBSTREAMS (16)
  87. #define MLP_HEADER_SYNC (28)
  88. #define MLP_HEADER_SIZE (4 + MLP_HEADER_SYNC + 4 * MLP_MAX_SUBSTREAMS)
  89. static const uint8_t pu_start_code[3] = { 0xf8, 0x72, 0x6f };
  90. /****************************************************************************
  91.  * Local prototypes
  92.  ****************************************************************************/
  93. static block_t *Packetize( decoder_t *, block_t **pp_block );
  94. static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp );
  95. static int SyncInfoDolby( const uint8_t *p_buf );
  96. /*****************************************************************************
  97.  * Open: probe the decoder/packetizer and return score
  98.  *****************************************************************************/
  99. static int Open( vlc_object_t *p_this )
  100. {
  101.     decoder_t *p_dec = (decoder_t*)p_this;
  102.     decoder_sys_t *p_sys;
  103.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','l','p',' ') &&
  104.         p_dec->fmt_in.i_codec != VLC_FOURCC('t','r','h','d') )
  105.         return VLC_EGENERIC;
  106.     /* */
  107.     p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
  108.     if( !p_sys )
  109.         return VLC_ENOMEM;
  110.     /* */
  111.     p_sys->i_state = STATE_NOSYNC;
  112.     aout_DateSet( &p_sys->end_date, 0 );
  113.     p_sys->bytestream = block_BytestreamInit();
  114.     p_sys->b_mlp = false;
  115.     /* Set output properties */
  116.     p_dec->fmt_out.i_cat = AUDIO_ES;
  117.     p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
  118.     p_dec->fmt_out.audio.i_rate = 0;
  119.     /* Set callback */
  120.     p_dec->pf_packetize = Packetize;
  121.     return VLC_SUCCESS;
  122. }
  123. /****************************************************************************
  124.  * Packetize:
  125.  ****************************************************************************/
  126. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
  127. {
  128.     decoder_sys_t *p_sys = p_dec->p_sys;
  129.     uint8_t p_header[MLP_HEADER_SIZE];
  130.     block_t *p_out_buffer;
  131.     /* */
  132.     if( !pp_block || !*pp_block )
  133.         return NULL;
  134.     /* */
  135.     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
  136.     {
  137.         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
  138.         {
  139.             p_sys->b_mlp = false;
  140.             p_sys->i_state = STATE_NOSYNC;
  141.             block_BytestreamEmpty( &p_sys->bytestream );
  142.         }
  143.         aout_DateSet( &p_sys->end_date, 0 );
  144.         block_Release( *pp_block );
  145.         return NULL;
  146.     }
  147.     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
  148.     {
  149.         /* We've just started the stream, wait for the first PTS. */
  150.         block_Release( *pp_block );
  151.         return NULL;
  152.     }
  153.     block_BytestreamPush( &p_sys->bytestream, *pp_block );
  154.     for( ;; )
  155.     {
  156.         switch( p_sys->i_state )
  157.         {
  158.         case STATE_NOSYNC:
  159.             while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
  160.             {
  161.                 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
  162.                 {
  163.                     p_sys->i_state = STATE_SYNC;
  164.                     break;
  165.                 }
  166.                 else if( SyncInfoDolby( p_header ) > 0 )
  167.                 {
  168.                     p_sys->i_state = STATE_SYNC;
  169.                     break;
  170.                 }
  171.                 block_SkipByte( &p_sys->bytestream );
  172.             }
  173.             if( p_sys->i_state != STATE_SYNC )
  174.             {
  175.                 block_BytestreamFlush( &p_sys->bytestream );
  176.                 /* Need more data */
  177.                 return NULL;
  178.             }
  179.         case STATE_SYNC:
  180.             /* New frame, set the Presentation Time Stamp */
  181.             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
  182.             if( p_sys->i_pts != 0 &&
  183.                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
  184.             {
  185.                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  186.             }
  187.             p_sys->i_state = STATE_HEADER;
  188.         case STATE_HEADER:
  189.             /* Get a MLP header */
  190.             if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
  191.             {
  192.                 /* Need more data */
  193.                 return NULL;
  194.             }
  195.             /* Check if frame is valid and get frame info */
  196.             p_sys->i_frame_size = SyncInfoDolby( p_header );
  197.             if( p_sys->i_frame_size <= 0 )
  198.                 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
  199.             if( p_sys->i_frame_size <= 0 )
  200.             {
  201.                 msg_Dbg( p_dec, "emulated sync word" );
  202.                 block_SkipByte( &p_sys->bytestream );
  203.                 p_sys->b_mlp = false;
  204.                 p_sys->i_state = STATE_NOSYNC;
  205.                 break;
  206.             }
  207.             p_sys->i_state = STATE_NEXT_SYNC;
  208.         case STATE_NEXT_SYNC:
  209.             /* TODO: If pp_block == NULL, flush the buffer without checking the
  210.              * next sync word */
  211.             /* Check if next expected frame contains the sync word */
  212.             if( block_PeekOffsetBytes( &p_sys->bytestream,
  213.                                        p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
  214.             {
  215.                 /* Need more data */
  216.                 return NULL;
  217.             }
  218.             bool b_mlp = p_sys->b_mlp;
  219.             mlp_header_t mlp = p_sys->mlp;
  220.             if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
  221.             {
  222.                 msg_Dbg( p_dec, "emulated sync word "
  223.                          "(no sync on following frame)" );
  224.                 p_sys->b_mlp = false;
  225.                 p_sys->i_state = STATE_NOSYNC;
  226.                 block_SkipByte( &p_sys->bytestream );
  227.                 break;
  228.             }
  229.             p_sys->i_state = STATE_SEND_DATA;
  230.             break;
  231.         case STATE_GET_DATA:
  232.             /* Make sure we have enough data.
  233.              * (Not useful if we went through NEXT_SYNC) */
  234.             if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) )
  235.             {
  236.                 /* Need more data */
  237.                 return NULL;
  238.             }
  239.             p_sys->i_state = STATE_SEND_DATA;
  240.         case STATE_SEND_DATA:
  241.             /* When we reach this point we already know we have enough
  242.              * data available. */
  243.             p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
  244.             if( !p_out_buffer )
  245.                 return NULL;
  246.             /* Copy the whole frame into the buffer */
  247.             block_GetBytes( &p_sys->bytestream,
  248.                             p_out_buffer->p_buffer, p_out_buffer->i_buffer );
  249.             /* Just ignore (E)AC3 frames */
  250.             if( SyncInfoDolby( p_out_buffer->p_buffer ) > 0 )
  251.             {
  252.                 block_Release( p_out_buffer );
  253.                 p_sys->i_state = STATE_NOSYNC;
  254.                 break;
  255.             }
  256.             /* Setup output */
  257.             if( p_dec->fmt_out.audio.i_rate != p_sys->mlp.i_rate )
  258.             {
  259.                 msg_Info( p_dec, "MLP channels: %d samplerate: %d",
  260.                           p_sys->mlp.i_channels, p_sys->mlp.i_rate );
  261.                 aout_DateInit( &p_sys->end_date, p_sys->mlp.i_rate );
  262.                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
  263.             }
  264.             p_dec->fmt_out.audio.i_rate     = p_sys->mlp.i_rate;
  265.             p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
  266.             p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
  267.             p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf & AOUT_CHAN_PHYSMASK;
  268.             p_out_buffer->i_pts = p_out_buffer->i_dts = aout_DateGet( &p_sys->end_date );
  269.             p_out_buffer->i_length =
  270.                 aout_DateIncrement( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
  271.             /* Make sure we don't reuse the same pts twice */
  272.             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
  273.                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
  274.             /* So p_block doesn't get re-added several times */
  275.             *pp_block = block_BytestreamPop( &p_sys->bytestream );
  276.             p_sys->i_state = STATE_NOSYNC;
  277.             return p_out_buffer;
  278.         }
  279.     }
  280.     return NULL;
  281. }
  282. /*****************************************************************************
  283.  * Close:
  284.  *****************************************************************************/
  285. static void Close( vlc_object_t *p_this )
  286. {
  287.     decoder_t *p_dec = (decoder_t*)p_this;
  288.     decoder_sys_t *p_sys = p_dec->p_sys;
  289.     block_BytestreamRelease( &p_sys->bytestream );
  290.     free( p_sys );
  291. }
  292. /**
  293.  * It parse MLP sync info.
  294.  *
  295.  * TODO handle CRC (at offset 26)
  296.   */
  297. static int TrueHdChannels( int i_map )
  298. {
  299.     static const uint8_t pu_thd[13] =
  300.     {
  301.          2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
  302.     };
  303.     int i_count = 0;
  304.     for( int i = 0; i < 13; i++ )
  305.     {
  306.         if( i_map & (1<<i) )
  307.             i_count += pu_thd[i];
  308.     }
  309.     return i_count;
  310. }
  311. static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
  312. {
  313.     bs_t s;
  314.     assert( !memcmp( p_hdr, pu_start_code, 3 ) );
  315.     /* TODO Checksum ? */
  316.     /* */
  317.     bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
  318.     /* Stream type */
  319.     p_mlp->i_type = bs_read( &s, 8 );
  320.     int i_rate_idx1;
  321.     if( p_mlp->i_type == 0xbb )        /* MLP */
  322.     {
  323.         static const unsigned pu_channels[32] = {
  324.             1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
  325.             5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  326.         };
  327.         bs_skip( &s, 4 + 4 );
  328.         i_rate_idx1 = bs_read( &s, 4 );
  329.         const int i_rate_idx2 = bs_read( &s, 4 );
  330.         bs_skip( &s, 11 );
  331.         const int i_channel_idx = bs_read( &s, 5 );
  332.         p_mlp->i_channels = pu_channels[i_channel_idx];
  333.     }
  334.     else if( p_mlp->i_type == 0xba )   /* True HD */
  335.     {
  336.         i_rate_idx1 = bs_read( &s, 4 );
  337.         bs_skip( &s, 8 );
  338.         const int i_channel1 = bs_read( &s, 5 );
  339.         bs_skip( &s, 2 );
  340.         const int i_channel2 = bs_read( &s, 13 );
  341.         if( i_channel2 )
  342.             p_mlp->i_channels = TrueHdChannels( i_channel2 );
  343.         else
  344.             p_mlp->i_channels = TrueHdChannels( i_channel1 );
  345.     }
  346.     else
  347.     {
  348.         return VLC_EGENERIC;
  349.     }
  350.     if( i_rate_idx1 == 0x0f )
  351.         p_mlp->i_rate = 0;
  352.     else
  353.         p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
  354.     p_mlp->i_channels_conf = 0; /* TODO ? */
  355.     p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
  356.     bs_skip( &s, 48 );
  357.     p_mlp->b_vbr = bs_read( &s, 1 );
  358.     p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
  359.     p_mlp->i_substreams = bs_read( &s, 4 );
  360.     bs_skip( &s, 4 + 11 * 8 );
  361.     //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%dn",
  362.     //        p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
  363.     return VLC_SUCCESS;
  364. }
  365. static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
  366. {
  367.     /* Check major sync presence */
  368.     const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
  369.     /* Wait for a major sync */
  370.     if( !b_has_sync && !*pb_mlp )
  371.         return 0;
  372.     /* Parse major sync if present */
  373.     if( b_has_sync )
  374.     {
  375.         *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
  376.         if( !*pb_mlp )
  377.             return 0;
  378.     }
  379.     /* Check parity TODO even with major sync */
  380.     if( 1 )
  381.     {
  382.         int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
  383.         const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
  384.         for( int i = 0; i < p_mlp->i_substreams; i++ )
  385.         {
  386.             i_tmp ^= *p++;
  387.             i_tmp ^= *p++;
  388.             if( p[-2] & 0x80 )
  389.             {
  390.                 i_tmp ^= *p++;
  391.                 i_tmp ^= *p++;
  392.             }
  393.         }
  394.         i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
  395.         if( ( i_tmp & 0x0f ) != 0x0f )
  396.             return 0;
  397.     }
  398.     /* */
  399.     const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
  400.     return i_word * 2;
  401. }
  402. /**
  403.  * It returns the size of an AC3 frame (or 0 if invalid)
  404.  */
  405. static int GetAc3Size( const uint8_t *p_buf )
  406. {
  407.     static const int pi_rate[] = { 32,  40,  48,  56,  64,  80,  96, 112,
  408.                                 128, 160, 192, 224, 256, 320, 384, 448,
  409.                                 512, 576, 640 };
  410.     /* */
  411.     const int i_frmsizecod = p_buf[4] & 63;
  412.     if( i_frmsizecod >= 38 )
  413.         return 0;
  414.     const int bitrate = pi_rate[i_frmsizecod >> 1];
  415.     switch( p_buf[4] & 0xc0 )
  416.     {
  417.     case 0:
  418.         return 4 * bitrate;
  419.     case 0x40:
  420.         return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
  421.     case 0x80:
  422.         return 6 * bitrate;
  423.     default:
  424.         return 0;
  425.     }
  426. }
  427. /**
  428.  * It return the size of a EAC3 frame (or 0 if invalid)
  429.  */
  430. static int GetEac3Size( const uint8_t *p_buf )
  431. {
  432.     int i_frame_size;
  433.     int i_bytes;
  434.     i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
  435.     if( i_frame_size < 2 )
  436.         return 0;
  437.     i_bytes = 2 * ( i_frame_size + 1 );
  438.     return i_bytes;
  439. }
  440. /**
  441.  * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
  442.  */
  443. static int SyncInfoDolby( const uint8_t *p_buf )
  444. {
  445.     int bsid;
  446.     /* Check synword */
  447.     if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
  448.         return 0;
  449.     /* Check bsid */
  450.     bsid = p_buf[5] >> 3;
  451.     if( bsid > 16 )
  452.         return 0;
  453.     if( bsid <= 10 )
  454.         return GetAc3Size( p_buf );
  455.     else
  456.         return GetEac3Size( p_buf );
  457. }