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 *****************************************************************************/
67 unsigned i_substreams;
78 block_bytestream_t bytestream;
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 date_Set( &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 date_Set( &p_sys->end_date, 0 );
172 block_Release( *pp_block );
176 if( !date_Get( &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 > VLC_TS_INVALID &&
216 p_sys->i_pts != date_Get( &p_sys->end_date ) )
218 date_Set( &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 const mtime_t i_end_date = date_Get( &p_sys->end_date );
306 date_Init( &p_sys->end_date, p_sys->mlp.i_rate, 1 );
307 date_Set( &p_sys->end_date, i_end_date );
310 p_dec->fmt_out.audio.i_rate = p_sys->mlp.i_rate;
311 p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
312 p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
313 p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf & AOUT_CHAN_PHYSMASK;
315 p_out_buffer->i_pts = p_out_buffer->i_dts = date_Get( &p_sys->end_date );
317 p_out_buffer->i_length =
318 date_Increment( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
320 /* Make sure we don't reuse the same pts twice */
321 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
322 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
324 /* So p_block doesn't get re-added several times */
325 *pp_block = block_BytestreamPop( &p_sys->bytestream );
327 p_sys->i_state = STATE_NOSYNC;
336 /*****************************************************************************
338 *****************************************************************************/
339 static void Close( vlc_object_t *p_this )
341 decoder_t *p_dec = (decoder_t*)p_this;
342 decoder_sys_t *p_sys = p_dec->p_sys;
344 block_BytestreamRelease( &p_sys->bytestream );
350 * It parse MLP sync info.
352 * TODO handle CRC (at offset 26)
355 static int TrueHdChannels( int i_map )
357 static const uint8_t pu_thd[13] =
359 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
363 for( int i = 0; i < 13; i++ )
366 i_count += pu_thd[i];
371 static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
375 assert( !memcmp( p_hdr, pu_start_code, 3 ) );
377 /* TODO Checksum ? */
380 bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
383 p_mlp->i_type = bs_read( &s, 8 );
386 if( p_mlp->i_type == 0xbb ) /* MLP */
388 static const unsigned pu_channels[32] = {
389 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
390 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 bs_skip( &s, 4 + 4 );
395 i_rate_idx1 = bs_read( &s, 4 );
397 // Just skip the 4 following, since we don't use it
398 // const int i_rate_idx2 = bs_read( &s, 4 );
403 const int i_channel_idx = bs_read( &s, 5 );
404 p_mlp->i_channels = pu_channels[i_channel_idx];
406 else if( p_mlp->i_type == 0xba ) /* True HD */
408 i_rate_idx1 = bs_read( &s, 4 );
412 const int i_channel1 = bs_read( &s, 5 );
416 const int i_channel2 = bs_read( &s, 13 );
418 p_mlp->i_channels = TrueHdChannels( i_channel2 );
420 p_mlp->i_channels = TrueHdChannels( i_channel1 );
427 if( i_rate_idx1 == 0x0f )
430 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
431 p_mlp->i_channels_conf = 0; /* TODO ? */
433 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
437 p_mlp->b_vbr = bs_read( &s, 1 );
438 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
440 p_mlp->i_substreams = bs_read( &s, 4 );
441 bs_skip( &s, 4 + 11 * 8 );
443 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
444 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
448 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
450 /* Check major sync presence */
451 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
453 /* Wait for a major sync */
454 if( !b_has_sync && !*pb_mlp )
457 /* Parse major sync if present */
460 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
466 /* Check parity TODO even with major sync */
469 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
470 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
472 for( unsigned i = 0; i < p_mlp->i_substreams; i++ )
482 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
484 if( ( i_tmp & 0x0f ) != 0x0f )
489 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
494 * It returns the size of an AC3 frame (or 0 if invalid)
496 static int GetAc3Size( const uint8_t *p_buf )
498 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
499 128, 160, 192, 224, 256, 320, 384, 448,
502 const int i_frmsizecod = p_buf[4] & 63;
503 if( i_frmsizecod >= 38 )
506 const int bitrate = pi_rate[i_frmsizecod >> 1];
508 switch( p_buf[4] & 0xc0 )
513 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
522 * It return the size of a EAC3 frame (or 0 if invalid)
524 static int GetEac3Size( const uint8_t *p_buf )
529 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
530 if( i_frame_size < 2 )
532 i_bytes = 2 * ( i_frame_size + 1 );
538 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
540 static int SyncInfoDolby( const uint8_t *p_buf )
545 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
549 bsid = p_buf[5] >> 3;
554 return GetAc3Size( p_buf );
556 return GetEac3Size( p_buf );