📄 mp4_vld.c
字号:
/********************************************************************************
* *
* 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 + -