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.fr/>.
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
28 static int cadence[12];
31 /**********************************************************************
33 *********************************************************************/
34 typedef struct hb_libmpeg2_s
36 mpeg2dec_t * libmpeg2;
37 const mpeg2_info_t * info;
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 */
50 /**********************************************************************
52 **********************************************************************
54 *********************************************************************/
55 static hb_libmpeg2_t * hb_libmpeg2_init()
57 hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
59 m->libmpeg2 = mpeg2_init();
60 m->info = mpeg2_info( m->libmpeg2 );
66 /**********************************************************************
68 **********************************************************************
70 *********************************************************************/
71 static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
72 hb_list_t * list_raw )
81 if( buf_es->start > -1 )
83 mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
84 buf_es->start & 0xFFFFFFFF );
86 mpeg2_buffer( m->libmpeg2, buf_es->data,
87 buf_es->data + buf_es->size );
92 state = mpeg2_parse( m->libmpeg2 );
93 if( state == STATE_BUFFER )
95 /* Require some more data */
98 else if( state == STATE_SEQUENCE )
100 if( !( m->width && m->height && m->rate ) )
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 )
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 * We do the calc in floating point to get the rounding right.
113 * We round in the second decimal digit because we scale
114 * the (integer) aspect by 9 to preserve the 1st digit.
116 double ar_numer = m->width * m->info->sequence->pixel_width;
117 double ar_denom = m->height * m->info->sequence->pixel_height;
118 m->aspect_ratio = ( ar_numer / ar_denom + .05 ) * HB_ASPECT_BASE;
122 else if( state == STATE_GOP && m->look_for_break)
124 // we were looking for a gop to add a chapter break - we found it
125 // so now start looking for an iframe.
126 m->look_for_iframe = m->look_for_break;
127 m->look_for_break = 0;
129 else if( ( state == STATE_SLICE || state == STATE_END ) &&
130 m->info->display_fbuf )
132 if( ( m->info->display_picture->flags &
133 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
135 // we got an iframe so we can start decoding video now
141 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
144 buf->sequence = buf_es->sequence;
146 memcpy( data, m->info->display_fbuf->buf[0],
147 m->width * m->height );
148 data += m->width * m->height;
149 memcpy( data, m->info->display_fbuf->buf[1],
150 m->width * m->height / 4 );
151 data += m->width * m->height / 4;
152 memcpy( data, m->info->display_fbuf->buf[2],
153 m->width * m->height / 4 );
155 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
158 ( (uint64_t) m->info->display_picture->tag << 32 ) |
159 ( (uint64_t) m->info->display_picture->tag2 );
161 * Add back in again to track PTS of MPEG2 frames
162 * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
165 else if( m->last_pts > -1 )
167 /* For some reason nb_fields is sometimes 1 while it
169 buf->start = m->last_pts +
170 MAX( 2, m->info->display_picture->nb_fields ) *
171 m->info->sequence->frame_period / 600;
177 m->last_pts = buf->start;
179 if( m->look_for_iframe && ( m->info->display_picture->flags &
180 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
182 // we were waiting for an iframe to insert a chapter mark
184 buf->new_chap = m->look_for_iframe;
185 m->look_for_iframe = 0;
186 const char *chap_name = "";
187 if ( m->job && buf->new_chap > 0 &&
188 hb_list_item( m->job->title->list_chapter,
189 buf->new_chap - 1 ) )
191 hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
193 chap_name = c->title;
195 hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld",
196 chap_name, buf->new_chap, m->nframes, buf->start );
197 } else if ( m->nframes == 0 && m->job &&
198 hb_list_item( m->job->title->list_chapter,
199 m->job->chapter_start - 1 ) )
201 hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
202 m->job->chapter_start - 1 );
203 hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld", c->title,
204 m->job->chapter_start, m->nframes, buf->start );
208 flag = m->info->display_picture->flags;
210 /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.
211 hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
212 if( flag & TOP_FIRST )
213 hb_log("MPEG2 Flag: Top field first");
214 if( flag & PROGRESSIVE )
215 hb_log("MPEG2 Flag: Progressive");
216 if( flag & COMPOSITE )
217 hb_log("MPEG2 Flag: Composite");
219 hb_log("MPEG2 Flag: Skip!");
221 hb_log("MPEG2 Flag: TAGS");
222 if(flag & REPEAT_FIRST )
223 hb_log("MPEG2 Flag: Repeat first field");
224 if( flag & COMPOSITE_MASK )
225 hb_log("MPEG2 Flag: Composite mask");
226 hb_log("fields: %d", m->info->display_picture->nb_fields);
228 /* Rotate the cadence tracking. */
230 for(i=11; i > 0; i--)
232 cadence[i] = cadence[i-1];
235 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
237 /* Not progressive, not top first...
238 That means it's probably bottom
239 first, 2 fields displayed.
241 //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
244 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
246 /* Not progressive, top is first,
247 Two fields displayed.
249 //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
252 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
254 /* Progressive, but noting else.
255 That means Bottom first,
258 //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
259 cadence[0] = BT_PROG;
261 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
263 /* Progressive, and repeat. .
264 That means Bottom first,
267 //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
268 cadence[0] = BTB_PROG;
270 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
272 /* Progressive, top first.
273 That means top first,
276 //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
277 cadence[0] = TB_PROG;
279 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
281 /* Progressive, top, repeat.
282 That means top first,
285 //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
286 cadence[0] = TBT_PROG;
289 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
290 hb_log("%fs: Video -> Film", (float)buf->start / 90000);
291 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
292 hb_log("%fs: Film -> Video", (float)buf->start / 90000);
294 /* Store picture flags for later use by filters */
295 buf->flags = m->info->display_picture->flags;
297 hb_list_add( list_raw, buf );
300 else if( state == STATE_INVALID )
302 mpeg2_reset( m->libmpeg2, 0 );
308 /**********************************************************************
310 **********************************************************************
312 *********************************************************************/
313 static void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
314 int * rate, int *aspect_ratio )
318 if (m->info->display_fbuf)
320 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
322 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
323 This might not be correct for the title. It's really just for scan.c's benefit.
324 Scan.c will reset the fps to 29.97, until a simple majority of the preview
325 frames report at 23.976.
327 //hb_log("Detecting NTSC Progressive Frame");
332 *aspect_ratio = m->aspect_ratio;
335 /**********************************************************************
337 **********************************************************************
339 *********************************************************************/
340 static void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
342 hb_libmpeg2_t * m = *_m;
344 mpeg2_close( m->libmpeg2 );
350 /**********************************************************************
351 * The decmpeg2 work object
352 **********************************************************************
354 *********************************************************************/
355 struct hb_work_private_s
357 hb_libmpeg2_t * libmpeg2;
361 /**********************************************************************
362 * hb_work_decmpeg2_init
363 **********************************************************************
365 *********************************************************************/
366 static int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
368 hb_work_private_t * pv;
370 pv = calloc( 1, sizeof( hb_work_private_t ) );
371 w->private_data = pv;
373 pv->libmpeg2 = hb_libmpeg2_init();
374 pv->list = hb_list_init();
376 pv->libmpeg2->job = job;
381 /**********************************************************************
383 **********************************************************************
385 *********************************************************************/
386 static int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
387 hb_buffer_t ** buf_out )
389 hb_work_private_t * pv = w->private_data;
390 hb_buffer_t * buf, * last = NULL;
391 int status = HB_WORK_OK;
393 // The reader found a chapter break, consume it completely, and remove it from the
394 // stream. We need to shift it.
395 if( (*buf_in)->new_chap )
397 pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
398 (*buf_in)->new_chap = 0;
401 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
403 /* if we got an empty buffer signaling end-of-stream send it downstream */
404 if ( (*buf_in)->size == 0 )
406 hb_list_add( pv->list, *buf_in );
408 status = HB_WORK_DONE;
412 while( ( buf = hb_list_item( pv->list, 0 ) ) )
414 hb_list_rem( pv->list, buf );
430 /**********************************************************************
432 **********************************************************************
434 *********************************************************************/
435 static void decmpeg2Close( hb_work_object_t * w )
437 hb_work_private_t * pv = w->private_data;
439 // don't log during scan
440 if ( pv->libmpeg2->job )
442 hb_log( "mpeg2 done: %d frames", pv->libmpeg2->nframes );
444 hb_list_close( &pv->list );
445 hb_libmpeg2_close( &pv->libmpeg2 );
449 static int decmpeg2Info( hb_work_object_t *w, hb_work_info_t *info )
451 hb_work_private_t *pv = w->private_data;
453 if ( pv && pv->libmpeg2 )
456 hb_libmpeg2_t *m = pv->libmpeg2;
458 hb_libmpeg2_info( m, &info->width, &info->height, &info->rate_base,
461 info->aspect = (double)aspect;
462 info->rate = 27000000;
464 info->bitrate = m->info->sequence->byte_rate * 8;
465 info->profile = m->info->sequence->profile_level_id >> 4;
466 info->level = m->info->sequence->profile_level_id & 0xf;
467 info->name = "mpeg2";
473 hb_work_object_t hb_decmpeg2 =
476 "MPEG-2 decoder (libmpeg2)",