提交 41f55277 编写于 作者: M Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master: (34 commits)
  h264: reset h->ref_count in case of errors in ff_h264_decode_ref_pic_list_reordering()
  error_resilience: fix the check for missing references in ff_er_frame_end() for H264
  4xm: prevent NULL dereference with invalid huffman table
  4xmdemux: prevent use of uninitialized memory
  4xm: clear FF_INPUT_BUFFER_PADDING_SIZE bytes in temporary buffers
  ptx: check for out of bound reads
  tiffdec: fix out of bound reads/writes
  eacmv: check for out of bound reads
  eacmv: fix potential pointer arithmetic overflows
  adpcm: fix out of bound reads due to integer overflow
  anm: prevent infinite loop
  avsdemux: check for out of bound writes
  avs: check for out of bound reads
  avsdemux: check for corrupted data
  AVOptions: refactor set_number/write_number
  AVOptions: cosmetics, rename static av_set_number2() to write_number().
  AVOptions: cosmetics, move and rename static av_set_number().
  AVOptions: split av_set_string3 into opt type-specific functions
  avidec: fix signed overflow in avi_sync()
  mxfdec: Fix some buffer overreads caused by the misuse of AVPacket related functions.
  ...

Conflicts:
	Changelog
	configure
	libavcodec/ptx.c
	libavcodec/ra144.c
	libavcodec/vaapi_vc1.c
	libavcodec/vc1.c
	libavcodec/version.h
	libavformat/4xm.c
	libavformat/avidec.c
