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 printf("MPEG2: Group of pictures found, searching for I-Frame\n");
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 printf("MPEG2: I-Frame Found\n");
144 m->look_for_break = 0;
151 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
154 // Was a good break point found?
157 printf("MPEG2: Chapter Break Inserted\n");
162 memcpy( data, m->info->display_fbuf->buf[0],
163 m->width * m->height );
164 data += m->width * m->height;
165 memcpy( data, m->info->display_fbuf->buf[1],
166 m->width * m->height / 4 );
167 data += m->width * m->height / 4;
168 memcpy( data, m->info->display_fbuf->buf[2],
169 m->width * m->height / 4 );
171 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
174 ( (uint64_t) m->info->display_picture->tag << 32 ) |
175 ( (uint64_t) m->info->display_picture->tag2 );
177 * Add back in again to track PTS of MPEG2 frames
178 * hb_log("MPEG2: Normal buf->start = %lld", buf->start);
181 else if( m->last_pts > -1 )
183 /* For some reason nb_fields is sometimes 1 while it
185 buf->start = m->last_pts +
186 MAX( 2, m->info->display_picture->nb_fields ) *
187 m->info->sequence->frame_period / 600;
193 m->last_pts = buf->start;
195 flag = m->info->display_picture->flags;
197 /* Uncomment this block to see frame-by-frame picture flags, as the video encodes.
198 hb_log("***** MPEG 2 Picture Info for PTS %lld *****", buf->start);
199 if( flag & TOP_FIRST )
200 hb_log("MPEG2 Flag: Top field first");
201 if( flag & PROGRESSIVE )
202 hb_log("MPEG2 Flag: Progressive");
203 if( flag & COMPOSITE )
204 hb_log("MPEG2 Flag: Composite");
206 hb_log("MPEG2 Flag: Skip!");
208 hb_log("MPEG2 Flag: TAGS");
209 if(flag & REPEAT_FIRST )
210 hb_log("MPEG2 Flag: Repeat first field");
211 if( flag & COMPOSITE_MASK )
212 hb_log("MPEG2 Flag: Composite mask");
213 hb_log("fields: %d", m->info->display_picture->nb_fields);
215 /* Rotate the cadence tracking. */
216 cadence[5] = cadence[4];
217 cadence[4] = cadence[3];
218 cadence[3] = cadence[2];
219 cadence[2] = cadence[1];
220 cadence[1] = cadence[0];
222 if ( !(flag & PROGRESSIVE) && !(flag & TOP_FIRST) )
224 /* Not progressive, not top first...
225 That means it's probably bottom
226 first, 2 fields displayed.
228 //hb_log("MPEG2 Flag: Bottom field first, 2 fields displayed.");
231 else if ( !(flag & PROGRESSIVE) && (flag & TOP_FIRST) )
233 /* Not progressive, top is first,
234 Two fields displayed.
236 //hb_log("MPEG2 Flag: Top field first, 2 fields displayed.");
239 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
241 /* Progressive, but noting else.
242 That means Bottom first,
245 //hb_log("MPEG2 Flag: Progressive. Bottom field first, 2 fields displayed.");
246 cadence[0] = BT_PROG;
248 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
250 /* Progressive, and repeat. .
251 That means Bottom first,
254 //hb_log("MPEG2 Flag: Progressive repeat. Bottom field first, 3 fields displayed.");
255 cadence[0] = BTB_PROG;
257 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
259 /* Progressive, top first.
260 That means top first,
263 //hb_log("MPEG2 Flag: Progressive. Top field first, 2 fields displayed.");
264 cadence[0] = TB_PROG;
266 else if ( (flag & PROGRESSIVE) && (flag & TOP_FIRST) && ( flag & REPEAT_FIRST ) )
268 /* Progressive, top, repeat.
269 That means top first,
272 //hb_log("MPEG2 Flag: Progressive repeat. Top field first, 3 fields displayed.");
273 cadence[0] = TBT_PROG;
276 if ( (cadence[2] <= TB) && (cadence[1] <= TB) && (cadence[0] > TB) && (cadence[0]) && (cadence[1]) )
277 hb_log("PTS %lld: Interlaced -> Progressive", buf->start);
278 if ( (cadence[2] > TB) && (cadence[1] <= TB) && (cadence[0] <= TB) && (cadence[0]) && (cadence[1]) )
279 hb_log("PTS %lld: Progressive -> Interlaced", buf->start);
281 /* Store picture flags for later use by filters */
282 buf->flags = m->info->display_picture->flags;
284 hb_list_add( list_raw, buf );
287 else if( state == STATE_INVALID )
289 mpeg2_reset( m->libmpeg2, 0 );
295 /**********************************************************************
297 **********************************************************************
299 *********************************************************************/
300 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
301 int * rate, int *aspect_ratio )
305 if (m->info->display_fbuf)
307 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
309 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
310 This might not be correct for the title. It's really just for scan.c's benefit.
311 Scan.c will reset the fps to 29.97, until a simple majority of the preview
312 frames report at 23.976.
314 //hb_log("Detecting NTSC Progressive Frame");
319 *aspect_ratio = m->aspect_ratio;
322 /**********************************************************************
324 **********************************************************************
326 *********************************************************************/
327 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
329 hb_libmpeg2_t * m = *_m;
331 mpeg2_close( m->libmpeg2 );
337 /**********************************************************************
338 * The decmpeg2 work object
339 **********************************************************************
341 *********************************************************************/
342 struct hb_work_private_s
344 hb_libmpeg2_t * libmpeg2;
348 /**********************************************************************
349 * hb_work_decmpeg2_init
350 **********************************************************************
352 *********************************************************************/
353 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
355 hb_work_private_t * pv;
357 pv = calloc( 1, sizeof( hb_work_private_t ) );
358 w->private_data = pv;
360 pv->libmpeg2 = hb_libmpeg2_init();
361 pv->list = hb_list_init();
366 /**********************************************************************
368 **********************************************************************
370 *********************************************************************/
371 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
372 hb_buffer_t ** buf_out )
374 hb_work_private_t * pv = w->private_data;
375 hb_buffer_t * buf, * last = NULL;
377 // The reader found a chapter break, consume it completely, and remove it from the
378 // stream. We need to shift it.
379 if( (*buf_in)->new_chap )
381 printf("MPEG2: Chapter Break Cell Found, searching for GOP\n");
382 pv->libmpeg2->look_for_break = 2;
383 (*buf_in)->new_chap = 0;
386 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
389 while( ( buf = hb_list_item( pv->list, 0 ) ) )
391 hb_list_rem( pv->list, buf );
407 /**********************************************************************
409 **********************************************************************
411 *********************************************************************/
412 void decmpeg2Close( hb_work_object_t * w )
414 hb_work_private_t * pv = w->private_data;
415 hb_list_close( &pv->list );
416 hb_libmpeg2_close( &pv->libmpeg2 );
420 hb_work_object_t hb_decmpeg2 =
423 "MPEG-2 decoder (libmpeg2)",