Moves the filters' logging info to work.c, adds parameter info. I also changed the...
[HandBrake.git] / libhb / decmpeg2.c
blob359a79e355b2864b1a50d8b59555818481278438
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. */
7 #include "hb.h"
9 #include "mpeg2dec/mpeg2.h"
11 /* Cadence tracking */
12 #ifndef PIC_FLAG_REPEAT_FIRST_FIELD
13 #define PIC_FLAG_REPEAT_FIRST_FIELD 256
14 #endif
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
22 #define TB 8
23 #define BT 16
24 #define BT_PROG 32
25 #define BTB_PROG 64
26 #define TB_PROG 128
27 #define TBT_PROG 256
28 int cadence[6];
29 int flag = 0;
31 /**********************************************************************
32 * hb_libmpeg2_t
33 **********************************************************************
34 * A convenient libmpeg wrapper, used both here and in scan.c
35 *********************************************************************/
36 struct hb_libmpeg2_s
38 mpeg2dec_t * libmpeg2;
39 const mpeg2_info_t * info;
40 int width;
41 int height;
42 int rate;
43 int aspect_ratio;
44 int got_iframe;
45 int look_for_break;
46 int64_t last_pts;
49 /**********************************************************************
50 * hb_libmpeg2_init
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 );
60 m->last_pts = -1;
61 m->look_for_break = 0;
63 return m;
66 /**********************************************************************
67 * hb_libmpeg2_decode
68 **********************************************************************
70 *********************************************************************/
71 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
72 hb_list_t * list_raw )
74 mpeg2_state_t state;
75 hb_buffer_t * buf;
76 uint8_t * data;
77 int chap_break = 0;
79 /* Feed libmpeg2 */
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 );
88 for( ;; )
90 state = mpeg2_parse( m->libmpeg2 );
91 if( state == STATE_BUFFER )
93 /* Require some more data */
94 break;
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)
114 case 2:
115 m->aspect_ratio = HB_ASPECT_BASE * 4 / 3; // 4:3
116 break;
117 case 3:
118 m->aspect_ratio = HB_ASPECT_BASE * 16 / 9; // 16:9
119 break;
120 default:
121 hb_log("hb_libmpeg2_decode - STATE_SEQUENCE unexpected aspect ratio/frame rate 0x%x\n", ar_fr);
122 break;
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 )
138 m->got_iframe = 1;
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;
145 chap_break = 1;
149 if( m->got_iframe )
151 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
152 data = buf->data;
154 // Was a good break point found?
155 if( chap_break )
157 printf("MPEG2: Chapter Break Inserted\n");
158 chap_break = 0;
159 buf->new_chap = 1;
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 )
173 buf->start =
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
184 should be 2 */
185 buf->start = m->last_pts +
186 MAX( 2, m->info->display_picture->nb_fields ) *
187 m->info->sequence->frame_period / 600;
189 else
191 buf->start = -1;
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");
205 if( flag & SKIP )
206 hb_log("MPEG2 Flag: Skip!");
207 if( flag & TAGS )
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.");
229 cadence[0] = BT;
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.");
237 cadence[0] = TB;
239 else if ( (flag & PROGRESSIVE) && !(flag & TOP_FIRST) && !( flag & REPEAT_FIRST ) )
241 /* Progressive, but noting else.
242 That means Bottom first,
243 2 fields displayed.
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,
252 3 fields displayed.
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,
261 2 fields displayed.
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,
270 3 fields displayed.
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 );
292 return 1;
295 /**********************************************************************
296 * hb_libmpeg2_info
297 **********************************************************************
299 *********************************************************************/
300 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
301 int * rate, int *aspect_ratio )
303 *width = m->width;
304 *height = m->height;
305 if( (m->info->display_picture->flags & PROGRESSIVE) && (m->height == 480) )
307 /* The frame is progressive and it's NTSC DVD height, so change its FPS to 23.976.
308 This might not be correct for the title. It's really just for scan.c's benefit.
309 Scan.c will reset the fps to 29.97, until a simple majority of the preview
310 frames report at 23.976.
312 //hb_log("Detecting NTSC Progressive Frame");
313 m->rate = 1126125;
315 *rate = m->rate;
316 *aspect_ratio = m->aspect_ratio;
319 /**********************************************************************
320 * hb_libmpeg2_close
321 **********************************************************************
323 *********************************************************************/
324 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
326 hb_libmpeg2_t * m = *_m;
328 mpeg2_close( m->libmpeg2 );
330 free( m );
331 *_m = NULL;
334 /**********************************************************************
335 * The decmpeg2 work object
336 **********************************************************************
338 *********************************************************************/
339 struct hb_work_private_s
341 hb_libmpeg2_t * libmpeg2;
342 hb_list_t * list;
345 /**********************************************************************
346 * hb_work_decmpeg2_init
347 **********************************************************************
349 *********************************************************************/
350 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
352 hb_work_private_t * pv;
354 pv = calloc( 1, sizeof( hb_work_private_t ) );
355 w->private_data = pv;
357 pv->libmpeg2 = hb_libmpeg2_init();
358 pv->list = hb_list_init();
360 return 0;
363 /**********************************************************************
364 * Work
365 **********************************************************************
367 *********************************************************************/
368 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
369 hb_buffer_t ** buf_out )
371 hb_work_private_t * pv = w->private_data;
372 hb_buffer_t * buf, * last = NULL;
374 // The reader found a chapter break, consume it completely, and remove it from the
375 // stream. We need to shift it.
376 if( (*buf_in)->new_chap )
378 printf("MPEG2: Chapter Break Cell Found, searching for GOP\n");
379 pv->libmpeg2->look_for_break = 2;
380 (*buf_in)->new_chap = 0;
383 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
385 *buf_out = NULL;
386 while( ( buf = hb_list_item( pv->list, 0 ) ) )
388 hb_list_rem( pv->list, buf );
389 if( last )
391 last->next = buf;
392 last = buf;
394 else
396 *buf_out = buf;
397 last = buf;
401 return HB_WORK_OK;
404 /**********************************************************************
405 * Close
406 **********************************************************************
408 *********************************************************************/
409 void decmpeg2Close( hb_work_object_t * w )
411 hb_work_private_t * pv = w->private_data;
412 hb_list_close( &pv->list );
413 hb_libmpeg2_close( &pv->libmpeg2 );
414 free( pv );
417 hb_work_object_t hb_decmpeg2 =
419 WORK_DECMPEG2,
420 "MPEG-2 decoder (libmpeg2)",
421 decmpeg2Init,
422 decmpeg2Work,
423 decmpeg2Close