⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decore.c

📁 MPEG4解压缩算法源代码
💻 C
字号:
/**************************************************************************
 *                                                                        *
 * This code has been developed by Andrea Graziani. This software is an   *
 * implementation of a part of one or more MPEG-4 Video tools as          *
 * specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
 * software module in hardware or software products are advised that its  *
 * use may infringe existing patents or copyrights, and any such use      *
 * would be at such party's own risk.  The original developer of this     *
 * software module and his/her company, and subsequent editors and their  *
 * companies (including Project Mayo), will have no liability for use of  *
 * this software or modifications or derivatives thereof.                 *
 *                                                                        *
 * Project Mayo gives users of the Codec a license to this software       *
 * module or modifications thereof for use in hardware or software        *
 * products claiming conformance to the MPEG-4 Video Standard as          *
 * described in the Open DivX license.                                    *
 *                                                                        *
 * The complete Open DivX license can be found at                         *
 * http://www.projectmayo.com/opendivx/license.php                        *
 *                                                                        *
 **************************************************************************/
/**
*  Copyright (C) 2001 - Project Mayo
 *
 * Andrea Graziani
 * Adam Li
 * Jonathan White
 *
 * DivX Advanced Research Center <darc@projectmayo.com>
*
**/
// decore.c //

#include <stdio.h>
#include <stdlib.h>

#if ( (defined (WIN32)) && (! defined (_DECORE)) )
#include <string.h>
#include <io.h>
#include <fcntl.h>
#endif

#include "gen_usetime.h"
#include "debug.h"
#include "mp4_vars.h"
#include "getbits.h"
#include "yuv2rgb.h"
#include "decore.h"

/**
 *
**/

/***/

static int flag_firstpicture = 1;

/***/

int STDCALL decore(unsigned long handle, unsigned long dec_opt,
	void *param1, void *param2)
{
	if (handle) 
	{
		switch (dec_opt)
		{
			case DEC_OPT_MEMORY_REQS:
			{
				DEC_PARAM *dec_param = (DEC_PARAM *)param1;
				DEC_MEM_REQS *dec_mem_reqs = (DEC_MEM_REQS *)param2;

				int coded_y_size = ((dec_param->x_dim + 64) * (dec_param->y_dim + 64));
				int coded_c_size = (((dec_param->x_dim>>1) + 64) * ((dec_param->y_dim>>1) + 64));
				int display_y_size = (dec_param->x_dim * dec_param->y_dim);
				int display_c_size = ((dec_param->x_dim * dec_param->y_dim) >> 2);
				int edged_size = coded_y_size + (2 * coded_c_size);
				int display_size = display_y_size + (2 * display_c_size);

				dec_mem_reqs->mp4_edged_ref_buffers_size = edged_size;
				dec_mem_reqs->mp4_edged_for_buffers_size = edged_size;
				dec_mem_reqs->mp4_display_buffers_size = display_size;
				dec_mem_reqs->mp4_state_size = sizeof(MP4_STATE);
				dec_mem_reqs->mp4_tables_size = sizeof(MP4_TABLES);
				dec_mem_reqs->mp4_stream_size = sizeof(MP4_STREAM);

				return DEC_OK;
			}
			case DEC_OPT_INIT:
			{
				DEC_PARAM *dec_param = (DEC_PARAM *) param1;

				decore_init(dec_param->x_dim, dec_param->y_dim, dec_param->output_format,
					dec_param->time_incr, dec_param->buffers); // init decoder resources

				return DEC_OK;
			}
			break; 
			case DEC_OPT_RELEASE:
			{
				decore_release();

				return DEC_OK;
			}
			break;
			case DEC_OPT_SETPP:
			{
				DEC_SET *dec_set = (DEC_SET *) param1;
				int postproc_level = dec_set->postproc_level;

				if ((postproc_level < 0) | (postproc_level > 100))
					return DEC_BAD_FORMAT;

				if (postproc_level < 1) {
					mp4_state->post_flag = 0;
					return DEC_OK;
				}
				else 
				{
					mp4_state->post_flag = 1;

					if (postproc_level < 10) {
						mp4_state->pp_options = PP_DEBLOCK_Y_H;
					}
					else if (postproc_level < 20) {
						mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V;
					}
					else if (postproc_level < 30) {
						mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y;
					}
					else if (postproc_level < 40) {
						mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | PP_DEBLOCK_C_H;
					}
					else if (postproc_level < 50) {
						mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | 
							PP_DEBLOCK_C_H | PP_DEBLOCK_C_V;
					}
					else {
						mp4_state->pp_options = PP_DEBLOCK_Y_H | PP_DEBLOCK_Y_V | PP_DERING_Y | 
							PP_DEBLOCK_C_H | PP_DEBLOCK_C_V | PP_DERING_C;
					}
				}

				return DEC_OK;
			}
			break;
			case DEC_OPT_SETOUT:
			{
				DEC_PARAM *dec_param = (DEC_PARAM *) param1;

				decore_setoutput(dec_param->output_format);

				return DEC_OK;
			}
			break;
			default:
			{
				DEC_FRAME *dec_frame = (DEC_FRAME *) param1;

				if (decore_frame(dec_frame->bitstream, dec_frame->length, 
					dec_frame->bmp, dec_frame->stride, dec_frame->render_flag))
					return DEC_OK;
				else 
					return DEC_EXIT;
			}
			break;
		}
	}
	return DEC_BAD_FORMAT;
}

