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 block_Release( *pp_block );
173 if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
175 /* We've just started the stream, wait for the first PTS. */
176 block_Release( *pp_block );
180 block_BytestreamPush( &p_sys->bytestream, *pp_block );
184 switch( p_sys->i_state )
187 while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
189 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
191 p_sys->i_state = STATE_SYNC;
194 else if( SyncInfoDolby( p_header ) > 0 )
196 p_sys->i_state = STATE_SYNC;
199 block_SkipByte( &p_sys->bytestream );
201 if( p_sys->i_state != STATE_SYNC )
203 block_BytestreamFlush( &p_sys->bytestream );
210 /* New frame, set the Presentation Time Stamp */
211 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
212 if( p_sys->i_pts != 0 &&
213 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
215 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
217 p_sys->i_state = STATE_HEADER;
220 /* Get a MLP header */
221 if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
227 /* Check if frame is valid and get frame info */
228 p_sys->i_frame_size = SyncInfoDolby( p_header );
229 if( p_sys->i_frame_size <= 0 )
230 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
231 if( p_sys->i_frame_size <= 0 )
233 msg_Dbg( p_dec, "emulated sync word" );
234 block_SkipByte( &p_sys->bytestream );
235 p_sys->b_mlp = false;
236 p_sys->i_state = STATE_NOSYNC;
239 p_sys->i_state = STATE_NEXT_SYNC;
241 case STATE_NEXT_SYNC:
242 /* TODO: If pp_block == NULL, flush the buffer without checking the
245 /* Check if next expected frame contains the sync word */
246 if( block_PeekOffsetBytes( &p_sys->bytestream,
247 p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
253 bool b_mlp = p_sys->b_mlp;
254 mlp_header_t mlp = p_sys->mlp;
255 if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
257 msg_Dbg( p_dec, "emulated sync word "
258 "(no sync on following frame)" );
259 fprintf( stderr,"\n" );
260 p_sys->b_mlp = false;
261 p_sys->i_state = STATE_NOSYNC;
262 block_SkipByte( &p_sys->bytestream );
265 p_sys->i_state = STATE_SEND_DATA;
269 /* Make sure we have enough data.
270 * (Not useful if we went through NEXT_SYNC) */
271 if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) )
276 p_sys->i_state = STATE_SEND_DATA;
278 case STATE_SEND_DATA:
279 /* When we reach this point we already know we have enough
281 p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
285 /* Copy the whole frame into the buffer */
286 block_GetBytes( &p_sys->bytestream,
287 p_out_buffer->p_buffer, p_out_buffer->i_buffer );
289 /* Just ignore (E)AC3 frames */
290 if( SyncInfoDolby( p_out_buffer->p_buffer ) > 0 )
292 block_Release( p_out_buffer );
293 p_sys->i_state = STATE_NOSYNC;
298 if( p_dec->fmt_out.audio.i_rate != p_sys->mlp.i_rate )
300 msg_Info( p_dec, "MLP channels: %d samplerate: %d",
301 p_sys->mlp.i_channels, p_sys->mlp.i_rate );
303 aout_DateInit( &p_sys->end_date, p_sys->mlp.i_rate );
304 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
307 p_dec->fmt_out.audio.i_rate = p_sys->mlp.i_rate;
308 p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
309 p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
310 p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf & AOUT_CHAN_PHYSMASK;
312 p_out_buffer->i_pts = p_out_buffer->i_dts = aout_DateGet( &p_sys->end_date );
314 p_out_buffer->i_length =
315 aout_DateIncrement( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
317 /* Make sure we don't reuse the same pts twice */
318 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
319 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
321 /* So p_block doesn't get re-added several times */
322 *pp_block = block_BytestreamPop( &p_sys->bytestream );
324 p_sys->i_state = STATE_NOSYNC;
333 /*****************************************************************************
335 *****************************************************************************/
336 static void Close( vlc_object_t *p_this )
338 decoder_t *p_dec = (decoder_t*)p_this;
339 decoder_sys_t *p_sys = p_dec->p_sys;
341 block_BytestreamRelease( &p_sys->bytestream );
347 * It parse MLP sync info.
349 * TODO handle CRC (at offset 26)
352 static int TrueHdChannels( int i_map )
354 static const uint8_t pu_thd[13] =
356 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
360 for( int i = 0; i < 13; i++ )
363 i_count += pu_thd[i];
368 static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
372 assert( !memcmp( p_hdr, pu_start_code, 3 ) );
374 /* TODO Checksum ? */
377 bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
380 p_mlp->i_type = bs_read( &s, 8 );
383 if( p_mlp->i_type == 0xbb ) /* MLP */
385 static const unsigned pu_channels[32] = {
386 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
387 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
390 bs_skip( &s, 4 + 4 );
392 i_rate_idx1 = bs_read( &s, 4 );
393 const int i_rate_idx2 = bs_read( &s, 4 );
397 const int i_channel_idx = bs_read( &s, 5 );
398 p_mlp->i_channels = pu_channels[i_channel_idx];
400 else if( p_mlp->i_type == 0xba ) /* True HD */
402 i_rate_idx1 = bs_read( &s, 4 );
406 const int i_channel1 = bs_read( &s, 5 );
410 const int i_channel2 = bs_read( &s, 13 );
412 p_mlp->i_channels = TrueHdChannels( i_channel2 );
414 p_mlp->i_channels = TrueHdChannels( i_channel1 );
421 if( i_rate_idx1 == 0x0f )
424 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
425 p_mlp->i_channels_conf = 0; /* TODO ? */
427 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
431 p_mlp->b_vbr = bs_read( &s, 1 );
432 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
434 p_mlp->i_substreams = bs_read( &s, 4 );
435 bs_skip( &s, 4 + 11 * 8 );
437 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
438 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
442 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
444 /* Check major sync presence */
445 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
447 /* Wait for a major sync */
448 if( !b_has_sync && !*pb_mlp )
451 /* Parse major sync if present */
454 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
460 /* Check parity TODO even with major sync */
463 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
464 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
466 for( int i = 0; i < p_mlp->i_substreams; i++ )
476 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
478 if( ( i_tmp & 0x0f ) != 0x0f )
483 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
488 * It returns the size of an AC3 frame (or 0 if invalid)
490 static int GetAc3Size( const uint8_t *p_buf )
492 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
493 128, 160, 192, 224, 256, 320, 384, 448,
496 const int i_frmsizecod = p_buf[4] & 63;
497 if( i_frmsizecod >= 38 )
500 const int bitrate = pi_rate[i_frmsizecod >> 1];
502 switch( p_buf[4] & 0xc0 )
507 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
516 * It return the size of a EAC3 frame (or 0 if invalid)
518 static int GetEac3Size( const uint8_t *p_buf )
523 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
524 if( i_frame_size < 2 )
526 i_bytes = 2 * ( i_frame_size + 1 );
532 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
534 static int SyncInfoDolby( const uint8_t *p_buf )
539 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
543 bsid = p_buf[5] >> 3;
548 return GetAc3Size( p_buf );
550 return GetEac3Size( p_buf );