--- vlc_codes.h 2002/03/09 15:53:05 1.3 +++ vlc_codes.h 2002/04/10 07:43:20 1.5 @@ -2,8 +2,10 @@ #define _VLC_CODES_H_ #include "../portab.h" +#include "mbcoding.h" #define VLC_ERROR (-1) +#define ESCAPE 7167 typedef struct { @@ -11,6 +13,8 @@ int8_t len; } VLC; +static VLC *DCT3D[2]; + /****************************************************************** * common tables between encoder/decoder * @@ -632,20 +636,25 @@ coeff_inter_last1, }; -static const VLC mcbpc_I[4] = { - {1, 1}, {1, 3}, {2, 3}, {3, 3} -}; - -static const VLC mcbpc_P_intra[4] = { - {3, 5}, {4, 8}, {3, 8}, {3, 7} -}; - -static const VLC mcbpc_P_inter[4] = { - {1, 1}, {3, 4}, {2, 4}, {5, 6} -}; - -static const VLC mcbpc_P_inter4v[4] = { - {2, 3}, {5, 7}, {4, 7}, {5, 8} +/* MCBPC Indexing by cbpc in first two bits, mode in last two. + CBPC as in table 4/H.263, MB type (mode): 3 = 01, 4 = 10. + Example: cbpc = 01 and mode = 4 gives index = 0110 = 6. */ + +static VLC mcbpc_intra_tab[15] = { + {0x01, 9}, {0x01, 1}, {0x01, 4}, {0x00, 0}, + {0x00, 0}, {0x01, 3}, {0x01, 6}, {0x00, 0}, + {0x00, 0}, {0x02, 3}, {0x02, 6}, {0x00, 0}, + {0x00, 0}, {0x03, 3}, {0x03, 6} +}; + +/* MCBPC inter. + Addressing: 5 bit ccmmm (cc = CBPC, mmm = mode (1-4 binary)) */ + +static VLC mcbpc_inter_tab[29] = { + {1, 1}, {3, 3}, {2, 3}, {3, 5}, {4, 6}, {1, 9}, {0, 0}, {0, 0}, + {3, 4}, {7, 7}, {5, 7}, {4, 8}, {4, 9}, {0, 0}, {0, 0}, {0, 0}, + {2, 4}, {6, 7}, {4, 7}, {3, 8}, {3, 9}, {0, 0}, {0, 0}, {0, 0}, + {5, 6}, {5, 9}, {5, 8}, {3, 7}, {2, 9} }; static const VLC cbpy_tab[16] = { @@ -1218,4 +1227,98 @@ {2, 2}, {2, 2}, {1, 2}, {1, 2}, }; +static __inline int get_coeff(Bitstream * bs, int *run, int *last, + int intra, int short_video_header) +{ + + uint32_t mode; + const VLC *tab; + int32_t level; + + if(short_video_header) // inter-VLCs will be used for both intra and inter blocks + intra = 0; + + tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; + + if(tab->code == -1) + goto error; + + BitstreamSkip(bs, tab->len); + + if(tab->code != ESCAPE) { + if(!intra) + { + *run = (tab->code >> 4) & 255; + level = tab->code & 15; + *last = (tab->code >> 12) & 1; + } + else + { + *run = (tab->code >> 8) & 255; + level = tab->code & 255; + *last = (tab->code >> 16) & 1; + } + return BitstreamGetBit(bs) ? -level : level; + } + + if(short_video_header) + { + // escape mode 4 - H.263 type, only used if short_video_header = 1 + *last = BitstreamGetBit(bs); + *run = BitstreamGetBits(bs, 6); + level = BitstreamGetBits(bs, 8); + + if (level == 0 || level == 128) + DEBUG1("Illegal LEVEL for ESCAPE mode 4:", level); + + return (level >= 128 ? -(256 - level) : level); + } + + mode = BitstreamShowBits(bs, 2); + + if(mode < 3) { + BitstreamSkip(bs, (mode == 2) ? 2 : 1); + + tab = &DCT3D[intra][BitstreamShowBits(bs, 12)]; + if (tab->code == -1) + goto error; + + BitstreamSkip(bs, tab->len); + + if (!intra) { + *run = (tab->code >> 4) & 255; + level = tab->code & 15; + *last = (tab->code >> 12) & 1; + } + else + { + *run = (tab->code >> 8) & 255; + level = tab->code & 255; + *last = (tab->code >> 16) & 1; + } + + if(mode < 2) // first escape mode, level is offset + level += max_level[*last + (!intra<<1)][*run]; // need to add back the max level + else if(mode == 2) // second escape mode, run is offset + *run += max_run[*last + (!intra<<1)][level] + 1; + + return BitstreamGetBit(bs) ? -level : level; + } + + // third escape mode - fixed length codes + BitstreamSkip(bs, 2); + *last = BitstreamGetBits(bs, 1); + *run = BitstreamGetBits(bs, 6); + BitstreamSkip(bs, 1); // marker + level = BitstreamGetBits(bs, 12); + BitstreamSkip(bs, 1); // marker + + return (level & 0x800) ? (level | (-1 ^ 0xfff)) : level; + + error: + *run = VLC_ERROR; + return 0; + +} + #endif /* _VLC_CODES_H */