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 /**********************************************************************
13 **********************************************************************
14 * A convenient libmpeg wrapper, used both here and in scan.c
15 *********************************************************************/
18 mpeg2dec_t * libmpeg2;
19 const mpeg2_info_t * info;
27 /**********************************************************************
29 **********************************************************************
31 *********************************************************************/
32 hb_libmpeg2_t * hb_libmpeg2_init()
34 hb_libmpeg2_t * m = calloc( sizeof( hb_libmpeg2_t ), 1 );
36 m->libmpeg2 = mpeg2_init();
37 m->info = mpeg2_info( m->libmpeg2 );
43 /**********************************************************************
45 **********************************************************************
47 *********************************************************************/
48 int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
49 hb_list_t * list_raw )
56 if( buf_es->start > -1 )
58 mpeg2_tag_picture( m->libmpeg2, buf_es->start >> 32,
59 buf_es->start & 0xFFFFFFFF );
61 mpeg2_buffer( m->libmpeg2, buf_es->data,
62 buf_es->data + buf_es->size );
66 state = mpeg2_parse( m->libmpeg2 );
67 if( state == STATE_BUFFER )
69 /* Require some more data */
72 else if( state == STATE_SEQUENCE )
74 if( !( m->width && m->height && m->rate ) )
76 m->width = m->info->sequence->width;
77 m->height = m->info->sequence->height;
78 m->rate = m->info->sequence->frame_period;
80 if( m->rate == 900900 )
82 /* 29.97 fps. 3:2 pulldown might, or might not be
83 used. I can't find a way to know, so we always
89 else if( ( state == STATE_SLICE || state == STATE_END ) &&
90 m->info->display_fbuf )
92 if( ( m->info->display_picture->flags &
93 PIC_MASK_CODING_TYPE ) == PIC_FLAG_CODING_TYPE_I )
100 buf = hb_buffer_init( m->width * m->height * 3 / 2 );
103 memcpy( data, m->info->display_fbuf->buf[0],
104 m->width * m->height );
105 data += m->width * m->height;
106 memcpy( data, m->info->display_fbuf->buf[1],
107 m->width * m->height / 4 );
108 data += m->width * m->height / 4;
109 memcpy( data, m->info->display_fbuf->buf[2],
110 m->width * m->height / 4 );
112 if( m->info->display_picture->flags & PIC_FLAG_TAGS )
115 ( (uint64_t) m->info->display_picture->tag << 32 ) |
116 ( (uint64_t) m->info->display_picture->tag2 );
118 else if( m->last_pts > -1 )
120 /* For some reason nb_fields is sometimes 1 while it
122 buf->start = m->last_pts +
123 MAX( 2, m->info->display_picture->nb_fields ) *
124 m->info->sequence->frame_period / 600;
130 m->last_pts = buf->start;
132 hb_list_add( list_raw, buf );
135 else if( state == STATE_INVALID )
137 mpeg2_reset( m->libmpeg2, 0 );
143 /**********************************************************************
145 **********************************************************************
147 *********************************************************************/
148 void hb_libmpeg2_info( hb_libmpeg2_t * m, int * width, int * height,
156 /**********************************************************************
158 **********************************************************************
160 *********************************************************************/
161 void hb_libmpeg2_close( hb_libmpeg2_t ** _m )
163 hb_libmpeg2_t * m = *_m;
165 mpeg2_close( m->libmpeg2 );
171 /**********************************************************************
172 * The decmpeg2 work object
173 **********************************************************************
175 *********************************************************************/
176 struct hb_work_object_s
180 hb_libmpeg2_t * libmpeg2;
184 /***********************************************************************
186 **********************************************************************/
187 static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
188 hb_buffer_t ** buf_out );
189 static void Close( hb_work_object_t ** _w );
191 /**********************************************************************
192 * hb_work_decmpeg2_init
193 **********************************************************************
195 *********************************************************************/
196 hb_work_object_t * hb_work_decmpeg2_init( hb_job_t * job )
198 hb_work_object_t * w = calloc( sizeof( hb_work_object_t ), 1 );
199 w->name = strdup( "MPEG-2 decoder (libmpeg2)" );
203 w->libmpeg2 = hb_libmpeg2_init();
204 w->list = hb_list_init();
208 /**********************************************************************
210 **********************************************************************
212 *********************************************************************/
213 static int Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
214 hb_buffer_t ** buf_out )
216 hb_buffer_t * buf, * last = NULL;
218 hb_libmpeg2_decode( w->libmpeg2, *buf_in, w->list );
222 while( ( buf = hb_list_item( w->list, 0 ) ) )
224 hb_list_rem( w->list, buf );
240 /**********************************************************************
242 **********************************************************************
244 *********************************************************************/
245 static void Close( hb_work_object_t ** _w )
247 hb_work_object_t * w = *_w;
248 hb_list_close( &w->list );
249 hb_libmpeg2_close( &w->libmpeg2 );