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 #include "packetizer_helper.h"
41 /*****************************************************************************
43 *****************************************************************************/
44 static int Open ( vlc_object_t * );
45 static void Close( vlc_object_t * );
48 set_category( CAT_SOUT )
49 set_subcategory( SUBCAT_SOUT_PACKETIZER )
50 set_description( N_("MLP/TrueHD parser") )
51 set_capability( "packetizer", 50 )
52 set_callbacks( Open, Close )
55 /*****************************************************************************
57 *****************************************************************************/
69 unsigned i_substreams;
80 block_bytestream_t bytestream;
94 #define MLP_MAX_SUBSTREAMS (16)
95 #define MLP_HEADER_SYNC (28)
96 #define MLP_HEADER_SIZE (4 + MLP_HEADER_SYNC + 4 * MLP_MAX_SUBSTREAMS)
98 static const uint8_t pu_start_code[3] = { 0xf8, 0x72, 0x6f };
100 /****************************************************************************
102 ****************************************************************************/
103 static block_t *Packetize( decoder_t *, block_t **pp_block );
104 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp );
105 static int SyncInfoDolby( const uint8_t *p_buf );
107 /*****************************************************************************
108 * Open: probe the decoder/packetizer and return score
109 *****************************************************************************/
110 static int Open( vlc_object_t *p_this )
112 decoder_t *p_dec = (decoder_t*)p_this;
113 decoder_sys_t *p_sys;
115 if( p_dec->fmt_in.i_codec != VLC_CODEC_MLP &&
116 p_dec->fmt_in.i_codec != VLC_CODEC_TRUEHD )
120 p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
125 p_sys->i_state = STATE_NOSYNC;
126 date_Set( &p_sys->end_date, 0 );
128 block_BytestreamInit( &p_sys->bytestream );
129 p_sys->b_mlp = false;
131 /* Set output properties */
132 p_dec->fmt_out.i_cat = AUDIO_ES;
133 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
134 p_dec->fmt_out.audio.i_rate = 0;
137 p_dec->pf_packetize = Packetize;
141 /****************************************************************************
143 ****************************************************************************/
144 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
146 decoder_sys_t *p_sys = p_dec->p_sys;
147 uint8_t p_header[MLP_HEADER_SIZE];
148 block_t *p_out_buffer;
151 if( !pp_block || !*pp_block )
155 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
157 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
159 p_sys->b_mlp = false;
160 p_sys->i_state = STATE_NOSYNC;
161 block_BytestreamEmpty( &p_sys->bytestream );
163 date_Set( &p_sys->end_date, 0 );
164 block_Release( *pp_block );
168 if( !date_Get( &p_sys->end_date ) && !(*pp_block)->i_pts )
170 /* We've just started the stream, wait for the first PTS. */
171 block_Release( *pp_block );
175 block_BytestreamPush( &p_sys->bytestream, *pp_block );
179 switch( p_sys->i_state )
182 while( !block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
184 if( SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp ) > 0 )
186 p_sys->i_state = STATE_SYNC;
189 else if( SyncInfoDolby( p_header ) > 0 )
191 p_sys->i_state = STATE_SYNC;
194 block_SkipByte( &p_sys->bytestream );
196 if( p_sys->i_state != STATE_SYNC )
198 block_BytestreamFlush( &p_sys->bytestream );
205 /* New frame, set the Presentation Time Stamp */
206 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
207 if( p_sys->i_pts > VLC_TS_INVALID &&
208 p_sys->i_pts != date_Get( &p_sys->end_date ) )
210 date_Set( &p_sys->end_date, p_sys->i_pts );
212 p_sys->i_state = STATE_HEADER;
215 /* Get a MLP header */
216 if( block_PeekBytes( &p_sys->bytestream, p_header, MLP_HEADER_SIZE ) )
222 /* Check if frame is valid and get frame info */
223 p_sys->i_frame_size = SyncInfoDolby( p_header );
224 if( p_sys->i_frame_size <= 0 )
225 p_sys->i_frame_size = SyncInfo( p_header, &p_sys->b_mlp, &p_sys->mlp );
226 if( p_sys->i_frame_size <= 0 )
228 msg_Dbg( p_dec, "emulated sync word" );
229 block_SkipByte( &p_sys->bytestream );
230 p_sys->b_mlp = false;
231 p_sys->i_state = STATE_NOSYNC;
234 p_sys->i_state = STATE_NEXT_SYNC;
236 case STATE_NEXT_SYNC:
237 /* TODO: If pp_block == NULL, flush the buffer without checking the
240 /* Check if next expected frame contains the sync word */
241 if( block_PeekOffsetBytes( &p_sys->bytestream,
242 p_sys->i_frame_size, p_header, MLP_HEADER_SIZE ) )
248 bool b_mlp = p_sys->b_mlp;
249 mlp_header_t mlp = p_sys->mlp;
250 if( SyncInfo( p_header, &b_mlp, &mlp ) <= 0 && SyncInfoDolby( p_header ) <= 0 )
252 msg_Dbg( p_dec, "emulated sync word "
253 "(no sync on following frame)" );
254 p_sys->b_mlp = false;
255 p_sys->i_state = STATE_NOSYNC;
256 block_SkipByte( &p_sys->bytestream );
259 p_sys->i_state = STATE_SEND_DATA;
263 /* Make sure we have enough data.
264 * (Not useful if we went through NEXT_SYNC) */
265 if( block_WaitBytes( &p_sys->bytestream, p_sys->i_frame_size ) )
270 p_sys->i_state = STATE_SEND_DATA;
272 case STATE_SEND_DATA:
273 /* When we reach this point we already know we have enough
275 p_out_buffer = block_New( p_dec, p_sys->i_frame_size );
279 /* Copy the whole frame into the buffer */
280 block_GetBytes( &p_sys->bytestream,
281 p_out_buffer->p_buffer, p_out_buffer->i_buffer );
283 /* Just ignore (E)AC3 frames */
284 if( SyncInfoDolby( p_out_buffer->p_buffer ) > 0 )
286 block_Release( p_out_buffer );
287 p_sys->i_state = STATE_NOSYNC;
292 if( p_dec->fmt_out.audio.i_rate != p_sys->mlp.i_rate )
294 msg_Info( p_dec, "MLP channels: %d samplerate: %d",
295 p_sys->mlp.i_channels, p_sys->mlp.i_rate );
297 const mtime_t i_end_date = date_Get( &p_sys->end_date );
298 date_Init( &p_sys->end_date, p_sys->mlp.i_rate, 1 );
299 date_Set( &p_sys->end_date, i_end_date );
302 p_dec->fmt_out.audio.i_rate = p_sys->mlp.i_rate;
303 p_dec->fmt_out.audio.i_channels = p_sys->mlp.i_channels;
304 p_dec->fmt_out.audio.i_original_channels = p_sys->mlp.i_channels_conf;
305 p_dec->fmt_out.audio.i_physical_channels = p_sys->mlp.i_channels_conf & AOUT_CHAN_PHYSMASK;
307 p_out_buffer->i_pts = p_out_buffer->i_dts = date_Get( &p_sys->end_date );
309 p_out_buffer->i_length =
310 date_Increment( &p_sys->end_date, p_sys->mlp.i_samples ) - p_out_buffer->i_pts;
312 /* Make sure we don't reuse the same pts twice */
313 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
314 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
316 /* So p_block doesn't get re-added several times */
317 *pp_block = block_BytestreamPop( &p_sys->bytestream );
319 p_sys->i_state = STATE_NOSYNC;
328 /*****************************************************************************
330 *****************************************************************************/
331 static void Close( vlc_object_t *p_this )
333 decoder_t *p_dec = (decoder_t*)p_this;
334 decoder_sys_t *p_sys = p_dec->p_sys;
336 block_BytestreamRelease( &p_sys->bytestream );
342 * It parse MLP sync info.
344 * TODO handle CRC (at offset 26)
347 static int TrueHdChannels( int i_map )
349 static const uint8_t pu_thd[13] =
351 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
355 for( int i = 0; i < 13; i++ )
358 i_count += pu_thd[i];
363 static int MlpParse( mlp_header_t *p_mlp, const uint8_t p_hdr[MLP_HEADER_SYNC] )
367 assert( !memcmp( p_hdr, pu_start_code, 3 ) );
369 /* TODO Checksum ? */
372 bs_init( &s, &p_hdr[3], MLP_HEADER_SYNC - 3 );
375 p_mlp->i_type = bs_read( &s, 8 );
378 if( p_mlp->i_type == 0xbb ) /* MLP */
380 static const unsigned pu_channels[32] = {
381 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
382 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385 bs_skip( &s, 4 + 4 );
387 i_rate_idx1 = bs_read( &s, 4 );
389 // Just skip the 4 following, since we don't use it
390 // const int i_rate_idx2 = bs_read( &s, 4 );
395 const int i_channel_idx = bs_read( &s, 5 );
396 p_mlp->i_channels = pu_channels[i_channel_idx];
398 else if( p_mlp->i_type == 0xba ) /* True HD */
400 i_rate_idx1 = bs_read( &s, 4 );
404 const int i_channel1 = bs_read( &s, 5 );
408 const int i_channel2 = bs_read( &s, 13 );
410 p_mlp->i_channels = TrueHdChannels( i_channel2 );
412 p_mlp->i_channels = TrueHdChannels( i_channel1 );
419 if( i_rate_idx1 == 0x0f )
422 p_mlp->i_rate = ( ( i_rate_idx1 & 0x8 ) ? 44100 : 48000 ) << (i_rate_idx1 & 0x7);
423 p_mlp->i_channels_conf = 0; /* TODO ? */
425 p_mlp->i_samples = 40 << ( i_rate_idx1 & 0x07 );
429 p_mlp->b_vbr = bs_read( &s, 1 );
430 p_mlp->i_bitrate = ( bs_read( &s, 15 ) * p_mlp->i_rate + 8) / 16;
432 p_mlp->i_substreams = bs_read( &s, 4 );
433 bs_skip( &s, 4 + 11 * 8 );
435 //fprintf( stderr, "i_samples = %d channels:%d rate:%d bitsrate=%d substreams=%d\n",
436 // p_mlp->i_samples, p_mlp->i_channels, p_mlp->i_rate, p_mlp->i_bitrate, p_mlp->i_substreams );
440 static int SyncInfo( const uint8_t *p_hdr, bool *pb_mlp, mlp_header_t *p_mlp )
442 /* Check major sync presence */
443 const bool b_has_sync = !memcmp( &p_hdr[4], pu_start_code, 3 );
445 /* Wait for a major sync */
446 if( !b_has_sync && !*pb_mlp )
449 /* Parse major sync if present */
452 *pb_mlp = !MlpParse( p_mlp, &p_hdr[4] );
458 /* Check parity TODO even with major sync */
461 int i_tmp = 0 ^ p_hdr[0] ^ p_hdr[1] ^ p_hdr[2] ^ p_hdr[3];
462 const uint8_t *p = &p_hdr[4 + ( b_has_sync ? 28 : 0 )];
464 for( unsigned i = 0; i < p_mlp->i_substreams; i++ )
474 i_tmp = ( i_tmp >> 4 ) ^ i_tmp;
476 if( ( i_tmp & 0x0f ) != 0x0f )
481 const int i_word = ( ( p_hdr[0] << 8 ) | p_hdr[1] ) & 0xfff;
486 * It returns the size of an AC3 frame (or 0 if invalid)
488 static int GetAc3Size( const uint8_t *p_buf )
490 static const int pi_rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
491 128, 160, 192, 224, 256, 320, 384, 448,
494 const int i_frmsizecod = p_buf[4] & 63;
495 if( i_frmsizecod >= 38 )
498 const int bitrate = pi_rate[i_frmsizecod >> 1];
500 switch( p_buf[4] & 0xc0 )
505 return 2 * (320 * bitrate / 147 + (i_frmsizecod & 1));
514 * It return the size of a EAC3 frame (or 0 if invalid)
516 static int GetEac3Size( const uint8_t *p_buf )
521 i_frame_size = ( ( p_buf[2] << 8 ) | p_buf[3] ) & 0x7ff;
522 if( i_frame_size < 2 )
524 i_bytes = 2 * ( i_frame_size + 1 );
530 * It returns the size of an AC3/EAC3 frame (or 0 if invalid)
532 static int SyncInfoDolby( const uint8_t *p_buf )
537 if( p_buf[0] != 0x0b || p_buf[1] != 0x77 )
541 bsid = p_buf[5] >> 3;
546 return GetAc3Size( p_buf );
548 return GetEac3Size( p_buf );