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 *****************************************************************************/
78 block_bytestream_t bytestream;
83 audio_date_t end_date;
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_FOURCC('m','l','p',' ') )
127 p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
132 p_sys->i_state = STATE_NOSYNC;
133 aout_DateSet( &p_sys->end_date, 0 );
135 p_sys->bytestream = block_BytestreamInit();
136 p_sys->b_mlp = false;
138 /* Set output properties */
139 p_dec->fmt_out.i_cat = AUDIO_ES;
140 p_dec->fmt_out.i_codec = VLC_FOURCC('m','l','p',' ');
141 p_dec->fmt_out.audio.i_rate = 0;
144 p_dec->pf_packetize = Packetize;
148 /****************************************************************************
150 ****************************************************************************/
151 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
153 decoder_sys_t *p_sys = p_dec->p_sys;
154 uint8_t p_header[MLP_HEADER_SIZE];
155 block_t *p_out_buffer;
158 if( !pp_block || !*pp_block )
162 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
164 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
166 p_sys->b_mlp = false;
167 p_sys->i_state = STATE_NOSYNC;
168 block_BytestreamEmpty( &p_sys->bytestream );
170 aout_DateSet( &p_sys->end_date, 0 );
171 block_Release( *pp_block );
175 if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
177 /* We've just started the stream, wait for the first PTS. */
178 block_Release( *pp_block );
182 block_BytestreamPush( &p_sys->bytestream, *pp_block );
186 switch( p_sys->i_state )
189 while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
191 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
193 p_sys->i_state = STATE_SYNC;
196 else if( SyncInfoDolby( p_header ) > 0 )
198 p_sys->i_state = STATE_SYNC;
201 block_SkipByte( &p_sys->bytestream );
203 if( p_sys->i_state != STATE_SYNC )
205 block_BytestreamFlush( &p_sys->bytestream );
212 /* New frame, set the Presentation Time Stamp */
213 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
214 if( p_sys->i_pts != 0 &&
215 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
217 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
219 p_sys->i_state = STATE_HEADER;
222 /* Get a MLP header */
223 if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
229 /* Check if frame is valid and get frame info */
230 p_sys->i_frame_size = SyncInfoDolby( p_header );
231 if( p_sys->i_frame_size <= 0 )
232 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
233 if( p_sys->i_frame_size <= 0 )
235 msg_Dbg( p_dec, "emulated sync word" );
236 block_SkipByte( &p_sys->bytestream );
237 p_sys->b_mlp = false;
238 p_sys->i_state = STATE_NOSYNC;
241 p_sys->i_state = STATE_NEXT_SYNC;
243 case STATE_NEXT_SYNC:
244 /* TODO: If pp_block == NULL, flush the buffer without checking the
247 /* Check if next expected frame contains the sync word */
248 if( block_PeekOffsetBytes( &p_sys->bytestream,
249 p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
255 bool b_mlp = p_sys->b_mlp;
256 mlp_header_t mlp = p_sys->mlp;
257 if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
259 msg_Dbg( p_dec, "emulated sync word "
260 "(no sync on following frame)" );
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 );