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;
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 */
52 /**********************************************************************
54 **********************************************************************
56 *********************************************************************/
57 hb_libmpeg2_t * hb_libmpeg2_init()
59 hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
61 m->libmpeg2 = mpeg2_init();
62 m->info = mpeg2_info( m->libmpeg2 );
68 /**********************************************************************
70 **********************************************************************
72 *********************************************************************/
73 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
74 hb_list_t * list_raw )
83 if( buf_es->start > -1 )
85 mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
86 buf_es->start & 0xFFFFFFFF );
88 mpeg2_buffer( m->libmpeg2, buf_es->data,
89 buf_es->data + buf_es->size );
94 state = mpeg2_parse( m->libmpeg2 );
95 if( state == STATE_BUFFER )
97 /* Require some more data */
100 else if( state == STATE_SEQUENCE )
102 if( !( m->width && m->height && m->rate ) )
104 m->width = m->info->sequence->width;
105 m->height = m->info->sequence->height;
106 m->rate = m->info->sequence->frame_period;
107 if ( m->aspect_ratio <= 0 && m->height &&
108 m->info->sequence->pixel_height )
110 /* mpeg2_parse doesn't store the aspect ratio. Instead
111 * it keeps the pixel width & height that would cause
112 * the storage width & height to come out in the correct
113 * aspect ratio. Convert these back to aspect ratio.
114 * We do the calc in floating point to get the rounding right.
115 * We round in the second decimal digit because we scale
116 * the (integer) aspect by 9 to preserve the 1st digit.
118 double ar_numer = m->width * m->info->sequence->pixel_width;
119 double ar_denom = m->height * m->info->sequence->pixel_height;
120 m->aspect_ratio = ( ar_numer / ar_denom + .05 ) * HB_ASPECT_BASE;
124 else if( state == STATE_GOP && m->look_for_break)
126 // we were looking for a gop to add a chapter break - we found it
127 // so now start looking for an iframe.
128 m->look_for_iframe = m->look_for_break;
129 m->look_for_break = 0;
131 else if( ( state == STATE_SLICE || state == STATE_END ) &&
132 m->info->display_fbuf )
134 if( ( m->info->display_picture->flags &
135 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
137 // we got an iframe so we can start decoding video now
143 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
146 buf->sequence = buf_es->sequence;
148 memcpy( data, m->info->display_fbuf->buf[0],
149 m->width * m->height );
150 data += m->width * m->height;
151 memcpy( data, m->info->display_fbuf->buf[1],
152 m->width * m->height / 4 );
153 data += m->width * m->height / 4;
154 memcpy( data, m->info->display_fbuf->buf[2],
155 m->width * m->height / 4 );
157 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
160 ( (uint64_t) m->info->display_picture->tag << 32 ) |
161 ( (uint64_t) m->info->display_picture->tag2 );
163 * Add back in again to track PTS of MPEG2 frames
164 * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
167 else if( m->last_pts > -1 )
169 /* For some reason nb_fields is sometimes 1 while it
171 buf->start = m->last_pts +
172 MAX( 2, m->info->display_picture->nb_fields ) *
173 m->info->sequence->frame_period / 600;
179 m->last_pts = buf->start;
181 if( m->look_for_iframe && ( m->info->display_picture->flags &
182 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
184 // we were waiting for an iframe to insert a chapter mark
186 buf->new_chap = m->look_for_iframe;
187 m->look_for_iframe = 0;
188 const char *chap_name = "";
189 if ( m->job && buf->new_chap > 0 &&
190 hb_list_item( m->job->title->list_chapter,
191 buf->new_chap - 1 ) )
193 hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
195 chap_name = c->title;
197 hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld",
198 chap_name, buf->new_chap, m->nframes, buf->start );
202 flag = m->info->display_picture->flags;
204 /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.
205 hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
206 if( flag & TOP_FIRST )
207 hb_log("MPEG2 Flag: Top field first");
208 if( flag & PROGRESSIVE )
209 hb_log("MPEG2 Flag: Progressive");
210 if( flag & COMPOSITE )
211 hb_log("MPEG2 Flag: Composite");
213 hb_log("MPEG2 Flag: Skip!");
215 hb_log("MPEG2 Flag: TAGS");
216 if(flag & REPEAT_FIRST )
217 hb_log("MPEG2 Flag: Repeat first field");
218 if( flag & COMPOSITE_MASK )
219 hb_log("MPEG2 Flag: Composite mask");
220 hb_log("fields: %d", m->info->display_picture->nb_fields);
222 /* Rotate the cadence tracking. */
224 for(i=11; i > 0; i--)
226 cadence[i] = cadence[i-1];
229 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
231 /* Not progressive, not top first...
232 That means it's probably bottom
233 first, 2 fields displayed.
235 //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
238 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
240 /* Not progressive, top is first,
241 Two fields displayed.
243 //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
246 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
248 /* Progressive, but noting else.
249 That means Bottom first,
252 //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
253 cadence[0] = BT_PROG;
255 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
257 /* Progressive, and repeat. .
258 That means Bottom first,
261 //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
262 cadence[0] = BTB_PROG;
264 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
266 /* Progressive, top first.
267 That means top first,
270 //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
271 cadence[0] = TB_PROG;
273 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
275 /* Progressive, top, repeat.
276 That means top first,
279 //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
280 cadence[0] = TBT_PROG;
283 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
284 hb_log("%fs: Video -> Film", (float)buf->start / 90000);
285 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
286 hb_log("%fs: Film -> Video", (float)buf->start / 90000);
288 /* Store picture flags for later use by filters */
289 buf->flags = m->info->display_picture->flags;
291 hb_list_add( list_raw, buf );
294 else if( state == STATE_INVALID )
296 mpeg2_reset( m->libmpeg2, 0 );
302 /**********************************************************************
304 **********************************************************************
306 *********************************************************************/
307 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
308 int * rate, int *aspect_ratio )
312 if (m->info->display_fbuf)
314 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
316 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
317 This might not be correct for the title. It's really just for scan.c's benefit.
318 Scan.c will reset the fps to 29.97, until a simple majority of the preview
319 frames report at 23.976.
321 //hb_log("Detecting NTSC Progressive Frame");
326 *aspect_ratio = m->aspect_ratio;
329 int hb_libmpeg2_clear_aspect_ratio( hb_libmpeg2_t * m )
331 int ar = m->aspect_ratio;
336 /**********************************************************************
338 **********************************************************************
340 *********************************************************************/
341 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
343 hb_libmpeg2_t * m = *_m;
345 mpeg2_close( m->libmpeg2 );
351 /**********************************************************************
352 * The decmpeg2 work object
353 **********************************************************************
355 *********************************************************************/
356 struct hb_work_private_s
358 hb_libmpeg2_t * libmpeg2;
362 /**********************************************************************
363 * hb_work_decmpeg2_init
364 **********************************************************************
366 *********************************************************************/
367 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
369 hb_work_private_t * pv;
371 pv = calloc( 1, sizeof( hb_work_private_t ) );
372 w->private_data = pv;
374 pv->libmpeg2 = hb_libmpeg2_init();
375 pv->list = hb_list_init();
377 pv->libmpeg2->job = job;
382 /**********************************************************************
384 **********************************************************************
386 *********************************************************************/
387 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
388 hb_buffer_t ** buf_out )
390 hb_work_private_t * pv = w->private_data;
391 hb_buffer_t * buf, * last = NULL;
392 int status = HB_WORK_OK;
394 // The reader found a chapter break, consume it completely, and remove it from the
395 // stream. We need to shift it.
396 if( (*buf_in)->new_chap )
398 pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
399 (*buf_in)->new_chap = 0;
402 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
404 /* if we got an empty buffer signaling end-of-stream send it downstream */
405 if ( (*buf_in)->size == 0 )
407 hb_list_add( pv->list, *buf_in );
409 status = HB_WORK_DONE;
413 while( ( buf = hb_list_item( pv->list, 0 ) ) )
415 hb_list_rem( pv->list, buf );
431 /**********************************************************************
433 **********************************************************************
435 *********************************************************************/
436 void decmpeg2Close( hb_work_object_t * w )
438 hb_work_private_t * pv = w->private_data;
439 hb_log( "mpeg2 done: %d frames", pv->libmpeg2->nframes );
440 hb_list_close( &pv->list );
441 hb_libmpeg2_close( &pv->libmpeg2 );
445 hb_work_object_t hb_decmpeg2 =
448 "MPEG-2 decoder (libmpeg2)",