OSDN Git Service

Remove some noise from the log: Only announce chapters when we're reading, not while...
[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 #include "hbffmpeg.h"
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
29 /**********************************************************************
30  * hb_libmpeg2_t
31  *********************************************************************/
32 typedef struct hb_libmpeg2_s
33 {
34     mpeg2dec_t         * libmpeg2;
35     const mpeg2_info_t * info;
36     hb_job_t           * job;
37     hb_title_t         * title;
38     int                  width;
39     int                  height;
40     int                  rate;
41     double               aspect_ratio;
42     int                  got_iframe;        /* set when we get our first iframe */
43     int                  look_for_iframe;   /* need an iframe to add chap break */
44     int                  look_for_break;    /* need gop start to add chap break */
45     uint32_t             nframes;           /* number of frames we've decoded */
46     int64_t              last_pts;
47     int cadence[12];
48     int flag;
49     hb_subtitle_t      * subtitle;
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 void hb_mpeg2_cc( hb_libmpeg2_t * m, uint8_t *cc_block )
69 {
70     uint8_t cc_valid = (*cc_block & 4) >>2;
71     uint8_t cc_type = *cc_block & 3;
72     hb_buffer_t *cc_buf;
73     
74     if( !m->job )
75     {
76         /*
77          * Ignore CC decoding during scanning.
78          */
79         return;
80     }
81
82     if (cc_valid || cc_type==3)
83     {
84         switch (cc_type)
85         {
86         case 0:
87             // CC1 stream
88             cc_buf = hb_buffer_init( 2 );
89             if( cc_buf )
90             {
91                 cc_buf->start = m->last_pts;
92                 memcpy( cc_buf->data, cc_block+1, 2 );
93                 hb_fifo_push( m->subtitle->fifo_in, cc_buf );
94             }
95             break;
96         case 1:
97             // CC2 stream
98             //process608( cc_block+1, 2, &m->cc608 );
99             break;
100         case 2: //EIA-708
101             // DTVCC packet data
102             // Fall through
103         case 3: //EIA-708
104         {
105             uint8_t temp[4];
106             temp[0]=cc_valid;
107             temp[1]=cc_type;
108             temp[2]=cc_block[1];
109             temp[3]=cc_block[2];
110             //do_708 ((const unsigned char *) temp, 4);
111         }
112         break;
113         default:
114             break;
115         } 
116     } 
117     else
118     {
119         hb_log("Ignoring invalid CC block");
120     }
121 }
122
123 static hb_buffer_t *hb_copy_frame( hb_job_t *job, int width, int height,
124                                    uint8_t* y, uint8_t *u, uint8_t *v )
125 {
126     int dst_w = width, dst_h = height;
127     if ( job )
128     {
129         dst_w = job->title->width;
130         dst_h = job->title->height;
131     }
132     int dst_wh = dst_w * dst_h;
133     hb_buffer_t *buf  = hb_video_buffer_init( dst_w, dst_h );
134
135     if ( dst_w != width || dst_h != height )
136     {
137         // we're encoding and the frame dimensions don't match the title dimensions -
138         // rescale & matte Y, U, V into our output buf.
139         AVPicture in, out;
140         avpicture_alloc(&in,  PIX_FMT_YUV420P, width, height );
141         avpicture_alloc(&out, PIX_FMT_YUV420P, dst_w, dst_h );
142
143         int src_wh = width * height;
144         memcpy( in.data[0], y, src_wh );
145         memcpy( in.data[1], u, src_wh >> 2 );
146         memcpy( in.data[2], v, src_wh >> 2 );
147         struct SwsContext *context = sws_getContext( width, height, PIX_FMT_YUV420P,
148                                                      dst_w, dst_h, PIX_FMT_YUV420P,
149                                                      SWS_LANCZOS|SWS_ACCURATE_RND,
150                                                      NULL, NULL, NULL );
151         sws_scale( context, in.data, in.linesize, 0, height, out.data, out.linesize );
152         sws_freeContext( context );
153
154         uint8_t *data = buf->data;
155         memcpy( data, out.data[0], dst_wh );
156         data += dst_wh;
157         // U & V planes are 1/4 the size of Y plane.
158         dst_wh >>= 2;
159         memcpy( data, out.data[1], dst_wh );
160         data += dst_wh;
161         memcpy( data, out.data[2], dst_wh );
162
163         avpicture_free( &out );
164         avpicture_free( &in );
165     }
166     else
167     {
168         // we're scanning or the frame dimensions match the title's dimensions
169         // so we can do a straight copy.
170         uint8_t *data = buf->data;
171         memcpy( data, y, dst_wh );
172         data += dst_wh;
173         // U & V planes are 1/4 the size of Y plane.
174         dst_wh >>= 2;
175         memcpy( data, u, dst_wh );
176         data += dst_wh;
177         memcpy( data, v, dst_wh );
178     }
179     return buf;
180 }
181
182 /**********************************************************************
183  * hb_libmpeg2_decode
184  **********************************************************************
185  *
186  *********************************************************************/
187 static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
188                                hb_list_t * list_raw )
189 {
190     mpeg2_state_t   state;
191     hb_buffer_t   * buf;
192
193     if ( buf_es->size )
194     {
195         /* Feed libmpeg2 */
196         if( buf_es->start > -1 )
197         {
198             mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
199                                buf_es->start & 0xFFFFFFFF );
200         }
201         mpeg2_buffer( m->libmpeg2, buf_es->data,
202                       buf_es->data + buf_es->size );
203     }
204
205     for( ;; )
206     {
207         state = mpeg2_parse( m->libmpeg2 );
208         if( state == STATE_BUFFER )
209         {
210             /* Require some more data */
211             break;
212         }
213         else if( state == STATE_SEQUENCE )
214         {
215             if( !( m->width && m->height && m->rate ) )
216             {
217                 m->width  = m->info->sequence->width;
218                 m->height = m->info->sequence->height;
219                 m->rate   = m->info->sequence->frame_period;
220                 if ( m->aspect_ratio <= 0 && m->height &&
221                      m->info->sequence->pixel_height )
222                 {
223                     /* mpeg2_parse doesn't store the aspect ratio. Instead
224                      * it keeps the pixel width & height that would cause
225                      * the storage width & height to come out in the correct
226                      * aspect ratio. Convert these back to aspect ratio.
227                      */
228                     double ar_numer = m->width * m->info->sequence->pixel_width;
229                     double ar_denom = m->height * m->info->sequence->pixel_height;
230                     m->aspect_ratio = ar_numer / ar_denom;
231                 }
232             }
233         }
234         else if( state == STATE_GOP && m->look_for_break)
235         {
236             // we were looking for a gop to add a chapter break - we found it
237             // so now start looking for an iframe.
238             m->look_for_iframe = m->look_for_break;
239             m->look_for_break = 0;
240         }
241         else if( ( state == STATE_SLICE || state == STATE_END ) &&
242                  m->info->display_fbuf )
243         {
244             if( ( m->info->display_picture->flags &
245                   PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
246             {
247                 // we got an iframe so we can start decoding video now
248                 m->got_iframe = 1;
249             }
250
251             if( m->got_iframe )
252             {
253                 buf  = hb_copy_frame( m->job, m->info->sequence->width,
254                                       m->info->sequence->height,
255                                       m->info->display_fbuf->buf[0],
256                                       m->info->display_fbuf->buf[1],
257                                       m->info->display_fbuf->buf[2] );
258                 buf->sequence = buf_es->sequence;
259
260                 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
261                 {
262                     buf->start =
263                         ( (uint64_t) m->info->display_picture->tag << 32 ) |
264                         ( (uint64_t) m->info->display_picture->tag2 );
265                 }
266                 else if( m->last_pts > -1 )
267                 {
268                     /* For some reason nb_fields is sometimes 1 while it
269                        should be 2 */
270                     buf->start = m->last_pts +
271                         MAX( 2, m->info->display_picture->nb_fields ) *
272                         m->info->sequence->frame_period / 600;
273                 }
274                 else
275                 {
276                     buf->start = -1;
277                 }
278                 m->last_pts = buf->start;
279
280                 if( m->look_for_iframe && ( m->info->display_picture->flags &
281                       PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
282                 {
283                     // we were waiting for an iframe to insert a chapter mark
284                     // and we have one.
285                     buf->new_chap = m->look_for_iframe;
286                     m->look_for_iframe = 0;
287                     const char *chap_name = "";
288                     if ( m->job && buf->new_chap > 0 &&
289                          hb_list_item( m->job->title->list_chapter,
290                                        buf->new_chap - 1 ) )
291                     {
292                         hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
293                                                          buf->new_chap - 1 );
294                         chap_name = c->title;
295                     }
296                     hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld",
297                             chap_name, buf->new_chap, m->nframes, buf->start );
298                 } else if ( m->nframes == 0 && m->job &&
299                             hb_list_item( m->job->title->list_chapter,
300                                           m->job->chapter_start - 1 ) )
301                 {
302                     hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
303                                                      m->job->chapter_start - 1 );
304                     hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld", c->title,
305                             m->job->chapter_start, m->nframes, buf->start );
306                 }
307                 ++m->nframes;
308
309                 m->flag = m->info->display_picture->flags;
310
311 /*  Uncomment this block to see frame-by-frame picture flags, as the video encodes.
312                hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
313                 if( m->flag & TOP_FIRST )
314                     hb_log("MPEG2 Flag: Top field first");
315                 if( m->flag & PROGRESSIVE )
316                     hb_log("MPEG2 Flag: Progressive");
317                 if( m->flag & COMPOSITE )
318                     hb_log("MPEG2 Flag: Composite");
319                 if( m->flag & SKIP )
320                     hb_log("MPEG2 Flag: Skip!");
321                 if( m->flag & TAGS )
322                     hb_log("MPEG2 Flag: TAGS");
323                 if(fm->lag & REPEAT_FIRST )
324                     hb_log("MPEG2 Flag: Repeat first field");
325                 if( m->flag & COMPOSITE_MASK )
326                     hb_log("MPEG2 Flag: Composite mask");
327                 hb_log("fields: %d", m->info->display_picture->nb_fields);
328 */
329                 /*  Rotate the cadence tracking. */
330                 int i = 0;
331                 for(i=11; i > 0; i--)
332                 {
333                     m->cadence[i] = m->cadence[i-1];
334                 }
335
336                 if ( !(m->flag & PROGRESSIVE) && !(m->flag & TOP_FIRST) )
337                 {
338                     /* Not progressive, not top first...
339                        That means it's probably bottom
340                        first, 2 fields displayed.
341                     */
342                     //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
343                     m->cadence[0] = BT;
344                 }
345                 else if ( !(m->flag & PROGRESSIVE) && (m->flag & TOP_FIRST) )
346                 {
347                     /* Not progressive, top is first,
348                        Two fields displayed.
349                     */
350                     //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
351                     m->cadence[0] = TB;
352                 }
353                 else if ( (m->flag & PROGRESSIVE) && !(m->flag & TOP_FIRST) && !( m->flag & REPEAT_FIRST )  )
354                 {
355                     /* Progressive, but noting else.
356                        That means Bottom first,
357                        2 fields displayed.
358                     */
359                     //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
360                     m->cadence[0] = BT_PROG;
361                 }
362                 else if ( (m->flag & PROGRESSIVE) && !(m->flag & TOP_FIRST) && ( m->flag & REPEAT_FIRST )  )
363                 {
364                     /* Progressive, and repeat. .
365                        That means Bottom first,
366                        3 fields displayed.
367                     */
368                     //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
369                     m->cadence[0] = BTB_PROG;
370                 }
371                 else if ( (m->flag & PROGRESSIVE) && (m->flag & TOP_FIRST) && !( m->flag & REPEAT_FIRST )  )
372                 {
373                     /* Progressive, top first.
374                        That means top first,
375                        2 fields displayed.
376                     */
377                     //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
378                     m->cadence[0] = TB_PROG;
379                 }
380                 else if ( (m->flag & PROGRESSIVE) && (m->flag & TOP_FIRST) && ( m->flag & REPEAT_FIRST )  )
381                 {
382                     /* Progressive, top, repeat.
383                        That means top first,
384                        3 fields displayed.
385                     */
386                     //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
387                     m->cadence[0] = TBT_PROG;
388                 }
389
390                 if ( (m->cadence[2] <= TB) && (m->cadence[1] <= TB) && (m->cadence[0] > TB) && (m->cadence[11]) )
391                     hb_log("%fs: Video -> Film", (float)buf->start / 90000);
392                 if ( (m->cadence[2] > TB) && (m->cadence[1] <= TB) && (m->cadence[0] <= TB) && (m->cadence[11]) )
393                     hb_log("%fs: Film -> Video", (float)buf->start / 90000);
394
395                 /* Store picture flags for later use by filters */
396                 buf->flags = m->info->display_picture->flags;
397
398                 hb_list_add( list_raw, buf );
399             }
400         }
401         else if( state == STATE_INVALID )
402         {
403             mpeg2_reset( m->libmpeg2, 0 );
404         }
405
406         /*
407          * Look for Closed Captions if scanning (!job) or if closed captions have been requested.
408          *
409          * Send them on to the closed caption decoder if requested and found.
410          */
411         if( ( !m->job || m->subtitle) &&
412             ( m->info->user_data_len != 0 &&
413               m->info->user_data[0] == 0x43 &&
414               m->info->user_data[1] == 0x43 ) ) 
415         {
416             int i, j;
417             const uint8_t *header = &m->info->user_data[4];
418             uint8_t pattern=header[0] & 0x80;
419             int field1packet = 0; /* expect Field 1 first */
420             if (pattern==0x00) 
421                 field1packet=1; /* expect Field 1 second */
422             int capcount=(header[0] & 0x1e) / 2;
423             header++;
424             
425             /*
426              * Add closed captions to the title if we are scanning (no job).
427              *
428              * Just because we don't add this doesn't mean that there aren't any when 
429              * we scan, just that noone said anything. So you should be able to add
430              * closed captions some other way (See decmpeg2Init() for alternative
431              * approach of assuming that there are always CC, which is probably
432              * safer - however I want to leave the autodetect in here for now to
433              * see how it goes).
434              */
435             if( !m->job && m->title )
436             {
437                 hb_subtitle_t * subtitle;
438                 int found = 0;
439                 int i;
440                 
441                 for( i = 0; i < hb_list_count( m->title->list_subtitle ); i++ )
442                 {
443                     subtitle = hb_list_item( m->title->list_subtitle, i);
444                     /*
445                      * Let's call them 608 subs for now even if they aren't, since they 
446                      * are the only types we grok.
447                      */
448                     if( subtitle && subtitle->source == CC608SUB ) 
449                     {
450                         found = 1;
451                         break;
452                     }
453                 }
454                 
455                 if( !found )
456                 {
457                     subtitle = calloc( sizeof( hb_subtitle_t ), 1 );
458                     subtitle->track = 0;
459                     subtitle->id = 0x0;
460                     snprintf( subtitle->lang, sizeof( subtitle->lang ), "Closed Captions");
461                     /*
462                      * The language of the subtitles will be the same as the first audio
463                      * track, i.e. the same as the video.
464                      */
465                     hb_audio_t *audio = hb_list_item( m->title->list_audio, 0 );
466                     if( audio )
467                     {
468                         snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), 
469                                   audio->config.lang.iso639_2);
470                     } else {
471                         snprintf( subtitle->iso639_2, sizeof( subtitle->iso639_2 ), "und");
472                     }
473                     subtitle->format = TEXTSUB;
474                     subtitle->source = CC608SUB;
475                     subtitle->dest   = PASSTHRUSUB;
476                     subtitle->type = 5; 
477                     
478                     hb_list_add( m->title->list_subtitle, subtitle );
479                 }
480             }
481
482             for( i=0; i<capcount; i++ )
483             {
484                 for( j=0; j<2; j++ )
485                 {
486                     uint8_t data[3];
487                     data[0] = header[0];
488                     data[1] = header[1];
489                     data[2] = header[2];
490                     header += 3;
491                     /* Field 1 and 2 data can be in either order,
492                        with marker bytes of \xff and \xfe
493                        Since markers can be repeated, use pattern as well */
494                     if( data[0] == 0xff && j == field1packet )
495                     {
496                         data[0] = 0x04; // Field 1
497                     }   
498                     else
499                     {
500                         data[0] = 0x05; // Field 2
501                     }
502                     hb_mpeg2_cc( m, data );
503                 }
504             }
505             // Deal with extra closed captions some DVD have.
506             while( header[0]==0xfe || header[0]==0xff )
507             {
508                 for( j=0; j<2; j++ )
509                 {
510                     uint8_t data[3];
511                     data[0] = header[0];
512                     data[1] = header[1];
513                     data[2] = header[2];
514                     header += 3;
515                     /* Field 1 and 2 data can be in either order,
516                        with marker bytes of \xff and \xfe
517                        Since markers can be repeated, use pattern as well */
518                     if( data[0] == 0xff && j == field1packet )
519                     {
520                         data[0] = 0x04; // Field 1
521                     }   
522                     else
523                     {
524                         data[0] = 0x05; // Field 2
525                     } 
526                     hb_mpeg2_cc( m, data );
527                 }
528             }   
529         }
530     }
531     return 1;
532 }
533
534 /**********************************************************************
535  * hb_libmpeg2_close
536  **********************************************************************
537  *
538  *********************************************************************/
539 static void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
540 {
541     hb_libmpeg2_t * m = *_m;
542
543     mpeg2_close( m->libmpeg2 );
544
545     free( m );
546     *_m = NULL;
547 }
548
549 /**********************************************************************
550  * The decmpeg2 work object
551  **********************************************************************
552  *
553  *********************************************************************/
554 struct hb_work_private_s
555 {
556     hb_libmpeg2_t * libmpeg2;
557     hb_list_t     * list;
558 };
559
560 /**********************************************************************
561  * hb_work_decmpeg2_init
562  **********************************************************************
563  *
564  *********************************************************************/
565 static int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
566 {
567     hb_work_private_t * pv;
568
569     pv              = calloc( 1, sizeof( hb_work_private_t ) );
570     w->private_data = pv;
571
572     pv->libmpeg2 = hb_libmpeg2_init();
573     pv->list     = hb_list_init();
574
575     pv->libmpeg2->job = job;
576
577     if( job && job->title ) {
578         pv->libmpeg2->title = job->title;
579     }
580
581     /*
582      * If not scanning, then are we supposed to extract Closed Captions
583      * and send them to the decoder? 
584      */
585     if( job )
586     {
587         hb_subtitle_t * subtitle;
588         int i;
589         
590         for( i = 0; i < hb_list_count( job->list_subtitle ); i++ )
591         {
592             subtitle = hb_list_item( job->list_subtitle, i);
593             if( subtitle && subtitle->source == CC608SUB ) 
594             {
595                 pv->libmpeg2->subtitle = subtitle;
596                 break;
597             }
598         }
599
600     }
601
602     return 0;
603 }
604
605 /**********************************************************************
606  * Work
607  **********************************************************************
608  *
609  *********************************************************************/
610 static int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
611                          hb_buffer_t ** buf_out )
612 {
613     hb_work_private_t * pv = w->private_data;
614     hb_buffer_t * buf, * last = NULL;
615     int status = HB_WORK_OK;
616
617     if( w->title && pv && pv->libmpeg2 && !pv->libmpeg2->title ) {
618         pv->libmpeg2->title = w->title;
619     }
620
621     // The reader found a chapter break. Remove it from the input 
622     // stream. If we're reading (as opposed to scanning) start looking
623     // for the next GOP start since that's where the chapter begins.
624     if( (*buf_in)->new_chap )
625     {
626         if ( pv->libmpeg2->job )
627         {
628             pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
629         }
630         (*buf_in)->new_chap = 0;
631     }
632
633     hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
634
635     /* if we got an empty buffer signaling end-of-stream send it downstream */
636     if ( (*buf_in)->size == 0 )
637     {
638         hb_list_add( pv->list, *buf_in );
639         *buf_in = NULL;
640         status = HB_WORK_DONE;
641         /*
642          * Let the Closed Captions know that it is the end of the data.
643          */
644         if( pv->libmpeg2->subtitle )
645         {
646             hb_buffer_t *buf_eof = hb_buffer_init( 0 );
647             
648             if( buf_eof )
649             {
650                 hb_fifo_push( pv->libmpeg2->subtitle->fifo_in, buf_eof );
651             }
652         }
653     }
654
655     *buf_out = NULL;
656     while( ( buf = hb_list_item( pv->list, 0 ) ) )
657     {
658         hb_list_rem( pv->list, buf );
659         if( last )
660         {
661             last->next = buf;
662             last       = buf;
663         }
664         else
665         {
666             *buf_out = buf;
667             last     = buf;
668         }
669     }
670
671     return status;
672 }
673
674 /**********************************************************************
675  * Close
676  **********************************************************************
677  *
678  *********************************************************************/
679 static void decmpeg2Close( hb_work_object_t * w )
680 {
681     hb_work_private_t * pv = w->private_data;
682
683     // don't log during scan
684     if ( pv->libmpeg2->job )
685     {
686         hb_log( "mpeg2 done: %d frames", pv->libmpeg2->nframes );
687     }
688     hb_list_close( &pv->list );
689     hb_libmpeg2_close( &pv->libmpeg2 );
690     free( pv );
691 }
692
693 static int decmpeg2Info( hb_work_object_t *w, hb_work_info_t *info )
694 {
695     hb_work_private_t *pv = w->private_data;
696
697     memset( info, 0, sizeof(*info) );
698
699     if ( pv && pv->libmpeg2 && pv->libmpeg2->info && pv->libmpeg2->info->sequence )
700     {
701         hb_libmpeg2_t *m = pv->libmpeg2;
702
703         info->width = m->width;
704         info->height = m->height;
705         info->pixel_aspect_width = m->info->sequence->pixel_width;
706         info->pixel_aspect_height = m->info->sequence->pixel_height;
707         info->aspect = m->aspect_ratio;
708
709         // if the frame is progressive & NTSC DVD height report it as 23.976 FPS
710         // so that scan can autodetect NTSC film
711         info->rate = 27000000;
712         info->rate_base = ( m->info->display_fbuf && m->info->display_picture &&
713                             (m->info->display_picture->flags & PROGRESSIVE) &&
714                             (m->height == 480 ) ) ?  1126125 : m->rate;
715
716         info->bitrate = m->info->sequence->byte_rate * 8;
717         info->profile = m->info->sequence->profile_level_id >> 4;
718         info->level = m->info->sequence->profile_level_id & 0xf;
719         info->name = "mpeg2";
720         return 1;
721     }
722     return 0;
723 }
724
725 hb_work_object_t hb_decmpeg2 =
726 {
727     WORK_DECMPEG2,
728     "MPEG-2 decoder (libmpeg2)",
729     decmpeg2Init,
730     decmpeg2Work,
731     decmpeg2Close,
732     decmpeg2Info
733 };
734