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
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 );
199 } else if ( m->nframes == 0 && m->job &&
200 hb_list_item( m->job->title->list_chapter,
201 m->job->chapter_start - 1 ) )
203 hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
204 m->job->chapter_start - 1 );
205 hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld", c->title,
206 m->job->chapter_start, m->nframes, buf->start );
210 flag = m->info->display_picture->flags;
212 /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.
213 hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
214 if( flag & TOP_FIRST )
215 hb_log("MPEG2 Flag: Top field first");
216 if( flag & PROGRESSIVE )
217 hb_log("MPEG2 Flag: Progressive");
218 if( flag & COMPOSITE )
219 hb_log("MPEG2 Flag: Composite");
221 hb_log("MPEG2 Flag: Skip!");
223 hb_log("MPEG2 Flag: TAGS");
224 if(flag & REPEAT_FIRST )
225 hb_log("MPEG2 Flag: Repeat first field");
226 if( flag & COMPOSITE_MASK )
227 hb_log("MPEG2 Flag: Composite mask");
228 hb_log("fields: %d", m->info->display_picture->nb_fields);
230 /* Rotate the cadence tracking. */
232 for(i=11; i > 0; i--)
234 cadence[i] = cadence[i-1];
237 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
239 /* Not progressive, not top first...
240 That means it's probably bottom
241 first, 2 fields displayed.
243 //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
246 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
248 /* Not progressive, top is first,
249 Two fields displayed.
251 //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
254 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
256 /* Progressive, but noting else.
257 That means Bottom first,
260 //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
261 cadence[0] = BT_PROG;
263 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
265 /* Progressive, and repeat. .
266 That means Bottom first,
269 //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
270 cadence[0] = BTB_PROG;
272 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
274 /* Progressive, top first.
275 That means top first,
278 //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
279 cadence[0] = TB_PROG;
281 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
283 /* Progressive, top, repeat.
284 That means top first,
287 //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
288 cadence[0] = TBT_PROG;
291 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
292 hb_log("%fs: Video -> Film", (float)buf->start / 90000);
293 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
294 hb_log("%fs: Film -> Video", (float)buf->start / 90000);
296 /* Store picture flags for later use by filters */
297 buf->flags = m->info->display_picture->flags;
299 hb_list_add( list_raw, buf );
302 else if( state == STATE_INVALID )
304 mpeg2_reset( m->libmpeg2, 0 );
310 /**********************************************************************
312 **********************************************************************
314 *********************************************************************/
315 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
316 int * rate, int *aspect_ratio )
320 if (m->info->display_fbuf)
322 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
324 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
325 This might not be correct for the title. It's really just for scan.c's benefit.
326 Scan.c will reset the fps to 29.97, until a simple majority of the preview
327 frames report at 23.976.
329 //hb_log("Detecting NTSC Progressive Frame");
334 *aspect_ratio = m->aspect_ratio;
337 int hb_libmpeg2_clear_aspect_ratio( hb_libmpeg2_t * m )
339 int ar = m->aspect_ratio;
344 /**********************************************************************
346 **********************************************************************
348 *********************************************************************/
349 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
351 hb_libmpeg2_t * m = *_m;
353 mpeg2_close( m->libmpeg2 );
359 /**********************************************************************
360 * The decmpeg2 work object
361 **********************************************************************
363 *********************************************************************/
364 struct hb_work_private_s
366 hb_libmpeg2_t * libmpeg2;
370 /**********************************************************************
371 * hb_work_decmpeg2_init
372 **********************************************************************
374 *********************************************************************/
375 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
377 hb_work_private_t * pv;
379 pv = calloc( 1, sizeof( hb_work_private_t ) );
380 w->private_data = pv;
382 pv->libmpeg2 = hb_libmpeg2_init();
383 pv->list = hb_list_init();
385 pv->libmpeg2->job = job;
390 /**********************************************************************
392 **********************************************************************
394 *********************************************************************/
395 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
396 hb_buffer_t ** buf_out )
398 hb_work_private_t * pv = w->private_data;
399 hb_buffer_t * buf, * last = NULL;
400 int status = HB_WORK_OK;
402 // The reader found a chapter break, consume it completely, and remove it from the
403 // stream. We need to shift it.
404 if( (*buf_in)->new_chap )
406 pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
407 (*buf_in)->new_chap = 0;
410 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
412 /* if we got an empty buffer signaling end-of-stream send it downstream */
413 if ( (*buf_in)->size == 0 )
415 hb_list_add( pv->list, *buf_in );
417 status = HB_WORK_DONE;
421 while( ( buf = hb_list_item( pv->list, 0 ) ) )
423 hb_list_rem( pv->list, buf );
439 /**********************************************************************
441 **********************************************************************
443 *********************************************************************/
444 void decmpeg2Close( hb_work_object_t * w )
446 hb_work_private_t * pv = w->private_data;
447 hb_log( "mpeg2 done: %d frames", pv->libmpeg2->nframes );
448 hb_list_close( &pv->list );
449 hb_libmpeg2_close( &pv->libmpeg2 );
453 hb_work_object_t hb_decmpeg2 =
456 "MPEG-2 decoder (libmpeg2)",