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