OSDN Git Service

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