1 /*****************************************************************************
2 * mlp.c: packetize MLP/TrueHD audio
3 *****************************************************************************
4 * Copyright (C) 2008 Laurent Aimar
7 * Authors: Laurent Aimar < fenrir _AT videolan _DOT_ org >
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
35 #include <vlc_block_helper.h>
39 /*****************************************************************************
41 *****************************************************************************/
42 static int Open ( vlc_object_t * );
43 static void Close( vlc_object_t * );
46 set_category( CAT_SOUT )
47 set_subcategory( SUBCAT_SOUT_PACKETIZER )
48 set_description( N_("MLP/TrueHD parser") )
49 set_capability( "packetizer", 50 )
50 set_callbacks( Open, Close )
53 /*****************************************************************************
55 *****************************************************************************/
67 unsigned i_substreams;
78 block_bytestream_t bytestream;
102 #define MLP_MAX_SUBSTREAMS (16)
103 #define MLP_HEADER_SYNC (28)
104 #define MLP_HEADER_SIZE (4 + MLP_HEADER_SYNC + 4 * MLP_MAX_SUBSTREAMS)
106 static const uint8_t pu_start_code[3] = { 0xf8, 0x72, 0x6f };
108 /****************************************************************************
110 ****************************************************************************/
111 static block_t *Packetize( decoder_t *, block_t **pp_block );
112 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp );
113 static int SyncInfoDolby( const uint8_t *p_buf );
115 /*****************************************************************************
116 * Open: probe the decoder/packetizer and return score
117 *****************************************************************************/
118 static int Open( vlc_object_t *p_this )
120 decoder_t *p_dec = (decoder_t*)p_this;
121 decoder_sys_t *p_sys;
123 if( p_dec->fmt_in.i_codec != VLC_CODEC_MLP &&
124 p_dec->fmt_in.i_codec != VLC_CODEC_TRUEHD )
128 p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
133 p_sys->i_state = STATE_NOSYNC;
134 date_Set( &p_sys->end_date, 0 );
136 p_sys->bytestream = block_BytestreamInit();
137 p_sys->b_mlp = false;
139 /* Set output properties */
140 p_dec->fmt_out.i_cat = AUDIO_ES;
141 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
142 p_dec->fmt_out.audio.i_rate = 0;
145 p_dec->pf_packetize = Packetize;
149 /****************************************************************************
151 ****************************************************************************/
152 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
154 decoder_sys_t *p_sys = p_dec->p_sys;
155 uint8_t p_header[MLP_HEADER_SIZE];
156 block_t *p_out_buffer;
159 if( !pp_block || !*pp_block )
163 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
165 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
167 p_sys->b_mlp = false;
168 p_sys->i_state = STATE_NOSYNC;
169 block_BytestreamEmpty( &p_sys->bytestream );
171 date_Set( &p_sys->end_date, 0 );
172 block_Release( *pp_block );
176 if( !date_Get( &p_sys->end_date ) && !(*pp_block)->i_pts )
178 /* We've just started the stream, wait for the first PTS. */
179 block_Release( *pp_block );
183 block_BytestreamPush( &p_sys->bytestream, *pp_block );
187 switch( p_sys->i_state )
190 while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
192 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
194 p_sys->i_state = STATE_SYNC;
197 else if( SyncInfoDolby( p_header ) > 0 )
199 p_sys->i_state = STATE_SYNC;
202 block_SkipByte( &p_sys->bytestream );
204 if( p_sys->i_state != STATE_SYNC )
206 block_BytestreamFlush( &p_sys->bytestream );
213 /* New frame, set the Presentation Time Stamp */
214 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
215 if( p_sys->i_pts > VLC_TS_INVALID &&
216 p_sys->i_pts != date_Get( &p_sys->end_date ) )
218 date_Set( &p_sys->end_date, p_sys->i_pts );
220 p_sys->i_state = STATE_HEADER;
223 /* Get a MLP header */
224 if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
230 /* Check if frame is valid and get frame info */
231 p_sys->i_frame_size = SyncInfoDolby( p_header );
232 if( p_sys->i_frame_size <= 0 )
233 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
234 if( p_sys->i_frame_size <= 0 )
236 msg_Dbg( p_dec, "emulated sync word" );
237 block_SkipByte( &p_sys->bytestream );
238 p_sys->b_mlp = false;
239 p_sys->i_state = STATE_NOSYNC;
242 p_sys->i_state = STATE_NEXT_SYNC;
244 case STATE_NEXT_SYNC:
245 /* TODO: If pp_block == NULL, flush the buffer without checking the
248 /* Check if next expected frame contains the sync word */
249 if( block_PeekOffsetBytes( &p_sys->bytestream,
250 p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
256 bool b_mlp = p_sys->b_mlp;
257 mlp_header_t mlp = p_sys->mlp;
258 if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
260 msg_Dbg( p_dec, "emulated sync word "
261 "(no sync on following frame)" );
262 p_sys->b_mlp = false;
263 p_sys->i_state = STATE_NOSYNC;
264 block_SkipByte( &p_sys->bytestream );
267 p_sys->i_state = STATE_SEND_DATA;
271 /* Make sure we have enough data.
272 * (Not useful if we went through NEXT_SYNC) */
273 if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) )
278 p_sys->i_state = STATE_SEND_DATA;
280 case STATE_SEND_DATA:
281 /* When we reach this point we already know we have enough
283 p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
287 /* Copy the whole frame into the buffer */
288 block_GetBytes( &p_sys->bytestream,
289 p_out_buffer->p_buffer, p_out_buffer->i_buffer );
291 /* Just ignore (E)AC3 frames */
292 if( SyncInfoDolby( p_out_buffer->p_buffer ) > 0 )
294 block_Release( p_out_buffer );
295 p_sys->i_state = STATE_NOSYNC;
300 if( p_dec->fmt_out.audio.i_rate != p_sys->mlp.i_rate )
302 msg_Info( p_dec, "MLP channels: %d samplerate: %d",
303 p_sys->mlp.i_channels, p_sys->mlp.i_rate );
305 date_Init( &p_sys->end_date, p_sys->mlp.i_rate, 1 );
306 date_Set( &p_sys->end_date, p_sys->i_pts );
309 p_dec->fmt_out.audio.i_rate = p_sys->mlp.i_rate;
310 p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
311 p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
312 p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf & AOUT_CHAN_PHYSMASK;
314 p_out_buffer->i_pts = p_out_buffer->i_dts = date_Get( &p_sys->end_date );
316 p_out_buffer->i_length =
317 date_Increment( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
319 /* Make sure we don't reuse the same pts twice */
320 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
321 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
323 /* So p_block doesn't get re-added several times */
324 *pp_block = block_BytestreamPop( &p_sys->bytestream );
326 p_sys->i_state = STATE_NOSYNC;
335 /*****************************************************************************
337 *****************************************************************************/
338 static void Close( vlc_object_t *p_this )
340 decoder_t *p_dec = (decoder_t*)p_this;
341 decoder_sys_t *p_sys = p_dec->p_sys;
343 block_BytestreamRelease( &p_sys->bytestream );
349 * It parse MLP sync info.
351 * TODO handle CRC (at offset 26)
354 static int TrueHdChannels( int i_map )
356 static const uint8_t pu_thd[13] =
358 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
362 for( int i = 0; i < 13; i++ )
365 i_count += pu_thd[i];
370 static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
374 assert( !memcmp( p_hdr, pu_start_code, 3 ) );
376 /* TODO Checksum ? */
379 bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
382 p_mlp->i_type = bs_read( &s, 8 );
385 if( p_mlp->i_type == 0xbb ) /* MLP */
387 static const unsigned pu_channels[32] = {
388 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
389 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
392 bs_skip( &s, 4 + 4 );
394 i_rate_idx1 = bs_read( &s, 4 );
396 // Just skip the 4 following, since we don't use it
397 // const int i_rate_idx2 = bs_read( &s, 4 );
402 const int i_channel_idx = bs_read( &s, 5 );
403 p_mlp->i_channels = pu_channels[i_channel_idx];
405 else if( p_mlp->i_type == 0xba ) /* True HD */
407 i_rate_idx1 = bs_read( &s, 4 );
411 const int i_channel1 = bs_read( &s, 5 );
415 const int i_channel2 = bs_read( &s, 13 );
417 p_mlp->i_channels = TrueHdChannels( i_channel2 );
419 p_mlp->i_channels = TrueHdChannels( i_channel1 );
426 if( i_rate_idx1 == 0x0f )
429 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
430 p_mlp->i_channels_conf = 0; /* TODO ? */
432 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
436 p_mlp->b_vbr = bs_read( &s, 1 );
437 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
439 p_mlp->i_substreams = bs_read( &s, 4 );
440 bs_skip( &s, 4 + 11 * 8 );
442 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
443 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
447 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
449 /* Check major sync presence */
450 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
452 /* Wait for a major sync */
453 if( !b_has_sync && !*pb_mlp )
456 /* Parse major sync if present */
459 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
465 /* Check parity TODO even with major sync */
468 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
469 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
471 for( unsigned i = 0; i < p_mlp->i_substreams; i++ )
481 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
483 if( ( i_tmp & 0x0f ) != 0x0f )
488 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
493 * It returns the size of an AC3 frame (or 0 if invalid)
495 static int GetAc3Size( const uint8_t *p_buf )
497 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
498 128, 160, 192, 224, 256, 320, 384, 448,
501 const int i_frmsizecod = p_buf[4] & 63;
502 if( i_frmsizecod >= 38 )
505 const int bitrate = pi_rate[i_frmsizecod >> 1];
507 switch( p_buf[4] & 0xc0 )
512 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
521 * It return the size of a EAC3 frame (or 0 if invalid)
523 static int GetEac3Size( const uint8_t *p_buf )
528 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
529 if( i_frame_size < 2 )
531 i_bytes = 2 * ( i_frame_size + 1 );
537 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
539 static int SyncInfoDolby( const uint8_t *p_buf )
544 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
548 bsid = p_buf[5] >> 3;
553 return GetAc3Size( p_buf );
555 return GetEac3Size( p_buf );