/***/

int decore_alloc(DEC_BUFFERS buffers);

static int decore_init(int hor_size, int ver_size, int output_format,
											 int time_inc, DEC_BUFFERS buffers)
{
	mp4_state = (MP4_STATE *) buffers.mp4_state;
	mp4_tables = (MP4_TABLES *) buffers.mp4_tables;
	ld = (MP4_STREAM *) buffers.mp4_stream;

#ifndef _DECORE
	// open input file
	if ((ld->infile = open (mp4_state->infilename, O_RDONLY | O_BINARY)) < 0) {
		_Print ("Input file %s not found\n", mp4_state->infilename);
		exit(91);
	}
	initbits (NULL, 0);
	mp4_state->juice_flag = 0;
#else 
	mp4_state->juice_flag = 1;
#endif // _DECORE

	mp4_state->post_flag = 0;

	// read first vol and vop
	mp4_state->hdr.width = hor_size;
	mp4_state->hdr.height = ver_size;
	
	mp4_state->hdr.quant_precision = 5;
	mp4_state->hdr.bits_per_pixel = 8;
	
	mp4_state->hdr.quant_type = 0;
	
	if (flag_firstpicture == 1) {
		mp4_state->hdr.time_increment_resolution = 15;
		flag_firstpicture = 0;
	}
	mp4_state->hdr.complexity_estimation_disable = 1;

	decore_alloc (buffers);
	decore_setoutput (output_format);

	return 1;
}

/***/

int decore_alloc(DEC_BUFFERS buffers)
{
	mp4_state->hdr.picnum = 0;
	mp4_state->hdr.mb_xsize = mp4_state->hdr.width / 16;
	mp4_state->hdr.mb_ysize = mp4_state->hdr.height / 16;
	mp4_state->hdr.mba_size = mp4_state->hdr.mb_xsize * mp4_state->hdr.mb_ysize;

	// set picture dimension global vars
	{
		mp4_state->horizontal_size = mp4_state->hdr.width;
		mp4_state->vertical_size = mp4_state->hdr.height;

		mp4_state->mb_width = mp4_state->horizontal_size / 16;
		mp4_state->mb_height = mp4_state->vertical_size / 16;

		mp4_state->coded_picture_width = mp4_state->horizontal_size + 64;
		mp4_state->coded_picture_height = mp4_state->vertical_size + 64;
		mp4_state->chrom_width = mp4_state->coded_picture_width >> 1;
		mp4_state->chrom_height = mp4_state->coded_picture_height >> 1;
	}

	// init decoder
	initdecoder (buffers);

	return 1;
}

/***/

