OSDN Git Service

BuildSystem: general, configure and Xcode updates.
[handbrake-jp/handbrake-jp-git.git] / libhb / decdca.c
1 /* $Id: decdca.c,v 1.14 2005/03/03 17:21:57 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8 #include "dca.h"
9
10 struct hb_work_private_s
11 {
12     hb_job_t    * job;
13
14     /* libdca handle */
15     dca_state_t * state;
16
17     double        next_pts;
18     int64_t       last_buf_pts;
19     int           flags_in;
20     int           flags_out;
21     int           rate;
22     int           bitrate;
23     int           frame_length;
24     float         level;
25
26     int           error;
27     int           sync;
28     int           size;
29
30     /* max frame size of the 16 bits version is 16384 */
31     /* max frame size of the 14 bits version is 18726 */
32     uint8_t       frame[18726];
33
34     hb_list_t   * list;
35
36         int           out_discrete_channels;
37
38 };
39
40 static int  decdcaInit( hb_work_object_t *, hb_job_t * );
41 static int  decdcaWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
42 static void decdcaClose( hb_work_object_t * );
43 static int  decdcaBSInfo( hb_work_object_t *, const hb_buffer_t *,
44                           hb_work_info_t * );
45
46 hb_work_object_t hb_decdca =
47 {
48     WORK_DECDCA,
49     "DCA decoder",
50     decdcaInit,
51     decdcaWork,
52     decdcaClose,
53     0,
54     decdcaBSInfo
55 };
56
57 /***********************************************************************
58  * Local prototypes
59  **********************************************************************/
60 static hb_buffer_t * Decode( hb_work_object_t * w );
61
62 /***********************************************************************
63  * hb_work_decdca_init
64  ***********************************************************************
65  * Allocate the work object, initialize libdca
66  **********************************************************************/
67 static int decdcaInit( hb_work_object_t * w, hb_job_t * job )
68 {
69     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
70     hb_audio_t * audio = w->audio;
71     w->private_data = pv;
72
73     pv->job   = job;
74
75     pv->list      = hb_list_init();
76     pv->state     = dca_init( 0 );
77
78         /* Decide what format we want out of libdca
79         work.c has already done some of this deduction for us in do_job() */
80
81         pv->flags_out = HB_AMIXDOWN_GET_DCA_FORMAT(audio->config.out.mixdown);
82
83         /* pass the number of channels used into the private work data */
84         /* will only be actually used if we're not doing AC3 passthru */
85     pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
86
87     pv->level     = 32768.0;
88
89     return 0;
90 }
91
92 /***********************************************************************
93  * Close
94  ***********************************************************************
95  * Free memory
96  **********************************************************************/
97 static void decdcaClose( hb_work_object_t * w )
98 {
99     hb_work_private_t * pv = w->private_data;
100     dca_free( pv->state );
101     hb_list_empty( &pv->list );
102     free( pv );
103     w->private_data = NULL;
104 }
105
106 /***********************************************************************
107  * Work
108  ***********************************************************************
109  * Add the given buffer to the data we already have, and decode as much
110  * as we can
111  **********************************************************************/
112 static int decdcaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
113                 hb_buffer_t ** buf_out )
114 {
115     hb_work_private_t * pv = w->private_data;
116     hb_buffer_t * buf;
117
118     if ( (*buf_in)->size <= 0 )
119     {
120         /* EOF on input stream - send it downstream & say that we're done */
121         *buf_out = *buf_in;
122         *buf_in = NULL;
123         return HB_WORK_DONE;
124     }
125
126     if ( (*buf_in)->start < -1 && pv->next_pts == 0 )
127     {
128         // discard buffers that start before video time 0
129         *buf_out = NULL;
130         return HB_WORK_OK;
131     }
132
133     hb_list_add( pv->list, *buf_in );
134     *buf_in = NULL;
135
136     /* If we got more than a frame, chain raw buffers */
137     *buf_out = buf = Decode( w );
138     while( buf )
139     {
140         buf->next = Decode( w );
141         buf       = buf->next;
142     }
143
144     return HB_WORK_OK;
145 }
146
147 /***********************************************************************
148  * Decode
149  ***********************************************************************
150  *
151  **********************************************************************/
152 static hb_buffer_t * Decode( hb_work_object_t * w )
153 {
154     hb_work_private_t * pv = w->private_data;
155     hb_buffer_t * buf;
156     int           i, j, k;
157     int64_t       pts, pos;
158     int           num_blocks;
159
160     /* Get a frame header if don't have one yet */
161     if( !pv->sync )
162     {
163         while( hb_list_bytes( pv->list ) >= 14 )
164         {
165             /* We have 14 bytes, check if this is a correct header */
166             hb_list_seebytes( pv->list, pv->frame, 14 );
167             pv->size = dca_syncinfo( pv->state, pv->frame, &pv->flags_in, &pv->rate,
168                                     &pv->bitrate, &pv->frame_length );
169             if( pv->size )
170             {
171                 /* It is. W00t. */
172                 if( pv->error )
173                 {
174                     hb_log( "dca_syncinfo ok" );
175                 }
176                 pv->error = 0;
177                 pv->sync  = 1;
178                 break;
179             }
180
181             /* It is not */
182             if( !pv->error )
183             {
184                 hb_log( "dca_syncinfo failed" );
185                 pv->error = 1;
186             }
187
188             /* Try one byte later */
189             hb_list_getbytes( pv->list, pv->frame, 1, NULL, NULL );
190         }
191     }
192
193     if( !pv->sync || hb_list_bytes( pv->list ) < pv->size )
194     {
195         /* Need more data */
196         return NULL;
197     }
198
199     /* Get the whole frame */
200     hb_list_getbytes( pv->list, pv->frame, pv->size, &pts, &pos );
201     if ( pts != pv->last_buf_pts )
202     {
203         pv->last_buf_pts = pts;
204     }
205     else
206     {
207         // spec says that the PTS is the start time of the first frame
208         // that starts in the PES frame so we only use the PTS once then
209         // get the following frames' PTS from the frame length.
210         pts = -1;
211     }
212
213     /* Feed libdca */
214     dca_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 );
215
216     /* find out how many blocks are in this frame */
217     num_blocks = dca_blocks_num( pv->state );
218
219     /* num_blocks blocks per frame, 256 samples per block, channelsused channels */
220     int nsamp = num_blocks * 256;
221     buf = hb_buffer_init( nsamp * pv->out_discrete_channels * sizeof( float ) );
222
223     // mkv files typically use a 1ms timebase which results in a lot of
224     // truncation error in their timestamps. Also, TSMuxer or something
225     // in the m2ts-to-mkv toolchain seems to take a very casual attitude
226     // about time - timestamps seem to randomly offset by ~40ms for a few
227     // seconds then recover. So, if the pts we got is within 50ms of the
228     // pts computed from the data stream, use the data stream pts.
229     if ( pts == -1 || ( pv->next_pts && fabs( pts - pv->next_pts ) < 50.*90. ) )
230     {
231         pts = pv->next_pts;
232     }
233     buf->start = pts;
234     pv->next_pts = pts + (double)nsamp / (double)pv->rate * 90000.;
235     buf->stop  = pv->next_pts;
236
237     for( i = 0; i < num_blocks; i++ )
238     {
239         dca_sample_t * samples_in;
240         float    * samples_out;
241
242         dca_block( pv->state );
243         samples_in  = dca_samples( pv->state );
244         samples_out = ((float *) buf->data) + 256 * pv->out_discrete_channels * i;
245
246         /* Interleave */
247         for( j = 0; j < 256; j++ )
248         {
249                         for ( k = 0; k < pv->out_discrete_channels; k++ )
250                         {
251                                 samples_out[(pv->out_discrete_channels*j)+k]   = samples_in[(256*k)+j] * 16384;
252                         }
253         }
254
255     }
256
257     pv->sync = 0;
258     return buf;
259 }
260
261
262 static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
263                          hb_work_info_t *info )
264 {
265     int i, flags, rate, bitrate, frame_length;
266     dca_state_t * state = dca_init( 0 );
267
268     memset( info, 0, sizeof(*info) );
269
270     /* since DCA frames don't line up with MPEG ES frames scan the
271      * entire frame for an DCA sync pattern.  */
272     for ( i = 0; i < b->size - 7; ++i )
273     {
274         if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate,
275                           &frame_length ) )
276         {
277             break;
278         }
279     }
280     if ( i >= b->size - 7 )
281     {
282         /* didn't find DCA sync */
283         return 0;
284     }
285
286     info->name = "DCA";
287     info->rate = rate;
288     info->rate_base = 1;
289     info->bitrate = bitrate;
290     info->flags = flags;
291
292     if ( ( flags & DCA_CHANNEL_MASK) == DCA_DOLBY )
293     {
294         info->flags |= AUDIO_F_DOLBY;
295     }
296
297     switch( flags & DCA_CHANNEL_MASK )
298     {
299         /* mono sources */
300         case DCA_MONO:
301             info->channel_layout = HB_INPUT_CH_LAYOUT_MONO;
302             break;
303         /* stereo input */
304         case DCA_CHANNEL:
305         case DCA_STEREO:
306         case DCA_STEREO_SUMDIFF:
307         case DCA_STEREO_TOTAL:
308             info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
309             break;
310         /* 3F/2R input */
311         case DCA_3F2R:
312             info->channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
313             break;
314         /* 3F/1R input */
315         case DCA_3F1R:
316             info->channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
317             break;
318         /* other inputs */
319         case DCA_3F:
320             info->channel_layout = HB_INPUT_CH_LAYOUT_3F;
321             break;
322         case DCA_2F1R:
323             info->channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
324             break;
325         case DCA_2F2R:
326             info->channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
327             break;
328         case DCA_4F2R:
329             info->channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
330             break;
331         /* unknown */
332         default:
333             info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
334     }
335
336     if (flags & DCA_LFE)
337     {
338         info->channel_layout |= HB_INPUT_CH_LAYOUT_HAS_LFE;
339     }
340
341     return 1;
342 }