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

📄 mp4_vld.c

📁 基于MPEG4的DIVX解码模块
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************
 *																				*
 * This code has been developed by Project Mayo. 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.						*
 *																				*
 ********************************************************************************
 *																				*	
 * This program is free software; you can redistribute it and/or modify			*
 * it under the terms of the GNU General Public License as published by			*
 * the Free Software Foundation; either version 2 of the License, or			*
 * (at your option) any later version.											*
 *																				*
 * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html				*
 *																				*
 * Authors:																		*
 *																				*
 *	John Funnell (JF) and														*
 *	Andrea Graziani	(Ag):														*
 *		- Original source code (Open Divx Decoder 0.4a).						*		
 *																				*
 *	Pedro Mateu		(Pm):														*
 *		- Modified and optimized code + MIPS ASM								*
 *																				*
 ********************************************************************************/

// mp4_vld.c //
#include "global.h"
#include "mp4_vld.h"

/**/

 int vldTableB19(int last, int run);
 int vldTableB20(int last, int run);
 int vldTableB21(int last, int level);
 int vldTableB22(int last, int level);

 int vldTableB16(int code);
 int vldTableB17(int code);

/**/

int vld_intra_dct() 
{
#ifdef MIPS_ASM
	__asm("li	$4,12;"
		  "jal	showbits;"
		  "move	$4,$2;"
		  "jal	vldTableB16;"
		  "li	$8,7167;"
		  "beq	$2,$8,INTRA_ESCAPE_MODE;"
  		  "beq	$2,$0,INTRA_ERROR;"
		  "sra	$5,$2,6;" //run=tab>>6...
		  "andi	$5,$5,63;"//...&63
		  "andi	$6,$2,63;"//level=tab&63
		  "sra	$7,$2,12;"//last= tab>>12...
		  "andi	$7,$7,1;"//...&1
		  );
__asm(	  "jal	getbits1;"
		  "beq	$2,$0,INTRA_POS1;"
		  "neg	$6;" // -level
		  "INTRA_POS1:sll	$6,$6,16;" //level <<16
		  "sll	$7,$7,8;" //last << 8
		  "or	$2,$6,$7;" 
		  "or	$2,$2,$5;"
		  "b	INTRA_FIN;");
		  
__asm(	  "INTRA_ESCAPE_MODE:li	$4,2;"
		  "jal	showbits;" //showbits (2)
		  
		  "li	$8,2;" // !0x1, !0x0?
		  "beq	$8,$2,INTRA_02;"
		  "li	$8,3;" // !0x1, !0x0?
		  "beq	$8,$2,INTRA_03;"

		  "li	$4,1;"
		  "jal	flushbits;"//flushbits (1)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB16;"
		  "beq	$2,$0,INTRA_ERROR;"
		  "sra	$5,$2,6;" //run=tab>>6...
		  "andi	$5,$5,63;"//...&63
		  "andi	$6,$2,63;"//level=tab&63
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB19;"
		  "add	$6,$6,$2;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTRA_POS2;"
		  "neg	$6;" // -level
		  "INTRA_POS2:sll	$6,$6,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$6;" 
		  "or	$2,$2,$5;"
		  "b	INTRA_FIN;");
		 
__asm(	  "INTRA_02:li	$4,2;"
		  "jal	flushbits;"//flushbits (2)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB16;"
		  "beq	$2,$0,INTRA_ERROR;"
		  "sra	$6,$2,6;" //run=tab>>6...
		  "andi	$6,$6,63;"//...&63
		  "andi	$5,$2,63;"//level=tab&63
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB21;"
		  "add	$6,$6,$2;"
		  "addi	$6,$6,1;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTRA_POS3;"
		  "neg	$5;" // -level
		  "INTRA_POS3:sll	$5,$5,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$5;" 
		  "or	$2,$2,$6;"
		  "b	INTRA_FIN;");

__asm(	  "INTRA_03:"
		  "li	$4,23;"
		  "jal	getbits;"		//getbits (23)
		  "srl	$2,$2,1;"				 
		  "andi	$7,$2,4095;"	//level=tab&4095
		  "srl	$2,$2,13;"		
		  "andi	$6,$2,63;"		//run=tab&63
		  "srl	$2,$2,6;"		
		  "andi	$5,$2,1;"		//last=tab&1
		  "andi	$8,$7,0x800;"
		  "beq	$8,$0,INTRA_POS4;"
		  "li	$9,-1;"
		  "xori	$9,$9,0xfff;"
		  "or	$7,$7,$9;"
		  "INTRA_POS4:"
		  "sll	$7,$7,16;" //level <<16
		  "sll	$5,$5,8;" //last << 8
		  "or	$2,$5,$7;" 
		  "or	$2,$2,$6;"
		  "b	INTRA_FIN;"
		  "INTRA_ERROR:li	$2,-1;"
		  "INTRA_FIN:" );
#else
	
	int run,level,last;
	int tab = 0;
	int lmax, rmax;

	tab = vldTableB16(showbits(12));
	if (!tab) return -1;
	if (tab != ESCAPE) {
		run   = (tab >>  6) & 63;
		level =  tab        & 63;
		last  = (tab >> 12) &  1;
		level = getbits1() ? -level : level;
	} else {
		/* this value is escaped - see para 7.4.1.3 */
		/* assuming short_video_header == 0 */
		switch (showbits(2)) {
			case 0x0 :  /* Type 1 */
			case 0x1 :  /* Type 1 */
				flushbits(1);
				tab = vldTableB16(showbits(12));  /* use table B-16 */
				if (!tab) return -1;
				run   = (tab >>  6) & 63;
				level =  tab        & 63;
				last  = (tab >> 12) &  1;
				lmax = vldTableB19(last, run);  /* use table B-19 */
				level += lmax;
				level =  getbits1() ? -level : level;
				break;
			case 0x2 :  /* Type 2 */
				flushbits(2);
				tab = vldTableB16(showbits(12));  /* use table B-16 */
				if (!tab) return -1;
				run   = (tab >>  6) & 63;
				level =  tab        & 63;
				last  = (tab >> 12) &  1;
				rmax = vldTableB21(last, level);  /* use table B-21 */
				run = run + rmax + 1;
				level = getbits1() ? -level : level;
				break;
			default: //case 0x3 :  /* Type 3  - fixed length codes */
				tab = getbits(23)>>1;
				level = tab&4095; // table B-18 
				tab	>>=	13;
				run   = tab&63;  // table B-18  
				tab >>=	6;
				last  = tab&1;
				// sign extend level... 
				level = (level & 0x800) ? (level | (-1 ^ 0xfff)) : level;
				break;
					 
					 /*	flushbits(2);
				last  = getbits1();
				run   = getbits(6);  // table B-18  
				flushbits(1); // marker bit 
				level = getbits(12); // table B-18 
				// sign extend level... 
				level = (level & 0x800) ? (level | (-1 ^ 0xfff)) : level;
				flushbits(1); // marker bit 
				break;*/
		}
	}

	return (level<<16)|(last<<8)|(run);
#endif
}