int decore_frame(unsigned char *stream, int length, unsigned char *bmp, 
	unsigned int stride, int render_flag)
{
#ifndef _DECORE
	mp4_state->juice_flag = 0;
	_SetPrintCond(0, 1000, 0, 1000);
	_Print("- Picture %d\r", mp4_state->hdr.picnum);
#else
	initbits (stream, length);
#endif // _DECORE

	// mp4_state->hdr.time_increment_resolution = 15; // [Ag][Review] This must be passed by the app!

	getvolhdr();
	getgophdr();	

	if (! getvophdr()) // read vop header
		return 0;

	get_mp4picture(bmp, stride, render_flag); // decode vop
	mp4_state->hdr.picnum++;

	return 1;
}

/***/

static int decore_release()
{
	// closedecoder(); // [Ag][Review] 

	/*
			I have to check and close the decoder only when it is really been opened: 
			for some reason VirtualDub first of all wants to close the decoder and this 
			cause a free(nothing) and a crash.
	*/
#ifndef _DECORE
	close (ld->infile);
#endif // _DECORE

	return 1;
}

/***/

int decore_setoutput(int output_format)
{
	mp4_state->flag_invert = +1;

	switch (output_format)
	{
	case DEC_RGB32:
		mp4_state->convert_yuv = yuv2rgb_32;
		mp4_state->flag_invert = -1;
		break;
	case DEC_RGB32_INV:
		mp4_state->convert_yuv = yuv2rgb_32;
		mp4_state->flag_invert = +1;
		break;
	case DEC_RGB24:
		mp4_state->convert_yuv = yuv2rgb_24;
		mp4_state->flag_invert = -1;
		break;
	case DEC_RGB24_INV:
		mp4_state->convert_yuv = yuv2rgb_24;
		mp4_state->flag_invert = +1;
		break;
	case DEC_RGB555:
		mp4_state->convert_yuv = yuv2rgb_555;
		mp4_state->flag_invert = -1;
		break;
	case DEC_RGB555_INV:
		mp4_state->convert_yuv = yuv2rgb_555;
		mp4_state->flag_invert = +1;
		break;
	case DEC_RGB565:
		mp4_state->convert_yuv = yuv2rgb_565;
		mp4_state->flag_invert = -1;
		break;
	case DEC_RGB565_INV:
		mp4_state->convert_yuv = yuv2rgb_565;
		mp4_state->flag_invert = +1;
		break;
	case DEC_420:
		mp4_state->convert_yuv = yuv12_out;
		break;
	case DEC_YUV2:
		mp4_state->convert_yuv = yuy2_out;
		break;
	case DEC_UYVY:
		mp4_state->convert_yuv = uyvy_out;
		break;
	}

	return 1;
}

/**
 *	for a console application
**/

#ifndef _DECORE

/***/

static int dec_reinit();

static void options (int *argcp, char **argvp[]);
static void optionhelp (int *argcp);

/***

int main (int argc, char *argv[])
{
	char * infilename = argv[1];
	mp4_state->output_flag = mp4_state->juice_flag = mp4_state->post_flag = 0;

	// decode args from input line
	optionhelp (&argc);
  options (&argc, &argv);

//	startTimer();

	dec_init(infilename, mp4_state->juice_hor, mp4_state->juice_ver); // init decoder resources

	_SetPrintCond(0, 1000, 0, 1000);

  while (dec_frame()) // cycle on decoding engine
		;

//	stopTimer();
//	displayTimer(mp4_hdr.picnum);

  dec_release(); // release decoder resources

  return 0;
}

***/

