*/
#include "internal.h"
-#include "dsputil.h"
#include "avcodec.h"
+#include "error_resilience.h"
+#include "mpeg_er.h"
+#include "mpegutils.h"
#include "mpegvideo.h"
#include "h263.h"
+#include "h264chroma.h"
+#include "qpeldsp.h"
#include "vc1.h"
#include "vc1data.h"
#include "vc1acdata.h"
#include "msmpeg4data.h"
#include "unary.h"
-#include "simple_idct.h"
#include "mathops.h"
-#include "vdpau_internal.h"
#undef NDEBUG
#include <assert.h>
};
/** @} */ //imode defines
+static void init_block_index(VC1Context *v)
+{
+ MpegEncContext *s = &v->s;
+ ff_init_block_index(s);
+ if (v->field_mode && !(v->second_field ^ v->tff)) {
+ s->dest[0] += s->current_picture_ptr->f->linesize[0];
+ s->dest[1] += s->current_picture_ptr->f->linesize[1];
+ s->dest[2] += s->current_picture_ptr->f->linesize[2];
+ }
+}
/** @} */ //Bitplane group
{
MpegEncContext *s = &v->s;
int topleft_mb_pos, top_mb_pos;
- int stride_y, fieldtx;
+ int stride_y, fieldtx = 0;
int v_dist;
/* The put pixels loop is always one MB row behind the decoding loop,
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];
+ if (v->fcm == ILACE_FRAME)
+ 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,
- stride_y);
- s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
- s->dest[0] - 16 * s->linesize - 8,
- stride_y);
- s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
- 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] - 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);
- s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][5],
- s->dest[2] - 8 * s->uvlinesize - 8,
- s->uvlinesize);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
+ s->dest[0] - 16 * s->linesize - 16,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][1],
+ s->dest[0] - 16 * s->linesize - 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][2],
+ s->dest[0] - v_dist * s->linesize - 16,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][3],
+ s->dest[0] - v_dist * s->linesize - 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][4],
+ s->dest[1] - 8 * s->uvlinesize - 8,
+ s->uvlinesize);
+ s->idsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][5],
+ s->dest[2] - 8 * s->uvlinesize - 8,
+ 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];
+ if (v->fcm == ILACE_FRAME)
+ 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,
- stride_y);
- s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
- s->dest[0] - 16 * s->linesize + 8,
- stride_y);
- s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
- 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] - 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);
- s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][5],
- s->dest[2] - 8 * s->uvlinesize,
- s->uvlinesize);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
+ s->dest[0] - 16 * s->linesize,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][1],
+ s->dest[0] - 16 * s->linesize + 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][2],
+ s->dest[0] - v_dist * s->linesize,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][3],
+ s->dest[0] - v_dist * s->linesize + 8,
+ stride_y);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][4],
+ s->dest[1] - 8 * s->uvlinesize,
+ s->uvlinesize);
+ s->idsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][5],
+ s->dest[2] - 8 * s->uvlinesize,
+ s->uvlinesize);
}
}
static void vc1_mc_1mv(VC1Context *v, int dir)
{
MpegEncContext *s = &v->s;
- DSPContext *dsp = &v->s.dsp;
+ H264ChromaContext *h264chroma = &v->h264chroma;
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;
+ int i;
+ uint8_t (*luty)[256], (*lutuv)[256];
+ int use_ic;
if ((!v->field_mode ||
(v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
- !v->s.last_picture.f.data[0])
+ !v->s.last_picture.f->data[0])
return;
mx = s->mv[dir][0][0];
// 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] + v->blocks_off][0] = mx;
- s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my;
+ for (i = 0; i < 4; i++) {
+ s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
+ s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
+ }
}
uvmx = (mx + ((mx & 3) == 3)) >> 1;
uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
}
- 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];
- }
+ if (!dir) {
+ if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+ srcY = s->current_picture.f->data[0];
+ srcU = s->current_picture.f->data[1];
+ srcV = s->current_picture.f->data[2];
+ luty = v->curr_luty;
+ lutuv = v->curr_lutuv;
+ use_ic = v->curr_use_ic;
} else {
- srcY = s->next_picture.f.data[0];
- srcU = s->next_picture.f.data[1];
- srcV = s->next_picture.f.data[2];
+ srcY = s->last_picture.f->data[0];
+ srcU = s->last_picture.f->data[1];
+ srcV = s->last_picture.f->data[2];
+ luty = v->last_luty;
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
}
} else {
- 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];
- }
+ srcY = s->next_picture.f->data[0];
+ srcU = s->next_picture.f->data[1];
+ srcV = s->next_picture.f->data[2];
+ luty = v->next_luty;
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
+ }
+
+ if (!srcY || !srcU) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
+ return;
}
src_x = s->mb_x * 16 + (mx >> 2);
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];
+ 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 */
srcV = s->edge_emu_buffer + 18 * s->linesize;
}
- if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+ if (v->rangeredfrm || use_ic
|| s->h_edge_pos < 22 || v_edge_pos < 22
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
- || (unsigned)(src_y - s->mspel) > v_edge_pos - (my&3) - 16 - s->mspel * 3) {
+ || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 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, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, s->linesize,
+ 17 + s->mspel * 2, 17 + s->mspel * 2,
+ 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, 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, v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(uvbuf, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 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 */
}
}
/* if we deal with intensity compensation we need to scale source blocks */
- if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (use_ic) {
int i, j;
uint8_t *src, *src2;
src = srcY;
for (j = 0; j < 17 + s->mspel * 2; j++) {
+ int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ;
for (i = 0; i < 17 + s->mspel * 2; i++)
- src[i] = v->luty[src[i]];
+ src[i] = luty[f][src[i]];
src += s->linesize;
}
src = srcU;
src2 = srcV;
for (j = 0; j < 9; j++) {
+ int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);
for (i = 0; i < 9; i++) {
- src[i] = v->lutuv[src[i]];
- src2[i] = v->lutuv[src2[i]];
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
}
src += s->uvlinesize;
src2 += s->uvlinesize;
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] + 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);
+ 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);
srcY += s->linesize * 8;
- 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);
+ 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);
} 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] + off, srcY, s->linesize, 16);
+ s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
else
- dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+ s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
}
if (s->flags & CODEC_FLAG_GRAY) return;
uvmx = (uvmx & 3) << 1;
uvmy = (uvmy & 3) << 1;
if (!v->rnd) {
- 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);
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
} else {
- 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);
+ 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);
}
}
/** Do motion compensation for 4-MV macroblock - luminance block
*/
-static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
+static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
{
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 == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ uint8_t (*luty)[256];
+ int use_ic;
if ((!v->field_mode ||
(v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
- !v->s.last_picture.f.data[0])
+ !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->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+ srcY = s->current_picture.f->data[0];
+ luty = v->curr_luty;
+ use_ic = v->curr_use_ic;
+ } else {
+ srcY = s->last_picture.f->data[0];
+ luty = v->last_luty;
+ use_ic = v->last_use_ic;
+ }
+ } else {
+ srcY = s->next_picture.f->data[0];
+ luty = v->next_luty;
+ use_ic = v->next_use_ic;
+ }
+
+ if (!srcY) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
+ return;
+ }
if (v->field_mode) {
if (v->cur_field_type != v->ref_field_type[dir])
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;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+ s->current_picture.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;
}
int qx, qy;
int width = s->avctx->coded_width;
int height = s->avctx->coded_height >> 1;
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
+ s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
+ }
qx = (s->mb_x * 16) + (mx >> 2);
qy = (s->mb_y * 8) + (my >> 3);
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);
if (!fieldmv)
srcY += src_y * s->linesize + src_x;
if (v->field_mode && v->ref_field_type[dir])
- srcY += s->current_picture_ptr->f.linesize[0];
+ 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)
+ if (v->rangeredfrm || use_ic
|| s->h_edge_pos < 13 || v_edge_pos < 23
|| (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
|| (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);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, 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) {
}
}
/* if we deal with intensity compensation we need to scale source blocks */
- if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (use_ic) {
int i, j;
uint8_t *src;
src = srcY;
for (j = 0; j < 9 + s->mspel * 2; j++) {
+ int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);
for (i = 0; i < 9 + s->mspel * 2; i++)
- src[i] = v->luty[src[i]];
+ src[i] = luty[f][src[i]];
src += 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 << fieldmv, v->rnd);
+ if (avg)
+ v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
+ else
+ 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)
- dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
+ s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
else
- dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
+ s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
}
}
static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
{
MpegEncContext *s = &v->s;
- DSPContext *dsp = &v->s.dsp;
+ H264ChromaContext *h264chroma = &v->h264chroma;
uint8_t *srcU, *srcV;
int uvmx, uvmy, uvsrc_x, uvsrc_y;
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 chroma_ref_type = v->cur_field_type;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
+ uint8_t (*lutuv)[256];
+ int use_ic;
- if (!v->field_mode && !v->s.last_picture.f.data[0])
+ if (!v->field_mode && !v->s.last_picture.f->data[0])
return;
if (s->flags & CODEC_FLAG_GRAY)
return;
/* calculate chroma MV vector from four luma MVs */
if (!v->field_mode || (v->field_mode && !v->numref)) {
valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
+ chroma_ref_type = v->reffield;
if (!valid_count) {
- 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.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
return; //no need to do MC for intra blocks
}
if (dominant)
chroma_ref_type = !v->cur_field_type;
}
- if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0])
+ if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
return;
- 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;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
uvmx = (tx + ((tx & 3) == 3)) >> 1;
uvmy = (ty + ((ty & 3) == 3)) >> 1;
}
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;
- }
+ if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
+ srcU = s->current_picture.f->data[1];
+ srcV = s->current_picture.f->data[2];
+ lutuv = v->curr_lutuv;
+ use_ic = v->curr_use_ic;
} 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;
+ srcU = s->last_picture.f->data[1];
+ srcV = s->last_picture.f->data[2];
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
}
} 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;
+ srcU = s->next_picture.f->data[1];
+ srcV = s->next_picture.f->data[2];
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
}
+ if (!srcU) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
+ return;
+ }
+
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += 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];
+ 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)
+ if (v->rangeredfrm || use_ic
|| s->h_edge_pos < 18 || v_edge_pos < 18
|| (unsigned)uvsrc_x > (s->h_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, 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, v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 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;
}
}
/* if we deal with intensity compensation we need to scale source blocks */
- if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+ if (use_ic) {
int i, j;
uint8_t *src, *src2;
src = srcU;
src2 = srcV;
for (j = 0; j < 9; j++) {
+ int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1);
for (i = 0; i < 9; i++) {
- src[i] = v->lutuv[src[i]];
- src2[i] = v->lutuv[src2[i]];
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
}
src += s->uvlinesize;
src2 += s->uvlinesize;
uvmx = (uvmx & 3) << 1;
uvmy = (uvmy & 3) << 1;
if (!v->rnd) {
- 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);
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
} else {
- 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);
+ 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);
}
}
-/** Do motion compensation for 4-MV field chroma macroblock (both U and V)
+/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
*/
-static void vc1_mc_4mv_chroma4(VC1Context *v)
+static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
{
MpegEncContext *s = &v->s;
- DSPContext *dsp = &v->s.dsp;
+ H264ChromaContext *h264chroma = &v->h264chroma;
uint8_t *srcU, *srcV;
int uvsrc_x, uvsrc_y;
int uvmx_field[4], uvmy_field[4];
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;
+ int use_ic;
+ uint8_t (*lutuv)[256];
- 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];
+ int d = i < 2 ? dir: dir2;
+ tx = s->mv[d][i][0];
uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
- ty = s->mv[0][i][1];
+ ty = s->mv[d][i][1];
if (fieldmv)
uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
else
// 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;
+ if (i < 2 ? dir : dir2) {
+ 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;
+ lutuv = v->next_lutuv;
+ use_ic = v->next_use_ic;
+ } 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;
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
+ }
uvmx_field[i] = (uvmx_field[i] & 3) << 1;
uvmy_field[i] = (uvmy_field[i] & 3) << 1;
v_edge_pos--;
if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
uvsrc_y--;
- if ((v->mv_mode == MV_PMODE_INTENSITY_COMP)
+ if (use_ic
|| s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
|| (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);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 5, (5 << fieldmv), uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
+ s->uvlinesize, 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) {
+ if (use_ic) {
int i, j;
uint8_t *src, *src2;
src = srcU;
src2 = srcV;
for (j = 0; j < 5; j++) {
+ int f = (uvsrc_y + (j << fieldmv)) & 1;
for (i = 0; i < 5; i++) {
- src[i] = v->lutuv[src[i]];
- src2[i] = v->lutuv[src2[i]];
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
}
- src += s->uvlinesize << 1;
- src2 += s->uvlinesize << 1;
+ src += s->uvlinesize << fieldmv;
+ src2 += s->uvlinesize << fieldmv;
}
}
}
- 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]);
+ if (avg) {
+ if (!v->rnd) {
+ h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ } else {
+ v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ v->vc1dsp.avg_no_rnd_vc1_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]);
+ if (!v->rnd) {
+ h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+ h264chroma->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]);
+ }
}
}
}
mquant = v->altpq; \
if ((edges&8) && s->mb_y == (s->mb_height - 1)) \
mquant = v->altpq; \
+ if (!mquant || mquant > 31) { \
+ av_log(v->s.avctx, AV_LOG_ERROR, \
+ "Overriding invalid mquant %d\n", mquant); \
+ mquant = 1; \
+ } \
}
/**
*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;
+ if (pred_flag) {
+ *pred_flag = *dmv_y & 1;
+ *dmv_y = (*dmv_y + *pred_flag) >> 1;
+ } else {
+ *dmv_y = (*dmv_y + (*dmv_y & 1)) >> 1;
+ }
}
}
else {
*dmv_y = (sign ^ ((val >> 1) + offs_tab[index1 >> v->numref])) - sign;
} else
*dmv_y = 0;
- if (v->numref)
+ if (v->numref && pred_flag)
*pred_flag = index1 & 1;
}
}
int px, py;
int sum;
int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
- int opposit, a_f, b_f, c_f;
+ int opposite, a_f, b_f, c_f;
int16_t field_predA[2];
int16_t field_predB[2];
int16_t field_predC[2];
xy = s->block_index[n];
if (s->mb_intra) {
- 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;
+ s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
+ s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
+ s->current_picture.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 + 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;
+ s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->current_picture.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 + 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;
+ s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
}
return;
}
- 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];
+ C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off];
+ A = s->current_picture.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;
off = -1;
}
}
- B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off];
+ B = s->current_picture.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);
}
if (v->field_mode) {
- if (num_samefield <= num_oppfield)
- opposit = 1 - pred_flag;
- else
- opposit = pred_flag;
+ if (!v->numref)
+ // REFFIELD determines if the last field or the second-last field is
+ // to be used as reference
+ opposite = 1 - v->reffield;
+ else {
+ if (num_samefield <= num_oppfield)
+ opposite = 1 - pred_flag;
+ else
+ opposite = pred_flag;
+ }
} else
- opposit = 0;
- if (opposit) {
+ opposite = 0;
+ if (opposite) {
if (a_valid && !a_f) {
field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
}
}
- 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;
+ s->mv[dir][n][0] = s->current_picture.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.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];
+ s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.motion_val[dir][xy + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+ s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.motion_val[dir][xy + wrap + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+ s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+ s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.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)
+ int mvn, int r_x, int r_y, uint8_t* is_intra, int dir)
{
MpegEncContext *s = &v->s;
int xy, wrap, off = 0;
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.motion_val[0][xy][0] = 0;
+ s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
+ s->current_picture.motion_val[1][xy][0] = 0;
+ s->current_picture.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;
+ s->current_picture.motion_val[0][xy + 1][0] = 0;
+ s->current_picture.motion_val[0][xy + 1][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap][0] = 0;
+ s->current_picture.motion_val[0][xy + wrap][1] = 0;
+ s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
+ s->current_picture.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;
+ s->current_picture.motion_val[1][xy + 1][0] = 0;
+ s->current_picture.motion_val[1][xy + 1][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
}
return;
}
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[0] = s->current_picture.motion_val[dir][xy - 1][0];
+ A[1] = s->current_picture.motion_val[dir][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[0] = (s->current_picture.motion_val[dir][xy - 1][0]
+ + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
+ A[1] = (s->current_picture.motion_val[dir][xy - 1][1]
+ + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
a_valid = 1;
}
if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
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];
+ B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
+ B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
- B[0] = (B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
- B[1] = (B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
+ B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
+ B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
}
}
if (s->mb_width > 1) {
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];
+ C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
+ C[1] = s->current_picture.motion_val[dir][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;
+ C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
+ C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][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]) {
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];
+ C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
+ C[1] = s->current_picture.motion_val[dir][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;
+ C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
+ C[1] = (1 + C[1] + s->current_picture.motion_val[dir][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];
+ B[0] = s->current_picture.motion_val[dir][pos_b][0];
+ B[1] = s->current_picture.motion_val[dir][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];
+ C[0] = s->current_picture.motion_val[dir][pos_c][0];
+ C[1] = s->current_picture.motion_val[dir][pos_c][1];
}
total_valid = a_valid + b_valid + c_valid;
} else if (c_valid) {
px = C[0];
py = C[1];
- }
+ } else
+ px = py = 0;
}
} else if (total_valid == 1) {
px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[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;
+ s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+ s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
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];
+ s->current_picture.motion_val[dir][xy + 1 ][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + 1 ][1] = s->current_picture.motion_val[dir][xy][1];
+ s->current_picture.motion_val[dir][xy + wrap ][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + wrap ][1] = s->current_picture.motion_val[dir][xy][1];
+ s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][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];
+ s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0];
+ s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1];
+ s->mv[dir][n + 1][0] = s->mv[dir][n][0];
+ s->mv[dir][n + 1][1] = s->mv[dir][n][1];
}
}
static void vc1_interp_mc(VC1Context *v)
{
MpegEncContext *s = &v->s;
- DSPContext *dsp = &v->s.dsp;
+ H264ChromaContext *h264chroma = &v->h264chroma;
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;
+ int use_ic = v->next_use_ic;
- if (!v->field_mode && !v->s.next_picture.f.data[0])
+ if (!v->field_mode && !v->s.next_picture.f->data[0])
return;
mx = s->mv[1][0][0];
uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
}
- srcY = s->next_picture.f.data[0];
- srcU = s->next_picture.f.data[1];
- srcV = s->next_picture.f.data[2];
+ 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);
src_y = s->mb_y * 16 + (my >> 2);
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];
+ 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 */
srcV = s->edge_emu_buffer + 18 * s->linesize;
}
- if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22
- || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 16 - s->mspel * 3
- || (unsigned)(src_y - s->mspel) > v_edge_pos - (my & 3) - 16 - s->mspel * 3) {
+ if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
+ || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
+ || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 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, v_edge_pos);
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+ s->linesize, s->linesize,
+ 17 + s->mspel * 2, 17 + s->mspel * 2,
+ 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, 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, v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(uvbuf, srcU,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 1,
+ uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+ s->uvlinesize, s->uvlinesize,
+ 8 + 1, 8 + 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 */
src2 += s->uvlinesize;
}
}
+
+ if (use_ic) {
+ uint8_t (*luty )[256] = v->next_luty;
+ uint8_t (*lutuv)[256] = v->next_lutuv;
+ int i, j;
+ uint8_t *src, *src2;
+
+ src = srcY;
+ for (j = 0; j < 17 + s->mspel * 2; j++) {
+ int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1);
+ for (i = 0; i < 17 + s->mspel * 2; i++)
+ src[i] = luty[f][src[i]];
+ src += s->linesize;
+ }
+ src = srcU;
+ src2 = srcV;
+ for (j = 0; j < 9; j++) {
+ int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1);
+ for (i = 0; i < 9; i++) {
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
+ }
+ src += s->uvlinesize;
+ src2 += s->uvlinesize;
+ }
+ }
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;
- }
+ off = 0;
+ off_uv = 0;
if (s->mspel) {
dxy = ((my & 3) << 2) | (mx & 3);
dxy = (my & 2) | ((mx & 2) >> 1);
if (!v->rnd)
- dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+ s->hdsp.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] + off, srcY, s->linesize, 16);
+ s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
}
if (s->flags & CODEC_FLAG_GRAY) return;
uvmx = (uvmx & 3) << 1;
uvmy = (uvmy & 3) << 1;
if (!v->rnd) {
- 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);
+ h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+ h264chroma->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] + 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);
#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)
{
- if (v->use_ic) {
- v->mv_mode2 = v->mv_mode;
- v->mv_mode = MV_PMODE_INTENSITY_COMP;
- }
if (direct) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
- if (v->use_ic)
- v->mv_mode = v->mv_mode2;
return;
}
if (mode == BMV_TYPE_INTERPOLATED) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
- if (v->use_ic)
- v->mv_mode = v->mv_mode2;
return;
}
- if (v->use_ic && (mode == BMV_TYPE_BACKWARD))
- v->mv_mode = v->mv_mode2;
vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
- if (v->use_ic)
- v->mv_mode = v->mv_mode2;
}
static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
xy = s->block_index[0];
if (s->mb_intra) {
- 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;
+ s->current_picture.motion_val[0][xy + v->blocks_off][0] =
+ s->current_picture.motion_val[0][xy + v->blocks_off][1] =
+ s->current_picture.motion_val[1][xy + v->blocks_off][0] =
+ s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
return;
}
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);
+ s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_picture.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[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 + 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];
+ s->current_picture.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
+ s->current_picture.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
+ s->current_picture.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
+ s->current_picture.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
return;
}
if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
- C = s->current_picture.f.motion_val[0][xy - 2];
- A = s->current_picture.f.motion_val[0][xy - wrap * 2];
+ C = s->current_picture.motion_val[0][xy - 2];
+ A = s->current_picture.motion_val[0][xy - wrap * 2];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- B = s->current_picture.f.motion_val[0][xy - wrap * 2 + off];
+ B = s->current_picture.motion_val[0][xy - wrap * 2 + off];
if (!s->mb_x) C[0] = C[1] = 0;
if (!s->first_slice_line) { // predictor A is not out of bounds
s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
}
if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
- C = s->current_picture.f.motion_val[1][xy - 2];
- A = s->current_picture.f.motion_val[1][xy - wrap * 2];
+ C = s->current_picture.motion_val[1][xy - 2];
+ A = s->current_picture.motion_val[1][xy - wrap * 2];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
- B = s->current_picture.f.motion_val[1][xy - wrap * 2 + off];
+ B = s->current_picture.motion_val[1][xy - wrap * 2 + off];
if (!s->mb_x)
C[0] = C[1] = 0;
s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
}
- 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.motion_val[0][xy][0] = s->mv[0][0][0];
+ s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
+ s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
+ s->current_picture.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)
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);
+ if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
+ s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
+ v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
+ v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
+ v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
+ v->bfraction, 1, s->quarter_sample);
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->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];
+ s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
+ s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
+ s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
+ s->current_picture.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;
}
b = dc_val[ - 1 - wrap];
a = dc_val[ - wrap];
/* scale predictors if needed */
- q1 = s->current_picture.f.qscale_table[mb_pos];
+ q1 = s->current_picture.qscale_table[mb_pos];
dqscale_index = s->y_dc_scale_table[q1] - 1;
if (dqscale_index < 0)
return 0;
if (c_avail && (n != 1 && n != 3)) {
- q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+ q2 = s->current_picture.qscale_table[mb_pos - 1];
if (q2 && q2 != q1)
c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
}
if (a_avail && (n != 2 && n != 3)) {
- q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+ q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
if (q2 && q2 != q1)
a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
}
off--;
if (n != 2)
off -= s->mb_stride;
- q2 = s->current_picture.f.qscale_table[off];
+ q2 = s->current_picture.qscale_table[off];
if (q2 && q2 != q1)
b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
}
* @param coded are AC coeffs present or not
* @param codingset set of VLC to decode data
*/
-static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
int coded, int codingset)
{
GetBitContext *gb = &v->s.gb;
* @param codingset set of VLC to decode data
* @param mquant quantizer value for this macroblock
*/
-static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
int coded, int codingset, int mquant)
{
GetBitContext *gb = &v->s.gb;
else // top
ac_val -= 16 * s->block_wrap[n];
- q1 = s->current_picture.f.qscale_table[mb_pos];
+ q1 = s->current_picture.qscale_table[mb_pos];
if ( dc_pred_dir && c_avail && mb_pos)
- q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+ q2 = s->current_picture.qscale_table[mb_pos - 1];
if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
- q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+ q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
if ( dc_pred_dir && n == 1)
q2 = q1;
if (!dc_pred_dir && n == 2)
* @param mquant block quantizer
* @param codingset set of VLC to decode data
*/
-static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
int coded, int mquant, int codingset)
{
GetBitContext *gb = &v->s.gb;
int scale;
int q1, q2 = 0;
- s->dsp.clear_block(block);
+ s->bdsp.clear_block(block);
/* XXX: Guard against dumb values of mquant */
mquant = (mquant < 1) ? 0 : ((mquant > 31) ? 31 : mquant);
else //top
ac_val -= 16 * s->block_wrap[n];
- q1 = s->current_picture.f.qscale_table[mb_pos];
+ q1 = s->current_picture.qscale_table[mb_pos];
if (dc_pred_dir && c_avail && mb_pos)
- q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+ q2 = s->current_picture.qscale_table[mb_pos - 1];
if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
- q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+ q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
if ( dc_pred_dir && n == 1)
q2 = q1;
if (!dc_pred_dir && n == 2)
/** Decode P block
*/
-static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n,
int mquant, int ttmb, int first_block,
uint8_t *dst, int linesize, int skip_block,
int *ttmb_out)
int ttblk = ttmb & 7;
int pat = 0;
- s->dsp.clear_block(block);
+ s->bdsp.clear_block(block);
if (ttmb == -1) {
ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
v->vc1dsp.vc1_inv_trans_8x8_dc(dst, linesize, block);
else {
v->vc1dsp.vc1_inv_trans_8x8(block);
- s->dsp.add_pixels_clamped(block, dst, linesize);
+ s->idsp.add_pixels_clamped(block, dst, linesize);
}
}
break;
bottom_is_intra = (block_num < 2) ? (mb_is_intra >> ((block_num + 2) * 4))
: (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
mv_stride = s->b8_stride;
- mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
+ mv = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
}
if (bottom_is_intra & 1 || block_is_intra & 1 ||
: (mb_cbp >> ((block_num + 1) * 4));
right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
: (mb_is_intra >> ((block_num + 1) * 4));
- mv = &s->current_picture.f.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
+ mv = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
}
if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
GET_MVDATA(dmv_x, dmv_y);
if (s->mb_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.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.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;
+ s->current_picture.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], 0, 0);
/* FIXME Set DC val for inter block ? */
mquant = v->pq;
cbp = 0;
}
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
if (v->rangeredfrm)
for (j = 0; j < 64; j++)
s->block[i][j] <<= 1;
- s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ i & 4 ? s->uvlinesize
+ : s->linesize);
if (v->pq >= 9 && v->overlap) {
if (v->c_avail)
v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
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;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.qscale_table[mb_pos] = 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);
}
}
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);
+ vc1_mc_4mv_luma(v, i, 0, 0);
intra_count += s->mb_intra;
is_intra[i] = s->mb_intra;
is_coded[i] = mb_has_coeffs;
if (!intra_count && !coded_inter)
goto end;
GET_MQUANT();
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.qscale_table[mb_pos] = mquant;
/* test if block is intra and has pred */
{
int intrapred = 0;
if (v->rangeredfrm)
for (j = 0; j < 64; j++)
s->block[i][j] <<= 1;
- s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off,
- (i & 4) ? s->uvlinesize : s->linesize);
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ (i & 4) ? s->uvlinesize
+ : s->linesize);
if (v->pq >= 9 && v->overlap) {
if (v->c_avail)
v->vc1dsp.vc1_h_overlap(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
}
} else { // skipped MB
s->mb_intra = 0;
- s->current_picture.f.qscale_table[mb_pos] = 0;
+ s->current_picture.qscale_table[mb_pos] = 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;
}
for (i = 0; i < 4; 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_luma(v, i, 0, 0);
}
vc1_mc_4mv_chroma(v, 0);
- s->current_picture.f.qscale_table[mb_pos] = 0;
+ s->current_picture.qscale_table[mb_pos] = 0;
}
}
end:
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;
+ for (i = 0; i < 4; i++) {
+ s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
+ }
+ s->current_picture.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;
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;
+ s->current_picture.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];
stride_y = s->uvlinesize;
off = 0;
}
- s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y);
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ stride_y);
//TODO: loop filter
}
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);
+ vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0);
+ vc1_mc_4mv_luma(v, i, 0, 0);
} else if (i == 4) {
- vc1_mc_4mv_chroma4(v);
+ vc1_mc_4mv_chroma4(v, 0, 0, 0);
}
}
} else if (twomv) {
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);
+ vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
+ vc1_mc_4mv_luma(v, 0, 0, 0);
+ vc1_mc_4mv_luma(v, 1, 0, 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);
+ vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
+ vc1_mc_4mv_luma(v, 2, 0, 0);
+ vc1_mc_4mv_luma(v, 3, 0, 0);
+ vc1_mc_4mv_chroma4(v, 0, 0, 0);
} else {
mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
dmv_x = dmv_y = 0;
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_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
vc1_mc_1mv(v, 0);
}
if (cbp)
GET_MQUANT(); // p. 227
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.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++) {
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;
+ s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.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_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
vc1_mc_1mv(v, 0);
}
if (s->mb_x == s->mb_width - 1)
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;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
GET_MQUANT();
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.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];
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);
+ s->idsp.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;
+ s->current_picture.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 = pred_flag = 0;
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);
+ vc1_mc_4mv_luma(v, i, 0, 0);
} else if (i == 4)
vc1_mc_4mv_chroma(v, 0);
}
if (cbp) {
GET_MQUANT();
}
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.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 += 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,
v->mb_type[0][s->block_index[i]] = 0;
s->dc_val[0][s->block_index[i]] = 0;
}
- s->current_picture.f.qscale_table[mb_pos] = 0;
+ s->current_picture.qscale_table[mb_pos] = 0;
if (!direct) {
if (!skipped) {
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
s->mb_intra = 0;
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.qscale_table[mb_pos] = mquant;
if (!v->ttmbf)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
}
if (s->mb_intra && !mb_has_coeffs) {
GET_MQUANT();
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.qscale_table[mb_pos] = mquant;
s->ac_pred = get_bits1(gb);
cbp = 0;
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
s->ac_pred = get_bits1(gb);
cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
GET_MQUANT();
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.qscale_table[mb_pos] = mquant;
if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
}
if (v->rangeredfrm)
for (j = 0; j < 64; j++)
s->block[i][j] <<= 1;
- s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);
+ s->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ i & 4 ? s->uvlinesize
+ : s->linesize);
} else if (val) {
vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
first_block, s->dest[dst_idx] + off,
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;
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
GET_MQUANT();
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.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];
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);
+ s->idsp.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;
+ s->current_picture.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);
&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);
+ vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD, 0);
} else if (i == 4)
vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
}
if (cbp) {
GET_MQUANT();
}
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.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 += 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,
}
}
+/** Decode one B-frame MB (in interlaced frame B picture)
+ */
+static int vc1_decode_b_mb_intfr(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 mvsw = 0; /* motion vector switch */
+ 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, direct, twomv = 0;
+ int block_cbp = 0, pat, block_tt = 0;
+ int idx_mbmode = 0, mvbp;
+ int stride_y, fieldtx;
+ int bmvtype = BMV_TYPE_BACKWARD;
+ int dir, dir2;
+
+ mquant = v->pq; /* Lossy initialization */
+ s->mb_intra = 0;
+ if (v->skip_is_raw)
+ skipped = get_bits1(gb);
+ else
+ skipped = v->s.mbskip_table[mb_pos];
+
+ if (!skipped) {
+ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
+ if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == 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;
+ } else {
+ 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;
+ }
+ }
+
+ if (v->dmb_is_raw)
+ direct = get_bits1(gb);
+ else
+ direct = v->direct_mb_plane[mb_pos];
+
+ if (direct) {
+ s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample);
+
+ if (twomv) {
+ s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample);
+
+ for (i = 1; i < 4; i += 2) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0];
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1];
+ s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0];
+ s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1];
+ }
+ } else {
+ for (i = 1; i < 4; i++) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0];
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1];
+ s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0];
+ s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1];
+ }
+ }
+ }
+
+ if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+ for (i = 0; i < 4; i++) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0;
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0;
+ s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
+ s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
+ }
+ s->current_picture.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.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->idsp.put_signed_pixels_clamped(s->block[i],
+ s->dest[dst_idx] + off,
+ stride_y);
+ }
+ } else {
+ s->mb_intra = v->is_intra[s->mb_x] = 0;
+ if (!direct) {
+ if (skipped || !s->mb_intra) {
+ bmvtype = decode012(gb);
+ switch (bmvtype) {
+ case 0:
+ bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
+ break;
+ case 1:
+ bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
+ break;
+ case 2:
+ bmvtype = BMV_TYPE_INTERPOLATED;
+ }
+ }
+
+ if (twomv && bmvtype != BMV_TYPE_INTERPOLATED)
+ mvsw = get_bits1(gb);
+ }
+
+ if (!skipped) { // inter MB
+ mb_has_coeffs = ff_vc1_mbmode_intfrp[0][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 (!direct) {
+ if (bmvtype == BMV_TYPE_INTERPOLATED & twomv) {
+ v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+ } else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) {
+ v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
+ }
+ }
+
+ 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[0][idx_mbmode][1];
+ /* for all motion vector read MVDATA and motion compensate each block */
+ dst_idx = 0;
+ if (direct) {
+ if (twomv) {
+ for (i = 0; i < 4; i++) {
+ vc1_mc_4mv_luma(v, i, 0, 0);
+ vc1_mc_4mv_luma(v, i, 1, 1);
+ }
+ vc1_mc_4mv_chroma4(v, 0, 0, 0);
+ vc1_mc_4mv_chroma4(v, 1, 1, 1);
+ } else {
+ vc1_mc_1mv(v, 0);
+ vc1_interp_mc(v);
+ }
+ } else if (twomv && bmvtype == BMV_TYPE_INTERPOLATED) {
+ mvbp = v->fourmvbp;
+ for (i = 0; i < 4; i++) {
+ dir = i==1 || i==3;
+ dmv_x = dmv_y = 0;
+ val = ((mvbp >> (3 - i)) & 1);
+ if (val)
+ get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+ j = i > 1 ? 2 : 0;
+ vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
+ vc1_mc_4mv_luma(v, j, dir, dir);
+ vc1_mc_4mv_luma(v, j+1, dir, dir);
+ }
+
+ vc1_mc_4mv_chroma4(v, 0, 0, 0);
+ vc1_mc_4mv_chroma4(v, 1, 1, 1);
+ } else if (bmvtype == BMV_TYPE_INTERPOLATED) {
+ 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, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+ vc1_mc_1mv(v, 0);
+
+ dmv_x = dmv_y = 0;
+ if (mvbp & 1)
+ 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], 1);
+ vc1_interp_mc(v);
+ } else if (twomv) {
+ dir = bmvtype == BMV_TYPE_BACKWARD;
+ dir2 = dir;
+ if (mvsw)
+ dir2 = !dir;
+ 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], dir);
+
+ 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], dir2);
+
+ if (mvsw) {
+ for (i = 0; i < 2; i++) {
+ s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
+ s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
+ s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
+ s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
+ }
+ } else {
+ vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
+ vc1_pred_mv_intfr(v, 2, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
+ }
+
+ vc1_mc_4mv_luma(v, 0, dir, 0);
+ vc1_mc_4mv_luma(v, 1, dir, 0);
+ vc1_mc_4mv_luma(v, 2, dir2, 0);
+ vc1_mc_4mv_luma(v, 3, dir2, 0);
+ vc1_mc_4mv_chroma4(v, dir, dir2, 0);
+ } else {
+ dir = bmvtype == BMV_TYPE_BACKWARD;
+
+ mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
+ dmv_x = dmv_y = 0;
+ 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], dir);
+ 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;
+ vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
+ for (i = 0; i < 2; i++) {
+ s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
+ s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
+ }
+ vc1_mc_1mv(v, dir);
+ }
+
+ if (cbp)
+ GET_MQUANT(); // p. 227
+ s->current_picture.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
+ dir = 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.mb_type[mb_pos] = MB_TYPE_SKIP;
+ s->current_picture.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;
+
+ if (!direct) {
+ if (bmvtype == BMV_TYPE_INTERPOLATED) {
+ vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+ vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 1);
+ } else {
+ dir = bmvtype == BMV_TYPE_BACKWARD;
+ vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], dir);
+ if (mvsw) {
+ int dir2 = dir;
+ if (mvsw)
+ dir2 = !dir;
+ for (i = 0; i < 2; i++) {
+ s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
+ s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
+ s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
+ s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
+ }
+ } else {
+ 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;
+ vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
+ for (i = 0; i < 2; i++) {
+ s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
+ s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
+ }
+ }
+ }
+ }
+
+ vc1_mc_1mv(v, dir);
+ if (direct || bmvtype == BMV_TYPE_INTERPOLATED) {
+ vc1_interp_mc(v);
+ }
+ }
+ }
+ 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);
+ v->cbp[s->mb_x] = block_cbp;
+ v->ttblk[s->mb_x] = block_tt;
+ return 0;
+}
+
/** Decode blocks of I-frame
*/
static void vc1_decode_i_blocks(VC1Context *v)
s->mb_x = s->mb_y = 0;
s->mb_intra = 1;
s->first_slice_line = 1;
- for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
+ for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
- ff_init_block_index(s);
- for (; s->mb_x < s->mb_width; s->mb_x++) {
+ init_block_index(v);
+ for (; s->mb_x < v->end_mb_x; s->mb_x++) {
uint8_t *dst[6];
ff_update_block_index(s);
dst[0] = s->dest[0];
dst[3] = dst[2] + 8;
dst[4] = s->dest[1];
dst[5] = s->dest[2];
- s->dsp.clear_blocks(s->block[0]);
+ s->bdsp.clear_blocks(s->block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_width;
- s->current_picture.f.mb_type[mb_pos] = MB_TYPE_INTRA;
- s->current_picture.f.qscale_table[mb_pos] = v->pq;
- 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.mb_type[mb_pos] = MB_TYPE_INTRA;
+ s->current_picture.qscale_table[mb_pos] = v->pq;
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
// do actual MB decoding and displaying
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
if (v->rangeredfrm)
for (j = 0; j < 64; j++)
s->block[k][j] <<= 1;
- s->dsp.put_signed_pixels_clamped(s->block[k], dst[k], k & 4 ? s->uvlinesize : s->linesize);
+ s->idsp.put_signed_pixels_clamped(s->block[k], dst[k],
+ k & 4 ? s->uvlinesize
+ : s->linesize);
} else {
if (v->rangeredfrm)
for (j = 0; j < 64; j++)
s->block[k][j] = (s->block[k][j] - 64) << 1;
- s->dsp.put_pixels_clamped(s->block[k], dst[k], k & 4 ? s->uvlinesize : s->linesize);
+ s->idsp.put_pixels_clamped(s->block[k], dst[k],
+ k & 4 ? s->uvlinesize
+ : s->linesize);
}
}
if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
if (get_bits_count(&s->gb) > v->bits) {
- ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
+ ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
get_bits_count(&s->gb), v->bits);
return;
}
}
if (!v->s.loop_filter)
- ff_draw_horiz_band(s, s->mb_y * 16, 16);
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
else if (s->mb_y)
- ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+ ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
s->first_slice_line = 0;
}
if (v->s.loop_filter)
- ff_draw_horiz_band(s, (s->mb_height - 1) * 16, 16);
- ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+
+ /* This is intentionally mb_height and not end_mb_y - unlike in advanced
+ * profile, these only differ are when decoding MSS2 rectangles. */
+ ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
}
/** Decode blocks of I-frame for advanced profile
s->mb_y = s->start_mb_y;
if (s->start_mb_y) {
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
(1 + s->b8_stride) * sizeof(*s->coded_block));
}
for (; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
for (;s->mb_x < s->mb_width; s->mb_x++) {
- DCTELEM (*block)[64] = v->block[v->cur_blk_idx];
+ int16_t (*block)[64] = v->block[v->cur_blk_idx];
ff_update_block_index(s);
- s->dsp.clear_blocks(block[0]);
+ s->bdsp.clear_blocks(block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- 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;
+ s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
// do actual MB decoding and displaying
if (v->fieldtx_is_raw)
GET_MQUANT();
- s->current_picture.f.qscale_table[mb_pos] = mquant;
+ s->current_picture.qscale_table[mb_pos] = mquant;
/* Set DC scale - y and c use the same */
s->y_dc_scale = s->y_dc_scale_table[mquant];
s->c_dc_scale = s->c_dc_scale_table[mquant];
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, ER_MB_ERROR);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
get_bits_count(&s->gb), v->bits);
return;
}
}
if (!v->s.loop_filter)
- ff_draw_horiz_band(s, s->mb_y * 16, 16);
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
else if (s->mb_y)
- ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+ ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
s->first_slice_line = 0;
}
/* raw bottom MB row */
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
+
for (;s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
vc1_put_signed_blocks_clamped(v);
vc1_loop_filter_iblk_delayed(v, v->pq);
}
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 << v->field_mode, s->mb_width - 1,
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
(s->end_mb_y << v->field_mode) - 1, ER_MB_END);
}
break;
}
- apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY);
+ apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
+ v->fcm == PROGRESSIVE;
s->first_slice_line = 1;
memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
for (; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
else if (v->fcm == ILACE_FRAME)
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 == PROGRESSIVE)
+ if (s->mb_y != s->start_mb_y && apply_loop_filter)
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, ER_MB_ERROR);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
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;
memmove(v->ttblk_base, v->ttblk, sizeof(v->ttblk_base[0]) * s->mb_stride);
memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
memmove(v->luma_mv_base, v->luma_mv, sizeof(v->luma_mv_base[0]) * s->mb_stride);
- if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+ if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
s->first_slice_line = 0;
}
if (apply_loop_filter) {
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
for (; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
vc1_apply_p_loop_filter(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 << v->field_mode, s->mb_width - 1,
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
(s->end_mb_y << v->field_mode) - 1, ER_MB_END);
}
s->first_slice_line = 1;
for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
for (; s->mb_x < s->mb_width; s->mb_x++) {
ff_update_block_index(s);
if (v->fcm == ILACE_FIELD)
vc1_decode_b_mb_intfi(v);
+ else if (v->fcm == ILACE_FRAME)
+ vc1_decode_b_mb_intfr(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, ER_MB_ERROR);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
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;
if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
}
if (!v->s.loop_filter)
- ff_draw_horiz_band(s, s->mb_y * 16, 16);
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
else if (s->mb_y)
- ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+ ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
s->first_slice_line = 0;
}
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 << v->field_mode, s->mb_width - 1,
+ ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+ ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
(s->end_mb_y << v->field_mode) - 1, ER_MB_END);
}
{
MpegEncContext *s = &v->s;
- ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
+ if (!v->s.last_picture.f->data[0])
+ return;
+
+ ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
s->first_slice_line = 1;
for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
s->mb_x = 0;
- ff_init_block_index(s);
+ init_block_index(v);
ff_update_block_index(s);
- memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16);
- memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
- memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
- ff_draw_horiz_band(s, s->mb_y * 16, 16);
+ memcpy(s->dest[0], s->last_picture.f->data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16);
+ memcpy(s->dest[1], s->last_picture.f->data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
+ memcpy(s->dest[2], s->last_picture.f->data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8);
+ ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
s->first_slice_line = 0;
}
s->pict_type = AV_PICTURE_TYPE_P;
}
-static void vc1_decode_blocks(VC1Context *v)
+void ff_vc1_decode_blocks(VC1Context *v)
{
v->s.esc3_level_length = 0;
for (sprite = 0; sprite <= v->two_sprites; sprite++) {
vc1_sprite_parse_transform(gb, sd->coefs[sprite]);
if (sd->coefs[sprite][1] || sd->coefs[sprite][3])
- av_log_ask_for_sample(avctx, "Rotation coefficients are not zero");
+ avpriv_request_sample(avctx, "Non-zero rotation coefficients");
av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:");
for (i = 0; i < 7; i++)
av_log(avctx, AV_LOG_DEBUG, " %d.%.3d",
av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n");
if (get_bits_count(gb) >= gb->size_in_bits +
- (avctx->codec_id == CODEC_ID_WMV3IMAGE ? 64 : 0))
+ (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE ? 64 : 0))
av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n");
if (get_bits_count(gb) < gb->size_in_bits - 8)
av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n");
int width = v->output_width>>!!plane;
for (row = 0; row < v->output_height>>!!plane; row++) {
- uint8_t *dst = v->sprite_output_frame.data[plane] +
- v->sprite_output_frame.linesize[plane] * row;
+ uint8_t *dst = v->sprite_output_frame->data[plane] +
+ v->sprite_output_frame->linesize[plane] * row;
for (sprite = 0; sprite <= v->two_sprites; sprite++) {
- uint8_t *iplane = s->current_picture.f.data[plane];
- int iline = s->current_picture.f.linesize[plane];
+ uint8_t *iplane = s->current_picture.f->data[plane];
+ int iline = s->current_picture.f->linesize[plane];
int ycoord = yoff[sprite] + yadv[sprite] * row;
int yline = ycoord >> 16;
+ int next_line;
ysub[sprite] = ycoord & 0xFFFF;
if (sprite) {
- iplane = s->last_picture.f.data[plane];
- iline = s->last_picture.f.linesize[plane];
+ iplane = s->last_picture.f->data[plane];
+ iline = s->last_picture.f->linesize[plane];
}
+ next_line = FFMIN(yline + 1, (v->sprite_height >> !!plane) - 1) * iline;
if (!(xoff[sprite] & 0xFFFF) && xadv[sprite] == 1 << 16) {
src_h[sprite][0] = iplane + (xoff[sprite] >> 16) + yline * iline;
if (ysub[sprite])
- src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + (yline + 1) * iline;
+ src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + next_line;
} else {
if (sr_cache[sprite][0] != yline) {
if (sr_cache[sprite][1] == yline) {
}
}
if (ysub[sprite] && sr_cache[sprite][1] != yline + 1) {
- v->vc1dsp.sprite_h(v->sr_rows[sprite][1], iplane + (yline + 1) * iline, xoff[sprite], xadv[sprite], width);
+ v->vc1dsp.sprite_h(v->sr_rows[sprite][1],
+ iplane + next_line, xoff[sprite],
+ xadv[sprite], width);
sr_cache[sprite][1] = yline + 1;
}
src_h[sprite][0] = v->sr_rows[sprite][0];
vc1_parse_sprites(v, gb, &sd);
- if (!s->current_picture.f.data[0]) {
+ if (!s->current_picture.f->data[0]) {
av_log(avctx, AV_LOG_ERROR, "Got no sprites\n");
return -1;
}
- if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f.data[0])) {
+ if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f->data[0])) {
av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n");
v->two_sprites = 0;
}
- if (v->sprite_output_frame.data[0])
- avctx->release_buffer(avctx, &v->sprite_output_frame);
-
- v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID;
- v->sprite_output_frame.reference = 0;
- if (avctx->get_buffer(avctx, &v->sprite_output_frame) < 0) {
+ av_frame_unref(v->sprite_output_frame);
+ if (ff_get_buffer(avctx, v->sprite_output_frame, 0) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
{
VC1Context *v = avctx->priv_data;
MpegEncContext *s = &v->s;
- AVFrame *f = &s->current_picture.f;
+ AVFrame *f = s->current_picture.f;
int plane, i;
/* Windows Media Image codecs have a convergence interval of two keyframes.
#endif
-static av_cold int vc1_decode_init_alloc_tables(VC1Context *v)
+av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)
{
MpegEncContext *s = &v->s;
int i;
+ int mb_height = FFALIGN(s->mb_height, 2);
/* 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);
+ v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height);
+ v->direct_mb_plane = av_malloc (s->mb_stride * mb_height);
+ v->forward_mb_plane = av_malloc (s->mb_stride * mb_height);
+ v->fieldtx_plane = av_mallocz(s->mb_stride * mb_height);
+ v->acpred_plane = av_malloc (s->mb_stride * mb_height);
+ v->over_flags_plane = av_malloc (s->mb_stride * mb_height);
v->n_allocated_blks = s->mb_width + 2;
v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks);
v->luma_mv = v->luma_mv_base + s->mb_stride;
/* allocate block type info in that way so it could be used with s->block_index[] */
- v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+ v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
v->mb_type[0] = v->mb_type_base + s->b8_stride + 1;
- 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);
+ v->mb_type[1] = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1;
+ v->mb_type[2] = v->mb_type[1] + s->mb_stride * (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_base = av_mallocz( s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (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_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (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[1] = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
+ v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (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);
+ v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
/* Init coded blocks info */
if (v->profile == PROFILE_ADVANCED) {
ff_intrax8_common_init(&v->x8,s);
- if (s->avctx->codec_id == CODEC_ID_WMV3IMAGE || s->avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
for (i = 0; i < 4; i++)
if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) return -1;
}
if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane ||
!v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base ||
- !v->mb_type_base)
- return -1;
+ !v->mb_type_base) {
+ av_freep(&v->mv_type_mb_plane);
+ av_freep(&v->direct_mb_plane);
+ av_freep(&v->acpred_plane);
+ av_freep(&v->over_flags_plane);
+ av_freep(&v->block);
+ av_freep(&v->cbp_base);
+ av_freep(&v->ttblk_base);
+ av_freep(&v->is_intra_base);
+ av_freep(&v->luma_mv_base);
+ av_freep(&v->mb_type_base);
+ return AVERROR(ENOMEM);
+ }
return 0;
}
+av_cold void ff_vc1_init_transposed_scantables(VC1Context *v)
+{
+ int i;
+ for (i = 0; i < 64; i++) {
+#define transpose(x) ((x >> 3) | ((x & 7) << 3))
+ v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]);
+ v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]);
+ v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]);
+ v->zz_8x8[3][i] = transpose(ff_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;
+}
+
/** Initialize a VC1/WMV3 decoder
* @todo TODO: Handle VC-1 IDUs (Transport level?)
* @todo TODO: Decypher remaining bits in extra_data
VC1Context *v = avctx->priv_data;
MpegEncContext *s = &v->s;
GetBitContext gb;
- int i;
/* save the container output size for WMImage */
v->output_width = avctx->width;
if (!avctx->extradata_size || !avctx->extradata)
return -1;
if (!(avctx->flags & CODEC_FLAG_GRAY))
- avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
+ avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
else
- avctx->pix_fmt = PIX_FMT_GRAY8;
- avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
v->s.avctx = avctx;
- avctx->flags |= CODEC_FLAG_EMU_EDGE;
- v->s.flags |= CODEC_FLAG_EMU_EDGE;
-
- if (avctx->idct_algo == FF_IDCT_AUTO) {
- avctx->idct_algo = FF_IDCT_WMV2;
- }
if (ff_vc1_init_common(v) < 0)
return -1;
+ ff_blockdsp_init(&s->bdsp, avctx);
+ ff_h264chroma_init(&v->h264chroma, 8);
+ ff_qpeldsp_init(&s->qdsp);
ff_vc1dsp_init(&v->vc1dsp);
- if (avctx->codec_id == CODEC_ID_WMV3 || avctx->codec_id == CODEC_ID_WMV3IMAGE) {
+ if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) {
int count = 0;
// looks like WMV3 has a sequence header stored in the extradata
av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
return -1;
}
- v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2'));
+ v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE);
}
+ v->sprite_output_frame = av_frame_alloc();
+ if (!v->sprite_output_frame)
+ return AVERROR(ENOMEM);
+
avctx->profile = v->profile;
if (v->profile == PROFILE_ADVANCED)
avctx->level = v->level;
s->mb_height = (avctx->coded_height + 15) >> 4;
if (v->profile == PROFILE_ADVANCED || v->res_fasttx) {
- for (i = 0; i < 64; i++) {
-#define transpose(x) ((x >> 3) | ((x & 7) << 3))
- v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]);
- v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]);
- v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]);
- v->zz_8x8[3][i] = transpose(ff_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;
+ ff_vc1_init_transposed_scantables(v);
} else {
memcpy(v->zz_8x8, ff_wmv1_scantable, 4*64);
v->left_blk_sh = 3;
v->top_blk_sh = 0;
}
- if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
v->sprite_width = avctx->coded_width;
v->sprite_height = avctx->coded_height;
/** Close a VC1/WMV3 decoder
* @warning Initial try at using MpegEncContext stuff
*/
-static av_cold int vc1_decode_end(AVCodecContext *avctx)
+av_cold int ff_vc1_decode_end(AVCodecContext *avctx)
{
VC1Context *v = avctx->priv_data;
int i;
- if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
- && v->sprite_output_frame.data[0])
- avctx->release_buffer(avctx, &v->sprite_output_frame);
+ av_frame_free(&v->sprite_output_frame);
+
for (i = 0; i < 4; i++)
av_freep(&v->sr_rows[i >> 1][i & 1]);
av_freep(&v->hrd_rate);
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);
* @todo TODO: Handle VC-1 IDUs (Transport level?)
*/
static int vc1_decode_frame(AVCodecContext *avctx, void *data,
- int *data_size, AVPacket *avpkt)
+ int *got_frame, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size, n_slices = 0, i;
+ int buf_size = avpkt->size, n_slices = 0, i, ret;
VC1Context *v = avctx->priv_data;
MpegEncContext *s = &v->s;
AVFrame *pict = data;
if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
/* special case for last picture */
if (s->low_delay == 0 && s->next_picture_ptr) {
- *pict = s->next_picture_ptr->f;
+ if ((ret = av_frame_ref(pict, s->next_picture_ptr->f)) < 0)
+ return ret;
s->next_picture_ptr = NULL;
- *data_size = sizeof(AVFrame);
+ *got_frame = 1;
}
return 0;
}
- if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
- if (v->profile < PROFILE_ADVANCED)
- avctx->pix_fmt = PIX_FMT_VDPAU_WMV3;
- else
- avctx->pix_fmt = PIX_FMT_VDPAU_VC1;
- }
-
//for advanced profile we may need to parse and unescape data
- if (avctx->codec_id == CODEC_ID_VC1 || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
int buf_size2 = 0;
buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (size <= 0) continue;
switch (AV_RB32(start)) {
case VC1_CODE_FRAME:
- if (avctx->hwaccel ||
- s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ if (avctx->hwaccel)
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)
+ tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
+ if (!tmp)
goto err;
+ slices = tmp;
slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!slices[n_slices].buf)
goto err;
break;
case VC1_CODE_SLICE: {
int buf_size3;
- slices = av_realloc(slices, sizeof(*slices) * (n_slices+1));
- if (!slices)
+ tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));
+ if (!tmp)
goto err;
+ slices = tmp;
slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!slices[n_slices].buf)
goto err;
if (v->res_sprite) {
v->new_sprite = !get_bits1(&s->gb);
v->two_sprites = get_bits1(&s->gb);
- /* res_sprite means a Windows Media Image stream, CODEC_ID_*IMAGE means
+ /* res_sprite means a Windows Media Image stream, AV_CODEC_ID_*IMAGE means
we're using the sprite compositor. These are intentionally kept separate
so you can get the raw sprites by using the wmv3 decoder for WMVP or
the vc1 one for WVP2 */
- if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
if (v->new_sprite) {
// switch AVCodecContext parameters to those of the sprites
avctx->width = avctx->coded_width = v->sprite_width;
if (s->context_initialized &&
(s->width != avctx->coded_width ||
s->height != avctx->coded_height)) {
- vc1_decode_end(avctx);
+ ff_vc1_decode_end(avctx);
}
if (!s->context_initialized) {
- if (ff_msmpeg4_decode_init(avctx) < 0 || vc1_decode_init_alloc_tables(v) < 0)
- return -1;
+ if (ff_msmpeg4_decode_init(avctx) < 0)
+ goto err;
+ if (ff_vc1_decode_init_alloc_tables(v) < 0) {
+ ff_MPV_common_end(s);
+ goto err;
+ }
s->low_delay = !avctx->has_b_frames || v->res_sprite;
}
}
- /* We need to set current_picture_ptr before reading the header,
- * otherwise we cannot store anything in there. */
- if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
- int i = ff_find_unused_picture(s, 0);
- if (i < 0)
- goto err;
- s->current_picture_ptr = &s->picture[i];
- }
-
// do parse frame header
v->pic_header_flag = 0;
+ v->first_pic_header_flag = 1;
if (v->profile < PROFILE_ADVANCED) {
- if (ff_vc1_parse_frame_header(v, &s->gb) == -1) {
+ if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {
goto err;
}
} else {
- if (ff_vc1_parse_frame_header_adv(v, &s->gb) == -1) {
+ if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
goto err;
}
}
+ v->first_pic_header_flag = 0;
- if ((avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE)
+ if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
&& s->pict_type != AV_PICTURE_TYPE_I) {
av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");
goto err;
}
- // process pulldown flags
- s->current_picture_ptr->f.repeat_pict = 0;
- // Pulldown flags are only valid when 'broadcast' has been set.
- // So ticks_per_frame will be 2
- if (v->rff) {
- // repeat field
- s->current_picture_ptr->f.repeat_pict = 1;
- } else if (v->rptfrm) {
- // repeat frames
- s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2;
- }
-
// for skipping the frame
- s->current_picture.f.pict_type = s->pict_type;
- s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
+ s->current_picture.f->pict_type = s->pict_type;
+ s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
/* skip B-frames if we don't have reference frames */
- if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->dropable)) {
- goto err;
+ if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) {
+ goto end;
}
if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||
(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) ||
goto err;
}
- s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
- s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
+ // process pulldown flags
+ s->current_picture_ptr->f->repeat_pict = 0;
+ // Pulldown flags are only valid when 'broadcast' has been set.
+ // So ticks_per_frame will be 2
+ if (v->rff) {
+ // repeat field
+ s->current_picture_ptr->f->repeat_pict = 1;
+ } else if (v->rptfrm) {
+ // repeat frames
+ s->current_picture_ptr->f->repeat_pict = v->rptfrm * 2;
+ }
+
+ s->me.qpel_put = s->qdsp.put_qpel_pixels_tab;
+ s->me.qpel_avg = s->qdsp.avg_qpel_pixels_tab;
- if ((CONFIG_VC1_VDPAU_DECODER)
- &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
- ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
- else if (avctx->hwaccel) {
+ if (avctx->hwaccel) {
if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
goto err;
if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
if (avctx->hwaccel->end_frame(avctx) < 0)
goto err;
} else {
- ff_er_frame_start(s);
+ int header_ret = 0;
+
+ ff_mpeg_er_frame_start(s);
v->bits = buf_size * 8;
+ v->end_mb_x = s->mb_width;
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->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;
+
+ if (!mb_height) {
+ av_log(v->s.avctx, AV_LOG_ERROR, "Invalid mb_height.\n");
+ goto err;
+ }
+
for (i = 0; i <= n_slices; i++) {
if (i > 0 && slices[i - 1].mby_start >= mb_height) {
if (v->field_mode <= 0) {
if (i) {
v->pic_header_flag = 0;
if (v->field_mode && i == n_slices1 + 2) {
- if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
+ if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto err;
continue;
}
} else if (get_bits1(&s->gb)) {
v->pic_header_flag = 1;
- if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
+ if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto err;
continue;
}
}
}
+ if (header_ret < 0)
+ continue;
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);
+ ff_vc1_decode_blocks(v);
if (i != n_slices)
s->gb = slices[i].gb;
}
if (v->field_mode) {
v->second_field = 0;
- 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->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;
+ if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) {
+ FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]);
+ FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]);
+ }
}
-//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits);
+ av_dlog(s->avctx, "Consumed %i/%i bits\n",
+ get_bits_count(&s->gb), s->gb.size_in_bits);
// if (get_bits_count(&s->gb) > buf_size * 8)
// return -1;
- ff_er_frame_end(s);
+ if (!v->field_mode)
+ ff_er_frame_end(&s->er);
}
ff_MPV_frame_end(s);
- if (avctx->codec_id == CODEC_ID_WMV3IMAGE || avctx->codec_id == CODEC_ID_VC1IMAGE) {
+ if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
image:
avctx->width = avctx->coded_width = v->output_width;
avctx->height = avctx->coded_height = v->output_height;
if (vc1_decode_sprites(v, &s->gb))
goto err;
#endif
- *pict = v->sprite_output_frame;
- *data_size = sizeof(AVFrame);
+ if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0)
+ goto err;
+ *got_frame = 1;
} else {
if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
- *pict = s->current_picture_ptr->f;
+ if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)
+ goto err;
+ ff_print_debug_info(s, s->current_picture_ptr);
+ *got_frame = 1;
} else if (s->last_picture_ptr != NULL) {
- *pict = s->last_picture_ptr->f;
- }
- if (s->last_picture_ptr || s->low_delay) {
- *data_size = sizeof(AVFrame);
- ff_print_debug_info(s, pict);
+ if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0)
+ goto err;
+ ff_print_debug_info(s, s->last_picture_ptr);
+ *got_frame = 1;
}
}
{ FF_PROFILE_UNKNOWN },
};
+static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_VC1_DXVA2_HWACCEL
+ AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_VC1_VAAPI_HWACCEL
+ AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_VC1_VDPAU_HWACCEL
+ AV_PIX_FMT_VDPAU,
+#endif
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+};
+
AVCodec ff_vc1_decoder = {
.name = "vc1",
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_VC1,
+ .id = AV_CODEC_ID_VC1,
.priv_data_size = sizeof(VC1Context),
.init = vc1_decode_init,
- .close = vc1_decode_end,
+ .close = ff_vc1_decode_end,
.decode = vc1_decode_frame,
+ .flush = ff_mpeg_flush,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
- .pix_fmts = ff_hwaccel_pixfmt_list_420,
+ .pix_fmts = vc1_hwaccel_pixfmt_list_420,
.profiles = NULL_IF_CONFIG_SMALL(profiles)
};
#if CONFIG_WMV3_DECODER
AVCodec ff_wmv3_decoder = {
.name = "wmv3",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_WMV3,
- .priv_data_size = sizeof(VC1Context),
- .init = vc1_decode_init,
- .close = vc1_decode_end,
- .decode = vc1_decode_frame,
- .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
- .pix_fmts = ff_hwaccel_pixfmt_list_420,
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
-};
-#endif
-
-#if CONFIG_WMV3_VDPAU_DECODER
-AVCodec ff_wmv3_vdpau_decoder = {
- .name = "wmv3_vdpau",
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_WMV3,
+ .id = AV_CODEC_ID_WMV3,
.priv_data_size = sizeof(VC1Context),
.init = vc1_decode_init,
- .close = vc1_decode_end,
+ .close = ff_vc1_decode_end,
.decode = vc1_decode_frame,
- .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
- .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_VDPAU_WMV3, PIX_FMT_NONE },
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
-};
-#endif
-
-#if CONFIG_VC1_VDPAU_DECODER
-AVCodec ff_vc1_vdpau_decoder = {
- .name = "vc1_vdpau",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_VC1,
- .priv_data_size = sizeof(VC1Context),
- .init = vc1_decode_init,
- .close = vc1_decode_end,
- .decode = vc1_decode_frame,
- .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
- .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
- .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_VDPAU_VC1, PIX_FMT_NONE },
+ .flush = ff_mpeg_flush,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .pix_fmts = vc1_hwaccel_pixfmt_list_420,
.profiles = NULL_IF_CONFIG_SMALL(profiles)
};
#endif
#if CONFIG_WMV3IMAGE_DECODER
AVCodec ff_wmv3image_decoder = {
.name = "wmv3image",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_WMV3IMAGE,
+ .id = AV_CODEC_ID_WMV3IMAGE,
.priv_data_size = sizeof(VC1Context),
.init = vc1_decode_init,
- .close = vc1_decode_end,
+ .close = ff_vc1_decode_end,
.decode = vc1_decode_frame,
.capabilities = CODEC_CAP_DR1,
.flush = vc1_sprite_flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
- .pix_fmts = ff_pixfmt_list_420
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
};
#endif
#if CONFIG_VC1IMAGE_DECODER
AVCodec ff_vc1image_decoder = {
.name = "vc1image",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_VC1IMAGE,
+ .id = AV_CODEC_ID_VC1IMAGE,
.priv_data_size = sizeof(VC1Context),
.init = vc1_decode_init,
- .close = vc1_decode_end,
+ .close = ff_vc1_decode_end,
.decode = vc1_decode_frame,
.capabilities = CODEC_CAP_DR1,
.flush = vc1_sprite_flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
- .pix_fmts = ff_pixfmt_list_420
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
};
#endif