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 )
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 );
91 state = mpeg2_parse( m->libmpeg2 );
92 if( state == STATE_BUFFER )
94 /* Require some more data */
97 else if( state == STATE_SEQUENCE )
99 if( !( m->width && m->height && m->rate ) )
101 m->width = m->info->sequence->width;
102 m->height = m->info->sequence->height;
103 m->rate = m->info->sequence->frame_period;
104 if ( m->aspect_ratio <= 0 && m->height &&
105 m->info->sequence->pixel_height )
107 /* mpeg2_parse doesn't store the aspect ratio. Instead
108 * it keeps the pixel width & height that would cause
109 * the storage width & height to come out in the correct
110 * aspect ratio. Convert these back to aspect ratio.
111 * We do the calc in floating point to get the rounding right.
112 * We round in the second decimal digit because we scale
113 * the (integer) aspect by 9 to preserve the 1st digit.
115 double ar_numer = m->width * m->info->sequence->pixel_width;
116 double ar_denom = m->height * m->info->sequence->pixel_height;
117 m->aspect_ratio = ( ar_numer / ar_denom + .05 ) * HB_ASPECT_BASE;
121 else if( state == STATE_GOP && m->look_for_break)
123 // we were looking for a gop to add a chapter break - we found it
124 // so now start looking for an iframe.
125 m->look_for_iframe = m->look_for_break;
126 m->look_for_break = 0;
128 else if( ( state == STATE_SLICE || state == STATE_END ) &&
129 m->info->display_fbuf )
131 if( ( m->info->display_picture->flags &
132 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
134 // we got an iframe so we can start decoding video now
140 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
143 buf->sequence = buf_es->sequence;
145 memcpy( data, m->info->display_fbuf->buf[0],
146 m->width * m->height );
147 data += m->width * m->height;
148 memcpy( data, m->info->display_fbuf->buf[1],
149 m->width * m->height / 4 );
150 data += m->width * m->height / 4;
151 memcpy( data, m->info->display_fbuf->buf[2],
152 m->width * m->height / 4 );
154 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
157 ( (uint64_t) m->info->display_picture->tag << 32 ) |
158 ( (uint64_t) m->info->display_picture->tag2 );
160 * Add back in again to track PTS of MPEG2 frames
161 * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
164 else if( m->last_pts > -1 )
166 /* For some reason nb_fields is sometimes 1 while it
168 buf->start = m->last_pts +
169 MAX( 2, m->info->display_picture->nb_fields ) *
170 m->info->sequence->frame_period / 600;
176 m->last_pts = buf->start;
178 if( m->look_for_iframe && ( m->info->display_picture->flags &
179 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
181 // we were waiting for an iframe to insert a chapter mark
183 buf->new_chap = m->look_for_iframe;
184 m->look_for_iframe = 0;
185 const char *chap_name = "";
186 if ( m->job && buf->new_chap > 0 &&
187 hb_list_item( m->job->title->list_chapter,
188 buf->new_chap - 1 ) )
190 hb_chapter_t * c = hb_list_item( m->job->title->list_chapter,
192 chap_name = c->title;
194 hb_log( "mpeg2: \"%s\" (%d) at frame %u time %lld",
195 chap_name, buf->new_chap, m->nframes, buf->start );
199 flag = m->info->display_picture->flags;
201 /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.
202 hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
203 if( flag & TOP_FIRST )
204 hb_log("MPEG2 Flag: Top field first");
205 if( flag & PROGRESSIVE )
206 hb_log("MPEG2 Flag: Progressive");
207 if( flag & COMPOSITE )
208 hb_log("MPEG2 Flag: Composite");
210 hb_log("MPEG2 Flag: Skip!");
212 hb_log("MPEG2 Flag: TAGS");
213 if(flag & REPEAT_FIRST )
214 hb_log("MPEG2 Flag: Repeat first field");
215 if( flag & COMPOSITE_MASK )
216 hb_log("MPEG2 Flag: Composite mask");
217 hb_log("fields: %d", m->info->display_picture->nb_fields);
219 /* Rotate the cadence tracking. */
221 for(i=11; i > 0; i--)
223 cadence[i] = cadence[i-1];
226 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
228 /* Not progressive, not top first...
229 That means it's probably bottom
230 first, 2 fields displayed.
232 //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
235 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
237 /* Not progressive, top is first,
238 Two fields displayed.
240 //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
243 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
245 /* Progressive, but noting else.
246 That means Bottom first,
249 //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
250 cadence[0] = BT_PROG;
252 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
254 /* Progressive, and repeat. .
255 That means Bottom first,
258 //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
259 cadence[0] = BTB_PROG;
261 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
263 /* Progressive, top first.
264 That means top first,
267 //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
268 cadence[0] = TB_PROG;
270 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
272 /* Progressive, top, repeat.
273 That means top first,
276 //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
277 cadence[0] = TBT_PROG;
280 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[11]) )
281 hb_log("%fs: Video -> Film", (float)buf->start / 90000);
282 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[11]) )
283 hb_log("%fs: Film -> Video", (float)buf->start / 90000);
285 /* Store picture flags for later use by filters */
286 buf->flags = m->info->display_picture->flags;
288 hb_list_add( list_raw, buf );
291 else if( state == STATE_INVALID )
293 mpeg2_reset( m->libmpeg2, 0 );
299 /**********************************************************************
301 **********************************************************************
303 *********************************************************************/
304 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
305 int * rate, int *aspect_ratio )
309 if (m->info->display_fbuf)
311 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
313 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
314 This might not be correct for the title. It's really just for scan.c's benefit.
315 Scan.c will reset the fps to 29.97, until a simple majority of the preview
316 frames report at 23.976.
318 //hb_log("Detecting NTSC Progressive Frame");
323 *aspect_ratio = m->aspect_ratio;
326 int hb_libmpeg2_clear_aspect_ratio( hb_libmpeg2_t * m )
328 int ar = m->aspect_ratio;
333 /**********************************************************************
335 **********************************************************************
337 *********************************************************************/
338 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
340 hb_libmpeg2_t * m = *_m;
342 mpeg2_close( m->libmpeg2 );
348 /**********************************************************************
349 * The decmpeg2 work object
350 **********************************************************************
352 *********************************************************************/
353 struct hb_work_private_s
355 hb_libmpeg2_t * libmpeg2;
359 /**********************************************************************
360 * hb_work_decmpeg2_init
361 **********************************************************************
363 *********************************************************************/
364 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
366 hb_work_private_t * pv;
368 pv = calloc( 1, sizeof( hb_work_private_t ) );
369 w->private_data = pv;
371 pv->libmpeg2 = hb_libmpeg2_init();
372 pv->list = hb_list_init();
374 pv->libmpeg2->job = job;
379 /**********************************************************************
381 **********************************************************************
383 *********************************************************************/
384 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
385 hb_buffer_t ** buf_out )
387 hb_work_private_t * pv = w->private_data;
388 hb_buffer_t * buf, * last = NULL;
390 // The reader found a chapter break, consume it completely, and remove it from the
391 // stream. We need to shift it.
392 if( (*buf_in)->new_chap )
394 pv->libmpeg2->look_for_break = (*buf_in)->new_chap;
395 (*buf_in)->new_chap = 0;
398 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
401 while( ( buf = hb_list_item( pv->list, 0 ) ) )
403 hb_list_rem( pv->list, buf );
419 /**********************************************************************
421 **********************************************************************
423 *********************************************************************/
424 void decmpeg2Close( hb_work_object_t * w )
426 hb_work_private_t * pv = w->private_data;
427 hb_list_close( &pv->list );
428 hb_libmpeg2_close( &pv->libmpeg2 );
432 hb_work_object_t hb_decmpeg2 =
435 "MPEG-2 decoder (libmpeg2)",