OSDN Git Service

Put the correct subtitle language in the Queue for the Mac GUI.
[handbrake-jp/handbrake-jp-git.git] / libhb / decmpeg2.c
1 /* $Id: decmpeg2.c,v 1.12 2005/03/03 16:30:42 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 #include "mpeg2dec/mpeg2.h"
10
11 /* Cadence tracking */
12 #ifndef PIC_FLAG_REPEAT_FIRST_FIELD
13 #define PIC_FLAG_REPEAT_FIRST_FIELD 256
14 #endif
15 #define TOP_FIRST PIC_FLAG_TOP_FIELD_FIRST
16 #define PROGRESSIVE PIC_FLAG_PROGRESSIVE_FRAME
17 #define COMPOSITE PIC_FLAG_COMPOSITE_DISPLAY
18 #define SKIP PIC_FLAG_SKIP
19 #define TAGS PIC_FLAG_TAGS
20 #define REPEAT_FIRST PIC_FLAG_REPEAT_FIRST_FIELD
21 #define COMPOSITE_MASK PIC_MASK_COMPOSITE_DISPLAY
22 #define TB 8
23 #define BT 16
24 #define BT_PROG 32
25 #define BTB_PROG 64
26 #define TB_PROG 128
27 #define TBT_PROG 256
28 int cadence[12];
29 int flag = 0;
30
31 /**********************************************************************
32  * hb_libmpeg2_t
33  **********************************************************************
34  * A convenient libmpeg wrapper, used both here and in scan.c
35  *********************************************************************/
36 struct hb_libmpeg2_s
37 {
38     mpeg2dec_t         * libmpeg2;
39     const mpeg2_info_t * info;
40     int                  width;
41     int                  height;
42     int                  rate;
43     int                  aspect_ratio;
44     int                  got_iframe;
45     int                  look_for_break;
46     int64_t              last_pts;
47 };
48
49 /**********************************************************************
50  * hb_libmpeg2_init
51  **********************************************************************
52  * 
53  *********************************************************************/
54 hb_libmpeg2_t * hb_libmpeg2_init()
55 {
56     hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
57     
58     m->libmpeg2 = mpeg2_init();
59     m->info     = mpeg2_info( m->libmpeg2 );
60     m->last_pts = -1;
61     m->look_for_break = 0;
62
63     return m;
64 }
65
66 /**********************************************************************
67  * hb_libmpeg2_decode
68  **********************************************************************
69  * 
70  *********************************************************************/
71 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
72                         hb_list_t * list_raw )
73 {
74     mpeg2_state_t   state;
75     hb_buffer_t   * buf;
76     uint8_t       * data;
77     int             chap_break = 0;
78
79     /* Feed libmpeg2 */
80     if( buf_es->start > -1 )
81     {
82         mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
83                            buf_es->start & 0xFFFFFFFF );
84     }
85     mpeg2_buffer( m->libmpeg2, buf_es->data,
86                   buf_es->data + buf_es->size );
87
88     for( ;; )
89     {
90         state = mpeg2_parse( m->libmpeg2 );
91         if( state == STATE_BUFFER )
92         {
93             /* Require some more data */
94             break;
95         }
96         else if( state == STATE_SEQUENCE )
97         {
98             if( !( m->width && m->height && m->rate ) )
99             {
100                 m->width  = m->info->sequence->width;
101                 m->height = m->info->sequence->height;
102                 m->rate   = m->info->sequence->frame_period;
103             }
104             if ( m->aspect_ratio <= 0 )
105             {
106               // We can parse out the aspect ratio from the Sequence Start Header data in buf_es->data
107               
108               // Make sure we have the correct data in the buffer
109               if ((buf_es->data[0] == 0x00) && (buf_es->data[1] == 0x00) && (buf_es->data[2] == 0x01) && (buf_es->data[3] == 0xb3))
110               {
111                 unsigned char ar_fr = buf_es->data[7];    // Top 4 bits == aspect ratio flag  - bottom 4 bits == rate flags
112                 switch ((ar_fr & 0xf0) >> 4)
113                 {
114                   case 2:
115                     m->aspect_ratio = HB_ASPECT_BASE * 4 / 3;   // 4:3
116                     break;
117                   case 3:
118                     m->aspect_ratio = HB_ASPECT_BASE * 16 / 9;  // 16:9
119                     break;
120                   default:
121                     hb_log("hb_libmpeg2_decode - STATE_SEQUENCE unexpected aspect ratio/frame rate 0x%x\n", ar_fr);
122                     break;
123                 }
124               } 
125             }
126         }
127         else if( state == STATE_GOP && m->look_for_break == 2)
128         {
129             hb_log("MPEG2: Group of pictures found, searching for I-Frame");
130             m->look_for_break = 1;
131         }
132         else if( ( state == STATE_SLICE || state == STATE_END ) &&
133                  m->info->display_fbuf )
134         {
135             if( ( m->info->display_picture->flags &
136                   PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
137             {
138                 m->got_iframe = 1;
139                 
140                 // If we are looking for a break, insert the chapter break on an I-Frame
141                 if( m->look_for_break == 1 )
142                 {
143                     hb_log("MPEG2: I-Frame Found");
144                     m->look_for_break = 0;
145                     chap_break = 1;
146                 }
147             }
148
149             if( m->got_iframe )
150             {
151                 buf  = hb_buffer_init( m->width * m->height * 3 / 2 );
152                 data = buf->data;
153
154                 buf->sequence = buf_es->sequence;
155
156                 // Was a good break point found?
157                 if( chap_break )
158                 {
159                     hb_log("MPEG2: Chapter Break Inserted");
160                     chap_break = 0;
161                     buf->new_chap = 1;
162                 }
163
164                 memcpy( data, m->info->display_fbuf->buf[0],
165                         m->width * m->height );
166                 data += m->width * m->height;
167                 memcpy( data, m->info->display_fbuf->buf[1],
168                         m->width * m->height / 4 );
169                 data += m->width * m->height / 4;
170                 memcpy( data, m->info->display_fbuf->buf[2],
171                         m->width * m->height / 4 );
172
173                 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
174                 {
175                     buf->start =
176                         ( (uint64_t) m->info->display_picture->tag << 32 ) |
177                         ( (uint64_t) m->info->display_picture->tag2 );
178                     /*
179                       * Add back in again to track PTS of MPEG2 frames
180                       * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
181                     */
182                 }
183                 else if( m->last_pts > -1 )
184                 {
185                     /* For some reason nb_fields is sometimes 1 while it
186                        should be 2 */
187                     buf->start = m->last_pts +
188                         MAX( 2, m->info->display_picture->nb_fields ) *
189                         m->info->sequence->frame_period / 600;
190                 }
191                 else
192                 {
193                     buf->start = -1;
194                 }
195                 m->last_pts = buf->start;
196
197                 flag = m->info->display_picture->flags;
198                
199 /*  Uncomment this block to see frame-by-frame picture flags, as the video encodes.
200                hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
201                 if( flag & TOP_FIRST )
202                     hb_log("MPEG2 Flag: Top field first");
203                 if( flag & PROGRESSIVE )
204                     hb_log("MPEG2 Flag: Progressive");
205                 if( flag & COMPOSITE )
206                     hb_log("MPEG2 Flag: Composite");
207                 if( flag & SKIP )
208                     hb_log("MPEG2 Flag: Skip!");
209                 if( flag & TAGS )
210                     hb_log("MPEG2 Flag: TAGS");
211                 if(flag & REPEAT_FIRST )
212                     hb_log("MPEG2 Flag: Repeat first field");
213                 if( flag & COMPOSITE_MASK )
214                     hb_log("MPEG2 Flag: Composite mask");
215                 hb_log("fields: %d", m->info->display_picture->nb_fields);
216 */             
217                 /*  Rotate the cadence tracking. */
218                 int i = 0;
219                 for(i=11; i > 0; i--)
220                 {
221                     cadence[i] = cadence[i-1];
222                 }
223                
224                 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
225                 {
226                     /* Not progressive, not top first...
227                        That means it's probably bottom
228                        first, 2 fields displayed.
229                     */
230                     //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
231                     cadence[0] = BT;
232                 }
233                 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
234                 {
235                     /* Not progressive, top is first,
236                        Two fields displayed.
237                     */
238                     //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
239                     cadence[0] = TB;
240                 }
241                 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST )  )
242                 {
243                     /* Progressive, but noting else.
244                        That means Bottom first,
245                        2 fields displayed.
246                     */
247                     //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
248                     cadence[0] = BT_PROG;
249                 }
250                 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST )  )
251                 {
252                     /* Progressive, and repeat. .
253                        That means Bottom first,
254                        3 fields displayed.
255                     */
256                     //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
257                     cadence[0] = BTB_PROG;
258                 }
259                 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST )  )
260                 {
261                     /* Progressive, top first.
262                        That means top first,
263                        2 fields displayed.
264                     */
265                     //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
266                     cadence[0] = TB_PROG;
267                 }
268                 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST )  )
269                 {
270                     /* Progressive, top, repeat.
271                        That means top first,
272                        3 fields displayed.
273                     */
274                     //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
275                     cadence[0] = TBT_PROG;
276                 }
277                                                
278                 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
279                     hb_log("%fs: Interlaced -> Progressive", (float)buf->start / 90000);
280                 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
281                     hb_log("%fs: Progressive -> Interlaced", (float)buf->start / 90000);
282
283                 /* Store picture flags for later use by filters */
284                 buf->flags = m->info->display_picture->flags;
285                 
286                 hb_list_add( list_raw, buf );
287             }
288         }
289         else if( state == STATE_INVALID )
290         {
291             mpeg2_reset( m->libmpeg2, 0 );
292         }
293     }
294     return 1;
295 }
296
297 /**********************************************************************
298  * hb_libmpeg2_info
299  **********************************************************************
300  * 
301  *********************************************************************/
302 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
303                         int * rate, int *aspect_ratio )
304 {
305     *width  = m->width;
306     *height = m->height;
307     if (m->info->display_fbuf)
308     {
309         if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
310         {
311             /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
312                This might not be correct for the title. It's really just for scan.c's benefit.
313                Scan.c will reset the fps to 29.97, until a simple majority of the preview
314                frames report at 23.976.
315             */
316             //hb_log("Detecting NTSC Progressive Frame");
317             m->rate = 1126125;
318         }
319     }
320     *rate   = m->rate;
321     *aspect_ratio = m->aspect_ratio;
322 }
323
324 /**********************************************************************
325  * hb_libmpeg2_close
326  **********************************************************************
327  * 
328  *********************************************************************/
329 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
330 {
331     hb_libmpeg2_t * m = *_m;
332
333     mpeg2_close( m->libmpeg2 );
334
335     free( m );
336     *_m = NULL;
337 }
338
339 /**********************************************************************
340  * The decmpeg2 work object
341  **********************************************************************
342  * 
343  *********************************************************************/
344 struct hb_work_private_s
345 {
346     hb_libmpeg2_t * libmpeg2;
347     hb_list_t     * list;
348 };
349
350 /**********************************************************************
351  * hb_work_decmpeg2_init
352  **********************************************************************
353  * 
354  *********************************************************************/
355 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
356 {
357     hb_work_private_t * pv;
358     
359     pv              = calloc( 1, sizeof( hb_work_private_t ) );
360     w->private_data = pv;
361     
362     pv->libmpeg2 = hb_libmpeg2_init();
363     pv->list     = hb_list_init();
364
365     return 0;
366 }
367
368 /**********************************************************************
369  * Work
370  **********************************************************************
371  * 
372  *********************************************************************/
373 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
374                    hb_buffer_t ** buf_out )
375 {
376     hb_work_private_t * pv = w->private_data;
377     hb_buffer_t * buf, * last = NULL;
378
379     // The reader found a chapter break, consume it completely, and remove it from the
380     // stream. We need to shift it.
381     if( (*buf_in)->new_chap )
382     {
383         hb_log("MPEG2: Chapter Break Cell Found, searching for GOP");
384         pv->libmpeg2->look_for_break = 2;
385         (*buf_in)->new_chap = 0;
386     }
387
388     hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
389
390     *buf_out = NULL;
391     while( ( buf = hb_list_item( pv->list, 0 ) ) )
392     {
393         hb_list_rem( pv->list, buf );
394         if( last )
395         {
396             last->next = buf;
397             last       = buf;
398         }
399         else
400         {
401             *buf_out = buf;
402             last     = buf;
403         }
404     }
405
406     return HB_WORK_OK;
407 }
408
409 /**********************************************************************
410  * Close
411  **********************************************************************
412  * 
413  *********************************************************************/
414 void decmpeg2Close( hb_work_object_t * w )
415 {
416     hb_work_private_t * pv = w->private_data;
417     hb_list_close( &pv->list );
418     hb_libmpeg2_close( &pv->libmpeg2 );
419     free( pv );
420 }
421
422 hb_work_object_t hb_decmpeg2 =
423 {
424     WORK_DECMPEG2,
425     "MPEG-2 decoder (libmpeg2)",
426     decmpeg2Init,
427     decmpeg2Work,
428     decmpeg2Close
429 };
430