OSDN Git Service

WinGui:
[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     if ( audio->config.out.codec == HB_ACODEC_LAME )
83         pv->flags_out |= DCA_ADJUST_LEVEL;
84
85     /* pass the number of channels used into the private work data */
86     /* will only be actually used if we're not doing AC3 passthru */
87     pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
88
89     pv->level     = 32768.0;
90
91     return 0;
92 }
93
94 /***********************************************************************
95  * Close
96  ***********************************************************************
97  * Free memory
98  **********************************************************************/
99 static void decdcaClose( hb_work_object_t * w )
100 {
101     hb_work_private_t * pv = w->private_data;
102     dca_free( pv->state );
103     hb_list_empty( &pv->list );
104     free( pv );
105     w->private_data = NULL;
106 }
107
108 /***********************************************************************
109  * Work
110  ***********************************************************************
111  * Add the given buffer to the data we already have, and decode as much
112  * as we can
113  **********************************************************************/
114 static int decdcaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
115                 hb_buffer_t ** buf_out )
116 {
117     hb_work_private_t * pv = w->private_data;
118     hb_buffer_t * buf;
119
120     if ( (*buf_in)->size <= 0 )
121     {
122         /* EOF on input stream - send it downstream & say that we're done */
123         *buf_out = *buf_in;
124         *buf_in = NULL;
125         return HB_WORK_DONE;
126     }
127
128     if ( (*buf_in)->start < -1 && pv->next_pts == 0 )
129     {
130         // discard buffers that start before video time 0
131         *buf_out = NULL;
132         return HB_WORK_OK;
133     }
134
135     hb_list_add( pv->list, *buf_in );
136     *buf_in = NULL;
137
138     /* If we got more than a frame, chain raw buffers */
139     *buf_out = buf = Decode( w );
140     while( buf )
141     {
142         buf->next = Decode( w );
143         buf       = buf->next;
144     }
145
146     return HB_WORK_OK;
147 }
148
149 /***********************************************************************
150  * Decode
151  ***********************************************************************
152  *
153  **********************************************************************/
154 static hb_buffer_t * Decode( hb_work_object_t * w )
155 {
156     hb_work_private_t * pv = w->private_data;
157     hb_buffer_t * buf;
158     hb_audio_t  * audio = w->audio;
159     int           i, j, k;
160     int64_t       pts, pos;
161     uint64_t      upts, upos;
162     int           num_blocks;
163
164     /* Get a frame header if don't have one yet */
165     if( !pv->sync )
166     {
167         while( hb_list_bytes( pv->list ) >= 14 )
168         {
169             /* We have 14 bytes, check if this is a correct header */
170             hb_list_seebytes( pv->list, pv->frame, 14 );
171             pv->size = dca_syncinfo( pv->state, pv->frame, &pv->flags_in, &pv->rate,
172                                     &pv->bitrate, &pv->frame_length );
173             if( pv->size )
174             {
175                 /* It is. W00t. */
176                 if( pv->error )
177                 {
178                     hb_log( "dca_syncinfo ok" );
179                 }
180                 pv->error = 0;
181                 pv->sync  = 1;
182                 break;
183             }
184
185             /* It is not */
186             if( !pv->error )
187             {
188                 hb_log( "dca_syncinfo failed" );
189                 pv->error = 1;
190             }
191
192             /* Try one byte later */
193             hb_list_getbytes( pv->list, pv->frame, 1, NULL, NULL );
194         }
195     }
196
197     if( !pv->sync || hb_list_bytes( pv->list ) < pv->size )
198     {
199         /* Need more data */
200         return NULL;
201     }
202
203     /* Get the whole frame */
204     hb_list_getbytes( pv->list, pv->frame, pv->size, &upts, &upos );
205     pts = (int64_t)upts;
206     pos = (int64_t)upos;
207
208     if ( pts != pv->last_buf_pts )
209     {
210         pv->last_buf_pts = pts;
211     }
212     else
213     {
214         // spec says that the PTS is the start time of the first frame
215         // that starts in the PES frame so we only use the PTS once then
216         // get the following frames' PTS from the frame length.
217         pts = -1;
218     }
219
220     // mkv files typically use a 1ms timebase which results in a lot of
221     // truncation error in their timestamps. Also, TSMuxer or something
222     // in the m2ts-to-mkv toolchain seems to take a very casual attitude
223     // about time - timestamps seem to randomly offset by ~40ms for a few
224     // seconds then recover. So, if the pts we got is within 50ms of the
225     // pts computed from the data stream, use the data stream pts.
226     if ( pts == -1 || ( pv->next_pts && fabs( pts - pv->next_pts ) < 50.*90. ) )
227     {
228         pts = pv->next_pts;
229     }
230
231     double frame_dur = (double)(pv->frame_length & ~0xFF) / (double)pv->rate * 90000.;
232
233     /* DCA passthrough: don't decode the DCA frame */
234     if( audio->config.out.codec == HB_ACODEC_DCA_PASS )
235     {
236         buf = hb_buffer_init( pv->size );
237         memcpy( buf->data, pv->frame, pv->size );
238         buf->start = pts;
239         pv->next_pts = pts + frame_dur;
240         buf->stop  = pv->next_pts;
241         pv->sync = 0;
242         return buf;
243     }
244
245     /* Feed libdca */
246     dca_frame( pv->state, pv->frame, &pv->flags_out, &pv->level, 0 );
247
248     /* find out how many blocks are in this frame */
249     num_blocks = dca_blocks_num( pv->state );
250
251     /* num_blocks blocks per frame, 256 samples per block, channelsused channels */
252     int nsamp = num_blocks * 256;
253     buf = hb_buffer_init( nsamp * pv->out_discrete_channels * sizeof( float ) );
254
255     buf->start = pts;
256     pv->next_pts = pts + (double)nsamp / (double)pv->rate * 90000.;
257     buf->stop  = pv->next_pts;
258
259     for( i = 0; i < num_blocks; i++ )
260     {
261         dca_sample_t * samples_in;
262         float    * samples_out;
263
264         dca_block( pv->state );
265         samples_in  = dca_samples( pv->state );
266         samples_out = ((float *) buf->data) + 256 * pv->out_discrete_channels * i;
267
268         /* Interleave */
269         for( j = 0; j < 256; j++ )
270         {
271             for ( k = 0; k < pv->out_discrete_channels; k++ )
272             {
273                 samples_out[(pv->out_discrete_channels*j)+k]   = samples_in[(256*k)+j] * 16384;
274             }
275         }
276
277     }
278
279     pv->sync = 0;
280     return buf;
281 }
282
283
284 static int decdcaBSInfo( hb_work_object_t *w, const hb_buffer_t *b,
285                          hb_work_info_t *info )
286 {
287     int i, flags, rate, bitrate, frame_length;
288     dca_state_t * state = dca_init( 0 );
289
290     memset( info, 0, sizeof(*info) );
291
292     /* since DCA frames don't line up with MPEG ES frames scan the
293      * entire frame for an DCA sync pattern.  */
294     for ( i = 0; i < b->size - 7; ++i )
295     {
296         if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate,
297                           &frame_length ) )
298         {
299             break;
300         }
301     }
302     if ( i >= b->size - 7 )
303     {
304         /* didn't find DCA sync */
305         return 0;
306     }
307
308     info->name = "DCA";
309     info->rate = rate;
310     info->rate_base = 1;
311     info->bitrate = bitrate;
312     info->flags = flags;
313
314     if ( ( flags & DCA_CHANNEL_MASK) == DCA_DOLBY )
315     {
316         info->flags |= AUDIO_F_DOLBY;
317     }
318
319     switch( flags & DCA_CHANNEL_MASK )
320     {
321         /* mono sources */
322         case DCA_MONO:
323             info->channel_layout = HB_INPUT_CH_LAYOUT_MONO;
324             break;
325         /* stereo input */
326         case DCA_CHANNEL:
327         case DCA_STEREO:
328         case DCA_STEREO_SUMDIFF:
329         case DCA_STEREO_TOTAL:
330             info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
331             break;
332         /* 3F/2R input */
333         case DCA_3F2R:
334             info->channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
335             break;
336         /* 3F/1R input */
337         case DCA_3F1R:
338             info->channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
339             break;
340         /* other inputs */
341         case DCA_3F:
342             info->channel_layout = HB_INPUT_CH_LAYOUT_3F;
343             break;
344         case DCA_2F1R:
345             info->channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
346             break;
347         case DCA_2F2R:
348             info->channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
349             break;
350         case DCA_4F2R:
351             info->channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
352             break;
353         /* unknown */
354         default:
355             info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
356     }
357
358     if (flags & DCA_LFE)
359     {
360         info->channel_layout |= HB_INPUT_CH_LAYOUT_HAS_LFE;
361     }
362
363     return 1;
364 }