1 /* $Id: decmpeg2.c,v 1.12 2005/03/03 16:30:42 titer Exp $
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. */
9 #include "mpeg2dec/mpeg2.h"
11 /* Cadence tracking */
12 #ifndef PIC_FLAG_REPEAT_FIRST_FIELD
13 #define PIC_FLAG_REPEAT_FIRST_FIELD 256
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
31 /**********************************************************************
33 **********************************************************************
34 * A convenient libmpeg wrapper, used both here and in scan.c
35 *********************************************************************/
38 mpeg2dec_t * libmpeg2;
39 const mpeg2_info_t * info;
49 /**********************************************************************
51 **********************************************************************
53 *********************************************************************/
54 hb_libmpeg2_t * hb_libmpeg2_init()
56 hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
58 m->libmpeg2 = mpeg2_init();
59 m->info = mpeg2_info( m->libmpeg2 );
61 m->look_for_break = 0;
66 /**********************************************************************
68 **********************************************************************
70 *********************************************************************/
71 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
72 hb_list_t * list_raw )
80 if( buf_es->start > -1 )
82 mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
83 buf_es->start & 0xFFFFFFFF );
85 mpeg2_buffer( m->libmpeg2, buf_es->data,
86 buf_es->data + buf_es->size );
90 state = mpeg2_parse( m->libmpeg2 );
91 if( state == STATE_BUFFER )
93 /* Require some more data */
96 else if( state == STATE_SEQUENCE )
98 if( !( m->width && m->height && m->rate ) )
100 m->width = m->info->sequence->width;
101 m->height = m->info->sequence->height;
102 m->rate = m->info->sequence->frame_period;
104 if ( m->aspect_ratio <= 0 )
106 // We can parse out the aspect ratio from the Sequence Start Header data in buf_es->data
108 // Make sure we have the correct data in the buffer
109 if ((buf_es->data[0] == 0x00) && (buf_es->data[1] == 0x00) && (buf_es->data[2] == 0x01) && (buf_es->data[3] == 0xb3))
111 unsigned char ar_fr = buf_es->data[7]; // Top 4 bits == aspect ratio flag - bottom 4 bits == rate flags
112 switch ((ar_fr & 0xf0) >> 4)
115 m->aspect_ratio = HB_ASPECT_BASE * 4 / 3; // 4:3
118 m->aspect_ratio = HB_ASPECT_BASE * 16 / 9; // 16:9
121 hb_log("hb_libmpeg2_decode - STATE_SEQUENCE unexpected aspect ratio/frame rate 0x%x\n", ar_fr);
127 else if( state == STATE_GOP && m->look_for_break == 2)
129 hb_log("MPEG2: Group of pictures found, searching for I-Frame");
130 m->look_for_break = 1;
132 else if( ( state == STATE_SLICE || state == STATE_END ) &&
133 m->info->display_fbuf )
135 if( ( m->info->display_picture->flags &
136 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
140 // If we are looking for a break, insert the chapter break on an I-Frame
141 if( m->look_for_break == 1 )
143 hb_log("MPEG2: I-Frame Found");
144 m->look_for_break = 0;
151 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
154 buf->sequence = buf_es->sequence;
156 // Was a good break point found?
159 hb_log("MPEG2: Chapter Break Inserted");
164 memcpy( data, m->info->display_fbuf->buf[0],
165 m->width * m->height );
166 data += m->width * m->height;
167 memcpy( data, m->info->display_fbuf->buf[1],
168 m->width * m->height / 4 );
169 data += m->width * m->height / 4;
170 memcpy( data, m->info->display_fbuf->buf[2],
171 m->width * m->height / 4 );
173 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
176 ( (uint64_t) m->info->display_picture->tag << 32 ) |
177 ( (uint64_t) m->info->display_picture->tag2 );
179 * Add back in again to track PTS of MPEG2 frames
180 * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
183 else if( m->last_pts > -1 )
185 /* For some reason nb_fields is sometimes 1 while it
187 buf->start = m->last_pts +
188 MAX( 2, m->info->display_picture->nb_fields ) *
189 m->info->sequence->frame_period / 600;
195 m->last_pts = buf->start;
197 flag = m->info->display_picture->flags;
199 /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.
200 hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
201 if( flag & TOP_FIRST )
202 hb_log("MPEG2 Flag: Top field first");
203 if( flag & PROGRESSIVE )
204 hb_log("MPEG2 Flag: Progressive");
205 if( flag & COMPOSITE )
206 hb_log("MPEG2 Flag: Composite");
208 hb_log("MPEG2 Flag: Skip!");
210 hb_log("MPEG2 Flag: TAGS");
211 if(flag & REPEAT_FIRST )
212 hb_log("MPEG2 Flag: Repeat first field");
213 if( flag & COMPOSITE_MASK )
214 hb_log("MPEG2 Flag: Composite mask");
215 hb_log("fields: %d", m->info->display_picture->nb_fields);
217 /* Rotate the cadence tracking. */
219 for(i=11; i > 0; i--)
221 cadence[i] = cadence[i-1];
224 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
226 /* Not progressive, not top first...
227 That means it's probably bottom
228 first, 2 fields displayed.
230 //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
233 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
235 /* Not progressive, top is first,
236 Two fields displayed.
238 //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
241 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
243 /* Progressive, but noting else.
244 That means Bottom first,
247 //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
248 cadence[0] = BT_PROG;
250 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
252 /* Progressive, and repeat. .
253 That means Bottom first,
256 //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
257 cadence[0] = BTB_PROG;
259 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
261 /* Progressive, top first.
262 That means top first,
265 //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
266 cadence[0] = TB_PROG;
268 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
270 /* Progressive, top, repeat.
271 That means top first,
274 //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
275 cadence[0] = TBT_PROG;
278 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
279 hb_log("%fs: Interlaced -> Progressive", (float)buf->start / 90000);
280 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
281 hb_log("%fs: Progressive -> Interlaced", (float)buf->start / 90000);
283 /* Store picture flags for later use by filters */
284 buf->flags = m->info->display_picture->flags;
286 hb_list_add( list_raw, buf );
289 else if( state == STATE_INVALID )
291 mpeg2_reset( m->libmpeg2, 0 );
297 /**********************************************************************
299 **********************************************************************
301 *********************************************************************/
302 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
303 int * rate, int *aspect_ratio )
307 if (m->info->display_fbuf)
309 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
311 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
312 This might not be correct for the title. It's really just for scan.c's benefit.
313 Scan.c will reset the fps to 29.97, until a simple majority of the preview
314 frames report at 23.976.
316 //hb_log("Detecting NTSC Progressive Frame");
321 *aspect_ratio = m->aspect_ratio;
324 /**********************************************************************
326 **********************************************************************
328 *********************************************************************/
329 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
331 hb_libmpeg2_t * m = *_m;
333 mpeg2_close( m->libmpeg2 );
339 /**********************************************************************
340 * The decmpeg2 work object
341 **********************************************************************
343 *********************************************************************/
344 struct hb_work_private_s
346 hb_libmpeg2_t * libmpeg2;
350 /**********************************************************************
351 * hb_work_decmpeg2_init
352 **********************************************************************
354 *********************************************************************/
355 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
357 hb_work_private_t * pv;
359 pv = calloc( 1, sizeof( hb_work_private_t ) );
360 w->private_data = pv;
362 pv->libmpeg2 = hb_libmpeg2_init();
363 pv->list = hb_list_init();
368 /**********************************************************************
370 **********************************************************************
372 *********************************************************************/
373 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
374 hb_buffer_t ** buf_out )
376 hb_work_private_t * pv = w->private_data;
377 hb_buffer_t * buf, * last = NULL;
379 // The reader found a chapter break, consume it completely, and remove it from the
380 // stream. We need to shift it.
381 if( (*buf_in)->new_chap )
383 hb_log("MPEG2: Chapter Break Cell Found, searching for GOP");
384 pv->libmpeg2->look_for_break = 2;
385 (*buf_in)->new_chap = 0;
388 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
391 while( ( buf = hb_list_item( pv->list, 0 ) ) )
393 hb_list_rem( pv->list, buf );
409 /**********************************************************************
411 **********************************************************************
413 *********************************************************************/
414 void decmpeg2Close( hb_work_object_t * w )
416 hb_work_private_t * pv = w->private_data;
417 hb_list_close( &pv->list );
418 hb_libmpeg2_close( &pv->libmpeg2 );
422 hb_work_object_t hb_decmpeg2 =
425 "MPEG-2 decoder (libmpeg2)",