#include "msmpeg4data.h"
#include "unary.h"
#include "mathops.h"
-#include "vdpau_internal.h"
#undef NDEBUG
#include <assert.h>
int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
int i;
- const uint8_t *luty, *lutuv;
+ uint8_t (*luty)[256], (*lutuv)[256];
+ int use_ic;
if ((!v->field_mode ||
(v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
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 [v->ref_field_type[dir]];
- lutuv = v->curr_lutuv[v->ref_field_type[dir]];
+ luty = v->curr_luty;
+ lutuv = v->curr_lutuv;
+ use_ic = v->curr_use_ic;
} else {
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 [v->ref_field_type[dir]];
- lutuv = v->last_lutuv[v->ref_field_type[dir]];
+ luty = v->last_luty;
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
}
} else {
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 [v->ref_field_type[dir]];
- lutuv = v->next_lutuv[v->ref_field_type[dir]];
+ 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 = 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 - 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->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+ 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->vdsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8 + 1, 8 + 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, 8 + 1, 8 + 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 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] = 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] = lutuv[src[i]];
- src2[i] = lutuv[src2[i]];
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
}
src += s->uvlinesize;
src2 += s->uvlinesize;
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;
- const uint8_t *luty;
+ uint8_t (*luty)[256];
+ int use_ic;
if ((!v->field_mode ||
(v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
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];
- luty = v->curr_luty[v->ref_field_type[dir]];
+ luty = v->curr_luty;
+ use_ic = v->curr_use_ic;
} else {
srcY = s->last_picture.f.data[0];
- luty = v->last_luty[v->ref_field_type[dir]];
+ luty = v->last_luty;
+ use_ic = v->last_use_ic;
}
} else {
srcY = s->next_picture.f.data[0];
- luty = v->next_luty[v->ref_field_type[dir]];
+ 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) {
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->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+ 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);
}
}
/* 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] = luty[src[i]];
+ src[i] = luty[f][src[i]];
src += s->linesize << fieldmv;
}
}
int valid_count;
int chroma_ref_type = v->cur_field_type;
int v_edge_pos = s->v_edge_pos >> v->field_mode;
- const uint8_t *lutuv;
+ uint8_t (*lutuv)[256];
+ int use_ic;
if (!v->field_mode && !v->s.last_picture.f.data[0])
return;
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[chroma_ref_type];
+ lutuv = v->curr_lutuv;
+ use_ic = v->curr_use_ic;
} else {
srcU = s->last_picture.f.data[1];
srcV = s->last_picture.f.data[2];
- lutuv = v->last_lutuv[chroma_ref_type];
+ lutuv = v->last_lutuv;
+ use_ic = v->last_use_ic;
}
} else {
srcU = s->next_picture.f.data[1];
srcV = s->next_picture.f.data[2];
- lutuv = v->next_lutuv[chroma_ref_type];
+ 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;
}
}
- 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->vdsp.emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize,
+ 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->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;
}
}
/* 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] = lutuv[src[i]];
- src2[i] = lutuv[src2[i]];
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
}
src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
-/** 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;
H264ChromaContext *h264chroma = &v->h264chroma;
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->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
+ 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->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;
- const uint8_t *lutuv = v->last_lutuv[v->ref_field_type[0]];
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] = lutuv[src[i]];
- src2[i] = 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) {
- 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]);
+ 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]);
+ }
}
}
}
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])
return;
srcV = s->edge_emu_buffer + 18 * s->linesize;
}
- if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22
- || v->mv_mode == MV_PMODE_INTENSITY_COMP
+ 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->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+ 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->vdsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8 + 1, 8 + 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, 8 + 1, 8 + 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 (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
- const uint8_t *luty = v->next_luty [v->ref_field_type[1]];
- const uint8_t *lutuv= v->next_lutuv[v->ref_field_type[1]];
+ 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[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[1] : ((j+uvsrc_y) & 1);
for (i = 0; i < 9; i++) {
- src[i] = lutuv[src[i]];
- src2[i] = lutuv[src2[i]];
+ src[i] = lutuv[f][src[i]];
+ src2[i] = lutuv[f][src2[i]];
}
src += s->uvlinesize;
src2 += s->uvlinesize;
static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
int direct, int mode)
{
- int use_ic = v->next_use_ic || v->curr_use_ic || v->last_use_ic;
- if (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 (use_ic)
- v->mv_mode = v->mv_mode2;
return;
}
if (mode == BMV_TYPE_INTERPOLATED) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
- if (use_ic)
- v->mv_mode = v->mv_mode2;
return;
}
- if (use_ic && (mode == BMV_TYPE_BACKWARD))
- v->mv_mode = v->mv_mode2;
vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
- if (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],
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) {
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);
+ vc1_mc_4mv_chroma4(v, 0, 0, 0);
} else {
mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
dmv_x = dmv_y = 0;
vc1_mc_4mv_luma(v, i, 0, 0);
vc1_mc_4mv_luma(v, i, 1, 1);
}
- vc1_mc_4mv_chroma4(v);
+ 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);
vc1_mc_4mv_luma(v, j+1, dir, dir);
}
- vc1_mc_4mv_chroma4(v);
+ 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;
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);
+ vc1_mc_4mv_chroma4(v, dir, dir2, 0);
} else {
dir = bmvtype == BMV_TYPE_BACKWARD;
{
MpegEncContext *s = &v->s;
+ 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++) {
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];
v->two_sprites = 0;
}
- av_frame_unref(&v->sprite_output_frame);
- if (ff_get_buffer(avctx, &v->sprite_output_frame, 0) < 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;
}
{
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_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) {
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;
}
avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
else
avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+ avctx->hwaccel = ff_find_hwaccel(avctx);
v->s.avctx = avctx;
- avctx->flags |= CODEC_FLAG_EMU_EDGE;
- v->s.flags |= CODEC_FLAG_EMU_EDGE;
if (ff_vc1_init_common(v) < 0)
return -1;
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;
VC1Context *v = avctx->priv_data;
int i;
- av_frame_unref(&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]);
return 0;
}
- if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
- if (v->profile < PROFILE_ADVANCED)
- avctx->pix_fmt = AV_PIX_FMT_VDPAU_WMV3;
- else
- avctx->pix_fmt = AV_PIX_FMT_VDPAU_VC1;
- }
-
//for advanced profile we may need to parse and unescape data
if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
int buf_size2 = 0;
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;
}
if (!s->context_initialized) {
- if (ff_msmpeg4_decode_init(avctx) < 0 || ff_vc1_decode_init_alloc_tables(v) < 0)
+ 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;
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;
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;
+ }
+
s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
s->me.qpel_avg = s->dsp.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 {
+ int header_ret = 0;
+
ff_mpeg_er_frame_start(s);
v->bits = buf_size * 8;
s->uvlinesize <<= 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);
if (vc1_decode_sprites(v, &s->gb))
goto err;
#endif
- if ((ret = av_frame_ref(pict, &v->sprite_output_frame)) < 0)
+ if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0)
goto err;
*got_frame = 1;
} else {
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) {
if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
goto err;
ff_print_debug_info(s, s->last_picture_ptr);
- }
- if (s->last_picture_ptr || s->low_delay) {
*got_frame = 1;
}
}
AVCodec ff_vc1_decoder = {
.name = "vc1",
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_VC1,
.priv_data_size = sizeof(VC1Context),
.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 = vc1_hwaccel_pixfmt_list_420,
.profiles = NULL_IF_CONFIG_SMALL(profiles)
};
#if CONFIG_WMV3_DECODER
AVCodec ff_wmv3_decoder = {
.name = "wmv3",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_WMV3,
.priv_data_size = sizeof(VC1Context),
.decode = vc1_decode_frame,
.flush = ff_mpeg_flush,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
.pix_fmts = vc1_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 = AV_CODEC_ID_WMV3,
- .priv_data_size = sizeof(VC1Context),
- .init = vc1_decode_init,
- .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 AVPixelFormat[]){ AV_PIX_FMT_VDPAU_WMV3, AV_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 = AV_CODEC_ID_VC1,
- .priv_data_size = sizeof(VC1Context),
- .init = vc1_decode_init,
- .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("SMPTE VC-1 VDPAU"),
- .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_VC1, AV_PIX_FMT_NONE },
- .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 = AV_CODEC_ID_WMV3IMAGE,
.priv_data_size = sizeof(VC1Context),
.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
};
#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 = AV_CODEC_ID_VC1IMAGE,
.priv_data_size = sizeof(VC1Context),
.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
};
#endif