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>
34 #include <vlc_block_helper.h>
38 #include "packetizer_helper.h"
40 /*****************************************************************************
42 *****************************************************************************/
43 static int Open ( vlc_object_t * );
44 static void Close( vlc_object_t * );
47 set_category( CAT_SOUT )
48 set_subcategory( SUBCAT_SOUT_PACKETIZER )
49 set_description( N_("MLP/TrueHD parser") )
50 set_capability( "packetizer", 50 )
51 set_callbacks( Open, Close )
54 /*****************************************************************************
56 *****************************************************************************/
68 unsigned i_substreams;
79 block_bytestream_t bytestream;
93 #define MLP_MAX_SUBSTREAMS (16)
94 #define MLP_HEADER_SYNC (28)
95 #define MLP_HEADER_SIZE (4 + MLP_HEADER_SYNC + 4 * MLP_MAX_SUBSTREAMS)
97 static const uint8_t pu_start_code[3] = { 0xf8, 0x72, 0x6f };
99 /****************************************************************************
101 ****************************************************************************/
102 static block_t *Packetize( decoder_t *, block_t **pp_block );
103 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp );
104 static int SyncInfoDolby( const uint8_t *p_buf );
106 /*****************************************************************************
107 * Open: probe the decoder/packetizer and return score
108 *****************************************************************************/
109 static int Open( vlc_object_t *p_this )
111 decoder_t *p_dec = (decoder_t*)p_this;
112 decoder_sys_t *p_sys;
114 if( p_dec->fmt_in.i_codec != VLC_CODEC_MLP &&
115 p_dec->fmt_in.i_codec != VLC_CODEC_TRUEHD )
119 p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
124 p_sys->i_state = STATE_NOSYNC;
125 date_Set( &p_sys->end_date, 0 );
127 block_BytestreamInit( &p_sys->bytestream );
128 p_sys->b_mlp = false;
130 /* Set output properties */
131 p_dec->fmt_out.i_cat = AUDIO_ES;
132 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
133 p_dec->fmt_out.audio.i_rate = 0;
136 p_dec->pf_packetize = Packetize;
140 /****************************************************************************
142 ****************************************************************************/
143 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
145 decoder_sys_t *p_sys = p_dec->p_sys;
146 uint8_t p_header[MLP_HEADER_SIZE];
147 block_t *p_out_buffer;
150 if( !pp_block || !*pp_block )
154 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
156 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
158 p_sys->b_mlp = false;
159 p_sys->i_state = STATE_NOSYNC;
160 block_BytestreamEmpty( &p_sys->bytestream );
162 date_Set( &p_sys->end_date, 0 );
163 block_Release( *pp_block );
167 if( !date_Get( &p_sys->end_date ) && !(*pp_block)->i_pts )
169 /* We've just started the stream, wait for the first PTS. */
170 block_Release( *pp_block );
174 block_BytestreamPush( &p_sys->bytestream, *pp_block );
178 switch( p_sys->i_state )
181 while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
183 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
185 p_sys->i_state = STATE_SYNC;
188 else if( SyncInfoDolby( p_header ) > 0 )
190 p_sys->i_state = STATE_SYNC;
193 block_SkipByte( &p_sys->bytestream );
195 if( p_sys->i_state != STATE_SYNC )
197 block_BytestreamFlush( &p_sys->bytestream );
204 /* New frame, set the Presentation Time Stamp */
205 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
206 if( p_sys->i_pts > VLC_TS_INVALID &&
207 p_sys->i_pts != date_Get( &p_sys->end_date ) )
209 date_Set( &p_sys->end_date, p_sys->i_pts );
211 p_sys->i_state = STATE_HEADER;
214 /* Get a MLP header */
215 if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
221 /* Check if frame is valid and get frame info */
222 p_sys->i_frame_size = SyncInfoDolby( p_header );
223 if( p_sys->i_frame_size <= 0 )
224 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
225 if( p_sys->i_frame_size <= 0 )
227 msg_Dbg( p_dec, "emulated sync word" );
228 block_SkipByte( &p_sys->bytestream );
229 p_sys->b_mlp = false;
230 p_sys->i_state = STATE_NOSYNC;
233 p_sys->i_state = STATE_NEXT_SYNC;
235 case STATE_NEXT_SYNC:
236 /* TODO: If pp_block == NULL, flush the buffer without checking the
239 /* Check if next expected frame contains the sync word */
240 if( block_PeekOffsetBytes( &p_sys->bytestream,
241 p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
247 bool b_mlp = p_sys->b_mlp;
248 mlp_header_t mlp = p_sys->mlp;
249 if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
251 msg_Dbg( p_dec, "emulated sync word "
252 "(no sync on following frame)" );
253 p_sys->b_mlp = false;
254 p_sys->i_state = STATE_NOSYNC;
255 block_SkipByte( &p_sys->bytestream );
258 p_sys->i_state = STATE_SEND_DATA;
262 /* Make sure we have enough data.
263 * (Not useful if we went through NEXT_SYNC) */
264 if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) )
269 p_sys->i_state = STATE_SEND_DATA;
271 case STATE_SEND_DATA:
272 /* When we reach this point we already know we have enough
274 p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
278 /* Copy the whole frame into the buffer */
279 block_GetBytes( &p_sys->bytestream,
280 p_out_buffer->p_buffer, p_out_buffer->i_buffer );
282 /* Just ignore (E)AC3 frames */
283 if( SyncInfoDolby( p_out_buffer->p_buffer ) > 0 )
285 block_Release( p_out_buffer );
286 p_sys->i_state = STATE_NOSYNC;
291 if( p_dec->fmt_out.audio.i_rate != p_sys->mlp.i_rate )
293 msg_Info( p_dec, "MLP channels: %d samplerate: %d",
294 p_sys->mlp.i_channels, p_sys->mlp.i_rate );
296 const mtime_t i_end_date = date_Get( &p_sys->end_date );
297 date_Init( &p_sys->end_date, p_sys->mlp.i_rate, 1 );
298 date_Set( &p_sys->end_date, i_end_date );
301 p_dec->fmt_out.audio.i_rate = p_sys->mlp.i_rate;
302 p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
303 p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
304 p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf;
306 p_out_buffer->i_pts = p_out_buffer->i_dts = date_Get( &p_sys->end_date );
308 p_out_buffer->i_length =
309 date_Increment( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
311 /* Make sure we don't reuse the same pts twice */
312 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
313 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
315 /* So p_block doesn't get re-added several times */
316 *pp_block = block_BytestreamPop( &p_sys->bytestream );
318 p_sys->i_state = STATE_NOSYNC;
327 /*****************************************************************************
329 *****************************************************************************/
330 static void Close( vlc_object_t *p_this )
332 decoder_t *p_dec = (decoder_t*)p_this;
333 decoder_sys_t *p_sys = p_dec->p_sys;
335 block_BytestreamRelease( &p_sys->bytestream );
341 * It parse MLP sync info.
343 * TODO handle CRC (at offset 26)
346 static int TrueHdChannels( int i_map )
348 static const uint8_t pu_thd[13] =
350 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
354 for( int i = 0; i < 13; i++ )
357 i_count += pu_thd[i];
362 static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
366 assert( !memcmp( p_hdr, pu_start_code, 3 ) );
368 /* TODO Checksum ? */
371 bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
374 p_mlp->i_type = bs_read( &s, 8 );
377 if( p_mlp->i_type == 0xbb ) /* MLP */
379 static const unsigned pu_channels[32] = {
380 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
381 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
384 bs_skip( &s, 4 + 4 );
386 i_rate_idx1 = bs_read( &s, 4 );
388 // Just skip the 4 following, since we don't use it
389 // const int i_rate_idx2 = bs_read( &s, 4 );
394 const int i_channel_idx = bs_read( &s, 5 );
395 p_mlp->i_channels = pu_channels[i_channel_idx];
397 else if( p_mlp->i_type == 0xba ) /* True HD */
399 i_rate_idx1 = bs_read( &s, 4 );
403 const int i_channel1 = bs_read( &s, 5 );
407 const int i_channel2 = bs_read( &s, 13 );
409 p_mlp->i_channels = TrueHdChannels( i_channel2 );
411 p_mlp->i_channels = TrueHdChannels( i_channel1 );
418 if( i_rate_idx1 == 0x0f )
421 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
422 p_mlp->i_channels_conf = 0; /* TODO ? */
424 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
428 p_mlp->b_vbr = bs_read( &s, 1 );
429 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
431 p_mlp->i_substreams = bs_read( &s, 4 );
432 bs_skip( &s, 4 + 11 * 8 );
434 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
435 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
439 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
441 /* Check major sync presence */
442 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
444 /* Wait for a major sync */
445 if( !b_has_sync && !*pb_mlp )
448 /* Parse major sync if present */
451 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
457 /* Check parity TODO even with major sync */
460 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
461 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
463 for( unsigned i = 0; i < p_mlp->i_substreams; i++ )
473 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
475 if( ( i_tmp & 0x0f ) != 0x0f )
480 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
485 * It returns the size of an AC3 frame (or 0 if invalid)
487 static int GetAc3Size( const uint8_t *p_buf )
489 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
490 128, 160, 192, 224, 256, 320, 384, 448,
493 const int i_frmsizecod = p_buf[4] & 63;
494 if( i_frmsizecod >= 38 )
497 const int bitrate = pi_rate[i_frmsizecod >> 1];
499 switch( p_buf[4] & 0xc0 )
504 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
513 * It return the size of a EAC3 frame (or 0 if invalid)
515 static int GetEac3Size( const uint8_t *p_buf )
520 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
521 if( i_frame_size < 2 )
523 i_bytes = 2 * ( i_frame_size + 1 );
529 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
531 static int SyncInfoDolby( const uint8_t *p_buf )
536 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
540 bsid = p_buf[5] >> 3;
545 return GetAc3Size( p_buf );
547 return GetEac3Size( p_buf );