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_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 aout_DateSet( &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 aout_DateSet( &p_sys->end_date, 0 );
172 block_Release( *pp_block );
176 if( !aout_DateGet( &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 != 0 &&
216 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
218 aout_DateSet( &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 aout_DateInit( &p_sys->end_date, p_sys->mlp.i_rate );
306 aout_DateSet( &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 = aout_DateGet( &p_sys->end_date );
316 p_out_buffer->i_length =
317 aout_DateIncrement( &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 = 0;
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 );
395 const int i_rate_idx2 = bs_read( &s, 4 );
399 const int i_channel_idx = bs_read( &s, 5 );
400 p_mlp->i_channels = pu_channels[i_channel_idx];
402 else if( p_mlp->i_type == 0xba ) /* True HD */
404 i_rate_idx1 = bs_read( &s, 4 );
408 const int i_channel1 = bs_read( &s, 5 );
412 const int i_channel2 = bs_read( &s, 13 );
414 p_mlp->i_channels = TrueHdChannels( i_channel2 );
416 p_mlp->i_channels = TrueHdChannels( i_channel1 );
423 if( i_rate_idx1 == 0x0f )
426 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
427 p_mlp->i_channels_conf = 0; /* TODO ? */
429 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
433 p_mlp->b_vbr = bs_read( &s, 1 );
434 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
436 p_mlp->i_substreams = bs_read( &s, 4 );
437 bs_skip( &s, 4 + 11 * 8 );
439 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
440 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
444 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
446 /* Check major sync presence */
447 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
449 /* Wait for a major sync */
450 if( !b_has_sync && !*pb_mlp )
453 /* Parse major sync if present */
456 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
462 /* Check parity TODO even with major sync */
465 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
466 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
468 for( int i = 0; i < p_mlp->i_substreams; i++ )
478 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
480 if( ( i_tmp & 0x0f ) != 0x0f )
485 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
490 * It returns the size of an AC3 frame (or 0 if invalid)
492 static int GetAc3Size( const uint8_t *p_buf )
494 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
495 128, 160, 192, 224, 256, 320, 384, 448,
498 const int i_frmsizecod = p_buf[4] & 63;
499 if( i_frmsizecod >= 38 )
502 const int bitrate = pi_rate[i_frmsizecod >> 1];
504 switch( p_buf[4] & 0xc0 )
509 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
518 * It return the size of a EAC3 frame (or 0 if invalid)
520 static int GetEac3Size( const uint8_t *p_buf )
525 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
526 if( i_frame_size < 2 )
528 i_bytes = 2 * ( i_frame_size + 1 );
534 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
536 static int SyncInfoDolby( const uint8_t *p_buf )
541 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
545 bsid = p_buf[5] >> 3;
550 return GetAc3Size( p_buf );
552 return GetEac3Size( p_buf );