/**/

int vld_inter_dct() 
{
#ifdef MIPS_ASM
	__asm("li	$4,12;"
		  "jal	showbits;"
		  "move	$4,$2;"
		  "jal	vldTableB17;"
		  "beq	$2,$0,INTER_ERROR;"
		  "li	$8,7167;"
		  "beq	$2,$8,INTER_ESCAPE_MODE;"
		  "sra	$5,$2,4;" //run=tab>>4...
		  "andi	$5,$5,255;"//...&255
		  "andi	$6,$2,15;"//level=tab&15
		  "sra	$7,$2,12;"//last= tab>>12...
		  "andi	$7,$7,1;"//...&1
		  );
__asm(	  "jal	getbits1;"
		  "beq	$2,$0,INTER_POS1;"
		  "neg	$6;" // -level
		  "INTER_POS1:sll	$6,$6,16;" //level <<16
		  "sll	$7,$7,8;" //last << 8
		  "or	$2,$6,$7;" 
		  "or	$2,$2,$5;"
		  "b	INTER_FIN;");
		  
__asm(	  "INTER_ESCAPE_MODE:li	$4,2;"
		  "jal	showbits;" //showbits (2)
		  
		  "li	$8,2;" // !0x1, !0x0?
		  "beq	$8,$2,INTER_02;"
		  "li	$8,3;" // !0x1, !0x0?
		  "beq	$8,$2,INTER_03;"

		  "li	$4,1;"
		  "jal	flushbits;"//flushbits (1)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB17;"
		  "beq	$2,$0,INTER_ERROR;"
		  "sra	$5,$2,4;" //run=tab>>4...
		  "andi	$5,$5,255;"//...&255
		  "andi	$6,$2,15;"//level=tab&15
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB20;"
		  "add	$6,$6,$2;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTER_POS2;"
		  "neg	$6;" // -level
		  "INTER_POS2:sll	$6,$6,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$6;" 
		  "or	$2,$2,$5;"
		  "b	INTER_FIN;");
		 
__asm(	  "INTER_02:li	$4,2;"
		  "jal	flushbits;"//flushbits (2)
		  "li	$4,12;"
		  "jal	showbits;"	//showbits (12)
		  "move	$4,$2;"
		  "jal	vldTableB17;"
		  "beq	$2,$0,INTER_ERROR;"
		  "sra	$6,$2,4;" //run=tab>>6...
		  "andi	$6,$6,255;"//...&255
		  "andi	$5,$2,15;"//level=tab&15
		  "sra	$4,$2,12;"//last= tab>>12...
		  "andi	$4,$4,1;"//...&1
		  "jal	vldTableB22;"
		  "add	$6,$6,$2;"
		  "addi	$6,$6,1;"
		  "jal	getbits1;"
		  "beq	$2,$0,INTER_POS3;"
		  "neg	$5;" // -level
		  "INTER_POS3:sll	$5,$5,16;" //level <<16
		  "sll	$4,$4,8;" //last << 8
		  "or	$2,$4,$5;" 
		  "or	$2,$2,$6;"
		  "b	INTER_FIN;");

__asm(	  "INTER_03:"
		  "li	$4,23;"
		  "jal	getbits;"		//getbits (23)
		  "srl	$2,$2,1;"				 
		  "andi	$7,$2,4095;"	//level=tab&4095
		  "srl	$2,$2,13;"		
		  "andi	$6,$2,63;"		//run=tab&63
		  "srl	$2,$2,6;"		
		  "andi	$5,$2,1;"		//last=tab&1
		  "andi	$8,$7,0x800;"
		  "beq	$8,$0,INTER_POS4;"
		  "li	$9,-1;"
		  "xori	$9,$9,0xfff;"
		  "or	$7,$7,$9;"
		  "INTER_POS4:"
		  "sll	$7,$7,16;" //level <<16
		  "sll	$5,$5,8;" //last << 8
		  "or	$2,$5,$7;" 
		  "or	$2,$2,$6;"
		  "b	INTER_FIN;"
		  "INTER_ERROR:li	$2,-1;"
		  "INTER_FIN:" );
#else

	int run, level,last;
	int tab =0;
	int lmax, rmax;

	tab = vldTableB17(showbits(12));
	if (!tab) return -1;
	if (tab != ESCAPE) {
		run   = (tab >>  4) & 255;
		level =  tab        & 15;
		last  = (tab >> 12) &  1;
		level = getbits1() ? -level : level;
		return (level<<16)|(last<<8)|(run);
	} else {
		/* this value is escaped - see para 7.4.1.3 */
		/* assuming short_video_header == 0 */
		int mode = showbits(2);
		switch (mode) {
			case 0x0 :  /* Type 1 */
			case 0x1 :  /* Type 1 */
				flushbits(1);
				tab = vldTableB17(showbits(12));  /* use table B-17 */
				if (!tab) return -1;
				run   = (tab >>  4) & 255;
				level =  tab        & 15;
				last  = (tab >> 12) &  1;
				lmax = vldTableB20(last, run);  /* use table B-20 */
				level += lmax;
				level = getbits1() ? -level : level;
				break;
			case 0x2 :  /* Type 2 */
				flushbits(2);
				tab = vldTableB17(showbits(12));  /* use table B-16 */
				if (!tab) return -1;
				run   = (tab >>  4) & 255;
				level =  tab        & 15;
				last  = (tab >> 12) &  1;
				rmax = vldTableB22(last, level);  /* use table B-22 */
				run = run + rmax + 1;
				level = getbits1() ? -level : level;
				break;
			default: //case 0x3 :  /* Type 3  - fixed length codes */
				tab = getbits(23)>>1;
				level = tab&4095; // table B-18 
				tab	>>=	13;
				run   = tab&63;  // table B-18  
				tab >>=	6;
				last  = tab&1;
				// sign extend level... 
				level = (level & 0x800) ? (level | (-1 ^ 0xfff)) : level;
				break;
		}
	}

	return (level<<16)|(last<<8)|(run);

#endif
}

// Table B-19 -- ESCL(a), LMAX values of intra macroblocks 

 int vldTableB19(int last, int run) {
#ifdef MIPS_ASM
	__asm (".set noreorder;"
		"bne	$4,$0,LAST_19;"
		"li		$8,0;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,27;"
	
		"li		$8,1;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,10;"
	
		"li		$8,2;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,5;"

		"li		$8,3;"
		"beq	$8,$5,FINAL_B19;"
		"li		$2,4;"

		"slti	$8,$5,8;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,3;"

		"slti	$8,$5,10;"
		"bne	$8,$0,FINAL_B19;"
		"li		$2,2;"

⌨️ 快捷键说明

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