OSDN Git Service

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