📄 quant.c
字号:
/********************************************************************
* *
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2005 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include "codec_internal.h"
#include "quant_lookup.h"
/* the *V1 tables are the originals used by the VP3 codec */
static const ogg_uint32_t QThreshTableV1[Q_TABLE_SIZE] = {
500, 450, 400, 370, 340, 310, 285, 265,
245, 225, 210, 195, 185, 180, 170, 160,
150, 145, 135, 130, 125, 115, 110, 107,
100, 96, 93, 89, 85, 82, 75, 74,
70, 68, 64, 60, 57, 56, 52, 50,
49, 45, 44, 43, 40, 38, 37, 35,
33, 32, 30, 29, 28, 25, 24, 22,
21, 19, 18, 17, 15, 13, 12, 10
};
static const Q_LIST_ENTRY DcScaleFactorTableV1[ Q_TABLE_SIZE ] = {
220, 200, 190, 180, 170, 170, 160, 160,
150, 150, 140, 140, 130, 130, 120, 120,
110, 110, 100, 100, 90, 90, 90, 80,
80, 80, 70, 70, 70, 60, 60, 60,
60, 50, 50, 50, 50, 40, 40, 40,
40, 40, 30, 30, 30, 30, 30, 30,
30, 20, 20, 20, 20, 20, 20, 20,
20, 10, 10, 10, 10, 10, 10, 10
};
/* dbm -- defined some alternative tables to test header packing */
#define NEW_QTABLES 0
#if NEW_QTABLES
static const Q_LIST_ENTRY Y_coeffsV1[64] =
{
8, 16, 16, 16, 20, 20, 20, 20,
16, 16, 16, 16, 20, 20, 20, 20,
16, 16, 16, 16, 22, 22, 22, 22,
16, 16, 16, 16, 22, 22, 22, 22,
20, 20, 22, 22, 24, 24, 24, 24,
20, 20, 22, 22, 24, 24, 24, 24,
20, 20, 22, 22, 24, 24, 24, 24,
20, 20, 22, 22, 24, 24, 24, 24
};
static const Q_LIST_ENTRY UV_coeffsV1[64] =
{ 17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
static const Q_LIST_ENTRY Inter_coeffsV1[64] =
{
12, 16, 16, 16, 20, 20, 20, 20,
16, 16, 16, 16, 20, 20, 20, 20,
16, 16, 16, 16, 22, 22, 22, 22,
16, 16, 16, 16, 22, 22, 22, 22,
20, 20, 22, 22, 24, 24, 24, 24,
20, 20, 22, 22, 24, 24, 24, 24,
20, 20, 22, 22, 24, 24, 24, 24,
20, 20, 22, 22, 24, 24, 24, 24
};
#else /* these are the old VP3 values: */
static const Q_LIST_ENTRY Y_coeffsV1[64] ={
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 58, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
static const Q_LIST_ENTRY UV_coeffsV1[64] ={
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
static const Q_LIST_ENTRY Inter_coeffsV1[64] ={
16, 16, 16, 20, 24, 28, 32, 40,
16, 16, 20, 24, 28, 32, 40, 48,
16, 20, 24, 28, 32, 40, 48, 64,
20, 24, 28, 32, 40, 48, 64, 64,
24, 28, 32, 40, 48, 64, 64, 64,
28, 32, 40, 48, 64, 64, 64, 96,
32, 40, 48, 64, 64, 64, 96, 128,
40, 48, 64, 64, 64, 96, 128, 128
};
#endif
static int _ilog(unsigned int v){
int ret=0;
while(v){
ret++;
v>>=1;
}
return(ret);
}
void WriteQTables(PB_INSTANCE *pbi,oggpack_buffer* opb) {
int x, bits;
bits=10;
oggpackB_write(opb, bits-1, 4);
for(x=0; x<64; x++) {
oggpackB_write(opb, pbi->QThreshTable[x],bits);
}
oggpackB_write(opb, bits-1, 4);
for(x=0; x<64; x++) {
oggpackB_write(opb, pbi->DcScaleFactorTable[x],bits);
}
oggpackB_write(opb, 3 - 1, 9); /* number of base matricies */
for(x=0; x<64; x++) {
oggpackB_write(opb, pbi->Y_coeffs[x],8);
}
for(x=0; x<64; x++) {
oggpackB_write(opb, pbi->U_coeffs[x],8);
}
for(x=0; x<64; x++) {
oggpackB_write(opb, pbi->InterY_coeffs[x],8);
}
/* table mapping */
oggpackB_write(opb, 0, 2); /* matrix 0 for intra Y */
oggpackB_write(opb, 62, 6); /* used for every q */
oggpackB_write(opb, 0, 2);
oggpackB_write(opb, 1, 1); /* next range is explicit */
oggpackB_write(opb, 1, 2); /* matrix 1 for intra U */
oggpackB_write(opb, 62, 6);
oggpackB_write(opb, 1, 2);
oggpackB_write(opb, 0, 1); /* intra V is the same */
oggpackB_write(opb, 1, 1); /* next range is explicit */
oggpackB_write(opb, 2, 2); /* matrix 2 for inter Y */
oggpackB_write(opb, 62, 6);
oggpackB_write(opb, 2, 2);
oggpackB_write(opb, 0, 2); /* inter U the same */
oggpackB_write(opb, 0, 2); /* inter V the same */
}
static int _read_qtable_range(codec_setup_info *ci, oggpack_buffer* opb,
int N, int type)
{
int index, range;
int qi = 0;
int count = 0;
qmat_range_table table[65];
theora_read(opb,_ilog(N-1),&index); /* qi=0 index */
table[count].startqi = 0;
table[count++].qmat = ci->qmats + index * Q_TABLE_SIZE;
while(qi<63) {
theora_read(opb,_ilog(62-qi),&range); /* range to next code q matrix */
range++;
if(range<=0) return OC_BADHEADER;
qi+=range;
theora_read(opb,_ilog(N-1),&index); /* next index */
table[count].startqi = qi;
table[count++].qmat = ci->qmats + index * Q_TABLE_SIZE;
}
ci->range_table[type] = _ogg_malloc(count * sizeof(qmat_range_table));
if (ci->range_table[type] != NULL) {
memcpy(ci->range_table[type], table, count * sizeof(qmat_range_table));
return 0;
}
return OC_FAULT; /* allocation failed */
}
int ReadQTables(codec_setup_info *ci, oggpack_buffer* opb) {
long bits,value;
int x,y, N;
/* AC scale table */
theora_read(opb,4,&bits); bits++;
for(x=0; x<Q_TABLE_SIZE; x++) {
theora_read(opb,bits,&value);
if(bits<0)return OC_BADHEADER;
ci->QThreshTable[x]=value;
}
/* DC scale table */
theora_read(opb,4,&bits); bits++;
for(x=0; x<Q_TABLE_SIZE; x++) {
theora_read(opb,bits,&value);
if(bits<0)return OC_BADHEADER;
ci->DcScaleFactorTable[x]=(Q_LIST_ENTRY)value;
}
/* base matricies */
theora_read(opb,9,&N); N++;
ci->qmats=_ogg_malloc(N*64*sizeof(Q_LIST_ENTRY));
ci->MaxQMatrixIndex = N;
for(y=0; y<N; y++) {
for(x=0; x<64; x++) {
theora_read(opb,8,&value);
if(bits<0)return OC_BADHEADER;
ci->qmats[(y<<6)+x]=(Q_LIST_ENTRY)value;
}
}
/* table mapping */
for(x=0; x<6; x++) {
ci->range_table[x] = NULL;
}
{
int flag, ret;
/* intra Y */
if((ret=_read_qtable_range(ci,opb,N,0))<0) return ret;
/* intra U */
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* explicitly coded */
if((ret=_read_qtable_range(ci,opb,N,1))<0) return ret;
} else {
/* same as previous */
}
/* intra V */
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* explicitly coded */
if((ret=_read_qtable_range(ci,opb,N,2))<0) return ret;
} else {
/* same as previous */
}
/* inter Y */
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* explicitly coded */
if((ret=_read_qtable_range(ci,opb,N,3))<0) return ret;
} else {
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* same as corresponding intra */
} else {
/* same as previous */
}
}
/* inter U */
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* explicitly coded */
if((ret=_read_qtable_range(ci,opb,N,4))<0) return ret;
} else {
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* same as corresponding intra */
} else {
/* same as previous */
}
}
/* inter V */
theora_read(opb,1,&flag);
if(flag<0) return OC_BADHEADER;
if(flag) {
/* explicitly coded */
if((ret=_read_qtable_range(ci,opb,N,5))<0) return ret;
} else {
theora_read(opb,1,&flag);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -