r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / decore50 / decore.c
blobbc07b1efc4c3ee74cc4dfede018e0b24bc6b5261
1 /**************************************************************************
2 * *
3 * This code has been developed by Andrea Graziani. This software is an *
4 * implementation of a part of one or more MPEG-4 Video tools as *
5 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
6 * software module in hardware or software products are advised that its *
7 * use may infringe existing patents or copyrights, and any such use *
8 * would be at such party's own risk. The original developer of this *
9 * software module and his/her company, and subsequent editors and their *
10 * companies (including Project Mayo), will have no liability for use of *
11 * this software or modifications or derivatives thereof. *
12 * *
13 * Project Mayo gives users of the Codec a license to this software *
14 * module or modifications thereof for use in hardware or software *
15 * products claiming conformance to the MPEG-4 Video Standard as *
16 * described in the Open DivX license. *
17 * *
18 * The complete Open DivX license can be found at *
19 * http://www.projectmayo.com/opendivx/license.php *
20 * *
21 **************************************************************************/
22 /**
23 * Copyright (C) 2001 - Project Mayo
25 * Andrea Graziani
26 * Adam Li
27 * Jonathan White
29 * DivX Advanced Research Center <darc@projectmayo.com>
31 **/
32 // decore.c //
34 #include <stdio.h>
35 #include <stdlib.h>
37 #if ( (defined (WIN32)) && (! defined (_DECORE)) )
38 #include <string.h>
39 #include <io.h>
40 #include <fcntl.h>
41 #endif
43 #include "gen_usetime.h"
44 #include "debug.h"
45 #include "mp4_vars.h"
46 #include "getbits.h"
47 #include "yuv2rgb.h"
48 #include "decore.h"
50 /**
52 **/
54 /***/
56 static int flag_firstpicture = 1;
58 /***/
60 // Set global variables for a decoding session
61 void decore_set_global(DEC_PARAM *param)
63 DEC_BUFFERS *buffers;
64 int cc;
66 if(param)
68 buffers = &param->buffers;
69 mp4_state = (MP4_STATE*)buffers->mp4_state;
70 mp4_tables = (MP4_TABLES*)buffers->mp4_tables;
71 ld = (MP4_STREAM *)buffers->mp4_stream;
72 for(cc = 0; cc < 3; cc++)
74 edged_ref[cc] = buffers->edged_ref[cc];
75 edged_for[cc] = buffers->edged_for[cc];
76 frame_ref[cc] = buffers->frame_ref[cc];
77 frame_for[cc] = buffers->frame_for[cc];
78 display_frame[cc] = buffers->display_frame[cc];
83 void decore_save_global(DEC_PARAM *param)
85 DEC_BUFFERS *buffers;
86 int cc;
88 if(param)
90 buffers = &param->buffers;
91 buffers->mp4_state = mp4_state;
92 buffers->mp4_tables = mp4_tables;
93 buffers->mp4_stream = ld;
94 for(cc = 0; cc < 3; cc++)
96 buffers->edged_ref[cc] = edged_ref[cc];
97 buffers->edged_for[cc] = edged_for[cc];
98 buffers->frame_ref[cc] = frame_ref[cc];
99 buffers->frame_for[cc] = frame_for[cc];
100 buffers->display_frame[cc] = display_frame[cc];
105 static int mmx_test()
107 int result = 0;
108 FILE *proc;
109 char string[1024];
112 #ifdef ARCH_X86
113 if(!(proc = fopen("/proc/cpuinfo", "r")))
115 fprintf(stderr, "mmx_test: failed to open /proc/cpuinfo\n");
116 return 0;
119 while(!feof(proc))
121 fgets(string, 1024, proc);
122 /* Got the flags line */
123 if(!strncasecmp(string, "flags", 5))
125 char *needle;
126 needle = strstr(string, "mmx");
127 if(!needle)
129 fclose(proc);
130 return 0;
132 if(!strncasecmp(needle, "mmx", 3))
134 fclose(proc);
135 return 1;
139 fclose(proc);
140 #endif
142 return 0;
146 int STDCALL decore(unsigned long handle, unsigned long dec_opt,
147 void *param1, void *param2)
149 int cc;
154 * printf("decore 1 %p %p %p %p %p\n",
155 * edged_ref[0], edged_for[0], frame_ref[0], frame_for[0], display_frame[0]);
158 if (handle)
160 switch (dec_opt)
162 case DEC_OPT_MEMORY_REQS:
164 DEC_PARAM *dec_param = (DEC_PARAM *)param1;
165 DEC_MEM_REQS *dec_mem_reqs = (DEC_MEM_REQS *)param2;
167 int coded_y_size = ((dec_param->x_dim + 64) * (dec_param->y_dim + 64));
168 int coded_c_size = (((dec_param->x_dim>>1) + 64) * ((dec_param->y_dim>>1) + 64));
169 int display_y_size = (dec_param->x_dim * dec_param->y_dim);
170 int display_c_size = ((dec_param->x_dim * dec_param->y_dim) >> 2);
171 int edged_size = coded_y_size + (2 * coded_c_size);
172 int display_size = display_y_size + (2 * display_c_size);
174 dec_mem_reqs->mp4_edged_ref_buffers_size = edged_size;
175 dec_mem_reqs->mp4_edged_for_buffers_size = edged_size;
176 dec_mem_reqs->mp4_display_buffers_size = display_size;
177 dec_mem_reqs->mp4_state_size = sizeof(MP4_STATE);
178 dec_mem_reqs->mp4_tables_size = sizeof(MP4_TABLES);
179 dec_mem_reqs->mp4_stream_size = sizeof(MP4_STREAM);
181 return DEC_OK;
183 case DEC_OPT_INIT:
185 DEC_PARAM *dec_param = (DEC_PARAM *) param1;
187 // have_mmx = mmx_test();
188 decore_init(dec_param->x_dim,
189 dec_param->y_dim,
190 dec_param->output_format,
191 dec_param->time_incr,
192 dec_param->buffers); // init decoder resources
194 return DEC_OK;
196 break;
197 case DEC_OPT_RELEASE:
199 decore_release();
201 return DEC_OK;
203 break;
204 case DEC_OPT_SETPP:
206 DEC_SET *dec_set = (DEC_SET *) param1;
207 int postproc_level = dec_set->postproc_level;
209 if ((postproc_level < 0) | (postproc_level > 100))
210 return DEC_BAD_FORMAT;
212 if (postproc_level < 1)
214 mp4_state->post_flag = 0;
216 return DEC_OK;
218 else
220 mp4_state->post_flag = 1;
222 if (postproc_level < 10) {
223 mp4_state->pp_options = PP_DEBLOCK_Y_H;
225 else if (postproc_level < 20) {
226 mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V;
228 else if (postproc_level < 30) {
229 mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y;
231 else if (postproc_level < 40) {
232 mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | PP_DEBLOCK_C_H;
234 else if (postproc_level < 50) {
235 mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y |
236 PP_DEBLOCK_C_H | PP_DEBLOCK_C_V;
238 else {
239 mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y |
240 PP_DEBLOCK_C_H | PP_DEBLOCK_C_V | PP_DERING_C;
244 return DEC_OK;
246 break;
247 case DEC_OPT_SETOUT:
249 DEC_PARAM *dec_param = (DEC_PARAM *) param1;
251 decore_setoutput(dec_param->output_format);
253 return DEC_OK;
255 break;
256 default:
258 DEC_FRAME *dec_frame = (DEC_FRAME *) param1;
261 if (decore_frame(dec_frame->bitstream, dec_frame->length,
262 dec_frame->bmp, dec_frame->stride, dec_frame->render_flag))
265 * printf("decore 2 %p %p %p %p %p\n",
266 * edged_ref[0], edged_for[0], frame_ref[0], frame_for[0], display_frame[0]);
268 return DEC_OK;
270 else
272 return DEC_EXIT;
275 break;
278 return DEC_BAD_FORMAT;
281 /***/
283 int decore_alloc(DEC_BUFFERS buffers);
285 static int decore_init(int hor_size,
286 int ver_size,
287 int output_format,
288 int time_inc,
289 DEC_BUFFERS buffers)
291 mp4_state = (MP4_STATE *) buffers.mp4_state;
292 mp4_tables = (MP4_TABLES *) buffers.mp4_tables;
293 ld = (MP4_STREAM *) buffers.mp4_stream;
295 #ifndef _DECORE
296 // open input file
297 if ((ld->infile = open (mp4_state->infilename, O_RDONLY | O_BINARY)) < 0) {
298 _Print ("Input file %s not found\n", mp4_state->infilename);
299 exit(91);
301 initbits (NULL, 0);
302 mp4_state->juice_flag = 0;
303 #else
304 mp4_state->juice_flag = 1;
305 #endif // _DECORE
307 mp4_state->post_flag = 0;
309 // read first vol and vop
310 mp4_state->hdr.width = hor_size;
311 mp4_state->hdr.height = ver_size;
313 mp4_state->hdr.quant_precision = 5;
314 mp4_state->hdr.bits_per_pixel = 8;
316 mp4_state->hdr.quant_type = 0;
318 if (flag_firstpicture == 1) {
319 mp4_state->hdr.time_increment_resolution = 15;
320 flag_firstpicture = 0;
322 mp4_state->hdr.complexity_estimation_disable = 1;
324 decore_alloc (buffers);
325 decore_setoutput (output_format);
327 return 1;
330 /***/
332 int decore_alloc(DEC_BUFFERS buffers)
334 mp4_state->hdr.picnum = 0;
335 mp4_state->hdr.mb_xsize = mp4_state->hdr.width / 16;
336 mp4_state->hdr.mb_ysize = mp4_state->hdr.height / 16;
337 mp4_state->hdr.mba_size = mp4_state->hdr.mb_xsize * mp4_state->hdr.mb_ysize;
339 // set picture dimension global vars
341 mp4_state->horizontal_size = mp4_state->hdr.width;
342 mp4_state->vertical_size = mp4_state->hdr.height;
344 mp4_state->mb_width = mp4_state->horizontal_size / 16;
345 mp4_state->mb_height = mp4_state->vertical_size / 16;
347 mp4_state->coded_picture_width = mp4_state->horizontal_size + 64;
348 mp4_state->coded_picture_height = mp4_state->vertical_size + 64;
349 mp4_state->chrom_width = mp4_state->coded_picture_width >> 1;
350 mp4_state->chrom_height = mp4_state->coded_picture_height >> 1;
353 // init decoder
354 initdecoder (buffers);
356 return 1;
359 /***/
361 int decore_frame(unsigned char *stream, int length, unsigned char *bmp[],
362 unsigned int stride, int render_flag)
364 #ifndef _DECORE
365 mp4_state->juice_flag = 0;
366 _SetPrintCond(0, 1000, 0, 1000);
367 _Print("- Picture %d\r", mp4_state->hdr.picnum);
368 #else
369 initbits (stream, length);
370 #endif // _DECORE
372 // mp4_state->hdr.time_increment_resolution = 15; // [Ag][Review] This must be passed by the app!
373 //printf("decore_frame 1\n");
375 getvolhdr();
376 getgophdr();
378 //printf("decore_frame 1\n");
379 if (! getvophdr()) // read vop header
380 return 0;
381 //printf("decore_frame 1\n");
383 get_mp4picture(bmp, stride, render_flag); // decode vop
384 mp4_state->hdr.picnum++;
385 //printf("decore_frame 2\n");
387 return 1;
390 /***/
392 int decore_release()
394 closedecoder();
397 I have to check and close the decoder only when it is really been opened:
398 for some reason VirtualDub first of all wants to close the decoder and this
399 cause a free(nothing) and a crash.
401 #ifndef _DECORE
402 close (ld->infile);
403 #endif // _DECORE
405 return 1;
408 /***/
410 int decore_setoutput(int output_format)
412 mp4_state->flag_invert = +1;
414 switch (output_format)
416 case DEC_RGB32:
417 mp4_state->convert_yuv = yuv2rgb_32;
418 mp4_state->flag_invert = -1;
419 break;
420 case DEC_RGB32_INV:
421 mp4_state->convert_yuv = yuv2rgb_32;
422 mp4_state->flag_invert = +1;
423 break;
424 case DEC_RGB24:
425 mp4_state->convert_yuv = yuv2rgb_24;
426 mp4_state->flag_invert = -1;
427 break;
428 case DEC_RGB24_INV:
429 mp4_state->convert_yuv = yuv2rgb_24;
430 mp4_state->flag_invert = +1;
431 break;
432 case DEC_RGB555:
433 mp4_state->convert_yuv = yuv2rgb_555;
434 mp4_state->flag_invert = -1;
435 break;
436 case DEC_RGB555_INV:
437 mp4_state->convert_yuv = yuv2rgb_555;
438 mp4_state->flag_invert = +1;
439 break;
440 case DEC_RGB565:
441 mp4_state->convert_yuv = yuv2rgb_565;
442 mp4_state->flag_invert = -1;
443 break;
444 case DEC_RGB565_INV:
445 mp4_state->convert_yuv = yuv2rgb_565;
446 mp4_state->flag_invert = +1;
447 break;
448 case DEC_420:
449 mp4_state->convert_yuv = yuv12_out;
450 break;
451 case DEC_YUV2:
452 mp4_state->convert_yuv = yuy2_out;
453 break;
454 case DEC_UYVY:
455 mp4_state->convert_yuv = uyvy_out;
456 break;
459 return 1;
463 * for a console application
466 #ifndef _DECORE
468 /***/
470 static int dec_reinit();
472 static void options (int *argcp, char **argvp[]);
473 static void optionhelp (int *argcp);
475 /***
477 int main (int argc, char *argv[])
479 char * infilename = argv[1];
480 mp4_state->output_flag = mp4_state->juice_flag = mp4_state->post_flag = 0;
482 // decode args from input line
483 optionhelp (&argc);
484 options (&argc, &argv);
486 // startTimer();
488 dec_init(infilename, mp4_state->juice_hor, mp4_state->juice_ver); // init decoder resources
490 _SetPrintCond(0, 1000, 0, 1000);
492 while (dec_frame()) // cycle on decoding engine
495 // stopTimer();
496 // displayTimer(mp4_hdr.picnum);
498 dec_release(); // release decoder resources
500 return 0;
503 ***/
505 int main (int argc, char *argv[])
507 char * infilename = argv[1];
508 char outputfilename[256] = "Test.yuv";
510 DEC_MEM_REQS decMemReqs;
511 DEC_PARAM decParam;
513 decParam.x_dim = 352;
514 decParam.y_dim = 288;
515 decParam.output_format = 0;
516 decParam.time_incr = 0;
518 decore(1, DEC_OPT_MEMORY_REQS, &decParam, &decMemReqs);
520 decParam.buffers.mp4_edged_ref_buffers = malloc(decMemReqs.mp4_edged_ref_buffers_size);
521 decParam.buffers.mp4_edged_for_buffers = malloc(decMemReqs.mp4_edged_for_buffers_size);
522 decParam.buffers.mp4_display_buffers = malloc(decMemReqs.mp4_display_buffers_size);
523 decParam.buffers.mp4_state = malloc(decMemReqs.mp4_state_size);
524 decParam.buffers.mp4_tables = malloc(decMemReqs.mp4_tables_size);
525 decParam.buffers.mp4_stream = malloc(decMemReqs.mp4_stream_size);
527 memset(decParam.buffers.mp4_state, 0, decMemReqs.mp4_state_size);
528 memset(decParam.buffers.mp4_tables, 0, decMemReqs.mp4_tables_size);
529 memset(decParam.buffers.mp4_stream, 0, decMemReqs.mp4_stream_size);
531 ((MP4_STATE *) decParam.buffers.mp4_state)->infilename = infilename;
532 ((MP4_STATE *) decParam.buffers.mp4_state)->outputname = outputfilename;
534 decore(1, DEC_OPT_INIT, &decParam, NULL);
536 startTimer();
538 // decode frames
540 DEC_FRAME decFrame;
542 decFrame.bitstream = NULL;
543 decFrame.bmp = NULL;
544 decFrame.length = 0;
545 decFrame.render_flag = 0;
547 while ( decore(1, 0, &decFrame, NULL) == DEC_OK )
551 stopTimer();
552 displayTimer(mp4_state->hdr.picnum);
554 return 1;
557 /***/
559 static void options (int *argcp, char **argvp[])
561 (*argvp)++;
562 (*argcp)--;
564 while (*argcp > 1 && (*argvp)[1][0] == '-')
566 switch (toupper ((*argvp)[1][1]))
568 case 'O':
569 mp4_state->output_flag = 1;
570 mp4_state->outputname = (*argvp)[2];
571 (*argvp) += 2;
572 (*argcp) -= 2;
573 break;
574 case 'J':
575 mp4_state->juice_flag = 1;
576 mp4_state->juice_hor = atoi ((*argvp)[2]);
577 mp4_state->juice_ver = atoi ((*argvp)[3]);
578 (*argvp) += 3;
579 (*argcp) -= 3;
580 break;
581 default:
582 printf ("Error: Undefined option -%c ignored\n", (*argvp)[1][1]);
587 /***/
589 static void optionhelp(int *argcp)
591 if (*argcp < 2)
593 _Print ("Usage: opendivx_dec bitstream {options} \n");
594 _Print ("Options: -o {outputfilename} YUV concatenated file output\n");
595 _Print (" -j {hor_size ver_size} juice stream and its picture format\n");
596 exit (0);
600 /***
602 int dec_init(char *infilename, int hor_size, int ver_size, DEC_BUFFERS buffers)
604 mp4_state = (MP4_STATE *) buffers.mp4_state;
605 mp4_tables = (MP4_TABLES *) buffers.mp4_tables;
607 // open input file
608 if ((mp4_state->ld.infile = open (infilename, O_RDONLY | O_BINARY)) < 0) {
609 _Print ("Input file %s not found\n", infilename);
610 exit(91);
613 initbits (NULL);
615 // read header info (contains info to correctly initialize the decoder)
616 getvolhdr();
618 getgophdr();
619 getvophdr(); // read vop header
621 decore_alloc(buffers);
623 return 1;
628 int dec_frame()
630 // decoded vop
631 get_mp4picture(NULL, 0, 0);
632 mp4_state->hdr.picnum++;
634 _Print("- Picture %d\r", mp4_state->hdr.picnum);
636 // read next vop header
637 getvolhdr();
638 getgophdr();
639 return getvophdr();
644 int dec_release()
646 close (mp4_state->ld.infile);
647 decore_release();
649 return 1;
652 ***/
654 int dec_reinit()
656 if (ld->infile != 0)
657 lseek (ld->infile, 0l, 0);
658 initbits (NULL, 0);
660 return 1;
663 /***/
665 #endif // !_DECORE