Patches mpeg4ip to write the compressor name correctly for h.264 (so it reads "AVC...
[HandBrake.git] / libhb / decmpeg2.c
blob65293c681e4494bdb8d5573f0fbb5c12dc35a878
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 /**********************************************************************
12 * hb_libmpeg2_t
13 **********************************************************************
14 * A convenient libmpeg wrapper, used both here and in scan.c
15 *********************************************************************/
16 struct hb_libmpeg2_s
18 mpeg2dec_t * libmpeg2;
19 const mpeg2_info_t * info;
20 int width;
21 int height;
22 int rate;
23 int aspect_ratio;
24 int got_iframe;
25 int look_for_break;
26 int64_t last_pts;
29 /**********************************************************************
30 * hb_libmpeg2_init
31 **********************************************************************
33 *********************************************************************/
34 hb_libmpeg2_t * hb_libmpeg2_init()
36 hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
38 m->libmpeg2 = mpeg2_init();
39 m->info = mpeg2_info( m->libmpeg2 );
40 m->last_pts = -1;
41 m->look_for_break = 0;
43 return m;
46 /**********************************************************************
47 * hb_libmpeg2_decode
48 **********************************************************************
50 *********************************************************************/
51 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
52 hb_list_t * list_raw )
54 mpeg2_state_t state;
55 hb_buffer_t * buf;
56 uint8_t * data;
57 int chap_break = 0;
59 /* Feed libmpeg2 */
60 if( buf_es->start > -1 )
62 mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
63 buf_es->start & 0xFFFFFFFF );
65 mpeg2_buffer( m->libmpeg2, buf_es->data,
66 buf_es->data + buf_es->size );
68 for( ;; )
70 state = mpeg2_parse( m->libmpeg2 );
71 if( state == STATE_BUFFER )
73 /* Require some more data */
74 break;
76 else if( state == STATE_SEQUENCE )
78 if( !( m->width && m->height && m->rate ) )
80 m->width = m->info->sequence->width;
81 m->height = m->info->sequence->height;
82 m->rate = m->info->sequence->frame_period;
84 if( m->rate == 900900 )
86 /* 29.97 fps. 3:2 pulldown might, or might not be
87 used. I can't find a way to know, so we always
88 output 23.976 */
89 m->rate = 1126125;
92 if ( m->aspect_ratio <= 0 )
94 // We can parse out the aspect ratio from the Sequence Start Header data in buf_es->data
96 // Make sure we have the correct data in the buffer
97 if ((buf_es->data[0] == 0x00) && (buf_es->data[1] == 0x00) && (buf_es->data[2] == 0x01) && (buf_es->data[3] == 0xb3))
99 unsigned char ar_fr = buf_es->data[7]; // Top 4 bits == aspect ratio flag - bottom 4 bits == rate flags
100 switch ((ar_fr & 0xf0) >> 4)
102 case 2:
103 m->aspect_ratio = HB_ASPECT_BASE * 4 / 3; // 4:3
104 break;
105 case 3:
106 m->aspect_ratio = HB_ASPECT_BASE * 16 / 9; // 16:9
107 break;
108 default:
109 hb_log("hb_libmpeg2_decode - STATE_SEQUENCE unexpected aspect ratio/frame rate 0x%x\n", ar_fr);
110 break;
115 else if( state == STATE_GOP && m->look_for_break == 2)
117 printf("MPEG2: Group of pictures found, searching for I-Frame\n");
118 m->look_for_break = 1;
120 else if( ( state == STATE_SLICE || state == STATE_END ) &&
121 m->info->display_fbuf )
123 if( ( m->info->display_picture->flags &
124 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
126 m->got_iframe = 1;
128 // If we are looking for a break, insert the chapter break on an I-Frame
129 if( m->look_for_break == 1 )
131 printf("MPEG2: I-Frame Found\n");
132 m->look_for_break = 0;
133 chap_break = 1;
137 if( m->got_iframe )
139 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
140 data = buf->data;
142 // Was a good break point found?
143 if( chap_break )
145 printf("MPEG2: Chapter Break Inserted\n");
146 chap_break = 0;
147 buf->new_chap = 1;
150 memcpy( data, m->info->display_fbuf->buf[0],
151 m->width * m->height );
152 data += m->width * m->height;
153 memcpy( data, m->info->display_fbuf->buf[1],
154 m->width * m->height / 4 );
155 data += m->width * m->height / 4;
156 memcpy( data, m->info->display_fbuf->buf[2],
157 m->width * m->height / 4 );
159 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
161 buf->start =
162 ( (uint64_t) m->info->display_picture->tag << 32 ) |
163 ( (uint64_t) m->info->display_picture->tag2 );
165 else if( m->last_pts > -1 )
167 /* For some reason nb_fields is sometimes 1 while it
168 should be 2 */
169 buf->start = m->last_pts +
170 MAX( 2, m->info->display_picture->nb_fields ) *
171 m->info->sequence->frame_period / 600;
173 else
175 buf->start = -1;
177 m->last_pts = buf->start;
179 hb_list_add( list_raw, buf );
182 else if( state == STATE_INVALID )
184 mpeg2_reset( m->libmpeg2, 0 );
187 return 1;
190 /**********************************************************************
191 * hb_libmpeg2_info
192 **********************************************************************
194 *********************************************************************/
195 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
196 int * rate, int *aspect_ratio )
198 *width = m->width;
199 *height = m->height;
200 *rate = m->rate;
201 *aspect_ratio = m->aspect_ratio;
204 /**********************************************************************
205 * hb_libmpeg2_close
206 **********************************************************************
208 *********************************************************************/
209 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
211 hb_libmpeg2_t * m = *_m;
213 mpeg2_close( m->libmpeg2 );
215 free( m );
216 *_m = NULL;
219 /**********************************************************************
220 * The decmpeg2 work object
221 **********************************************************************
223 *********************************************************************/
224 struct hb_work_private_s
226 hb_libmpeg2_t * libmpeg2;
227 hb_list_t * list;
230 /**********************************************************************
231 * hb_work_decmpeg2_init
232 **********************************************************************
234 *********************************************************************/
235 int decmpeg2Init( hb_work_object_t * w, hb_job_t * job )
237 hb_work_private_t * pv;
239 pv = calloc( 1, sizeof( hb_work_private_t ) );
240 w->private_data = pv;
242 pv->libmpeg2 = hb_libmpeg2_init();
243 pv->list = hb_list_init();
245 return 0;
248 /**********************************************************************
249 * Work
250 **********************************************************************
252 *********************************************************************/
253 int decmpeg2Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
254 hb_buffer_t ** buf_out )
256 hb_work_private_t * pv = w->private_data;
257 hb_buffer_t * buf, * last = NULL;
259 // The reader found a chapter break, consume it completely, and remove it from the
260 // stream. We need to shift it.
261 if( (*buf_in)->new_chap )
263 printf("MPEG2: Chapter Break Cell Found, searching for GOP\n");
264 pv->libmpeg2->look_for_break = 2;
265 (*buf_in)->new_chap = 0;
268 hb_libmpeg2_decode( pv->libmpeg2, *buf_in, pv->list );
270 *buf_out = NULL;
271 while( ( buf = hb_list_item( pv->list, 0 ) ) )
273 hb_list_rem( pv->list, buf );
274 if( last )
276 last->next = buf;
277 last = buf;
279 else
281 *buf_out = buf;
282 last = buf;
286 return HB_WORK_OK;
289 /**********************************************************************
290 * Close
291 **********************************************************************
293 *********************************************************************/
294 void decmpeg2Close( hb_work_object_t * w )
296 hb_work_private_t * pv = w->private_data;
297 hb_list_close( &pv->list );
298 hb_libmpeg2_close( &pv->libmpeg2 );
299 free( pv );
302 hb_work_object_t hb_decmpeg2 =
304 WORK_DECMPEG2,
305 "MPEG-2 decoder (libmpeg2)",
306 decmpeg2Init,
307 decmpeg2Work,
308 decmpeg2Close