1 /*
2  *
3  *  This file is part of libmpeg3
4  *
5  * LibMPEG3
6  * Author: Adam Williams <broadcast@earthling.net>
7  * Page: heroine.linuxbox.com
8  * Page: http://www.smalltalkconsulting.com/html/mpeg3source.html (for Squeak)
9  *
10     LibMPEG3 was originally licenced under GPL. It was relicensed by
11     the author under the LGPL and the Squeak license on Nov 1st, 2000
12 
13     This library is free software; you can redistribute it and/or
14     modify it under the terms of the GNU Lesser General Public
15     License as published by the Free Software Foundation; either
16     version 2.1 of the License, or (at your option) any later version.
17 
18     This library is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21     Lesser General Public License for more details.
22 
23     You should have received a copy of the GNU Lesser General Public
24     License along with this library; if not, write to the Free Software
25     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 
27     Also licensed under the Squeak license.
28     http://www.squeak.org/license.html
29  */
30  /*  Changed Sept 15th by John M McIntosh to support Macintosh & Squeak
31  */
32 #include "mpeg3private.h"
33 #include "mpeg3protos.h"
34 
35 #include "mpeg3video.h"
36 #include "mpeg3videoprotos.h"
37 #include <stdlib.h>
38 
39 unsigned char mpeg3_zig_zag_scan_mmx[64] =
40 {
41     0*8+0 /* 0*/, 1*8+0 /* 1*/, 0*8+1 /* 8*/, 0*8+2 /*16*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 3*8+0 /* 3*/, 2*8+1 /*10*/,
42     1*8+2 /*17*/, 0*8+3 /*24*/, 0*8+4 /*32*/, 1*8+3 /*25*/, 2*8+2 /*18*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 5*8+0 /* 5*/,
43     4*8+1 /*12*/, 5*8+2 /*19*/, 2*8+3 /*26*/, 1*8+4 /*33*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 1*8+5 /*41*/, 2*8+4 /*34*/,
44     3*8+3 /*27*/, 4*8+2 /*20*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 7*8+0 /* 7*/, 6*8+1 /*14*/, 5*8+2 /*21*/, 4*8+3 /*28*/,
45     3*8+4 /*35*/, 2*8+5 /*42*/, 1*8+6 /*49*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 2*8+6 /*50*/, 3*8+5 /*43*/, 4*8+4 /*36*/,
46     5*8+3 /*29*/, 6*8+2 /*22*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 6*8+3 /*30*/, 5*8+4 /*37*/, 4*8+5 /*44*/, 3*8+6 /*51*/,
47     2*8+7 /*58*/, 3*8+7 /*59*/, 4*8+6 /*52*/, 5*8+5 /*45*/, 6*8+4 /*38*/, 7*8+3 /*31*/, 7*8+4 /*39*/, 6*8+5 /*46*/,
48     7*8+6 /*53*/, 4*8+7 /*60*/, 5*8+7 /*61*/, 6*8+6 /*54*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 6*8+7 /*62*/, 7*8+7 /*63*/
49 };
50 
51 /* alternate scan */
52 unsigned char mpeg3_alternate_scan_mmx[64] =
53 {
54      0*8+0 /*0 */, 0*8+1 /* 8*/, 0*8+2 /*16*/, 0*8+3 /*24*/, 1*8+0 /* 1*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 2*8+1 /*10*/,
55      1*8+2 /*17*/, 1*8+3 /*25*/, 0*8+4 /*32*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 1*8+6 /*49*/,
56      1*8+5 /*41*/, 1*8+4 /*33*/, 2*8+3 /*26*/, 2*8+2 /*18*/, 3*8+0 /* 3*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 4*8+1 /*12*/,
57      3*8+2 /*19*/, 3*8+3 /*27*/, 2*8+4 /*34*/, 2*8+5 /*42*/, 2*8+6 /*50*/, 2*8+7 /*58*/, 3*8+4 /*35*/, 3*8+5 /*43*/,
58      3*8+6 /*51*/, 3*8+7 /*59*/, 4*8+2 /*20*/, 4*8+3 /*28*/, 5*8+0 /* 5*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 6*8+1 /*14*/,
59      5*8+2 /*21*/, 5*8+3 /*29*/, 4*8+4 /*36*/, 4*8+5 /*44*/, 4*8+6 /*52*/, 4*8+7 /*60*/, 5*8+4 /*37*/, 5*8+5 /*45*/,
60      5*8+6 /*53*/, 5*8+7 /*61*/, 6*8+2 /*22*/, 6*8+3 /*30*/, 7*8+0 /* 7*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 7*8+3 /*31*/,
61      6*8+4 /*38*/, 6*8+5 /*46*/, 6*8+6 /*54*/, 6*8+7 /*62*/, 7*8+4 /*39*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 7*8+6 /*63*/
62 };
63 
64 
65 
66 /* zig-zag scan */
67 unsigned char mpeg3_zig_zag_scan_nommx[64] =
68 {
69   0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
70   12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
71   35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
72   58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
73 };
74 
75 /* alternate scan */
76 unsigned char mpeg3_alternate_scan_nommx[64] =
77 {
78   0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49,
79   41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43,
80   51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45,
81   53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63
82 };
83 
84 /* default intra quantization matrix */
85 unsigned char mpeg3_default_intra_quantizer_matrix[64] =
86 {
87   8, 16, 19, 22, 26, 27, 29, 34,
88   16, 16, 22, 24, 27, 29, 34, 37,
89   19, 22, 26, 27, 29, 34, 34, 38,
90   22, 22, 26, 27, 29, 34, 37, 40,
91   22, 26, 27, 29, 32, 35, 40, 48,
92   26, 27, 29, 32, 35, 40, 48, 58,
93   26, 27, 29, 34, 38, 46, 56, 69,
94   27, 29, 35, 38, 46, 56, 69, 83
95 };
96 
97 unsigned char mpeg3_non_linear_mquant_table[32] =
98 {
99    0, 1, 2, 3, 4, 5, 6, 7,
100    8, 10, 12, 14, 16, 18, 20, 22,
101   24, 28, 32, 36, 40, 44, 48, 52,
102   56, 64, 72, 80, 88, 96, 104, 112
103 };
104 
105 double mpeg3_frame_rate_table[16] =
106 {
107   0.0,   /* Pad */
108   24000.0/1001.0,       /* Official frame rates */
109   24.0,
110   25.0,
111   30000.0/1001.0,
112   30.0,
113   50.0,
114   ((60.0*1000.0)/1001.0),
115   60.0,
116 
117   1,                    /* Unofficial economy rates */
118   5,
119   10,
120   12,
121   15,
122   0,
123   0,
124 };
125 
mpeg3video_initdecoder(mpeg3video_t * video)126 int mpeg3video_initdecoder(mpeg3video_t *video)
127 {
128 	int blk_cnt_tab[3] = {6, 8, 12};
129 	int cc;
130   	int i;
131 	long size[4], padding[2];         /* Size of Y, U, and V buffers */
132 
133 	if(!video->mpeg2)
134 	{
135 /* force MPEG-1 parameters */
136     	video->prog_seq = 1;
137     	video->prog_frame = 1;
138     	video->pict_struct = FRAME_PICTURE;
139     	video->frame_pred_dct = 1;
140     	video->chroma_format = CHROMA420;
141     	video->matrix_coefficients = 5;
142 	}
143 
144 /* Get dimensions rounded to nearest multiple of coded macroblocks */
145 	video->mb_width = (video->horizontal_size + 15) / 16;
146 	video->mb_height = (video->mpeg2 && !video->prog_seq) ?
147 					(2 * ((video->vertical_size + 31) / 32)) :
148 					((video->vertical_size + 15) / 16);
149 	video->coded_picture_width = 16 * video->mb_width;
150 	video->coded_picture_height = 16 * video->mb_height;
151 	video->chrom_width = (video->chroma_format == CHROMA444) ?
152 					video->coded_picture_width :
153 					(video->coded_picture_width >> 1);
154 	video->chrom_height = (video->chroma_format != CHROMA420) ?
155 					video->coded_picture_height :
156                     (video->coded_picture_height >> 1);
157 	video->blk_cnt = blk_cnt_tab[video->chroma_format - 1];
158 
159 /* Get sizes of YUV buffers */
160 	padding[0] = 16 * video->coded_picture_width;
161 	size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2;
162 
163 	padding[1] = 16 * video->chrom_width;
164 	size[1] = video->chrom_width * video->chrom_height + 2 * padding[1];
165 
166 	size[2] = (video->llw * video->llh);
167 	size[3] = (video->llw * video->llh) / 4;
168 
169 /* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
170 	video->yuv_buffer[0] = (unsigned char*)memoryAllocate(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
171 	video->yuv_buffer[1] = (unsigned char*)memoryAllocate(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
172 	video->yuv_buffer[2] = (unsigned char*)memoryAllocate(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
173 
174     if(video->scalable_mode == SC_SPAT)
175 	{
176 		video->yuv_buffer[3] = (unsigned char*)memoryAllocate(1, size[2] + 2 * size[3]);
177 		video->yuv_buffer[4] = (unsigned char*)memoryAllocate(1, size[2] + 2 * size[3]);
178 	}
179 
180 /* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */
181 	for(cc = 0; cc < 3; cc++)
182 	{
183 		video->llframe0[cc] = 0;
184 		video->llframe1[cc] = 0;
185 		video->newframe[cc] = 0;
186 	}
187 
188 	video->refframe[0]    = video->yuv_buffer[0];
189 	video->oldrefframe[0] = video->yuv_buffer[1];
190 	video->auxframe[0]    = video->yuv_buffer[2];
191 	video->refframe[2]    = video->yuv_buffer[0] + size[0] + padding[0];
192 	video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0];
193 	video->auxframe[2]    = video->yuv_buffer[2] + size[0] + padding[0];
194 	video->refframe[1]    = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1];
195 	video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1];
196 	video->auxframe[1]    = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1];
197 
198     if(video->scalable_mode == SC_SPAT)
199 	{
200 /* this assumes lower layer is 4:2:0 */
201 		video->llframe0[0] = video->yuv_buffer[3] + padding[0] 				   ;
202 		video->llframe1[0] = video->yuv_buffer[4] + padding[0] 				   ;
203 		video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2]		   ;
204 		video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2]		   ;
205 		video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3];
206 		video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3];
207     }
208 
209 /* Initialize the YUV tables for software YUV decoding */
210 	video->cr_to_r = (long *) memoryAllocate(1,sizeof(long) * 256);
211 	video->cr_to_g = (long *) memoryAllocate(1,sizeof(long) * 256);
212 	video->cb_to_g = (long *) memoryAllocate(1,sizeof(long) * 256);
213 	video->cb_to_b = (long *) memoryAllocate(1,sizeof(long) * 256);
214 	video->cr_to_r_ptr = video->cr_to_r + 128;
215 	video->cr_to_g_ptr = video->cr_to_g + 128;
216 	video->cb_to_g_ptr = video->cb_to_g + 128;
217 	video->cb_to_b_ptr = video->cb_to_b + 128;
218 
219 	for(i = -128; i < 128; i++)
220 	{
221 		video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i);
222 		video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i);
223 		video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i);
224 		video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i);
225 	}
226 
227 	return 0;
228 }
229 
mpeg3video_deletedecoder(mpeg3video_t * video)230 int mpeg3video_deletedecoder(mpeg3video_t *video)
231 {
232 	int i, padding;
233 
234 	memoryFree(video->yuv_buffer[0]);
235 	memoryFree(video->yuv_buffer[1]);
236 	memoryFree(video->yuv_buffer[2]);
237 
238 	if(video->llframe0[0])
239 	{
240 		memoryFree(video->yuv_buffer[3]);
241 		memoryFree(video->yuv_buffer[4]);
242 	}
243 
244 	memoryFree(video->cr_to_r);
245 	memoryFree(video->cr_to_g);
246 	memoryFree(video->cb_to_g);
247 	memoryFree(video->cb_to_b);
248 	return 0;
249 }
250 
mpeg3video_init_scantables(mpeg3video_t * video)251 void mpeg3video_init_scantables(mpeg3video_t *video)
252 {
253 #ifdef HAVE_MMX
254 	if(video->have_mmx)
255 	{
256 		video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx;
257 		video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx;
258 	}
259 	else
260 #endif
261 	{
262 		video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx;
263 		video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx;
264 	}
265 }
266 
mpeg3video_allocate_struct(mpeg3_t * file,mpeg3_vtrack_t * track)267 mpeg3video_t* mpeg3video_allocate_struct(mpeg3_t *file, mpeg3_vtrack_t *track)
268 {
269 	int i;
270 	mpeg3video_t *video = (mpeg3video_t *) memoryAllocate(1, sizeof(mpeg3video_t));
271 
272 #ifdef USE_PTHREADS
273 	pthread_mutexattr_t mutex_attr;
274 #endif
275 
276 	video->file = file;
277 	video->track = track;
278 	video->vstream = mpeg3bits_new_stream(file, track->demuxer);
279 	video->last_number = -1;
280 
281 /* First frame is all green */
282 	video->framenum = -1;
283 	video->have_mmx = file->have_mmx;
284 
285 	video->percentage_seek = -1;
286 	video->frame_seek = -1;
287 
288 	mpeg3video_init_scantables(video);
289 	mpeg3video_init_output();
290 
291 #ifdef USE_PTHREADS
292 	pthread_mutexattr_init(&mutex_attr);
293 	pthread_mutex_init(&(video->test_lock), &mutex_attr);
294 	pthread_mutex_init(&(video->slice_lock), &mutex_attr);
295 #endif
296 	return video;
297 }
298 
mpeg3video_delete_struct(mpeg3video_t * video)299 int mpeg3video_delete_struct(mpeg3video_t *video)
300 {
301 	int i;
302 	mpeg3bits_delete_stream(video->vstream);
303 #ifdef USE_PTHREADS
304 	pthread_mutex_destroy(&(video->test_lock));
305 	pthread_mutex_destroy(&(video->slice_lock));
306 #endif
307 	if(video->x_table)
308 	{
309 		memoryFree(video->x_table);
310 		memoryFree(video->y_table);
311 	}
312 	if(video->total_slice_decoders)
313 	{
314 		for(i = 0; i < video->total_slice_decoders; i++)
315 			mpeg3_delete_slice_decoder(video->slice_decoders[i]);
316 	}
317 	for(i = 0; i < video->slice_buffers_initialized; i++)
318 		mpeg3_delete_slice_buffer(&(video->slice_buffers[i]));
319 
320 	memoryFree(video);
321 }
322 
323 
mpeg3video_read_frame_backend(mpeg3video_t * video,int skip_bframes)324 int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes)
325 {
326 	int result = 0;
327 
328 	if(mpeg3bits_eof(video->vstream)) result = 1;
329 
330 	if(!result) result = mpeg3video_get_header(video, 0);
331 
332 //printf("frame type %d\n", video->pict_type);
333 /* skip_bframes is the number of bframes we can skip successfully. */
334 /* This is in case a skipped B-frame is repeated and the second repeat happens */
335 /* to be a B frame we need. */
336 	video->skip_bframes = skip_bframes;
337 
338 	if(!result)
339 		result = mpeg3video_getpicture(video, video->framenum);
340 
341 #ifdef HAVE_MMX
342 	if(video->have_mmx)
343 		__asm__ __volatile__ ("emms");
344 #endif
345 
346 	if(!result)
347 	{
348 		video->last_number = video->framenum;
349 		video->framenum++;
350 	}
351 	return result;
352 }
353 
mpeg3video_get_scaletable(int input_w,int output_w)354 int* mpeg3video_get_scaletable(int input_w, int output_w)
355 {
356 	int *result = (int *) memoryAllocate(1,sizeof(int) * output_w);
357 	float i;
358 	float scale = (float)input_w / output_w;
359 	for(i = 0; i < output_w; i++)
360 	{
361 		result[(int)i] = (int)(scale * i);
362 	}
363 	return result;
364 }
365 
366 /* Get the first frame read. */
mpeg3video_get_firstframe(mpeg3video_t * video)367 int mpeg3video_get_firstframe(mpeg3video_t *video)
368 {
369 	int result = 0;
370 	if(video->framenum < 0)
371 	{
372 		video->repeat_count = video->current_repeat = 0;
373 		result = mpeg3video_read_frame_backend(video, 0);
374 		mpeg3bits_seek_byte(video->vstream, 0);
375 		mpeg3video_match_refframes(video);
376 	}
377 	return result;
378 }
379 
380 
381 /* ======================================================================= */
382 /*                                    ENTRY POINTS */
383 /* ======================================================================= */
384 
385 
386 
mpeg3video_new(mpeg3_t * file,mpeg3_vtrack_t * track)387 mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track)
388 {
389 	mpeg3video_t *video;
390 	int result = 0;
391 
392 	video = mpeg3video_allocate_struct(file, track);
393 	result = mpeg3video_get_header(video, 1);
394 
395 	if(!result)
396 	{
397 		int hour, minute, second, frame;
398 		int gop_found;
399 
400 		mpeg3video_initdecoder(video);
401 		video->decoder_initted = 1;
402 		track->width = video->horizontal_size;
403 		track->height = video->vertical_size;
404 		track->frame_rate = video->frame_rate;
405 
406 /* Get the length of the file from an elementary stream */
407 		if(file->is_video_stream)
408 		{
409 /* Load the first GOP */
410 			mpeg3bits_seek_start(video->vstream);
411 			result = mpeg3video_next_code(video->vstream, MPEG3_GOP_START_CODE);
412 			if(!result) mpeg3bits_getbits(video->vstream, 32);
413 			if(!result) result = mpeg3video_getgophdr(video);
414 
415 			hour = video->gop_timecode.hour;
416 			minute = video->gop_timecode.minute;
417 			second = video->gop_timecode.second;
418 			frame = video->gop_timecode.frame;
419 			video->first_frame = (long)(hour * 3600 * video->frame_rate +
420 				minute * 60 * video->frame_rate +
421 				second * video->frame_rate +
422 				frame);
423 
424 /* GOPs always have 16 frames */
425 			video->frames_per_gop = 16;
426 
427 /* Read the last GOP in the file by seeking backward. */
428 			mpeg3bits_seek_end(video->vstream);
429 			mpeg3bits_start_reverse(video->vstream);
430 			result = mpeg3video_prev_code(video->vstream, MPEG3_GOP_START_CODE);
431 			mpeg3bits_start_forward(video->vstream);
432 			mpeg3bits_getbits(video->vstream, 8);
433 			if(!result) result = mpeg3video_getgophdr(video);
434 
435 			hour = video->gop_timecode.hour;
436 			minute = video->gop_timecode.minute;
437 			second = video->gop_timecode.second;
438 			frame = video->gop_timecode.frame;
439 
440 			video->last_frame = (long)(hour * 3600 * video->frame_rate +
441 				minute * 60 * video->frame_rate +
442 				second * video->frame_rate +
443 				frame);
444 
445 /* Count number of frames to end */
446 			while(!result)
447 			{
448 				result = mpeg3video_next_code(video->vstream, MPEG3_PICTURE_START_CODE);
449 				if(!result)
450 				{
451 					mpeg3bits_getbyte_noptr(video->vstream);
452 					video->last_frame++;
453 				}
454 			}
455 
456 			track->total_frames = video->last_frame - video->first_frame + 1;
457 			mpeg3bits_seek_start(video->vstream);
458 		}
459 		else
460 		{
461 /* Gross approximation from a multiplexed file. */
462 			video->first_frame = 0;
463 			track->total_frames = video->last_frame =
464 				(long)(mpeg3demux_length(video->vstream->demuxer) *
465 					video->frame_rate);
466 			video->first_frame = 0;
467 		}
468 
469 		video->maxframe = track->total_frames;
470 		mpeg3bits_seek_start(video->vstream);
471 	}
472 	else
473 	{
474 		mpeg3video_delete(video);
475 		video = 0;
476 	}
477 
478 	return video;
479 }
480 
mpeg3video_delete(mpeg3video_t * video)481 int mpeg3video_delete(mpeg3video_t *video)
482 {
483 	if(video->decoder_initted)
484 	{
485 		mpeg3video_deletedecoder(video);
486 	}
487 	mpeg3video_delete_struct(video);
488 	return 0;
489 }
490 
mpeg3video_set_cpus(mpeg3video_t * video,int cpus)491 int mpeg3video_set_cpus(mpeg3video_t *video, int cpus)
492 {
493 	return 0;
494 }
495 
mpeg3video_set_mmx(mpeg3video_t * video,int use_mmx)496 int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx)
497 {
498 	video->have_mmx = use_mmx;
499 	mpeg3video_init_scantables(video);
500 	return 0;
501 }
502 
mpeg3video_seek_percentage(mpeg3video_t * video,double percentage)503 int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage)
504 {
505 	video->percentage_seek = percentage;
506 	return 0;
507 }
508 
mpeg3video_previous_frame(mpeg3video_t * video)509 int mpeg3video_previous_frame(mpeg3video_t *video)
510 {
511 	if(mpeg3bits_tell_percentage(video->vstream) <= 0) return 1;
512 	mpeg3bits_start_reverse(video->vstream);
513 	mpeg3video_prev_code(video->vstream, MPEG3_PICTURE_START_CODE);
514 	mpeg3bits_getbits_reverse(video->vstream, 32);
515 
516 	if(mpeg3bits_bof(video->vstream)) mpeg3bits_seek_percentage(video->vstream, 0);
517 	mpeg3bits_start_forward(video->vstream);
518 	video->repeat_count = 0;
519 	return 0;
520 }
521 
mpeg3video_seek_frame(mpeg3video_t * video,long frame)522 int mpeg3video_seek_frame(mpeg3video_t *video, long frame)
523 {
524 	video->frame_seek = frame;
525 	return 0;
526 }
527 
528 /* Read all the way up to and including the next picture start code */
mpeg3video_read_raw(mpeg3video_t * video,unsigned char * output,long * size,long max_size)529 int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size)
530 {
531 	unsigned MPEG3_INT32 code = 0;
532 	mpeg3_bits_t *vstream = video->vstream;
533 
534 	*size = 0;
535 	while(code != MPEG3_PICTURE_START_CODE &&
536 		code != MPEG3_SEQUENCE_END_CODE &&
537 		*size < max_size &&
538 		!mpeg3bits_eof(vstream))
539 	{
540 		code <<= 8;
541 		*output = mpeg3bits_getbyte_noptr(vstream);
542 		code |= *output++;
543 		(*size)++;
544 	}
545 	return mpeg3bits_eof(vstream);
546 }
547 
mpeg3video_read_frame(mpeg3video_t * video,long frame_number,unsigned char ** output_rows,int in_x,int in_y,int in_w,int in_h,int out_w,int out_h,int color_model)548 int mpeg3video_read_frame(mpeg3video_t *video,
549 		long frame_number,
550 		unsigned char **output_rows,
551 		int in_x,
552 		int in_y,
553 		int in_w,
554 		int in_h,
555 		int out_w,
556 		int out_h,
557 		int color_model)
558 {
559 	int result = 0;
560 
561 	video->want_yvu = 0;
562 	video->output_rows = output_rows;
563 	video->color_model = color_model;
564 
565 /* Get scaling tables */
566 	if(video->out_w != out_w || video->out_h != out_h ||
567 		video->in_w != in_w || video->in_h != in_h ||
568 		video->in_x != in_x || video->in_y != in_y)
569 	{
570 		if(video->x_table)
571 		{
572 			memoryFree(video->x_table);
573 			memoryFree(video->y_table);
574 			video->x_table = 0;
575 			video->y_table = 0;
576 		}
577 	}
578 
579 	video->out_w = out_w;
580 	video->out_h = out_h;
581 	video->in_w = in_w;
582 	video->in_h = in_h;
583 	video->in_x = in_x;
584 	video->in_y = in_y;
585 
586 	if(!video->x_table)
587 	{
588 		video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w);
589 		video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h);
590 	}
591 
592 	mpeg3video_get_firstframe(video);
593 
594 	if(!result) result = mpeg3video_seek(video);
595 
596 	if(!result) result = mpeg3video_read_frame_backend(video, 0);
597 
598 	if(video->output_src) mpeg3video_present_frame(video);
599 
600 	video->percentage_seek = -1;
601 	return result;
602 }
603 
mpeg3video_read_yuvframe(mpeg3video_t * video,long frame_number,char * y_output,char * u_output,char * v_output,int in_x,int in_y,int in_w,int in_h)604 int mpeg3video_read_yuvframe(mpeg3video_t *video,
605 					long frame_number,
606 					char *y_output,
607 					char *u_output,
608 					char *v_output,
609 					int in_x,
610 					int in_y,
611 					int in_w,
612 					int in_h)
613 {
614 	int result = 0;
615 
616 	video->want_yvu = 1;
617 	video->y_output = y_output;
618 	video->u_output = u_output;
619 	video->v_output = v_output;
620 	video->in_x = in_x;
621 	video->in_y = in_y;
622 	video->in_w = in_w;
623 	video->in_h = in_h;
624 
625 	mpeg3video_get_firstframe(video);
626 
627 	if(!result) result = mpeg3video_seek(video);
628 
629 	if(!result) result = mpeg3video_read_frame_backend(video, 0);
630 
631 	if(video->output_src) mpeg3video_present_frame(video);
632 
633 	video->want_yvu = 0;
634 	video->percentage_seek = -1;
635 	return result;
636 }
637