📄 putvlc.c
字号:
/**************************************************************************
* *
* This code is developed by Adam Li. 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 . *
* *
**************************************************************************/
/**************************************************************************
*
* putvlc.c
*
* Copyright (C) 2001 Project Mayo
*
* Adam Li
*
* DivX Advance Research Center <darc@projectmayo.com>
*
**************************************************************************/
/* This file contains some functions to code the RVLC code for bitstream. */
/* Some codes of this project come from MoMuSys MPEG-4 implementation. */
/* Please see seperate acknowledgement file for a list of contributors. */
#include <assert.h>
#include "putvlc.h"
/***********************************************************CommentBegin******
*
* -- Putxxx -- Write bits from huffman tables to file
*
* Purpose :
* Writes bits from huffman tables to bitstream
*
* Arguments in :
* various
*
* Return values :
* Number of bits written
*
***********************************************************CommentEnd********/
__inline static int PutDCsize4lum(BitWriter * bitstream, int size)
{
assert(size >= 0 && size < 13);
BitstreamPutBits(bitstream, DCtab_lum[size].code, DCtab_lum[size].len);
return DCtab_lum[size].len;
}
__inline static int PutDCsize4chrom(BitWriter * bitstream, int size)
{
assert(size >= 0 && size < 13);
BitstreamPutBits(bitstream, DCtab_chrom[size].code, DCtab_chrom[size].len);
return DCtab_chrom[size].len;
}
int PutMV(BitWriter * bitstream, int mvint)
{
int sign = 0;
int absmv;
if (mvint > 32)
{
absmv = -mvint + 65;
sign = 1;
}
else
absmv = mvint;
BitstreamPutBits(bitstream, mvtab[absmv].code, mvtab[absmv].len);
if (mvint != 0)
{
BitstreamPutBits(bitstream, sign, 1);
return mvtab[absmv].len + 1;
}
else
return mvtab[absmv].len;
}
int PutMCBPC_intra(BitWriter * bitstream, int cbpc, int mode)
{
int ind = ((mode >> 1) & 3) | ((cbpc & 3) << 2);
BitstreamPutBits(bitstream, mcbpc_intra_tab[ind].code,
mcbpc_intra_tab[ind].len);
return mcbpc_intra_tab[ind].len;
}
int PutMCBPC_inter(BitWriter * bitstream, int cbpc, int mode)
{
int ind;
ind = (mode & 7) | ((cbpc & 3) << 3);
BitstreamPutBits(bitstream, mcbpc_inter_tab[ind].code,
mcbpc_inter_tab[ind].len);
return mcbpc_inter_tab[ind].len;
}
/*
int PutMCBPC_Sprite(BitWriter * bitstream, int cbpc, int mode)
{
int ind;
ind = (mode & 7) | ((cbpc & 3) << 3);
BitstreamPutBits(bitstream, mcbpc_sprite_tab[ind].code,
mcbpc_sprite_tab[ind].len);
return mcbpc_sprite_tab[ind].len;
}
*/
int PutCBPY(BitWriter * bitstream, int cbpy, bool intra)
{
if (intra == 0)
cbpy = 15 - cbpy;
BitstreamPutBits(bitstream, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len);
return cbpy_tab[cbpy].len;
}
__inline static int PutCoeff4inter(BitWriter * bitstream, int run, int level, int last)
{
int length = 0;
assert(run >= 0 && run < 64);
assert(level > 0 && level < 128);
if (!last)
{
if (run < 2 && level < 13)
{
BitstreamPutBits(bitstream, coeff_tab0[run][level - 1].code,
coeff_tab0[run][level - 1].len);
length = coeff_tab0[run][level - 1].len;
}
else if (run > 1 && run < 27 && level < 5)
{
BitstreamPutBits(bitstream, coeff_tab1[run - 2][level - 1].code,
coeff_tab1[run - 2][level - 1].len);
length = coeff_tab1[run - 2][level - 1].len;
}
}
else // last == 1
{
if (run < 2 && level < 4)
{
BitstreamPutBits(bitstream, coeff_tab2[run][level - 1].code,
coeff_tab2[run][level - 1].len);
length = coeff_tab2[run][level - 1].len;
}
else if (run > 1 && run < 42 && level == 1)
{
BitstreamPutBits(bitstream, coeff_tab3[run - 2].code,
coeff_tab3[run - 2].len);
length = coeff_tab3[run - 2].len;
}
}
return length;
}
__inline static int PutCoeff4intra(BitWriter * bitstream, int run, int level, int last)
{
int length = 0;
assert(run >= 0 && run < 64);
assert(level > 0 && level < 128);
if (!last)
{
if (run == 0 && level < 28)
{
BitstreamPutBits(bitstream, coeff_tab4[level - 1].code,
coeff_tab4[level - 1].len);
length = coeff_tab4[level - 1].len;
}
else if (run == 1 && level < 11)
{
BitstreamPutBits(bitstream, coeff_tab5[level - 1].code,
coeff_tab5[level - 1].len);
length = coeff_tab5[level - 1].len;
}
else if (run > 1 && run < 10 && level < 6)
{
BitstreamPutBits(bitstream, coeff_tab6[run - 2][level - 1].code,
coeff_tab6[run - 2][level - 1].len);
length = coeff_tab6[run - 2][level - 1].len;
}
else if (run > 9 && run < 15 && level == 1)
{
BitstreamPutBits(bitstream, coeff_tab7[run - 10].code,
coeff_tab7[run - 10].len);
length = coeff_tab7[run - 10].len;
}
}
else // last == 1
{
if (run == 0 && level < 9)
{
BitstreamPutBits(bitstream, coeff_tab8[level - 1].code,
coeff_tab8[level - 1].len);
length = coeff_tab8[level - 1].len;
}
else if (run > 0 && run < 7 && level < 4)
{
BitstreamPutBits(bitstream, coeff_tab9[run - 1][level - 1].code,
coeff_tab9[run - 1][level - 1].len);
length = coeff_tab9[run - 1][level - 1].len;
}
else if (run > 6 && run < 21 && level == 1)
{
BitstreamPutBits(bitstream, coeff_tab10[run - 7].code,
coeff_tab10[run - 7].len);
length = coeff_tab10[run - 7].len;
}
}
return length;
}
// 3-mode VLC
__inline static int PutRunCoeff4inter(BitWriter * bitstream, int run, int level, int last)
{
int length = 0;
assert(run >= 0 && run < 64);
assert(level > 0 && level < 128);
if (!last)
{
if (run < 2 && level < 13)
{
length = coeff_tab0[run][level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9; /* boon */
BitstreamPutBits(bitstream,
coeff_tab0[run][level - 1].code,
coeff_tab0[run][level - 1].len);
}
}
else if (run > 1 && run < 27 && level < 5)
{
length = coeff_tab1[run - 2][level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9; /* boon */
BitstreamPutBits(bitstream,
coeff_tab1[run - 2][level - 1].code,
coeff_tab1[run - 2][level - 1].len);
}
}
}
else // last == 1
{
if (run < 2 && level < 4)
{
length = coeff_tab2[run][level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9; /* boon */
BitstreamPutBits(bitstream,
coeff_tab2[run][level - 1].code,
coeff_tab2[run][level - 1].len);
}
}
else if (run > 1 && run < 42 && level == 1)
{
length = coeff_tab3[run - 2].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream,
coeff_tab3[run - 2].code,
coeff_tab3[run - 2].len);
}
}
}
return length;
}
__inline static int PutRunCoeff4intra(BitWriter * bitstream, int run, int level, int last)
{
int length = 0;
assert(run >= 0 && run < 64);
assert(level > 0 && level < 128);
if (!last)
{
if (run == 0 && level < 28)
{
length = coeff_tab4[level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream,
coeff_tab4[level - 1].code,
coeff_tab4[level - 1].len);
}
}
else if (run == 1 && level < 11)
{
length = coeff_tab5[level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream,
coeff_tab5[level - 1].code,
coeff_tab5[level - 1].len);
}
}
else if (run > 1 && run < 10 && level < 6)
{
length = coeff_tab6[run - 2][level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream,
coeff_tab6[run - 2][level - 1].code,
coeff_tab6[run - 2][level - 1].len);
}
}
else if (run > 9 && run < 15 && level == 1)
{
length = coeff_tab7[run - 10].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream,
coeff_tab7[run - 10].code,
coeff_tab7[run - 10].len);
}
}
}
else // last == 1
{
if (run == 0 && level < 9)
{
length = coeff_tab8[level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream, coeff_tab8[level - 1].code,
coeff_tab8[level - 1].len);
}
}
else if (run > 0 && run < 7 && level < 4)
{
length = coeff_tab9[run - 1][level - 1].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9;
BitstreamPutBits(bitstream,
coeff_tab9[run - 1][level - 1].code,
coeff_tab9[run - 1][level - 1].len);
}
}
else if (run > 6 && run < 21 && level == 1)
{
length = coeff_tab10[run - 7].len;
if (length != 0)
{
/* boon 120697 */
BitstreamPutBits(bitstream, 3L, 7L);
/* boon 120697 */
BitstreamPutBits(bitstream, 2L, 2L);
length += 9; /* boon */
BitstreamPutBits(bitstream,
coeff_tab10[run - 7].code,
coeff_tab10[run - 7].len);
}
}
}
return length;
}
__inline static int PutLevelCoeff4inter(BitWriter * bitstream, int run, int level, int last)
{
int length = 0;
assert(run >= 0 && run < 64);
assert(level > 0 && level < 128);
if (!last)
{
if (run < 2 && level < 13)
{
length = coeff_tab0[run][level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8;
BitstreamPutBits(bitstream, coeff_tab0[run][level - 1].code,
coeff_tab0[run][level - 1].len);
}
}
else if (run > 1 && run < 27 && level < 5)
{
length = coeff_tab1[run - 2][level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8;
BitstreamPutBits(bitstream,
coeff_tab1[run - 2][level - 1].code,
coeff_tab1[run - 2][level - 1].len);
}
}
}
else // last == 1
{
if (run < 2 && level < 4)
{
length = coeff_tab2[run][level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab2[run][level - 1].code,
coeff_tab2[run][level - 1].len);
}
}
else if (run > 1 && run < 42 && level == 1)
{
length = coeff_tab3[run - 2].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -