]> git.sesse.net Git - vlc/blob - modules/codec/dts.c
string review
[vlc] / modules / codec / dts.c
1 /*****************************************************************************
2  * dts.c: parse DTS audio sync info and packetize the stream
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: dts.c,v 1.11 2004/01/25 18:20:12 bigben Exp $
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <vlc/vlc.h>
29 #include <vlc/decoder.h>
30
31 #include "vlc_block_helper.h"
32
33 #define DTS_HEADER_SIZE 12
34
35 /*****************************************************************************
36  * decoder_sys_t : decoder descriptor
37  *****************************************************************************/
38 struct decoder_sys_t
39 {
40     /* Module mode */
41     vlc_bool_t b_packetizer;
42
43     /*
44      * Input properties
45      */
46     int i_state;
47
48     block_bytestream_t bytestream;
49
50     /*
51      * Common properties
52      */
53     audio_date_t   end_date;
54
55     mtime_t i_pts;
56
57     int i_frame_size, i_bit_rate;
58     unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
59
60     /* This is very hacky. For DTS over S/PDIF we apparently need to send
61      * 3 frames at a time. This should likely be moved to the output stage. */
62     int i_frames_in_buf;
63     aout_buffer_t *p_aout_buffer;        /* current aout buffer being filled */
64
65 };
66
67 enum {
68
69     STATE_NOSYNC,
70     STATE_SYNC,
71     STATE_HEADER,
72     STATE_NEXT_SYNC,
73     STATE_GET_DATA,
74     STATE_SEND_DATA
75 };
76
77 /****************************************************************************
78  * Local prototypes
79  ****************************************************************************/
80 static int  OpenDecoder   ( vlc_object_t * );
81 static int  OpenPacketizer( vlc_object_t * );
82 static void CloseDecoder  ( vlc_object_t * );
83 static void *DecodeBlock  ( decoder_t *, block_t ** );
84
85 static inline int SyncCode( const uint8_t * );
86 static int  SyncInfo      ( const uint8_t *, unsigned int *, unsigned int *,
87                             unsigned int *, unsigned int *, unsigned int * );
88
89 static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
90 static aout_buffer_t *GetAoutBuffer( decoder_t * );
91 static block_t       *GetSoutBuffer( decoder_t * );
92
93 /*****************************************************************************
94  * Module descriptor
95  *****************************************************************************/
96 vlc_module_begin();
97     set_description( _("DTS parser") );
98     set_capability( "decoder", 100 );
99     set_callbacks( OpenDecoder, CloseDecoder );
100
101     add_submodule();
102     set_description( _("DTS audio packetizer") );
103     set_capability( "packetizer", 10 );
104     set_callbacks( OpenPacketizer, NULL );
105 vlc_module_end();
106
107 /*****************************************************************************
108  * OpenDecoder: probe the decoder and return score
109  *****************************************************************************/
110 static int OpenDecoder( vlc_object_t *p_this )
111 {
112     decoder_t *p_dec = (decoder_t*)p_this;
113     decoder_sys_t *p_sys;
114
115     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s',' ')
116          && p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s','b') )
117     {
118         return VLC_EGENERIC;
119     }
120
121     /* Allocate the memory needed to store the decoder's structure */
122     if( ( p_dec->p_sys = p_sys =
123           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
124     {
125         msg_Err( p_dec, "out of memory" );
126         return VLC_EGENERIC;
127     }
128
129     /* Misc init */
130     p_sys->b_packetizer = VLC_FALSE;
131     p_sys->i_state = STATE_NOSYNC;
132     aout_DateSet( &p_sys->end_date, 0 );
133     p_sys->i_frames_in_buf = 0;
134
135     p_sys->bytestream = block_BytestreamInit( p_dec );
136
137     /* Set output properties */
138     p_dec->fmt_out.i_cat = AUDIO_ES;
139     p_dec->fmt_out.i_codec = VLC_FOURCC('d','t','s',' ');
140
141     /* Set callback */
142     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
143         DecodeBlock;
144     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
145         DecodeBlock;
146
147     return VLC_SUCCESS;
148 }
149
150 static int OpenPacketizer( vlc_object_t *p_this )
151 {
152     decoder_t *p_dec = (decoder_t*)p_this;
153
154     int i_ret = OpenDecoder( p_this );
155
156     if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
157
158     return i_ret;
159 }
160
161 /****************************************************************************
162  * DecodeBlock: the whole thing
163  ****************************************************************************
164  * This function is called just after the thread is launched.
165  ****************************************************************************/
166 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
167 {
168     decoder_sys_t *p_sys = p_dec->p_sys;
169     uint8_t p_header[DTS_HEADER_SIZE];
170     uint8_t *p_buf;
171     void *p_out_buffer;
172
173     if( !pp_block || !*pp_block ) return NULL;
174
175     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
176     {
177         /* We've just started the stream, wait for the first PTS. */
178         block_Release( *pp_block );
179         return NULL;
180     }
181
182     if( (*pp_block)->b_discontinuity )
183     {
184         p_sys->i_state = STATE_NOSYNC;
185     }
186
187     block_BytestreamPush( &p_sys->bytestream, *pp_block );
188
189     while( 1 )
190     {
191         switch( p_sys->i_state )
192         {
193         case STATE_NOSYNC:
194             /* Look for sync code - should be 0x7ffe8001 */
195             while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
196                    == VLC_SUCCESS )
197             {
198                 if( SyncCode( p_header ) == VLC_SUCCESS )
199                 {
200                     p_sys->i_state = STATE_SYNC;
201                     break;
202                 }
203                 block_SkipByte( &p_sys->bytestream );
204             }
205             if( p_sys->i_state != STATE_SYNC )
206             {
207                 block_BytestreamFlush( &p_sys->bytestream );
208
209                 /* Need more data */
210                 return NULL;
211             }
212
213         case STATE_SYNC:
214             /* New frame, set the Presentation Time Stamp */
215             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
216             if( p_sys->i_pts != 0 &&
217                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
218             {
219                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
220             }
221             p_sys->i_state = STATE_HEADER;
222
223         case STATE_HEADER:
224             /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
225             if( block_PeekBytes( &p_sys->bytestream, p_header,
226                                  DTS_HEADER_SIZE ) != VLC_SUCCESS )
227             {
228                 /* Need more data */
229                 return NULL;
230             }
231
232             /* Check if frame is valid and get frame info */
233             p_sys->i_frame_size = SyncInfo( p_header,
234                                             &p_sys->i_channels,
235                                             &p_sys->i_channels_conf,
236                                             &p_sys->i_rate,
237                                             &p_sys->i_bit_rate,
238                                             &p_sys->i_frame_length );
239             if( !p_sys->i_frame_size )
240             {
241                 msg_Dbg( p_dec, "emulated sync word" );
242                 block_SkipByte( &p_sys->bytestream );
243                 p_sys->i_state = STATE_NOSYNC;
244                 break;
245             }
246             p_sys->i_state = STATE_NEXT_SYNC;
247
248         case STATE_NEXT_SYNC:
249             /* TODO: If pp_block == NULL, flush the buffer without checking the
250              * next sync word */
251
252             /* Check if next expected frame contains the sync word */
253             if( block_PeekOffsetBytes( &p_sys->bytestream,
254                                        p_sys->i_frame_size, p_header, 6 )
255                 != VLC_SUCCESS )
256             {
257                 /* Need more data */
258                 return NULL;
259             }
260
261             if( SyncCode( p_header ) != VLC_SUCCESS )
262             {
263                 msg_Dbg( p_dec, "emulated sync word "
264                          "(no sync on following frame): %2.2x%2.2x%2.2x%2.2x",
265                          (int)p_header[0], (int)p_header[1],
266                          (int)p_header[2], (int)p_header[3] );
267                 p_sys->i_state = STATE_NOSYNC;
268                 block_SkipByte( &p_sys->bytestream );
269                 break;
270             }
271             p_sys->i_state = STATE_SEND_DATA;
272             break;
273
274         case STATE_GET_DATA:
275             /* Make sure we have enough data.
276              * (Not useful if we went through NEXT_SYNC) */
277             if( block_WaitBytes( &p_sys->bytestream,
278                                  p_sys->i_frame_size ) != VLC_SUCCESS )
279             {
280                 /* Need more data */
281                 return NULL;
282             }
283             p_sys->i_state = STATE_SEND_DATA;
284
285         case STATE_SEND_DATA:
286             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
287             {
288                 //p_dec->b_error = VLC_TRUE;
289                 return NULL;
290             }
291
292             /* Copy the whole frame into the buffer. When we reach this point
293              * we already know we have enough data available. */
294             block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
295
296             /* Make sure we don't reuse the same pts twice */
297             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
298                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
299
300             /* So p_block doesn't get re-added several times */
301             *pp_block = block_BytestreamPop( &p_sys->bytestream );
302
303             p_sys->i_state = STATE_NOSYNC;
304
305             if( !p_sys->b_packetizer )
306             {
307                 if( p_sys->i_frames_in_buf != 3 ) return NULL;
308                 else
309                 {
310                     p_sys->i_frames_in_buf = 0;
311                     p_sys->p_aout_buffer = 0;
312                 }
313             }
314
315             return p_out_buffer;
316         }
317     }
318
319     return NULL;
320 }
321
322 /*****************************************************************************
323  * CloseDecoder: clean up the decoder
324  *****************************************************************************/
325 static void CloseDecoder( vlc_object_t *p_this )
326 {
327     decoder_t *p_dec = (decoder_t*)p_this;
328     decoder_sys_t *p_sys = p_dec->p_sys;
329
330     block_BytestreamRelease( &p_sys->bytestream );
331
332     free( p_sys );
333 }
334
335 /*****************************************************************************
336  * GetOutBuffer:
337  *****************************************************************************/
338 static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
339 {
340     decoder_sys_t *p_sys = p_dec->p_sys;
341     uint8_t *p_buf;
342
343     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
344     {
345         msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
346                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
347
348         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
349         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
350     }
351
352     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
353     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
354     p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
355     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
356
357     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
358     p_dec->fmt_out.audio.i_physical_channels =
359         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
360
361     p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
362
363     if( p_sys->b_packetizer )
364     {
365         block_t *p_sout_buffer = GetSoutBuffer( p_dec );
366         p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
367         *pp_out_buffer = p_sout_buffer;
368     }
369     else
370     {
371         if( !p_sys->i_frames_in_buf )
372         {
373             p_sys->p_aout_buffer = GetAoutBuffer( p_dec );
374         }
375         p_buf = p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer +
376             p_sys->i_frames_in_buf * p_sys->i_frame_size : NULL;
377         *pp_out_buffer = p_sys->p_aout_buffer;
378     }
379
380     p_sys->i_frames_in_buf++;
381
382     return p_buf;
383 }
384
385 /*****************************************************************************
386  * GetAoutBuffer:
387  *****************************************************************************/
388 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
389 {
390     decoder_sys_t *p_sys = p_dec->p_sys;
391     aout_buffer_t *p_buf;
392
393     p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length * 3 );
394     if( p_buf == NULL ) return NULL;
395
396     p_buf->start_date = aout_DateGet( &p_sys->end_date );
397     p_buf->end_date =
398         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length * 3 );
399
400     return p_buf;
401 }
402
403 /*****************************************************************************
404  * GetSoutBuffer:
405  *****************************************************************************/
406 static block_t *GetSoutBuffer( decoder_t *p_dec )
407 {
408     decoder_sys_t *p_sys = p_dec->p_sys;
409     block_t *p_block;
410
411     p_block = block_New( p_dec, p_sys->i_frame_size );
412     if( p_block == NULL ) return NULL;
413
414     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
415
416     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
417         p_sys->i_frame_length ) - p_block->i_pts;
418
419     return p_block;
420 }
421
422 /*****************************************************************************
423  * SyncInfo: parse DTS sync info
424  *****************************************************************************/
425 static const unsigned int ppi_dts_samplerate[] =
426 {
427     0, 8000, 16000, 32000, 64000, 128000,
428     11025, 22050, 44010, 88020, 176400,
429     12000, 24000, 48000, 96000, 192000
430 };
431
432 static const unsigned int ppi_dts_bitrate[] =
433 {
434     32000, 56000, 64000, 96000, 112000, 128000,
435     192000, 224000, 256000, 320000, 384000,
436     448000, 512000, 576000, 640000, 768000,
437     896000, 1024000, 1152000, 1280000, 1344000,
438     1408000, 1411200, 1472000, 1536000, 1920000,
439     2048000, 3072000, 3840000, 4096000, 0, 0
440 };
441
442 static int SyncInfo16be( const uint8_t *p_buf,
443                          unsigned int *pi_audio_mode,
444                          unsigned int *pi_sample_rate,
445                          unsigned int *pi_bit_rate,
446                          unsigned int *pi_frame_length )
447 {
448     unsigned int i_frame_size;
449
450     *pi_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
451     i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
452                    (p_buf[7] >> 4);
453
454     *pi_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
455     *pi_sample_rate = (p_buf[8] >> 2) & 0x0f;
456     *pi_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
457
458     return i_frame_size + 1;
459 }
460
461 static int Buf14leTO16be( uint8_t *p_out, const uint8_t *p_in, int i_in )
462 {
463     unsigned char tmp, cur = 0;
464     int bits_in, bits_out = 0;
465     int i, i_out = 0;
466
467     for( i = 0; i < i_in; i++  )
468     {
469         if( i%2 )
470         {
471             tmp = p_in[i-1];
472             bits_in = 8;
473         }
474         else
475         {
476             tmp = p_in[i+1] & 0x3F;
477             bits_in = 8 - 2;
478         }
479
480         if( bits_out < 8 )
481         {
482             int need = __MIN( 8 - bits_out, bits_in );
483             cur <<= need;
484             cur |= ( tmp >> (bits_in - need) );
485             tmp <<= (8 - bits_in + need);
486             tmp >>= (8 - bits_in + need);
487             bits_in -= need;
488             bits_out += need;
489         }
490
491         if( bits_out == 8 )
492         {
493             p_out[i_out] = cur;
494             cur = 0;
495             bits_out = 0;
496             i_out++;
497         }
498
499         bits_out += bits_in;
500         cur <<= bits_in;
501         cur |= tmp;
502     }
503
504     return i_out;
505 }
506
507 static inline int SyncCode( const uint8_t *p_buf )
508 {
509     /* 14 bits, little endian version of the bitstream */
510     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
511         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
512         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
513     {
514         return VLC_SUCCESS;
515     }
516     /* 16 bits, big endian version of the bitstream */
517     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
518              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
519     {
520         return VLC_SUCCESS;
521     }
522     else return VLC_EGENERIC;
523 }
524
525 static int SyncInfo( const uint8_t *p_buf,
526                      unsigned int *pi_channels,
527                      unsigned int *pi_channels_conf,
528                      unsigned int *pi_sample_rate,
529                      unsigned int *pi_bit_rate,
530                      unsigned int *pi_frame_length )
531 {
532     unsigned int i_audio_mode;
533     unsigned int i_frame_size;
534
535     /* 14 bits, little endian version of the bitstream */
536     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
537         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
538         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
539     {
540         uint8_t conv_buf[12];
541         Buf14leTO16be( conv_buf, p_buf, 12 );
542         i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
543                                      pi_bit_rate, pi_frame_length );
544         i_frame_size = i_frame_size * 8 / 14 * 2;
545     }
546     /* 16 bits, big endian version of the bitstream */
547     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
548              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
549     {
550         i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
551                                      pi_bit_rate, pi_frame_length );
552     }
553     else return 0;
554
555     switch( i_audio_mode )
556     {
557         case 0x0:
558             /* Mono */
559             *pi_channels_conf = AOUT_CHAN_CENTER;
560             break;
561         case 0x1:
562             /* Dual-mono = stereo + dual-mono */
563             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
564                            AOUT_CHAN_DUALMONO;
565             break;
566         case 0x2:
567         case 0x3:
568         case 0x4:
569             /* Stereo */
570             *pi_channels = 2;
571             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
572             break;
573         case 0x5:
574             /* 3F */
575             *pi_channels = 3;
576             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
577                                 AOUT_CHAN_CENTER;
578             break;
579         case 0x6:
580             /* 2F/LFE */
581             *pi_channels = 3;
582             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
583                                 AOUT_CHAN_LFE;
584             break;
585         case 0x7:
586             /* 3F/LFE */
587             *pi_channels = 4;
588             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
589                                 AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
590             break;
591         case 0x8:
592             /* 2F2R */
593             *pi_channels = 4;
594             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
595                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
596             break;
597         case 0x9:
598             /* 3F2R */
599             *pi_channels = 5;
600             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
601                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
602                                 AOUT_CHAN_REARRIGHT;
603             break;
604         case 0xA:
605         case 0xB:
606             /* 2F2M2R */
607             *pi_channels = 6;
608             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
609                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
610                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
611             break;
612         case 0xC:
613             /* 3F2M2R */
614             *pi_channels = 7;
615             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
616                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
617                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
618                                 AOUT_CHAN_REARRIGHT;
619             break;
620         case 0xD:
621         case 0xE:
622             /* 3F2M2R/LFE */
623             *pi_channels = 8;
624             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
625                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
626                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
627                                 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
628             break;
629
630         default:
631             if( i_audio_mode <= 63 )
632             {
633                 /* User defined */
634                 *pi_channels = 0;
635                 *pi_channels_conf = 0;
636             }
637             else return 0;
638             break;
639     }
640
641     if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
642                            sizeof( ppi_dts_samplerate[0] ) )
643     {
644         return 0;
645     }
646
647     *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
648
649     if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
650                         sizeof( ppi_dts_bitrate[0] ) )
651     {
652         return 0;
653     }
654
655     *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
656
657     *pi_frame_length = (*pi_frame_length + 1) * 32;
658
659     return i_frame_size;
660 }