mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/vp56: decode interlace content
Modification of patch submitted by Aurelien Jacobs (November 2007). Fixes ticket #5581 and #5582.
This commit is contained in:
parent
44a0a0c050
commit
492a3b4b89
|
@ -58,10 +58,7 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
|||
if(vp56_rac_gets(c, 5) > 5)
|
||||
return AVERROR_INVALIDDATA;
|
||||
vp56_rac_gets(c, 2);
|
||||
if (vpx_rac_get(c)) {
|
||||
avpriv_report_missing_feature(s->avctx, "Interlacing");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
s->interlaced = vp56_rac_gets(c, 1);
|
||||
rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */
|
||||
cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */
|
||||
if (!rows || !cols) {
|
||||
|
|
|
@ -338,7 +338,7 @@ static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
|
|||
}
|
||||
|
||||
static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
|
||||
ptrdiff_t stride, int x, int y)
|
||||
ptrdiff_t stride, int x, int y, ptrdiff_t ref_stride)
|
||||
{
|
||||
uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b];
|
||||
uint8_t *src_block;
|
||||
|
@ -364,7 +364,17 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
|
|||
x += dx - 2;
|
||||
y += dy - 2;
|
||||
|
||||
if (x<0 || x+12>=s->plane_width[plane] ||
|
||||
if (s->interlaced && s->il_block) {
|
||||
/* extract 12*(4+16+4) block from frame (containing both fields), then treat src_block as specific field */
|
||||
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
|
||||
src + s->block_offset[b] + (dy-4)*ref_stride + (dx-2),
|
||||
ref_stride, ref_stride,
|
||||
12, 24, x, y - 2,
|
||||
s->plane_width[plane],
|
||||
s->plane_height[plane]);
|
||||
src_block = s->edge_emu_buffer;
|
||||
src_offset = 2 + 4*ref_stride;
|
||||
} else if (x<0 || x+12>=s->plane_width[plane] ||
|
||||
y<0 || y+12>=s->plane_height[plane]) {
|
||||
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
|
||||
src + s->block_offset[b] + (dy-2)*stride + (dx-2),
|
||||
|
@ -431,6 +441,7 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in
|
|||
int b, ab, b_max, plane, off;
|
||||
AVFrame *frame_current, *frame_ref;
|
||||
VP56Frame ref_frame = ff_vp56_reference_frame[mb_type];
|
||||
ptrdiff_t ref_stride[4];
|
||||
|
||||
vp56_add_predictors_dc(s, ref_frame);
|
||||
|
||||
|
@ -439,6 +450,13 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in
|
|||
if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
|
||||
return;
|
||||
|
||||
memcpy(ref_stride, s->stride, sizeof(s->stride));
|
||||
if (s->interlaced && s->il_block) {
|
||||
s->block_offset[2] -= s->stride[0] * 7;
|
||||
s->block_offset[3] -= s->stride[0] * 7;
|
||||
s->stride[0] *= 2;
|
||||
}
|
||||
|
||||
ab = 6*is_alpha;
|
||||
b_max = 6 - 2*is_alpha;
|
||||
|
||||
|
@ -473,10 +491,10 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in
|
|||
case VP56_MB_INTER_V2_GF:
|
||||
for (b=0; b<b_max; b++) {
|
||||
int x_off = b==1 || b==3 ? 8 : 0;
|
||||
int y_off = b==2 || b==3 ? 8 : 0;
|
||||
int y_off = b==2 || b==3 ? (s->interlaced && s->il_block ? 1 : 8) : 0;
|
||||
plane = ff_vp56_b2p[b+ab];
|
||||
vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane],
|
||||
16*col+x_off, 16*row+y_off);
|
||||
16*col+x_off, 16*row+y_off, ref_stride[plane]);
|
||||
vp56_idct_add(s, frame_current->data[plane] + s->block_offset[b],
|
||||
s->stride[plane], s->block_coeff[b], s->idct_selector[b]);
|
||||
}
|
||||
|
@ -487,6 +505,12 @@ static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, in
|
|||
s->block_coeff[4][0] = 0;
|
||||
s->block_coeff[5][0] = 0;
|
||||
}
|
||||
|
||||
if (s->interlaced && s->il_block) {
|
||||
s->stride[0] /= 2;
|
||||
s->block_offset[2] += s->stride[0] * 7;
|
||||
s->block_offset[3] += s->stride[0] * 7;
|
||||
}
|
||||
}
|
||||
|
||||
static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
|
||||
|
@ -494,6 +518,19 @@ static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
|
|||
VP56mb mb_type;
|
||||
int ret;
|
||||
|
||||
if (s->interlaced) {
|
||||
int prob = s->il_prob;
|
||||
|
||||
if (col > 0) {
|
||||
if (s->il_block)
|
||||
prob -= prob >> 1;
|
||||
else
|
||||
prob += (256 - prob) >> 1; /* can be simplified/combined */
|
||||
}
|
||||
|
||||
s->il_block = vpx_rac_get_prob(&s->c, prob);
|
||||
}
|
||||
|
||||
if (s->frames[VP56_FRAME_CURRENT]->flags & AV_FRAME_FLAG_KEY)
|
||||
mb_type = VP56_MB_INTRA;
|
||||
else
|
||||
|
@ -552,12 +589,12 @@ static int vp56_size_changed(VP56Context *s)
|
|||
av_reallocp_array(&s->macroblocks, s->mb_width*s->mb_height,
|
||||
sizeof(*s->macroblocks));
|
||||
av_free(s->edge_emu_buffer_alloc);
|
||||
s->edge_emu_buffer_alloc = av_malloc(16*stride);
|
||||
s->edge_emu_buffer_alloc = av_malloc(16*stride*2);
|
||||
s->edge_emu_buffer = s->edge_emu_buffer_alloc;
|
||||
if (!s->above_blocks || !s->macroblocks || !s->edge_emu_buffer_alloc)
|
||||
return AVERROR(ENOMEM);
|
||||
if (s->flip < 0)
|
||||
s->edge_emu_buffer += 15 * stride;
|
||||
s->edge_emu_buffer += 15 * stride * 2;
|
||||
|
||||
if (s->alpha_context)
|
||||
return vp56_size_changed(s->alpha_context);
|
||||
|
@ -686,6 +723,11 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
|
|||
if (s->parse_coeff_models(s))
|
||||
goto next;
|
||||
|
||||
if (s->interlaced) {
|
||||
s->frames[VP56_FRAME_CURRENT]->flags |= AV_FRAME_FLAG_INTERLACED;
|
||||
s->il_prob = vp56_rac_gets(&s->c, 8);
|
||||
}
|
||||
|
||||
memset(s->prev_dc, 0, sizeof(s->prev_dc));
|
||||
s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
|
||||
s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
|
||||
|
|
|
@ -151,6 +151,7 @@ struct vp56_context {
|
|||
VP56Macroblock *macroblocks;
|
||||
DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
|
||||
int idct_selector[6];
|
||||
const uint8_t *def_coeff_reorder;/* used in vp6 only */
|
||||
|
||||
/* motion vectors */
|
||||
VP56mv mv[6]; /* vectors for each block in MB */
|
||||
|
@ -171,6 +172,11 @@ struct vp56_context {
|
|||
|
||||
int has_alpha;
|
||||
|
||||
/* interlacing params */
|
||||
int interlaced;
|
||||
int il_prob;
|
||||
int il_block;
|
||||
|
||||
/* upside-down flipping hints */
|
||||
int flip; /* are we flipping ? */
|
||||
int frbi; /* first row block index in MB */
|
||||
|
|
|
@ -68,10 +68,11 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
|||
if (sub_version > 8)
|
||||
return AVERROR_INVALIDDATA;
|
||||
s->filter_header = buf[1] & 0x06;
|
||||
if (buf[1] & 1) {
|
||||
avpriv_report_missing_feature(s->avctx, "Interlacing");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
s->interlaced = buf[1] & 1;
|
||||
if (s->interlaced)
|
||||
s->def_coeff_reorder = vp6_il_coeff_reorder;
|
||||
else
|
||||
s->def_coeff_reorder = vp6_def_coeff_reorder;
|
||||
if (separated_coeff || !s->filter_header) {
|
||||
coeff_offset = AV_RB16(buf+2) - 2;
|
||||
buf += 2;
|
||||
|
@ -228,7 +229,7 @@ static void vp6_default_models_init(VP56Context *s)
|
|||
memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv));
|
||||
memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv));
|
||||
memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv));
|
||||
memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder));
|
||||
memcpy(model->coeff_reorder, s->def_coeff_reorder, sizeof(model->coeff_reorder));
|
||||
|
||||
vp6_coeff_order_table_init(s);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,17 @@ static const uint8_t vp6_def_coeff_reorder[] = {
|
|||
14, 14, 15, 15, 15, 15, 15, 15,
|
||||
};
|
||||
|
||||
static const uint8_t vp6_il_coeff_reorder[] = {
|
||||
0, 1, 0, 1, 1, 2, 5, 3,
|
||||
2, 2, 2, 2, 4, 7, 8, 10,
|
||||
9, 7, 5, 4, 2, 3, 5, 6,
|
||||
8, 9, 11, 12, 13, 12, 11, 10,
|
||||
9, 7, 5, 4, 6, 7, 9, 11,
|
||||
12, 12, 13, 13, 14, 12, 11, 9,
|
||||
7, 9, 11, 12, 14, 14, 14, 15,
|
||||
13, 11, 13, 15, 15, 15, 15, 15,
|
||||
};
|
||||
|
||||
static const uint8_t vp6_def_runv_coeff_model[2][14] = {
|
||||
{ 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 },
|
||||
{ 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 },
|
||||
|
|
Loading…
Reference in New Issue