static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int x, int y, int w, int h, int wmv9_mask) { MSS2Context *ctx = avctx->priv_data; MSS12Context *c = &ctx->c; VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; AVFrame *f; int ret; ff_mpeg_flush(avctx); init_get_bits(&s->gb, buf, buf_size * 8); s->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL; if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { av_log(v->s.avctx, AV_LOG_ERROR, "header error\n"); return AVERROR_INVALIDDATA; } if (s->pict_type != AV_PICTURE_TYPE_I) { av_log(v->s.avctx, AV_LOG_ERROR, "expected I-frame\n"); return AVERROR_INVALIDDATA; } avctx->pix_fmt = AV_PIX_FMT_YUV420P; if ((ret = ff_MPV_frame_start(s, avctx)) < 0) { av_log(v->s.avctx, AV_LOG_ERROR, "ff_MPV_frame_start error\n"); avctx->pix_fmt = AV_PIX_FMT_RGB24; return ret; } ff_mpeg_er_frame_start(s); v->bits = buf_size * 8; v->end_mb_x = (w + 15) >> 4; s->end_mb_y = (h + 15) >> 4; if (v->respic & 1) v->end_mb_x = v->end_mb_x + 1 >> 1; if (v->respic & 2) s->end_mb_y = s->end_mb_y + 1 >> 1; ff_vc1_decode_blocks(v); ff_er_frame_end(&s->er); ff_MPV_frame_end(s); f = &s->current_picture.f; if (v->respic == 3) { ctx->dsp.upsample_plane(f->data[0], f->linesize[0], w, h); ctx->dsp.upsample_plane(f->data[1], f->linesize[1], w >> 1, h >> 1); ctx->dsp.upsample_plane(f->data[2], f->linesize[2], w >> 1, h >> 1); } else if (v->respic) avpriv_request_sample(v->s.avctx, "Asymmetric WMV9 rectangle subsampling"); av_assert0(f->linesize[1] == f->linesize[2]); if (wmv9_mask != -1) ctx->dsp.mss2_blit_wmv9_masked(c->rgb_pic + y * c->rgb_stride + x * 3, c->rgb_stride, wmv9_mask, c->pal_pic + y * c->pal_stride + x, c->pal_stride, f->data[0], f->linesize[0], f->data[1], f->data[2], f->linesize[1], w, h); else ctx->dsp.mss2_blit_wmv9(c->rgb_pic + y * c->rgb_stride + x * 3, c->rgb_stride, f->data[0], f->linesize[0], f->data[1], f->data[2], f->linesize[1], w, h); avctx->pix_fmt = AV_PIX_FMT_RGB24; return 0; }