Merged-by: NMichael Niedermayer <michaelni@gmx.at>
......@@ -62,6 +62,7 @@ easier to use. The changes are:
- CELT in Ogg demuxing
- G.723.1 demuxer and decoder
- libmodplug support (--enable-libmodplug)
- VC-1 interlaced decoding
version 0.8:
......
......@@ -3163,6 +3163,7 @@ check_cflags -Wtype-limits
check_cflags -Wundef
check_cflags -Wmissing-prototypes
check_cflags -Wno-pointer-to-int-cast
check_cflags -Wstrict-prototypes
enabled extra_warnings && check_cflags -Winline
# add some linker flags
......
......@@ -60,7 +60,6 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
avctx->pix_fmt = PIX_FMT_RGB555;
if (buf_end - buf < offset)
return AVERROR_INVALIDDATA;
if (offset != 0x2c)
......
......@@ -1544,22 +1544,22 @@ void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset)
int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
{
int b, i, j;
int buffer1[10];
int buffer2[10];
int buffer1[LPC_ORDER];
int buffer2[LPC_ORDER];
int *bp1 = buffer1;
int *bp2 = buffer2;
for (i=0; i < 10; i++)
for (i=0; i < LPC_ORDER; i++)
buffer2[i] = coefs[i];
refl[9] = bp2[9];
refl[LPC_ORDER-1] = bp2[LPC_ORDER-1];
if ((unsigned) bp2[9] + 0x1000 > 0x1fff) {
if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) {
av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
return 1;
}
for (i=8; i >= 0; i--) {
for (i = LPC_ORDER-2; i >= 0; i--) {
b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
if (!b)
......@@ -1584,12 +1584,12 @@ int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
*/
void ff_eval_coefs(int *coefs, const int *refl)
{
int buffer[10];
int buffer[LPC_ORDER];
int *b1 = buffer;
int *b2 = coefs;
int i, j;
for (i=0; i < 10; i++) {
for (i=0; i < LPC_ORDER; i++) {
b1[i] = refl[i] << 4;
for (j=0; j < i; j++)
......@@ -1598,7 +1598,7 @@ void ff_eval_coefs(int *coefs, const int *refl)
FFSWAP(int *, b1, b2);
}
for (i=0; i < 10; i++)
for (i=0; i < LPC_ORDER; i++)
coefs[i] >>= 4;
}
......@@ -1606,7 +1606,7 @@ void ff_int_to_int16(int16_t *out, const int *inp)
{
int i;
for (i=0; i < 10; i++)
for (i = 0; i < LPC_ORDER; i++)
*out++ = *inp++;
}
......@@ -1629,9 +1629,9 @@ unsigned int ff_rms(const int *data)
{
int i;
unsigned int res = 0x10000;
int b = 10;
int b = LPC_ORDER;
for (i=0; i < 10; i++) {
for (i = 0; i < LPC_ORDER; i++) {
res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
if (res == 0)
......@@ -1648,13 +1648,13 @@ unsigned int ff_rms(const int *data)
int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
{
int work[10];
int work[LPC_ORDER];
int b = NBLOCKS - a;
int i;
// Interpolate block coefficients from the this frame's forth block and
// last frame's forth block.
for (i=0; i<10; i++)
for (i = 0; i < LPC_ORDER; i++)
out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
if (ff_eval_refl(work, out, ractx->avctx)) {
......@@ -1690,7 +1690,7 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
int cba_idx, int cb1_idx, int cb2_idx,
int gval, int gain)
{
uint16_t buffer_a[40];
uint16_t buffer_a[BLOCKSIZE];
uint16_t *block;
int m[3];
......@@ -1711,10 +1711,10 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
memcpy(ractx->curr_sblock, ractx->curr_sblock + 40,
10*sizeof(*ractx->curr_sblock));
memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
LPC_ORDER*sizeof(*ractx->curr_sblock));
if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs,
block, BLOCKSIZE, 10, 1, 0, 0xfff))
memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock));
if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,
block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff))
memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));
}
......@@ -59,29 +59,33 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
unsigned int refl_rms[4]; // RMS of the reflection coefficients
uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block
unsigned int lpc_refl[10]; // LPC reflection coefficients of the frame
static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients
uint16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block
unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame
int i, j;
int out_size;
int16_t *data = vdata;
unsigned int energy;
RA144Context *ractx = avctx->priv_data;
GetBitContext gb;
if (*data_size < 2*160)
return -1;
out_size = NBLOCKS * BLOCKSIZE * av_get_bytes_per_sample(avctx->sample_fmt);
if (*data_size < out_size) {
av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
return AVERROR(EINVAL);
}
if(buf_size < 20) {
if(buf_size < FRAMESIZE) {
av_log(avctx, AV_LOG_ERROR,
"Frame too small (%d bytes). Truncated file?\n", buf_size);
*data_size = 0;
return buf_size;
}
init_get_bits(&gb, buf, 20 * 8);
init_get_bits(&gb, buf, FRAMESIZE * 8);
for (i=0; i<10; i++)
for (i = 0; i < LPC_ORDER; i++)
lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])];
ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
......@@ -98,7 +102,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]);
for (i=0; i < 4; i++) {
for (i=0; i < NBLOCKS; i++) {
do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb);
for (j=0; j < BLOCKSIZE; j++)
......@@ -110,8 +114,8 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,
FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
*data_size = 2*160;
return 20;
*data_size = out_size;
return FRAMESIZE;
}
AVCodec ff_ra_144_decoder = {
......
......@@ -31,6 +31,9 @@
#define MAX_BACKWARD_FILTER_LEN 40
#define MAX_BACKWARD_FILTER_NONREC 35
#define RA288_BLOCK_SIZE 5
#define RA288_BLOCKS_PER_FRAME 32
typedef struct {
float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A)
float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB)
......@@ -165,7 +168,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
float *out = data;
int i, j;
int i, j, out_size;
RA288Context *ractx = avctx->priv_data;
GetBitContext gb;
......@@ -176,18 +179,22 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
return 0;
}
if (*data_size < 32*5*4)
return -1;
out_size = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME *
av_get_bytes_per_sample(avctx->sample_fmt);
if (*data_size < out_size) {
av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
return AVERROR(EINVAL);
}
init_get_bits(&gb, buf, avctx->block_align * 8);
for (i=0; i < 32; i++) {
for (i=0; i < RA288_BLOCKS_PER_FRAME; i++) {
float gain = amptable[get_bits(&gb, 3)];
int cb_coef = get_bits(&gb, 6 + (i&1));
decode(ractx, gain, cb_coef);
for (j=0; j < 5; j++)
for (j=0; j < RA288_BLOCK_SIZE; j++)
*(out++) = ractx->sp_hist[70 + 36 + j];
if ((i & 7) == 3) {
......@@ -199,7 +206,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
}
}
*data_size = (char *)out - (char *)data;
*data_size = out_size;
return avctx->block_align;
}
......
/*
* VC-1 and WMV3 decoder common code
* Copyright (c) 2011 Mashiat Sarker Shakkhar
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
......@@ -25,6 +26,7 @@
* VC-1 and WMV3 decoder common code
*
*/
#include "internal.h"
#include "dsputil.h"
#include "avcodec.h"
......@@ -66,14 +68,16 @@ enum Imode {
* @param[in] height Height of this buffer
* @param[in] stride of this buffer
*/
static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
static void decode_rowskip(uint8_t* plane, int width, int height, int stride,
GetBitContext *gb)
{
int x, y;
for (y=0; y<height; y++){
for (y = 0; y < height; y++) {
if (!get_bits1(gb)) //rowskip
memset(plane, 0, width);
else
for (x=0; x<width; x++)
for (x = 0; x < width; x++)
plane[x] = get_bits1(gb);
plane += stride;
}
......@@ -86,15 +90,17 @@ static void decode_rowskip(uint8_t* plane, int width, int height, int stride, Ge
* @param[in] stride of this buffer
* @todo FIXME: Optimize
*/
static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
static void decode_colskip(uint8_t* plane, int width, int height, int stride,
GetBitContext *gb)
{
int x, y;
for (x=0; x<width; x++){
for (x = 0; x < width; x++) {
if (!get_bits1(gb)) //colskip
for (y=0; y<height; y++)
for (y = 0; y < height; y++)
plane[y*stride] = 0;
else
for (y=0; y<height; y++)
for (y = 0; y < height; y++)
plane[y*stride] = get_bits1(gb);
plane ++;
}
......@@ -115,76 +121,76 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
uint8_t invert, *planep = data;
int width, height, stride;
width = v->s.mb_width;
height = v->s.mb_height;
width = v->s.mb_width;
height = v->s.mb_height >> v->field_mode;
stride = v->s.mb_stride;
invert = get_bits1(gb);
imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
*raw_flag = 0;
switch (imode)
{
switch (imode) {
case IMODE_RAW:
//Data is actually read in the MB layer (same for all tests == "raw")
*raw_flag = 1; //invert ignored
return invert;
case IMODE_DIFF2:
case IMODE_NORM2:
if ((height * width) & 1)
{
if ((height * width) & 1) {
*planep++ = get_bits1(gb);
offset = 1;
offset = 1;
}
else offset = 0;
else
offset = 0;
// decode bitplane as one long line
for (y = offset; y < height * width; y += 2) {
code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1);
*planep++ = code & 1;
offset++;
if(offset == width) {
offset = 0;
if (offset == width) {
offset = 0;
planep += stride - width;
}
*planep++ = code >> 1;
offset++;
if(offset == width) {
offset = 0;
if (offset == width) {
offset = 0;
planep += stride - width;
}
}
break;
case IMODE_DIFF6:
case IMODE_NORM6:
if(!(height % 3) && (width % 3)) { // use 2x3 decoding
for(y = 0; y < height; y+= 3) {
for(x = width & 1; x < width; x += 2) {
if (!(height % 3) && (width % 3)) { // use 2x3 decoding
for (y = 0; y < height; y += 3) {
for (x = width & 1; x < width; x += 2) {
code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
if(code < 0){
if (code < 0) {
av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
return -1;
}
planep[x + 0] = (code >> 0) & 1;
planep[x + 1] = (code >> 1) & 1;
planep[x + 0 + stride] = (code >> 2) & 1;
planep[x + 1 + stride] = (code >> 3) & 1;
planep[x + 0] = (code >> 0) & 1;
planep[x + 1] = (code >> 1) & 1;
planep[x + 0 + stride] = (code >> 2) & 1;
planep[x + 1 + stride] = (code >> 3) & 1;
planep[x + 0 + stride * 2] = (code >> 4) & 1;
planep[x + 1 + stride * 2] = (code >> 5) & 1;
}
planep += stride * 3;
}
if(width & 1) decode_colskip(data, 1, height, stride, &v->s.gb);
if (width & 1)
decode_colskip(data, 1, height, stride, &v->s.gb);
} else { // 3x2
planep += (height & 1) * stride;
for(y = height & 1; y < height; y += 2) {
for(x = width % 3; x < width; x += 3) {
for (y = height & 1; y < height; y += 2) {
for (x = width % 3; x < width; x += 3) {
code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
if(code < 0){
if (code < 0) {
av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
return -1;
}
planep[x + 0] = (code >> 0) & 1;
planep[x + 1] = (code >> 1) & 1;
planep[x + 2] = (code >> 2) & 1;
planep[x + 0] = (code >> 0) & 1;
planep[x + 1] = (code >> 1) & 1;
planep[x + 2] = (code >> 2) & 1;
planep[x + 0 + stride] = (code >> 3) & 1;
planep[x + 1 + stride] = (code >> 4) & 1;
planep[x + 2 + stride] = (code >> 5) & 1;
......@@ -192,8 +198,10 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
planep += stride * 2;
}
x = width % 3;
if(x) decode_colskip(data , x, height , stride, &v->s.gb);
if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb);
if (x)
decode_colskip(data, x, height, stride, &v->s.gb);
if (height & 1)
decode_rowskip(data + x, width - x, 1, stride, &v->s.gb);
}
break;
case IMODE_ROWSKIP:
......@@ -202,33 +210,30 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
case IMODE_COLSKIP:
decode_colskip(data, width, height, stride, &v->s.gb);
break;
default: break;
default:
break;
}
/* Applying diff operator */
if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
{
if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) {
planep = data;
planep[0] ^= invert;
for (x=1; x<width; x++)
for (x = 1; x < width; x++)
planep[x] ^= planep[x-1];
for (y=1; y<height; y++)
{
for (y = 1; y < height; y++) {
planep += stride;
planep[0] ^= planep[-stride];
for (x=1; x<width; x++)
{
for (x = 1; x < width; x++) {
if (planep[x-1] != planep[x-stride]) planep[x] ^= invert;
else planep[x] ^= planep[x-1];
}
}
}
else if (invert)
{
} else if (invert) {
planep = data;
for (x=0; x<stride*height; x++) planep[x] = !planep[x]; //FIXME stride
for (x = 0; x < stride * height; x++)
planep[x] = !planep[x]; //FIXME stride
}
return (imode<<1) + invert;
return (imode << 1) + invert;
}
/** @} */ //Bitplane group
......@@ -243,35 +248,34 @@ static int vop_dquant_decoding(VC1Context *v)
int pqdiff;
//variable size
if (v->dquant == 2)
{
if (v->dquant == 2) {
pqdiff = get_bits(gb, 3);
if (pqdiff == 7) v->altpq = get_bits(gb, 5);
else v->altpq = v->pq + pqdiff + 1;
}
else
{
if (pqdiff == 7)
v->altpq = get_bits(gb, 5);
else
v->altpq = v->pq + pqdiff + 1;
} else {
v->dquantfrm = get_bits1(gb);
if ( v->dquantfrm )
{
if (v->dquantfrm) {
v->dqprofile = get_bits(gb, 2);
switch (v->dqprofile)
{
switch (v->dqprofile) {
case DQPROFILE_SINGLE_EDGE:
case DQPROFILE_DOUBLE_EDGES:
v->dqsbedge = get_bits(gb, 2);
break;
case DQPROFILE_ALL_MBS:
v->dqbilevel = get_bits1(gb);
if(!v->dqbilevel)
if (!v->dqbilevel)
v->halfpq = 0;
default: break; //Forbidden ?
default:
break; //Forbidden ?
}
if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
{
if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) {
pqdiff = get_bits(gb, 3);
if (pqdiff == 7) v->altpq = get_bits(gb, 5);
else v->altpq = v->pq + pqdiff + 1;
if (pqdiff == 7)
v->altpq = get_bits(gb, 5);
else
v->altpq = v->pq + pqdiff + 1;
}
}
}
......@@ -291,25 +295,20 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
{
av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
v->profile = get_bits(gb, 2);
if (v->profile == PROFILE_COMPLEX)
{
if (v->profile == PROFILE_COMPLEX) {
av_log(avctx, AV_LOG_WARNING, "WMV3 Complex Profile is not fully supported\n");
}
if (v->profile == PROFILE_ADVANCED)
{
if (v->profile == PROFILE_ADVANCED) {
v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz;
v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz;
return decode_sequence_header_adv(v, gb);
}
else
{
} else {
v->zz_8x4 = wmv2_scantableA;
v->zz_4x8 = wmv2_scantableB;
v->res_y411 = get_bits1(gb);
v->res_sprite = get_bits1(gb);
if (v->res_y411)
{
if (v->res_y411) {
av_log(avctx, AV_LOG_ERROR,
"Old interlaced mode is not supported\n");
return -1;
......@@ -320,48 +319,45 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
v->frmrtq_postproc = get_bits(gb, 3); //common
// (bitrate-32kbps)/64kbps
v->bitrtq_postproc = get_bits(gb, 5); //common
v->s.loop_filter = get_bits1(gb); //common
if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE)
{
v->s.loop_filter = get_bits1(gb); //common
if (v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE) {
av_log(avctx, AV_LOG_ERROR,
"LOOPFILTER shall not be enabled in Simple Profile\n");
}
if(v->s.avctx->skip_loop_filter >= AVDISCARD_ALL)
if (v->s.avctx->skip_loop_filter >= AVDISCARD_ALL)
v->s.loop_filter = 0;
v->res_x8 = get_bits1(gb); //reserved
v->multires = get_bits1(gb);
v->res_fasttx = get_bits1(gb);
if (!v->res_fasttx)
{
v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_8;
v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add;
v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add;
v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add;
v->res_x8 = get_bits1(gb); //reserved
v->multires = get_bits1(gb);
v->res_fasttx = get_bits1(gb);
if (!v->res_fasttx) {
v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_8;
v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add;
v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add;
v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add;
v->vc1dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add_8;
v->vc1dsp.vc1_inv_trans_8x4_dc = ff_simple_idct84_add;
v->vc1dsp.vc1_inv_trans_4x8_dc = ff_simple_idct48_add;
v->vc1dsp.vc1_inv_trans_4x4_dc = ff_simple_idct44_add;
}
v->fastuvmc = get_bits1(gb); //common
if (!v->profile && !v->fastuvmc)
{
v->fastuvmc = get_bits1(gb); //common
if (!v->profile && !v->fastuvmc) {
av_log(avctx, AV_LOG_ERROR,
"FASTUVMC unavailable in Simple Profile\n");
return -1;
}
v->extended_mv = get_bits1(gb); //common
v->extended_mv = get_bits1(gb); //common
if (!v->profile && v->extended_mv)
{
av_log(avctx, AV_LOG_ERROR,
"Extended MVs unavailable in Simple Profile\n");
return -1;
}
v->dquant = get_bits(gb, 2); //common
v->vstransform = get_bits1(gb); //common
v->dquant = get_bits(gb, 2); //common
v->vstransform = get_bits1(gb); //common
v->res_transtab = get_bits1(gb);
v->res_transtab = get_bits1(gb);
if (v->res_transtab)
{
av_log(avctx, AV_LOG_ERROR,
......@@ -369,12 +365,11 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
return -1;
}
v->overlap = get_bits1(gb); //common
v->overlap = get_bits1(gb); //common
v->s.resync_marker = get_bits1(gb);
v->rangered = get_bits1(gb);
if (v->rangered && v->profile == PROFILE_SIMPLE)
{
v->rangered = get_bits1(gb);
if (v->rangered && v->profile == PROFILE_SIMPLE) {
av_log(avctx, AV_LOG_INFO,
"RANGERED should be set to 0 in Simple Profile\n");
}
......@@ -399,8 +394,7 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
} else {
v->res_rtm_flag = get_bits1(gb); //reserved
}
if (!v->res_rtm_flag)
{
if (!v->res_rtm_flag) {
// av_log(avctx, AV_LOG_ERROR,
// "0 for reserved RES_RTM_FLAG is forbidden\n");
av_log(avctx, AV_LOG_ERROR,
......@@ -408,17 +402,17 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte
//return -1;
}
//TODO: figure out what they mean (always 0x402F)
if(!v->res_fasttx) skip_bits(gb, 16);
if (!v->res_fasttx)
skip_bits(gb, 16);
av_log(avctx, AV_LOG_DEBUG,
"Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
"Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
"DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
v->dquant, v->quantizer_mode, avctx->max_b_frames
);
"Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
"Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
"DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
v->dquant, v->quantizer_mode, avctx->max_b_frames);
return 0;
}
......@@ -427,59 +421,56 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
int w, h;
v->res_rtm_flag = 1;
v->level = get_bits(gb, 3);
if(v->level >= 5)
{
if (v->level >= 5) {
av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
}
v->chromaformat = get_bits(gb, 2);
if (v->chromaformat != 1)
{
if (v->chromaformat != 1) {
av_log(v->s.avctx, AV_LOG_ERROR,
"Only 4:2:0 chroma format supported\n");
return -1;
}
// (fps-2)/4 (->30)
v->frmrtq_postproc = get_bits(gb, 3); //common
v->frmrtq_postproc = get_bits(gb, 3); //common
// (bitrate-32kbps)/64kbps
v->bitrtq_postproc = get_bits(gb, 5); //common
v->postprocflag = get_bits1(gb); //common
v->bitrtq_postproc = get_bits(gb, 5); //common
v->postprocflag = get_bits1(gb); //common
w = (get_bits(gb, 12) + 1) << 1;
h = (get_bits(gb, 12) + 1) << 1;
avcodec_set_dimensions(v->s.avctx, w, h);
v->broadcast = get_bits1(gb);
v->interlace = get_bits1(gb);
v->tfcntrflag = get_bits1(gb);
v->finterpflag = get_bits1(gb);
v->broadcast = get_bits1(gb);
v->interlace = get_bits1(gb);
v->tfcntrflag = get_bits1(gb);
v->finterpflag = get_bits1(gb);
skip_bits1(gb); // reserved
av_log(v->s.avctx, AV_LOG_DEBUG,
"Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
"TFCTRflag=%i, FINTERPflag=%i\n",
v->level, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
v->tfcntrflag, v->finterpflag
);
"Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
"TFCTRflag=%i, FINTERPflag=%i\n",
v->level, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
v->tfcntrflag, v->finterpflag);
v->psf = get_bits1(gb);
if(v->psf) { //PsF, 6.1.13
if (v->psf) { //PsF, 6.1.13
av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");
return -1;
}
v->s.max_b_frames = v->s.avctx->max_b_frames = 7;
if(get_bits1(gb)) { //Display Info - decoding is not affected by it
if (get_bits1(gb)) { //Display Info - decoding is not affected by it
int w, h, ar = 0;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
w = get_bits(gb, 14) + 1;
h = get_bits(gb, 14) + 1;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
if(get_bits1(gb))
if (get_bits1(gb))
ar = get_bits(gb, 4);
if(ar && ar < 14){
if (ar && ar < 14) {
v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar];
}else if(ar == 15){
} else if (ar == 15) {
w = get_bits(gb, 8) + 1;
h = get_bits(gb, 8) + 1;
v->s.avctx->sample_aspect_ratio = (AVRational){w, h};
......@@ -488,43 +479,45 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
&v->s.avctx->sample_aspect_ratio.den,
v->s.avctx->height * w,
v->s.avctx->width * h,
1<<30);
1 << 30);
}
av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den);
av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n",
v->s.avctx->sample_aspect_ratio.num,
v->s.avctx->sample_aspect_ratio.den);
if(get_bits1(gb)){ //framerate stuff
if(get_bits1(gb)) {
if (get_bits1(gb)) { //framerate stuff
if (get_bits1(gb)) {
v->s.avctx->time_base.num = 32;
v->s.avctx->time_base.den = get_bits(gb, 16) + 1;
} else {
int nr, dr;
nr = get_bits(gb, 8);
dr = get_bits(gb, 4);
if(nr && nr < 8 && dr && dr < 3){
if (nr && nr < 8 && dr && dr < 3) {
v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1];
v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000;
}
}
if(v->broadcast) { // Pulldown may be present
v->s.avctx->time_base.den *= 2;
if (v->broadcast) { // Pulldown may be present
v->s.avctx->time_base.den *= 2;
v->s.avctx->ticks_per_frame = 2;
}
}
if(get_bits1(gb)){
v->color_prim = get_bits(gb, 8);
if (get_bits1(gb)) {
v->color_prim = get_bits(gb, 8);
v->transfer_char = get_bits(gb, 8);
v->matrix_coef = get_bits(gb, 8);
v->matrix_coef = get_bits(gb, 8);
}
}
v->hrd_param_flag = get_bits1(gb);
if(v->hrd_param_flag) {
if (v->hrd_param_flag) {
int i;
v->hrd_num_leaky_buckets = get_bits(gb, 5);
skip_bits(gb, 4); //bitrate exponent
skip_bits(gb, 4); //buffer size exponent
for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
for (i = 0; i < v->hrd_num_leaky_buckets; i++) {
skip_bits(gb, 16); //hrd_rate[n]
skip_bits(gb, 16); //hrd_buffer[n]
}
......@@ -537,20 +530,20 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *
int i;
av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
v->broken_link = get_bits1(gb);
v->closed_entry = get_bits1(gb);
v->panscanflag = get_bits1(gb);
v->refdist_flag = get_bits1(gb);
v->s.loop_filter = get_bits1(gb);
v->fastuvmc = get_bits1(gb);
v->extended_mv = get_bits1(gb);
v->dquant = get_bits(gb, 2);
v->vstransform = get_bits1(gb);
v->overlap = get_bits1(gb);
v->broken_link = get_bits1(gb);
v->closed_entry = get_bits1(gb);
v->panscanflag = get_bits1(gb);
v->refdist_flag = get_bits1(gb);
v->s.loop_filter = get_bits1(gb);
v->fastuvmc = get_bits1(gb);
v->extended_mv = get_bits1(gb);
v->dquant = get_bits(gb, 2);
v->vstransform = get_bits1(gb);
v->overlap = get_bits1(gb);
v->quantizer_mode = get_bits(gb, 2);
if(v->hrd_param_flag){
for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
if (v->hrd_param_flag) {
for (i = 0; i < v->hrd_num_leaky_buckets; i++) {
skip_bits(gb, 8); //hrd_full[n]
}
}
......@@ -560,23 +553,23 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *
int h = (get_bits(gb, 12)+1)<<1;
avcodec_set_dimensions(avctx, w, h);
}
if(v->extended_mv)
if (v->extended_mv)
v->extended_dmv = get_bits1(gb);
if((v->range_mapy_flag = get_bits1(gb))) {
if ((v->range_mapy_flag = get_bits1(gb))) {
av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");
v->range_mapy = get_bits(gb, 3);
}
if((v->range_mapuv_flag = get_bits1(gb))) {
if ((v->range_mapuv_flag = get_bits1(gb))) {
av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n");
v->range_mapuv = get_bits(gb, 3);
}
av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"
"BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
"RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
"DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter,
v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
"BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
"RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
"DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter,
v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
return 0;
}
......@@ -585,41 +578,48 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
{
int pqindex, lowquant, status;
if(v->finterpflag) v->interpfrm = get_bits1(gb);
if (v->finterpflag)
v->interpfrm = get_bits1(gb);
skip_bits(gb, 2); //framecnt unused
v->rangeredfrm = 0;
if (v->rangered) v->rangeredfrm = get_bits1(gb);
if (v->rangered)
v->rangeredfrm = get_bits1(gb);
v->s.pict_type = get_bits1(gb);
if (v->s.avctx->max_b_frames) {
if (!v->s.pict_type) {
if (get_bits1(gb)) v->s.pict_type = AV_PICTURE_TYPE_I;
else v->s.pict_type = AV_PICTURE_TYPE_B;
} else v->s.pict_type = AV_PICTURE_TYPE_P;
} else v->s.pict_type = v->s.pict_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
if (get_bits1(gb))
v->s.pict_type = AV_PICTURE_TYPE_I;
else
v->s.pict_type = AV_PICTURE_TYPE_B;
} else
v->s.pict_type = AV_PICTURE_TYPE_P;
} else
v->s.pict_type = v->s.pict_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
v->bi_type = 0;
if(v->s.pict_type == AV_PICTURE_TYPE_B) {
if (v->s.pict_type == AV_PICTURE_TYPE_B) {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
if(v->bfraction == 0) {
v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
if (v->bfraction == 0) {
v->s.pict_type = AV_PICTURE_TYPE_BI;
}
}
if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
skip_bits(gb, 7); // skip buffer fullness
if(v->parse_only)
if (v->parse_only)
return 0;
/* calculate RND */
if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
v->rnd = 1;
if(v->s.pict_type == AV_PICTURE_TYPE_P)
if (v->s.pict_type == AV_PICTURE_TYPE_P)
v->rnd ^= 1;
/* Quantizer stuff */
pqindex = get_bits(gb, 5);
if(!pqindex) return -1;
if (!pqindex)
return -1;
if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
v->pq = ff_vc1_pquant_table[0][pqindex];
else
......@@ -631,63 +631,69 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
if (v->quantizer_mode == QUANT_NON_UNIFORM)
v->pquantizer = 0;
v->pqindex = pqindex;
if (pqindex < 9) v->halfpq = get_bits1(gb);
else v->halfpq = 0;
if (pqindex < 9)
v->halfpq = get_bits1(gb);
else
v->halfpq = 0;
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits1(gb);
v->dquantfrm = 0;
if (v->extended_mv == 1) v->mvrange = get_unary(gb, 0, 3);
if (v->extended_mv == 1)
v->mvrange = get_unary(gb, 0, 3);
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B) v->respic = get_bits(gb, 2);
if (v->multires && v->s.pict_type != AV_PICTURE_TYPE_B)
v->respic = get_bits(gb, 2);
if(v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)){
if (v->res_x8 && (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)) {
v->x8_type = get_bits1(gb);
}else v->x8_type = 0;
} else
v->x8_type = 0;
//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
// (v->s.pict_type == AV_PICTURE_TYPE_P) ? 'P' : ((v->s.pict_type == AV_PICTURE_TYPE_I) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0;
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
v->use_ic = 0;
switch(v->s.pict_type) {
switch (v->s.pict_type) {
case AV_PICTURE_TYPE_P:
if (v->pq < 5) v->tt_index = 0;
else if(v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
if (v->pq < 5) v->tt_index = 0;
else if (v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
{
if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int scale, shift, i;
v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
v->use_ic = 1;
v->use_ic = 1;
/* fill lookup tables for intensity compensation */
if(!v->lumscale) {
if (!v->lumscale) {
scale = -64;
shift = (255 - v->lumshift * 2) << 6;
if(v->lumshift > 31)
if (v->lumshift > 31)
shift += 128 << 6;
} else {
scale = v->lumscale + 32;
if(v->lumshift > 31)
if (v->lumshift > 31)
shift = (v->lumshift - 64) << 6;
else
shift = v->lumshift << 6;
}
for(i = 0; i < 256; i++) {
v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
for (i = 0; i < 256; i++) {
v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
}
}
if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->qs_last = v->s.quarter_sample;
if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else
v->s.quarter_sample = 1;
......@@ -695,12 +701,12 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
v->s.quarter_sample = 1;
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV)
|| v->mv_mode == MV_PMODE_MIXED_MV)
{
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV) ||
v->mv_mode == MV_PMODE_MIXED_MV) {
status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
} else {
......@@ -708,7 +714,8 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
......@@ -716,18 +723,15 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
if (v->dquant)
{
if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0; //FIXME Is that so ?
if (v->vstransform)
{
if (v->vstransform) {
v->ttmbf = get_bits1(gb);
if (v->ttmbf)
{
if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
......@@ -736,38 +740,38 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
}
break;
case AV_PICTURE_TYPE_B:
if (v->pq < 5) v->tt_index = 0;
else if(v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
if (v->pq < 5) v->tt_index = 0;
else if (v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
v->s.mspel = v->s.quarter_sample;
v->s.mspel = v->s.quarter_sample;
status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2);
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
if (v->dquant)
{
if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0;
if (v->vstransform)
{
if (v->vstransform) {
v->ttmbf = get_bits1(gb);
if (v->ttmbf)
{
if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
......@@ -777,88 +781,154 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
break;
}
if(!v->x8_type)
{
if (!v->x8_type) {
/* AC Syntax */
v->c_ac_table_index = decode012(gb);
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
{
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
v->s.dc_table_index = get_bits1(gb);
}
if(v->s.pict_type == AV_PICTURE_TYPE_BI) {
if (v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->s.pict_type = AV_PICTURE_TYPE_B;
v->bi_type = 1;
v->bi_type = 1;
}
return 0;
}
/* fill lookup tables for intensity compensation */
#define INIT_LUT(lumscale, lumshift, luty, lutuv) \
if (!lumscale) { \
scale = -64; \
shift = (255 - lumshift * 2) << 6; \
if (lumshift > 31) \
shift += 128 << 6; \
} else { \
scale = lumscale + 32; \
if (lumshift > 31) \
shift = (lumshift - 64) << 6; \
else \
shift = lumshift << 6; \
} \
for (i = 0; i < 256; i++) { \
luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); \
lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); \
}
int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
{
int pqindex, lowquant;
int status;
int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */
int scale, shift, i; /* for initializing LUT for intensity compensation */
v->numref=0;
v->p_frame_skipped = 0;
if (v->second_field) {
v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
if (v->fptype & 4)
v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
v->s.current_picture_ptr->f.pict_type = v->s.pict_type;
if (!v->pic_header_flag)
goto parse_common_info;
}
if(v->interlace){
if (v->interlace) {
v->fcm = decode012(gb);
if(v->fcm){
if(!v->warn_interlaced++)
av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is not implemented\n");
return -1;
if (v->fcm) {
if (v->fcm == 2)
v->field_mode = 1;
else
v->field_mode = 0;
if (!v->warn_interlaced++)
av_log(v->s.avctx, AV_LOG_ERROR,
"Interlaced frames/fields support is incomplete\n");
}
}
switch(get_unary(gb, 0, 4)) {
case 0:
v->s.pict_type = AV_PICTURE_TYPE_P;
break;
case 1:
v->s.pict_type = AV_PICTURE_TYPE_B;
break;
case 2:
v->s.pict_type = AV_PICTURE_TYPE_I;
break;
case 3:
v->s.pict_type = AV_PICTURE_TYPE_BI;
break;
case 4:
v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic
v->p_frame_skipped = 1;
break;
if (v->field_mode) {
v->fptype = get_bits(gb, 3);
v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
if (v->fptype & 4) // B-picture
v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
} else {
switch (get_unary(gb, 0, 4)) {
case 0:
v->s.pict_type = AV_PICTURE_TYPE_P;
break;
case 1:
v->s.pict_type = AV_PICTURE_TYPE_B;
break;
case 2:
v->s.pict_type = AV_PICTURE_TYPE_I;
break;
case 3:
v->s.pict_type = AV_PICTURE_TYPE_BI;
break;
case 4:
v->s.pict_type = AV_PICTURE_TYPE_P; // skipped pic
v->p_frame_skipped = 1;
break;
}
}
if(v->tfcntrflag)
if (v->tfcntrflag)
skip_bits(gb, 8);
if(v->broadcast) {
if(!v->interlace || v->psf) {
if (v->broadcast) {
if (!v->interlace || v->psf) {
v->rptfrm = get_bits(gb, 2);
} else {
v->tff = get_bits1(gb);
v->rff = get_bits1(gb);
}
}
if(v->panscanflag) {
if (v->panscanflag) {
av_log_missing_feature(v->s.avctx, "Pan-scan", 0);
//...
}
if(v->p_frame_skipped) {
if (v->p_frame_skipped) {
return 0;
}
v->rnd = get_bits1(gb);
if(v->interlace)
if (v->interlace)
v->uvsamp = get_bits1(gb);
if(v->finterpflag) v->interpfrm = get_bits1(gb);
if(v->s.pict_type == AV_PICTURE_TYPE_B) {
if (v->field_mode) {
if (!v->refdist_flag)
v->refdist = 0;
else {
if ((v->s.pict_type != AV_PICTURE_TYPE_B)
&& (v->s.pict_type != AV_PICTURE_TYPE_BI)) {
v->refdist = get_bits(gb, 2);
if (v->refdist == 3)
v->refdist += get_unary(gb, 0, 16);
} else {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
v->frfd = (v->bfraction * v->refdist) >> 8;
v->brfd = v->refdist - v->frfd - 1;
if (v->brfd < 0)
v->brfd = 0;
}
}
goto parse_common_info;
}
if (v->finterpflag)
v->interpfrm = get_bits1(gb);
if (v->s.pict_type == AV_PICTURE_TYPE_B) {
v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
if(v->bfraction == 0) {
v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index];
if (v->bfraction == 0) {
v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */
}
}
parse_common_info:
if (v->field_mode)
v->cur_field_type = !(v->tff ^ v->second_field);
pqindex = get_bits(gb, 5);
if(!pqindex) return -1;
if (!pqindex)
return -1;
v->pqindex = pqindex;
if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
v->pq = ff_vc1_pquant_table[0][pqindex];
......@@ -871,118 +941,193 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
if (v->quantizer_mode == QUANT_NON_UNIFORM)
v->pquantizer = 0;
v->pqindex = pqindex;
if (pqindex < 9) v->halfpq = get_bits1(gb);
else v->halfpq = 0;
if (pqindex < 9)
v->halfpq = get_bits1(gb);
else
v->halfpq = 0;
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits1(gb);
if(v->postprocflag)
if (v->postprocflag)
v->postproc = get_bits(gb, 2);
if(v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P) v->use_ic = 0;
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
v->use_ic = 0;
if(v->parse_only)
if (v->parse_only)
return 0;
switch(v->s.pict_type) {
switch (v->s.pict_type) {
case AV_PICTURE_TYPE_I:
case AV_PICTURE_TYPE_BI:
if (v->fcm == 1) { //interlace frame picture
status = bitplane_decoding(v->fieldtx_plane, &v->fieldtx_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "FIELDTX plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
}
status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->condover = CONDOVER_NONE;
if(v->overlap && v->pq <= 8) {
if (v->overlap && v->pq <= 8) {
v->condover = decode012(gb);
if(v->condover == CONDOVER_SELECT) {
if (v->condover == CONDOVER_SELECT) {
status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v);
if (status < 0) return -1;
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
"Imode: %i, Invert: %i\n", status>>1, status&1);
}
}
break;
case AV_PICTURE_TYPE_P:
if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
else v->mvrange = 0;
if (v->field_mode) {
v->numref = get_bits1(gb);
if (!v->numref) {
v->reffield = get_bits1(gb);
v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;
}
}
if (v->extended_mv)
v->mvrange = get_unary(gb, 0, 3);
else
v->mvrange = 0;
if (v->interlace) {
if (v->extended_dmv)
v->dmvrange = get_unary(gb, 0, 3);
else
v->dmvrange = 0;
if (v->fcm == 1) { // interlaced frame picture
v->fourmvswitch = get_bits1(gb);
v->intcomp = get_bits1(gb);
if (v->intcomp) {
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
mbmodetab = get_bits(gb, 2);
if (v->fourmvswitch)
v->mbmode_vlc = &ff_vc1_intfr_4mv_mbmode_vlc[mbmodetab];
else
v->mbmode_vlc = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab];
imvtab = get_bits(gb, 2);
v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];
// interlaced p-picture cbpcy range is [1, 63]
icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
twomvbptab = get_bits(gb, 2);
v->twomvbp_vlc = &ff_vc1_2mv_block_pattern_vlc[twomvbptab];
if (v->fourmvswitch) {
fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
}
}
}
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
if (v->pq < 5) v->tt_index = 0;
else if(v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
{
int scale, shift, i;
v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
/* fill lookup tables for intensity compensation */
if(!v->lumscale) {
scale = -64;
shift = (255 - v->lumshift * 2) << 6;
if(v->lumshift > 31)
shift += 128 << 6;
} else {
scale = v->lumscale + 32;
if(v->lumshift > 31)
shift = (v->lumshift - 64) << 6;
else
shift = v->lumshift << 6;
}
for(i = 0; i < 256; i++) {
v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
if (v->pq < 5)
v->tt_index = 0;
else if (v->pq < 13)
v->tt_index = 1;
else
v->tt_index = 2;
if (v->fcm != 1) {
int mvmode;
mvmode = get_unary(gb, 1, 4);
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table[lowquant][mvmode];
if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int mvmode2;
mvmode2 = get_unary(gb, 1, 3);
v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];
if (v->field_mode)
v->intcompfield = decode210(gb);
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
if ((v->field_mode) && !v->intcompfield) {
v->lumscale2 = get_bits(gb, 6);
v->lumshift2 = get_bits(gb, 6);
INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2);
}
v->use_ic = 1;
}
v->use_ic = 1;
}
if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
v->qs_last = v->s.quarter_sample;
if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else
else if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
if (v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
else
v->s.quarter_sample = 1;
} else
v->s.quarter_sample = 1;
} else
v->s.quarter_sample = 1;
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN
|| (v->mv_mode == MV_PMODE_INTENSITY_COMP
&& v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN));
}
if (v->fcm == 0) { // progressive
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV)
|| v->mv_mode == MV_PMODE_MIXED_MV)
{
status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
if (status < 0) return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
|| v->mv_mode == MV_PMODE_MIXED_MV) {
status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
} else {
v->mv_type_is_raw = 0;
memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
} else {
v->mv_type_is_raw = 0;
memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
}
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0) return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
/* Hopefully this is correct for P frames */
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
if (v->dquant)
{
/* Hopefully this is correct for P frames */
v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
} else if (v->fcm == 1) { // frame interlaced
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = 1;
v->s.mspel = 1;
} else { // field interlaced
mbmodetab = get_bits(gb, 3);
imvtab = get_bits(gb, 2 + v->numref);
if (!v->numref)
v->imv_vlc = &ff_vc1_1ref_mvdata_vlc[imvtab];
else
v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];
icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
v->mv_mode2 == MV_PMODE_MIXED_MV) || v->mv_mode == MV_PMODE_MIXED_MV) {
fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];
} else {
v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];
}
}
if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0; //FIXME Is that so ?
if (v->vstransform)
{
if (v->vstransform) {
v->ttmbf = get_bits1(gb);
if (v->ttmbf)
{
if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
......@@ -991,45 +1136,82 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
}
break;
case AV_PICTURE_TYPE_B:
if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3);
else v->mvrange = 0;
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
// TODO: implement interlaced frame B picture decoding
if (v->fcm == 1)
return -1;
if (v->extended_mv)
v->mvrange = get_unary(gb, 0, 3);
else
v->mvrange = 0;
v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
v->range_x = 1 << (v->k_x - 1);
v->range_y = 1 << (v->k_y - 1);
if (v->pq < 5) v->tt_index = 0;
else if(v->pq < 13) v->tt_index = 1;
else v->tt_index = 2;
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
v->s.mspel = v->s.quarter_sample;
status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
if (status < 0) return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0) return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2);
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
if (v->pq < 5)
v->tt_index = 0;
else if (v->pq < 13)
v->tt_index = 1;
else
v->tt_index = 2;
if (v->field_mode) {
int mvmode;
if (v->extended_dmv)
v->dmvrange = get_unary(gb, 0, 3);
mvmode = get_unary(gb, 1, 3);
lowquant = (v->pq > 12) ? 0 : 1;
v->mv_mode = ff_vc1_mv_pmode_table2[lowquant][mvmode];
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV || v->mv_mode == MV_PMODE_MIXED_MV);
v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || v->mv_mode == MV_PMODE_1MV_HPEL);
status = bitplane_decoding(v->forward_mb_plane, &v->fmb_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Forward Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
mbmodetab = get_bits(gb, 3);
if (v->mv_mode == MV_PMODE_MIXED_MV)
v->mbmode_vlc = &ff_vc1_if_mmv_mbmode_vlc[mbmodetab];
else
v->mbmode_vlc = &ff_vc1_if_1mv_mbmode_vlc[mbmodetab];
imvtab = get_bits(gb, 3);
v->imv_vlc = &ff_vc1_2ref_mvdata_vlc[imvtab];
icbptab = get_bits(gb, 3);
v->cbpcy_vlc = &ff_vc1_icbpcy_vlc[icbptab];
if (v->mv_mode == MV_PMODE_MIXED_MV) {
fourmvbptab = get_bits(gb, 2);
v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
}
v->numref = 1; // interlaced field B pictures are always 2-ref
} else {
v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
v->qs_last = v->s.quarter_sample;
v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV);
v->s.mspel = v->s.quarter_sample;
status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
if (status < 0)
return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
"Imode: %i, Invert: %i\n", status>>1, status&1);
v->s.mv_table_index = get_bits(gb, 2);
v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)];
}
if (v->dquant)
{
if (v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->ttfrm = 0;
if (v->vstransform)
{
if (v->vstransform) {
v->ttmbf = get_bits1(gb);
if (v->ttmbf)
{
if (v->ttmbf) {
v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)];
}
} else {
......@@ -1041,19 +1223,19 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
/* AC Syntax */
v->c_ac_table_index = decode012(gb);
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
{
if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->y_ac_table_index = decode012(gb);
}
/* DC Syntax */
v->s.dc_table_index = get_bits1(gb);
if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI) && v->dquant) {
if ((v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_BI)
&& v->dquant) {
av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
vop_dquant_decoding(v);
}
v->bi_type = 0;
if(v->s.pict_type == AV_PICTURE_TYPE_BI) {
if (v->s.pict_type == AV_PICTURE_TYPE_BI) {
v->s.pict_type = AV_PICTURE_TYPE_B;
v->bi_type = 1;
}
......
......@@ -105,12 +105,25 @@ enum MVModes {
};
//@}
/** MBMODE for interlaced frame P-picture */
//@{
enum MBModesIntfr {
MV_PMODE_INTFR_1MV,
MV_PMODE_INTFR_2MV_FIELD,
MV_PMODE_INTFR_2MV,
MV_PMODE_INTFR_4MV_FIELD,
MV_PMODE_INTFR_4MV,
MV_PMODE_INTFR_INTRA,
};
//@}
/** @name MV types for B frames */
//@{
enum BMVTypes {
BMV_TYPE_BACKWARD,
BMV_TYPE_FORWARD,
BMV_TYPE_INTERPOLATED
BMV_TYPE_INTERPOLATED,
BMV_TYPE_DIRECT
};
//@}
......@@ -260,16 +273,18 @@ typedef struct VC1Context{
* -# 2 -> [-512, 511.f] x [-128, 127.f]
* -# 3 -> [-1024, 1023.f] x [-256, 255.f]
*/
uint8_t mvrange;
uint8_t mvrange; ///< Extended MV range flag
uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use
VLC *cbpcy_vlc; ///< CBPCY VLC table
int tt_index; ///< Index for Transform Type tables
int tt_index; ///< Index for Transform Type tables (to decode TTMB)
uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV)
uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs
uint8_t* forward_mb_plane; ///< bitplane for "forward" MBs
int mv_type_is_raw; ///< mv type mb plane is not coded
int dmb_is_raw; ///< direct mb plane is raw
int fmb_is_raw; ///< forward 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
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
......@@ -307,6 +322,44 @@ typedef struct VC1Context{
uint8_t range_mapuv;
//@}
/** Frame decoding info for interlaced picture */
uint8_t dmvrange; ///< Extended differential MV range flag
int fourmvswitch;
int intcomp;
uint8_t lumscale2; ///< for interlaced field P picture
uint8_t lumshift2;
uint8_t luty2[256], lutuv2[256]; // lookup tables used for intensity compensation
VLC* mbmode_vlc;
VLC* imv_vlc;
VLC* twomvbp_vlc;
VLC* fourmvbp_vlc;
uint8_t twomvbp;
uint8_t fourmvbp;
uint8_t* fieldtx_plane;
int fieldtx_is_raw;
int8_t zzi_8x8[64];
uint8_t *blk_mv_type_base, *blk_mv_type; ///< 0: frame MV, 1: field MV (interlaced frame)
uint8_t *mv_f_base, *mv_f[2]; ///< 0: MV obtained from same field, 1: opposite field
uint8_t *mv_f_last_base, *mv_f_last[2];
uint8_t *mv_f_next_base, *mv_f_next[2];
int field_mode; ///< 1 for interlaced field pictures
int fptype;
int second_field;
int refdist; ///< distance of the current picture from reference
int numref; ///< number of past field pictures used as reference
// 0 corresponds to 1 and 1 corresponds to 2 references
int reffield; ///< if numref = 0 (1 reference) then reffield decides which
// field to use among the two fields from previous frame
int intcompfield; ///< which of the two fields to be intensity compensated
// 0: both fields, 1: bottom field, 2: top field
int cur_field_type; ///< 0: top, 1: bottom
int ref_field_type[2]; ///< forward and backward reference field type (top or bottom)
int blocks_off, mb_off;
int qs_last; ///< if qpel has been used in the previous (tr.) picture
int bmvtype;
int frfd, brfd; ///< reference frame distance (forward or backward)
int pic_header_flag;
/** Frame decoding info for sprite modes */
//@{
int new_sprite;
......
/*
* VC-1 and WMV3 decoder
* copyright (c) 2011 Mashiat Sarker Shakkhar
* copyright (c) 2006 Konstantin Shishkov
* (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer
*
......@@ -48,6 +49,40 @@ const uint8_t ff_vc1_mv_pmode_table2[2][4] = {
{ MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN }
};
/* MBMODE table for interlaced frame P-picture */
const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = {
{ /* 1: 4-MV, 0: non-4-MV */
/* Type, FIELDTX, 1-MV Differential present, Residuals (CBP) present */
/* Table 164 - Table 167 */
{ MV_PMODE_INTFR_1MV , 0, 1, 1},
{ MV_PMODE_INTFR_1MV , 1, 1, 1},
{ MV_PMODE_INTFR_1MV , 0, 1, 0},
{ MV_PMODE_INTFR_1MV , 0, 0, 1},
{ MV_PMODE_INTFR_1MV , 1, 0, 1},
{ MV_PMODE_INTFR_2MV_FIELD , 0, 0, 1},
{ MV_PMODE_INTFR_2MV_FIELD , 1, 0, 1},
{ MV_PMODE_INTFR_2MV_FIELD , 0, 0, 0},
{ MV_PMODE_INTFR_INTRA , 0, 0, 0} },
{
/* Table 160 - Table 163 */
{ MV_PMODE_INTFR_1MV , 0, 1, 1 },
{ MV_PMODE_INTFR_1MV , 1, 1, 1 },
{ MV_PMODE_INTFR_1MV , 0, 1, 0 },
{ MV_PMODE_INTFR_1MV , 0, 0, 1 },
{ MV_PMODE_INTFR_1MV , 1, 0, 1 },
{ MV_PMODE_INTFR_2MV_FIELD , 0, 0, 1 },
{ MV_PMODE_INTFR_2MV_FIELD , 1, 0, 1 },
{ MV_PMODE_INTFR_2MV_FIELD , 0, 0, 0 },
{ MV_PMODE_INTFR_4MV , 0, 0, 1 },
{ MV_PMODE_INTFR_4MV , 1, 0, 1 },
{ MV_PMODE_INTFR_4MV , 0, 0, 0 },
{ MV_PMODE_INTFR_4MV_FIELD , 0, 0, 1 },
{ MV_PMODE_INTFR_4MV_FIELD , 1, 0, 1 },
{ MV_PMODE_INTFR_4MV_FIELD , 0, 0, 0 },
{ MV_PMODE_INTFR_INTRA , 0, 0, 0 }
}
};
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] = {
......@@ -84,14 +119,33 @@ VLC ff_vc1_ttmb_vlc[3];
VLC ff_vc1_mv_diff_vlc[4];
#define VC1_CBPCY_P_VLC_BITS 9 //14
VLC ff_vc1_cbpcy_p_vlc[4];
#define VC1_ICBPCY_VLC_BITS 9
VLC ff_vc1_icbpcy_vlc[8];
#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6
VLC ff_vc1_4mv_block_pattern_vlc[4];
#define VC1_2MV_BLOCK_PATTERN_VLC_BITS 3
VLC ff_vc1_2mv_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];
#define VC1_INTFR_4MV_MBMODE_VLC_BITS 9
VLC ff_vc1_intfr_4mv_mbmode_vlc[4];
#define VC1_INTFR_NON4MV_MBMODE_VLC_BITS 6
VLC ff_vc1_intfr_non4mv_mbmode_vlc[4];
#define VC1_IF_MMV_MBMODE_VLC_BITS 5
VLC ff_vc1_if_mmv_mbmode_vlc[8];
#define VC1_IF_1MV_MBMODE_VLC_BITS 5
VLC ff_vc1_if_1mv_mbmode_vlc[8];
#define VC1_1REF_MVDATA_VLC_BITS 9
VLC ff_vc1_1ref_mvdata_vlc[4];
#define VC1_2REF_MVDATA_VLC_BITS 9
VLC ff_vc1_2ref_mvdata_vlc[8];
VLC ff_vc1_ac_coeff_table[8];
#define VC1_IF_MBMODE_VLC_BITS 5 // as a placeholder for VC1_IF_MMV_MBMODE_VLC_BITS
// or VC1_IF_1MV_MBMODE_VLC_BITS since they are the same
//@}
......@@ -202,6 +256,273 @@ const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = {
{ 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4}
};
/* 2MV Block pattern VLC tables */
const uint8_t ff_vc1_2mv_block_pattern_codes[4][4] = {
{ 2, 1, 0, 3}, { 1, 0, 2, 3}, { 2, 0, 3, 1}, { 1, 3, 2, 0}
};
const uint8_t ff_vc1_2mv_block_pattern_bits[4][4] = {
{ 2, 2, 2, 2}, { 1, 2, 3, 3}, { 3, 2, 3, 1}, { 1, 3, 3, 2}
};
/* Interlaced frame picture 4MV MBMODE VLC tables (p. 246, p. 360) */
const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15] = {
{ 22, 17, 0, 47, 32, 10, 1, 3, 67, 133, 132, 92, 19, 93, 18},
{ 3, 45, 0, 7, 23, 6, 1, 2, 10, 39, 44, 8, 18, 77, 76},
{ 15, 6, 28, 9, 41, 6, 2, 15, 14, 8, 40, 29, 0, 21, 11},
{ 7, 198, 1, 2, 193, 13, 25, 0, 97, 1599, 98, 398, 798, 192, 1598}
};
const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15] = {
{ 5, 5, 2, 6, 6, 4, 2, 2, 7, 8, 8, 7, 5, 7, 5},
{ 3, 6, 3, 3, 5, 3, 3, 3, 4, 6, 6, 4, 5, 7, 7},
{ 4, 3, 5, 5, 7, 4, 2, 5, 5, 5, 7, 5, 2, 6, 5},
{ 4, 9, 1, 3, 9, 5, 6, 2, 8, 12, 8, 10, 11, 9, 12}
};
/* Interlaced frame picture NON-4MV MBMODE VLC tables (p. 363) */
const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9] = {
{ 9, 22, 0, 17, 16, 10, 1, 3, 23},
{ 7, 0, 5, 2, 1, 1, 6, 3, 4},
{ 1, 0, 10, 23, 44, 8, 3, 9, 45},
{ 7, 97, 1, 2, 49, 13, 25, 0, 96}
};
const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9] = {
{ 4, 5, 2, 5, 5, 4, 2, 2, 5},
{ 3, 4, 6, 2, 3, 2, 3, 5, 6},
{ 2, 2, 4, 5, 6, 4, 2, 4, 6},
{ 4, 8, 1, 3, 7, 5, 6, 2, 8}
};
/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
/* mixed-MV */
const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8] = {
{ 16, 17, 3, 3, 0, 5, 9, 2 },
{ 8, 9, 3, 6, 7, 0, 5, 2 },
{ 16, 17, 5, 3, 0, 3, 9, 2 },
{ 56, 57, 15, 4, 5, 6, 29, 0 },
{ 52, 53, 27, 14, 15, 2, 12, 0 },
{ 56, 57, 29, 5, 6, 0, 15, 4 },
{ 16, 17, 6, 7, 0, 1, 9, 5 },
{ 56, 57, 0, 5, 6, 29, 4, 15 }
};
const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8] = {
{ 6, 6, 2, 3, 2, 4, 5, 2 },
{ 5, 5, 3, 3, 3, 2, 4, 2 },
{ 6, 6, 4, 3, 2, 2, 5, 2 },
{ 6, 6, 4, 3, 3, 3, 5, 1 },
{ 6, 6, 5, 4, 4, 2, 4, 1 },
{ 6, 6, 5, 3, 3, 1, 4, 3 },
{ 5, 5, 3, 3, 2, 2, 4, 3 },
{ 6, 6, 1, 3, 3, 5, 3, 4 }
};
/* 1MV */
const uint8_t ff_vc1_if_1mv_mbmode_codes[8][6] = {
{ 0, 1, 1, 1, 1, 1 },
{ 0, 1, 1, 1, 1, 1 },
{ 16, 17, 3, 0, 9, 5 },
{ 20, 21, 3, 11, 0, 4 },
{ 4, 5, 2, 3, 3, 0 },
{ 4, 5, 3, 2, 0, 3 },
{ 0, 1, 1, 1, 1, 1 },
{ 16, 17, 9, 5, 3, 0 }
};
const uint8_t ff_vc1_if_1mv_mbmode_bits[8][6] = {
{ 5, 5, 1, 3, 2, 4 },
{ 5, 5, 1, 2, 3, 4 },
{ 5, 5, 2, 1, 4, 3 },
{ 5, 5, 2, 4, 1, 3 },
{ 4, 4, 2, 3, 2, 2 },
{ 4, 4, 3, 2, 2, 2 },
{ 5, 5, 3, 4, 1, 2 },
{ 5, 5, 4, 3, 2, 1 }
};
/* Interlaced frame/field picture MVDATA VLC tables */
/* 1-reference tables */
const uint32_t ff_vc1_1ref_mvdata_codes[4][72] = { /* uint32_t may be too big */
{5, 12, 30, 18, 12, 52, 117, 112, 0, 8, 27, 8, 29, 124, 214, 478, 431, 5, 27, 38, 30, 18, 118, 77,
502, 500, 57, 127, 39, 106, 113, 53, 113, 104, 476, 39, 115, 255, 232, 233, 126, 505, 501, 509, 62, 458, 1017, 76,
105, 506, 479, 503, 112, 477, 3661, 1831, 914, 456, 459, 1016, 430, 504, 507, 58574, 58575, 29280, 29281, 29282, 29283, 29284, 29285, 29286},
{7, 1, 7, 22, 1, 69, 24, 694, 6, 4, 23, 16, 41, 44, 346, 102, 414, 9, 40, 23, 0, 42, 4, 91,
181, 206, 6, 68, 15, 70, 14, 172, 50, 55, 4587, 10, 26, 287, 22, 20, 43, 360, 85, 9173, 87, 47, 54, 46,
361, 84, 1147, 415, 11133, 142, 2782, 1145, 1390, 2292, 5567, 1144, 9172, 44529, 22265, 712462, 712463, 356224, 356225, 356226, 356227, 356228, 356229, 356230},
{2, 6, 7, 13, 7, 48, 255, 496, 2, 0, 5, 25, 30, 7, 99, 253, 35, 14, 27, 26, 6, 9, 24, 197,
51, 497, 2, 1019, 499, 34, 508, 66, 1571, 131, 1568, 125, 64, 67, 996, 997, 401, 4073, 261, 520, 252, 1572, 1570, 400,
1574, 2037, 3147, 8144, 4173, 101, 3138, 201, 1575, 3139, 3146, 4174, 8145, 4175, 1042, 66766, 66767, 33376, 33377, 33378, 33379, 33380, 33381, 33382},
{13, 1, 4, 0, 23, 5, 127, 77, 3, 17, 62, 59, 23, 103, 74, 195, 242, 10, 44, 50, 61, 21, 40, 147,
204, 150, 3, 117, 32, 45, 33, 41, 144, 464, 507, 28, 76, 96, 9, 8, 45, 159, 506, 317, 49, 252, 88, 146,
240, 241, 205, 389, 357, 78, 145, 233, 388, 465, 486, 151, 487, 179, 316, 5710, 5711, 2848, 2849, 2850, 2851, 2852, 2853, 2854}
};
const uint8_t ff_vc1_1ref_mvdata_bits[4][72] = {
{3, 4, 5, 5, 5, 6, 7, 7, 2, 4, 5, 5, 6, 7, 8, 9, 9, 4, 6, 6, 6, 6, 7, 8,
9, 9, 6, 8, 7, 7, 7, 7, 8, 8, 9, 6, 8, 8, 8, 8, 8, 9, 9, 9, 7, 10, 10, 8,
8, 9, 9, 9, 8, 9, 13, 12, 11, 10, 10, 10, 9, 9, 9, 17, 17, 16, 16, 16, 16, 16, 16, 16},
{3, 3, 4, 5, 5, 7, 8, 10, 3, 4, 5, 5, 6, 7, 9, 10, 12, 4, 6, 6, 5, 6, 6, 8,
9, 11, 4, 7, 7, 7, 7, 8, 9, 9, 13, 5, 8, 9, 8, 8, 9, 10, 10, 14, 7, 9, 9, 9,
10, 10, 11, 12, 14, 8, 12, 11, 11, 12, 13, 11, 14, 16, 15, 20, 20, 19, 19, 19, 19, 19, 19, 19},
{3, 4, 4, 4, 5, 6, 8, 9, 2, 4, 5, 5, 5, 6, 7, 8, 8, 4, 7, 7, 6, 6, 7, 8,
8, 9, 5, 10, 9, 8, 9, 9, 11, 10, 11, 7, 9, 9, 10, 10, 11, 12, 11, 12, 8, 11, 11, 11,
11, 11, 12, 13, 15, 9, 12, 10, 11, 12, 12, 15, 13, 15, 13, 19, 19, 18, 18, 18, 18, 18, 18, 18},
{4, 4, 4, 4, 5, 5, 7, 7, 3, 5, 6, 6, 6, 7, 7, 8, 8, 4, 6, 6, 6, 6, 7, 8,
8, 8, 4, 7, 6, 6, 6, 7, 8, 9, 9, 5, 7, 7, 6, 6, 7, 8, 9, 9, 6, 8, 8, 8,
8, 8, 8, 9, 10, 7, 8, 8, 9, 9, 9, 8, 9, 9, 9, 14, 14, 13, 13, 13, 13, 13, 13, 13}
};
/* 2-reference tables */
const uint32_t ff_vc1_2ref_mvdata_codes[8][126] = { /* table 132 - table 139 */
{12, 28, 11, 0, 14, 42, 80, 872, 2, 26, 4, 58, 29, 108,
239, 444, 351, 15, 3, 28, 13, 11, 62, 167, 326, 409, 6, 31,
4, 60, 7, 446, 139, 44, 1971, 5, 219, 86, 236, 82, 445, 120,
207, 1395, 9, 35, 237, 24, 6, 68, 245, 121, 1746, 110, 43, 349,
23, 895, 324, 206, 40, 171, 16, 437, 247, 166, 123, 40, 493, 489,
1789, 4, 245, 41, 650, 651, 655, 3577, 821, 7813, 238, 701, 43, 984,
977, 408, 489, 1309, 180, 63, 1109, 555, 553, 1105, 1400, 1970, 1392, 341,
50, 976, 84, 1747, 1393, 1108, 820, 7153, 183, 41, 7812, 364, 411, 7152,
1401, 3907, 181, 2209, 42, 365, 2208, 1952, 977, 2789, 340, 2788, 2617, 2616},
{3, 9, 22, 16, 215, 821, 1396, 1365, 0, 29, 9, 23, 44, 173,
884, 1715, 1399, 15, 24, 10, 46, 34, 380, 3707, 7049, 5592, 8, 52,
109, 35, 450, 886, 723, 7242, 13066, 20, 106, 114, 108, 227, 411, 1855,
7408, 2881, 50, 230, 224, 207, 171, 412, 683, 3627, 5593, 111, 451, 175,
191, 172, 381, 1763, 3625, 6532, 84, 181, 378, 429, 409, 376, 856, 722,
7243, 91, 680, 817, 904, 907, 880, 1811, 3267, 7409, 441, 1519, 1848, 754,
827, 697, 1771, 1392, 3620, 925, 1442, 1443, 3709, 1518, 1849, 1364, 2725, 2724,
887, 7413, 3022, 3705, 1632, 1652, 1770, 3708, 3429, 758, 5594, 7048, 1441, 7412,
1510, 3624, 1397, 3428, 820, 13067, 5595, 2880, 3023, 3525, 3626, 1653, 1393, 1363},
{4, 2, 16, 3, 23, 69, 62, 126, 3, 2, 40, 30, 21, 71,
2, 333, 96, 11, 38, 36, 20, 50, 111, 195, 1329, 1765, 21, 63,
45, 1, 318, 221, 246, 773, 817, 14, 3, 52, 51, 26, 330, 197,
244, 1764, 1, 60, 125, 141, 157, 49, 110, 662, 205, 37, 329, 50,
137, 54, 136, 111, 3, 797, 14, 426, 638, 97, 334, 335, 103, 255,
387, 54, 855, 245, 198, 194, 665, 281, 561, 848, 44, 399, 1328, 663,
4, 440, 192, 634, 785, 156, 1569, 409, 796, 247, 995, 854, 393, 5,
107, 2242, 816, 1279, 1264, 849, 1266, 498, 883, 0, 3137, 2243, 2540, 994,
772, 1271, 1265, 496, 328, 3136, 2541, 2240, 2241, 1267, 1278, 254, 499, 425},
{0, 4, 47, 82, 16, 173, 1291, 400, 3, 22, 7, 13, 187, 371,
201, 1295, 5932, 3, 17, 5, 67, 35, 75, 814, 11867, 1154, 9, 42,
20, 42, 264, 1482, 1626, 8502, 8498, 11, 19, 65, 184, 372, 256, 5338,
16462, 5175, 43, 133, 167, 160, 332, 666, 812, 8499, 5162, 81, 644, 172,
258, 69, 68, 2075, 1630, 3255, 24, 1292, 530, 740, 515, 148, 290, 2074,
1621, 51, 698, 582, 578, 2670, 1036, 2056, 8500, 16463, 373, 1029, 583, 298,
2580, 699, 401, 2127, 5176, 175, 2967, 1155, 5179, 811, 579, 5163, 2392, 10687,
73, 2668, 5339, 1197, 5342, 2126, 5172, 599, 11866, 519, 5173, 5177, 3254, 5178,
404, 1620, 8501, 21372, 348, 576, 4114, 21373, 2393, 4248, 5174, 1631, 8230, 8503},
{5, 25, 22, 17, 62, 94, 239, 226, 0, 57, 43, 38, 40, 18,
194, 237, 285, 13, 49, 42, 37, 32, 92, 493, 589, 1904, 6, 122,
96, 79, 72, 57, 390, 531, 3782, 15, 38, 95, 117, 112, 39, 475,
966, 1935, 63, 166, 240, 58, 82, 78, 227, 473, 783, 16, 477, 167,
247, 34, 146, 964, 751, 1890, 121, 143, 474, 135, 232, 186, 374, 238,
944, 133, 281, 782, 264, 466, 268, 1907, 1060, 1076, 113, 1501, 449, 935,
295, 141, 539, 1970, 479, 984, 1892, 3812, 947, 1869, 472, 1500, 2122, 1177,
965, 7566, 1893, 1077, 1905, 450, 280, 956, 897, 903, 31539, 4247, 4246, 7885,
3737, 3868, 3869, 3813, 284, 31538, 15768, 7567, 3736, 3943, 957, 896, 1176, 902},
{13, 16, 46, 57, 13, 116, 237, 182, 1, 2, 0, 48, 41, 112,
243, 140, 358, 9, 51, 120, 6, 196, 11, 355, 204, 1470, 31, 47,
100, 24, 198, 10, 354, 704, 3827, 7, 15, 227, 202, 178, 399, 942,
1887, 3153, 21, 71, 238, 226, 234, 9, 362, 707, 1437, 61, 8, 473,
50, 14, 366, 812, 1627, 6507, 2, 15, 472, 141, 180, 484, 103, 791,
1940, 34, 958, 789, 52, 55, 734, 108, 3838, 1644, 40, 971, 940, 53,
363, 957, 705, 1580, 7678, 14, 1438, 1471, 218, 1577, 1412, 3767, 2826, 1645,
12, 1918, 1436, 1912, 1886, 1882, 1581, 823, 820, 407, 7767, 7652, 6506, 7766,
3152, 2879, 7764, 2827, 398, 438, 7765, 3252, 2878, 3766, 7653, 7679, 821, 439},
{1, 11, 25, 111, 42, 117, 2027, 355, 1, 14, 26, 62, 28, 45,
356, 2028, 357, 4, 6, 54, 127, 174, 344, 348, 1389, 1037584, 0, 4,
123, 243, 59, 2029, 691, 716, 1390, 24, 62, 23, 30, 175, 1015, 1391,
717, 1037585, 20, 173, 170, 20, 168, 339, 232, 510, 3535, 120, 440, 338,
254, 689, 349, 352, 1037586, 1037587, 122, 688, 485, 233, 252, 1766, 3528, 1412,
1037588, 171, 3550, 345, 1012, 3529, 3530, 506, 1037589, 1037590, 252, 511, 484, 175,
346, 359, 3531, 1413, 1037591, 1015, 16213, 1037592, 3548, 1414, 16214, 1037593, 16215, 1037594,
442, 1415, 1416, 3551, 690, 1037595, 3534, 1014, 1037596, 4052, 1037597, 1037598, 1037599, 518784,
518785, 1388, 518786, 518787, 886, 1417, 1418, 518788, 518789, 3549, 518790, 518791, 1419, 32425},
{3, 14, 15, 126, 98, 198, 3289, 1598, 2, 2, 0, 24, 12, 105,
57, 1799, 3198, 2, 13, 27, 15, 410, 1607, 6711, 214724, 13421, 1, 30,
127, 10, 225, 1633, 3300, 214725, 214726, 29, 48, 13, 203, 409, 800, 142,
25902, 214727, 62, 57, 53, 51, 415, 448, 3290, 214728, 214729, 11, 208, 414,
34, 56, 398, 798, 12948, 572, 50, 18, 19, 113, 413, 32, 3207, 3264,
214730, 824, 1619, 418, 810, 802, 3303, 132, 287, 214731, 805, 1609, 811, 119,
1608, 1602, 3206, 3212, 214732, 58, 6583, 67, 807, 140, 141, 3213, 214733, 214734,
823, 3301, 133, 806, 839, 3236, 3199, 3354, 214735, 808, 107360, 107361, 3288, 1676,
12949, 12950, 25903, 26328, 817, 1798, 573, 118, 3265, 898, 3302, 26329, 26330, 26331}
};
const uint8_t ff_vc1_2ref_mvdata_bits[8][126] = {
{4, 5, 5, 5, 6, 7, 8, 10, 2, 5, 5, 6, 6, 7,
8, 9, 10, 4, 5, 6, 6, 7, 8, 9, 10, 11, 4, 6,
6, 7, 7, 9, 9, 10, 12, 5, 8, 8, 8, 8, 9, 9,
10, 12, 5, 7, 8, 7, 7, 8, 9, 9, 11, 7, 9, 10,
9, 10, 10, 10, 10, 12, 6, 9, 9, 9, 9, 9, 10, 10,
11, 7, 10, 10, 11, 11, 11, 12, 12, 14, 8, 11, 10, 11,
11, 11, 11, 12, 12, 8, 12, 11, 11, 12, 12, 12, 12, 13,
8, 12, 11, 11, 12, 12, 12, 13, 12, 9, 14, 13, 11, 13,
12, 13, 12, 13, 9, 13, 13, 12, 12, 13, 13, 13, 13, 13},
{3, 4, 5, 6, 8, 10, 11, 11, 2, 5, 5, 6, 7, 8,
10, 11, 11, 4, 5, 5, 6, 7, 9, 12, 13, 13, 4, 6,
7, 7, 9, 10, 11, 13, 14, 5, 7, 7, 7, 8, 9, 11,
13, 13, 6, 8, 8, 8, 8, 9, 10, 12, 13, 7, 9, 8,
8, 8, 9, 11, 12, 13, 7, 9, 9, 9, 9, 9, 10, 11,
13, 8, 10, 10, 10, 10, 10, 11, 12, 13, 9, 11, 11, 10,
10, 10, 11, 11, 12, 10, 12, 12, 12, 11, 11, 11, 12, 12,
10, 13, 12, 12, 11, 11, 11, 12, 12, 10, 13, 13, 12, 13,
11, 12, 11, 12, 10, 14, 13, 13, 12, 12, 12, 11, 11, 11},
{4, 4, 5, 5, 6, 7, 8, 9, 2, 5, 6, 6, 6, 7,
7, 9, 9, 4, 6, 6, 6, 7, 8, 9, 11, 12, 5, 7,
7, 7, 9, 9, 10, 11, 12, 5, 7, 7, 7, 7, 9, 9,
10, 12, 5, 8, 8, 8, 8, 8, 9, 10, 10, 6, 9, 8,
8, 8, 8, 9, 9, 11, 6, 10, 10, 9, 9, 9, 9, 10,
10, 7, 11, 10, 9, 9, 10, 9, 10, 11, 7, 10, 11, 10,
10, 10, 9, 10, 11, 8, 12, 11, 11, 10, 11, 11, 10, 10,
8, 12, 12, 11, 11, 11, 11, 10, 11, 8, 13, 12, 12, 11,
11, 11, 11, 10, 9, 13, 12, 12, 12, 11, 11, 10, 10, 10},
{3, 4, 6, 7, 7, 9, 11, 11, 2, 5, 5, 6, 8, 9,
10, 11, 13, 3, 5, 5, 7, 8, 9, 12, 14, 13, 4, 6,
6, 7, 9, 11, 13, 14, 14, 5, 7, 7, 8, 9, 9, 13,
15, 13, 6, 8, 8, 8, 9, 10, 12, 14, 13, 7, 10, 9,
9, 9, 9, 12, 13, 14, 7, 11, 10, 10, 10, 10, 11, 12,
13, 8, 11, 12, 12, 12, 11, 12, 14, 15, 9, 11, 12, 11,
12, 11, 11, 12, 13, 9, 12, 13, 13, 12, 12, 13, 14, 14,
9, 12, 13, 13, 13, 12, 13, 12, 14, 10, 13, 13, 14, 13,
11, 13, 14, 15, 10, 12, 13, 15, 14, 13, 13, 13, 14, 14},
{4, 5, 5, 5, 6, 7, 8, 8, 2, 6, 6, 6, 6, 6,
8, 9, 10, 4, 6, 6, 6, 6, 7, 9, 10, 11, 4, 7,
7, 7, 7, 7, 9, 10, 12, 5, 7, 7, 7, 7, 7, 9,
10, 11, 6, 8, 8, 7, 7, 7, 8, 9, 10, 6, 9, 8,
8, 7, 8, 10, 10, 11, 7, 9, 9, 8, 8, 8, 9, 9,
10, 8, 10, 10, 9, 9, 9, 11, 11, 11, 8, 11, 10, 10,
9, 9, 10, 11, 10, 10, 12, 12, 11, 11, 10, 11, 12, 11,
10, 13, 12, 11, 11, 10, 10, 11, 11, 11, 15, 13, 13, 13,
12, 12, 12, 12, 10, 15, 14, 13, 12, 12, 11, 11, 11, 11},
{4, 5, 6, 6, 6, 7, 8, 8, 2, 4, 5, 6, 6, 7,
8, 8, 9, 4, 6, 7, 7, 8, 8, 9, 10, 11, 5, 6,
7, 7, 8, 8, 9, 10, 12, 5, 7, 8, 8, 8, 9, 10,
11, 12, 5, 7, 8, 8, 8, 8, 9, 10, 11, 6, 8, 9,
8, 8, 9, 10, 11, 13, 5, 8, 9, 8, 8, 9, 9, 10,
11, 6, 10, 10, 9, 9, 10, 10, 12, 13, 6, 10, 10, 9,
9, 10, 10, 11, 13, 7, 11, 11, 11, 11, 11, 12, 12, 13,
7, 11, 11, 11, 11, 11, 11, 12, 12, 9, 13, 13, 13, 13,
12, 12, 13, 12, 9, 12, 13, 12, 12, 12, 13, 13, 12, 12},
{3, 5, 6, 8, 9, 10, 12, 12, 1, 5, 6, 7, 8, 9,
12, 12, 12, 4, 6, 7, 8, 9, 12, 12, 14, 21, 4, 6,
8, 9, 9, 12, 13, 13, 14, 6, 9, 8, 8, 9, 13, 14,
13, 21, 6, 9, 9, 8, 9, 10, 11, 12, 13, 8, 10, 10,
11, 11, 12, 12, 21, 21, 8, 11, 10, 11, 11, 12, 13, 14,
21, 9, 13, 10, 11, 13, 13, 12, 21, 21, 9, 12, 10, 11,
12, 12, 13, 14, 21, 11, 15, 21, 13, 14, 15, 21, 15, 21,
10, 14, 14, 13, 13, 21, 13, 13, 21, 13, 21, 21, 21, 20,
20, 14, 20, 20, 11, 14, 14, 20, 20, 13, 20, 20, 14, 16},
{2, 5, 6, 8, 9, 10, 13, 13, 2, 4, 5, 6, 8, 9,
10, 13, 14, 3, 5, 7, 8, 10, 12, 15, 20, 16, 4, 6,
8, 8, 10, 12, 13, 20, 20, 7, 8, 8, 9, 10, 11, 12,
16, 20, 7, 8, 8, 8, 10, 11, 13, 20, 20, 8, 10, 10,
10, 10, 11, 12, 15, 14, 8, 9, 9, 9, 10, 10, 13, 13,
20, 11, 12, 11, 11, 11, 13, 12, 13, 20, 11, 12, 11, 11,
12, 12, 13, 13, 20, 10, 14, 11, 11, 12, 12, 13, 20, 20,
11, 13, 12, 11, 12, 13, 14, 14, 20, 11, 19, 19, 13, 13,
15, 15, 16, 16, 11, 13, 14, 11, 13, 12, 13, 16, 16, 16}
};
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
};
......@@ -262,6 +583,112 @@ const uint8_t ff_vc1_cbpcy_p_bits[4][64] = {
}
};
/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */
const uint16_t ff_vc1_icbpcy_p_codes[8][63] = {
{
12058, 12059, 6028, 144, 680, 681, 3015, 145, 682, 683, 1504, 74, 150,
151, 189, 146, 684, 685, 1505, 152, 306, 307, 377, 308, 618, 619, 764,
78, 64, 65, 43, 147, 686, 687, 1506, 310, 622, 623, 765, 158, 318,
319, 383, 80, 66, 67, 44, 81, 164, 165, 190, 83, 68, 69, 45,
84, 70, 71, 46, 3, 0, 1, 1
}, {
65, 66, 256, 67, 136, 137, 257, 69, 140, 141, 258, 16, 34,
35, 36, 71, 16, 17, 259, 37, 88, 89, 90, 91, 90, 91, 92,
12, 48, 49, 25, 9, 20, 21, 44, 92, 93, 94, 95, 38, 93,
94, 95, 13, 52, 53, 27, 20, 39, 42, 43, 14, 56, 57, 29,
15, 60, 61, 31, 5, 9, 0, 3
}, {
50, 51, 26, 38, 228, 229, 486, 39, 230, 231, 487, 14, 99,
108, 119, 40, 232, 233, 488, 123, 218, 219, 236, 245, 440, 441, 474,
33, 75, 84, 43, 41, 234, 235, 489, 74, 442, 443, 475, 32, 222,
223, 242, 34, 85, 88, 45, 15, 112, 113, 120, 35, 89, 92, 47,
36, 93, 98, 48, 2, 31, 6, 0
}, {
40, 41, 157, 0, 490, 491, 492, 1, 493, 494, 495, 5, 240,
241, 59, 2, 496, 497, 498, 63, 348, 349, 153, 16, 976, 977, 304,
15, 158, 159, 251, 3, 499, 500, 501, 17, 978, 979, 305, 9, 350,
351, 156, 16, 168, 169, 56, 6, 242, 243, 77, 17, 170, 171, 57,
18, 172, 173, 58, 6, 22, 23, 14
}, {
60, 61, 31, 10, 97, 98, 2, 11, 99, 100, 3, 7, 3,
4, 11, 12, 101, 102, 4, 18, 10, 11, 20, 27, 24, 25, 52,
44, 103, 104, 53, 13, 105, 108, 5, 96, 26, 27, 53, 19, 14,
15, 21, 45, 109, 110, 56, 8, 8, 9, 12, 46, 111, 114, 58,
47, 115, 0, 59, 7, 20, 21, 4
}, {
56, 57, 157, 10, 145, 146, 147, 11, 148, 149, 150, 3, 238,
239, 54, 12, 151, 152, 153, 8, 484, 485, 106, 24, 972, 973, 214,
14, 158, 159, 245, 13, 154, 155, 156, 25, 974, 975, 215, 9, 488,
489, 144, 15, 232, 233, 246, 5, 240, 241, 55, 16, 234, 235, 247,
17, 236, 237, 52, 0, 62, 63, 2
}, {
60, 61, 463, 0, 191, 224, 508, 1, 225, 226, 509, 9, 497,
498, 499, 2, 227, 228, 510, 17, 1006, 1007, 1008, 33, 2018, 2019, 2020,
24, 1015, 1022, 1023, 3, 229, 230, 128, 46, 2021, 2022, 2023, 22, 1012,
1013, 1014, 25, 258, 259, 260, 10, 500, 501, 502, 26, 261, 262, 263,
27, 376, 377, 462, 29, 189, 190, 496
}, {
3, 4, 438, 4, 46, 47, 14, 5, 48, 49, 15, 3, 10,
11, 20, 6, 50, 51, 16, 5, 48, 49, 50, 9, 102, 103, 104,
29, 439, 440, 441, 7, 52, 53, 17, 22, 105, 106, 107, 10, 54,
55, 216, 30, 442, 443, 444, 4, 21, 22, 23, 31, 445, 446, 447,
0, 16, 17, 18, 28, 217, 218, 19
}
};
const uint8_t ff_vc1_icbpcy_p_bits[8][63] = {
{
15, 15, 14, 9, 11, 11, 13, 9, 11, 11, 12, 8, 9,
9, 9, 9, 11, 11, 12, 9, 10, 10, 10, 10, 11, 11, 11,
8, 8, 8, 7, 9, 11, 11, 12, 10, 11, 11, 11, 9, 10,
10, 10, 8, 8, 8, 7, 8, 9, 9, 9, 8, 8, 8, 7,
8, 8, 8, 7, 3, 3, 3, 1
}, {
7, 7, 9, 7, 8, 8, 9, 7, 8, 8, 9, 6, 7,
7, 7, 7, 7, 7, 9, 7, 8, 8, 8, 8, 9, 9, 9,
6, 7, 7, 6, 6, 7, 7, 8, 8, 9, 9, 9, 7, 8,
8, 8, 6, 7, 7, 6, 6, 7, 7, 7, 6, 7, 7, 6,
6, 7, 7, 6, 3, 4, 3, 2
}, {
6, 6, 5, 6, 8, 8, 9, 6, 8, 8, 9, 5, 7,
7, 7, 6, 8, 8, 9, 7, 8, 8, 8, 8, 9, 9, 9,
6, 7, 7, 6, 6, 8, 8, 9, 7, 9, 9, 9, 6, 8,
8, 8, 6, 7, 7, 6, 5, 7, 7, 7, 6, 7, 7, 6,
6, 7, 7, 6, 3, 5, 4, 2
}, {
6, 6, 8, 4, 9, 9, 9, 4, 9, 9, 9, 4, 8,
8, 7, 4, 9, 9, 9, 6, 9, 9, 8, 6, 10, 10, 9,
5, 8, 8, 8, 4, 9, 9, 9, 6, 10, 10, 9, 5, 9,
9, 8, 5, 8, 8, 7, 4, 8, 8, 7, 5, 8, 8, 7,
5, 8, 8, 7, 3, 5, 5, 4
}, {
6, 6, 5, 5, 7, 7, 7, 5, 7, 7, 7, 5, 6,
6, 6, 5, 7, 7, 7, 6, 7, 7, 7, 7, 8, 8, 8,
6, 7, 7, 6, 5, 7, 7, 7, 7, 8, 8, 8, 6, 7,
7, 7, 6, 7, 7, 6, 5, 6, 6, 6, 6, 7, 7, 6,
6, 7, 6, 6, 4, 5, 5, 3
}, {
6, 6, 8, 4, 8, 8, 8, 4, 8, 8, 8, 4, 8,
8, 7, 4, 8, 8, 8, 5, 9, 9, 8, 6, 10, 10, 9,
5, 8, 8, 8, 4, 8, 8, 8, 6, 10, 10, 9, 5, 9,
9, 8, 5, 8, 8, 8, 4, 8, 8, 7, 5, 8, 8, 8,
5, 8, 8, 7, 3, 6, 6, 4
}, {
6, 6, 9, 3, 8, 8, 9, 3, 8, 8, 9, 4, 9,
9, 9, 3, 8, 8, 9, 5, 10, 10, 10, 6, 11, 11, 11,
5, 10, 10, 10, 3, 8, 8, 8, 6, 11, 11, 11, 5, 10,
10, 10, 5, 9, 9, 9, 4, 9, 9, 9, 5, 9, 9, 9,
5, 9, 9, 9, 5, 8, 8, 9
}, {
6, 6, 10, 3, 7, 7, 7, 3, 7, 7, 7, 4, 8,
8, 8, 3, 7, 7, 7, 5, 9, 9, 9, 6, 10, 10, 10,
6, 10, 10, 10, 3, 7, 7, 7, 6, 10, 10, 10, 5, 9,
9, 9, 6, 10, 10, 10, 4, 8, 8, 8, 6, 10, 10, 10,
5, 9, 9, 9, 6, 9, 9, 9
}
};
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
* 8x4:B:btm 8x4:B:top 8x4:B:both,
......@@ -520,3 +947,38 @@ const int32_t ff_vc1_dqscale[63] = {
0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249,
0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000
};
/* P Interlaced field picture MV predictor scaling values (Table 114) */
const uint16_t vc1_field_mvpred_scales[2][7][4] = {
// Refdist 0 1 2 3 or greater
{ // current field is first
{ 128, 192, 213, 224}, // SCALEOPP
{ 512, 341, 307, 293}, // SCALESAME1
{ 219, 236, 242, 245}, // SCALESAME2
{ 32, 48, 53, 56}, // SCALEZONE1_X
{ 8, 12, 13, 14}, // SCALEZONE1_Y
{ 37, 20, 14, 11}, // ZONE1OFFSET_X
{ 10, 5, 4, 3} // ZONE1OFFSET_Y
},
{ // current field is second
{ 128, 64, 43, 32}, // SCALEOPP
{ 512, 1024, 1536, 2048}, // SCALESAME1
{ 219, 204, 200, 198}, // SCALESAME2
{ 32, 16, 11, 8}, // SCALEZONE1_X
{ 8, 4, 3, 2}, // SCALEZONE1_Y
{ 37, 52, 56, 58}, // ZONE1OFFSET_X
{ 10, 13, 14, 15} // ZONE1OFFSET_Y
}
};
/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */
const uint16_t vc1_b_field_mvpred_scales[7][4] = {
// BRFD 0 1 2 3 or greater
{ 171, 205, 219, 228}, // SCALESAME
{ 384, 320, 299, 288}, // SCALEOPP1
{ 230, 239, 244, 246}, // SCALEOPP2
{ 43, 51, 55, 57}, // SCALEZONE1_X
{ 11, 13, 14, 14}, // SCALEZONE1_Y
{ 26, 17, 12, 10}, // ZONE1OFFSET_X
{ 7, 4, 3, 3} // ZONE1OFFSET_Y
};
......@@ -44,6 +44,9 @@ 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];
/* MBMODE table for interlaced frame P-picture */
extern const uint8_t ff_vc1_mbmode_intfrp[2][15][4];
/** @name VC-1 VLC tables and defines
* @todo TODO move this into the context
*/
......@@ -63,14 +66,32 @@ extern VLC ff_vc1_ttmb_vlc[3];
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_ICBPCY_VLC_BITS 9
extern VLC ff_vc1_icbpcy_vlc[8];
#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6
extern VLC ff_vc1_4mv_block_pattern_vlc[4];
#define VC1_2MV_BLOCK_PATTERN_VLC_BITS 3
extern VLC ff_vc1_2mv_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];
#define VC1_INTFR_4MV_MBMODE_VLC_BITS 9
extern VLC ff_vc1_intfr_4mv_mbmode_vlc[4];
#define VC1_INTFR_NON4MV_MBMODE_VLC_BITS 6
extern VLC ff_vc1_intfr_non4mv_mbmode_vlc[4];
#define VC1_IF_MMV_MBMODE_VLC_BITS 5
extern VLC ff_vc1_if_mmv_mbmode_vlc[8];
#define VC1_IF_1MV_MBMODE_VLC_BITS 5
extern VLC ff_vc1_if_1mv_mbmode_vlc[8];
#define VC1_1REF_MVDATA_VLC_BITS 9
extern VLC ff_vc1_1ref_mvdata_vlc[4];
#define VC1_2REF_MVDATA_VLC_BITS 9
extern VLC ff_vc1_2ref_mvdata_vlc[8];
extern VLC ff_vc1_ac_coeff_table[8];
#define VC1_IF_MBMODE_VLC_BITS 5
//@}
......@@ -101,12 +122,20 @@ extern const uint8_t ff_vc1_norm6_spec[64][5];
extern const uint8_t ff_vc1_4mv_block_pattern_codes[4][16];
extern const uint8_t ff_vc1_4mv_block_pattern_bits[4][16];
/* 2MV Block pattern VLC tables */
extern const uint8_t ff_vc1_2mv_block_pattern_codes[4][4];
extern const uint8_t ff_vc1_2mv_block_pattern_bits[4][4];
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];
/* Interlaced CBPCY VLC tables (Table 124 - Table 131) */
extern const uint16_t ff_vc1_icbpcy_p_codes[8][63];
extern const uint8_t ff_vc1_icbpcy_p_bits[8][63];
/* MacroBlock Transform Type: 7.1.3.11, p89
* 8x8:B
* 8x4:B:btm 8x4:B:top 8x4:B:both,
......@@ -131,6 +160,26 @@ extern const uint8_t ff_vc1_subblkpat_bits[3][15];
extern const uint16_t ff_vc1_mv_diff_codes[4][73];
extern const uint8_t ff_vc1_mv_diff_bits[4][73];
/* Interlaced frame picture MBMODE VLC tables (p. 246, p. 360) */
extern const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15];
extern const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15];
extern const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9];
extern const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9];
/* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
extern const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8];
extern const uint8_t ff_vc1_if_mmv_mbmode_bits[8][8];
extern const uint8_t ff_vc1_if_1mv_mbmode_codes[8][6];
extern const uint8_t ff_vc1_if_1mv_mbmode_bits[8][6];
/* Interlaced frame/field picture MVDATA VLC tables */
/* 1-reference tables */
extern const uint32_t ff_vc1_1ref_mvdata_codes[4][72];
extern const uint8_t ff_vc1_1ref_mvdata_bits[4][72];
/* 2-reference tables */
extern const uint32_t ff_vc1_2ref_mvdata_codes[8][126];
extern const uint8_t ff_vc1_2ref_mvdata_bits[8][126];
/* 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) */
......@@ -141,8 +190,14 @@ 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];
extern const int8_t ff_vc1_intra_horz_8x8_zz [64];
extern const int8_t ff_vc1_intra_vert_8x8_zz [64];
/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
extern const int32_t ff_vc1_dqscale[63];
/* P Interlaced field picture MV predictor scaling values (Table 114) */
extern const uint16_t vc1_field_mvpred_scales[2][7][4];
/* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */
extern const uint16_t vc1_b_field_mvpred_scales[7][4];
#endif /* AVCODEC_VC1DATA_H */
/*
* VC-1 and WMV3 decoder
* Copyright (c) 2011 Mashiat Sarker Shakkhar
* Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
......@@ -48,11 +49,19 @@
static const uint16_t vlc_offs[] = {
0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436,
2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8620,
9262, 10202, 10756, 11310, 12228, 15078
0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436,
2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8342,
9304, 9988, 10630, 11234, 12174, 13006, 13560, 14232, 14786, 15432, 16350, 17522,
20372, 21818, 22330, 22394, 23166, 23678, 23742, 24820, 25332, 25396, 26460, 26980,
27048, 27592, 27600, 27608, 27616, 27624, 28224, 28258, 28290, 28802, 28834, 28866,
29378, 29412, 29444, 29960, 29994, 30026, 30538, 30572, 30604, 31120, 31154, 31186,
31714, 31746, 31778, 32306, 32340, 32372
};
// offset tables for interlaced picture MVDATA decoding
static const int offset_table1[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128};
static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255};
/**
* Init VC-1 specific tables and VC1Context members
* @param v The VC1Context to initialize
......@@ -62,7 +71,7 @@ static int vc1_init_common(VC1Context *v)
{
static int done = 0;
int i = 0;
static VLC_TYPE vlc_table[15078][2];
static VLC_TYPE vlc_table[32372][2];
v->hrd_rate = v->hrd_buffer = NULL;
......@@ -118,11 +127,64 @@ static int vc1_init_common(VC1Context *v)
ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
}
for(i=0; i<8; i++){
ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i+21]];
ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i+22] - vlc_offs[i+21];
ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i*2+21]];
ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i*2+22] - vlc_offs[i*2+21];
init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i],
&vc1_ac_tables[i][0][1], 8, 4,
&vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC);
/* initialize interlaced MVDATA tables (2-Ref) */
ff_vc1_2ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i*2+22]];
ff_vc1_2ref_mvdata_vlc[i].table_allocated = vlc_offs[i*2+23] - vlc_offs[i*2+22];
init_vlc(&ff_vc1_2ref_mvdata_vlc[i], VC1_2REF_MVDATA_VLC_BITS, 126,
ff_vc1_2ref_mvdata_bits[i], 1, 1,
ff_vc1_2ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC);
}
for (i=0; i<4; i++) {
/* initialize 4MV MBMODE VLC tables for interlaced frame P picture */
ff_vc1_intfr_4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+37]];
ff_vc1_intfr_4mv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+38] - vlc_offs[i*3+37];
init_vlc(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15,
ff_vc1_intfr_4mv_mbmode_bits[i], 1, 1,
ff_vc1_intfr_4mv_mbmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
/* initialize NON-4MV MBMODE VLC tables for the same */
ff_vc1_intfr_non4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+38]];
ff_vc1_intfr_non4mv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+39] - vlc_offs[i*3+38];
init_vlc(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9,
ff_vc1_intfr_non4mv_mbmode_bits[i], 1, 1,
ff_vc1_intfr_non4mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
/* initialize interlaced MVDATA tables (1-Ref) */
ff_vc1_1ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i*3+39]];
ff_vc1_1ref_mvdata_vlc[i].table_allocated = vlc_offs[i*3+40] - vlc_offs[i*3+39];
init_vlc(&ff_vc1_1ref_mvdata_vlc[i], VC1_1REF_MVDATA_VLC_BITS, 72,
ff_vc1_1ref_mvdata_bits[i], 1, 1,
ff_vc1_1ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC);
}
for (i=0; i<4; i++) {
/* Initialize 2MV Block pattern VLC tables */
ff_vc1_2mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i+49]];
ff_vc1_2mv_block_pattern_vlc[i].table_allocated = vlc_offs[i+50] - vlc_offs[i+49];
init_vlc(&ff_vc1_2mv_block_pattern_vlc[i], VC1_2MV_BLOCK_PATTERN_VLC_BITS, 4,
ff_vc1_2mv_block_pattern_bits[i], 1, 1,
ff_vc1_2mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
}
for (i=0; i<8; i++) {
/* Initialize interlaced CBPCY VLC tables (Table 124 - Table 131) */
ff_vc1_icbpcy_vlc[i].table = &vlc_table[vlc_offs[i*3+53]];
ff_vc1_icbpcy_vlc[i].table_allocated = vlc_offs[i*3+54] - vlc_offs[i*3+53];
init_vlc(&ff_vc1_icbpcy_vlc[i], VC1_ICBPCY_VLC_BITS, 63,
ff_vc1_icbpcy_p_bits[i], 1, 1,
ff_vc1_icbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
/* Initialize interlaced field picture MBMODE VLC tables */
ff_vc1_if_mmv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+54]];
ff_vc1_if_mmv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+55] - vlc_offs[i*3+54];
init_vlc(&ff_vc1_if_mmv_mbmode_vlc[i], VC1_IF_MMV_MBMODE_VLC_BITS, 8,
ff_vc1_if_mmv_mbmode_bits[i], 1, 1,
ff_vc1_if_mmv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
ff_vc1_if_1mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i*3+55]];
ff_vc1_if_1mv_mbmode_vlc[i].table_allocated = vlc_offs[i*3+56] - vlc_offs[i*3+55];
init_vlc(&ff_vc1_if_1mv_mbmode_vlc[i], VC1_IF_1MV_MBMODE_VLC_BITS, 6,
ff_vc1_if_1mv_mbmode_bits[i], 1, 1,
ff_vc1_if_1mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
}
done = 1;
}
......@@ -162,6 +224,9 @@ enum Imode {
static void vc1_put_signed_blocks_clamped(VC1Context *v)
{
MpegEncContext *s = &v->s;
int topleft_mb_pos, top_mb_pos;
int stride_y, fieldtx;
int v_dist;
/* The put pixels loop is always one MB row behind the decoding loop,
* because we can only put pixels when overlap filtering is done, and
......@@ -172,18 +237,22 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
* of the right MB edge, we need the next MB present. */
if (!s->first_slice_line) {
if (s->mb_x) {
topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
fieldtx = v->fieldtx_plane[topleft_mb_pos];
stride_y = (s->linesize) << fieldtx;
v_dist = (16 - fieldtx) >> (fieldtx == 0);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
s->dest[0] - 16 * s->linesize - 16,
s->linesize);
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
s->dest[0] - 16 * s->linesize - 8,
s->linesize);
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
s->dest[0] - 8 * s->linesize - 16,
s->linesize);
s->dest[0] - v_dist * s->linesize - 16,
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3],
s->dest[0] - 8 * s->linesize - 8,
s->linesize);
s->dest[0] - v_dist * s->linesize - 8,
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4],
s->dest[1] - 8 * s->uvlinesize - 8,
s->uvlinesize);
......@@ -192,18 +261,22 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
s->uvlinesize);
}
if (s->mb_x == s->mb_width - 1) {
top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
fieldtx = v->fieldtx_plane[top_mb_pos];
stride_y = s->linesize << fieldtx;
v_dist = fieldtx ? 15 : 8;
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
s->dest[0] - 16 * s->linesize,
s->linesize);
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
s->dest[0] - 16 * s->linesize + 8,
s->linesize);
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
s->dest[0] - 8 * s->linesize,
s->linesize);
s->dest[0] - v_dist * s->linesize,
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3],
s->dest[0] - 8 * s->linesize + 8,
s->linesize);
s->dest[0] - v_dist * s->linesize + 8,
stride_y);
s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4],
s->dest[1] - 8 * s->uvlinesize,
s->uvlinesize);
......@@ -406,33 +479,61 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
DSPContext *dsp = &v->s.dsp;
uint8_t *srcY, *srcU, *srcV;
int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
if(!v->s.last_picture.f.data[0])return;
int off, off_uv;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
if (!v->field_mode && !v->s.last_picture.f.data[0])
return;
mx = s->mv[dir][0][0];
my = s->mv[dir][0][1];
// store motion vectors for further use in B frames
if(s->pict_type == AV_PICTURE_TYPE_P) {
s->current_picture.f.motion_val[1][s->block_index[0]][0] = mx;
s->current_picture.f.motion_val[1][s->block_index[0]][1] = my;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my;
}
uvmx = (mx + ((mx & 3) == 3)) >> 1;
uvmy = (my + ((my & 3) == 3)) >> 1;
v->luma_mv[s->mb_x][0] = uvmx;
v->luma_mv[s->mb_x][1] = uvmy;
if(v->fastuvmc) {
if (v->field_mode &&
v->cur_field_type != v->ref_field_type[dir]) {
my = my - 2 + 4 * v->cur_field_type;
uvmy = uvmy - 2 + 4 * v->cur_field_type;
}
if(v->fastuvmc && (v->fcm != 1)) { // fastuvmc shall be ignored for interlaced frame picture
uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
}
if(!dir) {
srcY = s->last_picture.f.data[0];
srcU = s->last_picture.f.data[1];
srcV = s->last_picture.f.data[2];
if (v->field_mode) { // interlaced field picture
if (!dir) {
if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) {
srcY = s->current_picture.f.data[0];
srcU = s->current_picture.f.data[1];
srcV = s->current_picture.f.data[2];
} else {
srcY = s->last_picture.f.data[0];
srcU = s->last_picture.f.data[1];
srcV = s->last_picture.f.data[2];
}
} else {
srcY = s->next_picture.f.data[0];
srcU = s->next_picture.f.data[1];
srcV = s->next_picture.f.data[2];
}
} else {
srcY = s->next_picture.f.data[0];
srcU = s->next_picture.f.data[1];
srcV = s->next_picture.f.data[2];
if(!dir) {
srcY = s->last_picture.f.data[0];
srcU = s->last_picture.f.data[1];
srcV = s->last_picture.f.data[2];
} else {
srcY = s->next_picture.f.data[0];
srcU = s->next_picture.f.data[1];
srcV = s->next_picture.f.data[2];
}
}
src_x = s->mb_x * 16 + (mx >> 2);
......@@ -456,6 +557,12 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
if (v->field_mode && v->ref_field_type[dir]) {
srcY += s->current_picture_ptr->f.linesize[0];
srcU += s->current_picture_ptr->f.linesize[1];
srcV += s->current_picture_ptr->f.linesize[2];
}
/* for grayscale we should not try to read from unknown area */
if(s->flags & CODEC_FLAG_GRAY) {
srcU = s->edge_emu_buffer + 18 * s->linesize;
......@@ -464,17 +571,17 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3
|| (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){
|| (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel*3){
uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;
srcY -= s->mspel * (1 + s->linesize);
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2,
src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, v_edge_pos);
srcY = s->edge_emu_buffer;
s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
/* if we deal with range reduction we need to scale source blocks */
......@@ -520,20 +627,26 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
srcY += s->mspel * (1 + s->linesize);
}
if (v->field_mode && v->cur_field_type) {
off = s->current_picture_ptr->f.linesize[0];
off_uv = s->current_picture_ptr->f.linesize[1];
} else {
off = 0;
off_uv = 0;
}
if(s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
srcY += s->linesize * 8;
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
} else { // hpel mc - always used for luma
dxy = (my & 2) | ((mx & 2) >> 1);
if(!v->rnd)
dsp->put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
dsp->put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
else
dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
}
if(s->flags & CODEC_FLAG_GRAY) return;
......@@ -541,50 +654,147 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
uvmx = (uvmx&3)<<1;
uvmy = (uvmy&3)<<1;
if(!v->rnd){
dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
}else{
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
}
}
static inline int median4(int a, int b, int c, int d)
{
if(a < b) {
if(c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
} else {
if(c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
}
}
/** Do motion compensation for 4-MV macroblock - luminance block
*/
static void vc1_mc_4mv_luma(VC1Context *v, int n)
static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
{
MpegEncContext *s = &v->s;
DSPContext *dsp = &v->s.dsp;
uint8_t *srcY;
int dxy, mx, my, src_x, src_y;
int off;
int fieldmv = (v->fcm == 1) ? v->blk_mv_type[s->block_index[n]] : 0;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
if(!v->field_mode && !v->s.last_picture.f.data[0])return;
mx = s->mv[dir][n][0];
my = s->mv[dir][n][1];
if (!dir) {
if (v->field_mode) {
if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type)
srcY = s->current_picture.f.data[0];
else
srcY = s->last_picture.f.data[0];
} else
srcY = s->last_picture.f.data[0];
} else
srcY = s->next_picture.f.data[0];
if(!v->s.last_picture.f.data[0])return;
mx = s->mv[0][n][0];
my = s->mv[0][n][1];
srcY = s->last_picture.f.data[0];
off = s->linesize * 4 * (n&2) + (n&1) * 8;
if (v->field_mode) {
if (v->cur_field_type != v->ref_field_type[dir])
my = my - 2 + 4 * v->cur_field_type;
}
if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
int same_count = 0, opp_count = 0, k;
int chosen_mv[2][4][2], f;
int tx, ty;
for (k = 0; k < 4; k++) {
f = v->mv_f[0][s->block_index[k] + v->blocks_off];
chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];
chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];
opp_count += f;
same_count += 1 - f;
}
f = opp_count > same_count;
switch (f ? opp_count : same_count) {
case 4:
tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0], chosen_mv[f][3][0]);
ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1], chosen_mv[f][3][1]);
break;
case 3:
tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);
ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);
break;
case 2:
tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;
ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
break;
}
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
for (k = 0; k < 4; k++) v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
}
if (v->fcm == 1) { // not sure if needed for other types of picture
int qx, qy;
int width = s->avctx->coded_width;
int height = s->avctx->coded_height >> 1;
qx = (s->mb_x * 16) + (mx >> 2);
qy = (s->mb_y * 8) + (my >> 3);
if (qx < -17)
mx -= 4 * (qx + 17);
else if (qx > width)
mx -= 4 * (qx - width);
if (qy < -18)
my -= 8 * (qy + 18);
else if (qy > height + 1)
my -= 8 * (qy - height - 1);
}
if ((v->fcm == 1) && fieldmv)
off = ((n>1) ? s->linesize : 0) + (n&1) * 8;
else
off = s->linesize * 4 * (n&2) + (n&1) * 8;
if (v->field_mode && v->cur_field_type)
off += s->current_picture_ptr->f.linesize[0];
src_x = s->mb_x * 16 + (n&1) * 8 + (mx >> 2);
src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2);
if (!fieldmv)
src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2);
else
src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
if(v->profile != PROFILE_ADVANCED){
src_x = av_clip( src_x, -16, s->mb_width * 16);
src_y = av_clip( src_y, -16, s->mb_height * 16);
}else{
src_x = av_clip( src_x, -17, s->avctx->coded_width);
src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
if (v->fcm == 1) {
if (src_y & 1)
src_y = av_clip( src_y, -17, s->avctx->coded_height + 1);
else
src_y = av_clip( src_y, -18, s->avctx->coded_height);
} else {
src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
}
}
srcY += src_y * s->linesize + src_x;
if (v->field_mode && v->ref_field_type[dir])
srcY += s->current_picture_ptr->f.linesize[0];
if (fieldmv && !(src_y & 1))
v_edge_pos--;
if (fieldmv && (src_y & 1) && src_y < 4)
src_y--;
if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 8 - s->mspel*2
|| (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 8 - s->mspel*2){
srcY -= s->mspel * (1 + s->linesize);
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, 9+s->mspel*2,
src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
|| (unsigned)(src_y - (s->mspel<<fieldmv)) > v_edge_pos - (my&3) - ((8 + s->mspel*2)<<fieldmv)){
srcY -= s->mspel * (1 + (s->linesize << fieldmv));
/* check emulate edge stride and offset */
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, (9+s->mspel*2) << fieldmv, src_x - s->mspel,
src_y - (s->mspel << fieldmv), s->h_edge_pos, v_edge_pos);
srcY = s->edge_emu_buffer;
/* if we deal with range reduction we need to scale source blocks */
if(v->rangeredfrm) {
......@@ -594,7 +804,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n)
src = srcY;
for(j = 0; j < 9 + s->mspel*2; j++) {
for(i = 0; i < 9 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
src += s->linesize;
src += s->linesize << fieldmv;
}
}
/* if we deal with intensity compensation we need to scale source blocks */
......@@ -605,15 +815,15 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n)
src = srcY;
for(j = 0; j < 9 + s->mspel*2; j++) {
for(i = 0; i < 9 + s->mspel*2; i++) src[i] = v->luty[src[i]];
src += s->linesize;
src += s->linesize << fieldmv;
}
}
srcY += s->mspel * (1 + s->linesize);
srcY += s->mspel * (1 + (s->linesize << fieldmv));
}
if(s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, v->rnd);
v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
} else { // hpel mc - always used for luma
dxy = (my & 2) | ((mx & 2) >> 1);
if(!v->rnd)
......@@ -623,86 +833,108 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n)
}
}
static inline int median4(int a, int b, int c, int d)
static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag, int *tx, int *ty)
{
if(a < b) {
if(c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
int idx, i;
static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
idx = ((a[3] != flag) << 3) | ((a[2] != flag) << 2) | ((a[1] != flag) << 1) | (a[0] != flag);
if(!idx) {
*tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
*ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
return 4;
} else if(count[idx] == 1) {
switch(idx) {
case 0x1:
*tx = mid_pred(mvx[1], mvx[2], mvx[3]);
*ty = mid_pred(mvy[1], mvy[2], mvy[3]);
return 3;
case 0x2:
*tx = mid_pred(mvx[0], mvx[2], mvx[3]);
*ty = mid_pred(mvy[0], mvy[2], mvy[3]);
return 3;
case 0x4:
*tx = mid_pred(mvx[0], mvx[1], mvx[3]);
*ty = mid_pred(mvy[0], mvy[1], mvy[3]);
return 3;
case 0x8:
*tx = mid_pred(mvx[0], mvx[1], mvx[2]);
*ty = mid_pred(mvy[0], mvy[1], mvy[2]);
return 3;
}
} else if(count[idx] == 2) {
int t1 = 0, t2 = 0;
for (i = 0; i < 3; i++)
if (!a[i]) {
t1 = i;
break;
}
for (i = t1 + 1; i < 4; i++)
if (!a[i]) {
t2 = i;
break;
}
*tx = (mvx[t1] + mvx[t2]) / 2;
*ty = (mvy[t1] + mvy[t2]) / 2;
return 2;
} else {
if(c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
return 0;
}
return -1;
}
/** Do motion compensation for 4-MV macroblock - both chroma blocks
*/
static void vc1_mc_4mv_chroma(VC1Context *v)
static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
{
MpegEncContext *s = &v->s;
DSPContext *dsp = &v->s.dsp;
uint8_t *srcU, *srcV;
int uvmx, uvmy, uvsrc_x, uvsrc_y;
int i, idx, tx = 0, ty = 0;
int mvx[4], mvy[4], intra[4];
static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
int k, tx = 0, ty = 0;
int mvx[4], mvy[4], intra[4], mv_f[4];
int valid_count;
int chroma_ref_type = v->cur_field_type, off = 0;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
if(!v->s.last_picture.f.data[0])return;
if(!v->field_mode && !v->s.last_picture.f.data[0])return;
if(s->flags & CODEC_FLAG_GRAY) return;
for(i = 0; i < 4; i++) {
mvx[i] = s->mv[0][i][0];
mvy[i] = s->mv[0][i][1];
intra[i] = v->mb_type[0][s->block_index[i]];
for(k = 0; k < 4; k++) {
mvx[k] = s->mv[dir][k][0];
mvy[k] = s->mv[dir][k][1];
intra[k] = v->mb_type[0][s->block_index[k]];
if (v->field_mode)
mv_f[k] = v->mv_f[dir][s->block_index[k] + v->blocks_off];
}
/* calculate chroma MV vector from four luma MVs */
idx = (intra[3] << 3) | (intra[2] << 2) | (intra[1] << 1) | intra[0];
if(!idx) { // all blocks are inter
tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]);
ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]);
} else if(count[idx] == 1) { // 3 inter blocks
switch(idx) {
case 0x1:
tx = mid_pred(mvx[1], mvx[2], mvx[3]);
ty = mid_pred(mvy[1], mvy[2], mvy[3]);
break;
case 0x2:
tx = mid_pred(mvx[0], mvx[2], mvx[3]);
ty = mid_pred(mvy[0], mvy[2], mvy[3]);
break;
case 0x4:
tx = mid_pred(mvx[0], mvx[1], mvx[3]);
ty = mid_pred(mvy[0], mvy[1], mvy[3]);
break;
case 0x8:
tx = mid_pred(mvx[0], mvx[1], mvx[2]);
ty = mid_pred(mvy[0], mvy[1], mvy[2]);
break;
if (!v->field_mode || (v->field_mode && !v->numref)) {
valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
if (!valid_count) {
v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
return; //no need to do MC for intra blocks
}
} else if(count[idx] == 2) {
int t1 = 0, t2 = 0;
for(i=0; i<3;i++) if(!intra[i]) {t1 = i; break;}
for(i= t1+1; i<4; i++)if(!intra[i]) {t2 = i; break;}
tx = (mvx[t1] + mvx[t2]) / 2;
ty = (mvy[t1] + mvy[t2]) / 2;
} else {
s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
return; //no need to do MC for inter blocks
int dominant = 0;
if (mv_f[0] + mv_f[1] + mv_f[2] + mv_f[3] > 2)
dominant = 1;
valid_count = get_chroma_mv(mvx, mvy, mv_f, dominant, &tx, &ty);
if (dominant)
chroma_ref_type = !v->cur_field_type;
}
s->current_picture.f.motion_val[1][s->block_index[0]][0] = tx;
s->current_picture.f.motion_val[1][s->block_index[0]][1] = ty;
uvmx = (tx + ((tx&3) == 3)) >> 1;
uvmy = (ty + ((ty&3) == 3)) >> 1;
v->luma_mv[s->mb_x][0] = uvmx;
v->luma_mv[s->mb_x][1] = uvmy;
if(v->fastuvmc) {
uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
}
// Field conversion bias
if (v->cur_field_type != chroma_ref_type)
uvmy += 2 - 4 * chroma_ref_type;
uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
......@@ -715,15 +947,39 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
}
srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
if (!dir) {
if (v->field_mode) {
if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) {
srcU = s->current_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->current_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
} else {
srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
}
} else {
srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
}
} else {
srcU = s->next_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
}
if (v->field_mode) {
if (chroma_ref_type) {
srcU += s->current_picture_ptr->f.linesize[1];
srcV += s->current_picture_ptr->f.linesize[2];
}
off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0;
}
if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
|| (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){
|| (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9){
s->dsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = s->edge_emu_buffer;
srcV = s->edge_emu_buffer + 16;
......@@ -763,11 +1019,89 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
uvmx = (uvmx&3)<<1;
uvmy = (uvmy&3)<<1;
if(!v->rnd){
dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
}else{
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
}
}
/** Do motion compensation for 4-MV field chroma macroblock (both U and V)
*/
static void vc1_mc_4mv_chroma4(VC1Context *v)
{
MpegEncContext *s = &v->s;
DSPContext *dsp = &v->s.dsp;
uint8_t *srcU, *srcV;
int uvsrc_x, uvsrc_y;
int uvmx_field[4], uvmy_field[4];
int i, off, tx, ty;
int fieldmv = v->blk_mv_type[s->block_index[0]];
static const int s_rndtblfield[16] = {0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12};
int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
int v_edge_pos = s->v_edge_pos >> 1;
if (!v->s.last_picture.f.data[0]) return;
if (s->flags & CODEC_FLAG_GRAY) return;
for (i = 0; i < 4; i++) {
tx = s->mv[0][i][0];
uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
ty = s->mv[0][i][1];
if (fieldmv)
uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
else
uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
}
for (i = 0; i < 4; i++) {
off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2);
uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2);
// FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
uvmx_field[i] = (uvmx_field[i] & 3) << 1;
uvmy_field[i] = (uvmy_field[i] & 3) << 1;
if (fieldmv && !(uvsrc_y & 1))
v_edge_pos--;
if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
uvsrc_y--;
if((v->mv_mode == MV_PMODE_INTENSITY_COMP)
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
|| (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)){
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize, 5, (5 << fieldmv), uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos);
s->dsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 5, (5 << fieldmv), uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos);
srcU = s->edge_emu_buffer;
srcV = s->edge_emu_buffer + 16;
/* if we deal with intensity compensation we need to scale source blocks */
if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int i, j;
uint8_t *src, *src2;
src = srcU; src2 = srcV;
for(j = 0; j < 5; j++) {
for(i = 0; i < 5; i++) {
src[i] = v->lutuv[src[i]];
src2[i] = v->lutuv[src2[i]];
}
src += s->uvlinesize << 1;
src2 += s->uvlinesize << 1;
}
}
}
if (!v->rnd) {
dsp->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
dsp->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
} else {
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
}
}
}
......@@ -865,16 +1199,249 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
_dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \
}
static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, int *dmv_y, int *pred_flag)
{
int index, index1;
int extend_x = 0, extend_y = 0;
GetBitContext *gb = &v->s.gb;
int bits, esc;
int val, sign;
const int* offs_tab;
if (v->numref) {
bits = VC1_2REF_MVDATA_VLC_BITS;
esc = 125;
} else {
bits = VC1_1REF_MVDATA_VLC_BITS;
esc = 71;
}
switch (v->dmvrange) {
case 1:
extend_x = 1;
break;
case 2:
extend_y = 1;
break;
case 3:
extend_x = extend_y = 1;
break;
}
index = get_vlc2(gb, v->imv_vlc->table, bits, 3);
if (index == esc) {
*dmv_x = get_bits(gb, v->k_x);
*dmv_y = get_bits(gb, v->k_y);
if (v->numref) {
*pred_flag = *dmv_y & 1;
*dmv_y = (*dmv_y + *pred_flag) >> 1;
}
}
else {
if (extend_x)
offs_tab = offset_table2;
else
offs_tab = offset_table1;
index1 = (index + 1) % 9;
if (index1 != 0) {
val = get_bits(gb, index1 + extend_x);
sign = 0 -(val & 1);
*dmv_x = (sign ^ ((val >> 1) + offs_tab[index1])) - sign;
} else
*dmv_x = 0;
if (extend_y)
offs_tab = offset_table2;
else
offs_tab = offset_table1;
index1 = (index + 1) / 9;
if (index1 > v->numref) {
val = get_bits(gb, (index1 + (extend_y << v->numref)) >> v->numref);
sign = 0 - (val & 1);
*dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
} else
*dmv_y = 0;
if (v->numref)
*pred_flag = index1 & 1;
}
}
static av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir)
{
int scaledvalue, refdist;
int scalesame1, scalesame2;
int scalezone1_x, zone1offset_x;
if (v->s.pict_type != AV_PICTURE_TYPE_B)
refdist = v->refdist;
else
refdist = dir ? v->brfd : v->frfd;
if (refdist > 3)
refdist = 3;
scalesame1 = vc1_field_mvpred_scales[v->second_field][1][refdist];
scalesame2 = vc1_field_mvpred_scales[v->second_field][2][refdist];
scalezone1_x = vc1_field_mvpred_scales[v->second_field][3][refdist];
zone1offset_x = vc1_field_mvpred_scales[v->second_field][5][refdist];
if (FFABS(n) > 255)
scaledvalue = n;
else {
if (FFABS(n) < scalezone1_x)
scaledvalue = (n * scalesame1) >> 8;
else {
if (n < 0)
scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
else
scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
}
}
return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
}
static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir)
{
int scaledvalue, refdist;
int scalesame1, scalesame2;
int scalezone1_y, zone1offset_y;
if (v->s.pict_type != AV_PICTURE_TYPE_B)
refdist = v->refdist;
else
refdist = dir ? v->brfd : v->frfd;
if (refdist > 3)
refdist = 3;
scalesame1 = vc1_field_mvpred_scales[v->second_field][1][refdist];
scalesame2 = vc1_field_mvpred_scales[v->second_field][2][refdist];
scalezone1_y = vc1_field_mvpred_scales[v->second_field][4][refdist];
zone1offset_y = vc1_field_mvpred_scales[v->second_field][6][refdist];
if (FFABS(n) > 63)
scaledvalue = n;
else {
if (FFABS(n) < scalezone1_y)
scaledvalue = (n * scalesame1) >> 8;
else {
if (n < 0)
scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
else
scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
}
}
if (v->cur_field_type && !v->ref_field_type[dir])
return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
else
return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
}
static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
{
int scalezone1_x, zone1offset_x;
int scaleopp1, scaleopp2, brfd;
int scaledvalue;
brfd = FFMIN(v->brfd, 3);
scalezone1_x = vc1_b_field_mvpred_scales[3][brfd];
zone1offset_x = vc1_b_field_mvpred_scales[5][brfd];
scaleopp1 = vc1_b_field_mvpred_scales[1][brfd];
scaleopp2 = vc1_b_field_mvpred_scales[2][brfd];
if (FFABS(n) > 255)
scaledvalue = n;
else {
if (FFABS(n) < scalezone1_x)
scaledvalue = (n * scaleopp1) >> 8;
else {
if (n < 0)
scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
else
scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
}
}
return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
}
static av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir)
{
int scalezone1_y, zone1offset_y;
int scaleopp1, scaleopp2, brfd;
int scaledvalue;
brfd = FFMIN(v->brfd, 3);
scalezone1_y = vc1_b_field_mvpred_scales[4][brfd];
zone1offset_y = vc1_b_field_mvpred_scales[6][brfd];
scaleopp1 = vc1_b_field_mvpred_scales[1][brfd];
scaleopp2 = vc1_b_field_mvpred_scales[2][brfd];
if (FFABS(n) > 63)
scaledvalue = n;
else {
if (FFABS(n) < scalezone1_y)
scaledvalue = (n * scaleopp1) >> 8;
else {
if (n < 0)
scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
else
scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
}
}
if (v->cur_field_type && !v->ref_field_type[dir]) {
return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
} else {
return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
}
}
static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */, int dim, int dir)
{
int brfd, scalesame;
if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
if (dim)
return scaleforsame_y(v, i, n, dir);
else
return scaleforsame_x(v, n, dir);
}
brfd = FFMIN(v->brfd, 3);
scalesame = vc1_b_field_mvpred_scales[0][brfd];
return(n * scalesame >> 8);
}
static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */, int dim, int dir)
{
int refdist, scaleopp;
if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
if (dim)
return scaleforopp_y(v, n, dir);
else
return scaleforopp_x(v, n);
}
if (v->s.pict_type != AV_PICTURE_TYPE_B)
refdist = FFMIN(v->refdist, 3);
else
refdist = dir ? v->brfd : v->frfd;
scaleopp = vc1_field_mvpred_scales[v->second_field][0][refdist];
return(n * scaleopp >> 8);
}
/** Predict and set motion vector
*/
static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra)
static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra, int pred_flag, int dir)
{
MpegEncContext *s = &v->s;
int xy, wrap, off = 0;
int16_t *A, *B, *C;
int px, py;
int sum;
int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
int opposit, f;
int16_t samefield_pred[2], oppfield_pred[2];
int16_t samefield_predA[2], oppfield_predA[2];
int16_t samefield_predB[2], oppfield_predB[2];
int16_t samefield_predC[2], oppfield_predC[2];
int16_t *predA, *predC;
int a_valid, b_valid, c_valid;
int hybridmv_thresh, y_bias = 0;
if (v->mv_mode == MV_PMODE_MIXED_MV ||
((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV))) mixedmv_pic = 1;
else mixedmv_pic = 0;
/* scale MV difference to be quad-pel */
dmv_x <<= 1 - s->quarter_sample;
dmv_y <<= 1 - s->quarter_sample;
......@@ -883,35 +1450,38 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m
xy = s->block_index[n];
if(s->mb_intra){
s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0;
s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0;
s->current_picture.f.motion_val[1][xy][0] = 0;
s->current_picture.f.motion_val[1][xy][1] = 0;
s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = 0;
s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = 0;
s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
if(mv1) { /* duplicate motion data for 1-MV block */
s->current_picture.f.motion_val[0][xy + 1][0] = 0;
s->current_picture.f.motion_val[0][xy + 1][1] = 0;
s->current_picture.f.motion_val[0][xy + wrap][0] = 0;
s->current_picture.f.motion_val[0][xy + wrap][1] = 0;
s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0;
s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0;
s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][1] = 0;
s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][1] = 0;
s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
s->current_picture.f.motion_val[1][xy + 1][0] = 0;
s->current_picture.f.motion_val[1][xy + 1][1] = 0;
s->current_picture.f.motion_val[1][xy + wrap][0] = 0;
s->current_picture.f.motion_val[1][xy + wrap][1] = 0;
s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0;
s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0;
s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][1] = 0;
s->current_picture.f.motion_val[1][xy + wrap][0] = 0;
s->current_picture.f.motion_val[1][xy + wrap + v->blocks_off][1] = 0;
s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
}
return;
}
C = s->current_picture.f.motion_val[0][xy - 1];
A = s->current_picture.f.motion_val[0][xy - wrap];
if(mv1)
off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
else {
C = s->current_picture.f.motion_val[dir][xy - 1 + v->blocks_off];
A = s->current_picture.f.motion_val[dir][xy - wrap + v->blocks_off];
if(mv1) {
if (v->field_mode && mixedmv_pic)
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
else
off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
} else {
//in 4-MV mode different blocks have different B predictor position
switch(n){
switch (n) {
case 0:
off = (s->mb_x > 0) ? -1 : 1;
break;
......@@ -925,24 +1495,135 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m
off = -1;
}
}
B = s->current_picture.f.motion_val[0][xy - wrap + off];
if(!s->first_slice_line || (n==2 || n==3)) { // predictor A is not out of bounds
if(s->mb_width == 1) {
px = A[0];
py = A[1];
B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off];
a_valid = !s->first_slice_line || (n==2 || n==3);
b_valid = a_valid && (s->mb_width > 1);
c_valid = s->mb_x || (n==1 || n==3);
if (v->field_mode) {
a_valid = a_valid && !is_intra[xy - wrap];
b_valid = b_valid && !is_intra[xy - wrap + off];
c_valid = c_valid && !is_intra[xy - 1];
}
if (a_valid) {
f = v->mv_f[dir][xy - wrap + v->blocks_off];
num_oppfield += f;
num_samefield += 1 - f;
if (f) {
oppfield_predA[0] = A[0];
oppfield_predA[1] = A[1];
samefield_predA[0] = scaleforsame(v, 0, A[0], 0, dir);
samefield_predA[1] = scaleforsame(v, n, A[1], 1, dir);
} else {
samefield_predA[0] = A[0];
samefield_predA[1] = A[1];
if (v->numref)
oppfield_predA[0] = scaleforopp(v, A[0], 0, dir);
if (v->numref)
oppfield_predA[1] = scaleforopp(v, A[1], 1, dir);
}
} else {
samefield_predA[0] = samefield_predA[1] = 0;
oppfield_predA[0] = oppfield_predA[1] = 0;
}
if (c_valid) {
f = v->mv_f[dir][xy - 1 + v->blocks_off];
num_oppfield += f;
num_samefield += 1 - f;
if (f) {
oppfield_predC[0] = C[0];
oppfield_predC[1] = C[1];
samefield_predC[0] = scaleforsame(v, 0, C[0], 0, dir);
samefield_predC[1] = scaleforsame(v, n, C[1], 1, dir);
} else {
samefield_predC[0] = C[0];
samefield_predC[1] = C[1];
if (v->numref)
oppfield_predC[0] = scaleforopp(v, C[0], 0, dir);
if (v->numref)
oppfield_predC[1] = scaleforopp(v, C[1], 1, dir);
}
} else {
samefield_predC[0] = samefield_predC[1] = 0;
oppfield_predC[0] = oppfield_predC[1] = 0;
}
if (b_valid) {
f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
num_oppfield += f;
num_samefield += 1 - f;
if (f) {
oppfield_predB[0] = B[0];
oppfield_predB[1] = B[1];
samefield_predB[0] = scaleforsame(v, 0, B[0], 0, dir);
samefield_predB[1] = scaleforsame(v, n, B[1], 1, dir);
} else {
px = mid_pred(A[0], B[0], C[0]);
py = mid_pred(A[1], B[1], C[1]);
samefield_predB[0] = B[0];
samefield_predB[1] = B[1];
if (v->numref)
oppfield_predB[0] = scaleforopp(v, B[0], 0, dir);
if (v->numref)
oppfield_predB[1] = scaleforopp(v, B[1], 1, dir);
}
} else if(s->mb_x || (n==1 || n==3)) { // predictor C is not out of bounds
px = C[0];
py = C[1];
} else {
px = py = 0;
samefield_predB[0] = samefield_predB[1] = 0;
oppfield_predB[0] = oppfield_predB[1] = 0;
}
if (a_valid) {
samefield_pred[0] = samefield_predA[0];
samefield_pred[1] = samefield_predA[1];
oppfield_pred[0] = oppfield_predA[0];
oppfield_pred[1] = oppfield_predA[1];
} else if (c_valid) {
samefield_pred[0] = samefield_predC[0];
samefield_pred[1] = samefield_predC[1];
oppfield_pred[0] = oppfield_predC[0];
oppfield_pred[1] = oppfield_predC[1];
} else if (b_valid) {
samefield_pred[0] = samefield_predB[0];
samefield_pred[1] = samefield_predB[1];
oppfield_pred[0] = oppfield_predB[0];
oppfield_pred[1] = oppfield_predB[1];
} else {
samefield_pred[0] = samefield_pred[1] = 0;
oppfield_pred[0] = oppfield_pred[1] = 0;
}
if (num_samefield + num_oppfield > 1) {
samefield_pred[0] = mid_pred(samefield_predA[0], samefield_predB[0], samefield_predC[0]);
samefield_pred[1] = mid_pred(samefield_predA[1], samefield_predB[1], samefield_predC[1]);
if (v->numref)
oppfield_pred[0] = mid_pred(oppfield_predA[0], oppfield_predB[0], oppfield_predC[0]);
if (v->numref)
oppfield_pred[1] = mid_pred(oppfield_predA[1], oppfield_predB[1], oppfield_predC[1]);
}
if (v->field_mode) {
if (num_samefield <= num_oppfield)
opposit = 1 - pred_flag;
else
opposit = pred_flag;
} else
opposit = 0;
if (opposit) {
px = oppfield_pred[0];
py = oppfield_pred[1];
predA = oppfield_predA;
predC = oppfield_predC;
v->mv_f[dir][xy + v->blocks_off] = f = 1;
v->ref_field_type[dir] = !v->cur_field_type;
} else {
px = samefield_pred[0];
py = samefield_pred[1];
predA = samefield_predA;
predC = samefield_predC;
v->mv_f[dir][xy + v->blocks_off] = f = 0;
v->ref_field_type[dir] = v->cur_field_type;
}
/* Pullback MV as specified in 8.3.5.3.4 */
{
if (!v->field_mode) {
int qx, qy, X, Y;
qx = (s->mb_x << 6) + ((n==1 || n==3) ? 32 : 0);
qy = (s->mb_y << 6) + ((n==2 || n==3) ? 32 : 0);
......@@ -958,46 +1639,285 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y, int m
if(qx + px > X) px = X - qx;
if(qy + py > Y) py = Y - qy;
}
/* Calculate hybrid prediction as specified in 8.3.5.3.5 */
if((!s->first_slice_line || (n==2 || n==3)) && (s->mb_x || (n==1 || n==3))) {
if(is_intra[xy - wrap])
sum = FFABS(px) + FFABS(py);
if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
/* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
if (v->field_mode && !s->quarter_sample)
hybridmv_thresh = 16;
else
sum = FFABS(px - A[0]) + FFABS(py - A[1]);
if(sum > 32) {
if(get_bits1(&s->gb)) {
px = A[0];
py = A[1];
hybridmv_thresh = 32;
if (a_valid && c_valid) {
if (is_intra[xy - wrap])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - predA[0]) + FFABS(py - predA[1]);
if (sum > hybridmv_thresh) {
if (get_bits1(&s->gb)) { // read HYBRIDPRED bit
px = predA[0];
py = predA[1];
} else {
px = predC[0];
py = predC[1];
}
} else {
px = C[0];
py = C[1];
if (is_intra[xy - 1])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - predC[0]) + FFABS(py - predC[1]);
if (sum > hybridmv_thresh) {
if(get_bits1(&s->gb)) {
px = predA[0];
py = predA[1];
} else {
px = predC[0];
py = predC[1];
}
}
}
}
}
if (v->field_mode && !s->quarter_sample) {
r_x <<= 1;
r_y <<= 1;
}
if (v->field_mode && v->numref)
r_y >>= 1;
if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
y_bias = 1;
/* store MV using signed modulus of MV range defined in 4.11 */
s->mv[dir][n][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
s->mv[dir][n][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
if(mv1) { /* duplicate motion data for 1-MV block */
s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
s->current_picture.f.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
s->current_picture.f.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
v->mv_f[dir][xy + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
}
}
/** Predict and set motion vector for interlaced frame picture MBs
*/
static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, int mvn, int r_x, int r_y, uint8_t* is_intra)
{
MpegEncContext *s = &v->s;
int xy, wrap, off = 0;
int A[2], B[2], C[2];
int px, py;
int a_valid = 0, b_valid = 0, c_valid = 0;
int field_a, field_b, field_c; // 0: same, 1: opposit
int total_valid, num_samefield, num_oppfield;
int pos_c, pos_b, n_adj;
wrap = s->b8_stride;
xy = s->block_index[n];
if(s->mb_intra){
s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0;
s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0;
s->current_picture.f.motion_val[1][xy][0] = 0;
s->current_picture.f.motion_val[1][xy][1] = 0;
if(mvn == 1) { /* duplicate motion data for 1-MV block */
s->current_picture.f.motion_val[0][xy + 1][0] = 0;
s->current_picture.f.motion_val[0][xy + 1][1] = 0;
s->current_picture.f.motion_val[0][xy + wrap][0] = 0;
s->current_picture.f.motion_val[0][xy + wrap][1] = 0;
s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0;
s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0;
v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
s->current_picture.f.motion_val[1][xy + 1][0] = 0;
s->current_picture.f.motion_val[1][xy + 1][1] = 0;
s->current_picture.f.motion_val[1][xy + wrap][0] = 0;
s->current_picture.f.motion_val[1][xy + wrap][1] = 0;
s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0;
s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0;
}
return;
}
off = ((n == 0) || (n == 1)) ? 1 : -1;
/* predict A */
if (s->mb_x || (n == 1) || (n == 3)) {
if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
|| (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
A[0] = s->current_picture.f.motion_val[0][xy - 1][0];
A[1] = s->current_picture.f.motion_val[0][xy - 1][1];
a_valid = 1;
} else { // current block has frame mv and cand. has field MV (so average)
A[0] = (s->current_picture.f.motion_val[0][xy - 1][0]
+ s->current_picture.f.motion_val[0][xy - 1 + off*wrap][0] + 1) >> 1;
A[1] = (s->current_picture.f.motion_val[0][xy - 1][1]
+ s->current_picture.f.motion_val[0][xy - 1 + off*wrap][1] + 1) >> 1;
a_valid = 1;
}
if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
a_valid = 0;
A[0] = A[1] = 0;
}
} else A[0] = A[1] = 0;
/* Predict B and C */
B[0] = B[1] = C[0] = C[1] = 0;
if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
if (!s->first_slice_line) {
if (!v->is_intra[s->mb_x - s->mb_stride]) {
b_valid = 1;
n_adj = n | 2;
pos_b = s->block_index[n_adj] - 2 * wrap;
if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
n_adj = (n & 2) | (n & 1);
}
B[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][0];
B[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][1];
if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
B[0] = (1 + B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0]) >> 1;
B[1] = (1 + B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1]) >> 1;
}
}
if (s->mb_width > 1) {
if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
c_valid = 1;
n_adj = 2;
pos_c = s->block_index[2] - 2*wrap + 2;
if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
n_adj = n & 2;
}
C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap + 2][0];
C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap + 2][1];
if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
C[0] = (1 + C[0] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
C[1] = (1 + C[1] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
}
if (s->mb_x == s->mb_width - 1) {
if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
c_valid = 1;
n_adj = 3;
pos_c = s->block_index[3] - 2*wrap - 2;
if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
n_adj = n | 1;
}
C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap - 2][0];
C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2*wrap - 2][1];
if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
C[0] = (1 + C[0] + s->current_picture.f.motion_val[0][s->block_index[1] - 2*wrap - 2][0]) >> 1;
C[1] = (1 + C[1] + s->current_picture.f.motion_val[0][s->block_index[1] - 2*wrap - 2][1]) >> 1;
}
} else c_valid = 0;
}
}
}
}
} else {
pos_b = s->block_index[1];
b_valid = 1;
B[0] = s->current_picture.f.motion_val[0][pos_b][0];
B[1] = s->current_picture.f.motion_val[0][pos_b][1];
pos_c = s->block_index[0];
c_valid = 1;
C[0] = s->current_picture.f.motion_val[0][pos_c][0];
C[1] = s->current_picture.f.motion_val[0][pos_c][1];
}
total_valid = a_valid + b_valid + c_valid;
// check if predictor A is out of bounds
if (!s->mb_x && !(n==1 || n==3)) {
A[0] = A[1] = 0;
}
// check if predictor B is out of bounds
if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
B[0] = B[1] = C[0] = C[1] = 0;
}
if (!v->blk_mv_type[xy]) {
if(s->mb_width == 1) {
px = B[0];
py = B[1];
} else {
if(is_intra[xy - 1])
sum = FFABS(px) + FFABS(py);
else
sum = FFABS(px - C[0]) + FFABS(py - C[1]);
if(sum > 32) {
if(get_bits1(&s->gb)) {
if (total_valid >= 2) {
px = mid_pred(A[0], B[0], C[0]);
py = mid_pred(A[1], B[1], C[1]);
} else if (total_valid) {
if (a_valid) { px = A[0]; py = A[1]; }
if (b_valid) { px = B[0]; py = B[1]; }
if (c_valid) { px = C[0]; py = C[1]; }
} else px = py = 0;
}
} else {
if (a_valid)
field_a = (A[1] & 4) ? 1 : 0;
else
field_a = 0;
if (b_valid)
field_b = (B[1] & 4) ? 1 : 0;
else
field_b = 0;
if (c_valid)
field_c = (C[1] & 4) ? 1 : 0;
else
field_c = 0;
num_oppfield = field_a + field_b + field_c;
num_samefield = total_valid - num_oppfield;
if (total_valid == 3) {
if ((num_samefield == 3) || (num_oppfield == 3)) {
px = mid_pred(A[0], B[0], C[0]);
py = mid_pred(A[1], B[1], C[1]);
} else if (num_samefield >= num_oppfield) {
/* take one MV from same field set depending on priority
the check for B may not be necessary */
px = (!field_a) ? A[0] : B[0];
py = (!field_a) ? A[1] : B[1];
} else {
px = (field_a) ? A[0] : B[0];
py = (field_a) ? A[1] : B[1];
}
} else if (total_valid == 2) {
if (num_samefield >= num_oppfield) {
if (!field_a && a_valid) {
px = A[0];
py = A[1];
} else {
} else if (!field_b && b_valid) {
px = B[0];
py = B[1];
} else if (c_valid) {
px = C[0];
py = C[1];
} else px = py = 0;
} else {
if (field_a && a_valid) {
px = A[0];
py = A[1];
} else if (field_b && b_valid) {
px = B[0];
py = B[1];
} else if (c_valid) {
px = C[0];
py = C[1];
}
}
}
} else if (total_valid == 1) {
px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
} else px = py = 0;
}
/* store MV using signed modulus of MV range defined in 4.11 */
s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
if(mv1) { /* duplicate motion data for 1-MV block */
s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0];
s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1];
s->current_picture.f.motion_val[0][xy + wrap][0] = s->current_picture.f.motion_val[0][xy][0];
s->current_picture.f.motion_val[0][xy + wrap][1] = s->current_picture.f.motion_val[0][xy][1];
if(mvn == 1) { /* duplicate motion data for 1-MV block */
s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0];
s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1];
s->current_picture.f.motion_val[0][xy + wrap][0] = s->current_picture.f.motion_val[0][xy][0];
s->current_picture.f.motion_val[0][xy + wrap][1] = s->current_picture.f.motion_val[0][xy][1];
s->current_picture.f.motion_val[0][xy + wrap + 1][0] = s->current_picture.f.motion_val[0][xy][0];
s->current_picture.f.motion_val[0][xy + wrap + 1][1] = s->current_picture.f.motion_val[0][xy][1];
} else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0];
s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1];
s->mv[0][n + 1][0] = s->mv[0][n][0];
s->mv[0][n + 1][1] = s->mv[0][n][1];
}
}
......@@ -1009,13 +1929,21 @@ static void vc1_interp_mc(VC1Context *v)
DSPContext *dsp = &v->s.dsp;
uint8_t *srcY, *srcU, *srcV;
int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
int off, off_uv;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
if(!v->s.next_picture.f.data[0])return;
if (!v->field_mode && !v->s.next_picture.f.data[0])
return;
mx = s->mv[1][0][0];
my = s->mv[1][0][1];
uvmx = (mx + ((mx & 3) == 3)) >> 1;
uvmy = (my + ((my & 3) == 3)) >> 1;
if (v->field_mode) {
if (v->cur_field_type != v->ref_field_type[1])
my = my - 2 + 4 * v->cur_field_type;
uvmy = uvmy - 2 + 4 * v->cur_field_type;
}
if(v->fastuvmc) {
uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));
uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));
......@@ -1045,6 +1973,12 @@ static void vc1_interp_mc(VC1Context *v)
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
if (v->field_mode && v->ref_field_type[1]) {
srcY += s->current_picture_ptr->f.linesize[0];
srcU += s->current_picture_ptr->f.linesize[1];
srcV += s->current_picture_ptr->f.linesize[2];
}
/* for grayscale we should not try to read from unknown area */
if(s->flags & CODEC_FLAG_GRAY) {
srcU = s->edge_emu_buffer + 18 * s->linesize;
......@@ -1053,17 +1987,17 @@ static void vc1_interp_mc(VC1Context *v)
if(v->rangeredfrm
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3
|| (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){
|| (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel*3){
uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;
srcY -= s->mspel * (1 + s->linesize);
s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2,
src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, v_edge_pos);
srcY = s->edge_emu_buffer;
s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
srcU = uvbuf;
srcV = uvbuf + 16;
/* if we deal with range reduction we need to scale source blocks */
......@@ -1089,20 +2023,28 @@ static void vc1_interp_mc(VC1Context *v)
srcY += s->mspel * (1 + s->linesize);
}
if (v->field_mode && v->cur_field_type) {
off = s->current_picture_ptr->f.linesize[0];
off_uv = s->current_picture_ptr->f.linesize[1];
} else {
off = 0;
off_uv = 0;
}
if(s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off , srcY , s->linesize, v->rnd);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
srcY += s->linesize * 8;
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize , srcY , s->linesize, v->rnd);
v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
} else { // hpel mc
dxy = (my & 2) | ((mx & 2) >> 1);
if(!v->rnd)
dsp->avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
else
dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
}
if(s->flags & CODEC_FLAG_GRAY) return;
......@@ -1110,11 +2052,11 @@ static void vc1_interp_mc(VC1Context *v)
uvmx = (uvmx&3)<<1;
uvmy = (uvmy&3)<<1;
if(!v->rnd){
dsp->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
dsp->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
}else{
v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
}
}
......@@ -1137,6 +2079,19 @@ static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
#endif
}
static av_always_inline int scale_mv_intfi(int value, int bfrac, int inv, int qs, int qs_last)
{
int n = bfrac;
if (inv)
n -= 256;
n <<= !qs_last;
if (!qs)
return (value * n + 255) >> 9;
else
return (value * n + 128) >> 8;
}
/** Reconstruct motion vector for B-frame and do motion compensation
*/
static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mode)
......@@ -1185,27 +2140,29 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
xy = s->block_index[0];
if(s->mb_intra) {
s->current_picture.f.motion_val[0][xy][0] =
s->current_picture.f.motion_val[0][xy][1] =
s->current_picture.f.motion_val[1][xy][0] =
s->current_picture.f.motion_val[1][xy][1] = 0;
s->current_picture.f.motion_val[0][xy + v->blocks_off][0] =
s->current_picture.f.motion_val[0][xy + v->blocks_off][1] =
s->current_picture.f.motion_val[1][xy + v->blocks_off][0] =
s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
return;
}
s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
if (!v->field_mode) {
s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
/* Pullback predicted motion vectors as specified in 8.4.5.4 */
s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
/* Pullback predicted motion vectors as specified in 8.4.5.4 */
s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6));
s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
}
if(direct) {
s->current_picture.f.motion_val[0][xy][0] = s->mv[0][0][0];
s->current_picture.f.motion_val[0][xy][1] = s->mv[0][0][1];
s->current_picture.f.motion_val[1][xy][0] = s->mv[1][0][0];
s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1];
s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
return;
}
......@@ -1372,6 +2329,59 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int
s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1];
}
static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag)
{
int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
MpegEncContext *s = &v->s;
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
if (v->bmvtype == BMV_TYPE_DIRECT) {
int total_opp, k, f;
if (s->next_picture.f.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
s->mv[0][0][0] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 0, s->quarter_sample, v->qs_last);
s->mv[0][0][1] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 0, s->quarter_sample, v->qs_last);
s->mv[1][0][0] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0], v->bfraction, 1, s->quarter_sample, v->qs_last);
s->mv[1][0][1] = scale_mv_intfi(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1], v->bfraction, 1, s->quarter_sample, v->qs_last);
total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
+ v->mv_f_next[0][s->block_index[1] + v->blocks_off]
+ v->mv_f_next[0][s->block_index[2] + v->blocks_off]
+ v->mv_f_next[0][s->block_index[3] + v->blocks_off];
f = (total_opp > 2) ? 1 : 0;
} else {
s->mv[0][0][0] = s->mv[0][0][1] = 0;
s->mv[1][0][0] = s->mv[1][0][1] = 0;
f = 0;
}
v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
for (k = 0; k < 4; k++) {
s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
}
return;
}
if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
return;
}
if (dir) { // backward
vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
if (n == 3 || mv1) {
vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0], 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
}
} else { // forward
vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
if (n == 3 || mv1) {
vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1], 1, v->range_x, v->range_y, v->mb_type[0], 0, 1);
}
}
}
/** Get predicted DC value for I-frames only
* prediction dir: left=0, top=1
* @param s MpegEncContext
......@@ -1866,12 +2876,20 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c
int k;
if(v->s.ac_pred) {
if(!dc_pred_dir)
zz_table = v->zz_8x8[2];
if (!use_pred && v->fcm == 1) {
zz_table = v->zzi_8x8;
} else {
if(!dc_pred_dir) //top
zz_table = v->zz_8x8[2];
else //left
zz_table = v->zz_8x8[3];
}
} else {
if (v->fcm != 1)
zz_table = v->zz_8x8[1];
else
zz_table = v->zz_8x8[3];
} else
zz_table = v->zz_8x8[1];
zz_table = v->zzi_8x8;
}
while (!last) {
vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
......@@ -2076,7 +3094,18 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c
i += skip;
if(i > 63)
break;
block[v->zz_8x8[0][i++]] = value;
if (v->fcm == 0)
block[v->zz_8x8[0][i++]] = value;
else {
if(use_pred && (v->fcm == 1)) {
if(!dc_pred_dir) //top
block[v->zz_8x8[2][i++]] = value;
else //left
block[v->zz_8x8[3][i++]] = value;
} else {
block[v->zzi_8x8[i++]] = value;
}
}
}
/* apply AC prediction if needed */
......@@ -2217,7 +3246,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
i += skip;
if(i > 63)
break;
idx = v->zz_8x8[0][i++];
if (!v->interlace)
idx = v->zz_8x8[0][i++];
else
idx = v->zzi_8x8[i++];
block[idx] = value * scale;
if(!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
......@@ -2242,7 +3274,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
i += skip;
if(i > 15)
break;
idx = ff_vc1_simple_progressive_4x4_zz[i++];
if (!v->interlace)
idx = ff_vc1_simple_progressive_4x4_zz[i++];
else
idx = ff_vc1_adv_interlaced_4x4_zz[i++];
block[idx + off] = value * scale;
if(!v->pquantizer)
block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;
......@@ -2266,7 +3301,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
i += skip;
if(i > 31)
break;
idx = v->zz_8x4[i++]+off;
if (!v->interlace)
idx = v->zz_8x4[i++] + off;
else
idx = ff_vc1_adv_interlaced_8x4_zz[i++] + off;
block[idx] = value * scale;
if(!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
......@@ -2290,7 +3328,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
i += skip;
if(i > 31)
break;
idx = v->zz_4x8[i++]+off;
if (!v->interlace)
idx = v->zz_4x8[i++] + off;
else
idx = ff_vc1_adv_interlaced_4x8_zz[i++] + off;
block[idx] = value * scale;
if(!v->pquantizer)
block[idx] += (block[idx] < 0) ? -mquant : mquant;
......@@ -2463,7 +3504,7 @@ static void vc1_apply_p_loop_filter(VC1Context *v)
}
}
/** Decode one P-frame MB (in Simple/Main profile)
/** Decode one P-frame MB
*/
static int vc1_decode_p_mb(VC1Context *v)
{
......@@ -2506,7 +3547,7 @@ static int vc1_decode_p_mb(VC1Context *v)
s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
}
s->current_picture.f.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
/* FIXME Set DC val for inter block ? */
if (s->mb_intra && !mb_has_coeffs)
......@@ -2517,7 +3558,8 @@ static int vc1_decode_p_mb(VC1Context *v)
}
else if (mb_has_coeffs)
{
if (s->mb_intra) s->ac_pred = get_bits1(gb);
if (s->mb_intra)
s->ac_pred = get_bits1(gb);
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
}
......@@ -2578,7 +3620,7 @@ static int vc1_decode_p_mb(VC1Context *v)
}
s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP;
s->current_picture.f.qscale_table[mb_pos] = 0;
vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
vc1_mc_1mv(v, 0);
}
} //1MV mode
......@@ -2602,8 +3644,8 @@ static int vc1_decode_p_mb(VC1Context *v)
if(val) {
GET_MVDATA(dmv_x, dmv_y);
}
vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
if(!s->mb_intra) vc1_mc_4mv_luma(v, i);
vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
if(!s->mb_intra) vc1_mc_4mv_luma(v, i, 0);
intra_count += s->mb_intra;
is_intra[i] = s->mb_intra;
is_coded[i] = mb_has_coeffs;
......@@ -2612,7 +3654,7 @@ static int vc1_decode_p_mb(VC1Context *v)
is_intra[i] = (intra_count >= 3);
is_coded[i] = val;
}
if(i == 4) vc1_mc_4mv_chroma(v);
if(i == 4) vc1_mc_4mv_chroma(v, 0);
v->mb_type[0][s->block_index[i]] = is_intra[i];
if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i];
}
......@@ -2682,10 +3724,10 @@ static int vc1_decode_p_mb(VC1Context *v)
}
for (i=0; i<4; i++)
{
vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_4mv_luma(v, i);
vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
vc1_mc_4mv_luma(v, i, 0);
}
vc1_mc_4mv_chroma(v);
vc1_mc_4mv_chroma(v, 0);
s->current_picture.f.qscale_table[mb_pos] = 0;
}
}
......@@ -2697,6 +3739,324 @@ end:
return 0;
}
/* Decode one macroblock in an interlaced frame p picture */
static int vc1_decode_p_mb_intfr(VC1Context *v)
{
MpegEncContext *s = &v->s;
GetBitContext *gb = &s->gb;
int i;
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
int cbp = 0; /* cbp decoding stuff */
int mqdiff, mquant; /* MB quantization */
int ttmb = v->ttfrm; /* MB Transform type */
int mb_has_coeffs = 1; /* last_flag */
int dmv_x, dmv_y; /* Differential MV components */
int val; /* temp value */
int first_block = 1;
int dst_idx, off;
int skipped, fourmv = 0, twomv = 0;
int block_cbp = 0, pat, block_tt = 0;
int idx_mbmode = 0, mvbp;
int stride_y, fieldtx;
mquant = v->pq; /* Loosy initialization */
if (v->skip_is_raw)
skipped = get_bits1(gb);
else
skipped = v->s.mbskip_table[mb_pos];
if (!skipped) {
if (v->fourmvswitch)
idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done
else
idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line
switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) {
/* store the motion vector type in a flag (useful later) */
case MV_PMODE_INTFR_4MV:
fourmv = 1;
v->blk_mv_type[s->block_index[0]] = 0;
v->blk_mv_type[s->block_index[1]] = 0;
v->blk_mv_type[s->block_index[2]] = 0;
v->blk_mv_type[s->block_index[3]] = 0;
break;
case MV_PMODE_INTFR_4MV_FIELD:
fourmv = 1;
v->blk_mv_type[s->block_index[0]] = 1;
v->blk_mv_type[s->block_index[1]] = 1;
v->blk_mv_type[s->block_index[2]] = 1;
v->blk_mv_type[s->block_index[3]] = 1;
break;
case MV_PMODE_INTFR_2MV_FIELD:
twomv = 1;
v->blk_mv_type[s->block_index[0]] = 1;
v->blk_mv_type[s->block_index[1]] = 1;
v->blk_mv_type[s->block_index[2]] = 1;
v->blk_mv_type[s->block_index[3]] = 1;
break;
case MV_PMODE_INTFR_1MV:
v->blk_mv_type[s->block_index[0]] = 0;
v->blk_mv_type[s->block_index[1]] = 0;
v->blk_mv_type[s->block_index[2]] = 0;
v->blk_mv_type[s->block_index[3]] = 0;
break;
}
if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA;
s->mb_intra = v->is_intra[s->mb_x] = 1;
for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 1;
fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
mb_has_coeffs = get_bits1(gb);
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
GET_MQUANT();
s->current_picture.f.qscale_table[mb_pos] = mquant;
/* Set DC scale - y and c use the same (not sure if necessary here) */
s->y_dc_scale = s->y_dc_scale_table[mquant];
s->c_dc_scale = s->c_dc_scale_table[mquant];
dst_idx = 0;
for (i=0; i<6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
v->mb_type[0][s->block_index[i]] = s->mb_intra;
v->a_avail = v->c_avail = 0;
if(i == 2 || i == 3 || !s->first_slice_line)
v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
if(i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
if (i < 4) {
stride_y = s->linesize << fieldtx;
off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
} else {
stride_y = s->uvlinesize;
off = 0;
}
s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y);
//TODO: loop filter
}
} else { //inter MB
mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3];
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
} else {
if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV)
|| (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) {
v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
}
}
s->mb_intra = v->is_intra[s->mb_x] = 0;
for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1];
/* for all motion vector read MVDATA and motion compensate each block */
dst_idx = 0;
if (fourmv) {
mvbp = v->fourmvbp;
for (i=0; i<6; i++) {
if (i < 4) {
dmv_x = dmv_y = 0;
val = ((mvbp >> (3 - i)) & 1);
if(val) {
get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
}
vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_4mv_luma(v, i, 0);
} else if (i == 4) {
vc1_mc_4mv_chroma4(v);
}
}
} else if (twomv) {
mvbp = v->twomvbp;
dmv_x = dmv_y = 0;
if (mvbp & 2) {
get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
}
vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_4mv_luma(v, 0, 0);
vc1_mc_4mv_luma(v, 1, 0);
dmv_x = dmv_y = 0;
if (mvbp & 1) {
get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
}
vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_4mv_luma(v, 2, 0);
vc1_mc_4mv_luma(v, 3, 0);
vc1_mc_4mv_chroma4(v);
} else {
mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
if (mvbp) {
get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
}
vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_1mv(v, 0);
}
if (cbp)
GET_MQUANT(); // p. 227
s->current_picture.f.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && cbp)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
for (i=0; i<6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
if (!fieldtx)
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
else
off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
if (val) {
pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:(s->linesize << fieldtx), (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
block_cbp |= pat << (i << 2);
if (!v->ttmbf && ttmb < 8)
ttmb = -1;
first_block = 0;
}
}
}
} else { // skipped
s->mb_intra = v->is_intra[s->mb_x] = 0;
for(i = 0; i < 6; i++) {
v->mb_type[0][s->block_index[i]] = 0;
s->dc_val[0][s->block_index[i]] = 0;
}
s->current_picture.f.mb_type[mb_pos] = MB_TYPE_SKIP;
s->current_picture.f.qscale_table[mb_pos] = 0;
v->blk_mv_type[s->block_index[0]] = 0;
v->blk_mv_type[s->block_index[1]] = 0;
v->blk_mv_type[s->block_index[2]] = 0;
v->blk_mv_type[s->block_index[3]] = 0;
vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
vc1_mc_1mv(v, 0);
}
if (s->mb_x == s->mb_width - 1)
memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
return 0;
}
static int vc1_decode_p_mb_intfi(VC1Context *v)
{
MpegEncContext *s = &v->s;
GetBitContext *gb = &s->gb;
int i;
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
int cbp = 0; /* cbp decoding stuff */
int mqdiff, mquant; /* MB quantization */
int ttmb = v->ttfrm; /* MB Transform type */
int mb_has_coeffs = 1; /* last_flag */
int dmv_x, dmv_y; /* Differential MV components */
int val; /* temp values */
int first_block = 1;
int dst_idx, off;
int pred_flag;
int block_cbp = 0, pat, block_tt = 0;
int idx_mbmode = 0;
mquant = v->pq; /* Loosy initialization */
idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
if (idx_mbmode <= 1) { // intra MB
s->mb_intra = v->is_intra[s->mb_x] = 1;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
GET_MQUANT();
s->current_picture.f.qscale_table[mb_pos] = mquant;
/* Set DC scale - y and c use the same (not sure if necessary here) */
s->y_dc_scale = s->y_dc_scale_table[mquant];
s->c_dc_scale = s->c_dc_scale_table[mquant];
v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
mb_has_coeffs = idx_mbmode & 1;
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
dst_idx = 0;
for (i=0; i<6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
v->mb_type[0][s->block_index[i]] = 1;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
v->a_avail = v->c_avail = 0;
if(i == 2 || i == 3 || !s->first_slice_line)
v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
if(i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
//TODO: loop filter
}
} else {
s->mb_intra = v->is_intra[s->mb_x] = 0;
s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
if (idx_mbmode <= 5) { // 1-MV
dmv_x = dmv_y = 0;
if (idx_mbmode & 1) {
get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
}
vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
vc1_mc_1mv(v, 0);
mb_has_coeffs = !(idx_mbmode & 2);
} else { // 4-MV
v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
for (i=0; i<6; i++) {
if (i < 4) {
dmv_x = dmv_y = pred_flag = 0;
val = ((v->fourmvbp >> (3 - i)) & 1);
if(val) {
get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
}
vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
vc1_mc_4mv_luma(v, i, 0);
} else if (i == 4)
vc1_mc_4mv_chroma(v, 0);
}
mb_has_coeffs = idx_mbmode & 1;
}
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
if (cbp) {
GET_MQUANT();
}
s->current_picture.f.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && cbp) {
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
}
dst_idx = 0;
for (i=0; i<6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
if (v->cur_field_type)
off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
if(val) {
pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
block_cbp |= pat << (i << 2);
if(!v->ttmbf && ttmb < 8) ttmb = -1;
first_block = 0;
}
}
}
if (s->mb_x == s->mb_width - 1)
memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0])*s->mb_stride);
return 0;
}
/** Decode one B-frame MB (in Main profile)
*/
static void vc1_decode_b_mb(VC1Context *v)
......@@ -2841,6 +4201,153 @@ static void vc1_decode_b_mb(VC1Context *v)
}
}
/** Decode one B-frame MB (in interlaced field B picture)
*/
static void vc1_decode_b_mb_intfi(VC1Context *v)
{
MpegEncContext *s = &v->s;
GetBitContext *gb = &s->gb;
int i, j;
int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
int cbp = 0; /* cbp decoding stuff */
int mqdiff, mquant; /* MB quantization */
int ttmb = v->ttfrm; /* MB Transform type */
int mb_has_coeffs = 0; /* last_flag */
int val; /* temp value */
int first_block = 1;
int dst_idx, off;
int fwd;
int dmv_x[2], dmv_y[2], pred_flag[2];
int bmvtype = BMV_TYPE_BACKWARD;
int idx_mbmode, interpmvp;
mquant = v->pq; /* Loosy initialization */
s->mb_intra = 0;
idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
if (idx_mbmode <= 1) { // intra MB
s->mb_intra = v->is_intra[s->mb_x] = 1;
s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
GET_MQUANT();
s->current_picture.f.qscale_table[mb_pos] = mquant;
/* Set DC scale - y and c use the same (not sure if necessary here) */
s->y_dc_scale = s->y_dc_scale_table[mquant];
s->c_dc_scale = s->c_dc_scale_table[mquant];
v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
mb_has_coeffs = idx_mbmode & 1;
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_ICBPCY_VLC_BITS, 2);
dst_idx = 0;
for (i=0; i<6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
v->mb_type[0][s->block_index[i]] = s->mb_intra;
v->a_avail = v->c_avail = 0;
if(i == 2 || i == 3 || !s->first_slice_line)
v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
if(i == 1 || i == 3 || s->mb_x)
v->c_avail = v->mb_type[0][s->block_index[i] - 1];
vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;
v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
//TODO: yet to perform loop filter
}
} else {
s->mb_intra = v->is_intra[s->mb_x] = 0;
s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
if (v->fmb_is_raw)
fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
else
fwd = v->forward_mb_plane[mb_pos];
if (idx_mbmode <= 5) { // 1-MV
dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;
pred_flag[0] = pred_flag[1] = 0;
if (fwd)
bmvtype = BMV_TYPE_FORWARD;
else {
bmvtype = decode012(gb);
switch(bmvtype) {
case 0:
bmvtype = BMV_TYPE_BACKWARD;
break;
case 1:
bmvtype = BMV_TYPE_DIRECT;
break;
case 2:
bmvtype = BMV_TYPE_INTERPOLATED;
interpmvp = get_bits1(gb);
}
}
v->bmvtype = bmvtype;
if (bmvtype != BMV_TYPE_DIRECT && idx_mbmode & 1) {
get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
}
if (bmvtype == BMV_TYPE_INTERPOLATED && interpmvp) {
get_mvdata_interlaced(v, &dmv_x[1], &dmv_y[1], &pred_flag[1]);
}
if (bmvtype == BMV_TYPE_DIRECT) {
dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
dmv_x[1] = dmv_y[1] = pred_flag[0] = 0;
}
vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag);
vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype);
mb_has_coeffs = !(idx_mbmode & 2);
} else { // 4-MV
if (fwd)
bmvtype = BMV_TYPE_FORWARD;
v->bmvtype = bmvtype;
v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
for (i=0; i<6; i++) {
if (i < 4) {
dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
dmv_x[1] = dmv_y[1] = pred_flag[1] = 0;
val = ((v->fourmvbp >> (3 - i)) & 1);
if(val) {
get_mvdata_interlaced(v, &dmv_x[bmvtype == BMV_TYPE_BACKWARD], &dmv_y[bmvtype == BMV_TYPE_BACKWARD], &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
}
vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag);
vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD);
} else if (i == 4)
vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
}
mb_has_coeffs = idx_mbmode & 1;
}
if (mb_has_coeffs)
cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
if (cbp) {
GET_MQUANT();
}
s->current_picture.f.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && cbp) {
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
}
dst_idx = 0;
for (i=0; i<6; i++) {
s->dc_val[0][s->block_index[i]] = 0;
dst_idx += i >> 2;
val = ((cbp >> (5 - i)) & 1);
off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
if (v->cur_field_type)
off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
if(val) {
vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), NULL);
if(!v->ttmbf && ttmb < 8)
ttmb = -1;
first_block = 0;
}
}
}
}
/** Decode blocks of I-frame
*/
static void vc1_decode_i_blocks(VC1Context *v)
......@@ -3029,13 +4536,15 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
ff_update_block_index(s);
s->dsp.clear_blocks(block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_stride;
s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA;
s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
// do actual MB decoding and displaying
if (v->fieldtx_is_raw)
v->fieldtx_plane[mb_pos] = get_bits1(&v->s.gb);
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
if(v->acpred_is_raw)
if( v->acpred_is_raw)
v->s.ac_pred = get_bits1(&v->s.gb);
else
v->s.ac_pred = v->acpred_plane[mb_pos];
......@@ -3074,6 +4583,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
if(v->s.loop_filter) vc1_loop_filter_iblk_delayed(v, v->pq);
if(get_bits_count(&s->gb) > v->bits) {
// TODO: may need modification to handle slice coding
ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
return;
......@@ -3096,7 +4606,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
}
if (v->s.loop_filter)
ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, (AC_END|DC_END|MV_END));
}
static void vc1_decode_p_blocks(VC1Context *v)
......@@ -3138,10 +4648,15 @@ static void vc1_decode_p_blocks(VC1Context *v)
for(; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
vc1_decode_p_mb(v);
if (s->mb_y != s->start_mb_y && apply_loop_filter)
if (v->fcm == 2)
vc1_decode_p_mb_intfi(v);
else if (v->fcm == 1)
vc1_decode_p_mb_intfr(v);
else vc1_decode_p_mb(v);
if (s->mb_y != s->start_mb_y && apply_loop_filter && v->fcm == 0)
vc1_apply_p_loop_filter(v);
if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
// TODO: may need modification to handle slice coding
ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
return;
......@@ -3164,7 +4679,7 @@ static void vc1_decode_p_blocks(VC1Context *v)
}
if (s->end_mb_y >= s->start_mb_y)
ff_draw_horiz_band(s, (s->end_mb_y-1) * 16, 16);
ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, (AC_END|DC_END|MV_END));
}
static void vc1_decode_b_blocks(VC1Context *v)
......@@ -3203,8 +4718,12 @@ static void vc1_decode_b_blocks(VC1Context *v)
for(; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
vc1_decode_b_mb(v);
if (v->fcm == 2)
vc1_decode_b_mb_intfi(v);
else
vc1_decode_b_mb(v);
if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
// TODO: may need modification to handle slice coding
ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END));
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
return;
......@@ -3219,7 +4738,7 @@ static void vc1_decode_b_blocks(VC1Context *v)
}
if (v->s.loop_filter)
ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, (AC_END|DC_END|MV_END));
ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1, (s->end_mb_y << v->field_mode) - 1, (AC_END|DC_END|MV_END));
}
static void vc1_decode_skip_blocks(VC1Context *v)
......@@ -3559,6 +5078,8 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v)
/* Allocate mb bitplanes */
v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height);
v->direct_mb_plane = av_malloc(s->mb_stride * s->mb_height);
v->forward_mb_plane = av_malloc(s->mb_stride * s->mb_height);
v->fieldtx_plane = av_mallocz(s->mb_stride * s->mb_height);
v->acpred_plane = av_malloc(s->mb_stride * s->mb_height);
v->over_flags_plane = av_malloc(s->mb_stride * s->mb_height);
......@@ -3568,7 +5089,7 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v)
v->cbp = v->cbp_base + s->mb_stride;
v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride);
v->ttblk = v->ttblk_base + s->mb_stride;
v->is_intra_base = av_malloc(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride);
v->is_intra_base = av_mallocz(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride);
v->is_intra = v->is_intra_base + s->mb_stride;
v->luma_mv_base = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride);
v->luma_mv = v->luma_mv_base + s->mb_stride;
......@@ -3579,6 +5100,19 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v)
v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1;
v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1);
/* allocate memory to store block level MV info */
v->blk_mv_type_base = av_mallocz(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
v->blk_mv_type = v->blk_mv_type_base + s->b8_stride + 1;
v->mv_f_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
v->mv_f[0] = v->mv_f_base + s->b8_stride + 1;
v->mv_f[1] = v->mv_f[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
v->mv_f_last_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
v->mv_f_last[0] = v->mv_f_last_base + s->b8_stride + 1;
v->mv_f_last[1] = v->mv_f_last[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
v->mv_f_next[0] = v->mv_f_next_base + s->b8_stride + 1;
v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
/* Init coded blocks info */
if (v->profile == PROFILE_ADVANCED)
{
......@@ -3722,6 +5256,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
v->zz_8x8[1][i] = transpose(wmv1_scantable[1][i]);
v->zz_8x8[2][i] = transpose(wmv1_scantable[2][i]);
v->zz_8x8[3][i] = transpose(wmv1_scantable[3][i]);
v->zzi_8x8[i] = transpose(ff_vc1_adv_interlaced_8x8_zz[i]);
}
v->left_blk_sh = 0;
v->top_blk_sh = 3;
......@@ -3765,9 +5300,15 @@ static av_cold int vc1_decode_end(AVCodecContext *avctx)
MPV_common_end(&v->s);
av_freep(&v->mv_type_mb_plane);
av_freep(&v->direct_mb_plane);
av_freep(&v->forward_mb_plane);
av_freep(&v->fieldtx_plane);
av_freep(&v->acpred_plane);
av_freep(&v->over_flags_plane);
av_freep(&v->mb_type_base);
av_freep(&v->blk_mv_type_base);
av_freep(&v->mv_f_base);
av_freep(&v->mv_f_last_base);
av_freep(&v->mv_f_next_base);
av_freep(&v->block);
av_freep(&v->cbp_base);
av_freep(&v->ttblk_base);
......@@ -3791,7 +5332,9 @@ static int vc1_decode_frame(AVCodecContext *avctx,
MpegEncContext *s = &v->s;
AVFrame *pict = data;
uint8_t *buf2 = NULL;
uint8_t *buf_field2 = NULL;
const uint8_t *buf_start = buf;
int mb_height, n_slices1=-1;
struct {
uint8_t *buf;
GetBitContext gb;
......@@ -3839,6 +5382,26 @@ static int vc1_decode_frame(AVCodecContext *avctx,
buf_start = start;
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
break;
case VC1_CODE_FIELD: {
int buf_size3;
slices = av_realloc(slices, sizeof(*slices) * (n_slices+1));
if (!slices) goto err;
slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!slices[n_slices].buf) goto err;
buf_size3 = vc1_unescape_buffer(start + 4, size,
slices[n_slices].buf);
init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,
buf_size3 << 3);
/* assuming that the field marker is at the exact middle,
hope it's correct */
slices[n_slices].mby_start = s->mb_height >> 1;
n_slices1 = n_slices - 1; // index of the last slice of the first field
n_slices++;
// not necessary, ad hoc until I find a way to handle WVC1i
buf_field2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
vc1_unescape_buffer(start + 4, size, buf_field2);
break;
}
case VC1_CODE_ENTRYPOINT: /* it should be before frame data */
buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
init_get_bits(&s->gb, buf2, buf_size2*8);
......@@ -3867,13 +5430,11 @@ static int vc1_decode_frame(AVCodecContext *avctx,
if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){
av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n");
goto err;
} else { // found field marker, unescape second field
buf_field2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, buf_field2);
}
buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);
// TODO
if(!v->warn_interlaced++)
av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced WVC1 support is not implemented\n");
goto err;
}else{
buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);
}
......@@ -3925,6 +5486,7 @@ static int vc1_decode_frame(AVCodecContext *avctx,
}
// do parse frame header
v->pic_header_flag = 0;
if(v->profile < PROFILE_ADVANCED) {
if(vc1_parse_frame_header(v, &s->gb) == -1) {
goto err;
......@@ -3995,13 +5557,65 @@ static int vc1_decode_frame(AVCodecContext *avctx,
ff_er_frame_start(s);
v->bits = buf_size * 8;
if (v->field_mode) {
uint8_t *tmp[2];
s->current_picture.f.linesize[0] <<= 1;
s->current_picture.f.linesize[1] <<= 1;
s->current_picture.f.linesize[2] <<= 1;
s->linesize <<= 1;
s->uvlinesize <<= 1;
tmp[0] = v->mv_f_last[0];
tmp[1] = v->mv_f_last[1];
v->mv_f_last[0] = v->mv_f_next[0];
v->mv_f_last[1] = v->mv_f_next[1];
v->mv_f_next[0] = v->mv_f[0];
v->mv_f_next[1] = v->mv_f[1];
v->mv_f[0] = tmp[0];
v->mv_f[1] = tmp[1];
}
mb_height = s->mb_height >> v->field_mode;
for (i = 0; i <= n_slices; i++) {
if (i && get_bits1(&s->gb))
vc1_parse_frame_header_adv(v, &s->gb);
s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start);
s->end_mb_y = (i == n_slices) ? s->mb_height : FFMIN(s->mb_height, slices[i].mby_start);
if (i > 0 && slices[i - 1].mby_start >= mb_height) {
v->second_field = 1;
v->blocks_off = s->mb_width * s->mb_height << 1;
v->mb_off = s->mb_stride * s->mb_height >> 1;
} else {
v->second_field = 0;
v->blocks_off = 0;
v->mb_off = 0;
}
if (i) {
v->pic_header_flag = 0;
if (v->field_mode && i == n_slices1 + 2)
vc1_parse_frame_header_adv(v, &s->gb);
else if (get_bits1(&s->gb)) {
v->pic_header_flag = 1;
vc1_parse_frame_header_adv(v, &s->gb);
}
}
s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height);
if (!v->field_mode || v->second_field)
s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
else
s->end_mb_y = (i == n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
vc1_decode_blocks(v);
if (i != n_slices) s->gb = slices[i].gb;
if (i != n_slices)
s->gb = slices[i].gb;
}
if (v->field_mode) {
av_free(buf_field2);
v->second_field = 0;
}
if(v->field_mode){
if (s->pict_type == AV_PICTURE_TYPE_B) {
memcpy(v->mv_f_base, v->mv_f_next_base,
2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
}
s->current_picture.f.linesize[0] >>= 1;
s->current_picture.f.linesize[1] >>= 1;
s->current_picture.f.linesize[2] >>= 1;
s->linesize >>= 1;
s->uvlinesize >>= 1;
}
//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits);
// if(get_bits_count(&s->gb) > buf_size * 8)
......@@ -4011,9 +5625,6 @@ static int vc1_decode_frame(AVCodecContext *avctx,
MPV_frame_end(s);
assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
assert(s->current_picture.f.pict_type == s->pict_type);
if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
image:
avctx->width = avctx->coded_width = v->output_width;
......@@ -4051,6 +5662,7 @@ err:
for (i = 0; i < n_slices; i++)
av_free(slices[i].buf);
av_free(slices);
av_free(buf_field2);
return -1;
}
......
......@@ -688,6 +688,26 @@ static void put_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a
}
}
static void put_no_rnd_vc1_chroma_mc4_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y){
const int A=(8-x)*(8-y);
const int B=( x)*(8-y);
const int C=(8-x)*( y);
const int D=( x)*( y);
int i;
assert(x<8 && y<8 && x>=0 && y>=0);
for(i=0; i<h; i++)
{
dst[0] = (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + 32 - 4) >> 6;
dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6;
dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6;
dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6;
dst+= stride;
src+= stride;
}
}
#define avg2(a,b) ((a+b+1)>>1)
static void avg_no_rnd_vc1_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
const int A=(8-x)*(8-y);
......@@ -829,6 +849,7 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
dsp->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c;
dsp->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c;
dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = put_no_rnd_vc1_chroma_mc4_c;
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER
dsp->sprite_h = sprite_h_c;
......
......@@ -22,7 +22,7 @@
#define LIBAVCODEC_VERSION_MAJOR 53
#define LIBAVCODEC_VERSION_MINOR 20
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_MICRO 1
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
......
......@@ -177,7 +177,7 @@ static int fourxm_read_header(AVFormatContext *s,
sizeof(AudioTrack),
current_track + 1);
if (!fourxm->tracks) {
ret= AVERROR(ENOMEM);
ret = AVERROR(ENOMEM);
goto fail;
}
memset(&fourxm->tracks[fourxm->track_count], 0,
......
......@@ -874,12 +874,13 @@ static int avi_sync(AVFormatContext *s, int exit_early)
{
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
int n, d[8];
int n;
unsigned int d[8];
unsigned int size;
int64_t i, sync;
start_sync:
memset(d, -1, sizeof(int)*8);
memset(d, -1, sizeof(d));
for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
int j;
......@@ -891,7 +892,7 @@ start_sync:
n= get_stream_idx(d+2);
//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
if(i + (uint64_t)size > avi->fsize || d[0]<0)
if(i + (uint64_t)size > avi->fsize || d[0] > 127)
continue;
//parse ix##
......
......@@ -256,12 +256,13 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt,
if (length > 61444) /* worst case PAL 1920 samples 8 channels */
return -1;
av_new_packet(pkt, length);
avio_read(pb, pkt->data, length);
length = av_get_packet(pb, pkt, length);
if (length < 0)
return length;
data_ptr = pkt->data;
end_ptr = pkt->data + length;
buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
for (; buf_ptr < end_ptr; ) {
for (; buf_ptr + st->codec->channels*4 < end_ptr; ) {
for (i = 0; i < st->codec->channels; i++) {
uint32_t sample = bytestream_get_le32(&buf_ptr);
if (st->codec->bits_per_coded_sample == 24)
......@@ -271,7 +272,7 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt,
}
buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M
}
pkt->size = data_ptr - pkt->data;
av_shrink_packet(pkt, data_ptr - pkt->data);
return 0;
}
......@@ -323,12 +324,16 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv
if (memcmp(tmpbuf, checkv, 16))
av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
size -= 32;
av_get_packet(pb, pkt, size);
size = av_get_packet(pb, pkt, size);
if (size < 0)
return size;
else if (size < plaintext_size)
return AVERROR_INVALIDDATA;
size -= plaintext_size;
if (mxf->aesc)
av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
&pkt->data[plaintext_size], size >> 4, ivec, 1);
pkt->size = orig_size;
av_shrink_packet(pkt, orig_size);
pkt->stream_index = index;
avio_skip(pb, end - avio_tell(pb));
return 0;
......@@ -365,8 +370,11 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
return -1;
}
} else
av_get_packet(s->pb, pkt, klv.length);
} else {
int ret = av_get_packet(s->pb, pkt, klv.length);
if (ret < 0)
return ret;
}
pkt->stream_index = index;
pkt->pos = klv.offset;
return 0;
......
......@@ -53,22 +53,13 @@ const AVOption *av_next_option(void *obj, const AVOption *last)
else return (*(AVClass**)obj)->option;
}
static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out)
static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
{
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
if (o_out)
*o_out= o;
if (!o)
return AVERROR_OPTION_NOT_FOUND;
if (o->max*den < num*intnum || o->min*den > num*intnum) {
av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name);
av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, o->name);
return AVERROR(ERANGE);
}
dst= ((uint8_t*)obj) + o->offset;
switch (o->type) {
case FF_OPT_TYPE_FLAGS:
case FF_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break;
......@@ -85,15 +76,6 @@ static int av_set_number2(void *obj, const char *name, double num, int den, int6
return 0;
}
static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum)
{
const AVOption *o = NULL;
if (av_set_number2(obj, name, num, den, intnum, &o) < 0)
return NULL;
else
return o;
}
static const double const_values[] = {
M_PI,
M_E,
......@@ -115,10 +97,98 @@ static int hexchar2int(char c) {
return -1;
}
static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
{
int *lendst = (int *)(dst + 1);
uint8_t *bin, *ptr;
int len = strlen(val);
av_freep(dst);
*lendst = 0;
if (len & 1)
return AVERROR(EINVAL);
len /= 2;
ptr = bin = av_malloc(len);
while (*val) {
int a = hexchar2int(*val++);
int b = hexchar2int(*val++);
if (a < 0 || b < 0) {
av_free(bin);
return AVERROR(EINVAL);
}
*ptr++ = (a << 4) | b;
}
*dst = bin;
*lendst = len;
return 0;
}
static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
{
av_freep(dst);
*dst = av_strdup(val);
return 0;
}
static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst)
{
int ret = 0, notfirst = 0;
for (;;) {
int i;
char buf[256];
int cmd = 0;
double d;
if (*val == '+' || *val == '-')
cmd = *(val++);
for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
buf[i] = val[i];
buf[i] = 0;
{
const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
if (o_named && o_named->type == FF_OPT_TYPE_CONST)
d = o_named->default_val.dbl;
else if (!strcmp(buf, "default")) d = o->default_val.dbl;
else if (!strcmp(buf, "max" )) d = o->max;
else if (!strcmp(buf, "min" )) d = o->min;
else if (!strcmp(buf, "none" )) d = 0;
else if (!strcmp(buf, "all" )) d = ~0;
else {
int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
if (res < 0) {
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
return res;
}
}
}
if (o->type == FF_OPT_TYPE_FLAGS) {
if (cmd == '+') d = av_get_int(obj, o->name, NULL) | (int64_t)d;
else if (cmd == '-') d = av_get_int(obj, o->name, NULL) &~(int64_t)d;
} else {
if (cmd == '+') d = notfirst*av_get_double(obj, o->name, NULL) + d;
else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d;
}
if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
return ret;
val += i;
if (!*val)
return 0;
notfirst = 1;
}
return 0;
}
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
{
int ret;
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
if (o_out)
*o_out = o;
if (!o)
......@@ -126,100 +196,50 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
if (!val && o->type != FF_OPT_TYPE_STRING)
return AVERROR(EINVAL);
if (o->type == FF_OPT_TYPE_BINARY) {
uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset);
int *lendst = (int *)(dst + 1);
uint8_t *bin, *ptr;
int len = strlen(val);
av_freep(dst);
*lendst = 0;
if (len & 1) return AVERROR(EINVAL);
len /= 2;
ptr = bin = av_malloc(len);
while (*val) {
int a = hexchar2int(*val++);
int b = hexchar2int(*val++);
if (a < 0 || b < 0) {
av_free(bin);
return AVERROR(EINVAL);
}
*ptr++ = (a << 4) | b;
}
*dst = bin;
*lendst = len;
return 0;
dst = ((uint8_t*)obj) + o->offset;
switch (o->type) {
case FF_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
case FF_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
case FF_OPT_TYPE_FLAGS:
case FF_OPT_TYPE_INT:
case FF_OPT_TYPE_INT64:
case FF_OPT_TYPE_FLOAT:
case FF_OPT_TYPE_DOUBLE:
case FF_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
}
if (o->type != FF_OPT_TYPE_STRING) {
int notfirst=0;
for (;;) {
int i;
char buf[256];
int cmd=0;
double d;
if (*val == '+' || *val == '-')
cmd= *(val++);
for (i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)
buf[i]= val[i];
buf[i]=0;
{
const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
if (o_named && o_named->type == FF_OPT_TYPE_CONST)
d= o_named->default_val.dbl;
else if (!strcmp(buf, "default")) d= o->default_val.dbl;
else if (!strcmp(buf, "max" )) d= o->max;
else if (!strcmp(buf, "min" )) d= o->min;
else if (!strcmp(buf, "none" )) d= 0;
else if (!strcmp(buf, "all" )) d= ~0;
else {
int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
if (res < 0) {
av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
return res;
}
}
}
if (o->type == FF_OPT_TYPE_FLAGS) {
if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;
else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;
} else {
if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d;
else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d;
}
if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0)
return ret;
val+= i;
if (!*val)
return 0;
notfirst=1;
}
}
av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
return AVERROR(EINVAL);
}
if (alloc) {
av_free(*(void**)(((uint8_t*)obj) + o->offset));
val= av_strdup(val);
}
static const AVOption *set_number(void *obj, const char *name, double num, int den, int64_t intnum)
{
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val));
return 0;
if (!o)
return NULL;
dst = ((uint8_t*)obj) + o->offset;
if (write_number(obj, o, dst, num, den, intnum) < 0)
return NULL;
else
return o;
}
const AVOption *av_set_double(void *obj, const char *name, double n)
{
return av_set_number(obj, name, n, 1, 1);
return set_number(obj, name, n, 1, 1);
}
const AVOption *av_set_q(void *obj, const char *name, AVRational n)
{
return av_set_number(obj, name, n.num, n.den, 1);
return set_number(obj, name, n.num, n.den, 1);
}
const AVOption *av_set_int(void *obj, const char *name, int64_t n)
{
return av_set_number(obj, name, 1, 1, n);
return set_number(obj, name, 1, 1, n);
}
/**
......
......@@ -129,9 +129,7 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m
* similarly, '-' unsets a flag.
* @param[out] o_out if non-NULL put here a pointer to the AVOption
* found
* @param alloc when 1 then the old value will be av_freed() and the
* new av_strduped()
* when 0 then no av_free() nor av_strdup() will be used
* @param alloc this parameter is currently ignored
* @return 0 if the value has been set, or an AVERROR code in case of
* error:
* AVERROR_OPTION_NOT_FOUND if no matching option exists
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册