OSDN Git Service

Fix the automatic subtitle scan that I broke with r1412.
[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     hb_job_t           * job;
41     int                  width;
42     int                  height;
43     int                  rate;
44     int                  aspect_ratio;
45     int                  got_iframe;        /* set when we get our first iframe */
46     int                  look_for_iframe;   /* need an iframe to add chap break */
47     int                  look_for_break;    /* need gop start to add chap break */
48     uint32_t             nframes;           /* number of frames we've decoded */
49     int64_t              last_pts;
50 };
51
52 /**********************************************************************
53  * hb_libmpeg2_init
54  **********************************************************************
55  *
56  *********************************************************************/
57 hb_libmpeg2_t * hb_libmpeg2_init()
58 {
59     hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
60
61     m->libmpeg2 = mpeg2_init();
62     m->info     = mpeg2_info( m->libmpeg2 );
63     m->last_pts = -1;
64
65     return m;
66 }
67
68 /**********************************************************************
69  * hb_libmpeg2_decode
70  **********************************************************************
71  *
72  *********************************************************************/
73 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
74                         hb_list_t * list_raw )
75 {
76     mpeg2_state_t   state;
77     hb_buffer_t   * buf;
78     uint8_t       * data;
79
80     if ( buf_es->size )
81     {
82         /* Feed libmpeg2 */
83         if( buf_es->start > -1 )
84         {
85             mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
86                                buf_es->start & 0xFFFFFFFF );
87         }
88         mpeg2_buffer( m->libmpeg2, buf_es->data,
89                       buf_es->data + buf_es->size );
90     }
91
92     for( ;; )
93     {
94         state = mpeg2_parse( m->libmpeg2 );
95         if( state == STATE_BUFFER )
96         {
97             /* Require some more data */
98             break;
99         }
100         else if( state == STATE_SEQUENCE )
101         {
102             if( !( m->width && m->height && m->rate ) )
103             {
104                 m->width  = m->info->sequence->width;
105                 m->height = m->info->sequence->height;
106                 m->rate   = m->info->sequence->frame_period;
107                 if ( m->aspect_ratio <= 0 && m->height &&
108                      m->info->sequence->pixel_height )
109                 {
110                     /* mpeg2_parse doesn't store the aspect ratio. Instead
111                      * it keeps the pixel width & height that would cause
112                      * the storage width & height to come out in the correct
113                      * aspect ratio. Convert these back to aspect ratio.
114                      * We do the calc in floating point to get the rounding right.
115                      * We round in the second decimal digit because we scale
116                      * the (integer) aspect by 9 to preserve the 1st digit.
117                      */
118                     double ar_numer = m->width * m->info->sequence->pixel_width;
119                     double ar_denom = m->height * m->info->sequence->pixel_height;
120                     m->aspect_ratio = ( ar_numer / ar_denom + .05 ) * HB_ASPECT_BASE;
121                 }
122             }
123         }
124         else if( state == STATE_GOP && m->look_for_break)
125         {
126             // we were looking for a gop to add a chapter break - we found it
127             // so now start looking for an iframe.
128             m->look_for_iframe = m->look_for_break;
129             m->look_for_break = 0;
130         }
131         else if( ( state == STATE_SLICE || state == STATE_END ) &&
132                  m->info->display_fbuf )
133         {
134             if( ( m->info->display_picture->flags &
135                   PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
136             {
137                 // we got an iframe so we can start decoding video now
138                 m->got_iframe = 1;
139             }
140
141             if( m->got_iframe )
142             {
143                 buf  = hb_buffer_init( m->width * m->height * 3 / 2 );
144                 data = buf->data;
145
146                 buf->sequence = buf_es->sequence;
147
148                 memcpy( data, m->info->display_fbuf->buf[0],
149                         m->width * m->height );
150                 data += m->width * m->height;
151                 memcpy( data, m->info->display_fbuf->buf[1],
152                         m->width * m->height / 4 );
153                 data += m->width * m->height / 4;
154                 memcpy( data, m->info->display_fbuf->buf[2],
155                         m->width * m->height / 4 );
156
157                 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
158                 {
159                     buf->start =
160                         ( (uint64_t) m->info->display_picture->tag << 32 ) |
161                         ( (uint64_t) m->info->display_picture->tag2 );
162                     /*
163                       * Add back in again to track PTS of MPEG2 frames
164                       * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
165                     */
166                 }
167                 else if( m->last_pts > -1 )
168                 {
169                     /* For some reason nb_fields is sometimes 1 while it
170                        should be 2 */
171                     buf->start = m->last_pts +
172                         MAX( 2, m->info->display_picture->nb_fields ) *
173                         m->info->sequence->frame_period / 600;
174                 }
175                 else
176                 {
177                     buf->start = -1;
178                 }
179                 m->last_pts = buf->start;
180
181                 if( m->look_for_iframe && ( m->info->display_picture->flags &
182                       PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
183                 {
184                     // we were waiting for an iframe to insert a chapter mark
185                     // and we have one.
186                     buf->new_chap = m->look_for_iframe;
187                     m->look_for_iframe = 0;
188                     const char *chap_name = "";
189                     if ( m->job && buf->new_chap > 0 &&
190                          hb_list_item( m->job->title->list_chapter,
191                                        buf->new_chap - 1 ) )
192                     {
193                         hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
194                                                          buf->new_chap - 1 );
195                         chap_name = c->title;
196                     }
197                     hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld",
198                             chap_name, buf->new_chap, m->nframes, buf->start );
199                 }
200                 ++m->nframes;
201
202                 flag = m->info->display_picture->flags;
203
204 /*  Uncomment this block to see frame-by-frame picture flags, as the video encodes.
205                hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
206                 if( flag & TOP_FIRST )
207                     hb_log("MPEG2 Flag: Top field first");
208                 if( flag & PROGRESSIVE )
209                     hb_log("MPEG2 Flag: Progressive");
210                 if( flag & COMPOSITE )
211                     hb_log("MPEG2 Flag: Composite");
212                 if( flag & SKIP )
213                     hb_log("MPEG2 Flag: Skip!");
214                 if( flag & TAGS )
215                     hb_log("MPEG2 Flag: TAGS");
216                 if(flag & REPEAT_FIRST )
217                     hb_log("MPEG2 Flag: Repeat first field");
218                 if( flag & COMPOSITE_MASK )
219                     hb_log("MPEG2 Flag: Composite mask");
220                 hb_log("fields: %d", m->info->display_picture->nb_fields);
221 */
222                 /*  Rotate the cadence tracking. */
223                 int i = 0;
224                 for(i=11; i > 0; i--)
225                 {
226                     cadence[i] = cadence[i-1];
227                 }
228
229                 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
230                 {
231                     /* Not progressive, not top first...
232                        That means it's probably bottom
233                        first, 2 fields displayed.
234                     */
235                     //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
236                     cadence[0] = BT;
237                 }
238                 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
239                 {
240                     /* Not progressive, top is first,
241                        Two fields displayed.
242                     */
243                     //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
244                     cadence[0] = TB;
245                 }
246                 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST )  )
247                 {
248                     /* Progressive, but noting else.
249                        That means Bottom first,
250                        2 fields displayed.
251                     */
252                     //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
253                     cadence[0] = BT_PROG;
254                 }
255                 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST )  )
256                 {
257                     /* Progressive, and repeat. .
258                        That means Bottom first,
259                        3 fields displayed.
260                     */
261                     //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
262                     cadence[0] = BTB_PROG;
263                 }
264                 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST )  )
265                 {
266                     /* Progressive, top first.
267                        That means top first,
268                        2 fields displayed.
269                     */
270                     //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
271                     cadence[0] = TB_PROG;
272                 }
273                 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST )  )
274                 {
275                     /* Progressive, top, repeat.
276                        That means top first,
277                        3 fields displayed.
278                     */
279                     //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
280                     cadence[0] = TBT_PROG;
281                 }
282
283                 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
284                     hb_log("%fs: Video -> Film", (float)buf->start / 90000);
285                 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
286                     hb_log("%fs: Film -> Video", (float)buf->start / 90000);
287
288                 /* Store picture flags for later use by filters */
289                 buf->flags = m->info->display_picture->flags;
290
291                 hb_list_add( list_raw, buf );
292             }
293         }
294         else if( state == STATE_INVALID )
295         {
296             mpeg2_reset( m->libmpeg2, 0 );
297         }
298     }
299     return 1;
300 }
301
302 /**********************************************************************
303  * hb_libmpeg2_info
304  **********************************************************************
305  *
306  *********************************************************************/
307 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
308                         int * rate, int *aspect_ratio )
309 {
310     *width  = m->width;
311     *height = m->height;
312     if (m->info->display_fbuf)
313     {
314         if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
315         {
316             /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
317                This might not be correct for the title. It's really just for scan.c's benefit.
318                Scan.c will reset the fps to 29.97, until a simple majority of the preview
319                frames report at 23.976.
320             */
321             //hb_log("Detecting NTSC Progressive Frame");
322             m->rate = 1126125;
323         }
324     }
325     *rate   = m->rate;
326     *aspect_ratio = m->aspect_ratio;
327 }
328
329 int hb_libmpeg2_clear_aspect_ratio( hb_libmpeg2_t * m )
330 {
331     int ar = m->aspect_ratio;
332     m->aspect_ratio = 0;
333     return ar;
334 }
335
336 /**********************************************************************
337  * hb_libmpeg2_close
338  **********************************************************************
339  *
340  *********************************************************************/
341 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
342 {
343     hb_libmpeg2_t * m = *_m;
344
345     mpeg2_close( m->libmpeg2 );
346
347     free( m );
348     *_m = NULL;
349 }
350
351 /**********************************************************************
352  * The decmpeg2 work object
353  **********************************************************************
354  *
355  *********************************************************************/
356 struct hb_work_private_s
357 {
358     hb_libmpeg2_t * libmpeg2;
359     hb_list_t     * list;
360 };
361
362 /**********************************************************************
363  * hb_work_decmpeg2_init
364  **********************************************************************
365  *
366  *********************************************************************/
367 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
368 {
369     hb_work_private_t * pv;
370
371     pv              = calloc( 1, sizeof( hb_work_private_t ) );
372     w->private_data = pv;
373
374     pv->libmpeg2 = hb_libmpeg2_init();
375     pv->list     = hb_list_init();
376
377     pv->libmpeg2->job = job;
378
379     return 0;
380 }
381
382 /**********************************************************************
383  * Work
384  **********************************************************************
385  *
386  *********************************************************************/
387 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
388                    hb_buffer_t ** buf_out )
389 {
390     hb_work_private_t * pv = w->private_data;
391     hb_buffer_t * buf, * last = NULL;
392     int status = HB_WORK_OK;
393
394     // The reader found a chapter break, consume it completely, and remove it from the
395     // stream. We need to shift it.
396     if( (*buf_in)->new_chap )
397     {
398         pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
399         (*buf_in)->new_chap = 0;
400     }
401
402     hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
403
404     /* if we got an empty buffer signaling end-of-stream send it downstream */
405     if ( (*buf_in)->size == 0 )
406     {
407         hb_list_add( pv->list, *buf_in );
408         *buf_in = NULL;
409         status = HB_WORK_DONE;
410     }
411
412     *buf_out = NULL;
413     while( ( buf = hb_list_item( pv->list, 0 ) ) )
414     {
415         hb_list_rem( pv->list, buf );
416         if( last )
417         {
418             last->next = buf;
419             last       = buf;
420         }
421         else
422         {
423             *buf_out = buf;
424             last     = buf;
425         }
426     }
427
428     return status;
429 }
430
431 /**********************************************************************
432  * Close
433  **********************************************************************
434  *
435  *********************************************************************/
436 void decmpeg2Close( hb_work_object_t * w )
437 {
438     hb_work_private_t * pv = w->private_data;
439     hb_log( "mpeg2 done: %d frames", pv->libmpeg2->nframes );
440     hb_list_close( &pv->list );
441     hb_libmpeg2_close( &pv->libmpeg2 );
442     free( pv );
443 }
444
445 hb_work_object_t hb_decmpeg2 =
446 {
447     WORK_DECMPEG2,
448     "MPEG-2 decoder (libmpeg2)",
449     decmpeg2Init,
450     decmpeg2Work,
451     decmpeg2Close
452 };
453