OSDN Git Service

Correct chroma size for raw video frames - width & height need to be rounded up if...
[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 #include "libavcodec/avcodec.h"
11 #include "libswscale/swscale.h"
12
13 /* Cadence tracking */
14 #ifndef PIC_FLAG_REPEAT_FIRST_FIELD
15 #define PIC_FLAG_REPEAT_FIRST_FIELD 256
16 #endif
17 #define TOP_FIRST PIC_FLAG_TOP_FIELD_FIRST
18 #define PROGRESSIVE PIC_FLAG_PROGRESSIVE_FRAME
19 #define COMPOSITE PIC_FLAG_COMPOSITE_DISPLAY
20 #define SKIP PIC_FLAG_SKIP
21 #define TAGS PIC_FLAG_TAGS
22 #define REPEAT_FIRST PIC_FLAG_REPEAT_FIRST_FIELD
23 #define COMPOSITE_MASK PIC_MASK_COMPOSITE_DISPLAY
24 #define TB 8
25 #define BT 16
26 #define BT_PROG 32
27 #define BTB_PROG 64
28 #define TB_PROG 128
29 #define TBT_PROG 256
30 static int cadence[12];
31 static int flag = 0;
32
33 /**********************************************************************
34  * hb_libmpeg2_t
35  *********************************************************************/
36 typedef 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     double               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 } hb_libmpeg2_t;
51
52 /**********************************************************************
53  * hb_libmpeg2_init
54  **********************************************************************
55  *
56  *********************************************************************/
57 static 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 static hb_buffer_t *hb_copy_frame( hb_job_t *job, int width, int height,
69                                    uint8_t* y, uint8_t *u, uint8_t *v )
70 {
71     int dst_w = width, dst_h = height;
72     if ( job )
73     {
74         dst_w = job->title->width;
75         dst_h = job->title->height;
76     }
77     int dst_wh = dst_w * dst_h;
78     hb_buffer_t *buf  = hb_video_buffer_init( dst_w, dst_h );
79
80     if ( dst_w != width || dst_h != height )
81     {
82         // we're encoding and the frame dimensions don't match the title dimensions -
83         // rescale & matte Y, U, V into our output buf.
84         AVPicture in, out;
85         avpicture_alloc(&in,  PIX_FMT_YUV420P, width, height );
86         avpicture_alloc(&out, PIX_FMT_YUV420P, dst_w, dst_h );
87
88         int src_wh = width * height;
89         memcpy( in.data[0], y, src_wh );
90         memcpy( in.data[1], u, src_wh >> 2 );
91         memcpy( in.data[2], v, src_wh >> 2 );
92         struct SwsContext *context = sws_getContext( width, height, PIX_FMT_YUV420P,
93                                                      dst_w, dst_h, PIX_FMT_YUV420P,
94                                                      SWS_LANCZOS|SWS_ACCURATE_RND,
95                                                      NULL, NULL, NULL );
96         sws_scale( context, in.data, in.linesize, 0, height, out.data, out.linesize );
97         sws_freeContext( context );
98
99         u_int8_t *data = buf->data;
100         memcpy( data, out.data[0], dst_wh );
101         data += dst_wh;
102         // U & V planes are 1/4 the size of Y plane.
103         dst_wh >>= 2;
104         memcpy( data, out.data[1], dst_wh );
105         data += dst_wh;
106         memcpy( data, out.data[2], dst_wh );
107
108         avpicture_free( &out );
109         avpicture_free( &in );
110     }
111     else
112     {
113         // we're scanning or the frame dimensions match the title's dimensions
114         // so we can do a straight copy.
115         u_int8_t *data = buf->data;
116         memcpy( data, y, dst_wh );
117         data += dst_wh;
118         // U & V planes are 1/4 the size of Y plane.
119         dst_wh >>= 2;
120         memcpy( data, u, dst_wh );
121         data += dst_wh;
122         memcpy( data, v, dst_wh );
123     }
124     return buf;
125 }
126
127 /**********************************************************************
128  * hb_libmpeg2_decode
129  **********************************************************************
130  *
131  *********************************************************************/
132 static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
133                         hb_list_t * list_raw )
134 {
135     mpeg2_state_t   state;
136     hb_buffer_t   * buf;
137
138     if ( buf_es->size )
139     {
140         /* Feed libmpeg2 */
141         if( buf_es->start > -1 )
142         {
143             mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
144                                buf_es->start & 0xFFFFFFFF );
145         }
146         mpeg2_buffer( m->libmpeg2, buf_es->data,
147                       buf_es->data + buf_es->size );
148     }
149
150     for( ;; )
151     {
152         state = mpeg2_parse( m->libmpeg2 );
153         if( state == STATE_BUFFER )
154         {
155             /* Require some more data */
156             break;
157         }
158         else if( state == STATE_SEQUENCE )
159         {
160             if( !( m->width && m->height && m->rate ) )
161             {
162                 m->width  = m->info->sequence->width;
163                 m->height = m->info->sequence->height;
164                 m->rate   = m->info->sequence->frame_period;
165                 if ( m->aspect_ratio <= 0 && m->height &&
166                      m->info->sequence->pixel_height )
167                 {
168                     /* mpeg2_parse doesn't store the aspect ratio. Instead
169                      * it keeps the pixel width & height that would cause
170                      * the storage width & height to come out in the correct
171                      * aspect ratio. Convert these back to aspect ratio.
172                      */
173                     double ar_numer = m->width * m->info->sequence->pixel_width;
174                     double ar_denom = m->height * m->info->sequence->pixel_height;
175                     m->aspect_ratio = ar_numer / ar_denom;
176                 }
177             }
178         }
179         else if( state == STATE_GOP && m->look_for_break)
180         {
181             // we were looking for a gop to add a chapter break - we found it
182             // so now start looking for an iframe.
183             m->look_for_iframe = m->look_for_break;
184             m->look_for_break = 0;
185         }
186         else if( ( state == STATE_SLICE || state == STATE_END ) &&
187                  m->info->display_fbuf )
188         {
189             if( ( m->info->display_picture->flags &
190                   PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
191             {
192                 // we got an iframe so we can start decoding video now
193                 m->got_iframe = 1;
194             }
195
196             if( m->got_iframe )
197             {
198                 buf  = hb_copy_frame( m->job, m->info->sequence->width,
199                                       m->info->sequence->height,
200                                       m->info->display_fbuf->buf[0],
201                                       m->info->display_fbuf->buf[1],
202                                       m->info->display_fbuf->buf[2] );
203                 buf->sequence = buf_es->sequence;
204
205                 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
206                 {
207                     buf->start =
208                         ( (uint64_t) m->info->display_picture->tag << 32 ) |
209                         ( (uint64_t) m->info->display_picture->tag2 );
210                 }
211                 else if( m->last_pts > -1 )
212                 {
213                     /* For some reason nb_fields is sometimes 1 while it
214                        should be 2 */
215                     buf->start = m->last_pts +
216                         MAX( 2, m->info->display_picture->nb_fields ) *
217                         m->info->sequence->frame_period / 600;
218                 }
219                 else
220                 {
221                     buf->start = -1;
222                 }
223                 m->last_pts = buf->start;
224
225                 if( m->look_for_iframe && ( m->info->display_picture->flags &
226                       PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
227                 {
228                     // we were waiting for an iframe to insert a chapter mark
229                     // and we have one.
230                     buf->new_chap = m->look_for_iframe;
231                     m->look_for_iframe = 0;
232                     const char *chap_name = "";
233                     if ( m->job && buf->new_chap > 0 &&
234                          hb_list_item( m->job->title->list_chapter,
235                                        buf->new_chap - 1 ) )
236                     {
237                         hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
238                                                          buf->new_chap - 1 );
239                         chap_name = c->title;
240                     }
241                     hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld",
242                             chap_name, buf->new_chap, m->nframes, buf->start );
243                 } else if ( m->nframes == 0 && m->job &&
244                             hb_list_item( m->job->title->list_chapter,
245                                           m->job->chapter_start - 1 ) )
246                 {
247                     hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
248                                                      m->job->chapter_start - 1 );
249                     hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld", c->title,
250                             m->job->chapter_start, m->nframes, buf->start );
251                 }
252                 ++m->nframes;
253
254                 flag = m->info->display_picture->flags;
255
256 /*  Uncomment this block to see frame-by-frame picture flags, as the video encodes.
257                hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
258                 if( flag & TOP_FIRST )
259                     hb_log("MPEG2 Flag: Top field first");
260                 if( flag & PROGRESSIVE )
261                     hb_log("MPEG2 Flag: Progressive");
262                 if( flag & COMPOSITE )
263                     hb_log("MPEG2 Flag: Composite");
264                 if( flag & SKIP )
265                     hb_log("MPEG2 Flag: Skip!");
266                 if( flag & TAGS )
267                     hb_log("MPEG2 Flag: TAGS");
268                 if(flag & REPEAT_FIRST )
269                     hb_log("MPEG2 Flag: Repeat first field");
270                 if( flag & COMPOSITE_MASK )
271                     hb_log("MPEG2 Flag: Composite mask");
272                 hb_log("fields: %d", m->info->display_picture->nb_fields);
273 */
274                 /*  Rotate the cadence tracking. */
275                 int i = 0;
276                 for(i=11; i > 0; i--)
277                 {
278                     cadence[i] = cadence[i-1];
279                 }
280
281                 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
282                 {
283                     /* Not progressive, not top first...
284                        That means it's probably bottom
285                        first, 2 fields displayed.
286                     */
287                     //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
288                     cadence[0] = BT;
289                 }
290                 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
291                 {
292                     /* Not progressive, top is first,
293                        Two fields displayed.
294                     */
295                     //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
296                     cadence[0] = TB;
297                 }
298                 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST )  )
299                 {
300                     /* Progressive, but noting else.
301                        That means Bottom first,
302                        2 fields displayed.
303                     */
304                     //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
305                     cadence[0] = BT_PROG;
306                 }
307                 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST )  )
308                 {
309                     /* Progressive, and repeat. .
310                        That means Bottom first,
311                        3 fields displayed.
312                     */
313                     //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
314                     cadence[0] = BTB_PROG;
315                 }
316                 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST )  )
317                 {
318                     /* Progressive, top first.
319                        That means top first,
320                        2 fields displayed.
321                     */
322                     //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
323                     cadence[0] = TB_PROG;
324                 }
325                 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST )  )
326                 {
327                     /* Progressive, top, repeat.
328                        That means top first,
329                        3 fields displayed.
330                     */
331                     //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
332                     cadence[0] = TBT_PROG;
333                 }
334
335                 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
336                     hb_log("%fs: Video -> Film", (float)buf->start / 90000);
337                 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
338                     hb_log("%fs: Film -> Video", (float)buf->start / 90000);
339
340                 /* Store picture flags for later use by filters */
341                 buf->flags = m->info->display_picture->flags;
342
343                 hb_list_add( list_raw, buf );
344             }
345         }
346         else if( state == STATE_INVALID )
347         {
348             mpeg2_reset( m->libmpeg2, 0 );
349         }
350     }
351     return 1;
352 }
353
354 /**********************************************************************
355  * hb_libmpeg2_close
356  **********************************************************************
357  *
358  *********************************************************************/
359 static void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
360 {
361     hb_libmpeg2_t * m = *_m;
362
363     mpeg2_close( m->libmpeg2 );
364
365     free( m );
366     *_m = NULL;
367 }
368
369 /**********************************************************************
370  * The decmpeg2 work object
371  **********************************************************************
372  *
373  *********************************************************************/
374 struct hb_work_private_s
375 {
376     hb_libmpeg2_t * libmpeg2;
377     hb_list_t     * list;
378 };
379
380 /**********************************************************************
381  * hb_work_decmpeg2_init
382  **********************************************************************
383  *
384  *********************************************************************/
385 static int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
386 {
387     hb_work_private_t * pv;
388
389     pv              = calloc( 1, sizeof( hb_work_private_t ) );
390     w->private_data = pv;
391
392     pv->libmpeg2 = hb_libmpeg2_init();
393     pv->list     = hb_list_init();
394
395     pv->libmpeg2->job = job;
396
397     return 0;
398 }
399
400 /**********************************************************************
401  * Work
402  **********************************************************************
403  *
404  *********************************************************************/
405 static int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
406                    hb_buffer_t ** buf_out )
407 {
408     hb_work_private_t * pv = w->private_data;
409     hb_buffer_t * buf, * last = NULL;
410     int status = HB_WORK_OK;
411
412     // The reader found a chapter break, consume it completely, and remove it from the
413     // stream. We need to shift it.
414     if( (*buf_in)->new_chap )
415     {
416         pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
417         (*buf_in)->new_chap = 0;
418     }
419
420     hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
421
422     /* if we got an empty buffer signaling end-of-stream send it downstream */
423     if ( (*buf_in)->size == 0 )
424     {
425         hb_list_add( pv->list, *buf_in );
426         *buf_in = NULL;
427         status = HB_WORK_DONE;
428     }
429
430     *buf_out = NULL;
431     while( ( buf = hb_list_item( pv->list, 0 ) ) )
432     {
433         hb_list_rem( pv->list, buf );
434         if( last )
435         {
436             last->next = buf;
437             last       = buf;
438         }
439         else
440         {
441             *buf_out = buf;
442             last     = buf;
443         }
444     }
445
446     return status;
447 }
448
449 /**********************************************************************
450  * Close
451  **********************************************************************
452  *
453  *********************************************************************/
454 static void decmpeg2Close( hb_work_object_t * w )
455 {
456     hb_work_private_t * pv = w->private_data;
457
458     // don't log during scan
459     if ( pv->libmpeg2->job )
460     {
461         hb_log( "mpeg2 done: %d frames", pv->libmpeg2->nframes );
462     }
463     hb_list_close( &pv->list );
464     hb_libmpeg2_close( &pv->libmpeg2 );
465     free( pv );
466 }
467
468 static int decmpeg2Info( hb_work_object_t *w, hb_work_info_t *info )
469 {
470     hb_work_private_t *pv = w->private_data;
471
472     memset( info, 0, sizeof(*info) );
473
474     if ( pv && pv->libmpeg2 && pv->libmpeg2->info && pv->libmpeg2->info->sequence )
475     {
476         hb_libmpeg2_t *m = pv->libmpeg2;
477
478         info->width = m->width;
479         info->height = m->height;
480         info->pixel_aspect_width = m->info->sequence->pixel_width;
481         info->pixel_aspect_height = m->info->sequence->pixel_height;
482         info->aspect = m->aspect_ratio;
483
484         // if the frame is progressive & NTSC DVD height report it as 23.976 FPS
485         // so that scan can autodetect NTSC film
486         info->rate = 27000000;
487         info->rate_base = ( m->info->display_fbuf && m->info->display_picture &&
488                             (m->info->display_picture->flags & PROGRESSIVE) &&
489                             (m->height == 480 ) ) ?  1126125 : m->rate;
490
491         info->bitrate = m->info->sequence->byte_rate * 8;
492         info->profile = m->info->sequence->profile_level_id >> 4;
493         info->level = m->info->sequence->profile_level_id & 0xf;
494         info->name = "mpeg2";
495         return 1;
496     }
497     return 0;
498 }
499
500 hb_work_object_t hb_decmpeg2 =
501 {
502     WORK_DECMPEG2,
503     "MPEG-2 decoder (libmpeg2)",
504     decmpeg2Init,
505     decmpeg2Work,
506     decmpeg2Close,
507     decmpeg2Info
508 };
509