1 /**************************************************************************
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. *
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. *
18 * The complete Open DivX license can be found at *
19 * http://www.projectmayo.com/opendivx/license.php *
21 **************************************************************************/
23 * Copyright (C) 2001 - Project Mayo
29 * DivX Advanced Research Center <darc@projectmayo.com>
37 #if ( (defined (WIN32)) && (! defined (_DECORE)) )
43 #include "gen_usetime.h"
56 static int flag_firstpicture
= 1;
60 // Set global variables for a decoding session
61 void decore_set_global(DEC_PARAM
*param
)
68 buffers
= ¶m
->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
)
90 buffers
= ¶m
->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()
113 if(!(proc
= fopen("/proc/cpuinfo", "r")))
115 fprintf(stderr
, "mmx_test: failed to open /proc/cpuinfo\n");
121 fgets(string
, 1024, proc
);
122 /* Got the flags line */
123 if(!strncasecmp(string
, "flags", 5))
126 needle
= strstr(string
, "mmx");
132 if(!strncasecmp(needle
, "mmx", 3))
146 int STDCALL
decore(unsigned long handle
, unsigned long dec_opt
,
147 void *param1
, void *param2
)
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]);
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
);
185 DEC_PARAM
*dec_param
= (DEC_PARAM
*) param1
;
187 // have_mmx = mmx_test();
188 decore_init(dec_param
->x_dim
,
190 dec_param
->output_format
,
191 dec_param
->time_incr
,
192 dec_param
->buffers
); // init decoder resources
197 case DEC_OPT_RELEASE
:
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;
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
;
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
;
249 DEC_PARAM
*dec_param
= (DEC_PARAM
*) param1
;
251 decore_setoutput(dec_param
->output_format
);
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]);
278 return DEC_BAD_FORMAT
;
283 int decore_alloc(DEC_BUFFERS buffers
);
285 static int decore_init(int hor_size
,
291 mp4_state
= (MP4_STATE
*) buffers
.mp4_state
;
292 mp4_tables
= (MP4_TABLES
*) buffers
.mp4_tables
;
293 ld
= (MP4_STREAM
*) buffers
.mp4_stream
;
297 if ((ld
->infile
= open (mp4_state
->infilename
, O_RDONLY
| O_BINARY
)) < 0) {
298 _Print ("Input file %s not found\n", mp4_state
->infilename
);
302 mp4_state
->juice_flag
= 0;
304 mp4_state
->juice_flag
= 1;
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
);
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;
354 initdecoder (buffers
);
361 int decore_frame(unsigned char *stream
, int length
, unsigned char *bmp
[],
362 unsigned int stride
, int render_flag
)
365 mp4_state
->juice_flag
= 0;
366 _SetPrintCond(0, 1000, 0, 1000);
367 _Print("- Picture %d\r", mp4_state
->hdr
.picnum
);
369 initbits (stream
, length
);
372 // mp4_state->hdr.time_increment_resolution = 15; // [Ag][Review] This must be passed by the app!
373 //printf("decore_frame 1\n");
378 //printf("decore_frame 1\n");
379 if (! getvophdr()) // read vop header
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");
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.
410 int decore_setoutput(int output_format
)
412 mp4_state
->flag_invert
= +1;
414 switch (output_format
)
417 mp4_state
->convert_yuv
= yuv2rgb_32
;
418 mp4_state
->flag_invert
= -1;
421 mp4_state
->convert_yuv
= yuv2rgb_32
;
422 mp4_state
->flag_invert
= +1;
425 mp4_state
->convert_yuv
= yuv2rgb_24
;
426 mp4_state
->flag_invert
= -1;
429 mp4_state
->convert_yuv
= yuv2rgb_24
;
430 mp4_state
->flag_invert
= +1;
433 mp4_state
->convert_yuv
= yuv2rgb_555
;
434 mp4_state
->flag_invert
= -1;
437 mp4_state
->convert_yuv
= yuv2rgb_555
;
438 mp4_state
->flag_invert
= +1;
441 mp4_state
->convert_yuv
= yuv2rgb_565
;
442 mp4_state
->flag_invert
= -1;
445 mp4_state
->convert_yuv
= yuv2rgb_565
;
446 mp4_state
->flag_invert
= +1;
449 mp4_state
->convert_yuv
= yuv12_out
;
452 mp4_state
->convert_yuv
= yuy2_out
;
455 mp4_state
->convert_yuv
= uyvy_out
;
463 * for a console application
470 static int dec_reinit();
472 static void options (int *argcp
, char **argvp
[]);
473 static void optionhelp (int *argcp
);
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
484 options (&argc, &argv);
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
496 // displayTimer(mp4_hdr.picnum);
498 dec_release(); // release decoder resources
505 int main (int argc
, char *argv
[])
507 char * infilename
= argv
[1];
508 char outputfilename
[256] = "Test.yuv";
510 DEC_MEM_REQS decMemReqs
;
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
);
542 decFrame
.bitstream
= NULL
;
545 decFrame
.render_flag
= 0;
547 while ( decore(1, 0, &decFrame
, NULL
) == DEC_OK
)
552 displayTimer(mp4_state
->hdr
.picnum
);
559 static void options (int *argcp
, char **argvp
[])
564 while (*argcp
> 1 && (*argvp
)[1][0] == '-')
566 switch (toupper ((*argvp
)[1][1]))
569 mp4_state
->output_flag
= 1;
570 mp4_state
->outputname
= (*argvp
)[2];
575 mp4_state
->juice_flag
= 1;
576 mp4_state
->juice_hor
= atoi ((*argvp
)[2]);
577 mp4_state
->juice_ver
= atoi ((*argvp
)[3]);
582 printf ("Error: Undefined option -%c ignored\n", (*argvp
)[1][1]);
589 static void optionhelp(int *argcp
)
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");
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;
608 if ((mp4_state->ld.infile = open (infilename, O_RDONLY | O_BINARY)) < 0) {
609 _Print ("Input file %s not found\n", infilename);
615 // read header info (contains info to correctly initialize the decoder)
619 getvophdr(); // read vop header
621 decore_alloc(buffers);
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
646 close (mp4_state->ld.infile);
657 lseek (ld
->infile
, 0l, 0);