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>
38 /*****************************************************************************
40 *****************************************************************************/
41 static int Open ( vlc_object_t * );
42 static void Close( vlc_object_t * );
45 set_category( CAT_SOUT )
46 set_subcategory( SUBCAT_SOUT_PACKETIZER )
47 set_description( N_("MLP/TrueHD parser") )
48 set_capability( "packetizer", 50 )
49 set_callbacks( Open, Close )
52 /*****************************************************************************
54 *****************************************************************************/
77 block_bytestream_t bytestream;
82 audio_date_t end_date;
101 #define MLP_MAX_SUBSTREAMS (16)
102 #define MLP_HEADER_SYNC (28)
103 #define MLP_HEADER_SIZE (4 + MLP_HEADER_SYNC + 4 * MLP_MAX_SUBSTREAMS)
105 static const uint8_t pu_start_code[3] = { 0xf8, 0x72, 0x6f };
107 /****************************************************************************
109 ****************************************************************************/
110 static block_t *Packetize( decoder_t *, block_t **pp_block );
111 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp );
112 static int SyncInfoDolby( const uint8_t *p_buf );
114 /*****************************************************************************
115 * Open: probe the decoder/packetizer and return score
116 *****************************************************************************/
117 static int Open( vlc_object_t *p_this )
119 decoder_t *p_dec = (decoder_t*)p_this;
120 decoder_sys_t *p_sys;
122 if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','l','p',' ') )
126 p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
131 p_sys->i_state = STATE_NOSYNC;
132 aout_DateSet( &p_sys->end_date, 0 );
134 p_sys->bytestream = block_BytestreamInit();
135 p_sys->b_mlp = false;
137 /* Set output properties */
138 p_dec->fmt_out.i_cat = AUDIO_ES;
139 p_dec->fmt_out.i_codec = VLC_FOURCC('m','l','p',' ');
140 p_dec->fmt_out.audio.i_rate = 0;
143 p_dec->pf_packetize = Packetize;
147 /****************************************************************************
149 ****************************************************************************/
150 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
152 decoder_sys_t *p_sys = p_dec->p_sys;
153 uint8_t p_header[MLP_HEADER_SIZE];
154 block_t *p_out_buffer;
157 if( !pp_block || !*pp_block )
161 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
163 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
165 p_sys->b_mlp = false;
166 p_sys->i_state = STATE_NOSYNC;
167 block_BytestreamFlush( &p_sys->bytestream );
169 aout_DateSet( &p_sys->end_date, 0 );
170 block_Release( *pp_block );
174 if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
176 /* We've just started the stream, wait for the first PTS. */
177 block_Release( *pp_block );
181 block_BytestreamPush( &p_sys->bytestream, *pp_block );
185 switch( p_sys->i_state )
188 while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
190 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
192 p_sys->i_state = STATE_SYNC;
195 else if( SyncInfoDolby( p_header ) > 0 )
197 p_sys->i_state = STATE_SYNC;
200 block_SkipByte( &p_sys->bytestream );
202 if( p_sys->i_state != STATE_SYNC )
204 block_BytestreamFlush( &p_sys->bytestream );
211 /* New frame, set the Presentation Time Stamp */
212 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
213 if( p_sys->i_pts != 0 &&
214 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
216 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
218 p_sys->i_state = STATE_HEADER;
221 /* Get a MLP header */
222 if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
228 /* Check if frame is valid and get frame info */
229 p_sys->i_frame_size = SyncInfoDolby( p_header );
230 if( p_sys->i_frame_size <= 0 )
231 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
232 if( p_sys->i_frame_size <= 0 )
234 msg_Dbg( p_dec, "emulated sync word" );
235 block_SkipByte( &p_sys->bytestream );
236 p_sys->b_mlp = false;
237 p_sys->i_state = STATE_NOSYNC;
240 p_sys->i_state = STATE_NEXT_SYNC;
242 case STATE_NEXT_SYNC:
243 /* TODO: If pp_block == NULL, flush the buffer without checking the
246 /* Check if next expected frame contains the sync word */
247 if( block_PeekOffsetBytes( &p_sys->bytestream,
248 p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
254 bool b_mlp = p_sys->b_mlp;
255 mlp_header_t mlp = p_sys->mlp;
256 if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
258 msg_Dbg( p_dec, "emulated sync word "
259 "(no sync on following frame)" );
260 fprintf( stderr,"\n" );
261 p_sys->b_mlp = false;
262 p_sys->i_state = STATE_NOSYNC;
263 block_SkipByte( &p_sys->bytestream );
266 p_sys->i_state = STATE_SEND_DATA;
270 /* Make sure we have enough data.
271 * (Not useful if we went through NEXT_SYNC) */
272 if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) )
277 p_sys->i_state = STATE_SEND_DATA;
279 case STATE_SEND_DATA:
280 /* When we reach this point we already know we have enough
282 p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
286 /* Copy the whole frame into the buffer */
287 block_GetBytes( &p_sys->bytestream,
288 p_out_buffer->p_buffer, p_out_buffer->i_buffer );
290 /* Just ignore (E)AC3 frames */
291 if( SyncInfoDolby( p_out_buffer->p_buffer ) > 0 )
293 block_Release( p_out_buffer );
294 p_sys->i_state = STATE_NOSYNC;
299 if( p_dec->fmt_out.audio.i_rate != p_sys->mlp.i_rate )
301 msg_Info( p_dec, "MLP channels: %d samplerate: %d",
302 p_sys->mlp.i_channels, p_sys->mlp.i_rate );
304 aout_DateInit( &p_sys->end_date, p_sys->mlp.i_rate );
305 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
308 p_dec->fmt_out.audio.i_rate = p_sys->mlp.i_rate;
309 p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
310 p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
311 p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf & AOUT_CHAN_PHYSMASK;
313 p_out_buffer->i_pts = p_out_buffer->i_dts = aout_DateGet( &p_sys->end_date );
315 p_out_buffer->i_length =
316 aout_DateIncrement( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
318 /* Make sure we don't reuse the same pts twice */
319 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
320 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
322 /* So p_block doesn't get re-added several times */
323 *pp_block = block_BytestreamPop( &p_sys->bytestream );
325 p_sys->i_state = STATE_NOSYNC;
334 /*****************************************************************************
336 *****************************************************************************/
337 static void Close( vlc_object_t *p_this )
339 decoder_t *p_dec = (decoder_t*)p_this;
340 decoder_sys_t *p_sys = p_dec->p_sys;
342 block_BytestreamRelease( &p_sys->bytestream );
348 * It parse MLP sync info.
350 * TODO handle CRC (at offset 26)
353 static int TrueHdChannels( int i_map )
355 static const uint8_t pu_thd[13] =
357 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
361 for( int i = 0; i < 13; i++ )
364 i_count += pu_thd[i];
369 static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
373 assert( !memcmp( p_hdr, pu_start_code, 3 ) );
375 /* TODO Checksum ? */
378 bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
381 p_mlp->i_type = bs_read( &s, 8 );
384 if( p_mlp->i_type == 0xbb ) /* MLP */
386 static const unsigned pu_channels[32] = {
387 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
388 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
391 bs_skip( &s, 4 + 4 );
393 i_rate_idx1 = bs_read( &s, 4 );
394 const int i_rate_idx2 = bs_read( &s, 4 );
398 const int i_channel_idx = bs_read( &s, 5 );
399 p_mlp->i_channels = pu_channels[i_channel_idx];
401 else if( p_mlp->i_type == 0xba ) /* True HD */
403 i_rate_idx1 = bs_read( &s, 4 );
407 const int i_channel1 = bs_read( &s, 5 );
411 const int i_channel2 = bs_read( &s, 13 );
413 p_mlp->i_channels = TrueHdChannels( i_channel2 );
415 p_mlp->i_channels = TrueHdChannels( i_channel1 );
422 if( i_rate_idx1 == 0x0f )
425 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
426 p_mlp->i_channels_conf = 0; /* TODO ? */
428 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
432 p_mlp->b_vbr = bs_read( &s, 1 );
433 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
435 p_mlp->i_substreams = bs_read( &s, 4 );
436 bs_skip( &s, 4 + 11 * 8 );
438 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
439 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
443 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
445 /* Check major sync presence */
446 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
448 /* Wait for a major sync */
449 if( !b_has_sync && !*pb_mlp )
452 /* Parse major sync if present */
455 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
461 /* Check parity TODO even with major sync */
464 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
465 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
467 for( int i = 0; i < p_mlp->i_substreams; i++ )
477 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
479 if( ( i_tmp & 0x0f ) != 0x0f )
484 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
489 * It returns the size of an AC3 frame (or 0 if invalid)
491 static int GetAc3Size( const uint8_t *p_buf )
493 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
494 128, 160, 192, 224, 256, 320, 384, 448,
497 const int i_frmsizecod = p_buf[4] & 63;
498 if( i_frmsizecod >= 38 )
501 const int bitrate = pi_rate[i_frmsizecod >> 1];
503 switch( p_buf[4] & 0xc0 )
508 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
517 * It return the size of a EAC3 frame (or 0 if invalid)
519 static int GetEac3Size( const uint8_t *p_buf )
524 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
525 if( i_frame_size < 2 )
527 i_bytes = 2 * ( i_frame_size + 1 );
533 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
535 static int SyncInfoDolby( const uint8_t *p_buf )
540 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
544 bsid = p_buf[5] >> 3;
549 return GetAc3Size( p_buf );
551 return GetEac3Size( p_buf );