int main (int argc, char *argv[])
{
	char * infilename = argv[1];
	char outputfilename[256] = "Test.yuv";

	DEC_MEM_REQS decMemReqs;
	DEC_PARAM decParam;

	decParam.x_dim = 352;
	decParam.y_dim = 288;
	decParam.output_format = 0;
	decParam.time_incr = 0;
	
	decore(1, DEC_OPT_MEMORY_REQS, &decParam, &decMemReqs);

	decParam.buffers.mp4_edged_ref_buffers = malloc(decMemReqs.mp4_edged_ref_buffers_size);
	decParam.buffers.mp4_edged_for_buffers = malloc(decMemReqs.mp4_edged_for_buffers_size);
	decParam.buffers.mp4_display_buffers = malloc(decMemReqs.mp4_display_buffers_size);
	decParam.buffers.mp4_state = malloc(decMemReqs.mp4_state_size);
	decParam.buffers.mp4_tables = malloc(decMemReqs.mp4_tables_size);
	decParam.buffers.mp4_stream = malloc(decMemReqs.mp4_stream_size);

	memset(decParam.buffers.mp4_state, 0, decMemReqs.mp4_state_size);
	memset(decParam.buffers.mp4_tables, 0, decMemReqs.mp4_tables_size);
	memset(decParam.buffers.mp4_stream, 0, decMemReqs.mp4_stream_size);

	((MP4_STATE *) decParam.buffers.mp4_state)->infilename = infilename;
	((MP4_STATE *) decParam.buffers.mp4_state)->outputname = outputfilename;

	decore(1, DEC_OPT_INIT, &decParam, NULL);

	startTimer();

	// decode frames
	{
		DEC_FRAME decFrame;

		decFrame.bitstream = NULL;
		decFrame.bmp = NULL;
		decFrame.length = 0;
		decFrame.render_flag = 0;

		while ( decore(1, 0, &decFrame, NULL) == DEC_OK )
			;
	}

	stopTimer();
	displayTimer(mp4_state->hdr.picnum);

	return 1;
}

/***/

static void options (int *argcp, char **argvp[])
{
	(*argvp)++;
	(*argcp)--;

  while (*argcp > 1 && (*argvp)[1][0] == '-')
  {
    switch (toupper ((*argvp)[1][1]))
    {
      case 'O':
				mp4_state->output_flag = 1;
        mp4_state->outputname = (*argvp)[2];
				(*argvp) += 2;
				(*argcp) -= 2;
				break;
			case 'J':
				mp4_state->juice_flag = 1;
				mp4_state->juice_hor = atoi ((*argvp)[2]);
				mp4_state->juice_ver = atoi ((*argvp)[3]);
		    (*argvp) += 3;
				(*argcp) -= 3;
				break;
      default:
        printf ("Error: Undefined option -%c ignored\n", (*argvp)[1][1]);
    }
  }
}

/***/

static void optionhelp(int *argcp)
{
  if (*argcp < 2)
  {
    _Print ("Usage: opendivx_dec bitstream {options} \n");
		_Print ("Options: -o {outputfilename} YUV concatenated file output\n");
		_Print ("         -j {hor_size ver_size} juice stream and its picture format\n");
    exit (0);
  }
}

/***

int dec_init(char *infilename, int hor_size, int ver_size, DEC_BUFFERS buffers)
{
	mp4_state = (MP4_STATE *) buffers.mp4_state;
	mp4_tables = (MP4_TABLES *) buffers.mp4_tables;

	// open input file
	if ((mp4_state->ld.infile = open (infilename, O_RDONLY | O_BINARY)) < 0) {
		_Print ("Input file %s not found\n", infilename);
		exit(91);
	}

	initbits (NULL);

	// read header info (contains info to correctly initialize the decoder)
	getvolhdr();

	getgophdr();
	getvophdr(); // read vop header

	decore_alloc(buffers);

	return 1;
}



int dec_frame()
{
	// decoded vop
	get_mp4picture(NULL, 0, 0);
	mp4_state->hdr.picnum++;

	_Print("- Picture %d\r", mp4_state->hdr.picnum);

	// read next vop header
	getvolhdr();
	getgophdr();
	return getvophdr(); 
}



int dec_release()
{
  close (mp4_state->ld.infile);
	decore_release();

	return 1;
}

***/

int dec_reinit()
{
  if (ld->infile != 0)
    lseek (ld->infile, 0l, 0);
  initbits (NULL, 0);

	return 1;
}

/***/

#endif // !_DECORE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -