Update avcodec to 20080825

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27558 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2008-09-15 14:10:29 +00:00
parent 2aa0a78774
commit f900b2ed76
30 changed files with 17811 additions and 1896 deletions
@@ -0,0 +1,283 @@
/*
* Beam Software VB decoder
* Copyright (c) 2007 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vb.c
* VB Video decoder
*/
#include <stdio.h>
#include <stdlib.h>
#include "avcodec.h"
#include "bytestream.h"
enum VBFlags{
VB_HAS_GMC = 0x01,
VB_HAS_AUDIO = 0x04,
VB_HAS_VIDEO = 0x08,
VB_HAS_PALETTE = 0x10,
VB_HAS_LENGTH = 0x20
};
typedef struct VBDecContext {
AVCodecContext *avctx;
AVFrame pic;
uint8_t *frame, *prev_frame;
uint32_t pal[256];
const uint8_t *stream;
} VBDecContext;
static const uint16_t vb_patterns[64] = {
0x0660, 0xFF00, 0xCCCC, 0xF000, 0x8888, 0x000F, 0x1111, 0xFEC8,
0x8CEF, 0x137F, 0xF731, 0xC800, 0x008C, 0x0013, 0x3100, 0xCC00,
0x00CC, 0x0033, 0x3300, 0x0FF0, 0x6666, 0x00F0, 0x0F00, 0x2222,
0x4444, 0xF600, 0x8CC8, 0x006F, 0x1331, 0x318C, 0xC813, 0x33CC,
0x6600, 0x0CC0, 0x0066, 0x0330, 0xF900, 0xC88C, 0x009F, 0x3113,
0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC,
0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63,
0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C
};
static void vb_decode_palette(VBDecContext *c)
{
int start, size, i;
start = bytestream_get_byte(&c->stream);
size = (bytestream_get_byte(&c->stream) - 1) & 0xFF;
if(start + size > 255){
av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n");
return;
}
for(i = start; i <= start + size; i++)
c->pal[i] = bytestream_get_be24(&c->stream);
}
static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end)
{
return buf >= start && buf < end;
}
static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end)
{
return buf >= start && (buf + 4) <= end;
}
static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int offset)
{
uint8_t *prev, *cur;
int blk, blocks, t, blk2;
int blocktypes = 0;
int x, y, a, b;
int pattype, pattern;
const int width = c->avctx->width;
uint8_t *pstart = c->prev_frame;
uint8_t *pend = c->prev_frame + width*c->avctx->height;
prev = c->prev_frame + offset;
cur = c->frame;
blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2);
blk2 = 0;
for(blk = 0; blk < blocks; blk++){
if(!(blk & 3))
blocktypes = bytestream_get_byte(&buf);
switch(blocktypes & 0xC0){
case 0x00: //skip
for(y = 0; y < 4; y++)
if(check_line(prev + y*width, pstart, pend))
memcpy(cur + y*width, prev + y*width, 4);
else
memset(cur + y*width, 0, 4);
break;
case 0x40:
t = bytestream_get_byte(&buf);
if(!t){ //raw block
for(y = 0; y < 4; y++)
memcpy(cur + y*width, buf + y*4, 4);
buf += 16;
}else{ // motion compensation
x = ((t & 0xF)^8) - 8;
y = ((t >> 4) ^8) - 8;
t = x + y*width;
for(y = 0; y < 4; y++)
if(check_line(prev + t + y*width, pstart, pend))
memcpy(cur + y*width, prev + t + y*width, 4);
else
memset(cur + y*width, 0, 4);
}
break;
case 0x80: // fill
t = bytestream_get_byte(&buf);
for(y = 0; y < 4; y++)
memset(cur + y*width, t, 4);
break;
case 0xC0: // pattern fill
t = bytestream_get_byte(&buf);
pattype = t >> 6;
pattern = vb_patterns[t & 0x3F];
switch(pattype){
case 0:
a = bytestream_get_byte(&buf);
b = bytestream_get_byte(&buf);
for(y = 0; y < 4; y++)
for(x = 0; x < 4; x++, pattern >>= 1)
cur[x + y*width] = (pattern & 1) ? b : a;
break;
case 1:
pattern = ~pattern;
case 2:
a = bytestream_get_byte(&buf);
for(y = 0; y < 4; y++)
for(x = 0; x < 4; x++, pattern >>= 1)
if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))
cur[x + y*width] = prev[x + y*width];
else
cur[x + y*width] = a;
break;
case 3:
av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk);
return -1;
}
break;
}
blocktypes <<= 2;
cur += 4;
prev += 4;
blk2++;
if(blk2 == (width >> 2)){
blk2 = 0;
cur += width * 3;
prev += width * 3;
}
}
return 0;
}
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
{
VBDecContext * const c = avctx->priv_data;
uint8_t *outptr, *srcptr;
int i, j;
int flags;
uint32_t size;
int rest = buf_size;
int offset = 0;
c->stream = buf;
flags = bytestream_get_le16(&c->stream);
rest -= 2;
if(flags & VB_HAS_GMC){
i = (int16_t)bytestream_get_le16(&c->stream);
j = (int16_t)bytestream_get_le16(&c->stream);
offset = i + j * avctx->width;
rest -= 4;
}
if(flags & VB_HAS_VIDEO){
size = bytestream_get_le32(&c->stream);
if(size > rest){
av_log(avctx, AV_LOG_ERROR, "Frame size is too big\n");
return -1;
}
vb_decode_framedata(c, c->stream, offset);
c->stream += size - 4;
rest -= size;
}
if(flags & VB_HAS_PALETTE){
size = bytestream_get_le32(&c->stream);
if(size > rest){
av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n");
return -1;
}
vb_decode_palette(c);
rest -= size;
}
memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
c->pic.palette_has_changed = flags & VB_HAS_PALETTE;
outptr = c->pic.data[0];
srcptr = c->frame;
for(i = 0; i < avctx->height; i++){
memcpy(outptr, srcptr, avctx->width);
srcptr += avctx->width;
outptr += c->pic.linesize[0];
}
FFSWAP(uint8_t*, c->frame, c->prev_frame);
*data_size = sizeof(AVFrame);
*(AVFrame*)data = c->pic;
/* always report that the buffer was completely consumed */
return buf_size;
}
static av_cold int decode_init(AVCodecContext *avctx)
{
VBDecContext * const c = avctx->priv_data;
c->avctx = avctx;
avctx->pix_fmt = PIX_FMT_PAL8;
if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
return -1;
}
c->pic.reference = 1;
if(avctx->get_buffer(avctx, &c->pic) < 0){
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
c->frame = av_malloc( avctx->width * avctx->height);
c->prev_frame = av_malloc( avctx->width * avctx->height);
return 0;
}
static av_cold int decode_end(AVCodecContext *avctx)
{
VBDecContext *c = avctx->priv_data;
av_freep(&c->frame);
av_freep(&c->prev_frame);
if(c->pic.data[0])
avctx->release_buffer(avctx, &c->pic);
return 0;
}
AVCodec vb_decoder = {
"vb",
CODEC_TYPE_VIDEO,
CODEC_ID_VB,
sizeof(VBDecContext),
decode_init,
NULL,
decode_end,
decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Beam Software VB"),
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,311 @@
/*
* VC-1 and WMV3 decoder
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VC1_H
#define FFMPEG_VC1_H
#include "avcodec.h"
#include "mpegvideo.h"
#include "intrax8.h"
/** Markers used in VC-1 AP frame data */
//@{
enum VC1Code{
VC1_CODE_RES0 = 0x00000100,
VC1_CODE_ENDOFSEQ = 0x0000010A,
VC1_CODE_SLICE,
VC1_CODE_FIELD,
VC1_CODE_FRAME,
VC1_CODE_ENTRYPOINT,
VC1_CODE_SEQHDR,
};
//@}
#define IS_MARKER(x) (((x) & ~0xFF) == VC1_CODE_RES0)
/** Available Profiles */
//@{
enum Profile {
PROFILE_SIMPLE,
PROFILE_MAIN,
PROFILE_COMPLEX, ///< TODO: WMV9 specific
PROFILE_ADVANCED
};
//@}
/** Sequence quantizer mode */
//@{
enum QuantMode {
QUANT_FRAME_IMPLICIT, ///< Implicitly specified at frame level
QUANT_FRAME_EXPLICIT, ///< Explicitly specified at frame level
QUANT_NON_UNIFORM, ///< Non-uniform quant used for all frames
QUANT_UNIFORM ///< Uniform quant used for all frames
};
//@}
/** Where quant can be changed */
//@{
enum DQProfile {
DQPROFILE_FOUR_EDGES,
DQPROFILE_DOUBLE_EDGES,
DQPROFILE_SINGLE_EDGE,
DQPROFILE_ALL_MBS
};
//@}
/** @name Where quant can be changed
*/
//@{
enum DQSingleEdge {
DQSINGLE_BEDGE_LEFT,
DQSINGLE_BEDGE_TOP,
DQSINGLE_BEDGE_RIGHT,
DQSINGLE_BEDGE_BOTTOM
};
//@}
/** Which pair of edges is quantized with ALTPQUANT */
//@{
enum DQDoubleEdge {
DQDOUBLE_BEDGE_TOPLEFT,
DQDOUBLE_BEDGE_TOPRIGHT,
DQDOUBLE_BEDGE_BOTTOMRIGHT,
DQDOUBLE_BEDGE_BOTTOMLEFT
};
//@}
/** MV modes for P frames */
//@{
enum MVModes {
MV_PMODE_1MV_HPEL_BILIN,
MV_PMODE_1MV,
MV_PMODE_1MV_HPEL,
MV_PMODE_MIXED_MV,
MV_PMODE_INTENSITY_COMP
};
//@}
/** @name MV types for B frames */
//@{
enum BMVTypes {
BMV_TYPE_BACKWARD,
BMV_TYPE_FORWARD,
BMV_TYPE_INTERPOLATED
};
//@}
/** @name Block types for P/B frames */
//@{
enum TransformTypes {
TT_8X8,
TT_8X4_BOTTOM,
TT_8X4_TOP,
TT_8X4, //Both halves
TT_4X8_RIGHT,
TT_4X8_LEFT,
TT_4X8, //Both halves
TT_4X4
};
//@}
enum CodingSet {
CS_HIGH_MOT_INTRA = 0,
CS_HIGH_MOT_INTER,
CS_LOW_MOT_INTRA,
CS_LOW_MOT_INTER,
CS_MID_RATE_INTRA,
CS_MID_RATE_INTER,
CS_HIGH_RATE_INTRA,
CS_HIGH_RATE_INTER
};
/** @name Overlap conditions for Advanced Profile */
//@{
enum COTypes {
CONDOVER_NONE = 0,
CONDOVER_ALL,
CONDOVER_SELECT
};
//@}
/** The VC1 Context
* @todo Change size wherever another size is more efficient
* Many members are only used for Advanced Profile
*/
typedef struct VC1Context{
MpegEncContext s;
IntraX8Context x8;
int bits;
/** Simple/Main Profile sequence header */
//@{
int res_sm; ///< reserved, 2b
int res_x8; ///< reserved
int multires; ///< frame-level RESPIC syntax element present
int res_fasttx; ///< reserved, always 1
int res_transtab; ///< reserved, always 0
int rangered; ///< RANGEREDFRM (range reduction) syntax element present
///< at frame level
int res_rtm_flag; ///< reserved, set to 1
int reserved; ///< reserved
//@}
/** Advanced Profile */
//@{
int level; ///< 3bits, for Advanced/Simple Profile, provided by TS layer
int chromaformat; ///< 2bits, 2=4:2:0, only defined
int postprocflag; ///< Per-frame processing suggestion flag present
int broadcast; ///< TFF/RFF present
int interlace; ///< Progressive/interlaced (RPTFTM syntax element)
int tfcntrflag; ///< TFCNTR present
int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present
int extended_dmv; ///< Additional extended dmv range at P/B frame-level
int color_prim; ///< 8bits, chroma coordinates of the color primaries
int transfer_char; ///< 8bits, Opto-electronic transfer characteristics
int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix
int hrd_param_flag; ///< Presence of Hypothetical Reference
///< Decoder parameters
int psf; ///< Progressive Segmented Frame
//@}
/** Sequence header data for all Profiles
* TODO: choose between ints, uint8_ts and monobit flags
*/
//@{
int profile; ///< 2bits, Profile
int frmrtq_postproc; ///< 3bits,
int bitrtq_postproc; ///< 5bits, quantized framerate-based postprocessing strength
int fastuvmc; ///< Rounding of qpel vector to hpel ? (not in Simple)
int extended_mv; ///< Ext MV in P/B (not in Simple)
int dquant; ///< How qscale varies with MBs, 2bits (not in Simple)
int vstransform; ///< variable-size [48]x[48] transform type + info
int overlap; ///< overlapped transforms in use
int quantizer_mode; ///< 2bits, quantizer mode used for sequence, see QUANT_*
int finterpflag; ///< INTERPFRM present
//@}
/** Frame decoding info for all profiles */
//@{
uint8_t mv_mode; ///< MV coding monde
uint8_t mv_mode2; ///< Secondary MV coding mode (B frames)
int k_x; ///< Number of bits for MVs (depends on MV range)
int k_y; ///< Number of bits for MVs (depends on MV range)
int range_x, range_y; ///< MV range
uint8_t pq, altpq; ///< Current/alternate frame quantizer scale
const uint8_t* zz_8x4;///< Zigzag scan table for TT_8x4 coding mode
const uint8_t* zz_4x8;///< Zigzag scan table for TT_4x8 coding mode
/** pquant parameters */
//@{
uint8_t dquantfrm;
uint8_t dqprofile;
uint8_t dqsbedge;
uint8_t dqbilevel;
//@}
/** AC coding set indexes
* @see 8.1.1.10, p(1)10
*/
//@{
int c_ac_table_index; ///< Chroma index from ACFRM element
int y_ac_table_index; ///< Luma index from AC2FRM element
//@}
int ttfrm; ///< Transform type info present at frame level
uint8_t ttmbf; ///< Transform type flag
uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform
int codingset; ///< index of current table set from 11.8 to use for luma block decoding
int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding
int pqindex; ///< raw pqindex used in coding set selection
int a_avail, c_avail;
uint8_t *mb_type_base, *mb_type[3];
/** Luma compensation parameters */
//@{
uint8_t lumscale;
uint8_t lumshift;
//@}
int16_t bfraction; ///< Relative position % anchors=> how to scale MVs
uint8_t halfpq; ///< Uniform quant over image and qp+.5
uint8_t respic; ///< Frame-level flag for resized images
int buffer_fullness; ///< HRD info
/** Ranges:
* -# 0 -> [-64n 63.f] x [-32, 31.f]
* -# 1 -> [-128, 127.f] x [-64, 63.f]
* -# 2 -> [-512, 511.f] x [-128, 127.f]
* -# 3 -> [-1024, 1023.f] x [-256, 255.f]
*/
uint8_t mvrange;
uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use
VLC *cbpcy_vlc; ///< CBPCY VLC table
int tt_index; ///< Index for Transform Type tables
uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV)
uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs
int mv_type_is_raw; ///< mv type mb plane is not coded
int dmb_is_raw; ///< direct mb plane is raw
int skip_is_raw; ///< skip mb plane is not coded
uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation
int use_ic; ///< use intensity compensation in B-frames
int rnd; ///< rounding control
/** Frame decoding info for S/M profiles only */
//@{
uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128)
uint8_t interpfrm;
//@}
/** Frame decoding info for Advanced profile */
//@{
uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace
uint8_t numpanscanwin;
uint8_t tfcntr;
uint8_t rptfrm, tff, rff;
uint16_t topleftx;
uint16_t toplefty;
uint16_t bottomrightx;
uint16_t bottomrighty;
uint8_t uvsamp;
uint8_t postproc;
int hrd_num_leaky_buckets;
uint8_t bit_rate_exponent;
uint8_t buffer_size_exponent;
uint8_t* acpred_plane; ///< AC prediction flags bitplane
int acpred_is_raw;
uint8_t* over_flags_plane; ///< Overflags bitplane
int overflg_is_raw;
uint8_t condover;
uint16_t *hrd_rate, *hrd_buffer;
uint8_t *hrd_fullness;
uint8_t range_mapy_flag;
uint8_t range_mapuv_flag;
uint8_t range_mapy;
uint8_t range_mapuv;
//@}
int p_frame_skipped;
int bi_type;
int x8_type;
uint32_t *cbp_base, *cbp;
} VC1Context;
#endif /* FFMPEG_VC1_H */
@@ -0,0 +1,118 @@
/*
* VC-1 and WMV3 parser
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vc1_parser.c
* VC-1 and WMV3 parser
*/
#include "parser.h"
#include "vc1.h"
/**
* finds the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int vc1_find_frame_end(ParseContext *pc, const uint8_t *buf,
int buf_size) {
int pic_found, i;
uint32_t state;
pic_found= pc->frame_start_found;
state= pc->state;
i=0;
if(!pic_found){
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if(state == VC1_CODE_FRAME || state == VC1_CODE_FIELD){
i++;
pic_found=1;
break;
}
}
}
if(pic_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
for(; i<buf_size; i++){
state= (state<<8) | buf[i];
if(IS_MARKER(state) && state != VC1_CODE_FIELD && state != VC1_CODE_SLICE){
pc->frame_start_found=0;
pc->state=-1;
return i-3;
}
}
}
pc->frame_start_found= pic_found;
pc->state= state;
return END_NOT_FOUND;
}
static int vc1_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext *pc = s->priv_data;
int next;
if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
next= buf_size;
}else{
next= vc1_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
}
*poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
static int vc1_split(AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
int i;
uint32_t state= -1;
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if(IS_MARKER(state) && state != VC1_CODE_SEQHDR && state != VC1_CODE_ENTRYPOINT)
return i-3;
}
return 0;
}
AVCodecParser vc1_parser = {
{ CODEC_ID_VC1 },
sizeof(ParseContext1),
NULL,
vc1_parse,
ff_parse1_close,
vc1_split,
};
@@ -0,0 +1,592 @@
/*
* VC-1 and WMV3 decoder
* copyright (c) 2006 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VC1ACDATA_H
#define FFMPEG_VC1ACDATA_H
#include <stdint.h>
#define AC_MODES 8
static const int vc1_ac_sizes[AC_MODES] = {
186, 169, 133, 149, 103, 103, 163, 175
};
static const uint32_t vc1_ac_tables[AC_MODES][186][2] = {
{
{ 0x0001, 2}, { 0x0005, 3}, { 0x000D, 4}, { 0x0012, 5}, { 0x000E, 6}, { 0x0015, 7},
{ 0x0013, 8}, { 0x003F, 8}, { 0x004B, 9}, { 0x011F, 9}, { 0x00B8, 10}, { 0x03E3, 10},
{ 0x0172, 11}, { 0x024D, 12}, { 0x03DA, 12}, { 0x02DD, 13}, { 0x1F55, 13}, { 0x05B9, 14},
{ 0x3EAE, 14}, { 0x0000, 4}, { 0x0010, 5}, { 0x0008, 7}, { 0x0020, 8}, { 0x0029, 9},
{ 0x01F4, 9}, { 0x0233, 10}, { 0x01E0, 11}, { 0x012A, 12}, { 0x03DD, 12}, { 0x050A, 13},
{ 0x1F29, 13}, { 0x0A42, 14}, { 0x1272, 15}, { 0x1737, 15}, { 0x0003, 5}, { 0x0011, 7},
{ 0x00C4, 8}, { 0x004B, 10}, { 0x00B4, 11}, { 0x07D4, 11}, { 0x0345, 12}, { 0x02D7, 13},
{ 0x07BF, 13}, { 0x0938, 14}, { 0x0BBB, 14}, { 0x095E, 15}, { 0x0013, 5}, { 0x0078, 7},
{ 0x0069, 9}, { 0x0232, 10}, { 0x0461, 11}, { 0x03EC, 12}, { 0x0520, 13}, { 0x1F2A, 13},
{ 0x3E50, 14}, { 0x3E51, 14}, { 0x1486, 15}, { 0x000C, 6}, { 0x0024, 9}, { 0x0094, 11},
{ 0x08C0, 12}, { 0x0F09, 14}, { 0x1EF0, 15}, { 0x003D, 6}, { 0x0053, 9}, { 0x01A0, 11},
{ 0x02D6, 13}, { 0x0F08, 14}, { 0x0013, 7}, { 0x007C, 9}, { 0x07C1, 11}, { 0x04AC, 14},
{ 0x001B, 7}, { 0x00A0, 10}, { 0x0344, 12}, { 0x0F79, 14}, { 0x0079, 7}, { 0x03E1, 10},
{ 0x02D4, 13}, { 0x2306, 14}, { 0x0021, 8}, { 0x023C, 10}, { 0x0FAE, 12}, { 0x23DE, 14},
{ 0x0035, 8}, { 0x0175, 11}, { 0x07B3, 13}, { 0x00C5, 8}, { 0x0174, 11}, { 0x0785, 13},
{ 0x0048, 9}, { 0x01A3, 11}, { 0x049E, 13}, { 0x002C, 9}, { 0x00FA, 10}, { 0x07D6, 11},
{ 0x0092, 10}, { 0x05CC, 13}, { 0x1EF1, 15}, { 0x00A3, 10}, { 0x03ED, 12}, { 0x093E, 14},
{ 0x01E2, 11}, { 0x1273, 15}, { 0x07C4, 11}, { 0x1487, 15}, { 0x0291, 12}, { 0x0293, 12},
{ 0x0F8A, 12}, { 0x0509, 13}, { 0x0508, 13}, { 0x078D, 13}, { 0x07BE, 13}, { 0x078C, 13},
{ 0x04AE, 14}, { 0x0BBA, 14}, { 0x2307, 14}, { 0x0B9A, 14}, { 0x1736, 15}, { 0x000E, 4},
{ 0x0045, 7}, { 0x01F3, 9}, { 0x047A, 11}, { 0x05DC, 13}, { 0x23DF, 14}, { 0x0019, 5},
{ 0x0028, 9}, { 0x0176, 11}, { 0x049D, 13}, { 0x23DD, 14}, { 0x0030, 6}, { 0x00A2, 10},
{ 0x02EF, 12}, { 0x05B8, 14}, { 0x003F, 6}, { 0x00A5, 10}, { 0x03DB, 12}, { 0x093F, 14},
{ 0x0044, 7}, { 0x07CB, 11}, { 0x095F, 15}, { 0x0063, 7}, { 0x03C3, 12}, { 0x0015, 8},
{ 0x08F6, 12}, { 0x0017, 8}, { 0x0498, 13}, { 0x002C, 8}, { 0x07B2, 13}, { 0x002F, 8},
{ 0x1F54, 13}, { 0x008D, 8}, { 0x07BD, 13}, { 0x008E, 8}, { 0x1182, 13}, { 0x00FB, 8},
{ 0x050B, 13}, { 0x002D, 8}, { 0x07C0, 11}, { 0x0079, 9}, { 0x1F5F, 13}, { 0x007A, 9},
{ 0x1F56, 13}, { 0x0231, 10}, { 0x03E4, 10}, { 0x01A1, 11}, { 0x0143, 11}, { 0x01F7, 11},
{ 0x016F, 12}, { 0x0292, 12}, { 0x02E7, 12}, { 0x016C, 12}, { 0x016D, 12}, { 0x03DC, 12},
{ 0x0F8B, 12}, { 0x0499, 13}, { 0x03D8, 12}, { 0x078E, 13}, { 0x02D5, 13}, { 0x1F5E, 13},
{ 0x1F2B, 13}, { 0x078F, 13}, { 0x04AD, 14}, { 0x3EAF, 14}, { 0x23DC, 14}, { 0x004A, 9}
},
{
{ 0x0000, 3}, { 0x0003, 4}, { 0x000B, 5}, { 0x0014, 6}, { 0x003F, 6}, { 0x005D, 7},
{ 0x00A2, 8}, { 0x00AC, 9}, { 0x016E, 9}, { 0x020A, 10}, { 0x02E2, 10}, { 0x0432, 11},
{ 0x05C9, 11}, { 0x0827, 12}, { 0x0B54, 12}, { 0x04E6, 13}, { 0x105F, 13}, { 0x172A, 13},
{ 0x20B2, 14}, { 0x2D4E, 14}, { 0x39F0, 14}, { 0x4175, 15}, { 0x5A9E, 15}, { 0x0004, 4},
{ 0x001E, 5}, { 0x0042, 7}, { 0x00B6, 8}, { 0x0173, 9}, { 0x0395, 10}, { 0x072E, 11},
{ 0x0B94, 12}, { 0x16A4, 13}, { 0x20B3, 14}, { 0x2E45, 14}, { 0x0005, 5}, { 0x0040, 7},
{ 0x0049, 9}, { 0x028F, 10}, { 0x05CB, 11}, { 0x048A, 13}, { 0x09DD, 14}, { 0x73E2, 15},
{ 0x0018, 5}, { 0x0025, 8}, { 0x008A, 10}, { 0x051B, 11}, { 0x0E5F, 12}, { 0x09C9, 14},
{ 0x139C, 15}, { 0x0029, 6}, { 0x004F, 9}, { 0x0412, 11}, { 0x048D, 13}, { 0x2E41, 14},
{ 0x0038, 6}, { 0x010E, 9}, { 0x05A8, 11}, { 0x105C, 13}, { 0x39F2, 14}, { 0x0058, 7},
{ 0x021F, 10}, { 0x0E7E, 12}, { 0x39FF, 14}, { 0x0023, 8}, { 0x02E3, 10}, { 0x04E5, 13},
{ 0x2E40, 14}, { 0x00A1, 8}, { 0x05BE, 11}, { 0x09C8, 14}, { 0x0083, 8}, { 0x013A, 11},
{ 0x1721, 13}, { 0x0044, 9}, { 0x0276, 12}, { 0x39F6, 14}, { 0x008B, 10}, { 0x04EF, 13},
{ 0x5A9B, 15}, { 0x0208, 10}, { 0x1CFE, 13}, { 0x0399, 10}, { 0x1CB4, 13}, { 0x039E, 10},
{ 0x39F3, 14}, { 0x05AB, 11}, { 0x73E3, 15}, { 0x0737, 11}, { 0x5A9F, 15}, { 0x082D, 12},
{ 0x0E69, 12}, { 0x0E68, 12}, { 0x0433, 11}, { 0x0B7B, 12}, { 0x2DF8, 14}, { 0x2E56, 14},
{ 0x2E57, 14}, { 0x39F7, 14}, { 0x51A5, 15}, { 0x0003, 3}, { 0x002A, 6}, { 0x00E4, 8},
{ 0x028E, 10}, { 0x0735, 11}, { 0x1058, 13}, { 0x1CFA, 13}, { 0x2DF9, 14}, { 0x4174, 15},
{ 0x0009, 4}, { 0x0054, 8}, { 0x0398, 10}, { 0x048B, 13}, { 0x139D, 15}, { 0x000D, 4},
{ 0x00AD, 9}, { 0x0826, 12}, { 0x2D4C, 14}, { 0x0011, 5}, { 0x016B, 9}, { 0x0B7F, 12},
{ 0x51A4, 15}, { 0x0019, 5}, { 0x021B, 10}, { 0x16FD, 13}, { 0x001D, 5}, { 0x0394, 10},
{ 0x28D3, 14}, { 0x002B, 6}, { 0x05BC, 11}, { 0x5A9A, 15}, { 0x002F, 6}, { 0x0247, 12},
{ 0x0010, 7}, { 0x0A35, 12}, { 0x003E, 6}, { 0x0B7A, 12}, { 0x0059, 7}, { 0x105E, 13},
{ 0x0026, 8}, { 0x09CF, 14}, { 0x0055, 8}, { 0x1CB5, 13}, { 0x0057, 8}, { 0x0E5B, 12},
{ 0x00A0, 8}, { 0x1468, 13}, { 0x0170, 9}, { 0x0090, 10}, { 0x01CE, 9}, { 0x021A, 10},
{ 0x0218, 10}, { 0x0168, 9}, { 0x021E, 10}, { 0x0244, 12}, { 0x0736, 11}, { 0x0138, 11},
{ 0x0519, 11}, { 0x0E5E, 12}, { 0x072C, 11}, { 0x0B55, 12}, { 0x09DC, 14}, { 0x20BB, 14},
{ 0x048C, 13}, { 0x1723, 13}, { 0x2E44, 14}, { 0x16A5, 13}, { 0x0518, 11}, { 0x39FE, 14},
{ 0x0169, 9}
},
{
{ 0x0001, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x0016, 5}, { 0x0020, 6}, { 0x0018, 7},
{ 0x0008, 8}, { 0x009A, 8}, { 0x0056, 9}, { 0x013E, 9}, { 0x00F0, 10}, { 0x03A5, 10},
{ 0x0077, 11}, { 0x01EF, 11}, { 0x009A, 12}, { 0x005D, 13}, { 0x0001, 4}, { 0x0011, 5},
{ 0x0002, 7}, { 0x000B, 8}, { 0x0012, 9}, { 0x01D6, 9}, { 0x027E, 10}, { 0x0191, 11},
{ 0x00EA, 12}, { 0x03DC, 12}, { 0x013B, 13}, { 0x0004, 5}, { 0x0014, 7}, { 0x009E, 8},
{ 0x0009, 10}, { 0x01AC, 11}, { 0x01E2, 11}, { 0x03CA, 12}, { 0x005F, 13}, { 0x0017, 5},
{ 0x004E, 7}, { 0x005E, 9}, { 0x00F3, 10}, { 0x01AD, 11}, { 0x00EC, 12}, { 0x05F0, 13},
{ 0x000E, 6}, { 0x00E1, 8}, { 0x03A4, 10}, { 0x009C, 12}, { 0x013D, 13}, { 0x003B, 6},
{ 0x001C, 9}, { 0x0014, 11}, { 0x09BE, 12}, { 0x0006, 7}, { 0x007A, 9}, { 0x0190, 11},
{ 0x0137, 13}, { 0x001B, 7}, { 0x0008, 10}, { 0x075C, 11}, { 0x0071, 7}, { 0x00D7, 10},
{ 0x09BF, 12}, { 0x0007, 8}, { 0x00AF, 10}, { 0x04CC, 11}, { 0x0034, 8}, { 0x0265, 10},
{ 0x009F, 12}, { 0x00E0, 8}, { 0x0016, 11}, { 0x0327, 12}, { 0x0015, 9}, { 0x017D, 11},
{ 0x0EBB, 12}, { 0x0014, 9}, { 0x00F6, 10}, { 0x01E4, 11}, { 0x00CB, 10}, { 0x099D, 12},
{ 0x00CA, 10}, { 0x02FC, 12}, { 0x017F, 11}, { 0x04CD, 11}, { 0x02FD, 12}, { 0x04FE, 11},
{ 0x013A, 13}, { 0x000A, 4}, { 0x0042, 7}, { 0x01D3, 9}, { 0x04DD, 11}, { 0x0012, 5},
{ 0x00E8, 8}, { 0x004C, 11}, { 0x0136, 13}, { 0x0039, 6}, { 0x0264, 10}, { 0x0EBA, 12},
{ 0x0000, 7}, { 0x00AE, 10}, { 0x099C, 12}, { 0x001F, 7}, { 0x04DE, 11}, { 0x0043, 7},
{ 0x04DC, 11}, { 0x0003, 8}, { 0x03CB, 12}, { 0x0006, 8}, { 0x099E, 12}, { 0x002A, 8},
{ 0x05F1, 13}, { 0x000F, 8}, { 0x09FE, 12}, { 0x0033, 8}, { 0x09FF, 12}, { 0x0098, 8},
{ 0x099F, 12}, { 0x00EA, 8}, { 0x013C, 13}, { 0x002E, 8}, { 0x0192, 11}, { 0x0136, 9},
{ 0x006A, 9}, { 0x0015, 11}, { 0x03AF, 10}, { 0x01E3, 11}, { 0x0074, 11}, { 0x00EB, 12},
{ 0x02F9, 12}, { 0x005C, 13}, { 0x00ED, 12}, { 0x03DD, 12}, { 0x0326, 12}, { 0x005E, 13},
{ 0x0016, 7}
},
{
{ 0x0004, 3}, { 0x0014, 5}, { 0x0017, 7}, { 0x007F, 8}, { 0x0154, 9}, { 0x01F2, 10},
{ 0x00BF, 11}, { 0x0065, 12}, { 0x0AAA, 12}, { 0x0630, 13}, { 0x1597, 13}, { 0x03B7, 14},
{ 0x2B22, 14}, { 0x0BE6, 15}, { 0x000B, 4}, { 0x0037, 7}, { 0x0062, 9}, { 0x0007, 11},
{ 0x0166, 12}, { 0x00CE, 13}, { 0x1590, 13}, { 0x05F6, 14}, { 0x0BE7, 15}, { 0x0007, 5},
{ 0x006D, 8}, { 0x0003, 11}, { 0x031F, 12}, { 0x05F2, 14}, { 0x0002, 6}, { 0x0061, 9},
{ 0x0055, 12}, { 0x01DF, 14}, { 0x001A, 6}, { 0x001E, 10}, { 0x0AC9, 12}, { 0x2B23, 14},
{ 0x001E, 6}, { 0x001F, 10}, { 0x0AC3, 12}, { 0x2B2B, 14}, { 0x0006, 7}, { 0x0004, 11},
{ 0x02F8, 13}, { 0x0019, 7}, { 0x0006, 11}, { 0x063D, 13}, { 0x0057, 7}, { 0x0182, 11},
{ 0x2AA2, 14}, { 0x0004, 8}, { 0x0180, 11}, { 0x059C, 14}, { 0x007D, 8}, { 0x0164, 12},
{ 0x076D, 15}, { 0x0002, 9}, { 0x018D, 11}, { 0x1581, 13}, { 0x00AD, 8}, { 0x0060, 12},
{ 0x0C67, 14}, { 0x001C, 9}, { 0x00EE, 13}, { 0x0003, 9}, { 0x02CF, 13}, { 0x00D9, 9},
{ 0x1580, 13}, { 0x0002, 11}, { 0x0183, 11}, { 0x0057, 12}, { 0x0061, 12}, { 0x0031, 11},
{ 0x0066, 12}, { 0x0631, 13}, { 0x0632, 13}, { 0x00AC, 13}, { 0x031D, 12}, { 0x0076, 12},
{ 0x003A, 11}, { 0x0165, 12}, { 0x0C66, 14}, { 0x0003, 2}, { 0x0054, 7}, { 0x02AB, 10},
{ 0x0016, 13}, { 0x05F7, 14}, { 0x0005, 4}, { 0x00F8, 9}, { 0x0AA9, 12}, { 0x005F, 15},
{ 0x0004, 4}, { 0x001C, 10}, { 0x1550, 13}, { 0x0004, 5}, { 0x0077, 11}, { 0x076C, 15},
{ 0x000E, 5}, { 0x000A, 12}, { 0x000C, 5}, { 0x0562, 11}, { 0x0004, 6}, { 0x031C, 12},
{ 0x0006, 6}, { 0x00C8, 13}, { 0x000D, 6}, { 0x01DA, 13}, { 0x0007, 6}, { 0x00C9, 13},
{ 0x0001, 7}, { 0x002E, 14}, { 0x0014, 7}, { 0x1596, 13}, { 0x000A, 7}, { 0x0AC2, 12},
{ 0x0016, 7}, { 0x015B, 14}, { 0x0015, 7}, { 0x015A, 14}, { 0x000F, 8}, { 0x005E, 15},
{ 0x007E, 8}, { 0x00AB, 8}, { 0x002D, 9}, { 0x00D8, 9}, { 0x000B, 9}, { 0x0014, 10},
{ 0x02B3, 10}, { 0x01F3, 10}, { 0x003A, 10}, { 0x0000, 10}, { 0x0058, 10}, { 0x002E, 9},
{ 0x005E, 10}, { 0x0563, 11}, { 0x00EC, 12}, { 0x0054, 12}, { 0x0AC1, 12}, { 0x1556, 13},
{ 0x02FA, 13}, { 0x0181, 11}, { 0x1557, 13}, { 0x059D, 14}, { 0x2AA3, 14}, { 0x2B2A, 14},
{ 0x01DE, 14}, { 0x063C, 13}, { 0x00CF, 13}, { 0x1594, 13}, { 0x000D, 9}
},
{
{ 0x0002, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x000D, 5}, { 0x000C, 5}, { 0x0015, 6},
{ 0x0013, 6}, { 0x0012, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x001E, 8}, { 0x001D, 8},
{ 0x0025, 9}, { 0x0024, 9}, { 0x0023, 9}, { 0x0021, 9}, { 0x0021, 10}, { 0x0020, 10},
{ 0x000F, 10}, { 0x000E, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, { 0x0021, 11},
{ 0x0050, 12}, { 0x0051, 12}, { 0x0052, 12}, { 0x000E, 4}, { 0x0014, 6}, { 0x0016, 7},
{ 0x001C, 8}, { 0x0020, 9}, { 0x001F, 9}, { 0x000D, 10}, { 0x0022, 11}, { 0x0053, 12},
{ 0x0055, 12}, { 0x000B, 5}, { 0x0015, 7}, { 0x001E, 9}, { 0x000C, 10}, { 0x0056, 12},
{ 0x0011, 6}, { 0x001B, 8}, { 0x001D, 9}, { 0x000B, 10}, { 0x0010, 6}, { 0x0022, 9},
{ 0x000A, 10}, { 0x000D, 6}, { 0x001C, 9}, { 0x0008, 10}, { 0x0012, 7}, { 0x001B, 9},
{ 0x0054, 12}, { 0x0014, 7}, { 0x001A, 9}, { 0x0057, 12}, { 0x0019, 8}, { 0x0009, 10},
{ 0x0018, 8}, { 0x0023, 11}, { 0x0017, 8}, { 0x0019, 9}, { 0x0018, 9}, { 0x0007, 10},
{ 0x0058, 12}, { 0x0007, 4}, { 0x000C, 6}, { 0x0016, 8}, { 0x0017, 9}, { 0x0006, 10},
{ 0x0005, 11}, { 0x0004, 11}, { 0x0059, 12}, { 0x000F, 6}, { 0x0016, 9}, { 0x0005, 10},
{ 0x000E, 6}, { 0x0004, 10}, { 0x0011, 7}, { 0x0024, 11}, { 0x0010, 7}, { 0x0025, 11},
{ 0x0013, 7}, { 0x005A, 12}, { 0x0015, 8}, { 0x005B, 12}, { 0x0014, 8}, { 0x0013, 8},
{ 0x001A, 8}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, { 0x0012, 9}, { 0x0011, 9},
{ 0x0026, 11}, { 0x0027, 11}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12},
{ 0x0003, 7}
},
{
{ 0x0002, 2}, { 0x000F, 4}, { 0x0015, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x0025, 9},
{ 0x0024, 9}, { 0x0021, 10}, { 0x0020, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11},
{ 0x0006, 3}, { 0x0014, 6}, { 0x001E, 8}, { 0x000F, 10}, { 0x0021, 11}, { 0x0050, 12},
{ 0x000E, 4}, { 0x001D, 8}, { 0x000E, 10}, { 0x0051, 12}, { 0x000D, 5}, { 0x0023, 9},
{ 0x000D, 10}, { 0x000C, 5}, { 0x0022, 9}, { 0x0052, 12}, { 0x000B, 5}, { 0x000C, 10},
{ 0x0053, 12}, { 0x0013, 6}, { 0x000B, 10}, { 0x0054, 12}, { 0x0012, 6}, { 0x000A, 10},
{ 0x0011, 6}, { 0x0009, 10}, { 0x0010, 6}, { 0x0008, 10}, { 0x0016, 7}, { 0x0055, 12},
{ 0x0015, 7}, { 0x0014, 7}, { 0x001C, 8}, { 0x001B, 8}, { 0x0021, 9}, { 0x0020, 9},
{ 0x001F, 9}, { 0x001E, 9}, { 0x001D, 9}, { 0x001C, 9}, { 0x001B, 9}, { 0x001A, 9},
{ 0x0022, 11}, { 0x0023, 11}, { 0x0056, 12}, { 0x0057, 12}, { 0x0007, 4}, { 0x0019, 9},
{ 0x0005, 11}, { 0x000F, 6}, { 0x0004, 11}, { 0x000E, 6}, { 0x000D, 6}, { 0x000C, 6},
{ 0x0013, 7}, { 0x0012, 7}, { 0x0011, 7}, { 0x0010, 7}, { 0x001A, 8}, { 0x0019, 8},
{ 0x0018, 8}, { 0x0017, 8}, { 0x0016, 8}, { 0x0015, 8}, { 0x0014, 8}, { 0x0013, 8},
{ 0x0018, 9}, { 0x0017, 9}, { 0x0016, 9}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9},
{ 0x0012, 9}, { 0x0011, 9}, { 0x0007, 10}, { 0x0006, 10}, { 0x0005, 10}, { 0x0004, 10},
{ 0x0024, 11}, { 0x0025, 11}, { 0x0026, 11}, { 0x0027, 11}, { 0x0058, 12}, { 0x0059, 12},
{ 0x005A, 12}, { 0x005B, 12}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12},
{ 0x0003, 7}
},
{
{ 0x0000, 2}, { 0x0003, 3}, { 0x000D, 4}, { 0x0005, 4}, { 0x001C, 5}, { 0x0016, 5},
{ 0x003F, 6}, { 0x003A, 6}, { 0x002E, 6}, { 0x0022, 6}, { 0x007B, 7}, { 0x0067, 7},
{ 0x005F, 7}, { 0x0047, 7}, { 0x0026, 7}, { 0x00EF, 8}, { 0x00CD, 8}, { 0x00C1, 8},
{ 0x00A9, 8}, { 0x004F, 8}, { 0x01F2, 9}, { 0x01DD, 9}, { 0x0199, 9}, { 0x0185, 9},
{ 0x015D, 9}, { 0x011B, 9}, { 0x03EF, 10}, { 0x03E1, 10}, { 0x03C8, 10}, { 0x0331, 10},
{ 0x0303, 10}, { 0x02F1, 10}, { 0x02A0, 10}, { 0x0233, 10}, { 0x0126, 10}, { 0x07C0, 11},
{ 0x076F, 11}, { 0x076C, 11}, { 0x0661, 11}, { 0x0604, 11}, { 0x0572, 11}, { 0x0551, 11},
{ 0x046A, 11}, { 0x0274, 11}, { 0x0F27, 12}, { 0x0F24, 12}, { 0x0EDB, 12}, { 0x0C8E, 12},
{ 0x0C0B, 12}, { 0x0C0A, 12}, { 0x0AE3, 12}, { 0x08D6, 12}, { 0x0490, 12}, { 0x0495, 12},
{ 0x1F19, 13}, { 0x1DB5, 13}, { 0x0009, 4}, { 0x0010, 5}, { 0x0029, 6}, { 0x0062, 7},
{ 0x00F3, 8}, { 0x00AD, 8}, { 0x01E5, 9}, { 0x0179, 9}, { 0x009C, 9}, { 0x03B1, 10},
{ 0x02AE, 10}, { 0x0127, 10}, { 0x076E, 11}, { 0x0570, 11}, { 0x0275, 11}, { 0x0F25, 12},
{ 0x0EC0, 12}, { 0x0AA0, 12}, { 0x08D7, 12}, { 0x1E4C, 13}, { 0x0008, 5}, { 0x0063, 7},
{ 0x00AF, 8}, { 0x017B, 9}, { 0x03B3, 10}, { 0x07DD, 11}, { 0x0640, 11}, { 0x0F8D, 12},
{ 0x0BC1, 12}, { 0x0491, 12}, { 0x0028, 6}, { 0x00C3, 8}, { 0x0151, 9}, { 0x02A1, 10},
{ 0x0573, 11}, { 0x0EC3, 12}, { 0x1F35, 13}, { 0x0065, 7}, { 0x01DA, 9}, { 0x02AF, 10},
{ 0x0277, 11}, { 0x08C9, 12}, { 0x1781, 13}, { 0x0025, 7}, { 0x0118, 9}, { 0x0646, 11},
{ 0x0AA6, 12}, { 0x1780, 13}, { 0x00C9, 8}, { 0x0321, 10}, { 0x0F9B, 12}, { 0x191E, 13},
{ 0x0048, 8}, { 0x07CC, 11}, { 0x0AA1, 12}, { 0x0180, 9}, { 0x0465, 11}, { 0x1905, 13},
{ 0x03E2, 10}, { 0x0EC1, 12}, { 0x3C9B, 14}, { 0x02F4, 10}, { 0x08C8, 12}, { 0x07C1, 11},
{ 0x0928, 13}, { 0x05E1, 11}, { 0x320D, 14}, { 0x0EC2, 12}, { 0x6418, 15}, { 0x1F34, 13},
{ 0x0078, 7}, { 0x0155, 9}, { 0x0552, 11}, { 0x191F, 13}, { 0x00FA, 8}, { 0x07DC, 11},
{ 0x1907, 13}, { 0x00AC, 8}, { 0x0249, 11}, { 0x13B1, 14}, { 0x01F6, 9}, { 0x0AE2, 12},
{ 0x01DC, 9}, { 0x04ED, 12}, { 0x0184, 9}, { 0x1904, 13}, { 0x0156, 9}, { 0x09D9, 13},
{ 0x03E7, 10}, { 0x0929, 13}, { 0x03B2, 10}, { 0x3B68, 14}, { 0x02F5, 10}, { 0x13B0, 14},
{ 0x0322, 10}, { 0x3B69, 14}, { 0x0234, 10}, { 0x7935, 15}, { 0x07C7, 11}, { 0xC833, 16},
{ 0x0660, 11}, { 0x7934, 15}, { 0x024B, 11}, { 0xC832, 16}, { 0x0AA7, 12}, { 0x1F18, 13},
{ 0x007A, 7}
},
{
{ 0x0002, 2}, { 0x0000, 3}, { 0x001E, 5}, { 0x0004, 5}, { 0x0012, 6}, { 0x0070, 7},
{ 0x001A, 7}, { 0x005F, 8}, { 0x0047, 8}, { 0x01D3, 9}, { 0x00B5, 9}, { 0x0057, 9},
{ 0x03B5, 10}, { 0x016D, 10}, { 0x0162, 10}, { 0x07CE, 11}, { 0x0719, 11}, { 0x0691, 11},
{ 0x02C6, 11}, { 0x0156, 11}, { 0x0F92, 12}, { 0x0D2E, 12}, { 0x0D20, 12}, { 0x059E, 12},
{ 0x0468, 12}, { 0x02A6, 12}, { 0x1DA2, 13}, { 0x1C60, 13}, { 0x1A43, 13}, { 0x0B1D, 13},
{ 0x08C0, 13}, { 0x055D, 13}, { 0x0003, 3}, { 0x000A, 5}, { 0x0077, 7}, { 0x00E5, 8},
{ 0x01D9, 9}, { 0x03E5, 10}, { 0x0166, 10}, { 0x0694, 11}, { 0x0152, 11}, { 0x059F, 12},
{ 0x1F3C, 13}, { 0x1A4B, 13}, { 0x055E, 13}, { 0x000C, 4}, { 0x007D, 7}, { 0x0044, 8},
{ 0x03E0, 10}, { 0x0769, 11}, { 0x0E31, 12}, { 0x1F26, 13}, { 0x055C, 13}, { 0x001B, 5},
{ 0x00E2, 8}, { 0x03A5, 10}, { 0x02C9, 11}, { 0x1F23, 13}, { 0x3B47, 14}, { 0x0007, 5},
{ 0x01D8, 9}, { 0x02D8, 11}, { 0x1F27, 13}, { 0x3494, 14}, { 0x0035, 6}, { 0x03E1, 10},
{ 0x059C, 12}, { 0x38C3, 14}, { 0x000C, 6}, { 0x0165, 10}, { 0x1D23, 13}, { 0x1638, 14},
{ 0x0068, 7}, { 0x0693, 11}, { 0x3A45, 14}, { 0x0020, 7}, { 0x0F90, 12}, { 0x7CF6, 15},
{ 0x00E8, 8}, { 0x058F, 12}, { 0x2CEF, 15}, { 0x0045, 8}, { 0x0B3A, 13}, { 0x01F1, 9},
{ 0x3B46, 14}, { 0x01A7, 9}, { 0x1676, 14}, { 0x0056, 9}, { 0x692A, 15}, { 0x038D, 10},
{ 0xE309, 16}, { 0x00AA, 10}, { 0x1C611, 17}, { 0x02DF, 11}, { 0xB3B9, 17}, { 0x02C8, 11},
{ 0x38C20, 18}, { 0x01B0, 11}, { 0x16390, 18}, { 0x0F9F, 12}, { 0x16771, 18}, { 0x0ED0, 12},
{ 0x71843, 19}, { 0x0D2A, 12}, { 0xF9E8C, 20}, { 0x0461, 12}, { 0xF9E8E, 20}, { 0x0B67, 13},
{ 0x055F, 13}, { 0x003F, 6}, { 0x006D, 9}, { 0x0E90, 12}, { 0x054E, 13}, { 0x0013, 6},
{ 0x0119, 10}, { 0x0B66, 13}, { 0x000B, 6}, { 0x0235, 11}, { 0x7CF5, 15}, { 0x0075, 7},
{ 0x0D24, 12}, { 0xF9E9, 16}, { 0x002E, 7}, { 0x1F22, 13}, { 0x0021, 7}, { 0x054F, 13},
{ 0x0014, 7}, { 0x3A44, 14}, { 0x00E4, 8}, { 0x7CF7, 15}, { 0x005E, 8}, { 0x7185, 15},
{ 0x0037, 8}, { 0x2C73, 15}, { 0x01DB, 9}, { 0x59DD, 16}, { 0x01C7, 9}, { 0x692B, 15},
{ 0x01A6, 9}, { 0x58E5, 16}, { 0x00B4, 9}, { 0x1F3D0, 17}, { 0x00B0, 9}, { 0xB1C9, 17},
{ 0x03E6, 10}, { 0x16770, 18}, { 0x016E, 10}, { 0x3E7A2, 18}, { 0x011B, 10}, { 0xF9E8D, 20},
{ 0x00D9, 10}, { 0xF9E8F, 20}, { 0x00A8, 10}, { 0x2C723, 19}, { 0x0749, 11}, { 0xE3084, 20},
{ 0x0696, 11}, { 0x58E45, 20}, { 0x02DE, 11}, { 0xB1C88, 21}, { 0x0231, 11}, { 0x1C610A, 21},
{ 0x01B1, 11}, { 0x71842D, 23}, { 0x0D2B, 12}, { 0x38C217, 22}, { 0x0D2F, 12}, { 0x163913, 22},
{ 0x05B2, 12}, { 0x163912, 22}, { 0x0469, 12}, { 0x71842C, 23}, { 0x1A42, 13}, { 0x08C1, 13},
{ 0x0073, 7}
}
};
/* which indexes point to last=1 entries in tables */
static const int vc1_last_decode_table[AC_MODES] = {
119, 99, 85, 81, 67, 58, 126, 109
};
static const uint8_t vc1_index_decode_table[AC_MODES][185][2] = {
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
{ 0, 17}, { 0, 18}, { 0, 19}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5},
{ 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13},
{ 1, 14}, { 1, 15}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 2, 6},
{ 2, 7}, { 2, 8}, { 2, 9}, { 2, 10}, { 2, 11}, { 2, 12}, { 3, 1}, { 3, 2},
{ 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, { 3, 7}, { 3, 8}, { 3, 9}, { 3, 10},
{ 3, 11}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 4, 6}, { 5, 1},
{ 5, 2}, { 5, 3}, { 5, 4}, { 5, 5}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4},
{ 7, 1}, { 7, 2}, { 7, 3}, { 7, 4}, { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4},
{ 9, 1}, { 9, 2}, { 9, 3}, { 9, 4}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1},
{ 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, { 12, 3}, { 13, 1}, { 13, 2}, { 13, 3},
{ 14, 1}, { 14, 2}, { 14, 3}, { 15, 1}, { 15, 2}, { 15, 3}, { 16, 1}, { 16, 2},
{ 17, 1}, { 17, 2}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1},
{ 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 0, 1},
{ 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 1, 1}, { 1, 2}, { 1, 3},
{ 1, 4}, { 1, 5}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2},
{ 3, 3}, { 3, 4}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 6, 1},
{ 6, 2}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1},
{ 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1},
{ 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1},
{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1},
{ 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1},
{ 37, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 1, 1},
{ 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, { 1, 9},
{ 1, 10}, { 1, 11}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 2, 6},
{ 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5}, { 3, 6},
{ 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 5, 1}, { 5, 2},
{ 5, 3}, { 5, 4}, { 5, 5}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1},
{ 7, 2}, { 7, 3}, { 7, 4}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2},
{ 9, 3}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, { 11, 2}, { 11, 3}, { 12, 1},
{ 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, { 16, 1},
{ 16, 2}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1},
{ 24, 1}, { 25, 1}, { 26, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5},
{ 0, 6}, { 0, 7}, { 0, 8}, { 0, 9}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4},
{ 1, 5}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2}, { 3, 3},
{ 3, 4}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1},
{ 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2},
{ 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2},
{ 14, 1}, { 14, 2}, { 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1},
{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1},
{ 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8},
{ 1, 9}, { 1, 10}, { 1, 11}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5},
{ 2, 6}, { 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5},
{ 3, 6}, { 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 5, 1},
{ 5, 2}, { 5, 3}, { 5, 4}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1},
{ 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, { 9, 3},
{ 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, { 11, 2}, { 11, 3}, { 12, 1}, { 12, 2},
{ 12, 3}, { 13, 1}, { 13, 2}, { 13, 3}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2},
{ 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 0, 1}, { 0, 2}, { 0, 3},
{ 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 2, 1}, { 2, 2}, { 2, 3},
{ 3, 1}, { 3, 2}, { 3, 3}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1},
{ 6, 2}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1},
{ 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1},
{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1},
{ 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 1, 1}, { 1, 2},
{ 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 2, 1},
{ 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4},
{ 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4},
{ 6, 1}, { 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, { 8, 2},
{ 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1},
{ 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, { 12, 3}, { 13, 1}, { 13, 2}, { 14, 1},
{ 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1},
{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1},
{ 29, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 1, 1}, { 1, 2},
{ 1, 3}, { 1, 4}, { 2, 1}, { 2, 2}, { 2, 3}, { 3, 1}, { 3, 2}, { 3, 3},
{ 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2}, { 7, 1}, { 7, 2},
{ 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2}, { 11, 1}, { 11, 2},
{ 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2},
{ 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1},
{ 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 31, 1},
{ 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1},
{ 40, 1}, { 41, 1}, { 42, 1}, { 43, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24},
{ 0, 25}, { 0, 26}, { 0, 27}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5},
{ 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 1, 10}, { 2, 1}, { 2, 2}, { 2, 3},
{ 2, 4}, { 2, 5}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 4, 1}, { 4, 2},
{ 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1}, { 6, 2}, { 6, 3}, { 7, 1},
{ 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 11, 1},
{ 12, 1}, { 13, 1}, { 14, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5},
{ 0, 6}, { 0, 7}, { 0, 8}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2},
{ 3, 1}, { 3, 2}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2},
{ 7, 1}, { 8, 1}, { 9, 1}, { 10, 1}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1},
{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4},
{ 1, 5}, { 1, 6}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2},
{ 3, 3}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1},
{ 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2},
{ 10, 1}, { 10, 2}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, { 15, 1}, { 16, 1},
{ 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1},
{ 25, 1}, { 26, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 1, 1}, { 1, 2}, { 2, 1},
{ 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1}, { 8, 1}, { 9, 1}, { 10, 1},
{ 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, { 15, 1}, { 16, 1}, { 17, 1}, { 18, 1},
{ 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1},
{ 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1},
{ 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1}, { 40, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24},
{ 0, 25}, { 0, 26}, { 0, 27}, { 0, 28}, { 0, 29}, { 0, 30}, { 0, 31}, { 0, 32},
{ 0, 33}, { 0, 34}, { 0, 35}, { 0, 36}, { 0, 37}, { 0, 38}, { 0, 39}, { 0, 40},
{ 0, 41}, { 0, 42}, { 0, 43}, { 0, 44}, { 0, 45}, { 0, 46}, { 0, 47}, { 0, 48},
{ 0, 49}, { 0, 50}, { 0, 51}, { 0, 52}, { 0, 53}, { 0, 54}, { 0, 55}, { 0, 56},
{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8},
{ 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, { 1, 14}, { 1, 15}, { 1, 16},
{ 1, 17}, { 1, 18}, { 1, 19}, { 1, 20}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4},
{ 2, 5}, { 2, 6}, { 2, 7}, { 2, 8}, { 2, 9}, { 2, 10}, { 3, 1}, { 3, 2},
{ 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, { 3, 7}, { 4, 1}, { 4, 2}, { 4, 3},
{ 4, 4}, { 4, 5}, { 4, 6}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 5, 5},
{ 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1}, { 7, 2}, { 7, 3}, { 8, 1},
{ 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, { 10, 1}, { 10, 2}, { 11, 1},
{ 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 0, 1}, { 0, 2},
{ 0, 3}, { 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, { 2, 3},
{ 3, 1}, { 3, 2}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2},
{ 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2},
{ 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2},
{ 15, 1}, { 16, 1}
},
{
{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8},
{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16},
{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24},
{ 0, 25}, { 0, 26}, { 0, 27}, { 0, 28}, { 0, 29}, { 0, 30}, { 0, 31}, { 0, 32},
{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8},
{ 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, { 2, 1}, { 2, 2}, { 2, 3},
{ 2, 4}, { 2, 5}, { 2, 6}, { 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3},
{ 3, 4}, { 3, 5}, { 3, 6}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5},
{ 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4},
{ 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2},
{ 9, 3}, { 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1},
{ 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 16, 2}, { 17, 1},
{ 17, 2}, { 18, 1}, { 18, 2}, { 19, 1}, { 19, 2}, { 20, 1}, { 20, 2}, { 21, 1},
{ 21, 2}, { 22, 1}, { 22, 2}, { 23, 1}, { 24, 1}, { 0, 1}, { 0, 2}, { 0, 3},
{ 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, { 2, 3}, { 3, 1},
{ 3, 2}, { 3, 3}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2},
{ 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2},
{ 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2},
{ 15, 1}, { 15, 2}, { 16, 1}, { 16, 2}, { 17, 1}, { 17, 2}, { 18, 1}, { 18, 2},
{ 19, 1}, { 19, 2}, { 20, 1}, { 20, 2}, { 21, 1}, { 21, 2}, { 22, 1}, { 22, 2},
{ 23, 1}, { 23, 2}, { 24, 1}, { 24, 2}, { 25, 1}, { 25, 2}, { 26, 1}, { 26, 2},
{ 27, 1}, { 27, 2}, { 28, 1}, { 28, 2}, { 29, 1}, { 30, 1}
}
};
static const uint8_t vc1_delta_level_table[AC_MODES][31] = {
{
19, 15, 12, 11, 6, 5, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1
},
{
23, 11, 8, 7, 5, 5, 4, 4, 3, 3,
3, 3, 2, 2, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
},
{
16, 11, 8, 7, 5, 4, 4, 3, 3, 3,
3, 3, 3, 3, 2, 2, 1, 1, 1, 1,
1
},
{
14, 9, 5, 4, 4, 4, 3, 3, 3, 3,
3, 3, 3, 2, 2, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1,
1
},
{
27, 10, 5, 4, 3, 3, 3, 3, 2, 2,
1, 1, 1, 1, 1
},
{
12, 6, 4, 3, 3, 3, 3, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
},
{
56, 20, 10, 7, 6, 5, 4, 3, 3, 3,
2, 2, 2, 2, 1
},
{
32, 13, 8, 6, 5, 4, 4, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 1, 1
}
};
static const uint8_t vc1_last_delta_level_table[AC_MODES][44] = {
{
6, 5, 4, 4, 3, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
},
{
9, 5, 4, 4, 3, 3, 3, 2, 2, 2,
2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
},
{
4, 4, 3, 3, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
},
{
5, 4, 3, 3, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1
},
{
8, 3, 2, 2, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1
},
{
3, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1
},
{
4, 3, 3, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 1
},
{
4, 3, 3, 3, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
1
}
};
static const uint8_t vc1_delta_run_table[AC_MODES][57] = {
{
-1, 30, 17, 15, 9, 5, 4, 3, 3, 3,
3, 3, 2, 1, 1, 1, 0, 0, 0,
0
},
{
-1, 26, 16, 11, 7, 5, 3, 3, 2, 1,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
},
{
-1, 20, 15, 13, 6, 4, 3, 3, 2, 1,
1, 1, 0, 0, 0, 0, 0
},
{
-1, 29, 15, 12, 5, 2, 1, 1, 1, 1,
0, 0, 0, 0, 0
},
{
-1, 14, 9, 7, 3, 2, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
},
{
-1, 26, 10, 6, 2, 1, 1, 0, 0, 0,
0, 0, 0
},
{
-1, 14, 13, 9, 6, 5, 4, 3, 2, 2,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
},
{
-1, 24, 22, 9, 6, 4, 3, 2, 2, 1,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
}
};
static const uint8_t vc1_last_delta_run_table[AC_MODES][10] = {
{
-1, 37, 15, 4, 3, 1, 0
},
{
-1, 36, 14, 6, 3, 1, 0, 0, 0,
0
},
{
-1, 26, 13, 3, 1
},
{
-1, 43, 15, 3, 1, 0
},
{
-1, 20, 6, 1, 0, 0, 0, 0, 0
},
{
-1, 40, 1, 0
},
{
-1, 16, 14, 2, 0
},
{
-1, 30, 28, 3, 0
}
};
#endif /* FFMPEG_VC1ACDATA_H */
@@ -0,0 +1,645 @@
/*
* VC-1 and WMV3 decoder
* copyright (c) 2006 Konstantin Shishkov
* (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vc1data.c
* VC-1 tables.
*/
#include "avcodec.h"
#include "vc1.h"
#include "vc1data.h"
/** Table for conversion between TTBLK and TTMB */
const int ff_vc1_ttblk_to_tt[3][8] = {
{ TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT },
{ TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP },
{ TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP }
};
const int ff_vc1_ttfrm_to_tt[4] = { TT_8X8, TT_8X4, TT_4X8, TT_4X4 };
/** MV P mode - the 5th element is only used for mode 1 */
const uint8_t ff_vc1_mv_pmode_table[2][5] = {
{ MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV },
{ MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN }
};
const uint8_t ff_vc1_mv_pmode_table2[2][4] = {
{ MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV },
{ MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN }
};
const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 },
ff_vc1_fps_dr[2] = { 1000, 1001 };
const uint8_t ff_vc1_pquant_table[3][32] = {
{ /* Implicit quantizer */
0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31
},
{ /* Explicit quantizer, pquantizer uniform */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
},
{ /* Explicit quantizer, pquantizer non-uniform */
0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31
}
};
/** @name VC-1 VLC tables and defines
* @todo TODO move this into the context
*/
//@{
#define VC1_BFRACTION_VLC_BITS 7
VLC ff_vc1_bfraction_vlc;
#define VC1_IMODE_VLC_BITS 4
VLC ff_vc1_imode_vlc;
#define VC1_NORM2_VLC_BITS 3
VLC ff_vc1_norm2_vlc;
#define VC1_NORM6_VLC_BITS 9
VLC ff_vc1_norm6_vlc;
/* Could be optimized, one table only needs 8 bits */
#define VC1_TTMB_VLC_BITS 9 //12
VLC ff_vc1_ttmb_vlc[3];
#define VC1_MV_DIFF_VLC_BITS 9 //15
VLC ff_vc1_mv_diff_vlc[4];
#define VC1_CBPCY_P_VLC_BITS 9 //14
VLC ff_vc1_cbpcy_p_vlc[4];
#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6
VLC ff_vc1_4mv_block_pattern_vlc[4];
#define VC1_TTBLK_VLC_BITS 5
VLC ff_vc1_ttblk_vlc[3];
#define VC1_SUBBLKPAT_VLC_BITS 6
VLC ff_vc1_subblkpat_vlc[3];
VLC ff_vc1_ac_coeff_table[8];
//@}
#if B_FRACTION_DEN==840 //original bfraction from vc9data.h, not conforming to standard
/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */
const int16_t ff_vc1_bfraction_lut[23] = {
420 /*1/2*/, 280 /*1/3*/, 560 /*2/3*/, 210 /*1/4*/,
630 /*3/4*/, 168 /*1/5*/, 336 /*2/5*/,
504 /*3/5*/, 672 /*4/5*/, 140 /*1/6*/, 700 /*5/6*/,
120 /*1/7*/, 240 /*2/7*/, 360 /*3/7*/, 480 /*4/7*/,
600 /*5/7*/, 720 /*6/7*/, 105 /*1/8*/, 315 /*3/8*/,
525 /*5/8*/, 735 /*7/8*/,
-1 /*inv.*/, 0 /*BI fm*/
};
#else
/* pre-computed scales for all bfractions and base=256 */
const int16_t ff_vc1_bfraction_lut[23] = {
128 /*1/2*/, 85 /*1/3*/, 170 /*2/3*/, 64 /*1/4*/,
192 /*3/4*/, 51 /*1/5*/, 102 /*2/5*/,
153 /*3/5*/, 204 /*4/5*/, 43 /*1/6*/, 215 /*5/6*/,
37 /*1/7*/, 74 /*2/7*/, 111 /*3/7*/, 148 /*4/7*/,
185 /*5/7*/, 222 /*6/7*/, 32 /*1/8*/, 96 /*3/8*/,
160 /*5/8*/, 224 /*7/8*/,
-1 /*inv.*/, 0 /*BI fm*/
};
#endif
const uint8_t ff_vc1_bfraction_bits[23] = {
3, 3, 3, 3,
3, 3, 3,
7, 7, 7, 7,
7, 7, 7, 7,
7, 7, 7, 7,
7, 7,
7, 7
};
const uint8_t ff_vc1_bfraction_codes[23] = {
0, 1, 2, 3,
4, 5, 6,
112, 113, 114, 115,
116, 117, 118, 119,
120, 121, 122, 123,
124, 125,
126, 127
};
//Same as H.264
const AVRational ff_vc1_pixel_aspect[16]={
{0, 1},
{1, 1},
{12, 11},
{10, 11},
{16, 11},
{40, 33},
{24, 11},
{20, 11},
{32, 11},
{80, 33},
{18, 11},
{15, 11},
{64, 33},
{160, 99},
{0, 1},
{0, 1}
};
/* BitPlane IMODE - such a small table... */
const uint8_t ff_vc1_imode_codes[7] = {
0, 2, 1, 3, 1, 2, 3
};
const uint8_t ff_vc1_imode_bits[7] = {
4, 2, 3, 2, 4, 3, 3
};
/* Normal-2 imode */
const uint8_t ff_vc1_norm2_codes[4] = {
0, 4, 5, 3
};
const uint8_t ff_vc1_norm2_bits[4] = {
1, 3, 3, 2
};
const uint16_t ff_vc1_norm6_codes[64] = {
0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E,
0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037,
0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036,
0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007,
};
const uint8_t ff_vc1_norm6_bits[64] = {
1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13,
4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9,
4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9,
8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6,
};
#if 0
/* Normal-6 imode */
const uint8_t ff_vc1_norm6_spec[64][5] = {
{ 0, 1, 1 },
{ 1, 2, 4 },
{ 2, 3, 4 },
{ 3, 0, 8 },
{ 4, 4, 4 },
{ 5, 1, 8 },
{ 6, 2, 8 },
{ 7, 2, 5, 7, 5 },
{ 8, 5, 4 },
{ 9, 3, 8 },
{10, 4, 8 },
{11, 2, 5, 11, 5 },
{12, 5, 8 },
{13, 2, 5, 13, 5 },
{14, 2, 5, 14, 5 },
{15, 3, 5, 14, 8 },
{16, 6, 4 },
{17, 6, 8 },
{18, 7, 8 },
{19, 2, 5, 19, 5 },
{20, 8, 8 },
{21, 2, 5, 21, 5 },
{22, 2, 5, 22, 5 },
{23, 3, 5, 13, 8 },
{24, 9, 8 },
{25, 2, 5, 25, 5 },
{26, 2, 5, 26, 5 },
{27, 3, 5, 12, 8 },
{28, 2, 5, 28, 5 },
{29, 3, 5, 11, 8 },
{30, 3, 5, 10, 8 },
{31, 3, 5, 7, 4 },
{32, 7, 4 },
{33, 10, 8 },
{34, 11, 8 },
{35, 2, 5, 3, 5 },
{36, 12, 8 },
{37, 2, 5, 5, 5 },
{38, 2, 5, 6, 5 },
{39, 3, 5, 9, 8 },
{40, 13, 8 },
{41, 2, 5, 9, 5 },
{42, 2, 5, 10, 5 },
{43, 3, 5, 8, 8 },
{44, 2, 5, 12, 5 },
{45, 3, 5, 7, 8 },
{46, 3, 5, 6, 8 },
{47, 3, 5, 6, 4 },
{48, 14, 8 },
{49, 2, 5, 17, 5 },
{50, 2, 5, 18, 5 },
{51, 3, 5, 5, 8 },
{52, 2, 5, 20, 5 },
{53, 3, 5, 4, 8 },
{54, 3, 5, 3, 8 },
{55, 3, 5, 5, 4 },
{56, 2, 5, 24, 5 },
{57, 3, 5, 2, 8 },
{58, 3, 5, 1, 8 },
{59, 3, 5, 4, 4 },
{60, 3, 5, 0, 8 },
{61, 3, 5, 3, 4 },
{62, 3, 5, 2, 4 },
{63, 3, 5, 1, 1 },
};
#endif
/* 4MV Block pattern VLC tables */
const uint8_t ff_vc1_4mv_block_pattern_codes[4][16] = {
{ 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2},
{ 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0},
{ 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0},
{ 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10}
};
const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = {
{ 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2},
{ 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2},
{ 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3},
{ 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4}
};
const uint8_t wmv3_dc_scale_table[32]={
0, 2, 4, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21
};
/* P-Picture CBPCY VLC tables */
#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV?
const uint16_t ff_vc1_cbpcy_p_codes[4][64] = {
{
0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119,
1, 54, 96, 8, 10, 111, 5, 15, 12, 10, 2, 12, 13, 115, 53, 63,
1, 7, 1, 7, 14, 12, 4, 14, 1, 9, 97, 11, 7, 58, 52, 62,
4, 103, 1, 9, 11, 56, 101, 118, 4, 110, 100, 30, 2, 5, 4, 3
},
{
0, 9, 1, 18, 5, 14, 237, 26, 3, 121, 3, 22, 13, 16, 6, 30,
2, 10, 1, 20, 12, 241, 5, 28, 16, 12, 3, 24, 28, 124, 239, 247,
1, 240, 1, 19, 18, 15, 4, 27, 1, 122, 2, 23, 1, 17, 7, 31,
1, 11, 2, 21, 19, 246, 238, 29, 17, 13, 236, 25, 58, 63, 8, 125
},
{
0, 201, 25, 231, 5, 221, 1, 3, 2, 414, 2, 241, 16, 225, 195, 492,
2, 412, 1, 240, 7, 224, 98, 245, 1, 220, 96, 5, 9, 230, 101, 247,
1, 102, 1, 415, 24, 3, 2, 244, 3, 54, 3, 484, 17, 114, 200, 493,
3, 413, 1, 4, 13, 113, 99, 485, 4, 111, 194, 243, 5, 29, 26, 31
},
{
0, 28, 12, 44, 3, 36, 20, 52, 2, 32, 16, 48, 8, 40, 24, 28,
1, 30, 14, 46, 6, 38, 22, 54, 3, 34, 18, 50, 10, 42, 26, 30,
1, 29, 13, 45, 5, 37, 21, 53, 2, 33, 17, 49, 9, 41, 25, 29,
1, 31, 15, 47, 7, 39, 23, 55, 4, 35, 19, 51, 11, 43, 27, 31
}
};
const uint8_t ff_vc1_cbpcy_p_bits[4][64] = {
{
13, 13, 7, 13, 7, 13, 13, 12, 6, 13, 7, 12, 6, 8, 8, 8,
5, 7, 8, 12, 6, 8, 13, 12, 7, 13, 13, 12, 6, 8, 7, 7,
6, 13, 8, 12, 7, 13, 13, 12, 7, 13, 8, 12, 5, 7, 7, 7,
6, 8, 13, 12, 6, 7, 8, 8, 5, 8, 8, 6, 3, 3, 3, 2
},
{
14, 13, 8, 13, 3, 13, 8, 13, 3, 7, 8, 13, 4, 13, 13, 13,
3, 13, 13, 13, 4, 8, 13, 13, 5, 13, 13, 13, 5, 7, 8, 8,
3, 8, 14, 13, 5, 13, 13, 13, 4, 7, 13, 13, 6, 13, 13, 13,
5, 13, 8, 13, 5, 8, 8, 13, 5, 13, 8, 13, 6, 6, 13, 7
},
{
13, 8, 6, 8, 4, 8, 13, 12, 4, 9, 8, 8, 5, 8, 8, 9,
5, 9, 10, 8, 4, 8, 7, 8, 6, 8, 7, 13, 4, 8, 7, 8,
5, 7, 8, 9, 6, 13, 13, 8, 4, 6, 8, 9, 5, 7, 8, 9,
5, 9, 9, 13, 5, 7, 7, 9, 4, 7, 8, 8, 3, 5, 5, 5
},
{
9, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 8,
3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8
}
};
#else
const uint16_t ff_vc1_cbpcy_p_codes[4][64] = {
{
0, 1, 1, 4, 5, 1, 12, 4, 13, 14, 10, 11, 12, 7, 13, 2,
15, 1, 96, 1, 49, 97, 2, 100, 3, 4, 5, 101, 102, 52, 53, 4,
6, 7, 54, 103, 8, 9, 10, 110, 11, 12, 111, 56, 114, 58, 115, 5,
13, 7, 8, 9, 10, 11, 12, 30, 13, 14, 15, 118, 119, 62, 63, 3
},
{
0, 1, 2, 1, 3, 1, 16, 17, 5, 18, 12, 19, 13, 1, 28, 58,
1, 1, 1, 2, 3, 2, 3, 236, 237, 4, 5, 238, 6, 7, 239, 8,
9, 240, 10, 11, 121, 122, 12, 13, 14, 15, 241, 246, 16, 17, 124, 63,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 247, 125
},
{
0, 1, 2, 3, 2, 3, 1, 4, 5, 24, 7, 13, 16, 17, 9, 5,
25, 1, 1, 1, 2, 3, 96, 194, 1, 2, 98, 99, 195, 200, 101, 26,
201, 102, 412, 413, 414, 54, 220, 111, 221, 3, 224, 113, 225, 114, 230, 29,
231, 415, 240, 4, 241, 484, 5, 243, 3, 244, 245, 485, 492, 493, 247, 31
},
{
0, 1, 1, 1, 2, 2, 3, 4, 3, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 28, 29, 30, 31
}
};
const uint8_t ff_vc1_cbpcy_p_bits[4][64] = {
{
13, 6, 5, 6, 6, 7, 7, 5, 7, 7, 6, 6, 6, 5, 6, 3,
7, 8, 8, 13, 7, 8, 13, 8, 13, 13, 13, 8, 8, 7, 7, 3,
13, 13, 7, 8, 13, 13, 13, 8, 13, 13, 8, 7, 8, 7, 8, 3,
13, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 8, 8, 7, 7, 2
},
{
14, 3, 3, 5, 3, 4, 5, 5, 3, 5, 4, 5, 4, 6, 5, 6,
8, 14, 13, 8, 8, 13, 13, 8, 8, 13, 13, 8, 13, 13, 8, 13,
13, 8, 13, 13, 7, 7, 13, 13, 13, 13, 8, 8, 13, 13, 7, 6,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 7
},
{
13, 5, 5, 5, 4, 4, 6, 4, 4, 6, 4, 5, 5, 5, 4, 3,
6, 8, 10, 9, 8, 8, 7, 8, 13, 13, 7, 7, 8, 8, 7, 5,
8, 7, 9, 9, 9, 6, 8, 7, 8, 13, 8, 7, 8, 7, 8, 5,
8, 9, 8, 13, 8, 9, 13, 8, 12, 8, 8, 9, 9, 9, 8, 5
},
{
9, 2, 3, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8
}
};
#endif
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
* 8x4:B:btm 8x4:B:top 8x4:B:both,
* 4x8:B:right 4x8:B:left 4x8:B:both
* 4x4:B 8x8:MB
* 8x4:MB:btm 8x4:MB:top 8x4,MB,both
* 4x8,MB,right 4x8,MB,left
* 4x4,MB */
const uint16_t ff_vc1_ttmb_codes[3][16] = {
{
0x0003,
0x002E, 0x005F, 0x0000,
0x0016, 0x0015, 0x0001,
0x0004, 0x0014,
0x02F1, 0x0179, 0x017B,
0x0BC0, 0x0BC1, 0x05E1,
0x017A
},
{
0x0006,
0x0006, 0x0003, 0x0007,
0x000F, 0x000E, 0x0000,
0x0002, 0x0002,
0x0014, 0x0011, 0x000B,
0x0009, 0x0021, 0x0015,
0x0020
},
{
0x0006,
0x0000, 0x000E, 0x0005,
0x0002, 0x0003, 0x0003,
0x000F, 0x0002,
0x0081, 0x0021, 0x0009,
0x0101, 0x0041, 0x0011,
0x0100
}
};
const uint8_t ff_vc1_ttmb_bits[3][16] = {
{
2,
6, 7, 2,
5, 5, 2,
3, 5,
10, 9, 9,
12, 12, 11,
9
},
{
3,
4, 4, 4,
4, 4, 3,
3, 2,
7, 7, 6,
6, 8, 7,
8
},
{
3,
3, 4, 5,
3, 3, 4,
4, 2,
10, 8, 6,
11, 9, 7,
11
}
};
/* TTBLK (Transform Type per Block) tables */
const uint8_t ff_vc1_ttblk_codes[3][8] = {
{ 0, 1, 3, 5, 16, 17, 18, 19},
{ 3, 0, 1, 2, 3, 5, 8, 9},
{ 1, 0, 1, 4, 6, 7, 10, 11}
};
const uint8_t ff_vc1_ttblk_bits[3][8] = {
{ 2, 2, 2, 3, 5, 5, 5, 5},
{ 2, 3, 3, 3, 3, 3, 4, 4},
{ 2, 3, 3, 3, 3, 3, 4, 4}
};
/* SUBBLKPAT tables, p93-94, reordered */
const uint8_t ff_vc1_subblkpat_codes[3][15] = {
{ 14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1},
{ 14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1},
{ 5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15}
};
const uint8_t ff_vc1_subblkpat_bits[3][15] = {
{ 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1},
{ 4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2},
{ 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4}
};
/* MV differential tables, p265 */
const uint16_t ff_vc1_mv_diff_codes[4][73] = {
{
0, 2, 3, 8, 576, 3, 2, 6,
5, 577, 578, 7, 8, 9, 40, 19,
37, 82, 21, 22, 23, 579, 580, 166,
96, 167, 49, 194, 195, 581, 582, 583,
292, 293, 294, 13, 2, 7, 24, 50,
102, 295, 13, 7, 8, 18, 50, 103,
38, 20, 21, 22, 39, 204, 103, 23,
24, 25, 104, 410, 105, 106, 107, 108,
109, 220, 411, 442, 222, 443, 446, 447,
7 /* 73 elements */
},
{
0, 4, 5, 3, 4, 3, 4, 5,
20, 6, 21, 44, 45, 46, 3008, 95,
112, 113, 57, 3009, 3010, 116, 117, 3011,
118, 3012, 3013, 3014, 3015, 3016, 3017, 3018,
3019, 3020, 3021, 3022, 1, 4, 15, 160,
161, 41, 6, 11, 42, 162, 43, 119,
56, 57, 58, 163, 236, 237, 3023, 119,
120, 242, 122, 486, 1512, 487, 246, 494,
1513, 495, 1514, 1515, 1516, 1517, 1518, 1519,
31 /* 73 elements */
},
{
0, 512, 513, 514, 515, 2, 3, 258,
259, 260, 261, 262, 263, 264, 265, 266,
267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282,
283, 284, 285, 286, 1, 5, 287, 288,
289, 290, 6, 7, 291, 292, 293, 294,
295, 296, 297, 298, 299, 300, 301, 302,
303, 304, 305, 306, 307, 308, 309, 310,
311, 312, 313, 314, 315, 316, 317, 318,
319 /* 73 elements */
},
{
0, 1, 1, 2, 3, 4, 1, 5,
4, 3, 5, 8, 6, 9, 10, 11,
12, 7, 104, 14, 105, 4, 10, 15,
11, 6, 14, 8, 106, 107, 108, 15,
109, 9, 55, 10, 1, 2, 1, 2,
3, 12, 6, 2, 6, 7, 28, 7,
15, 8, 5, 18, 29, 152, 77, 24,
25, 26, 39, 108, 13, 109, 55, 56,
57, 116, 11, 153, 234, 235, 118, 119,
15 /* 73 elements */
}
};
const uint8_t ff_vc1_mv_diff_bits[4][73] = {
{
6, 7, 7, 8, 14, 6, 5, 6, 7, 14, 14, 6, 6, 6, 8, 9,
10, 9, 7, 7, 7, 14, 14, 10, 9, 10, 8, 10, 10, 14, 14, 14,
13, 13, 13, 6, 3, 5, 6, 8, 9, 13, 5, 4, 4, 5, 7, 9,
6, 5, 5, 5, 6, 9, 8, 5, 5, 5, 7, 10, 7, 7, 7, 7,
7, 8, 10, 9, 8, 9, 9, 9, 3 /* 73 elements */
},
{
5, 7, 7, 6, 6, 5, 5, 6, 7, 5, 7, 8, 8, 8, 14, 9,
9, 9, 8, 14, 14, 9, 9, 14, 9, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 2, 3, 6, 8, 8, 6, 3, 4, 6, 8, 6, 9,
6, 6, 6, 8, 8, 8, 14, 7, 7, 8, 7, 9, 13, 9, 8, 9,
13, 9, 13, 13, 13, 13, 13, 13, 5 /* 73 elements */
},
{
3, 12, 12, 12, 12, 3, 4, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 1, 5, 11, 11, 11, 11, 4, 4, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11 /* 73 elements */
},
{
15, 11, 15, 15, 15, 15, 12, 15, 12, 11, 12, 12, 15, 12, 12, 12,
12, 15, 15, 12, 15, 10, 11, 12, 11, 10, 11, 10, 15, 15, 15, 11,
15, 10, 14, 10, 4, 4, 5, 7, 8, 9, 5, 3, 4, 5, 6, 8,
5, 4, 3, 5, 6, 8, 7, 5, 5, 5, 6, 7, 9, 7, 6, 6,
6, 7, 10, 8, 8, 8, 7, 7, 4 /* 73 elements */
}
};
/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
/* Table 232 */
const int8_t ff_vc1_simple_progressive_4x4_zz [16] =
{
0, 8, 16, 1,
9, 24, 17, 2,
10, 18, 25, 3,
11, 26, 19, 27
};
const int8_t ff_vc1_adv_progressive_8x4_zz [32] = /* Table 233 */
{
0, 8, 1, 16, 2, 9, 10, 3,
24, 17, 4, 11, 18, 12, 5, 19,
25, 13, 20, 26, 27, 6, 21, 28,
14, 22, 29, 7, 30, 15, 23, 31
};
const int8_t ff_vc1_adv_progressive_4x8_zz [32] = /* Table 234 */
{
0, 1, 8, 2,
9, 16, 17, 24,
10, 32, 25, 18,
40, 3, 33, 26,
48, 11, 56, 41,
34, 49, 57, 42,
19, 50, 27, 58,
35, 43, 51, 59
};
const int8_t ff_vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */
{
0, 8, 1, 16, 24, 9, 2, 32,
40, 48, 56, 17, 10, 3, 25, 18,
11, 4, 33, 41, 49, 57, 26, 34,
42, 50, 58, 19, 12, 5, 27, 20,
13, 6, 35, 28, 21, 14, 7, 15,
22, 29, 36, 43, 51, 59, 60, 52,
44, 37, 30, 23, 31, 38, 45, 53,
61, 62, 54, 46, 39, 47, 55, 63
};
const int8_t ff_vc1_adv_interlaced_8x4_zz [32] = /* Table 236 */
{
0, 8, 16, 24, 1, 9, 2, 17,
25, 10, 3, 18, 26, 4, 11, 19,
12, 5, 13, 20, 27, 6, 21, 28,
14, 22, 29, 7, 30, 15, 23, 31
};
const int8_t ff_vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */
{
0, 1, 2, 8,
16, 9, 24, 17,
10, 3, 32, 40,
48, 56, 25, 18,
33, 26, 41, 34,
49, 57, 11, 42,
19, 50, 27, 58,
35, 43, 51, 59
};
const int8_t ff_vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */
{
0, 8, 16, 24,
1, 9, 17, 2,
25, 10, 18, 3,
26, 11, 19, 27
};
/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
const int32_t ff_vc1_dqscale[63] = {
0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000,
0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000,
0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB,
0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000,
0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A,
0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555,
0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249,
0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000
};
@@ -0,0 +1,157 @@
/*
* VC-1 and WMV3 decoder
* copyright (c) 2006 Konstantin Shishkov
* (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vc1data.h
* VC-1 tables.
*/
#ifndef FFMPEG_VC1DATA_H
#define FFMPEG_VC1DATA_H
#include <stdint.h>
#include "libavutil/rational.h"
#include "bitstream.h"
/** Table for conversion between TTBLK and TTMB */
extern const int ff_vc1_ttblk_to_tt[3][8];
extern const int ff_vc1_ttfrm_to_tt[4];
/** MV P mode - the 5th element is only used for mode 1 */
extern const uint8_t ff_vc1_mv_pmode_table[2][5];
extern const uint8_t ff_vc1_mv_pmode_table2[2][4];
extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2];
extern const uint8_t ff_vc1_pquant_table[3][32];
/** @name VC-1 VLC tables and defines
* @todo TODO move this into the context
*/
//@{
#define VC1_BFRACTION_VLC_BITS 7
extern VLC ff_vc1_bfraction_vlc;
#define VC1_IMODE_VLC_BITS 4
extern VLC ff_vc1_imode_vlc;
#define VC1_NORM2_VLC_BITS 3
extern VLC ff_vc1_norm2_vlc;
#define VC1_NORM6_VLC_BITS 9
extern VLC ff_vc1_norm6_vlc;
/* Could be optimized, one table only needs 8 bits */
#define VC1_TTMB_VLC_BITS 9 //12
extern VLC ff_vc1_ttmb_vlc[3];
#define VC1_MV_DIFF_VLC_BITS 9 //15
extern VLC ff_vc1_mv_diff_vlc[4];
#define VC1_CBPCY_P_VLC_BITS 9 //14
extern VLC ff_vc1_cbpcy_p_vlc[4];
#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6
extern VLC ff_vc1_4mv_block_pattern_vlc[4];
#define VC1_TTBLK_VLC_BITS 5
extern VLC ff_vc1_ttblk_vlc[3];
#define VC1_SUBBLKPAT_VLC_BITS 6
extern VLC ff_vc1_subblkpat_vlc[3];
extern VLC ff_vc1_ac_coeff_table[8];
//@}
#if 0 //original bfraction from vc9data.h, not conforming to standard
/* Denominator used for ff_vc1_bfraction_lut */
#define B_FRACTION_DEN 840
/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */
extern const int16_t ff_vc1_bfraction_lut[23];
#else
/* Denominator used for ff_vc1_bfraction_lut */
#define B_FRACTION_DEN 256
/* pre-computed scales for all bfractions and base=256 */
extern const int16_t ff_vc1_bfraction_lut[23];
#endif
extern const uint8_t ff_vc1_bfraction_bits[23];
extern const uint8_t ff_vc1_bfraction_codes[23];
//Same as H.264
extern const AVRational ff_vc1_pixel_aspect[16];
/* BitPlane IMODE - such a small table... */
extern const uint8_t ff_vc1_imode_codes[7];
extern const uint8_t ff_vc1_imode_bits[7];
/* Normal-2 imode */
extern const uint8_t ff_vc1_norm2_codes[4];
extern const uint8_t ff_vc1_norm2_bits[4];
extern const uint16_t ff_vc1_norm6_codes[64];
extern const uint8_t ff_vc1_norm6_bits[64];
/* Normal-6 imode */
extern const uint8_t ff_vc1_norm6_spec[64][5];
/* 4MV Block pattern VLC tables */
extern const uint8_t ff_vc1_4mv_block_pattern_codes[4][16];
extern const uint8_t ff_vc1_4mv_block_pattern_bits[4][16];
extern const uint8_t wmv3_dc_scale_table[32];
/* P-Picture CBPCY VLC tables */
extern const uint16_t ff_vc1_cbpcy_p_codes[4][64];
extern const uint8_t ff_vc1_cbpcy_p_bits[4][64];
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
* 8x4:B:btm 8x4:B:top 8x4:B:both,
* 4x8:B:right 4x8:B:left 4x8:B:both
* 4x4:B 8x8:MB
* 8x4:MB:btm 8x4:MB:top 8x4,MB,both
* 4x8,MB,right 4x8,MB,left
* 4x4,MB */
extern const uint16_t ff_vc1_ttmb_codes[3][16];
extern const uint8_t ff_vc1_ttmb_bits[3][16];
/* TTBLK (Transform Type per Block) tables */
extern const uint8_t ff_vc1_ttblk_codes[3][8];
extern const uint8_t ff_vc1_ttblk_bits[3][8];
/* SUBBLKPAT tables, p93-94, reordered */
extern const uint8_t ff_vc1_subblkpat_codes[3][15];
extern const uint8_t ff_vc1_subblkpat_bits[3][15];
/* MV differential tables, p265 */
extern const uint16_t ff_vc1_mv_diff_codes[4][73];
extern const uint8_t ff_vc1_mv_diff_bits[4][73];
/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
/* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */
extern const int8_t ff_vc1_simple_progressive_4x4_zz [16];
extern const int8_t ff_vc1_adv_progressive_8x4_zz [32];
extern const int8_t ff_vc1_adv_progressive_4x8_zz [32];
extern const int8_t ff_vc1_adv_interlaced_8x8_zz [64];
extern const int8_t ff_vc1_adv_interlaced_8x4_zz [32];
extern const int8_t ff_vc1_adv_interlaced_4x8_zz [32];
extern const int8_t ff_vc1_adv_interlaced_4x4_zz [16];
/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
extern const int32_t ff_vc1_dqscale[63];
#endif /* FFMPEG_VC1DATA_H */
@@ -0,0 +1,459 @@
/*
* VC-1 and WMV3 decoder - DSP functions
* Copyright (c) 2006 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vc1dsp.c
* VC-1 and WMV3 decoder
*
*/
#include "dsputil.h"
/** Apply overlap transform to horizontal edge
*/
static void vc1_v_overlap_c(uint8_t* src, int stride)
{
int i;
int a, b, c, d;
int d1, d2;
int rnd = 1;
for(i = 0; i < 8; i++) {
a = src[-2*stride];
b = src[-stride];
c = src[0];
d = src[stride];
d1 = (a - d + 3 + rnd) >> 3;
d2 = (a - d + b - c + 4 - rnd) >> 3;
src[-2*stride] = a - d1;
src[-stride] = b - d2;
src[0] = c + d2;
src[stride] = d + d1;
src++;
rnd = !rnd;
}
}
/** Apply overlap transform to vertical edge
*/
static void vc1_h_overlap_c(uint8_t* src, int stride)
{
int i;
int a, b, c, d;
int d1, d2;
int rnd = 1;
for(i = 0; i < 8; i++) {
a = src[-2];
b = src[-1];
c = src[0];
d = src[1];
d1 = (a - d + 3 + rnd) >> 3;
d2 = (a - d + b - c + 4 - rnd) >> 3;
src[-2] = a - d1;
src[-1] = b - d2;
src[0] = c + d2;
src[1] = d + d1;
src += stride;
rnd = !rnd;
}
}
/** Do inverse transform on 8x8 block
*/
static void vc1_inv_trans_8x8_c(DCTELEM block[64])
{
int i;
register int t1,t2,t3,t4,t5,t6,t7,t8;
DCTELEM *src, *dst;
src = block;
dst = block;
for(i = 0; i < 8; i++){
t1 = 12 * (src[0] + src[4]) + 4;
t2 = 12 * (src[0] - src[4]) + 4;
t3 = 16 * src[2] + 6 * src[6];
t4 = 6 * src[2] - 16 * src[6];
t5 = t1 + t3;
t6 = t2 + t4;
t7 = t2 - t4;
t8 = t1 - t3;
t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7];
t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7];
t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7];
t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7];
dst[0] = (t5 + t1) >> 3;
dst[1] = (t6 + t2) >> 3;
dst[2] = (t7 + t3) >> 3;
dst[3] = (t8 + t4) >> 3;
dst[4] = (t8 - t4) >> 3;
dst[5] = (t7 - t3) >> 3;
dst[6] = (t6 - t2) >> 3;
dst[7] = (t5 - t1) >> 3;
src += 8;
dst += 8;
}
src = block;
dst = block;
for(i = 0; i < 8; i++){
t1 = 12 * (src[ 0] + src[32]) + 64;
t2 = 12 * (src[ 0] - src[32]) + 64;
t3 = 16 * src[16] + 6 * src[48];
t4 = 6 * src[16] - 16 * src[48];
t5 = t1 + t3;
t6 = t2 + t4;
t7 = t2 - t4;
t8 = t1 - t3;
t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
dst[ 0] = (t5 + t1) >> 7;
dst[ 8] = (t6 + t2) >> 7;
dst[16] = (t7 + t3) >> 7;
dst[24] = (t8 + t4) >> 7;
dst[32] = (t8 - t4 + 1) >> 7;
dst[40] = (t7 - t3 + 1) >> 7;
dst[48] = (t6 - t2 + 1) >> 7;
dst[56] = (t5 - t1 + 1) >> 7;
src++;
dst++;
}
}
/** Do inverse transform on 8x4 part of block
*/
static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block)
{
int i;
register int t1,t2,t3,t4,t5,t6,t7,t8;
DCTELEM *src, *dst;
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
src = block;
dst = block;
for(i = 0; i < 4; i++){
t1 = 12 * (src[0] + src[4]) + 4;
t2 = 12 * (src[0] - src[4]) + 4;
t3 = 16 * src[2] + 6 * src[6];
t4 = 6 * src[2] - 16 * src[6];
t5 = t1 + t3;
t6 = t2 + t4;
t7 = t2 - t4;
t8 = t1 - t3;
t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7];
t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7];
t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7];
t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7];
dst[0] = (t5 + t1) >> 3;
dst[1] = (t6 + t2) >> 3;
dst[2] = (t7 + t3) >> 3;
dst[3] = (t8 + t4) >> 3;
dst[4] = (t8 - t4) >> 3;
dst[5] = (t7 - t3) >> 3;
dst[6] = (t6 - t2) >> 3;
dst[7] = (t5 - t1) >> 3;
src += 8;
dst += 8;
}
src = block;
for(i = 0; i < 8; i++){
t1 = 17 * (src[ 0] + src[16]) + 64;
t2 = 17 * (src[ 0] - src[16]) + 64;
t3 = 22 * src[ 8] + 10 * src[24];
t4 = 22 * src[24] - 10 * src[ 8];
dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)];
dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)];
dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)];
dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)];
src ++;
dest++;
}
}
/** Do inverse transform on 4x8 parts of block
*/
static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block)
{
int i;
register int t1,t2,t3,t4,t5,t6,t7,t8;
DCTELEM *src, *dst;
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
src = block;
dst = block;
for(i = 0; i < 8; i++){
t1 = 17 * (src[0] + src[2]) + 4;
t2 = 17 * (src[0] - src[2]) + 4;
t3 = 22 * src[1] + 10 * src[3];
t4 = 22 * src[3] - 10 * src[1];
dst[0] = (t1 + t3) >> 3;
dst[1] = (t2 - t4) >> 3;
dst[2] = (t2 + t4) >> 3;
dst[3] = (t1 - t3) >> 3;
src += 8;
dst += 8;
}
src = block;
for(i = 0; i < 4; i++){
t1 = 12 * (src[ 0] + src[32]) + 64;
t2 = 12 * (src[ 0] - src[32]) + 64;
t3 = 16 * src[16] + 6 * src[48];
t4 = 6 * src[16] - 16 * src[48];
t5 = t1 + t3;
t6 = t2 + t4;
t7 = t2 - t4;
t8 = t1 - t3;
t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56];
t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56];
t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56];
t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56];
dest[0*linesize] = cm[dest[0*linesize] + ((t5 + t1) >> 7)];
dest[1*linesize] = cm[dest[1*linesize] + ((t6 + t2) >> 7)];
dest[2*linesize] = cm[dest[2*linesize] + ((t7 + t3) >> 7)];
dest[3*linesize] = cm[dest[3*linesize] + ((t8 + t4) >> 7)];
dest[4*linesize] = cm[dest[4*linesize] + ((t8 - t4 + 1) >> 7)];
dest[5*linesize] = cm[dest[5*linesize] + ((t7 - t3 + 1) >> 7)];
dest[6*linesize] = cm[dest[6*linesize] + ((t6 - t2 + 1) >> 7)];
dest[7*linesize] = cm[dest[7*linesize] + ((t5 - t1 + 1) >> 7)];
src ++;
dest++;
}
}
/** Do inverse transform on 4x4 part of block
*/
static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block)
{
int i;
register int t1,t2,t3,t4;
DCTELEM *src, *dst;
const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
src = block;
dst = block;
for(i = 0; i < 4; i++){
t1 = 17 * (src[0] + src[2]) + 4;
t2 = 17 * (src[0] - src[2]) + 4;
t3 = 22 * src[1] + 10 * src[3];
t4 = 22 * src[3] - 10 * src[1];
dst[0] = (t1 + t3) >> 3;
dst[1] = (t2 - t4) >> 3;
dst[2] = (t2 + t4) >> 3;
dst[3] = (t1 - t3) >> 3;
src += 8;
dst += 8;
}
src = block;
for(i = 0; i < 4; i++){
t1 = 17 * (src[ 0] + src[16]) + 64;
t2 = 17 * (src[ 0] - src[16]) + 64;
t3 = 22 * src[ 8] + 10 * src[24];
t4 = 22 * src[24] - 10 * src[ 8];
dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)];
dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)];
dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)];
dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)];
src ++;
dest++;
}
}
/* motion compensation functions */
/** Filter in case of 2 filters */
#define VC1_MSPEL_FILTER_16B(DIR, TYPE) \
static av_always_inline int vc1_mspel_ ## DIR ## _filter_16bits(const TYPE *src, int stride, int mode) \
{ \
switch(mode){ \
case 0: /* no shift - should not occur */ \
return 0; \
case 1: /* 1/4 shift */ \
return -4*src[-stride] + 53*src[0] + 18*src[stride] - 3*src[stride*2]; \
case 2: /* 1/2 shift */ \
return -src[-stride] + 9*src[0] + 9*src[stride] - src[stride*2]; \
case 3: /* 3/4 shift */ \
return -3*src[-stride] + 18*src[0] + 53*src[stride] - 4*src[stride*2]; \
} \
return 0; /* should not occur */ \
}
VC1_MSPEL_FILTER_16B(ver, uint8_t);
VC1_MSPEL_FILTER_16B(hor, int16_t);
/** Filter used to interpolate fractional pel values
*/
static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int mode, int r)
{
switch(mode){
case 0: //no shift
return src[0];
case 1: // 1/4 shift
return (-4*src[-stride] + 53*src[0] + 18*src[stride] - 3*src[stride*2] + 32 - r) >> 6;
case 2: // 1/2 shift
return (-src[-stride] + 9*src[0] + 9*src[stride] - src[stride*2] + 8 - r) >> 4;
case 3: // 3/4 shift
return (-3*src[-stride] + 18*src[0] + 53*src[stride] - 4*src[stride*2] + 32 - r) >> 6;
}
return 0; //should not occur
}
/** Function used to do motion compensation with bicubic interpolation
*/
static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd)
{
int i, j;
if (vmode) { /* Horizontal filter to apply */
int r;
if (hmode) { /* Vertical filter to apply, output to tmp */
static const int shift_value[] = { 0, 5, 1, 5 };
int shift = (shift_value[hmode]+shift_value[vmode])>>1;
int16_t tmp[11*8], *tptr = tmp;
r = (1<<(shift-1)) + rnd-1;
src -= 1;
for(j = 0; j < 8; j++) {
for(i = 0; i < 11; i++)
tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode)+r)>>shift;
src += stride;
tptr += 11;
}
r = 64-rnd;
tptr = tmp+1;
for(j = 0; j < 8; j++) {
for(i = 0; i < 8; i++)
dst[i] = av_clip_uint8((vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode)+r)>>7);
dst += stride;
tptr += 11;
}
return;
}
else { /* No horizontal filter, output 8 lines to dst */
r = 1-rnd;
for(j = 0; j < 8; j++) {
for(i = 0; i < 8; i++)
dst[i] = av_clip_uint8(vc1_mspel_filter(src + i, stride, vmode, r));
src += stride;
dst += stride;
}
return;
}
}
/* Horizontal mode with no vertical mode */
for(j = 0; j < 8; j++) {
for(i = 0; i < 8; i++)
dst[i] = av_clip_uint8(vc1_mspel_filter(src + i, 1, hmode, rnd));
dst += stride;
src += stride;
}
}
/* pixel functions - really are entry points to vc1_mspel_mc */
/* this one is defined in dsputil.c */
void ff_put_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd);
#define PUT_VC1_MSPEL(a, b)\
static void put_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \
vc1_mspel_mc(dst, src, stride, a, b, rnd); \
}
PUT_VC1_MSPEL(1, 0)
PUT_VC1_MSPEL(2, 0)
PUT_VC1_MSPEL(3, 0)
PUT_VC1_MSPEL(0, 1)
PUT_VC1_MSPEL(1, 1)
PUT_VC1_MSPEL(2, 1)
PUT_VC1_MSPEL(3, 1)
PUT_VC1_MSPEL(0, 2)
PUT_VC1_MSPEL(1, 2)
PUT_VC1_MSPEL(2, 2)
PUT_VC1_MSPEL(3, 2)
PUT_VC1_MSPEL(0, 3)
PUT_VC1_MSPEL(1, 3)
PUT_VC1_MSPEL(2, 3)
PUT_VC1_MSPEL(3, 3)
void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) {
dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;
dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;
dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_c;
dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c;
dsp->vc1_h_overlap = vc1_h_overlap_c;
dsp->vc1_v_overlap = vc1_v_overlap_c;
dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c;
dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c;
dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_c;
dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_c;
dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_c;
dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_c;
dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_c;
dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_c;
dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_c;
dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_c;
dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_c;
dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_c;
dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_c;
dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_c;
dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_c;
dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_c;
}
@@ -2,19 +2,21 @@
* ATI VCR1 codec
* Copyright (c) 2003 Michael Niedermayer
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@@ -23,7 +25,7 @@
*/
#include "avcodec.h"
#include "mpegvideo.h"
#include "dsputil.h"
//#undef NDEBUG
//#include <assert.h>
@@ -37,21 +39,14 @@ typedef struct VCR1Context{
static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size)
{
VCR1Context * const a = avctx->priv_data;
AVFrame *picture = data;
AVFrame * const p= (AVFrame*)&a->picture;
uint8_t *bytestream= buf;
const uint8_t *bytestream= buf;
int i, x, y;
*data_size = 0;
/* special case for last picture */
if (buf_size == 0) {
return 0;
}
if(p->data[0])
avctx->release_buffer(avctx, p);
@@ -60,7 +55,7 @@ static int decode_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
p->pict_type= I_TYPE;
p->pict_type= FF_I_TYPE;
p->key_frame= 1;
for(i=0; i<16; i++){
@@ -127,7 +122,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
int mb_x, mb_y;
*p = *pict;
p->pict_type= I_TYPE;
p->pict_type= FF_I_TYPE;
p->key_frame= 1;
emms_c();
@@ -142,14 +137,14 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
}
#endif
static void common_init(AVCodecContext *avctx){
static av_cold void common_init(AVCodecContext *avctx){
VCR1Context * const a = avctx->priv_data;
avctx->coded_frame= (AVFrame*)&a->picture;
a->avctx= avctx;
}
static int decode_init(AVCodecContext *avctx){
static av_cold int decode_init(AVCodecContext *avctx){
common_init(avctx);
@@ -158,19 +153,14 @@ static int decode_init(AVCodecContext *avctx){
return 0;
}
static int encode_init(AVCodecContext *avctx){
#if 0
static av_cold int encode_init(AVCodecContext *avctx){
common_init(avctx);
return 0;
}
static int decode_end(AVCodecContext *avctx){
avcodec_default_free_buffers(avctx);
return 0;
}
#endif
AVCodec vcr1_decoder = {
"vcr1",
@@ -179,9 +169,10 @@ AVCodec vcr1_decoder = {
sizeof(VCR1Context),
decode_init,
NULL,
decode_end,
NULL,
decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
};
#if 0
#ifdef CONFIG_ENCODERS
@@ -194,6 +185,7 @@ AVCodec vcr1_encoder = {
encode_init,
encode_frame,
//encode_end,
.long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"),
};
#endif //CONFIG_ENCODERS
@@ -2,26 +2,29 @@
* Sierra VMD Audio & Video Decoders
* Copyright (C) 2004 the ffmpeg project
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vmdvideo.c
* Sierra VMD audio & video decoders
* by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
* for more information on the Sierra VMD format, visit:
* http://www.pcisys.net/~melanson/codecs/
*
* The video decoder outputs PAL8 colorspace data. The decoder expects
* a 0x330-byte VMD file header to be transmitted via extradata during
@@ -30,7 +33,7 @@
* information record from the VMD file.
*
* The audio decoder, like the video decoder, expects each encoded data
* chunk to be prepended with the approriate 16-byte frame information
* chunk to be prepended with the appropriate 16-byte frame information
* record from the VMD file. It does not require the 0x330-byte VMD file
* header, but it does need the audio setup parameters passed in through
* normal libavcodec API means.
@@ -41,19 +44,11 @@
#include <string.h>
#include <unistd.h>
#include "common.h"
#include "avcodec.h"
#include "dsputil.h"
#define VMD_HEADER_SIZE 0x330
#define PALETTE_COUNT 256
#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
#define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \
(((uint8_t*)(x))[2] << 16) | \
(((uint8_t*)(x))[1] << 8) | \
((uint8_t*)(x))[0])
/*
* Video Decoder
*/
@@ -61,25 +56,27 @@
typedef struct VmdVideoContext {
AVCodecContext *avctx;
DSPContext dsp;
AVFrame frame;
AVFrame prev_frame;
unsigned char *buf;
const unsigned char *buf;
int size;
unsigned char palette[PALETTE_COUNT * 4];
unsigned char *unpack_buffer;
int unpack_buffer_size;
int x_off, y_off;
} VmdVideoContext;
#define QUEUE_SIZE 0x1000
#define QUEUE_MASK 0x0FFF
static void lz_unpack(unsigned char *src, unsigned char *dest)
static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len)
{
unsigned char *s;
const unsigned char *s;
unsigned char *d;
unsigned char *d_end;
unsigned char queue[QUEUE_SIZE];
unsigned int qpos;
unsigned int dataleft;
@@ -91,10 +88,11 @@ static void lz_unpack(unsigned char *src, unsigned char *dest)
s = src;
d = dest;
dataleft = LE_32(s);
d_end = d + dest_len;
dataleft = AV_RL32(s);
s += 4;
memset(queue, QUEUE_SIZE, 0x20);
if (LE_32(s) == 0x56781234) {
memset(queue, 0x20, QUEUE_SIZE);
if (AV_RL32(s) == 0x56781234) {
s += 4;
qpos = 0x111;
speclen = 0xF + 3;
@@ -106,6 +104,8 @@ static void lz_unpack(unsigned char *src, unsigned char *dest)
while (dataleft > 0) {
tag = *s++;
if ((tag == 0xFF) && (dataleft > 8)) {
if (d + 8 > d_end)
return;
for (i = 0; i < 8; i++) {
queue[qpos++] = *d++ = *s++;
qpos &= QUEUE_MASK;
@@ -116,6 +116,8 @@ static void lz_unpack(unsigned char *src, unsigned char *dest)
if (dataleft == 0)
break;
if (tag & 0x01) {
if (d + 1 > d_end)
return;
queue[qpos++] = *d++ = *s++;
qpos &= QUEUE_MASK;
dataleft--;
@@ -125,6 +127,8 @@ static void lz_unpack(unsigned char *src, unsigned char *dest)
chainlen = (*s++ & 0x0F) + 3;
if (chainlen == speclen)
chainlen = *s++ + 0xF + 3;
if (d + chainlen > d_end)
return;
for (j = 0; j < chainlen; j++) {
*d = queue[chainofs++ & QUEUE_MASK];
queue[qpos++] = *d++;
@@ -138,27 +142,33 @@ static void lz_unpack(unsigned char *src, unsigned char *dest)
}
}
static int rle_unpack(unsigned char *src, unsigned char *dest, int len)
static int rle_unpack(const unsigned char *src, unsigned char *dest,
int src_len, int dest_len)
{
unsigned char *ps;
const unsigned char *ps;
unsigned char *pd;
int i, l;
unsigned char *dest_end = dest + dest_len;
ps = src;
pd = dest;
if (len & 1)
if (src_len & 1)
*pd++ = *ps++;
len >>= 1;
src_len >>= 1;
i = 0;
do {
l = *ps++;
if (l & 0x80) {
l = (l & 0x7F) * 2;
if (pd + l > dest_end)
return ps - src;
memcpy(pd, ps, l);
ps += l;
pd += l;
} else {
if (pd + i > dest_end)
return ps - src;
for (i = 0; i < l; i++) {
*pd++ = ps[0];
*pd++ = ps[1];
@@ -166,9 +176,9 @@ static int rle_unpack(unsigned char *src, unsigned char *dest, int len)
ps += 2;
}
i += l;
} while (i < len);
} while (i < src_len);
return (ps - src);
return ps - src;
}
static void vmd_decode(VmdVideoContext *s)
@@ -178,9 +188,9 @@ static void vmd_decode(VmdVideoContext *s)
unsigned char r, g, b;
/* point to the start of the encoded data */
unsigned char *p = s->buf + 16;
const unsigned char *p = s->buf + 16;
unsigned char *pb;
const unsigned char *pb;
unsigned char meth;
unsigned char *dp; /* pointer to current frame */
unsigned char *pp; /* pointer to previous frame */
@@ -189,11 +199,21 @@ static void vmd_decode(VmdVideoContext *s)
int frame_x, frame_y;
int frame_width, frame_height;
int dp_size;
frame_x = LE_16(&s->buf[6]);
frame_y = LE_16(&s->buf[8]);
frame_width = LE_16(&s->buf[10]) - frame_x + 1;
frame_height = LE_16(&s->buf[12]) - frame_y + 1;
frame_x = AV_RL16(&s->buf[6]);
frame_y = AV_RL16(&s->buf[8]);
frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
(frame_x || frame_y)) {
s->x_off = frame_x;
s->y_off = frame_y;
}
frame_x -= s->x_off;
frame_y -= s->y_off;
/* if only a certain region will be updated, copy the entire previous
* frame before the decode */
@@ -221,12 +241,13 @@ static void vmd_decode(VmdVideoContext *s)
pb = p;
meth = *pb++;
if (meth & 0x80) {
lz_unpack(pb, s->unpack_buffer);
lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
meth &= 0x7F;
pb = s->unpack_buffer;
}
dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
dp_size = s->frame.linesize[0] * s->avctx->height;
pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
switch (meth) {
case 1:
@@ -236,17 +257,21 @@ static void vmd_decode(VmdVideoContext *s)
len = *pb++;
if (len & 0x80) {
len = (len & 0x7F) + 1;
if (ofs + len > frame_width)
return;
memcpy(&dp[ofs], pb, len);
pb += len;
ofs += len;
} else {
/* interframe pixel copy */
if (ofs + len + 1 > frame_width)
return;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
}
} while (ofs < frame_width);
if (ofs > frame_width) {
printf (" VMD video: offset > width (%d > %d)\n",
av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
ofs, frame_width);
break;
}
@@ -272,19 +297,21 @@ static void vmd_decode(VmdVideoContext *s)
if (len & 0x80) {
len = (len & 0x7F) + 1;
if (*pb++ == 0xFF)
len = rle_unpack(pb, dp, len);
len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
else
memcpy(&dp[ofs], pb, len);
pb += len;
ofs += len;
} else {
/* interframe pixel copy */
if (ofs + len + 1 > frame_width)
return;
memcpy(&dp[ofs], &pp[ofs], len + 1);
ofs += len + 1;
}
} while (ofs < frame_width);
if (ofs > frame_width) {
printf (" VMD video: offset > width (%d > %d)\n",
av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
ofs, frame_width);
}
dp += s->frame.linesize[0];
@@ -295,9 +322,9 @@ static void vmd_decode(VmdVideoContext *s)
}
}
static int vmdvideo_decode_init(AVCodecContext *avctx)
static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
{
VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
VmdVideoContext *s = avctx->priv_data;
int i;
unsigned int *palette32;
int palette_index = 0;
@@ -307,18 +334,17 @@ static int vmdvideo_decode_init(AVCodecContext *avctx)
s->avctx = avctx;
avctx->pix_fmt = PIX_FMT_PAL8;
avctx->has_b_frames = 0;
dsputil_init(&s->dsp, avctx);
/* make sure the VMD header made it */
if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
printf(" VMD video: expected extradata size of %d\n",
av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
VMD_HEADER_SIZE);
return -1;
}
vmd_header = (unsigned char *)avctx->extradata;
s->unpack_buffer = av_malloc(LE_32(&vmd_header[800]));
s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
s->unpack_buffer = av_malloc(s->unpack_buffer_size);
if (!s->unpack_buffer)
return -1;
@@ -339,16 +365,19 @@ static int vmdvideo_decode_init(AVCodecContext *avctx)
static int vmdvideo_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size)
{
VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
VmdVideoContext *s = avctx->priv_data;
s->buf = buf;
s->size = buf_size;
if (buf_size < 16)
return buf_size;
s->frame.reference = 1;
if (avctx->get_buffer(avctx, &s->frame)) {
printf (" VMD Video: get_buffer() failed\n");
av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
return -1;
}
@@ -357,22 +386,21 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
/* make the palette available on the way out */
memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
if (s->prev_frame.data[0])
avctx->release_buffer(avctx, &s->prev_frame);
/* shuffle frames */
s->prev_frame = s->frame;
FFSWAP(AVFrame, s->frame, s->prev_frame);
if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame);
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame;
*(AVFrame*)data = s->prev_frame;
/* report that the buffer was completely consumed */
return buf_size;
}
static int vmdvideo_decode_end(AVCodecContext *avctx)
static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
{
VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
VmdVideoContext *s = avctx->priv_data;
if (s->prev_frame.data[0])
avctx->release_buffer(avctx, &s->prev_frame);
@@ -387,135 +415,135 @@ static int vmdvideo_decode_end(AVCodecContext *avctx)
*/
typedef struct VmdAudioContext {
AVCodecContext *avctx;
int channels;
int bits;
int block_align;
unsigned char steps8[16];
unsigned short steps16[16];
unsigned short steps128[256];
short predictors[2];
int predictors[2];
} VmdAudioContext;
static int vmdaudio_decode_init(AVCodecContext *avctx)
{
VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
int i;
static const uint16_t vmdaudio_table[128] = {
0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
};
static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
{
VmdAudioContext *s = avctx->priv_data;
s->avctx = avctx;
s->channels = avctx->channels;
s->bits = avctx->bits_per_sample;
s->block_align = avctx->block_align;
avctx->sample_fmt = SAMPLE_FMT_S16;
printf (" %d channels, %d bits/sample, block align = %d\n",
s->channels, s->bits, s->block_align);
/* set up the steps8 and steps16 tables */
for (i = 0; i < 8; i++) {
if (i < 4)
s->steps8[i] = i;
else
s->steps8[i] = s->steps8[i - 1] + i - 1;
if (i == 0)
s->steps16[i] = 0;
else if (i == 1)
s->steps16[i] = 4;
else if (i == 2)
s->steps16[i] = 16;
else
s->steps16[i] = 1 << (i + 4);
}
/* set up the step128 table */
s->steps128[0] = 0;
s->steps128[1] = 8;
for (i = 0x02; i <= 0x20; i++)
s->steps128[i] = (i - 1) << 4;
for (i = 0x21; i <= 0x60; i++)
s->steps128[i] = (i + 0x1F) << 3;
for (i = 0x61; i <= 0x70; i++)
s->steps128[i] = (i - 0x51) << 6;
for (i = 0x71; i <= 0x78; i++)
s->steps128[i] = (i - 0x69) << 8;
for (i = 0x79; i <= 0x7D; i++)
s->steps128[i] = (i - 0x75) << 10;
s->steps128[0x7E] = 0x3000;
s->steps128[0x7F] = 0x4000;
/* set up the negative half of each table */
for (i = 0; i < 8; i++) {
s->steps8[i + 8] = -s->steps8[i];
s->steps16[i + 8] = -s->steps16[i];
}
for (i = 0; i < 128; i++)
s->steps128[i + 128] = -s->steps128[i];
av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
s->channels, s->bits, s->block_align, avctx->sample_rate);
return 0;
}
static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
uint8_t *buf, int ratio) {
const uint8_t *buf, int stereo)
{
int i;
int chan = 0;
int16_t *out = (int16_t*)data;
for(i = 0; i < s->block_align; i++) {
if(buf[i] & 0x80)
s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
else
s->predictors[chan] += vmdaudio_table[buf[i]];
s->predictors[chan] = av_clip_int16(s->predictors[chan]);
out[i] = s->predictors[chan];
chan ^= stereo;
}
}
static void vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
uint8_t *buf, int silence)
static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
const uint8_t *buf, int silence)
{
int bytes_decoded = 0;
int i;
// if (silence)
// av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
if (s->channels == 2) {
if ((s->block_align & 0x01) == 0) {
if (silence)
/* stereo handling */
if (silence) {
memset(data, 0, s->block_align * 2);
else
} else {
if (s->bits == 16)
vmdaudio_decode_audio(s, data, buf, 1);
else {
/* copy the data but convert it to signed */
for (i = 0; i < s->block_align; i++){
*data++ = buf[i] + 0x80;
*data++ = buf[i] + 0x80;
}
}
}
} else {
if (silence)
bytes_decoded = s->block_align * 2;
/* mono handling */
if (silence) {
memset(data, 0, s->block_align * 2);
// else
// vmdaudio_decode_audio(s, data, buf, 1);
}
} else {
if (s->bits == 16) {
vmdaudio_decode_audio(s, data, buf, 0);
} else {
/* copy the data but convert it to signed */
for (i = 0; i < s->block_align; i++){
*data++ = buf[i] + 0x80;
*data++ = buf[i] + 0x80;
}
}
}
}
return s->block_align * 2;
}
static int vmdaudio_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size)
{
VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
unsigned int sound_flags;
VmdAudioContext *s = avctx->priv_data;
unsigned char *output_samples = (unsigned char *)data;
/* point to the start of the encoded data */
unsigned char *p = buf + 16;
unsigned char *p_end = buf + buf_size;
const unsigned char *p = buf + 16;
if (buf_size < 16)
return buf_size;
if (buf[6] == 1) {
/* the chunk contains audio */
vmdaudio_loadsound(s, output_samples, p, 0);
*data_size = vmdaudio_loadsound(s, output_samples, p, 0);
} else if (buf[6] == 2) {
/* the chunk contains audio and silence mixed together */
sound_flags = LE_32(p);
/* the chunk may contain audio */
p += 4;
/* do something with extrabufs here? */
while (p < p_end) {
if (sound_flags & 0x01)
/* audio */
vmdaudio_loadsound(s, output_samples, p, 1);
else
/* silence */
vmdaudio_loadsound(s, output_samples, p, 0);
p += s->block_align;
*data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
output_samples += (s->block_align * s->bits / 8);
sound_flags >>= 1;
}
} else if (buf[6] == 3) {
/* silent chunk */
vmdaudio_loadsound(s, output_samples, p, 1);
*data_size = vmdaudio_loadsound(s, output_samples, p, 1);
}
// *datasize = ;
return buf_size;
}
@@ -534,6 +562,7 @@ AVCodec vmdvideo_decoder = {
vmdvideo_decode_end,
vmdvideo_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
};
AVCodec vmdaudio_decoder = {
@@ -545,4 +574,5 @@ AVCodec vmdaudio_decoder = {
NULL,
NULL,
vmdaudio_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
};
@@ -0,0 +1,523 @@
/*
* VMware Screen Codec (VMnc) decoder
* Copyright (c) 2006 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vmnc.c
* VMware Screen Codec (VMnc) decoder
* As Alex Beregszaszi discovered, this is effectively RFB data dump
*/
#include <stdio.h>
#include <stdlib.h>
#include "avcodec.h"
enum EncTypes {
MAGIC_WMVd = 0x574D5664,
MAGIC_WMVe,
MAGIC_WMVf,
MAGIC_WMVg,
MAGIC_WMVh,
MAGIC_WMVi,
MAGIC_WMVj
};
enum HexTile_Flags {
HT_RAW = 1, // tile is raw
HT_BKG = 2, // background color is present
HT_FG = 4, // foreground color is present
HT_SUB = 8, // subrects are present
HT_CLR = 16 // each subrect has own color
};
/*
* Decoder context
*/
typedef struct VmncContext {
AVCodecContext *avctx;
AVFrame pic;
int bpp;
int bpp2;
int bigendian;
uint8_t pal[768];
int width, height;
/* cursor data */
int cur_w, cur_h;
int cur_x, cur_y;
int cur_hx, cur_hy;
uint8_t* curbits, *curmask;
uint8_t* screendta;
} VmncContext;
/* read pixel value from stream */
static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) {
switch(bpp * 2 + be) {
case 2:
case 3: return *buf;
case 4: return AV_RL16(buf);
case 5: return AV_RB16(buf);
case 8: return AV_RL32(buf);
case 9: return AV_RB32(buf);
default: return 0;
}
}
static void load_cursor(VmncContext *c, const uint8_t *src)
{
int i, j, p;
const int bpp = c->bpp2;
uint8_t *dst8 = c->curbits;
uint16_t *dst16 = (uint16_t*)c->curbits;
uint32_t *dst32 = (uint32_t*)c->curbits;
for(j = 0; j < c->cur_h; j++) {
for(i = 0; i < c->cur_w; i++) {
p = vmnc_get_pixel(src, bpp, c->bigendian);
src += bpp;
if(bpp == 1) *dst8++ = p;
if(bpp == 2) *dst16++ = p;
if(bpp == 4) *dst32++ = p;
}
}
dst8 = c->curmask;
dst16 = (uint16_t*)c->curmask;
dst32 = (uint32_t*)c->curmask;
for(j = 0; j < c->cur_h; j++) {
for(i = 0; i < c->cur_w; i++) {
p = vmnc_get_pixel(src, bpp, c->bigendian);
src += bpp;
if(bpp == 1) *dst8++ = p;
if(bpp == 2) *dst16++ = p;
if(bpp == 4) *dst32++ = p;
}
}
}
static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy)
{
int i, j;
int w, h, x, y;
w = c->cur_w;
if(c->width < c->cur_x + c->cur_w) w = c->width - c->cur_x;
h = c->cur_h;
if(c->height < c->cur_y + c->cur_h) h = c->height - c->cur_y;
x = c->cur_x;
y = c->cur_y;
if(x < 0) {
w += x;
x = 0;
}
if(y < 0) {
h += y;
y = 0;
}
if((w < 1) || (h < 1)) return;
dst += x * c->bpp2 + y * stride;
if(c->bpp2 == 1) {
uint8_t* cd = c->curbits, *msk = c->curmask;
for(j = 0; j < h; j++) {
for(i = 0; i < w; i++)
dst[i] = (dst[i] & cd[i]) ^ msk[i];
msk += c->cur_w;
cd += c->cur_w;
dst += stride;
}
} else if(c->bpp2 == 2) {
uint16_t* cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask;
uint16_t* dst2;
for(j = 0; j < h; j++) {
dst2 = (uint16_t*)dst;
for(i = 0; i < w; i++)
dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
msk += c->cur_w;
cd += c->cur_w;
dst += stride;
}
} else if(c->bpp2 == 4) {
uint32_t* cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask;
uint32_t* dst2;
for(j = 0; j < h; j++) {
dst2 = (uint32_t*)dst;
for(i = 0; i < w; i++)
dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
msk += c->cur_w;
cd += c->cur_w;
dst += stride;
}
}
}
/* fill rectangle with given color */
static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride)
{
int i, j;
dst += dx * bpp + dy * stride;
if(bpp == 1){
for(j = 0; j < h; j++) {
memset(dst, color, w);
dst += stride;
}
}else if(bpp == 2){
uint16_t* dst2;
for(j = 0; j < h; j++) {
dst2 = (uint16_t*)dst;
for(i = 0; i < w; i++) {
*dst2++ = color;
}
dst += stride;
}
}else if(bpp == 4){
uint32_t* dst2;
for(j = 0; j < h; j++) {
dst2 = (uint32_t*)dst;
for(i = 0; i < w; i++) {
dst2[i] = color;
}
dst += stride;
}
}
}
static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride)
{
int i, j, p;
for(j = 0; j < h; j++) {
for(i = 0; i < w; i++) {
p = vmnc_get_pixel(src, bpp, be);
src += bpp;
switch(bpp){
case 1:
dst[i] = p;
break;
case 2:
((uint16_t*)dst)[i] = p;
break;
case 4:
((uint32_t*)dst)[i] = p;
break;
}
}
dst += stride;
}
}
static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride)
{
int i, j, k;
int bg = 0, fg = 0, rects, color, flags, xy, wh;
const int bpp = c->bpp2;
uint8_t *dst2;
int bw = 16, bh = 16;
const uint8_t *ssrc=src;
for(j = 0; j < h; j += 16) {
dst2 = dst;
bw = 16;
if(j + 16 > h) bh = h - j;
for(i = 0; i < w; i += 16, dst2 += 16 * bpp) {
if(src - ssrc >= ssize) {
av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
return -1;
}
if(i + 16 > w) bw = w - i;
flags = *src++;
if(flags & HT_RAW) {
if(src - ssrc > ssize - bw * bh * bpp) {
av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
return -1;
}
paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride);
src += bw * bh * bpp;
} else {
if(flags & HT_BKG) {
bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
}
if(flags & HT_FG) {
fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
}
rects = 0;
if(flags & HT_SUB)
rects = *src++;
color = !!(flags & HT_CLR);
paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
if(src - ssrc > ssize - rects * (color * bpp + 2)) {
av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
return -1;
}
for(k = 0; k < rects; k++) {
if(color) {
fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
}
xy = *src++;
wh = *src++;
paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);
}
}
}
dst += stride * 16;
}
return src - ssrc;
}
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
{
VmncContext * const c = avctx->priv_data;
uint8_t *outptr;
const uint8_t *src = buf;
int dx, dy, w, h, depth, enc, chunks, res, size_left;
c->pic.reference = 1;
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
if(avctx->reget_buffer(avctx, &c->pic) < 0){
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
}
c->pic.key_frame = 0;
c->pic.pict_type = FF_P_TYPE;
//restore screen after cursor
if(c->screendta) {
int i;
w = c->cur_w;
if(c->width < c->cur_x + w) w = c->width - c->cur_x;
h = c->cur_h;
if(c->height < c->cur_y + h) h = c->height - c->cur_y;
dx = c->cur_x;
if(dx < 0) {
w += dx;
dx = 0;
}
dy = c->cur_y;
if(dy < 0) {
h += dy;
dy = 0;
}
if((w > 0) && (h > 0)) {
outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
for(i = 0; i < h; i++) {
memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2);
outptr += c->pic.linesize[0];
}
}
}
src += 2;
chunks = AV_RB16(src); src += 2;
while(chunks--) {
dx = AV_RB16(src); src += 2;
dy = AV_RB16(src); src += 2;
w = AV_RB16(src); src += 2;
h = AV_RB16(src); src += 2;
enc = AV_RB32(src); src += 4;
outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
size_left = buf_size - (src - buf);
switch(enc) {
case MAGIC_WMVd: // cursor
if(size_left < 2 + w * h * c->bpp2 * 2) {
av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left);
return -1;
}
src += 2;
c->cur_w = w;
c->cur_h = h;
c->cur_hx = dx;
c->cur_hy = dy;
if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {
av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
c->cur_hx = c->cur_hy = 0;
}
c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2);
c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2);
c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2);
load_cursor(c, src);
src += w * h * c->bpp2 * 2;
break;
case MAGIC_WMVe: // unknown
src += 2;
break;
case MAGIC_WMVf: // update cursor position
c->cur_x = dx - c->cur_hx;
c->cur_y = dy - c->cur_hy;
break;
case MAGIC_WMVg: // unknown
src += 10;
break;
case MAGIC_WMVh: // unknown
src += 4;
break;
case MAGIC_WMVi: // ServerInitialization struct
c->pic.key_frame = 1;
c->pic.pict_type = FF_I_TYPE;
depth = *src++;
if(depth != c->bpp) {
av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth);
}
src++;
c->bigendian = *src++;
if(c->bigendian & (~1)) {
av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian);
return -1;
}
//skip the rest of pixel format data
src += 13;
break;
case MAGIC_WMVj: // unknown
src += 2;
break;
case 0x00000000: // raw rectangle data
if((dx + w > c->width) || (dy + h > c->height)) {
av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
return -1;
}
if(size_left < w * h * c->bpp2) {
av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left);
return -1;
}
paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]);
src += w * h * c->bpp2;
break;
case 0x00000005: // HexTile encoded rectangle
if((dx + w > c->width) || (dy + h > c->height)) {
av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
return -1;
}
res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);
if(res < 0)
return -1;
src += res;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);
chunks = 0; // leave chunks decoding loop
}
}
if(c->screendta){
int i;
//save screen data before painting cursor
w = c->cur_w;
if(c->width < c->cur_x + w) w = c->width - c->cur_x;
h = c->cur_h;
if(c->height < c->cur_y + h) h = c->height - c->cur_y;
dx = c->cur_x;
if(dx < 0) {
w += dx;
dx = 0;
}
dy = c->cur_y;
if(dy < 0) {
h += dy;
dy = 0;
}
if((w > 0) && (h > 0)) {
outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
for(i = 0; i < h; i++) {
memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2);
outptr += c->pic.linesize[0];
}
outptr = c->pic.data[0];
put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y);
}
}
*data_size = sizeof(AVFrame);
*(AVFrame*)data = c->pic;
/* always report that the buffer was completely consumed */
return buf_size;
}
/*
*
* Init VMnc decoder
*
*/
static av_cold int decode_init(AVCodecContext *avctx)
{
VmncContext * const c = avctx->priv_data;
c->avctx = avctx;
c->pic.data[0] = NULL;
c->width = avctx->width;
c->height = avctx->height;
if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
return 1;
}
c->bpp = avctx->bits_per_sample;
c->bpp2 = c->bpp/8;
switch(c->bpp){
case 8:
avctx->pix_fmt = PIX_FMT_PAL8;
break;
case 16:
avctx->pix_fmt = PIX_FMT_RGB555;
break;
case 32:
avctx->pix_fmt = PIX_FMT_RGB32;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp);
}
return 0;
}
/*
*
* Uninit VMnc decoder
*
*/
static av_cold int decode_end(AVCodecContext *avctx)
{
VmncContext * const c = avctx->priv_data;
if (c->pic.data[0])
avctx->release_buffer(avctx, &c->pic);
av_free(c->curbits);
av_free(c->curmask);
av_free(c->screendta);
return 0;
}
AVCodec vmnc_decoder = {
"vmnc",
CODEC_TYPE_VIDEO,
CODEC_ID_VMNC,
sizeof(VmncContext),
decode_init,
NULL,
decode_end,
decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"),
};
@@ -0,0 +1,182 @@
/**
* @file vorbis.c
* Common code for Vorbis I encoder and decoder
* @author Denes Balatoni ( dbalatoni programozo hu )
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#undef V_DEBUG
//#define V_DEBUG
#define ALT_BITSTREAM_READER_LE
#include "avcodec.h"
#include "bitstream.h"
#include "vorbis.h"
/* Helper functions */
unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) { // x^(1/n)
unsigned int ret=0, i, j;
do {
++ret;
for(i=0,j=ret;i<n-1;i++) j*=ret;
} while (j<=x);
return ret - 1;
}
// Generate vlc codes from vorbis huffman code lengths
int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num) {
uint_fast32_t exit_at_level[33]={404,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint_fast8_t i,j;
uint_fast32_t code,p;
#ifdef V_DEBUG
GetBitContext gb;
#endif
for(p=0;(bits[p]==0) && (p<num);++p);
if (p==num) {
// av_log(vc->avccontext, AV_LOG_INFO, "An empty codebook. Heh?! \n");
return 0;
}
codes[p]=0;
for(i=0;i<bits[p];++i) {
exit_at_level[i+1]=1<<i;
}
#ifdef V_DEBUG
av_log(NULL, AV_LOG_INFO, " %d. of %d code len %d code %d - ", p, num, bits[p], codes[p]);
init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]);
for(i=0;i<bits[p];++i) {
av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0");
}
av_log(NULL, AV_LOG_INFO, "\n");
#endif
++p;
for(;p<num;++p) {
if (bits[p]==0) continue;
// find corresponding exit(node which the tree can grow further from)
for(i=bits[p];i>0;--i) {
if (exit_at_level[i]) break;
}
if (!i) return 1; // overspecified tree
code=exit_at_level[i];
exit_at_level[i]=0;
// construct code (append 0s to end) and introduce new exits
for(j=i+1;j<=bits[p];++j) {
exit_at_level[j]=code+(1<<(j-1));
}
codes[p]=code;
#ifdef V_DEBUG
av_log(NULL, AV_LOG_INFO, " %d. code len %d code %d - ", p, bits[p], codes[p]);
init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]);
for(i=0;i<bits[p];++i) {
av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0");
}
av_log(NULL, AV_LOG_INFO, "\n");
#endif
}
//no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC)
for (p=1; p<33; p++)
if (exit_at_level[p]) return 1;
return 0;
}
void ff_vorbis_ready_floor1_list(floor1_entry_t * list, int values) {
int i;
list[0].sort = 0;
list[1].sort = 1;
for (i = 2; i < values; i++) {
int j;
list[i].low = 0;
list[i].high = 1;
list[i].sort = i;
for (j = 2; j < i; j++) {
int tmp = list[j].x;
if (tmp < list[i].x) {
if (tmp > list[list[i].low].x) list[i].low = j;
} else {
if (tmp < list[list[i].high].x) list[i].high = j;
}
}
}
for (i = 0; i < values - 1; i++) {
int j;
for (j = i + 1; j < values; j++) {
if (list[list[i].sort].x > list[list[j].sort].x) {
int tmp = list[i].sort;
list[i].sort = list[j].sort;
list[j].sort = tmp;
}
}
}
}
static void render_line(int x0, int y0, int x1, int y1, float * buf) {
int dy = y1 - y0;
int adx = x1 - x0;
int base = dy / adx;
int ady = FFABS(dy) - FFABS(base) * adx;
int x = x0;
int y = y0;
int err = 0;
int sy = dy<0 ? -1 : 1;
buf[x] = ff_vorbis_floor1_inverse_db_table[y];
while (++x < x1) {
err += ady;
if (err >= adx) {
err -= adx;
y += sy;
}
y += base;
buf[x] = ff_vorbis_floor1_inverse_db_table[y];
}
}
void ff_vorbis_floor1_render_list(floor1_entry_t * list, int values, uint_fast16_t * y_list, int * flag, int multiplier, float * out, int samples) {
int lx, ly, i;
lx = 0;
ly = y_list[0] * multiplier;
for (i = 1; i < values; i++) {
int pos = list[i].sort;
if (flag[pos]) {
int x1 = list[pos].x;
int y1 = y_list[pos] * multiplier;
if (lx < samples)
render_line(lx, ly, FFMIN(x1,samples), y1, out);
lx = x1;
ly = y1;
}
if (lx >= samples) break;
}
if (lx < samples) render_line(lx, ly, samples, ly, out);
}
@@ -0,0 +1,43 @@
/*
* copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VORBIS_H
#define FFMPEG_VORBIS_H
#include "avcodec.h"
extern const float ff_vorbis_floor1_inverse_db_table[256];
extern const float * const ff_vorbis_vwin[8];
typedef struct {
uint_fast16_t x;
uint_fast16_t sort;
uint_fast16_t low;
uint_fast16_t high;
} floor1_entry_t;
void ff_vorbis_ready_floor1_list(floor1_entry_t * list, int values);
unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n)
int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num);
void ff_vorbis_floor1_render_list(floor1_entry_t * list, int values, uint_fast16_t * y_list, int * flag, int multiplier, float * out, int samples);
#define ilog(i) av_log2(2*(i))
#endif /* FFMPEG_VORBIS_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,505 @@
/*
* copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VORBIS_ENC_DATA_H
#define FFMPEG_VORBIS_ENC_DATA_H
#include <stdint.h>
static const uint8_t codebook0[] = {
2, 10, 8, 14, 7, 12, 11, 14, 1, 5, 3, 7, 4, 9, 7,
13,
};
static const uint8_t codebook1[] = {
1, 4, 2, 6, 3, 7, 5, 7,
};
static const uint8_t codebook2[] = {
1, 5, 7, 21, 5, 8, 9, 21, 10, 9, 12, 20, 20, 16, 20,
20, 4, 8, 9, 20, 6, 8, 9, 20, 11, 11, 13, 20, 20, 15,
17, 20, 9, 11, 14, 20, 8, 10, 15, 20, 11, 13, 15, 20, 20,
20, 20, 20, 20, 20, 20, 20, 13, 20, 20, 20, 18, 18, 20, 20,
20, 20, 20, 20, 3, 6, 8, 20, 6, 7, 9, 20, 10, 9, 12,
20, 20, 20, 20, 20, 5, 7, 9, 20, 6, 6, 9, 20, 10, 9,
12, 20, 20, 20, 20, 20, 8, 10, 13, 20, 8, 9, 12, 20, 11,
10, 12, 20, 20, 20, 20, 20, 18, 20, 20, 20, 15, 17, 18, 20,
18, 17, 18, 20, 20, 20, 20, 20, 7, 10, 12, 20, 8, 9, 11,
20, 14, 13, 14, 20, 20, 20, 20, 20, 6, 9, 12, 20, 7, 8,
11, 20, 12, 11, 13, 20, 20, 20, 20, 20, 9, 11, 15, 20, 8,
10, 14, 20, 12, 11, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 11, 16, 18,
20, 15, 15, 17, 20, 20, 17, 20, 20, 20, 20, 20, 20, 9, 14,
16, 20, 12, 12, 15, 20, 17, 15, 18, 20, 20, 20, 20, 20, 16,
19, 18, 20, 15, 16, 20, 20, 17, 17, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20,
};
static const uint8_t codebook3[] = {
2, 3, 7, 13, 4, 4, 7, 15, 8, 6, 9, 17, 21, 16, 15,
21, 2, 5, 7, 11, 5, 5, 7, 14, 9, 7, 10, 16, 17, 15,
16, 21, 4, 7, 10, 17, 7, 7, 9, 15, 11, 9, 11, 16, 21,
18, 15, 21, 18, 21, 21, 21, 15, 17, 17, 19, 21, 19, 18, 20,
21, 21, 21, 20,
};
static const uint8_t codebook4[] = {
5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6,
5, 6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5,
7, 5, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, 10, 6, 10,
6, 11, 6, 11, 7, 11, 7, 12, 7, 12, 7, 12, 7, 12, 7,
12, 7, 12, 7, 12, 7, 12, 8, 13, 8, 12, 8, 12, 8, 13,
8, 13, 9, 13, 9, 13, 9, 13, 9, 12, 10, 12, 10, 13, 10,
14, 11, 14, 12, 14, 13, 14, 13, 14, 14, 15, 16, 15, 15, 15,
14, 15, 17, 21, 22, 22, 21, 22, 22, 22, 22, 22, 22, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
};
static const uint8_t codebook5[] = {
2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 5, 6,
5, 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6,
9, 6,
};
static const uint8_t codebook6[] = {
8, 5, 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9,
4, 9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 9, 5, 9, 5,
9, 5, 9, 5, 9, 6, 10, 6, 10, 7, 10, 8, 11, 9, 11,
11, 12, 13, 12, 14, 13, 15, 13, 15, 14, 16, 14, 17, 15, 17,
15, 15, 16, 16, 15, 16, 16, 16, 15, 18, 16, 15, 17, 17, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19,
};
static const uint8_t codebook7[] = {
1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6,
5, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 9, 8, 10, 9,
10, 9,
};
static const uint8_t codebook8[] = {
4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 5, 6, 5, 6,
5, 7, 5, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 9, 8,
9, 9, 9, 9, 10, 10, 10, 11, 9, 12, 9, 12, 9, 15, 10,
14, 9, 13, 10, 13, 10, 12, 10, 12, 10, 13, 10, 12, 11, 13,
11, 14, 12, 13, 13, 14, 14, 13, 14, 15, 14, 16, 13, 13, 14,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 15, 15,
};
static const uint8_t codebook9[] = {
4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 4, 5,
5, 5,
};
static const uint8_t codebook10[] = {
3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 5,
7, 5, 8, 6, 8, 6, 9, 7, 10, 7, 10, 8, 10, 8, 11,
9, 11,
};
static const uint8_t codebook11[] = {
3, 7, 3, 8, 3, 10, 3, 8, 3, 9, 3, 8, 4, 9, 4,
9, 5, 9, 6, 10, 6, 9, 7, 11, 7, 12, 9, 13, 10, 13,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12,
};
static const uint8_t codebook12[] = {
4, 5, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4,
5, 4,
};
static const uint8_t codebook13[] = {
4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 7, 7, 8, 7,
8, 7, 8, 7, 9, 8, 9, 8, 9, 8, 10, 8, 11, 9, 12,
9, 12,
};
static const uint8_t codebook14[] = {
2, 5, 2, 6, 3, 6, 4, 7, 4, 7, 5, 9, 5, 11, 6,
11, 6, 11, 7, 11, 6, 11, 6, 11, 9, 11, 8, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10,
10, 10, 10,
};
static const uint8_t codebook15[] = {
5, 6, 11, 11, 11, 11, 10, 10, 12, 11, 5, 2, 11, 5, 6,
6, 7, 9, 11, 13, 13, 10, 7, 11, 6, 7, 8, 9, 10, 12,
11, 5, 11, 6, 8, 7, 9, 11, 14, 15, 11, 6, 6, 8, 4,
5, 7, 8, 10, 13, 10, 5, 7, 7, 5, 5, 6, 8, 10, 11,
10, 7, 7, 8, 6, 5, 5, 7, 9, 9, 11, 8, 8, 11, 8,
7, 6, 6, 7, 9, 12, 11, 10, 13, 9, 9, 7, 7, 7, 9,
11, 13, 12, 15, 12, 11, 9, 8, 8, 8,
};
static const uint8_t codebook16[] = {
2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0,
0, 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0,
7, 8, 8, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7,
0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0, 0, 0, 0, 0,
7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0,
0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0,
0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0,
7, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8,
0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0,
0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 8, 9,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0,
0, 0, 0, 8, 9, 8,
};
static const uint8_t codebook17[] = {
2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0,
0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0,
0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 10, 10, 0, 0,
0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0,
0, 7, 7, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0,
0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0,
0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0,
0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0,
5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0,
0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 10, 0, 0,
0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, 10, 10, 0, 0,
0, 0, 0, 0, 0, 8, 10, 10, 0, 0, 0, 9, 9, 0, 0,
0, 9, 9, 0, 0, 0, 10, 10,
};
static const uint8_t codebook18[] = {
2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 7, 9, 9,
};
static const uint8_t codebook19[] = {
2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0,
0, 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5,
6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0,
0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0,
0, 0, 0, 0, 0, 0, 9, 9,
};
static const uint8_t codebook20[] = {
1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7,
8, 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7,
8, 8, 8, 8, 10, 10, 0, 0, 0, 8, 8, 8, 8, 10, 10,
0, 0, 0, 9, 9, 9, 9, 10, 10, 0, 0, 0, 9, 9, 9,
9, 10, 10, 0, 0, 0, 10, 10, 10, 10, 11, 11, 0, 0, 0,
0, 0, 10, 10, 11, 11,
};
static const uint8_t codebook21[] = {
2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10,
11, 10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10,
10, 10, 11, 11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9,
10, 10, 10, 10, 11, 11, 0, 6, 6, 7, 7, 8, 8, 9, 9,
9, 9, 10, 10, 11, 11, 11, 11, 0, 0, 0, 7, 7, 8, 8,
9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 0, 0, 0, 8, 8,
8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 0, 0, 0,
8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 0,
0, 0, 9, 9, 9, 9, 10, 10, 10, 10, 11, 10, 11, 11, 12,
12, 0, 0, 0, 0, 0, 9, 9, 10, 10, 10, 10, 11, 11, 11,
11, 12, 12, 0, 0, 0, 0, 0, 9, 8, 9, 9, 10, 10, 11,
11, 12, 12, 12, 12, 0, 0, 0, 0, 0, 8, 8, 9, 9, 10,
10, 11, 11, 12, 11, 12, 12, 0, 0, 0, 0, 0, 9, 10, 10,
10, 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, 0, 0,
0, 10, 10, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0,
0, 0, 0, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 0, 0,
0, 0, 0, 0, 0, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13,
0, 0, 0, 0, 0, 0, 0, 11, 11, 12, 12, 12, 12, 13, 13,
13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12,
13, 13, 13, 13,
};
static const uint8_t codebook22[] = {
1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7, 10, 9, 9,
11, 9, 9, 4, 7, 7, 10, 9, 9, 11, 9, 9, 7, 10, 10,
11, 11, 10, 12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10,
6, 9, 9, 11, 10, 10, 11, 10, 10, 7, 11, 11, 11, 11, 11,
12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10, 6, 9, 9,
11, 10, 10, 11, 10, 10,
};
static const uint8_t codebook23[] = {
2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 10, 5, 5, 6,
6, 7, 7, 8, 8, 8, 8, 10, 5, 5, 6, 6, 7, 7, 8,
8, 8, 8, 10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 10,
10, 10, 7, 7, 8, 7, 8, 8, 8, 8, 10, 10, 10, 8, 8,
8, 8, 8, 8, 8, 8, 10, 10, 10, 7, 8, 8, 8, 8, 8,
8, 8, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10,
10, 10, 10, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 9,
9, 8, 8, 9, 8, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8,
8,
};
static const uint8_t codebook24[] = {
1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 6, 5,
5, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 7, 5, 5, 7,
7, 8, 8, 8, 8, 9, 9, 11, 10, 0, 8, 8, 8, 8, 9,
9, 9, 9, 10, 10, 11, 11, 0, 8, 8, 8, 8, 9, 9, 9,
9, 10, 10, 11, 11, 0, 12, 12, 9, 9, 10, 10, 10, 10, 11,
11, 11, 12, 0, 13, 13, 9, 9, 10, 10, 10, 10, 11, 11, 12,
12, 0, 0, 0, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 0,
0, 0, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 0, 0, 0,
14, 14, 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 14, 14,
11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, 0, 12, 12,
12, 12, 13, 13, 14, 13, 0, 0, 0, 0, 0, 13, 13, 12, 12,
13, 12, 14, 13,
};
static const uint8_t codebook25[] = {
2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5,
6, 5, 5, 5, 5, 6, 6, 6, 5, 5,
};
static const uint8_t codebook26[] = {
1, 4, 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 9,
8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 9, 7, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11,
};
static const uint8_t codebook27[] = {
1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9, 10, 10, 10, 10,
6, 5, 5, 7, 7, 8, 8, 10, 8, 11, 10, 12, 12, 13, 13,
6, 5, 5, 7, 7, 8, 8, 10, 9, 11, 11, 12, 12, 13, 12,
18, 8, 8, 8, 8, 9, 9, 10, 9, 11, 10, 12, 12, 13, 13,
18, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 13, 12, 14, 13,
18, 11, 11, 9, 9, 10, 10, 11, 11, 11, 12, 13, 12, 13, 14,
18, 11, 11, 9, 8, 11, 10, 11, 11, 11, 11, 12, 12, 14, 13,
18, 18, 18, 10, 11, 10, 11, 12, 12, 12, 12, 13, 12, 14, 13,
18, 18, 18, 10, 11, 11, 9, 12, 11, 12, 12, 12, 13, 13, 13,
18, 18, 17, 14, 14, 11, 11, 12, 12, 13, 12, 14, 12, 14, 13,
18, 18, 18, 14, 14, 11, 10, 12, 9, 12, 13, 13, 13, 13, 13,
18, 18, 17, 16, 18, 13, 13, 12, 12, 13, 11, 14, 12, 14, 14,
17, 18, 18, 17, 18, 13, 12, 13, 10, 12, 11, 14, 14, 14, 14,
17, 18, 18, 18, 18, 15, 16, 12, 12, 13, 10, 14, 12, 14, 15,
18, 18, 18, 16, 17, 16, 14, 12, 11, 13, 10, 13, 13, 14, 15,
};
static const uint8_t codebook28[] = {
2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9,
9, 9, 9, 9, 10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 10, 7, 7, 7, 7, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 7, 7, 8, 8,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 8, 8,
8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10,
10, 10, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10,
9, 10, 10, 10, 11, 11, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 11, 10, 11, 11, 11, 9, 9, 9, 9, 9, 9, 10,
10, 9, 9, 10, 9, 11, 10, 11, 11, 11, 9, 9, 9, 9, 9,
9, 9, 9, 10, 10, 10, 9, 11, 11, 11, 11, 11, 9, 9, 9,
9, 10, 10, 9, 9, 9, 9, 10, 9, 11, 11, 11, 11, 11, 11,
11, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
11, 11, 11, 10, 9, 10, 10, 9, 10, 9, 9, 10, 9, 11, 10,
10, 11, 11, 11, 11, 9, 10, 9, 9, 9, 9, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 10, 10, 10, 9, 9, 10, 9, 10, 9,
10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 9, 9, 9, 9,
9, 10, 10, 10,
};
static const struct {
int dim;
int len;
int real_len;
const uint8_t * clens;
int lookup;
float min;
float delta;
const uint8_t * quant;
} cvectors[] = {
{ 2, 16, 16, codebook0, 0 },
{ 2, 8, 8, codebook1, 0 },
{ 2, 256, 256, codebook2, 0 },
{ 2, 64, 64, codebook3, 0 },
{ 2, 128, 128, codebook4, 0 },
{ 2, 32, 32, codebook5, 0 },
{ 2, 96, 96, codebook6, 0 },
{ 2, 32, 32, codebook7, 0 },
{ 2, 96, 96, codebook8, 0 },
{ 2, 17, 17, codebook9, 0 },
{ 2, 32, 32, codebook10, 0 },
{ 2, 78, 78, codebook11, 0 },
{ 2, 17, 17, codebook12, 0 },
{ 2, 32, 32, codebook13, 0 },
{ 2, 78, 78, codebook14, 0 },
{ 2, 100, 100, codebook15, 0 },
{ 8, 1641, 6561, codebook16, 1, -1.0, 1.0, (const uint8_t[]){ 1, 0, 2, } },
{ 4, 443, 625, codebook17, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } },
{ 4, 105, 625, codebook18, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } },
{ 2, 68, 81, codebook19, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } },
{ 2, 81, 81, codebook20, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } },
{ 2, 289, 289, codebook21, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } },
{ 4, 81, 81, codebook22, 1, -11.0, 11.0, (const uint8_t[]){ 1, 0, 2, } },
{ 2, 121, 121, codebook23, 1, -5.0, 1.0, (const uint8_t[]){ 5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, } },
{ 2, 169, 169, codebook24, 1, -30.0, 5.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } },
{ 2, 25, 25, codebook25, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } },
{ 2, 169, 169, codebook26, 1, -1530.0, 255.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } },
{ 2, 225, 225, codebook27, 1, -119.0, 17.0, (const uint8_t[]){ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13, 0, 14, } },
{ 2, 289, 289, codebook28, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } },
};
static const struct {
int dim;
int subclass;
int masterbook;
const int * nbooks;
} floor_classes[] = {
{ 3, 0, 0, (const int[]){ 4 } },
{ 4, 1, 0, (const int[]){ 5, 6 } },
{ 3, 1, 1, (const int[]){ 7, 8 } },
{ 4, 2, 2, (const int[]){ -1, 9, 10, 11 } },
{ 3, 2, 3, (const int[]){ -1, 12, 13, 14 } },
};
#endif /* FFMPEG_VORBIS_ENC_DATA_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2008 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "parser.h"
static int parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
if(avctx->codec_id == CODEC_ID_THEORA)
s->pict_type= (buf[0]&0x40) ? FF_P_TYPE : FF_I_TYPE;
else
s->pict_type= (buf[0]&0x80) ? FF_P_TYPE : FF_I_TYPE;
*poutbuf = buf;
*poutbuf_size = buf_size;
return buf_size;
}
AVCodecParser vp3_parser = {
{ CODEC_ID_THEORA, CODEC_ID_VP3,
CODEC_ID_VP6, CODEC_ID_VP6F, CODEC_ID_VP6A },
0,
NULL,
parse,
};
@@ -1,8 +1,32 @@
#ifndef VP3DATA_H
#define VP3DATA_H
/*
* copyright (C) 2003 the ffmpeg project
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* these coefficients dequantize intraframe Y plane coefficients */
static int16_t vp31_intra_y_dequant[64] =
#ifndef FFMPEG_VP3DATA_H
#define FFMPEG_VP3DATA_H
#include <stdint.h>
#include <stdlib.h>
/* these coefficients dequantize intraframe Y plane coefficients
* (note: same as JPEG) */
static const int16_t vp31_intra_y_dequant[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,
@@ -13,8 +37,9 @@ static int16_t vp31_intra_y_dequant[64] =
72, 92, 95, 98, 112, 100, 103, 99
};
/* these coefficients dequantize intraframe C plane coefficients */
static int16_t vp31_intra_c_dequant[64] =
/* these coefficients dequantize intraframe C plane coefficients
* (note: same as JPEG) */
static const int16_t vp31_intra_c_dequant[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,
@@ -26,7 +51,7 @@ static int16_t vp31_intra_c_dequant[64] =
};
/* these coefficients dequantize interframe coefficients (all planes) */
static int16_t vp31_inter_dequant[64] =
static const int16_t vp31_inter_dequant[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,
@@ -37,7 +62,7 @@ static int16_t vp31_inter_dequant[64] =
40, 48, 64, 64, 64, 96, 128, 128
};
static int16_t vp31_dc_scale_factor[64] =
static const int16_t vp31_dc_scale_factor[64] =
{ 220, 200, 190, 180, 170, 170, 160, 160,
150, 150, 140, 140, 130, 130, 120, 120,
110, 110, 100, 100, 90, 90, 90, 80,
@@ -48,7 +73,7 @@ static int16_t vp31_dc_scale_factor[64] =
20, 10, 10, 10, 10, 10, 10, 10
};
static uint32_t vp31_quality_threshold[64] =
static const uint32_t vp31_ac_scale_factor[64] =
{ 500, 450, 400, 370, 340, 310, 285, 265,
245, 225, 210, 195, 185, 180, 170, 160,
150, 145, 135, 130, 125, 115, 110, 107,
@@ -59,20 +84,364 @@ static uint32_t vp31_quality_threshold[64] =
21, 19, 18, 17, 15, 13, 12, 10
};
/* table used to convert natural order <-> zigzag order */
static const int dezigzag_index[64] =
{ 0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
static const uint32_t vp31_filter_limit_values[64] =
{ 30, 25, 20, 20, 15, 15, 14, 14,
13, 13, 12, 12, 11, 11, 10, 10,
9, 9, 8, 8, 7, 7, 7, 7,
6, 6, 6, 6, 5, 5, 5, 5,
4, 4, 4, 4, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* inverse of dezigzag index */
static int zigzag_index[64];
static const uint16_t superblock_run_length_vlc_table[34][2] = {
{ 0, 1 },
{ 4, 3 }, { 5, 3 },
{ 0xC, 4 }, { 0xD, 4 },
{ 0x38, 6 }, { 0x39, 6 }, { 0x3A, 6 }, { 0x3B, 6 },
{ 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 },
{ 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 },
{ 0x3E0, 10 }, { 0x3E1, 10 }, { 0x3E2, 10 }, { 0x3E3, 10 },
{ 0x3E4, 10 }, { 0x3E5, 10 }, { 0x3E6, 10 }, { 0x3E7, 10 },
{ 0x3E8, 10 }, { 0x3E9, 10 }, { 0x3EA, 10 }, { 0x3EB, 10 },
{ 0x3EC, 10 }, { 0x3ED, 10 }, { 0x3EE, 10 }, { 0x3EF, 10 },
{ 0x3F, 6 } /* this last VLC is a special case for reading 12 more
bits from stream and adding the value 34 */
};
static const uint16_t fragment_run_length_vlc_table[30][2] = {
/* 1 -> 2 */
{ 0x0, 2 }, { 0x1, 2 },
/* 3 -> 4 */
{ 0x4, 3 }, { 0x5, 3 },
/* 5 -> 6 */
{ 0xC, 4 }, { 0xD, 4 },
/* 7 -> 10 */
{ 0x38, 6 }, { 0x39, 6 },
{ 0x3A, 6 }, { 0x3B, 6 },
/* 11 -> 14 */
{ 0x78, 7 }, { 0x79, 7 },
{ 0x7A, 7 }, { 0x7B, 7 },
/* 15 -> 30 */
{ 0x1F0, 9 }, { 0x1F1, 9 }, { 0x1F2, 9 }, { 0x1F3, 9 },
{ 0x1F4, 9 }, { 0x1F5, 9 }, { 0x1F6, 9 }, { 0x1F7, 9 },
{ 0x1F8, 9 }, { 0x1F9, 9 }, { 0x1FA, 9 }, { 0x1FB, 9 },
{ 0x1FC, 9 }, { 0x1FD, 9 }, { 0x1FE, 9 }, { 0x1FF, 9 }
};
static const uint8_t mode_code_vlc_table[8][2] = {
{ 0, 1 }, { 2, 2 },
{ 6, 3 }, { 14, 4 },
{ 30, 5 }, { 62, 6 },
{ 126, 7 }, { 127, 7 }
};
static const uint8_t motion_vector_vlc_table[63][2] = {
{ 0, 3 },
{ 1, 3 },
{ 2, 3 },
{ 6, 4 }, { 7, 4 },
{ 8, 4 }, { 9, 4 },
{ 40, 6 }, { 41, 6 }, { 42, 6 }, { 43, 6 },
{ 44, 6 }, { 45, 6 }, { 46, 6 }, { 47, 6 },
{ 96, 7 }, { 97, 7 }, { 98, 7 }, { 99, 7 },
{ 100, 7 }, { 101, 7 }, { 102, 7 }, { 103, 7 },
{ 104, 7 }, { 105, 7 }, { 106, 7 }, { 107, 7 },
{ 108, 7 }, { 109, 7 }, { 110, 7 }, { 111, 7 },
{ 0xE0, 8 }, { 0xE1, 8 }, { 0xE2, 8 }, { 0xE3, 8 },
{ 0xE4, 8 }, { 0xE5, 8 }, { 0xE6, 8 }, { 0xE7, 8 },
{ 0xE8, 8 }, { 0xE9, 8 }, { 0xEA, 8 }, { 0xEB, 8 },
{ 0xEC, 8 }, { 0xED, 8 }, { 0xEE, 8 }, { 0xEF, 8 },
{ 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 },
{ 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 },
{ 0xF8, 8 }, { 0xF9, 8 }, { 0xFA, 8 }, { 0xFB, 8 },
{ 0xFC, 8 }, { 0xFD, 8 }, { 0xFE, 8 }, { 0xFF, 8 }
};
static const int motion_vector_table[63] = {
0, 1, -1,
2, -2,
3, -3,
4, -4, 5, -5, 6, -6, 7, -7,
8, -8, 9, -9, 10, -10, 11, -11, 12, -12, 13, -13, 14, -14, 15, -15,
16, -16, 17, -17, 18, -18, 19, -19, 20, -20, 21, -21, 22, -22, 23, -23,
24, -24, 25, -25, 26, -26, 27, -27, 28, -28, 29, -29, 30, -30, 31, -31
};
static const int8_t fixed_motion_vector_table[64] = {
0, 0, 1, -1, 2, -2, 3, -3,
4, -4, 5, -5, 6, -6, 7, -7,
8, -8, 9, -9, 10, -10, 11, -11,
12, -12, 13, -13, 14, -14, 15, -15,
16, -16, 17, -17, 18, -18, 19, -19,
20, -20, 21, -21, 22, -22, 23, -23,
24, -24, 25, -25, 26, -26, 27, -27,
28, -28, 29, -29, 30, -30, 31, -31
};
/* only tokens 0..6 indicate eob runs */
static const int eob_run_base[7] = {
1, 2, 3, 4, 8, 16, 0
};
static const int eob_run_get_bits[7] = {
0, 0, 0, 2, 3, 4, 12
};
static const int zero_run_base[32] = {
0, 0, 0, 0, 0, 0, 0, /* 0..6 are never used */
0, 0, /* 7..8 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9..22 */
1, 2, 3, 4, 5, /* 23..27 */
6, 10, 1, 2 /* 28..31 */
};
static const int zero_run_get_bits[32] = {
0, 0, 0, 0, 0, 0, 0, /* 0..6 are never used */
3, 6, /* 7..8 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9..22 */
0, 0, 0, 0, 0, /* 23..27 */
2, 3, 0, 1 /* 28..31 */
};
static const int coeff_get_bits[32] = {
0, 0, 0, 0, 0, 0, 0, /* 0..6 are never used */
0, 0, 0, 0, 0, 0, /* 7..12 use constant coeffs */
1, 1, 1, 1, /* 13..16 are constants but still need sign bit */
2, 3, 4, 5, 6, 10, /* 17..22, for reading large coeffs */
1, 1, 1, 1, 1, 1, 1, /* 23..29 are constants but still need sign bit */
2, 2 /* 30..31 */
};
static const int16_t coeff_table_token_7_8[1] = { 0 };
static const int16_t coeff_table_token_9[1] = { 1 };
static const int16_t coeff_table_token_10[1] = { -1 };
static const int16_t coeff_table_token_11[1] = { 2 };
static const int16_t coeff_table_token_12[1] = { -2 };
static const int16_t coeff_table_token_13[2] = { 3, -3 };
static const int16_t coeff_table_token_14[2] = { 4, -4 };
static const int16_t coeff_table_token_15[2] = { 5, -5 };
static const int16_t coeff_table_token_16[2] = { 6, -6 };
static const int16_t coeff_table_token_23_24_25_26_27_28_29[2] = { 1, -1 };
static const int16_t coeff_table_token_30[4] = { 2, 3, -2, -3 };
static const int16_t coeff_table_token_31[4] = { 2, 3, -2, -3 };
static const int16_t coeff_table_token_17[4] = {
7, 8, -7, -8
};
static const int16_t coeff_table_token_18[8] = {
9, 10, 11, 12, -9, -10, -11, -12
};
static const int16_t coeff_table_token_19[16] = {
13, 14, 15, 16, 17, 18, 19, 20, -13, -14, -15, -16, -17, -18, -19, -20
};
static const int16_t coeff_table_token_20[32] = {
21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36,
-21, -22, -23, -24, -25, -26, -27, -28,
-29, -30, -31, -32, -33, -34, -35, -36
};
static const int16_t coeff_table_token_21[64] = {
37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68,
-37, -38, -39, -40, -41, -42, -43, -44,
-45, -46, -47, -48, -49, -50, -51, -52,
-53, -54, -55, -56, -57, -58, -59, -60,
-61, -62, -63, -64, -65, -66, -67, -68
};
static const int16_t coeff_table_token_22[1024] = {
69, 70, 71, 72, 73, 74, 75, 76,
77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92,
93, 94, 95, 96, 97, 98, 99, 100,
101, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 123, 124,
125, 126, 127, 128, 129, 130, 131, 132,
133, 134, 135, 136, 137, 138, 139, 140,
141, 142, 143, 144, 145, 146, 147, 148,
149, 150, 151, 152, 153, 154, 155, 156,
157, 158, 159, 160, 161, 162, 163, 164,
165, 166, 167, 168, 169, 170, 171, 172,
173, 174, 175, 176, 177, 178, 179, 180,
181, 182, 183, 184, 185, 186, 187, 188,
189, 190, 191, 192, 193, 194, 195, 196,
197, 198, 199, 200, 201, 202, 203, 204,
205, 206, 207, 208, 209, 210, 211, 212,
213, 214, 215, 216, 217, 218, 219, 220,
221, 222, 223, 224, 225, 226, 227, 228,
229, 230, 231, 232, 233, 234, 235, 236,
237, 238, 239, 240, 241, 242, 243, 244,
245, 246, 247, 248, 249, 250, 251, 252,
253, 254, 255, 256, 257, 258, 259, 260,
261, 262, 263, 264, 265, 266, 267, 268,
269, 270, 271, 272, 273, 274, 275, 276,
277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 287, 288, 289, 290, 291, 292,
293, 294, 295, 296, 297, 298, 299, 300,
301, 302, 303, 304, 305, 306, 307, 308,
309, 310, 311, 312, 313, 314, 315, 316,
317, 318, 319, 320, 321, 322, 323, 324,
325, 326, 327, 328, 329, 330, 331, 332,
333, 334, 335, 336, 337, 338, 339, 340,
341, 342, 343, 344, 345, 346, 347, 348,
349, 350, 351, 352, 353, 354, 355, 356,
357, 358, 359, 360, 361, 362, 363, 364,
365, 366, 367, 368, 369, 370, 371, 372,
373, 374, 375, 376, 377, 378, 379, 380,
381, 382, 383, 384, 385, 386, 387, 388,
389, 390, 391, 392, 393, 394, 395, 396,
397, 398, 399, 400, 401, 402, 403, 404,
405, 406, 407, 408, 409, 410, 411, 412,
413, 414, 415, 416, 417, 418, 419, 420,
421, 422, 423, 424, 425, 426, 427, 428,
429, 430, 431, 432, 433, 434, 435, 436,
437, 438, 439, 440, 441, 442, 443, 444,
445, 446, 447, 448, 449, 450, 451, 452,
453, 454, 455, 456, 457, 458, 459, 460,
461, 462, 463, 464, 465, 466, 467, 468,
469, 470, 471, 472, 473, 474, 475, 476,
477, 478, 479, 480, 481, 482, 483, 484,
485, 486, 487, 488, 489, 490, 491, 492,
493, 494, 495, 496, 497, 498, 499, 500,
501, 502, 503, 504, 505, 506, 507, 508,
509, 510, 511, 512, 513, 514, 515, 516,
517, 518, 519, 520, 521, 522, 523, 524,
525, 526, 527, 528, 529, 530, 531, 532,
533, 534, 535, 536, 537, 538, 539, 540,
541, 542, 543, 544, 545, 546, 547, 548,
549, 550, 551, 552, 553, 554, 555, 556,
557, 558, 559, 560, 561, 562, 563, 564,
565, 566, 567, 568, 569, 570, 571, 572,
573, 574, 575, 576, 577, 578, 579, 580,
-69, -70, -71, -72, -73, -74, -75, -76,
-77, -78, -79, -80, -81, -82, -83, -84,
-85, -86, -87, -88, -89, -90, -91, -92,
-93, -94, -95, -96, -97, -98, -99, -100,
-101, -102, -103, -104, -105, -106, -107, -108,
-109, -110, -111, -112, -113, -114, -115, -116,
-117, -118, -119, -120, -121, -122, -123, -124,
-125, -126, -127, -128, -129, -130, -131, -132,
-133, -134, -135, -136, -137, -138, -139, -140,
-141, -142, -143, -144, -145, -146, -147, -148,
-149, -150, -151, -152, -153, -154, -155, -156,
-157, -158, -159, -160, -161, -162, -163, -164,
-165, -166, -167, -168, -169, -170, -171, -172,
-173, -174, -175, -176, -177, -178, -179, -180,
-181, -182, -183, -184, -185, -186, -187, -188,
-189, -190, -191, -192, -193, -194, -195, -196,
-197, -198, -199, -200, -201, -202, -203, -204,
-205, -206, -207, -208, -209, -210, -211, -212,
-213, -214, -215, -216, -217, -218, -219, -220,
-221, -222, -223, -224, -225, -226, -227, -228,
-229, -230, -231, -232, -233, -234, -235, -236,
-237, -238, -239, -240, -241, -242, -243, -244,
-245, -246, -247, -248, -249, -250, -251, -252,
-253, -254, -255, -256, -257, -258, -259, -260,
-261, -262, -263, -264, -265, -266, -267, -268,
-269, -270, -271, -272, -273, -274, -275, -276,
-277, -278, -279, -280, -281, -282, -283, -284,
-285, -286, -287, -288, -289, -290, -291, -292,
-293, -294, -295, -296, -297, -298, -299, -300,
-301, -302, -303, -304, -305, -306, -307, -308,
-309, -310, -311, -312, -313, -314, -315, -316,
-317, -318, -319, -320, -321, -322, -323, -324,
-325, -326, -327, -328, -329, -330, -331, -332,
-333, -334, -335, -336, -337, -338, -339, -340,
-341, -342, -343, -344, -345, -346, -347, -348,
-349, -350, -351, -352, -353, -354, -355, -356,
-357, -358, -359, -360, -361, -362, -363, -364,
-365, -366, -367, -368, -369, -370, -371, -372,
-373, -374, -375, -376, -377, -378, -379, -380,
-381, -382, -383, -384, -385, -386, -387, -388,
-389, -390, -391, -392, -393, -394, -395, -396,
-397, -398, -399, -400, -401, -402, -403, -404,
-405, -406, -407, -408, -409, -410, -411, -412,
-413, -414, -415, -416, -417, -418, -419, -420,
-421, -422, -423, -424, -425, -426, -427, -428,
-429, -430, -431, -432, -433, -434, -435, -436,
-437, -438, -439, -440, -441, -442, -443, -444,
-445, -446, -447, -448, -449, -450, -451, -452,
-453, -454, -455, -456, -457, -458, -459, -460,
-461, -462, -463, -464, -465, -466, -467, -468,
-469, -470, -471, -472, -473, -474, -475, -476,
-477, -478, -479, -480, -481, -482, -483, -484,
-485, -486, -487, -488, -489, -490, -491, -492,
-493, -494, -495, -496, -497, -498, -499, -500,
-501, -502, -503, -504, -505, -506, -507, -508,
-509, -510, -511, -512, -513, -514, -515, -516,
-517, -518, -519, -520, -521, -522, -523, -524,
-525, -526, -527, -528, -529, -530, -531, -532,
-533, -534, -535, -536, -537, -538, -539, -540,
-541, -542, -543, -544, -545, -546, -547, -548,
-549, -550, -551, -552, -553, -554, -555, -556,
-557, -558, -559, -560, -561, -562, -563, -564,
-565, -566, -567, -568, -569, -570, -571, -572,
-573, -574, -575, -576, -577, -578, -579, -580
};
static const int16_t *const coeff_tables[32] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
coeff_table_token_7_8,
coeff_table_token_7_8,
coeff_table_token_9,
coeff_table_token_10,
coeff_table_token_11,
coeff_table_token_12,
coeff_table_token_13,
coeff_table_token_14,
coeff_table_token_15,
coeff_table_token_16,
coeff_table_token_17,
coeff_table_token_18,
coeff_table_token_19,
coeff_table_token_20,
coeff_table_token_21,
coeff_table_token_22,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_23_24_25_26_27_28_29,
coeff_table_token_30,
coeff_table_token_31
};
static const uint16_t dc_bias[16][32][2] = {
{ /* DC bias table 0 */
@@ -2809,4 +3178,4 @@ static const uint16_t ac_bias_3[16][32][2] = {
}
};
#endif /* VP3DATA_H */
#endif /* FFMPEG_VP3DATA_H */
@@ -0,0 +1,224 @@
/*
* Copyright (C) 2004 the ffmpeg project
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vp3dsp.c
* Standard C DSP-oriented functions cribbed from the original VP3
* source code.
*/
#include "avcodec.h"
#include "dsputil.h"
#define IdctAdjustBeforeShift 8
#define xC1S7 64277
#define xC2S6 60547
#define xC3S5 54491
#define xC4S4 46341
#define xC5S3 36410
#define xC6S2 25080
#define xC7S1 12785
#define M(a,b) (((a) * (b))>>16)
static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int type)
{
int16_t *ip = input;
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
int Ed, Gd, Add, Bdd, Fd, Hd;
int i;
/* Inverse DCT on the rows now */
for (i = 0; i < 8; i++) {
/* Check for non-zero values */
if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) {
A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
Ad = M(xC4S4, (A - C));
Bd = M(xC4S4, (B - D));
Cd = A + C;
Dd = B + D;
E = M(xC4S4, (ip[0] + ip[4]));
F = M(xC4S4, (ip[0] - ip[4]));
G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
Ed = E - G;
Gd = E + G;
Add = F + Ad;
Bdd = Bd - H;
Fd = F - Ad;
Hd = Bd + H;
/* Final sequence of operations over-write original inputs. */
ip[0] = Gd + Cd ;
ip[7] = Gd - Cd ;
ip[1] = Add + Hd;
ip[2] = Add - Hd;
ip[3] = Ed + Dd ;
ip[4] = Ed - Dd ;
ip[5] = Fd + Bdd;
ip[6] = Fd - Bdd;
}
ip += 8; /* next row */
}
ip = input;
for ( i = 0; i < 8; i++) {
/* Check for non-zero values (bitwise or faster than ||) */
if ( ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {
A = M(xC1S7, ip[1*8]) + M(xC7S1, ip[7*8]);
B = M(xC7S1, ip[1*8]) - M(xC1S7, ip[7*8]);
C = M(xC3S5, ip[3*8]) + M(xC5S3, ip[5*8]);
D = M(xC3S5, ip[5*8]) - M(xC5S3, ip[3*8]);
Ad = M(xC4S4, (A - C));
Bd = M(xC4S4, (B - D));
Cd = A + C;
Dd = B + D;
E = M(xC4S4, (ip[0*8] + ip[4*8])) + 8;
F = M(xC4S4, (ip[0*8] - ip[4*8])) + 8;
if(type==1){ //HACK
E += 16*128;
F += 16*128;
}
G = M(xC2S6, ip[2*8]) + M(xC6S2, ip[6*8]);
H = M(xC6S2, ip[2*8]) - M(xC2S6, ip[6*8]);
Ed = E - G;
Gd = E + G;
Add = F + Ad;
Bdd = Bd - H;
Fd = F - Ad;
Hd = Bd + H;
/* Final sequence of operations over-write original inputs. */
if(type==0){
ip[0*8] = (Gd + Cd ) >> 4;
ip[7*8] = (Gd - Cd ) >> 4;
ip[1*8] = (Add + Hd ) >> 4;
ip[2*8] = (Add - Hd ) >> 4;
ip[3*8] = (Ed + Dd ) >> 4;
ip[4*8] = (Ed - Dd ) >> 4;
ip[5*8] = (Fd + Bdd ) >> 4;
ip[6*8] = (Fd - Bdd ) >> 4;
}else if(type==1){
dst[0*stride] = cm[(Gd + Cd ) >> 4];
dst[7*stride] = cm[(Gd - Cd ) >> 4];
dst[1*stride] = cm[(Add + Hd ) >> 4];
dst[2*stride] = cm[(Add - Hd ) >> 4];
dst[3*stride] = cm[(Ed + Dd ) >> 4];
dst[4*stride] = cm[(Ed - Dd ) >> 4];
dst[5*stride] = cm[(Fd + Bdd ) >> 4];
dst[6*stride] = cm[(Fd - Bdd ) >> 4];
}else{
dst[0*stride] = cm[dst[0*stride] + ((Gd + Cd ) >> 4)];
dst[7*stride] = cm[dst[7*stride] + ((Gd - Cd ) >> 4)];
dst[1*stride] = cm[dst[1*stride] + ((Add + Hd ) >> 4)];
dst[2*stride] = cm[dst[2*stride] + ((Add - Hd ) >> 4)];
dst[3*stride] = cm[dst[3*stride] + ((Ed + Dd ) >> 4)];
dst[4*stride] = cm[dst[4*stride] + ((Ed - Dd ) >> 4)];
dst[5*stride] = cm[dst[5*stride] + ((Fd + Bdd ) >> 4)];
dst[6*stride] = cm[dst[6*stride] + ((Fd - Bdd ) >> 4)];
}
} else {
if(type==0){
ip[0*8] =
ip[1*8] =
ip[2*8] =
ip[3*8] =
ip[4*8] =
ip[5*8] =
ip[6*8] =
ip[7*8] = ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
}else if(type==1){
dst[0*stride]=
dst[1*stride]=
dst[2*stride]=
dst[3*stride]=
dst[4*stride]=
dst[5*stride]=
dst[6*stride]=
dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)];
}else{
if(ip[0*8]){
int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
dst[0*stride] = cm[dst[0*stride] + v];
dst[1*stride] = cm[dst[1*stride] + v];
dst[2*stride] = cm[dst[2*stride] + v];
dst[3*stride] = cm[dst[3*stride] + v];
dst[4*stride] = cm[dst[4*stride] + v];
dst[5*stride] = cm[dst[5*stride] + v];
dst[6*stride] = cm[dst[6*stride] + v];
dst[7*stride] = cm[dst[7*stride] + v];
}
}
}
ip++; /* next column */
dst++;
}
}
void ff_vp3_idct_c(DCTELEM *block/* align 16*/){
idct(NULL, 0, block, 0);
}
void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
idct(dest, line_size, block, 1);
}
void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
idct(dest, line_size, block, 2);
}
@@ -0,0 +1,296 @@
/**
* @file vp5.c
* VP5 compatible video decoder
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <string.h>
#include "avcodec.h"
#include "dsputil.h"
#include "bitstream.h"
#include "vp56.h"
#include "vp56data.h"
#include "vp5data.h"
static int vp5_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size,
int *golden_frame)
{
vp56_range_coder_t *c = &s->c;
int rows, cols;
vp56_init_range_decoder(&s->c, buf, buf_size);
s->framep[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
vp56_rac_get(c);
vp56_init_dequant(s, vp56_rac_gets(c, 6));
if (s->framep[VP56_FRAME_CURRENT]->key_frame)
{
vp56_rac_gets(c, 8);
if(vp56_rac_gets(c, 5) > 5)
return 0;
vp56_rac_gets(c, 2);
if (vp56_rac_get(c)) {
av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
return 0;
}
rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */
cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */
vp56_rac_gets(c, 8); /* number of displayed macroblock rows */
vp56_rac_gets(c, 8); /* number of displayed macroblock cols */
vp56_rac_gets(c, 2);
if (16*cols != s->avctx->coded_width ||
16*rows != s->avctx->coded_height) {
avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
return 2;
}
}
return 1;
}
/* Gives very similar result than the vp6 version except in a few cases */
static int vp5_adjust(int v, int t)
{
int s2, s1 = v >> 31;
v ^= s1;
v -= s1;
v *= v < 2*t;
v -= t;
s2 = v >> 31;
v ^= s2;
v -= s2;
v = t - v;
v += s1;
v ^= s1;
return v;
}
static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
int comp, di;
for (comp=0; comp<2; comp++) {
int delta = 0;
if (vp56_rac_get_prob(c, model->vector_dct[comp])) {
int sign = vp56_rac_get_prob(c, model->vector_sig[comp]);
di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]);
di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1;
delta = vp56_rac_get_tree(c, vp56_pva_tree,
model->vector_pdv[comp]);
delta = di | (delta << 2);
delta = (delta ^ -sign) + sign;
}
if (!comp)
vect->x = delta;
else
vect->y = delta;
}
}
static void vp5_parse_vector_models(vp56_context_t *s)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
int comp, node;
for (comp=0; comp<2; comp++) {
if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0]))
model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1]))
model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2]))
model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7);
if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3]))
model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7);
}
for (comp=0; comp<2; comp++)
for (node=0; node<7; node++)
if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node]))
model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
}
static void vp5_parse_coeff_models(vp56_context_t *s)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
uint8_t def_prob[11];
int node, cg, ctx;
int ct; /* code type */
int pt; /* plane type (0 for Y, 1 for U or V) */
memset(def_prob, 0x80, sizeof(def_prob));
for (pt=0; pt<2; pt++)
for (node=0; node<11; node++)
if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) {
def_prob[node] = vp56_rac_gets_nn(c, 7);
model->coeff_dccv[pt][node] = def_prob[node];
} else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
model->coeff_dccv[pt][node] = def_prob[node];
}
for (ct=0; ct<3; ct++)
for (pt=0; pt<2; pt++)
for (cg=0; cg<6; cg++)
for (node=0; node<11; node++)
if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) {
def_prob[node] = vp56_rac_gets_nn(c, 7);
model->coeff_ract[pt][ct][cg][node] = def_prob[node];
} else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
model->coeff_ract[pt][ct][cg][node] = def_prob[node];
}
/* coeff_dcct is a linear combination of coeff_dccv */
for (pt=0; pt<2; pt++)
for (ctx=0; ctx<36; ctx++)
for (node=0; node<5; node++)
model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254);
/* coeff_acct is a linear combination of coeff_ract */
for (ct=0; ct<3; ct++)
for (pt=0; pt<2; pt++)
for (cg=0; cg<3; cg++)
for (ctx=0; ctx<6; ctx++)
for (node=0; node<5; node++)
model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254);
}
static void vp5_parse_coeff(vp56_context_t *s)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
uint8_t *permute = s->scantable.permutated;
uint8_t *model1, *model2;
int coeff, sign, coeff_idx;
int b, i, cg, idx, ctx, ctx_last;
int pt = 0; /* plane type (0 for Y, 1 for U or V) */
for (b=0; b<6; b++) {
int ct = 1; /* code type */
if (b > 3) pt = 1;
ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0]
+ s->above_blocks[s->above_block_idx[b]].not_null_dc;
model1 = model->coeff_dccv[pt];
model2 = model->coeff_dcct[pt][ctx];
for (coeff_idx=0; coeff_idx<64; ) {
if (vp56_rac_get_prob(c, model2[0])) {
if (vp56_rac_get_prob(c, model2[2])) {
if (vp56_rac_get_prob(c, model2[3])) {
s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4;
idx = vp56_rac_get_tree(c, vp56_pc_tree, model1);
sign = vp56_rac_get(c);
coeff = vp56_coeff_bias[idx+5];
for (i=vp56_coeff_bit_length[idx]; i>=0; i--)
coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i;
} else {
if (vp56_rac_get_prob(c, model2[4])) {
coeff = 3 + vp56_rac_get_prob(c, model1[5]);
s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3;
} else {
coeff = 2;
s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2;
}
sign = vp56_rac_get(c);
}
ct = 2;
} else {
ct = 1;
s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1;
sign = vp56_rac_get(c);
coeff = 1;
}
coeff = (coeff ^ -sign) + sign;
if (coeff_idx)
coeff *= s->dequant_ac;
s->block_coeff[b][permute[coeff_idx]] = coeff;
} else {
if (ct && !vp56_rac_get_prob(c, model2[1]))
break;
ct = 0;
s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0;
}
cg = vp5_coeff_groups[++coeff_idx];
ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx];
model1 = model->coeff_ract[pt][ct][cg];
model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx];
}
ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24);
s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx;
if (coeff_idx < ctx_last)
for (i=coeff_idx; i<=ctx_last; i++)
s->coeff_ctx[vp56_b6to4[b]][i] = 5;
s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0];
}
}
static void vp5_default_models_init(vp56_context_t *s)
{
vp56_model_t *model = s->modelp;
int i;
for (i=0; i<2; i++) {
model->vector_sig[i] = 0x80;
model->vector_dct[i] = 0x80;
model->vector_pdi[i][0] = 0x55;
model->vector_pdi[i][1] = 0x80;
}
memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv));
}
static av_cold int vp5_decode_init(AVCodecContext *avctx)
{
vp56_context_t *s = avctx->priv_data;
vp56_init(avctx, 1, 0);
s->vp56_coord_div = vp5_coord_div;
s->parse_vector_adjustment = vp5_parse_vector_adjustment;
s->adjust = vp5_adjust;
s->parse_coeff = vp5_parse_coeff;
s->default_models_init = vp5_default_models_init;
s->parse_vector_models = vp5_parse_vector_models;
s->parse_coeff_models = vp5_parse_coeff_models;
s->parse_header = vp5_parse_header;
return 0;
}
AVCodec vp5_decoder = {
"vp5",
CODEC_TYPE_VIDEO,
CODEC_ID_VP5,
sizeof(vp56_context_t),
vp5_decode_init,
NULL,
vp56_free,
vp56_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP5"),
};
@@ -0,0 +1,701 @@
/**
* @file vp56.c
* VP5 and VP6 compatible video decoder (common features)
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "bytestream.h"
#include "vp56.h"
#include "vp56data.h"
void vp56_init_dequant(vp56_context_t *s, int quantizer)
{
s->quantizer = quantizer;
s->dequant_dc = vp56_dc_dequant[quantizer] << 2;
s->dequant_ac = vp56_ac_dequant[quantizer] << 2;
}
static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col,
vp56_frame_t ref_frame)
{
int nb_pred = 0;
vp56_mv_t vect[2] = {{0,0}, {0,0}};
int pos, offset;
vp56_mv_t mvp;
for (pos=0; pos<12; pos++) {
mvp.x = col + vp56_candidate_predictor_pos[pos][0];
mvp.y = row + vp56_candidate_predictor_pos[pos][1];
if (mvp.x < 0 || mvp.x >= s->mb_width ||
mvp.y < 0 || mvp.y >= s->mb_height)
continue;
offset = mvp.x + s->mb_width*mvp.y;
if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
continue;
if ((s->macroblocks[offset].mv.x == vect[0].x &&
s->macroblocks[offset].mv.y == vect[0].y) ||
(s->macroblocks[offset].mv.x == 0 &&
s->macroblocks[offset].mv.y == 0))
continue;
vect[nb_pred++] = s->macroblocks[offset].mv;
if (nb_pred > 1) {
nb_pred = -1;
break;
}
s->vector_candidate_pos = pos;
}
s->vector_candidate[0] = vect[0];
s->vector_candidate[1] = vect[1];
return nb_pred+1;
}
static void vp56_parse_mb_type_models(vp56_context_t *s)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
int i, ctx, type;
for (ctx=0; ctx<3; ctx++) {
if (vp56_rac_get_prob(c, 174)) {
int idx = vp56_rac_gets(c, 4);
memcpy(model->mb_types_stats[ctx],
vp56_pre_def_mb_type_stats[idx][ctx],
sizeof(model->mb_types_stats[ctx]));
}
if (vp56_rac_get_prob(c, 254)) {
for (type=0; type<10; type++) {
for(i=0; i<2; i++) {
if (vp56_rac_get_prob(c, 205)) {
int delta, sign = vp56_rac_get(c);
delta = vp56_rac_get_tree(c, vp56_pmbtm_tree,
vp56_mb_type_model_model);
if (!delta)
delta = 4 * vp56_rac_gets(c, 7);
model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;
}
}
}
}
}
/* compute MB type probability tables based on previous MB type */
for (ctx=0; ctx<3; ctx++) {
int p[10];
for (type=0; type<10; type++)
p[type] = 100 * model->mb_types_stats[ctx][type][1];
for (type=0; type<10; type++) {
int p02, p34, p0234, p17, p56, p89, p5689, p156789;
/* conservative MB type probability */
model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]);
p[type] = 0; /* same MB type => weight is null */
/* binary tree parsing probabilities */
p02 = p[0] + p[2];
p34 = p[3] + p[4];
p0234 = p02 + p34;
p17 = p[1] + p[7];
p56 = p[5] + p[6];
p89 = p[8] + p[9];
p5689 = p56 + p89;
p156789 = p17 + p5689;
model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789);
model->mb_type[ctx][type][2] = 1 + 255 * p02 / (1+p0234);
model->mb_type[ctx][type][3] = 1 + 255 * p17 / (1+p156789);
model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02);
model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34);
model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17);
model->mb_type[ctx][type][7] = 1 + 255 * p56 / (1+p5689);
model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56);
model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89);
/* restore initial value */
p[type] = 100 * model->mb_types_stats[ctx][type][1];
}
}
}
static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s,
vp56_mb_t prev_type, int ctx)
{
uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type];
vp56_range_coder_t *c = &s->c;
if (vp56_rac_get_prob(c, mb_type_model[0]))
return prev_type;
else
return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model);
}
static void vp56_decode_4mv(vp56_context_t *s, int row, int col)
{
vp56_mv_t mv = {0,0};
int type[4];
int b;
/* parse each block type */
for (b=0; b<4; b++) {
type[b] = vp56_rac_gets(&s->c, 2);
if (type[b])
type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */
}
/* get vectors */
for (b=0; b<4; b++) {
switch (type[b]) {
case VP56_MB_INTER_NOVEC_PF:
s->mv[b] = (vp56_mv_t) {0,0};
break;
case VP56_MB_INTER_DELTA_PF:
s->parse_vector_adjustment(s, &s->mv[b]);
break;
case VP56_MB_INTER_V1_PF:
s->mv[b] = s->vector_candidate[0];
break;
case VP56_MB_INTER_V2_PF:
s->mv[b] = s->vector_candidate[1];
break;
}
mv.x += s->mv[b].x;
mv.y += s->mv[b].y;
}
/* this is the one selected for the whole MB for prediction */
s->macroblocks[row * s->mb_width + col].mv = s->mv[3];
/* chroma vectors are average luma vectors */
if (s->avctx->codec->id == CODEC_ID_VP5) {
s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2);
s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2);
} else {
s->mv[4] = s->mv[5] = (vp56_mv_t) {mv.x/4, mv.y/4};
}
}
static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col)
{
vp56_mv_t *mv, vect = {0,0};
int ctx, b;
ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS);
s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx);
s->macroblocks[row * s->mb_width + col].type = s->mb_type;
switch (s->mb_type) {
case VP56_MB_INTER_V1_PF:
mv = &s->vector_candidate[0];
break;
case VP56_MB_INTER_V2_PF:
mv = &s->vector_candidate[1];
break;
case VP56_MB_INTER_V1_GF:
vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
mv = &s->vector_candidate[0];
break;
case VP56_MB_INTER_V2_GF:
vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
mv = &s->vector_candidate[1];
break;
case VP56_MB_INTER_DELTA_PF:
s->parse_vector_adjustment(s, &vect);
mv = &vect;
break;
case VP56_MB_INTER_DELTA_GF:
vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
s->parse_vector_adjustment(s, &vect);
mv = &vect;
break;
case VP56_MB_INTER_4V:
vp56_decode_4mv(s, row, col);
return s->mb_type;
default:
mv = &vect;
break;
}
s->macroblocks[row*s->mb_width + col].mv = *mv;
/* same vector for all blocks */
for (b=0; b<6; b++)
s->mv[b] = *mv;
return s->mb_type;
}
static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame)
{
int idx = s->scantable.permutated[0];
int b;
for (b=0; b<6; b++) {
vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[b]];
vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[b]];
int count = 0;
int dc = 0;
int i;
if (ref_frame == lb->ref_frame) {
dc += lb->dc_coeff;
count++;
}
if (ref_frame == ab->ref_frame) {
dc += ab->dc_coeff;
count++;
}
if (s->avctx->codec->id == CODEC_ID_VP5)
for (i=0; i<2; i++)
if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) {
dc += ab[-1+2*i].dc_coeff;
count++;
}
if (count == 0)
dc = s->prev_dc[vp56_b2p[b]][ref_frame];
else if (count == 2)
dc /= 2;
s->block_coeff[b][idx] += dc;
s->prev_dc[vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx];
ab->dc_coeff = s->block_coeff[b][idx];
ab->ref_frame = ref_frame;
lb->dc_coeff = s->block_coeff[b][idx];
lb->ref_frame = ref_frame;
s->block_coeff[b][idx] *= s->dequant_dc;
}
}
static void vp56_edge_filter(vp56_context_t *s, uint8_t *yuv,
int pix_inc, int line_inc, int t)
{
int pix2_inc = 2 * pix_inc;
int i, v;
for (i=0; i<12; i++) {
v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4) >>3;
v = s->adjust(v, t);
yuv[-pix_inc] = av_clip_uint8(yuv[-pix_inc] + v);
yuv[0] = av_clip_uint8(yuv[0] - v);
yuv += line_inc;
}
}
static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv,
int stride, int dx, int dy)
{
int t = vp56_filter_threshold[s->quantizer];
if (dx) vp56_edge_filter(s, yuv + 10-dx , 1, stride, t);
if (dy) vp56_edge_filter(s, yuv + stride*(10-dy), stride, 1, t);
}
static void vp56_mc(vp56_context_t *s, int b, int plane, uint8_t *src,
int stride, int x, int y)
{
uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b];
uint8_t *src_block;
int src_offset;
int overlap_offset = 0;
int mask = s->vp56_coord_div[b] - 1;
int deblock_filtering = s->deblock_filtering;
int dx;
int dy;
if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY
&& !s->framep[VP56_FRAME_CURRENT]->key_frame))
deblock_filtering = 0;
dx = s->mv[b].x / s->vp56_coord_div[b];
dy = s->mv[b].y / s->vp56_coord_div[b];
if (b >= 4) {
x /= 2;
y /= 2;
}
x += dx - 2;
y += dy - 2;
if (x<0 || x+12>=s->plane_width[plane] ||
y<0 || y+12>=s->plane_height[plane]) {
ff_emulated_edge_mc(s->edge_emu_buffer,
src + s->block_offset[b] + (dy-2)*stride + (dx-2),
stride, 12, 12, x, y,
s->plane_width[plane],
s->plane_height[plane]);
src_block = s->edge_emu_buffer;
src_offset = 2 + 2*stride;
} else if (deblock_filtering) {
/* only need a 12x12 block, but there is no such dsp function, */
/* so copy a 16x12 block */
s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer,
src + s->block_offset[b] + (dy-2)*stride + (dx-2),
stride, 12);
src_block = s->edge_emu_buffer;
src_offset = 2 + 2*stride;
} else {
src_block = src;
src_offset = s->block_offset[b] + dy*stride + dx;
}
if (deblock_filtering)
vp56_deblock_filter(s, src_block, stride, dx&7, dy&7);
if (s->mv[b].x & mask)
overlap_offset += (s->mv[b].x > 0) ? 1 : -1;
if (s->mv[b].y & mask)
overlap_offset += (s->mv[b].y > 0) ? stride : -stride;
if (overlap_offset) {
if (s->filter)
s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset,
stride, s->mv[b], mask, s->filter_selection, b<4);
else
s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset,
src_block+src_offset+overlap_offset,
stride, 8);
} else {
s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8);
}
}
static void vp56_decode_mb(vp56_context_t *s, int row, int col, int is_alpha)
{
AVFrame *frame_current, *frame_ref;
vp56_mb_t mb_type;
vp56_frame_t ref_frame;
int b, ab, b_max, plane, off;
if (s->framep[VP56_FRAME_CURRENT]->key_frame)
mb_type = VP56_MB_INTRA;
else
mb_type = vp56_decode_mv(s, row, col);
ref_frame = vp56_reference_frame[mb_type];
memset(s->block_coeff, 0, sizeof(s->block_coeff));
s->parse_coeff(s);
vp56_add_predictors_dc(s, ref_frame);
frame_current = s->framep[VP56_FRAME_CURRENT];
frame_ref = s->framep[ref_frame];
ab = 6*is_alpha;
b_max = 6 - 2*is_alpha;
switch (mb_type) {
case VP56_MB_INTRA:
for (b=0; b<b_max; b++) {
plane = vp56_b2p[b+ab];
s->dsp.idct_put(frame_current->data[plane] + s->block_offset[b],
s->stride[plane], s->block_coeff[b]);
}
break;
case VP56_MB_INTER_NOVEC_PF:
case VP56_MB_INTER_NOVEC_GF:
for (b=0; b<b_max; b++) {
plane = vp56_b2p[b+ab];
off = s->block_offset[b];
s->dsp.put_pixels_tab[1][0](frame_current->data[plane] + off,
frame_ref->data[plane] + off,
s->stride[plane], 8);
s->dsp.idct_add(frame_current->data[plane] + off,
s->stride[plane], s->block_coeff[b]);
}
break;
case VP56_MB_INTER_DELTA_PF:
case VP56_MB_INTER_V1_PF:
case VP56_MB_INTER_V2_PF:
case VP56_MB_INTER_DELTA_GF:
case VP56_MB_INTER_4V:
case VP56_MB_INTER_V1_GF:
case VP56_MB_INTER_V2_GF:
for (b=0; b<b_max; b++) {
int x_off = b==1 || b==3 ? 8 : 0;
int y_off = b==2 || b==3 ? 8 : 0;
plane = vp56_b2p[b+ab];
vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane],
16*col+x_off, 16*row+y_off);
s->dsp.idct_add(frame_current->data[plane] + s->block_offset[b],
s->stride[plane], s->block_coeff[b]);
}
break;
}
}
static int vp56_size_changed(AVCodecContext *avctx)
{
vp56_context_t *s = avctx->priv_data;
int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0];
int i;
s->plane_width[0] = s->plane_width[3] = avctx->coded_width;
s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2;
s->plane_height[0] = s->plane_height[3] = avctx->coded_height;
s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2;
for (i=0; i<4; i++)
s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i];
s->mb_width = (avctx->coded_width +15) / 16;
s->mb_height = (avctx->coded_height+15) / 16;
if (s->mb_width > 1000 || s->mb_height > 1000) {
av_log(avctx, AV_LOG_ERROR, "picture too big\n");
return -1;
}
s->above_blocks = av_realloc(s->above_blocks,
(4*s->mb_width+6) * sizeof(*s->above_blocks));
s->macroblocks = av_realloc(s->macroblocks,
s->mb_width*s->mb_height*sizeof(*s->macroblocks));
av_free(s->edge_emu_buffer_alloc);
s->edge_emu_buffer_alloc = av_malloc(16*stride);
s->edge_emu_buffer = s->edge_emu_buffer_alloc;
if (s->flip < 0)
s->edge_emu_buffer += 15 * stride;
return 0;
}
int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
vp56_context_t *s = avctx->priv_data;
AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
int remaining_buf_size = buf_size;
int is_alpha, alpha_offset;
if (s->has_alpha) {
alpha_offset = bytestream_get_be24(&buf);
remaining_buf_size -= 3;
}
for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) {
int mb_row, mb_col, mb_row_flip, mb_offset = 0;
int block, y, uv, stride_y, stride_uv;
int golden_frame = 0;
int res;
s->modelp = &s->models[is_alpha];
res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);
if (!res)
return -1;
if (!is_alpha) {
p->reference = 1;
if (avctx->get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
if (res == 2)
if (vp56_size_changed(avctx)) {
avctx->release_buffer(avctx, p);
return -1;
}
}
if (p->key_frame) {
p->pict_type = FF_I_TYPE;
s->default_models_init(s);
for (block=0; block<s->mb_height*s->mb_width; block++)
s->macroblocks[block].type = VP56_MB_INTRA;
} else {
p->pict_type = FF_P_TYPE;
vp56_parse_mb_type_models(s);
s->parse_vector_models(s);
s->mb_type = VP56_MB_INTER_NOVEC_PF;
}
s->parse_coeff_models(s);
memset(s->prev_dc, 0, sizeof(s->prev_dc));
s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
for (block=0; block < 4*s->mb_width+6; block++) {
s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
s->above_blocks[block].dc_coeff = 0;
s->above_blocks[block].not_null_dc = 0;
}
s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
stride_y = p->linesize[0];
stride_uv = p->linesize[1];
if (s->flip < 0)
mb_offset = 7;
/* main macroblocks loop */
for (mb_row=0; mb_row<s->mb_height; mb_row++) {
if (s->flip < 0)
mb_row_flip = s->mb_height - mb_row - 1;
else
mb_row_flip = mb_row;
for (block=0; block<4; block++) {
s->left_block[block].ref_frame = VP56_FRAME_NONE;
s->left_block[block].dc_coeff = 0;
s->left_block[block].not_null_dc = 0;
}
memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
s->above_block_idx[0] = 1;
s->above_block_idx[1] = 2;
s->above_block_idx[2] = 1;
s->above_block_idx[3] = 2;
s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
s->block_offset[1] = s->block_offset[0] + 8;
s->block_offset[3] = s->block_offset[2] + 8;
s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
s->block_offset[5] = s->block_offset[4];
for (mb_col=0; mb_col<s->mb_width; mb_col++) {
vp56_decode_mb(s, mb_row, mb_col, is_alpha);
for (y=0; y<4; y++) {
s->above_block_idx[y] += 2;
s->block_offset[y] += 16;
}
for (uv=4; uv<6; uv++) {
s->above_block_idx[uv] += 1;
s->block_offset[uv] += 8;
}
}
}
if (p->key_frame || golden_frame) {
if (s->framep[VP56_FRAME_GOLDEN]->data[0] &&
s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])
avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
s->framep[VP56_FRAME_GOLDEN] = p;
}
if (s->has_alpha) {
FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN],
s->framep[VP56_FRAME_GOLDEN2]);
buf += alpha_offset;
remaining_buf_size -= alpha_offset;
}
}
if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] ||
s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) {
if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] &&
s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2])
FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
s->framep[VP56_FRAME_UNUSED]);
else
FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
s->framep[VP56_FRAME_UNUSED2]);
} else if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
s->framep[VP56_FRAME_PREVIOUS]);
*(AVFrame*)data = *p;
*data_size = sizeof(AVFrame);
return buf_size;
}
av_cold void vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
{
vp56_context_t *s = avctx->priv_data;
int i;
s->avctx = avctx;
avctx->pix_fmt = has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P;
if (avctx->idct_algo == FF_IDCT_AUTO)
avctx->idct_algo = FF_IDCT_VP3;
dsputil_init(&s->dsp, avctx);
ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct);
avcodec_set_dimensions(avctx, 0, 0);
for (i=0; i<4; i++)
s->framep[i] = &s->frames[i];
s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN];
s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2];
s->edge_emu_buffer_alloc = NULL;
s->above_blocks = NULL;
s->macroblocks = NULL;
s->quantizer = -1;
s->deblock_filtering = 1;
s->filter = NULL;
s->has_alpha = has_alpha;
if (flip) {
s->flip = -1;
s->frbi = 2;
s->srbi = 0;
} else {
s->flip = 1;
s->frbi = 0;
s->srbi = 2;
}
}
av_cold int vp56_free(AVCodecContext *avctx)
{
vp56_context_t *s = avctx->priv_data;
av_free(s->above_blocks);
av_free(s->macroblocks);
av_free(s->edge_emu_buffer_alloc);
if (s->framep[VP56_FRAME_GOLDEN]->data[0])
avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
if (s->framep[VP56_FRAME_GOLDEN2]->data[0])
avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]);
if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
return 0;
}
@@ -0,0 +1,268 @@
/**
* @file vp56.h
* VP5 and VP6 compatible video decoder (common features)
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VP56_H
#define FFMPEG_VP56_H
#include "vp56data.h"
#include "dsputil.h"
#include "bitstream.h"
#include "bytestream.h"
typedef struct vp56_context vp56_context_t;
typedef struct vp56_mv vp56_mv_t;
typedef void (*vp56_parse_vector_adjustment_t)(vp56_context_t *s,
vp56_mv_t *vect);
typedef int (*vp56_adjust_t)(int v, int t);
typedef void (*vp56_filter_t)(vp56_context_t *s, uint8_t *dst, uint8_t *src,
int offset1, int offset2, int stride,
vp56_mv_t mv, int mask, int select, int luma);
typedef void (*vp56_parse_coeff_t)(vp56_context_t *s);
typedef void (*vp56_default_models_init_t)(vp56_context_t *s);
typedef void (*vp56_parse_vector_models_t)(vp56_context_t *s);
typedef void (*vp56_parse_coeff_models_t)(vp56_context_t *s);
typedef int (*vp56_parse_header_t)(vp56_context_t *s, const uint8_t *buf,
int buf_size, int *golden_frame);
typedef struct {
int high;
int bits;
const uint8_t *buffer;
unsigned long code_word;
} vp56_range_coder_t;
typedef struct {
uint8_t not_null_dc;
vp56_frame_t ref_frame;
DCTELEM dc_coeff;
} vp56_ref_dc_t;
struct vp56_mv {
int x;
int y;
};
typedef struct {
uint8_t type;
vp56_mv_t mv;
} vp56_macroblock_t;
typedef struct {
uint8_t coeff_reorder[64]; /* used in vp6 only */
uint8_t coeff_index_to_pos[64]; /* used in vp6 only */
uint8_t vector_sig[2]; /* delta sign */
uint8_t vector_dct[2]; /* delta coding types */
uint8_t vector_pdi[2][2]; /* predefined delta init */
uint8_t vector_pdv[2][7]; /* predefined delta values */
uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */
uint8_t coeff_dccv[2][11]; /* DC coeff value */
uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */
uint8_t coeff_runv[2][14]; /* run value (vp6 only) */
uint8_t mb_type[3][10][10]; /* model for decoding MB type */
uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */
} vp56_model_t;
struct vp56_context {
AVCodecContext *avctx;
DSPContext dsp;
ScanTable scantable;
AVFrame frames[4];
AVFrame *framep[6];
uint8_t *edge_emu_buffer_alloc;
uint8_t *edge_emu_buffer;
vp56_range_coder_t c;
vp56_range_coder_t cc;
vp56_range_coder_t *ccp;
int sub_version;
/* frame info */
int plane_width[4];
int plane_height[4];
int mb_width; /* number of horizontal MB */
int mb_height; /* number of vertical MB */
int block_offset[6];
int quantizer;
uint16_t dequant_dc;
uint16_t dequant_ac;
/* DC predictors management */
vp56_ref_dc_t *above_blocks;
vp56_ref_dc_t left_block[4];
int above_block_idx[6];
DCTELEM prev_dc[3][3]; /* [plan][ref_frame] */
/* blocks / macroblock */
vp56_mb_t mb_type;
vp56_macroblock_t *macroblocks;
DECLARE_ALIGNED_16(DCTELEM, block_coeff[6][64]);
/* motion vectors */
vp56_mv_t mv[6]; /* vectors for each block in MB */
vp56_mv_t vector_candidate[2];
int vector_candidate_pos;
/* filtering hints */
int filter_header; /* used in vp6 only */
int deblock_filtering;
int filter_selection;
int filter_mode;
int max_vector_length;
int sample_variance_threshold;
uint8_t coeff_ctx[4][64]; /* used in vp5 only */
uint8_t coeff_ctx_last[4]; /* used in vp5 only */
int has_alpha;
/* upside-down flipping hints */
int flip; /* are we flipping ? */
int frbi; /* first row block index in MB */
int srbi; /* second row block index in MB */
int stride[4]; /* stride for each plan */
const uint8_t *vp56_coord_div;
vp56_parse_vector_adjustment_t parse_vector_adjustment;
vp56_adjust_t adjust;
vp56_filter_t filter;
vp56_parse_coeff_t parse_coeff;
vp56_default_models_init_t default_models_init;
vp56_parse_vector_models_t parse_vector_models;
vp56_parse_coeff_models_t parse_coeff_models;
vp56_parse_header_t parse_header;
vp56_model_t *modelp;
vp56_model_t models[2];
/* huffman decoding */
int use_huffman;
GetBitContext gb;
VLC dccv_vlc[2];
VLC runv_vlc[2];
VLC ract_vlc[2][3][6];
unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */
};
void vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
int vp56_free(AVCodecContext *avctx);
void vp56_init_dequant(vp56_context_t *s, int quantizer);
int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
const uint8_t *buf, int buf_size);
/**
* vp56 specific range coder implementation
*/
static inline void vp56_init_range_decoder(vp56_range_coder_t *c,
const uint8_t *buf, int buf_size)
{
c->high = 255;
c->bits = 8;
c->buffer = buf;
c->code_word = bytestream_get_be16(&c->buffer);
}
static inline int vp56_rac_get_prob(vp56_range_coder_t *c, uint8_t prob)
{
unsigned int low = 1 + (((c->high - 1) * prob) / 256);
unsigned int low_shift = low << 8;
int bit = c->code_word >= low_shift;
if (bit) {
c->high -= low;
c->code_word -= low_shift;
} else {
c->high = low;
}
/* normalize */
while (c->high < 128) {
c->high <<= 1;
c->code_word <<= 1;
if (--c->bits == 0) {
c->bits = 8;
c->code_word |= *c->buffer++;
}
}
return bit;
}
static inline int vp56_rac_get(vp56_range_coder_t *c)
{
/* equiprobable */
int low = (c->high + 1) >> 1;
unsigned int low_shift = low << 8;
int bit = c->code_word >= low_shift;
if (bit) {
c->high = (c->high - low) << 1;
c->code_word -= low_shift;
} else {
c->high = low << 1;
}
/* normalize */
c->code_word <<= 1;
if (--c->bits == 0) {
c->bits = 8;
c->code_word |= *c->buffer++;
}
return bit;
}
static inline int vp56_rac_gets(vp56_range_coder_t *c, int bits)
{
int value = 0;
while (bits--) {
value = (value << 1) | vp56_rac_get(c);
}
return value;
}
static inline int vp56_rac_gets_nn(vp56_range_coder_t *c, int bits)
{
int v = vp56_rac_gets(c, 7) << 1;
return v + !v;
}
static inline int vp56_rac_get_tree(vp56_range_coder_t *c,
const vp56_tree_t *tree,
const uint8_t *probs)
{
while (tree->val > 0) {
if (vp56_rac_get_prob(c, probs[tree->prob_idx]))
tree += tree->val;
else
tree++;
}
return -tree->val;
}
#endif /* FFMPEG_VP56_H */
@@ -0,0 +1,66 @@
/**
* @file vp56data.c
* VP5 and VP6 compatible video decoder (common data)
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "vp56data.h"
const uint8_t vp56_b2p[] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3 };
const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 };
const uint8_t vp56_coeff_parse_table[6][11] = {
{ 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0 },
{ 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0 },
{ 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254 },
};
const uint8_t vp56_def_mb_types_stats[3][10][2] = {
{ { 69, 42 }, { 1, 2 }, { 1, 7 }, { 44, 42 }, { 6, 22 },
{ 1, 3 }, { 0, 2 }, { 1, 5 }, { 0, 1 }, { 0, 0 }, },
{ { 229, 8 }, { 1, 1 }, { 0, 8 }, { 0, 0 }, { 0, 0 },
{ 1, 2 }, { 0, 1 }, { 0, 0 }, { 1, 1 }, { 0, 0 }, },
{ { 122, 35 }, { 1, 1 }, { 1, 6 }, { 46, 34 }, { 0, 0 },
{ 1, 2 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, },
};
const vp56_tree_t vp56_pva_tree[] = {
{ 8, 0},
{ 4, 1},
{ 2, 2}, {-0}, {-1},
{ 2, 3}, {-2}, {-3},
{ 4, 4},
{ 2, 5}, {-4}, {-5},
{ 2, 6}, {-6}, {-7},
};
const vp56_tree_t vp56_pc_tree[] = {
{ 4, 6},
{ 2, 7}, {-0}, {-1},
{ 4, 8},
{ 2, 9}, {-2}, {-3},
{ 2,10}, {-4}, {-5},
};
const uint8_t vp56_coeff_bias[] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67 };
const uint8_t vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 };
@@ -0,0 +1,252 @@
/**
* @file vp56data.h
* VP5 and VP6 compatible video decoder (common data)
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VP56DATA_H
#define FFMPEG_VP56DATA_H
#include "libavutil/common.h"
typedef enum {
VP56_FRAME_NONE =-1,
VP56_FRAME_CURRENT = 0,
VP56_FRAME_PREVIOUS = 1,
VP56_FRAME_GOLDEN = 2,
VP56_FRAME_GOLDEN2 = 3,
VP56_FRAME_UNUSED = 4,
VP56_FRAME_UNUSED2 = 5,
} vp56_frame_t;
typedef enum {
VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */
VP56_MB_INTRA = 1, /**< Intra MB */
VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */
VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */
VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */
VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */
VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */
VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */
VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */
VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */
} vp56_mb_t;
typedef struct {
int8_t val;
int8_t prob_idx;
} vp56_tree_t;
extern const uint8_t vp56_b2p[];
extern const uint8_t vp56_b6to4[];
extern const uint8_t vp56_coeff_parse_table[6][11];
extern const uint8_t vp56_def_mb_types_stats[3][10][2];
extern const vp56_tree_t vp56_pva_tree[];
extern const vp56_tree_t vp56_pc_tree[];
extern const uint8_t vp56_coeff_bias[];
extern const uint8_t vp56_coeff_bit_length[];
static const vp56_frame_t vp56_reference_frame[] = {
VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_NOVEC_PF */
VP56_FRAME_CURRENT, /* VP56_MB_INTRA */
VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_DELTA_PF */
VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V1_PF */
VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V2_PF */
VP56_FRAME_GOLDEN, /* VP56_MB_INTER_NOVEC_GF */
VP56_FRAME_GOLDEN, /* VP56_MB_INTER_DELTA_GF */
VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_4V */
VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V1_GF */
VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V2_GF */
};
static const uint8_t vp56_ac_dequant[64] = {
94, 92, 90, 88, 86, 82, 78, 74,
70, 66, 62, 58, 54, 53, 52, 51,
50, 49, 48, 47, 46, 45, 44, 43,
42, 40, 39, 37, 36, 35, 34, 33,
32, 31, 30, 29, 28, 27, 26, 25,
24, 23, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 11, 10, 9,
8, 7, 6, 5, 4, 3, 2, 1,
};
static const uint8_t vp56_dc_dequant[64] = {
47, 47, 47, 47, 45, 43, 43, 43,
43, 43, 42, 41, 41, 40, 40, 40,
40, 35, 35, 35, 35, 33, 33, 33,
33, 32, 32, 32, 27, 27, 26, 26,
25, 25, 24, 24, 23, 23, 19, 19,
19, 19, 18, 18, 17, 16, 16, 16,
16, 16, 15, 11, 11, 11, 10, 10,
9, 8, 7, 5, 3, 3, 2, 2,
};
static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = {
{ { { 9, 15 }, { 32, 25 }, { 7, 19 }, { 9, 21 }, { 1, 12 },
{ 14, 12 }, { 3, 18 }, { 14, 23 }, { 3, 10 }, { 0, 4 }, },
{ { 41, 22 }, { 1, 0 }, { 1, 31 }, { 0, 0 }, { 0, 0 },
{ 0, 1 }, { 1, 7 }, { 0, 1 }, { 98, 25 }, { 4, 10 }, },
{ { 2, 3 }, { 2, 3 }, { 0, 2 }, { 0, 2 }, { 0, 0 },
{ 11, 4 }, { 1, 4 }, { 0, 2 }, { 3, 2 }, { 0, 4 }, }, },
{ { { 48, 39 }, { 1, 2 }, { 11, 27 }, { 29, 44 }, { 7, 27 },
{ 1, 4 }, { 0, 3 }, { 1, 6 }, { 1, 2 }, { 0, 0 }, },
{ { 123, 37 }, { 6, 4 }, { 1, 27 }, { 0, 0 }, { 0, 0 },
{ 5, 8 }, { 1, 7 }, { 0, 1 }, { 12, 10 }, { 0, 2 }, },
{ { 49, 46 }, { 3, 4 }, { 7, 31 }, { 42, 41 }, { 0, 0 },
{ 2, 6 }, { 1, 7 }, { 1, 4 }, { 2, 4 }, { 0, 1 }, }, },
{ { { 21, 32 }, { 1, 2 }, { 4, 10 }, { 32, 43 }, { 6, 23 },
{ 2, 3 }, { 1, 19 }, { 1, 6 }, { 12, 21 }, { 0, 7 }, },
{ { 26, 14 }, { 14, 12 }, { 0, 24 }, { 0, 0 }, { 0, 0 },
{ 55, 17 }, { 1, 9 }, { 0, 36 }, { 5, 7 }, { 1, 3 }, },
{ { 26, 25 }, { 1, 1 }, { 2, 10 }, { 67, 39 }, { 0, 0 },
{ 1, 1 }, { 0, 14 }, { 0, 2 }, { 31, 26 }, { 1, 6 }, }, },
{ { { 69, 83 }, { 0, 0 }, { 0, 2 }, { 10, 29 }, { 3, 12 },
{ 0, 1 }, { 0, 3 }, { 0, 3 }, { 2, 2 }, { 0, 0 }, },
{ { 209, 5 }, { 0, 0 }, { 0, 27 }, { 0, 0 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, },
{ { 103, 46 }, { 1, 2 }, { 2, 10 }, { 33, 42 }, { 0, 0 },
{ 1, 4 }, { 0, 3 }, { 0, 1 }, { 1, 3 }, { 0, 0 }, }, },
{ { { 11, 20 }, { 1, 4 }, { 18, 36 }, { 43, 48 }, { 13, 35 },
{ 0, 2 }, { 0, 5 }, { 3, 12 }, { 1, 2 }, { 0, 0 }, },
{ { 2, 5 }, { 4, 5 }, { 0, 121 }, { 0, 0 }, { 0, 0 },
{ 0, 3 }, { 2, 4 }, { 1, 4 }, { 2, 2 }, { 0, 1 }, },
{ { 14, 31 }, { 9, 13 }, { 14, 54 }, { 22, 29 }, { 0, 0 },
{ 2, 6 }, { 4, 18 }, { 6, 13 }, { 1, 5 }, { 0, 1 }, }, },
{ { { 70, 44 }, { 0, 1 }, { 2, 10 }, { 37, 46 }, { 8, 26 },
{ 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, },
{ { 175, 5 }, { 0, 1 }, { 0, 48 }, { 0, 0 }, { 0, 0 },
{ 0, 2 }, { 0, 1 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, },
{ { 85, 39 }, { 0, 0 }, { 1, 9 }, { 69, 40 }, { 0, 0 },
{ 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 0 }, }, },
{ { { 8, 15 }, { 0, 1 }, { 8, 21 }, { 74, 53 }, { 22, 42 },
{ 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 0, 0 }, },
{ { 83, 5 }, { 2, 3 }, { 0, 102 }, { 0, 0 }, { 0, 0 },
{ 1, 3 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, },
{ { 31, 28 }, { 0, 0 }, { 3, 14 }, { 130, 34 }, { 0, 0 },
{ 0, 1 }, { 0, 3 }, { 0, 1 }, { 3, 3 }, { 0, 1 }, }, },
{ { { 141, 42 }, { 0, 0 }, { 1, 4 }, { 11, 24 }, { 1, 11 },
{ 0, 1 }, { 0, 1 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, },
{ { 233, 6 }, { 0, 0 }, { 0, 8 }, { 0, 0 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, },
{ { 171, 25 }, { 0, 0 }, { 1, 5 }, { 25, 21 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, },
{ { { 8, 19 }, { 4, 10 }, { 24, 45 }, { 21, 37 }, { 9, 29 },
{ 0, 3 }, { 1, 7 }, { 11, 25 }, { 0, 2 }, { 0, 1 }, },
{ { 34, 16 }, { 112, 21 }, { 1, 28 }, { 0, 0 }, { 0, 0 },
{ 6, 8 }, { 1, 7 }, { 0, 3 }, { 2, 5 }, { 0, 2 }, },
{ { 17, 21 }, { 68, 29 }, { 6, 15 }, { 13, 22 }, { 0, 0 },
{ 6, 12 }, { 3, 14 }, { 4, 10 }, { 1, 7 }, { 0, 3 }, }, },
{ { { 46, 42 }, { 0, 1 }, { 2, 10 }, { 54, 51 }, { 10, 30 },
{ 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, },
{ { 159, 35 }, { 2, 2 }, { 0, 25 }, { 0, 0 }, { 0, 0 },
{ 3, 6 }, { 0, 5 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, },
{ { 51, 39 }, { 0, 1 }, { 2, 12 }, { 91, 44 }, { 0, 0 },
{ 0, 2 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 1 }, }, },
{ { { 28, 32 }, { 0, 0 }, { 3, 10 }, { 75, 51 }, { 14, 33 },
{ 0, 1 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, },
{ { 75, 39 }, { 5, 7 }, { 2, 48 }, { 0, 0 }, { 0, 0 },
{ 3, 11 }, { 2, 16 }, { 1, 4 }, { 7, 10 }, { 0, 2 }, },
{ { 81, 25 }, { 0, 0 }, { 2, 9 }, { 106, 26 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, },
{ { { 100, 46 }, { 0, 1 }, { 3, 9 }, { 21, 37 }, { 5, 20 },
{ 0, 1 }, { 0, 2 }, { 1, 2 }, { 0, 1 }, { 0, 0 }, },
{ { 212, 21 }, { 0, 1 }, { 0, 9 }, { 0, 0 }, { 0, 0 },
{ 1, 2 }, { 0, 2 }, { 0, 0 }, { 2, 2 }, { 0, 0 }, },
{ { 140, 37 }, { 0, 1 }, { 1, 8 }, { 24, 33 }, { 0, 0 },
{ 1, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, },
{ { { 27, 29 }, { 0, 1 }, { 9, 25 }, { 53, 51 }, { 12, 34 },
{ 0, 1 }, { 0, 3 }, { 1, 5 }, { 0, 2 }, { 0, 0 }, },
{ { 4, 2 }, { 0, 0 }, { 0, 172 }, { 0, 0 }, { 0, 0 },
{ 0, 1 }, { 0, 2 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, },
{ { 14, 23 }, { 1, 3 }, { 11, 53 }, { 90, 31 }, { 0, 0 },
{ 0, 3 }, { 1, 5 }, { 2, 6 }, { 1, 2 }, { 0, 0 }, }, },
{ { { 80, 38 }, { 0, 0 }, { 1, 4 }, { 69, 33 }, { 5, 16 },
{ 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, },
{ { 187, 22 }, { 1, 1 }, { 0, 17 }, { 0, 0 }, { 0, 0 },
{ 3, 6 }, { 0, 4 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, },
{ { 123, 29 }, { 0, 0 }, { 1, 7 }, { 57, 30 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, },
{ { { 16, 20 }, { 0, 0 }, { 2, 8 }, { 104, 49 }, { 15, 33 },
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, },
{ { 133, 6 }, { 1, 2 }, { 1, 70 }, { 0, 0 }, { 0, 0 },
{ 0, 2 }, { 0, 4 }, { 0, 3 }, { 1, 1 }, { 0, 0 }, },
{ { 13, 14 }, { 0, 0 }, { 4, 20 }, { 175, 20 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, },
{ { { 194, 16 }, { 0, 0 }, { 1, 1 }, { 1, 9 }, { 1, 3 },
{ 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, },
{ { 251, 1 }, { 0, 0 }, { 0, 2 }, { 0, 0 }, { 0, 0 },
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, },
{ { 202, 23 }, { 0, 0 }, { 1, 3 }, { 2, 9 }, { 0, 0 },
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, },
};
static const uint8_t vp56_filter_threshold[] = {
14, 14, 13, 13, 12, 12, 10, 10,
10, 10, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 7, 7, 7, 7,
7, 7, 6, 6, 6, 6, 6, 6,
5, 5, 5, 5, 4, 4, 4, 4,
4, 4, 4, 3, 3, 3, 3, 2,
};
static const uint8_t vp56_mb_type_model_model[] = {
171, 83, 199, 140, 125, 104,
};
static const vp56_tree_t vp56_pmbtm_tree[] = {
{ 4, 0},
{ 2, 1}, {-8}, {-4},
{ 8, 2},
{ 6, 3},
{ 4, 4},
{ 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0},
};
static const vp56_tree_t vp56_pmbt_tree[] = {
{ 8, 1},
{ 4, 2},
{ 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF},
{ 2, 5}, {-VP56_MB_INTER_V1_PF}, {-VP56_MB_INTER_V2_PF},
{ 4, 3},
{ 2, 6}, {-VP56_MB_INTRA}, {-VP56_MB_INTER_4V},
{ 4, 7},
{ 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF},
{ 2, 9}, {-VP56_MB_INTER_V1_GF}, {-VP56_MB_INTER_V2_GF},
};
/* relative pos of surrounding blocks, from closest to farthest */
static const int8_t vp56_candidate_predictor_pos[12][2] = {
{ 0, -1 },
{ -1, 0 },
{ -1, -1 },
{ 1, -1 },
{ 0, -2 },
{ -2, 0 },
{ -2, -1 },
{ -1, -2 },
{ 1, -2 },
{ 2, -1 },
{ -2, -2 },
{ 2, -2 },
};
#endif /* FFMPEG_VP56DATA_H */
@@ -0,0 +1,175 @@
/**
* @file vp5data.h
* VP5 compatible video decoder
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VP5DATA_H
#define FFMPEG_VP5DATA_H
#include <stdint.h>
static const uint8_t vp5_coeff_groups[] = {
-1, 0, 1, 1, 2, 1, 1, 2,
2, 1, 1, 2, 2, 2, 1, 2,
2, 2, 2, 2, 1, 1, 2, 2,
3, 3, 4, 3, 4, 4, 4, 3,
3, 3, 3, 3, 4, 3, 3, 3,
4, 4, 4, 4, 4, 3, 3, 4,
4, 4, 3, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 5,
};
static const uint8_t vp5_vmc_pct[2][11] = {
{ 243, 220, 251, 253, 237, 232, 241, 245, 247, 251, 253 },
{ 235, 211, 246, 249, 234, 231, 248, 249, 252, 252, 254 },
};
static const uint8_t vp5_dccv_pct[2][11] = {
{ 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 },
{ 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 },
};
static const uint8_t vp5_ract_pct[3][2][6][11] = {
{ { { 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 },
{ 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 },
{ 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 },
{ 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 },
{ 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } },
{ { 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 },
{ 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } },
{ { { 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 },
{ 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 },
{ 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 },
{ 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 },
{ 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } },
{ { 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } },
{ { { 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 },
{ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 },
{ 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 },
{ 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 },
{ 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } },
{ { 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 },
{ 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 },
{ 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
{ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } },
};
static const int16_t vp5_dccv_lc[5][36][2] = {
{ {154, 61}, {141, 54}, { 90, 45}, { 54, 34}, { 54, 13}, {128, 109},
{136, 54}, {148, 45}, { 92, 41}, { 54, 33}, { 51, 15}, { 87, 113},
{ 87, 44}, { 97, 40}, { 67, 36}, { 46, 29}, { 41, 15}, { 64, 80},
{ 59, 33}, { 61, 31}, { 51, 28}, { 44, 22}, { 33, 12}, { 49, 63},
{ 69, 12}, { 59, 16}, { 46, 14}, { 31, 13}, { 26, 6}, { 92, 26},
{128, 108}, { 77, 119}, { 54, 84}, { 26, 71}, { 87, 19}, { 95, 155} },
{ {154, 4}, {182, 0}, {159, -8}, {128, -5}, {143, -5}, {187, 55},
{182, 0}, {228, -3}, {187, -7}, {174, -9}, {189, -11}, {169, 79},
{161, -9}, {192, -8}, {187, -9}, {169, -10}, {136, -9}, {184, 40},
{164, -11}, {179, -10}, {174, -10}, {161, -10}, {115, -7}, {197, 20},
{195, -11}, {195, -11}, {146, -10}, {110, -6}, { 95, -4}, {195, 39},
{182, 55}, {172, 77}, {177, 37}, {169, 29}, {172, 52}, { 92, 162} },
{ {174, 80}, {164, 80}, { 95, 80}, { 46, 66}, { 56, 24}, { 36, 193},
{164, 80}, {166, 77}, {105, 76}, { 49, 68}, { 46, 31}, { 49, 186},
{ 97, 78}, {110, 74}, { 72, 72}, { 44, 60}, { 33, 30}, { 69, 131},
{ 61, 61}, { 69, 63}, { 51, 57}, { 31, 48}, { 26, 27}, { 64, 89},
{ 67, 23}, { 51, 32}, { 36, 33}, { 26, 28}, { 20, 12}, { 44, 68},
{ 26, 197}, { 41, 189}, { 61, 129}, { 28, 103}, { 49, 52}, {-12, 245} },
{ {102, 141}, { 79, 166}, { 72, 162}, { 97, 125}, {179, 4}, {307, 0},
{ 72, 168}, { 69, 175}, { 84, 160}, {105, 127}, {148, 34}, {310, 0},
{ 84, 151}, { 82, 161}, { 87, 153}, { 87, 135}, {115, 51}, {317, 0},
{ 97, 125}, {102, 131}, {105, 125}, { 87, 122}, { 84, 64}, { 54, 184},
{166, 18}, {146, 43}, {125, 51}, { 90, 64}, { 95, 7}, { 38, 154},
{294, 0}, { 13, 225}, { 10, 225}, { 67, 168}, { 0, 167}, {161, 94} },
{ {172, 76}, {172, 75}, {136, 80}, { 64, 98}, { 74, 67}, {315, 0},
{169, 76}, {207, 56}, {164, 66}, { 97, 80}, { 67, 72}, {328, 0},
{136, 80}, {187, 53}, {154, 62}, { 72, 85}, { -2, 105}, {305, 0},
{ 74, 91}, {128, 64}, {113, 64}, { 61, 77}, { 41, 75}, {259, 0},
{ 46, 84}, { 51, 81}, { 28, 89}, { 31, 78}, { 23, 77}, {202, 0},
{323, 0}, {323, 0}, {300, 0}, {236, 0}, {195, 0}, {328, 0} },
};
static const int16_t vp5_ract_lc[3][3][5][6][2] = {
{ { { {276, 0}, {238, 0}, {195, 0}, {156, 0}, {113, 0}, {274, 0} },
{ { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} },
{ {192, 59}, {182, 50}, {141, 48}, {110, 40}, { 92, 19}, {125,128} },
{ {169, 87}, {169, 83}, {184, 62}, {220, 16}, {184, 0}, {264, 0} },
{ {212, 40}, {212, 36}, {169, 49}, {174, 27}, { 8,120}, {182, 71} } },
{ { {259, 10}, {197, 19}, {143, 22}, {123, 16}, {110, 8}, {133, 88} },
{ { 0, 1}, {256, 0}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} },
{ {207, 46}, {187, 50}, { 97, 83}, { 23,100}, { 41, 56}, { 56,188} },
{ {166, 90}, {146,108}, {161, 88}, {136, 95}, {174, 0}, {266, 0} },
{ {264, 7}, {243, 18}, {184, 43}, {-14,154}, { 20,112}, { 20,199} } },
{ { {230, 26}, {197, 22}, {159, 20}, {146, 12}, {136, 4}, { 54,162} },
{ { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} },
{ {192, 59}, {156, 72}, { 84,101}, { 49,101}, { 79, 47}, { 79,167} },
{ {138,115}, {136,116}, {166, 80}, {238, 0}, {195, 0}, {261, 0} },
{ {225, 33}, {205, 42}, {159, 61}, { 79, 96}, { 92, 66}, { 28,195} } },
}, {
{ { {200, 37}, {197, 18}, {159, 13}, {143, 7}, {102, 5}, {123,126} },
{ {197, 3}, {220, -9}, {210,-12}, {187, -6}, {151, -2}, {174, 80} },
{ {200, 53}, {187, 47}, {159, 40}, {118, 38}, {100, 18}, {141,111} },
{ {179, 78}, {166, 86}, {197, 50}, {207, 27}, {187, 0}, {115,139} },
{ {218, 34}, {220, 29}, {174, 46}, {128, 61}, { 54, 89}, {187, 65} } },
{ { {238, 14}, {197, 18}, {125, 26}, { 90, 25}, { 82, 13}, {161, 86} },
{ {189, 1}, {205, -2}, {156, -4}, {143, -4}, {146, -4}, {172, 72} },
{ {230, 31}, {192, 45}, {102, 76}, { 38, 85}, { 56, 41}, { 64,173} },
{ {166, 91}, {141,111}, {128,116}, {118,109}, {177, 0}, { 23,222} },
{ {253, 14}, {236, 21}, {174, 49}, { 33,118}, { 44, 93}, { 23,187} } },
{ { {218, 28}, {179, 28}, {118, 35}, { 95, 30}, { 72, 24}, {128,108} },
{ {187, 1}, {174, -1}, {125, -1}, {110, -1}, {108, -1}, {202, 52} },
{ {197, 53}, {146, 75}, { 46,118}, { 33,103}, { 64, 50}, {118,126} },
{ {138,114}, {128,122}, {161, 86}, {243, -6}, {195, 0}, { 38,210} },
{ {215, 39}, {179, 58}, { 97,101}, { 95, 85}, { 87, 70}, { 69,152} } },
}, {
{ { {236, 24}, {205, 18}, {172, 12}, {154, 6}, {125, 1}, {169, 75} },
{ {187, 4}, {230, -2}, {228, -4}, {236, -4}, {241, -2}, {192, 66} },
{ {200, 46}, {187, 42}, {159, 34}, {136, 25}, {105, 10}, {179, 62} },
{ {207, 55}, {192, 63}, {192, 54}, {195, 36}, {177, 1}, {143, 98} },
{ {225, 27}, {207, 34}, {200, 30}, {131, 57}, { 97, 60}, {197, 45} } },
{ { {271, 8}, {218, 13}, {133, 19}, { 90, 19}, { 72, 7}, {182, 51} },
{ {179, 1}, {225, -1}, {154, -2}, {110, -1}, { 92, 0}, {195, 41} },
{ {241, 26}, {189, 40}, { 82, 64}, { 33, 60}, { 67, 17}, {120, 94} },
{ {192, 68}, {151, 94}, {146, 90}, {143, 72}, {161, 0}, {113,128} },
{ {256, 12}, {218, 29}, {166, 48}, { 44, 99}, { 31, 87}, {148, 78} } },
{ { {238, 20}, {184, 22}, {113, 27}, { 90, 22}, { 74, 9}, {192, 37} },
{ {184, 0}, {215, -1}, {141, -1}, { 97, 0}, { 49, 0}, {264, 13} },
{ {182, 51}, {138, 61}, { 95, 63}, { 54, 59}, { 64, 25}, {200, 45} },
{ {179, 75}, {156, 87}, {174, 65}, {177, 44}, {174, 0}, {164, 85} },
{ {195, 45}, {148, 65}, {105, 79}, { 95, 72}, { 87, 60}, {169, 63} } },
}
};
static const uint8_t vp5_coord_div[] = { 2, 2, 2, 2, 4, 4 };
#endif /* FFMPEG_VP5DATA_H */
@@ -0,0 +1,671 @@
/**
* @file vp6.c
* VP6 compatible video decoder
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
* - upper 4bits: difference between encoded width and visible width
* - lower 4bits: difference between encoded height and visible height
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include "avcodec.h"
#include "dsputil.h"
#include "bitstream.h"
#include "huffman.h"
#include "vp56.h"
#include "vp56data.h"
#include "vp6data.h"
static void vp6_parse_coeff(vp56_context_t *s);
static void vp6_parse_coeff_huffman(vp56_context_t *s);
static int vp6_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size,
int *golden_frame)
{
vp56_range_coder_t *c = &s->c;
int parse_filter_info = 0;
int coeff_offset = 0;
int vrt_shift = 0;
int sub_version;
int rows, cols;
int res = 1;
int separated_coeff = buf[0] & 1;
s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
sub_version = buf[1] >> 3;
if (sub_version > 8)
return 0;
s->filter_header = buf[1] & 0x06;
if (buf[1] & 1) {
av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
return 0;
}
if (separated_coeff || !s->filter_header) {
coeff_offset = AV_RB16(buf+2) - 2;
buf += 2;
buf_size -= 2;
}
rows = buf[2]; /* number of stored macroblock rows */
cols = buf[3]; /* number of stored macroblock cols */
/* buf[4] is number of displayed macroblock rows */
/* buf[5] is number of displayed macroblock cols */
if (16*cols != s->avctx->coded_width ||
16*rows != s->avctx->coded_height) {
avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
if (s->avctx->extradata_size == 1) {
s->avctx->width -= s->avctx->extradata[0] >> 4;
s->avctx->height -= s->avctx->extradata[0] & 0x0F;
}
res = 2;
}
vp56_init_range_decoder(c, buf+6, buf_size-6);
vp56_rac_gets(c, 2);
parse_filter_info = s->filter_header;
if (sub_version < 8)
vrt_shift = 5;
s->sub_version = sub_version;
} else {
if (!s->sub_version)
return 0;
if (separated_coeff || !s->filter_header) {
coeff_offset = AV_RB16(buf+1) - 2;
buf += 2;
buf_size -= 2;
}
vp56_init_range_decoder(c, buf+1, buf_size-1);
*golden_frame = vp56_rac_get(c);
if (s->filter_header) {
s->deblock_filtering = vp56_rac_get(c);
if (s->deblock_filtering)
vp56_rac_get(c);
if (s->sub_version > 7)
parse_filter_info = vp56_rac_get(c);
}
}
if (parse_filter_info) {
if (vp56_rac_get(c)) {
s->filter_mode = 2;
s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift;
s->max_vector_length = 2 << vp56_rac_gets(c, 3);
} else if (vp56_rac_get(c)) {
s->filter_mode = 1;
} else {
s->filter_mode = 0;
}
if (s->sub_version > 7)
s->filter_selection = vp56_rac_gets(c, 4);
else
s->filter_selection = 16;
}
s->use_huffman = vp56_rac_get(c);
s->parse_coeff = vp6_parse_coeff;
if (coeff_offset) {
buf += coeff_offset;
buf_size -= coeff_offset;
if (s->use_huffman) {
s->parse_coeff = vp6_parse_coeff_huffman;
init_get_bits(&s->gb, buf, buf_size<<3);
} else {
vp56_init_range_decoder(&s->cc, buf, buf_size);
s->ccp = &s->cc;
}
} else {
s->ccp = &s->c;
}
return res;
}
static void vp6_coeff_order_table_init(vp56_context_t *s)
{
int i, pos, idx = 1;
s->modelp->coeff_index_to_pos[0] = 0;
for (i=0; i<16; i++)
for (pos=1; pos<64; pos++)
if (s->modelp->coeff_reorder[pos] == i)
s->modelp->coeff_index_to_pos[idx++] = pos;
}
static void vp6_default_models_init(vp56_context_t *s)
{
vp56_model_t *model = s->modelp;
model->vector_dct[0] = 0xA2;
model->vector_dct[1] = 0xA4;
model->vector_sig[0] = 0x80;
model->vector_sig[1] = 0x80;
memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv));
memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv));
memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv));
memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder));
vp6_coeff_order_table_init(s);
}
static void vp6_parse_vector_models(vp56_context_t *s)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
int comp, node;
for (comp=0; comp<2; comp++) {
if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0]))
model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1]))
model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
}
for (comp=0; comp<2; comp++)
for (node=0; node<7; node++)
if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node]))
model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
for (comp=0; comp<2; comp++)
for (node=0; node<8; node++)
if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node]))
model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7);
}
/* nodes must ascend by count, but with descending symbol order */
static int vp6_huff_cmp(const void *va, const void *vb)
{
const Node *a = va, *b = vb;
return (a->count - b->count)*16 + (b->sym - a->sym);
}
static void vp6_build_huff_tree(vp56_context_t *s, uint8_t coeff_model[],
const uint8_t *map, unsigned size, VLC *vlc)
{
Node nodes[2*size], *tmp = &nodes[size];
int a, b, i;
/* first compute probabilities from model */
tmp[0].count = 256;
for (i=0; i<size-1; i++) {
a = tmp[i].count * coeff_model[i] >> 8;
b = tmp[i].count * (255 - coeff_model[i]) >> 8;
nodes[map[2*i ]].count = a + !a;
nodes[map[2*i+1]].count = b + !b;
}
/* then build the huffman tree accodring to probabilities */
ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp,
FF_HUFFMAN_FLAG_HNODE_FIRST);
}
static void vp6_parse_coeff_models(vp56_context_t *s)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
int def_prob[11];
int node, cg, ctx, pos;
int ct; /* code type */
int pt; /* plane type (0 for Y, 1 for U or V) */
memset(def_prob, 0x80, sizeof(def_prob));
for (pt=0; pt<2; pt++)
for (node=0; node<11; node++)
if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) {
def_prob[node] = vp56_rac_gets_nn(c, 7);
model->coeff_dccv[pt][node] = def_prob[node];
} else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
model->coeff_dccv[pt][node] = def_prob[node];
}
if (vp56_rac_get(c)) {
for (pos=1; pos<64; pos++)
if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos]))
model->coeff_reorder[pos] = vp56_rac_gets(c, 4);
vp6_coeff_order_table_init(s);
}
for (cg=0; cg<2; cg++)
for (node=0; node<14; node++)
if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node]))
model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7);
for (ct=0; ct<3; ct++)
for (pt=0; pt<2; pt++)
for (cg=0; cg<6; cg++)
for (node=0; node<11; node++)
if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) {
def_prob[node] = vp56_rac_gets_nn(c, 7);
model->coeff_ract[pt][ct][cg][node] = def_prob[node];
} else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
model->coeff_ract[pt][ct][cg][node] = def_prob[node];
}
if (s->use_huffman) {
for (pt=0; pt<2; pt++) {
vp6_build_huff_tree(s, model->coeff_dccv[pt],
vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]);
vp6_build_huff_tree(s, model->coeff_runv[pt],
vp6_huff_run_map, 9, &s->runv_vlc[pt]);
for (ct=0; ct<3; ct++)
for (cg = 0; cg < 6; cg++)
vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],
vp6_huff_coeff_map, 12,
&s->ract_vlc[pt][ct][cg]);
}
memset(s->nb_null, 0, sizeof(s->nb_null));
} else {
/* coeff_dcct is a linear combination of coeff_dccv */
for (pt=0; pt<2; pt++)
for (ctx=0; ctx<3; ctx++)
for (node=0; node<5; node++)
model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255);
}
}
static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect)
{
vp56_range_coder_t *c = &s->c;
vp56_model_t *model = s->modelp;
int comp;
*vect = (vp56_mv_t) {0,0};
if (s->vector_candidate_pos < 2)
*vect = s->vector_candidate[0];
for (comp=0; comp<2; comp++) {
int i, delta = 0;
if (vp56_rac_get_prob(c, model->vector_dct[comp])) {
static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4};
for (i=0; i<sizeof(prob_order); i++) {
int j = prob_order[i];
delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j;
}
if (delta & 0xF0)
delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3;
else
delta |= 8;
} else {
delta = vp56_rac_get_tree(c, vp56_pva_tree,
model->vector_pdv[comp]);
}
if (delta && vp56_rac_get_prob(c, model->vector_sig[comp]))
delta = -delta;
if (!comp)
vect->x += delta;
else
vect->y += delta;
}
}
/**
* Read number of consecutive blocks with null DC or AC.
* This value is < 74.
*/
static unsigned vp6_get_nb_null(vp56_context_t *s)
{
unsigned val = get_bits(&s->gb, 2);
if (val == 2)
val += get_bits(&s->gb, 2);
else if (val == 3) {
val = get_bits1(&s->gb) << 2;
val = 6+val + get_bits(&s->gb, 2+val);
}
return val;
}
static void vp6_parse_coeff_huffman(vp56_context_t *s)
{
vp56_model_t *model = s->modelp;
uint8_t *permute = s->scantable.permutated;
VLC *vlc_coeff;
int coeff, sign, coeff_idx;
int b, cg, idx;
int pt = 0; /* plane type (0 for Y, 1 for U or V) */
for (b=0; b<6; b++) {
int ct = 0; /* code type */
if (b > 3) pt = 1;
vlc_coeff = &s->dccv_vlc[pt];
for (coeff_idx=0; coeff_idx<64; ) {
int run = 1;
if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) {
s->nb_null[coeff_idx][pt]--;
if (coeff_idx)
break;
} else {
coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3);
if (coeff == 0) {
if (coeff_idx) {
int pt = (coeff_idx >= 6);
run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3);
if (run >= 9)
run += get_bits(&s->gb, 6);
} else
s->nb_null[0][pt] = vp6_get_nb_null(s);
ct = 0;
} else if (coeff == 11) { /* end of block */
if (coeff_idx == 1) /* first AC coeff ? */
s->nb_null[1][pt] = vp6_get_nb_null(s);
break;
} else {
int coeff2 = vp56_coeff_bias[coeff];
if (coeff > 4)
coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11);
ct = 1 + (coeff2 > 1);
sign = get_bits1(&s->gb);
coeff2 = (coeff2 ^ -sign) + sign;
if (coeff_idx)
coeff2 *= s->dequant_ac;
idx = model->coeff_index_to_pos[coeff_idx];
s->block_coeff[b][permute[idx]] = coeff2;
}
}
coeff_idx+=run;
cg = FFMIN(vp6_coeff_groups[coeff_idx], 3);
vlc_coeff = &s->ract_vlc[pt][ct][cg];
}
}
}
static void vp6_parse_coeff(vp56_context_t *s)
{
vp56_range_coder_t *c = s->ccp;
vp56_model_t *model = s->modelp;
uint8_t *permute = s->scantable.permutated;
uint8_t *model1, *model2, *model3;
int coeff, sign, coeff_idx;
int b, i, cg, idx, ctx;
int pt = 0; /* plane type (0 for Y, 1 for U or V) */
for (b=0; b<6; b++) {
int ct = 1; /* code type */
int run = 1;
if (b > 3) pt = 1;
ctx = s->left_block[vp56_b6to4[b]].not_null_dc
+ s->above_blocks[s->above_block_idx[b]].not_null_dc;
model1 = model->coeff_dccv[pt];
model2 = model->coeff_dcct[pt][ctx];
for (coeff_idx=0; coeff_idx<64; ) {
if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) {
/* parse a coeff */
if (vp56_rac_get_prob(c, model2[2])) {
if (vp56_rac_get_prob(c, model2[3])) {
idx = vp56_rac_get_tree(c, vp56_pc_tree, model1);
coeff = vp56_coeff_bias[idx+5];
for (i=vp56_coeff_bit_length[idx]; i>=0; i--)
coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i;
} else {
if (vp56_rac_get_prob(c, model2[4]))
coeff = 3 + vp56_rac_get_prob(c, model1[5]);
else
coeff = 2;
}
ct = 2;
} else {
ct = 1;
coeff = 1;
}
sign = vp56_rac_get(c);
coeff = (coeff ^ -sign) + sign;
if (coeff_idx)
coeff *= s->dequant_ac;
idx = model->coeff_index_to_pos[coeff_idx];
s->block_coeff[b][permute[idx]] = coeff;
run = 1;
} else {
/* parse a run */
ct = 0;
if (coeff_idx > 0) {
if (!vp56_rac_get_prob(c, model2[1]))
break;
model3 = model->coeff_runv[coeff_idx >= 6];
run = vp56_rac_get_tree(c, vp6_pcr_tree, model3);
if (!run)
for (run=9, i=0; i<6; i++)
run += vp56_rac_get_prob(c, model3[i+8]) << i;
}
}
cg = vp6_coeff_groups[coeff_idx+=run];
model1 = model2 = model->coeff_ract[pt][ct][cg];
}
s->left_block[vp56_b6to4[b]].not_null_dc =
s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0];
}
}
static int vp6_adjust(int v, int t)
{
int V = v, s = v >> 31;
V ^= s;
V -= s;
if (V-t-1 >= (unsigned)(t-1))
return v;
V = 2*t - V;
V += s;
V ^= s;
return V;
}
static int vp6_block_variance(uint8_t *src, int stride)
{
int sum = 0, square_sum = 0;
int y, x;
for (y=0; y<8; y+=2) {
for (x=0; x<8; x+=2) {
sum += src[x];
square_sum += src[x]*src[x];
}
src += 2*stride;
}
return (16*square_sum - sum*sum) >> 8;
}
static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride,
int delta, const int16_t *weights)
{
int x, y;
for (y=0; y<8; y++) {
for (x=0; x<8; x++) {
dst[x] = av_clip_uint8(( src[x-delta ] * weights[0]
+ src[x ] * weights[1]
+ src[x+delta ] * weights[2]
+ src[x+2*delta] * weights[3] + 64) >> 7);
}
src += stride;
dst += stride;
}
}
static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src,
int stride, int h_weight, int v_weight)
{
uint8_t *tmp = s->edge_emu_buffer+16;
s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
}
static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride,
const int16_t *h_weights,const int16_t *v_weights)
{
int x, y;
int tmp[8*11];
int *t = tmp;
src -= stride;
for (y=0; y<11; y++) {
for (x=0; x<8; x++) {
t[x] = av_clip_uint8(( src[x-1] * h_weights[0]
+ src[x ] * h_weights[1]
+ src[x+1] * h_weights[2]
+ src[x+2] * h_weights[3] + 64) >> 7);
}
src += stride;
t += 8;
}
t = tmp + 8;
for (y=0; y<8; y++) {
for (x=0; x<8; x++) {
dst[x] = av_clip_uint8(( t[x-8 ] * v_weights[0]
+ t[x ] * v_weights[1]
+ t[x+8 ] * v_weights[2]
+ t[x+16] * v_weights[3] + 64) >> 7);
}
dst += stride;
t += 8;
}
}
static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src,
int offset1, int offset2, int stride,
vp56_mv_t mv, int mask, int select, int luma)
{
int filter4 = 0;
int x8 = mv.x & mask;
int y8 = mv.y & mask;
if (luma) {
x8 *= 2;
y8 *= 2;
filter4 = s->filter_mode;
if (filter4 == 2) {
if (s->max_vector_length &&
(FFABS(mv.x) > s->max_vector_length ||
FFABS(mv.y) > s->max_vector_length)) {
filter4 = 0;
} else if (s->sample_variance_threshold
&& (vp6_block_variance(src+offset1, stride)
< s->sample_variance_threshold)) {
filter4 = 0;
}
}
}
if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) {
offset1 = offset2;
}
if (filter4) {
if (!y8) { /* left or right combine */
vp6_filter_hv4(dst, src+offset1, stride, 1,
vp6_block_copy_filter[select][x8]);
} else if (!x8) { /* above or below combine */
vp6_filter_hv4(dst, src+offset1, stride, stride,
vp6_block_copy_filter[select][y8]);
} else {
vp6_filter_diag4(dst, src+offset1 + ((mv.x^mv.y)>>31), stride,
vp6_block_copy_filter[select][x8],
vp6_block_copy_filter[select][y8]);
}
} else {
if (!x8 || !y8) {
s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8);
} else {
vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8);
}
}
}
static av_cold int vp6_decode_init(AVCodecContext *avctx)
{
vp56_context_t *s = avctx->priv_data;
vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6,
avctx->codec->id == CODEC_ID_VP6A);
s->vp56_coord_div = vp6_coord_div;
s->parse_vector_adjustment = vp6_parse_vector_adjustment;
s->adjust = vp6_adjust;
s->filter = vp6_filter;
s->default_models_init = vp6_default_models_init;
s->parse_vector_models = vp6_parse_vector_models;
s->parse_coeff_models = vp6_parse_coeff_models;
s->parse_header = vp6_parse_header;
return 0;
}
AVCodec vp6_decoder = {
"vp6",
CODEC_TYPE_VIDEO,
CODEC_ID_VP6,
sizeof(vp56_context_t),
vp6_decode_init,
NULL,
vp56_free,
vp56_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6"),
};
/* flash version, not flipped upside-down */
AVCodec vp6f_decoder = {
"vp6f",
CODEC_TYPE_VIDEO,
CODEC_ID_VP6F,
sizeof(vp56_context_t),
vp6_decode_init,
NULL,
vp56_free,
vp56_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
};
/* flash version, not flipped upside-down, with alpha channel */
AVCodec vp6a_decoder = {
"vp6a",
CODEC_TYPE_VIDEO,
CODEC_ID_VP6A,
sizeof(vp56_context_t),
vp6_decode_init,
NULL,
vp56_free,
vp56_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
};
@@ -0,0 +1,308 @@
/**
* @file vp6data.h
* VP6 compatible video decoder
*
* Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FFMPEG_VP6DATA_H
#define FFMPEG_VP6DATA_H
#include "vp56data.h"
static const uint8_t vp6_def_fdv_vector_model[2][8] = {
{ 247, 210, 135, 68, 138, 220, 239, 246 },
{ 244, 184, 201, 44, 173, 221, 239, 253 },
};
static const uint8_t vp6_def_pdv_vector_model[2][7] = {
{ 225, 146, 172, 147, 214, 39, 156 },
{ 204, 170, 119, 235, 140, 230, 228 },
};
static const uint8_t vp6_def_coeff_reorder[] = {
0, 0, 1, 1, 1, 2, 2, 2,
2, 2, 2, 3, 3, 4, 4, 4,
5, 5, 5, 5, 6, 6, 7, 7,
7, 7, 7, 8, 8, 9, 9, 9,
9, 9, 9, 10, 10, 11, 11, 11,
11, 11, 11, 12, 12, 12, 12, 12,
12, 13, 13, 13, 13, 13, 14, 14,
14, 14, 15, 15, 15, 15, 15, 15,
};
static const uint8_t vp6_def_runv_coeff_model[2][14] = {
{ 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 },
{ 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 },
};
static const uint8_t vp6_sig_dct_pct[2][2] = {
{ 237, 246 },
{ 231, 243 },
};
static const uint8_t vp6_pdv_pct[2][7] = {
{ 253, 253, 254, 254, 254, 254, 254 },
{ 245, 253, 254, 254, 254, 254, 254 },
};
static const uint8_t vp6_fdv_pct[2][8] = {
{ 254, 254, 254, 254, 254, 250, 250, 252 },
{ 254, 254, 254, 254, 254, 251, 251, 254 },
};
static const uint8_t vp6_dccv_pct[2][11] = {
{ 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 },
{ 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 },
};
static const uint8_t vp6_coeff_reorder_pct[] = {
255, 132, 132, 159, 153, 151, 161, 170,
164, 162, 136, 110, 103, 114, 129, 118,
124, 125, 132, 136, 114, 110, 142, 135,
134, 123, 143, 126, 153, 183, 166, 161,
171, 180, 179, 164, 203, 218, 225, 217,
215, 206, 203, 217, 229, 241, 248, 243,
253, 255, 253, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
};
static const uint8_t vp6_runv_pct[2][14] = {
{ 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 },
{ 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 },
};
static const uint8_t vp6_ract_pct[3][2][6][11] = {
{ { { 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 },
{ 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 },
{ 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } },
{ { 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } },
{ { { 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 },
{ 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 },
{ 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 },
{ 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 },
{ 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } },
{ { 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } },
{ { { 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 },
{ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 },
{ 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 },
{ 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 },
{ 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } },
{ { 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 },
{ 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 },
{ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
{ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }
};
static const int vp6_dccv_lc[3][5][2] = {
{ { 122, 133 }, { 0, 1 }, { 78, 171 }, { 139, 117 }, { 168, 79 } },
{ { 133, 51 }, { 0, 1 }, { 169, 71 }, { 214, 44 }, { 210, 38 } },
{ { 142, -16 }, { 0, 1 }, { 221, -30 }, { 246, -3 }, { 203, 17 } },
};
static const uint8_t vp6_coeff_groups[] = {
0, 0, 1, 1, 1, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
};
static const int16_t vp6_block_copy_filter[17][8][4] = {
{ { 0, 128, 0, 0 }, /* 0 */
{ -3, 122, 9, 0 },
{ -4, 109, 24, -1 },
{ -5, 91, 45, -3 },
{ -4, 68, 68, -4 },
{ -3, 45, 91, -5 },
{ -1, 24, 109, -4 },
{ 0, 9, 122, -3 } },
{ { 0, 128, 0, 0 }, /* 1 */
{ -4, 124, 9, -1 },
{ -5, 110, 25, -2 },
{ -6, 91, 46, -3 },
{ -5, 69, 69, -5 },
{ -3, 46, 91, -6 },
{ -2, 25, 110, -5 },
{ -1, 9, 124, -4 } },
{ { 0, 128, 0, 0 }, /* 2 */
{ -4, 123, 10, -1 },
{ -6, 110, 26, -2 },
{ -7, 92, 47, -4 },
{ -6, 70, 70, -6 },
{ -4, 47, 92, -7 },
{ -2, 26, 110, -6 },
{ -1, 10, 123, -4 } },
{ { 0, 128, 0, 0 }, /* 3 */
{ -5, 124, 10, -1 },
{ -7, 110, 27, -2 },
{ -7, 91, 48, -4 },
{ -6, 70, 70, -6 },
{ -4, 48, 92, -8 },
{ -2, 27, 110, -7 },
{ -1, 10, 124, -5 } },
{ { 0, 128, 0, 0 }, /* 4 */
{ -6, 124, 11, -1 },
{ -8, 111, 28, -3 },
{ -8, 92, 49, -5 },
{ -7, 71, 71, -7 },
{ -5, 49, 92, -8 },
{ -3, 28, 111, -8 },
{ -1, 11, 124, -6 } },
{ { 0, 128, 0, 0 }, /* 5 */
{ -6, 123, 12, -1 },
{ -9, 111, 29, -3 },
{ -9, 93, 50, -6 },
{ -8, 72, 72, -8 },
{ -6, 50, 93, -9 },
{ -3, 29, 111, -9 },
{ -1, 12, 123, -6 } },
{ { 0, 128, 0, 0 }, /* 6 */
{ -7, 124, 12, -1 },
{ -10, 111, 30, -3 },
{ -10, 93, 51, -6 },
{ -9, 73, 73, -9 },
{ -6, 51, 93, -10 },
{ -3, 30, 111, -10 },
{ -1, 12, 124, -7 } },
{ { 0, 128, 0, 0 }, /* 7 */
{ -7, 123, 13, -1 },
{ -11, 112, 31, -4 },
{ -11, 94, 52, -7 },
{ -10, 74, 74, -10 },
{ -7, 52, 94, -11 },
{ -4, 31, 112, -11 },
{ -1, 13, 123, -7 } },
{ { 0, 128, 0, 0 }, /* 8 */
{ -8, 124, 13, -1 },
{ -12, 112, 32, -4 },
{ -12, 94, 53, -7 },
{ -10, 74, 74, -10 },
{ -7, 53, 94, -12 },
{ -4, 32, 112, -12 },
{ -1, 13, 124, -8 } },
{ { 0, 128, 0, 0 }, /* 9 */
{ -9, 124, 14, -1 },
{ -13, 112, 33, -4 },
{ -13, 95, 54, -8 },
{ -11, 75, 75, -11 },
{ -8, 54, 95, -13 },
{ -4, 33, 112, -13 },
{ -1, 14, 124, -9 } },
{ { 0, 128, 0, 0 }, /* 10 */
{ -9, 123, 15, -1 },
{ -14, 113, 34, -5 },
{ -14, 95, 55, -8 },
{ -12, 76, 76, -12 },
{ -8, 55, 95, -14 },
{ -5, 34, 112, -13 },
{ -1, 15, 123, -9 } },
{ { 0, 128, 0, 0 }, /* 11 */
{ -10, 124, 15, -1 },
{ -14, 113, 34, -5 },
{ -15, 96, 56, -9 },
{ -13, 77, 77, -13 },
{ -9, 56, 96, -15 },
{ -5, 34, 113, -14 },
{ -1, 15, 124, -10 } },
{ { 0, 128, 0, 0 }, /* 12 */
{ -10, 123, 16, -1 },
{ -15, 113, 35, -5 },
{ -16, 98, 56, -10 },
{ -14, 78, 78, -14 },
{ -10, 56, 98, -16 },
{ -5, 35, 113, -15 },
{ -1, 16, 123, -10 } },
{ { 0, 128, 0, 0 }, /* 13 */
{ -11, 124, 17, -2 },
{ -16, 113, 36, -5 },
{ -17, 98, 57, -10 },
{ -14, 78, 78, -14 },
{ -10, 57, 98, -17 },
{ -5, 36, 113, -16 },
{ -2, 17, 124, -11 } },
{ { 0, 128, 0, 0 }, /* 14 */
{ -12, 125, 17, -2 },
{ -17, 114, 37, -6 },
{ -18, 99, 58, -11 },
{ -15, 79, 79, -15 },
{ -11, 58, 99, -18 },
{ -6, 37, 114, -17 },
{ -2, 17, 125, -12 } },
{ { 0, 128, 0, 0 }, /* 15 */
{ -12, 124, 18, -2 },
{ -18, 114, 38, -6 },
{ -19, 99, 59, -11 },
{ -16, 80, 80, -16 },
{ -11, 59, 99, -19 },
{ -6, 38, 114, -18 },
{ -2, 18, 124, -12 } },
{ { 0, 128, 0, 0 }, /* 16 */
{ -4, 118, 16, -2 },
{ -7, 106, 34, -5 },
{ -8, 90, 53, -7 },
{ -8, 72, 72, -8 },
{ -7, 53, 90, -8 },
{ -5, 34, 106, -7 },
{ -2, 16, 118, -4 } },
};
static const vp56_tree_t vp6_pcr_tree[] = {
{ 8, 0},
{ 4, 1},
{ 2, 2}, {-1}, {-2},
{ 2, 3}, {-3}, {-4},
{ 8, 4},
{ 4, 5},
{ 2, 6}, {-5}, {-6},
{ 2, 7}, {-7}, {-8},
{-0},
};
static const uint8_t vp6_coord_div[] = { 4, 4, 4, 4, 8, 8 };
static const uint8_t vp6_huff_coeff_map[] = {
13, 14, 11, 0, 1, 15, 16, 18, 2, 17, 3, 4, 19, 20, 5, 6, 21, 22, 7, 8, 9, 10
};
static const uint8_t vp6_huff_run_map[] = {
10, 13, 11, 12, 0, 1, 2, 3, 14, 8, 15, 16, 4, 5, 6, 7
};
#endif /* FFMPEG_VP6DATA_H */
@@ -2,27 +2,28 @@
* Westwood Studios VQA Video Decoder
* Copyright (C) 2003 the ffmpeg project
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file vqavideo.c
* VQA Video Decoder by Mike Melanson (melanson@pcisys.net)
* For more information about the RPZA format, visit:
* http://www.pcisys.net/~melanson/codecs/
* For more information about the VQA format, visit:
* http://wiki.multimedia.cx/index.php?title=VQA
*
* The VQA video decoder outputs PAL8 or RGB555 colorspace data, depending
* on the type of data in the file.
@@ -53,7 +54,7 @@
* file. This is an interesting technique, although it makes random file
* seeking difficult despite the fact that the frames are all intracoded.
*
* V1,2 VQA uses 12-bit codebook indices. If the 12-bit indices were
* V1,2 VQA uses 12-bit codebook indexes. If the 12-bit indexes were
* packed into bytes and then RLE compressed, bytewise, the results would
* be poor. That is why the coding method divides each index into 2 parts,
* the top 4 bits and the bottom 8 bits, then RL encodes the 4-bit pieces
@@ -67,9 +68,7 @@
#include <string.h>
#include <unistd.h>
#include "common.h"
#include "avcodec.h"
#include "dsputil.h"
#define PALETTE_COUNT 256
#define VQA_HEADER_SIZE 0x2A
@@ -82,26 +81,13 @@
#define MAX_VECTORS (MAX_CODEBOOK_VECTORS + SOLID_PIXEL_VECTORS)
#define MAX_CODEBOOK_SIZE (MAX_VECTORS * 4 * 4)
#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
(((uint8_t*)(x))[1] << 16) | \
(((uint8_t*)(x))[2] << 8) | \
((uint8_t*)(x))[3])
#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
( (long)(unsigned char)(ch3) | \
( (long)(unsigned char)(ch2) << 8 ) | \
( (long)(unsigned char)(ch1) << 16 ) | \
( (long)(unsigned char)(ch0) << 24 ) )
#define CBF0_TAG FOURCC_TAG('C', 'B', 'F', '0')
#define CBFZ_TAG FOURCC_TAG('C', 'B', 'F', 'Z')
#define CBP0_TAG FOURCC_TAG('C', 'B', 'P', '0')
#define CBPZ_TAG FOURCC_TAG('C', 'B', 'P', 'Z')
#define CPL0_TAG FOURCC_TAG('C', 'P', 'L', '0')
#define CPLZ_TAG FOURCC_TAG('C', 'P', 'L', 'Z')
#define VPTZ_TAG FOURCC_TAG('V', 'P', 'T', 'Z')
#define CBF0_TAG MKBETAG('C', 'B', 'F', '0')
#define CBFZ_TAG MKBETAG('C', 'B', 'F', 'Z')
#define CBP0_TAG MKBETAG('C', 'B', 'P', '0')
#define CBPZ_TAG MKBETAG('C', 'B', 'P', 'Z')
#define CPL0_TAG MKBETAG('C', 'P', 'L', '0')
#define CPLZ_TAG MKBETAG('C', 'P', 'L', 'Z')
#define VPTZ_TAG MKBETAG('V', 'P', 'T', 'Z')
#define VQA_DEBUG 0
@@ -114,13 +100,12 @@ static inline void vqa_debug(const char *format, ...) { }
typedef struct VqaContext {
AVCodecContext *avctx;
DSPContext dsp;
AVFrame frame;
unsigned char *buf;
const unsigned char *buf;
int size;
unsigned int palette[PALETTE_COUNT];
uint32_t palette[PALETTE_COUNT];
int width; /* width of a frame */
int height; /* height of a frame */
@@ -142,16 +127,14 @@ typedef struct VqaContext {
} VqaContext;
static int vqa_decode_init(AVCodecContext *avctx)
static av_cold int vqa_decode_init(AVCodecContext *avctx)
{
VqaContext *s = (VqaContext *)avctx->priv_data;
VqaContext *s = avctx->priv_data;
unsigned char *vqa_header;
int i, j, codebook_index;;
int i, j, codebook_index;
s->avctx = avctx;
avctx->pix_fmt = PIX_FMT_PAL8;
avctx->has_b_frames = 0;
dsputil_init(&s->dsp, avctx);
/* make sure the extradata made it */
if (s->avctx->extradata_size != VQA_HEADER_SIZE) {
@@ -162,8 +145,12 @@ static int vqa_decode_init(AVCodecContext *avctx)
/* load up the VQA parameters from the header */
vqa_header = (unsigned char *)s->avctx->extradata;
s->vqa_version = vqa_header[0];
s->width = LE_16(&vqa_header[6]);
s->height = LE_16(&vqa_header[8]);
s->width = AV_RL16(&vqa_header[6]);
s->height = AV_RL16(&vqa_header[8]);
if(avcodec_check_dimensions(avctx, s->width, s->height)){
s->width= s->height= 0;
return -1;
}
s->vector_width = vqa_header[10];
s->vector_height = vqa_header[11];
s->partial_count = s->partial_countdown = vqa_header[13];
@@ -212,7 +199,7 @@ static int vqa_decode_init(AVCodecContext *avctx)
return; \
}
static void decode_format80(unsigned char *src, int src_size,
static void decode_format80(const unsigned char *src, int src_size,
unsigned char *dest, int dest_size, int check_size) {
int src_index = 0;
@@ -239,9 +226,9 @@ static void decode_format80(unsigned char *src, int src_size,
if (src[src_index] == 0xFF) {
src_index++;
count = LE_16(&src[src_index]);
count = AV_RL16(&src[src_index]);
src_index += 2;
src_pos = LE_16(&src[src_index]);
src_pos = AV_RL16(&src[src_index]);
src_index += 2;
vqa_debug("(1) copy %X bytes from absolute pos %X\n", count, src_pos);
CHECK_COUNT();
@@ -252,7 +239,7 @@ static void decode_format80(unsigned char *src, int src_size,
} else if (src[src_index] == 0xFE) {
src_index++;
count = LE_16(&src[src_index]);
count = AV_RL16(&src[src_index]);
src_index += 2;
color = src[src_index++];
vqa_debug("(2) set %X bytes to %02X\n", count, color);
@@ -263,7 +250,7 @@ static void decode_format80(unsigned char *src, int src_size,
} else if ((src[src_index] & 0xC0) == 0xC0) {
count = (src[src_index++] & 0x3F) + 3;
src_pos = LE_16(&src[src_index]);
src_pos = AV_RL16(&src[src_index]);
src_index += 2;
vqa_debug("(3) copy %X bytes from absolute pos %X\n", count, src_pos);
CHECK_COUNT();
@@ -283,7 +270,7 @@ static void decode_format80(unsigned char *src, int src_size,
} else {
count = ((src[src_index] & 0x70) >> 4) + 3;
src_pos = BE_16(&src[src_index]) & 0x0FFF;
src_pos = AV_RB16(&src[src_index]) & 0x0FFF;
src_index += 2;
vqa_debug("(5) copy %X bytes from relpos %X\n", count, src_pos);
CHECK_COUNT();
@@ -333,8 +320,8 @@ static void vqa_decode_chunk(VqaContext *s)
/* first, traverse through the frame and find the subchunks */
while (index < s->size) {
chunk_type = BE_32(&s->buf[index]);
chunk_size = BE_32(&s->buf[index + 4]);
chunk_type = AV_RB32(&s->buf[index]);
chunk_size = AV_RB32(&s->buf[index + 4]);
switch (chunk_type) {
@@ -398,7 +385,7 @@ static void vqa_decode_chunk(VqaContext *s)
/* convert the RGB palette into the machine's endian format */
if (cpl0_chunk != -1) {
chunk_size = BE_32(&s->buf[cpl0_chunk + 4]);
chunk_size = AV_RB32(&s->buf[cpl0_chunk + 4]);
/* sanity check the palette size */
if (chunk_size / 3 > 256) {
av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found a palette chunk with %d colors\n",
@@ -426,7 +413,7 @@ static void vqa_decode_chunk(VqaContext *s)
/* decompress the full codebook chunk */
if (cbfz_chunk != -1) {
chunk_size = BE_32(&s->buf[cbfz_chunk + 4]);
chunk_size = AV_RB32(&s->buf[cbfz_chunk + 4]);
cbfz_chunk += CHUNK_PREAMBLE_SIZE;
decode_format80(&s->buf[cbfz_chunk], chunk_size,
s->codebook, s->codebook_size, 0);
@@ -435,7 +422,7 @@ static void vqa_decode_chunk(VqaContext *s)
/* copy a full codebook */
if (cbf0_chunk != -1) {
chunk_size = BE_32(&s->buf[cbf0_chunk + 4]);
chunk_size = AV_RB32(&s->buf[cbf0_chunk + 4]);
/* sanity check the full codebook size */
if (chunk_size > MAX_CODEBOOK_SIZE) {
av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: CBF0 chunk too large (0x%X bytes)\n",
@@ -455,7 +442,7 @@ static void vqa_decode_chunk(VqaContext *s)
return;
}
chunk_size = BE_32(&s->buf[vptz_chunk + 4]);
chunk_size = AV_RB32(&s->buf[vptz_chunk + 4]);
vptz_chunk += CHUNK_PREAMBLE_SIZE;
decode_format80(&s->buf[vptz_chunk], chunk_size,
s->decode_buffer, s->decode_buffer_size, 1);
@@ -478,7 +465,22 @@ static void vqa_decode_chunk(VqaContext *s)
case 1:
/* still need sample media for this case (only one game, "Legend of
* Kyrandia III : Malcolm's Revenge", is known to use this version) */
lines = 0;
lobyte = s->decode_buffer[lobytes * 2];
hibyte = s->decode_buffer[(lobytes * 2) + 1];
vector_index = ((hibyte << 8) | lobyte) >> 3;
vector_index <<= index_shift;
lines = s->vector_height;
/* uniform color fill - a quick hack */
if (hibyte == 0xFF) {
while (lines--) {
s->frame.data[0][pixel_ptr + 0] = 255 - lobyte;
s->frame.data[0][pixel_ptr + 1] = 255 - lobyte;
s->frame.data[0][pixel_ptr + 2] = 255 - lobyte;
s->frame.data[0][pixel_ptr + 3] = 255 - lobyte;
pixel_ptr += s->frame.linesize[0];
}
lines=0;
}
break;
case 2:
@@ -514,7 +516,7 @@ static void vqa_decode_chunk(VqaContext *s)
if (cbp0_chunk != -1) {
chunk_size = BE_32(&s->buf[cbp0_chunk + 4]);
chunk_size = AV_RB32(&s->buf[cbp0_chunk + 4]);
cbp0_chunk += CHUNK_PREAMBLE_SIZE;
/* accumulate partial codebook */
@@ -537,7 +539,7 @@ static void vqa_decode_chunk(VqaContext *s)
if (cbpz_chunk != -1) {
chunk_size = BE_32(&s->buf[cbpz_chunk + 4]);
chunk_size = AV_RB32(&s->buf[cbpz_chunk + 4]);
cbpz_chunk += CHUNK_PREAMBLE_SIZE;
/* accumulate partial codebook */
@@ -562,9 +564,9 @@ static void vqa_decode_chunk(VqaContext *s)
static int vqa_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size)
{
VqaContext *s = (VqaContext *)avctx->priv_data;
VqaContext *s = avctx->priv_data;
s->buf = buf;
s->size = buf_size;
@@ -590,9 +592,9 @@ static int vqa_decode_frame(AVCodecContext *avctx,
return buf_size;
}
static int vqa_decode_end(AVCodecContext *avctx)
static av_cold int vqa_decode_end(AVCodecContext *avctx)
{
VqaContext *s = (VqaContext *)avctx->priv_data;
VqaContext *s = avctx->priv_data;
av_free(s->codebook);
av_free(s->next_codebook_buffer);
@@ -614,4 +616,5 @@ AVCodec vqa_decoder = {
vqa_decode_end,
vqa_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"),
};