1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * VC-1 and WMV3 decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2011 Mashiat Sarker Shakkhar 4cabdff1aSopenharmony_ci * Copyright (c) 2006-2007 Konstantin Shishkov 5cabdff1aSopenharmony_ci * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * This file is part of FFmpeg. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 10cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 11cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 12cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 15cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 16cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17cabdff1aSopenharmony_ci * Lesser General Public License for more details. 18cabdff1aSopenharmony_ci * 19cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 20cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 21cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22cabdff1aSopenharmony_ci */ 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci/** 25cabdff1aSopenharmony_ci * @file 26cabdff1aSopenharmony_ci * VC-1 and WMV3 decoder 27cabdff1aSopenharmony_ci */ 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "config_components.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "avcodec.h" 32cabdff1aSopenharmony_ci#include "blockdsp.h" 33cabdff1aSopenharmony_ci#include "codec_internal.h" 34cabdff1aSopenharmony_ci#include "get_bits.h" 35cabdff1aSopenharmony_ci#include "hwconfig.h" 36cabdff1aSopenharmony_ci#include "internal.h" 37cabdff1aSopenharmony_ci#include "mpeg_er.h" 38cabdff1aSopenharmony_ci#include "mpegvideo.h" 39cabdff1aSopenharmony_ci#include "mpegvideodec.h" 40cabdff1aSopenharmony_ci#include "msmpeg4data.h" 41cabdff1aSopenharmony_ci#include "msmpeg4dec.h" 42cabdff1aSopenharmony_ci#include "profiles.h" 43cabdff1aSopenharmony_ci#include "vc1.h" 44cabdff1aSopenharmony_ci#include "vc1data.h" 45cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_citypedef struct SpriteData { 51cabdff1aSopenharmony_ci /** 52cabdff1aSopenharmony_ci * Transform coefficients for both sprites in 16.16 fixed point format, 53cabdff1aSopenharmony_ci * in the order they appear in the bitstream: 54cabdff1aSopenharmony_ci * x scale 55cabdff1aSopenharmony_ci * rotation 1 (unused) 56cabdff1aSopenharmony_ci * x offset 57cabdff1aSopenharmony_ci * rotation 2 (unused) 58cabdff1aSopenharmony_ci * y scale 59cabdff1aSopenharmony_ci * y offset 60cabdff1aSopenharmony_ci * alpha 61cabdff1aSopenharmony_ci */ 62cabdff1aSopenharmony_ci int coefs[2][7]; 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci int effect_type, effect_flag; 65cabdff1aSopenharmony_ci int effect_pcount1, effect_pcount2; ///< amount of effect parameters stored in effect_params 66cabdff1aSopenharmony_ci int effect_params1[15], effect_params2[10]; ///< effect parameters in 16.16 fixed point format 67cabdff1aSopenharmony_ci} SpriteData; 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_cistatic inline int get_fp_val(GetBitContext* gb) 70cabdff1aSopenharmony_ci{ 71cabdff1aSopenharmony_ci return (get_bits_long(gb, 30) - (1 << 29)) << 1; 72cabdff1aSopenharmony_ci} 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_cistatic void vc1_sprite_parse_transform(GetBitContext* gb, int c[7]) 75cabdff1aSopenharmony_ci{ 76cabdff1aSopenharmony_ci c[1] = c[3] = 0; 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci switch (get_bits(gb, 2)) { 79cabdff1aSopenharmony_ci case 0: 80cabdff1aSopenharmony_ci c[0] = 1 << 16; 81cabdff1aSopenharmony_ci c[2] = get_fp_val(gb); 82cabdff1aSopenharmony_ci c[4] = 1 << 16; 83cabdff1aSopenharmony_ci break; 84cabdff1aSopenharmony_ci case 1: 85cabdff1aSopenharmony_ci c[0] = c[4] = get_fp_val(gb); 86cabdff1aSopenharmony_ci c[2] = get_fp_val(gb); 87cabdff1aSopenharmony_ci break; 88cabdff1aSopenharmony_ci case 2: 89cabdff1aSopenharmony_ci c[0] = get_fp_val(gb); 90cabdff1aSopenharmony_ci c[2] = get_fp_val(gb); 91cabdff1aSopenharmony_ci c[4] = get_fp_val(gb); 92cabdff1aSopenharmony_ci break; 93cabdff1aSopenharmony_ci case 3: 94cabdff1aSopenharmony_ci c[0] = get_fp_val(gb); 95cabdff1aSopenharmony_ci c[1] = get_fp_val(gb); 96cabdff1aSopenharmony_ci c[2] = get_fp_val(gb); 97cabdff1aSopenharmony_ci c[3] = get_fp_val(gb); 98cabdff1aSopenharmony_ci c[4] = get_fp_val(gb); 99cabdff1aSopenharmony_ci break; 100cabdff1aSopenharmony_ci } 101cabdff1aSopenharmony_ci c[5] = get_fp_val(gb); 102cabdff1aSopenharmony_ci if (get_bits1(gb)) 103cabdff1aSopenharmony_ci c[6] = get_fp_val(gb); 104cabdff1aSopenharmony_ci else 105cabdff1aSopenharmony_ci c[6] = 1 << 16; 106cabdff1aSopenharmony_ci} 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_cistatic int vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd) 109cabdff1aSopenharmony_ci{ 110cabdff1aSopenharmony_ci AVCodecContext *avctx = v->s.avctx; 111cabdff1aSopenharmony_ci int sprite, i; 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci for (sprite = 0; sprite <= v->two_sprites; sprite++) { 114cabdff1aSopenharmony_ci vc1_sprite_parse_transform(gb, sd->coefs[sprite]); 115cabdff1aSopenharmony_ci if (sd->coefs[sprite][1] || sd->coefs[sprite][3]) 116cabdff1aSopenharmony_ci avpriv_request_sample(avctx, "Non-zero rotation coefficients"); 117cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:"); 118cabdff1aSopenharmony_ci for (i = 0; i < 7; i++) 119cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " %d.%.3d", 120cabdff1aSopenharmony_ci sd->coefs[sprite][i] / (1<<16), 121cabdff1aSopenharmony_ci (abs(sd->coefs[sprite][i]) & 0xFFFF) * 1000 / (1 << 16)); 122cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "\n"); 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci skip_bits(gb, 2); 126cabdff1aSopenharmony_ci if (sd->effect_type = get_bits_long(gb, 30)) { 127cabdff1aSopenharmony_ci switch (sd->effect_pcount1 = get_bits(gb, 4)) { 128cabdff1aSopenharmony_ci case 7: 129cabdff1aSopenharmony_ci vc1_sprite_parse_transform(gb, sd->effect_params1); 130cabdff1aSopenharmony_ci break; 131cabdff1aSopenharmony_ci case 14: 132cabdff1aSopenharmony_ci vc1_sprite_parse_transform(gb, sd->effect_params1); 133cabdff1aSopenharmony_ci vc1_sprite_parse_transform(gb, sd->effect_params1 + 7); 134cabdff1aSopenharmony_ci break; 135cabdff1aSopenharmony_ci default: 136cabdff1aSopenharmony_ci for (i = 0; i < sd->effect_pcount1; i++) 137cabdff1aSopenharmony_ci sd->effect_params1[i] = get_fp_val(gb); 138cabdff1aSopenharmony_ci } 139cabdff1aSopenharmony_ci if (sd->effect_type != 13 || sd->effect_params1[0] != sd->coefs[0][6]) { 140cabdff1aSopenharmony_ci // effect 13 is simple alpha blending and matches the opacity above 141cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Effect: %d; params: ", sd->effect_type); 142cabdff1aSopenharmony_ci for (i = 0; i < sd->effect_pcount1; i++) 143cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " %d.%.2d", 144cabdff1aSopenharmony_ci sd->effect_params1[i] / (1 << 16), 145cabdff1aSopenharmony_ci (abs(sd->effect_params1[i]) & 0xFFFF) * 1000 / (1 << 16)); 146cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "\n"); 147cabdff1aSopenharmony_ci } 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci sd->effect_pcount2 = get_bits(gb, 16); 150cabdff1aSopenharmony_ci if (sd->effect_pcount2 > 10) { 151cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Too many effect parameters\n"); 152cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 153cabdff1aSopenharmony_ci } else if (sd->effect_pcount2) { 154cabdff1aSopenharmony_ci i = -1; 155cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Effect params 2: "); 156cabdff1aSopenharmony_ci while (++i < sd->effect_pcount2) { 157cabdff1aSopenharmony_ci sd->effect_params2[i] = get_fp_val(gb); 158cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, " %d.%.2d", 159cabdff1aSopenharmony_ci sd->effect_params2[i] / (1 << 16), 160cabdff1aSopenharmony_ci (abs(sd->effect_params2[i]) & 0xFFFF) * 1000 / (1 << 16)); 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "\n"); 163cabdff1aSopenharmony_ci } 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci if (sd->effect_flag = get_bits1(gb)) 166cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Effect flag set\n"); 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci if (get_bits_count(gb) >= gb->size_in_bits + 169cabdff1aSopenharmony_ci (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE ? 64 : 0)) { 170cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Buffer overrun\n"); 171cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci if (get_bits_count(gb) < gb->size_in_bits - 8) 174cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Buffer not fully read\n"); 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci return 0; 177cabdff1aSopenharmony_ci} 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_cistatic void vc1_draw_sprites(VC1Context *v, SpriteData* sd) 180cabdff1aSopenharmony_ci{ 181cabdff1aSopenharmony_ci int i, plane, row, sprite; 182cabdff1aSopenharmony_ci int sr_cache[2][2] = { { -1, -1 }, { -1, -1 } }; 183cabdff1aSopenharmony_ci uint8_t* src_h[2][2]; 184cabdff1aSopenharmony_ci int xoff[2], xadv[2], yoff[2], yadv[2], alpha; 185cabdff1aSopenharmony_ci int ysub[2]; 186cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_ci for (i = 0; i <= v->two_sprites; i++) { 189cabdff1aSopenharmony_ci xoff[i] = av_clip(sd->coefs[i][2], 0, v->sprite_width-1 << 16); 190cabdff1aSopenharmony_ci xadv[i] = sd->coefs[i][0]; 191cabdff1aSopenharmony_ci if (xadv[i] != 1<<16 || (v->sprite_width << 16) - (v->output_width << 16) - xoff[i]) 192cabdff1aSopenharmony_ci xadv[i] = av_clip(xadv[i], 0, ((v->sprite_width<<16) - xoff[i] - 1) / v->output_width); 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci yoff[i] = av_clip(sd->coefs[i][5], 0, v->sprite_height-1 << 16); 195cabdff1aSopenharmony_ci yadv[i] = av_clip(sd->coefs[i][4], 0, ((v->sprite_height << 16) - yoff[i]) / v->output_height); 196cabdff1aSopenharmony_ci } 197cabdff1aSopenharmony_ci alpha = av_clip_uint16(sd->coefs[1][6]); 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci for (plane = 0; plane < (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY ? 1 : 3); plane++) { 200cabdff1aSopenharmony_ci int width = v->output_width>>!!plane; 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci for (row = 0; row < v->output_height>>!!plane; row++) { 203cabdff1aSopenharmony_ci uint8_t *dst = v->sprite_output_frame->data[plane] + 204cabdff1aSopenharmony_ci v->sprite_output_frame->linesize[plane] * row; 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci for (sprite = 0; sprite <= v->two_sprites; sprite++) { 207cabdff1aSopenharmony_ci uint8_t *iplane = s->current_picture.f->data[plane]; 208cabdff1aSopenharmony_ci int iline = s->current_picture.f->linesize[plane]; 209cabdff1aSopenharmony_ci int ycoord = yoff[sprite] + yadv[sprite] * row; 210cabdff1aSopenharmony_ci int yline = ycoord >> 16; 211cabdff1aSopenharmony_ci int next_line; 212cabdff1aSopenharmony_ci ysub[sprite] = ycoord & 0xFFFF; 213cabdff1aSopenharmony_ci if (sprite) { 214cabdff1aSopenharmony_ci iplane = s->last_picture.f->data[plane]; 215cabdff1aSopenharmony_ci iline = s->last_picture.f->linesize[plane]; 216cabdff1aSopenharmony_ci } 217cabdff1aSopenharmony_ci next_line = FFMIN(yline + 1, (v->sprite_height >> !!plane) - 1) * iline; 218cabdff1aSopenharmony_ci if (!(xoff[sprite] & 0xFFFF) && xadv[sprite] == 1 << 16) { 219cabdff1aSopenharmony_ci src_h[sprite][0] = iplane + (xoff[sprite] >> 16) + yline * iline; 220cabdff1aSopenharmony_ci if (ysub[sprite]) 221cabdff1aSopenharmony_ci src_h[sprite][1] = iplane + (xoff[sprite] >> 16) + next_line; 222cabdff1aSopenharmony_ci } else { 223cabdff1aSopenharmony_ci if (sr_cache[sprite][0] != yline) { 224cabdff1aSopenharmony_ci if (sr_cache[sprite][1] == yline) { 225cabdff1aSopenharmony_ci FFSWAP(uint8_t*, v->sr_rows[sprite][0], v->sr_rows[sprite][1]); 226cabdff1aSopenharmony_ci FFSWAP(int, sr_cache[sprite][0], sr_cache[sprite][1]); 227cabdff1aSopenharmony_ci } else { 228cabdff1aSopenharmony_ci v->vc1dsp.sprite_h(v->sr_rows[sprite][0], iplane + yline * iline, xoff[sprite], xadv[sprite], width); 229cabdff1aSopenharmony_ci sr_cache[sprite][0] = yline; 230cabdff1aSopenharmony_ci } 231cabdff1aSopenharmony_ci } 232cabdff1aSopenharmony_ci if (ysub[sprite] && sr_cache[sprite][1] != yline + 1) { 233cabdff1aSopenharmony_ci v->vc1dsp.sprite_h(v->sr_rows[sprite][1], 234cabdff1aSopenharmony_ci iplane + next_line, xoff[sprite], 235cabdff1aSopenharmony_ci xadv[sprite], width); 236cabdff1aSopenharmony_ci sr_cache[sprite][1] = yline + 1; 237cabdff1aSopenharmony_ci } 238cabdff1aSopenharmony_ci src_h[sprite][0] = v->sr_rows[sprite][0]; 239cabdff1aSopenharmony_ci src_h[sprite][1] = v->sr_rows[sprite][1]; 240cabdff1aSopenharmony_ci } 241cabdff1aSopenharmony_ci } 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci if (!v->two_sprites) { 244cabdff1aSopenharmony_ci if (ysub[0]) { 245cabdff1aSopenharmony_ci v->vc1dsp.sprite_v_single(dst, src_h[0][0], src_h[0][1], ysub[0], width); 246cabdff1aSopenharmony_ci } else { 247cabdff1aSopenharmony_ci memcpy(dst, src_h[0][0], width); 248cabdff1aSopenharmony_ci } 249cabdff1aSopenharmony_ci } else { 250cabdff1aSopenharmony_ci if (ysub[0] && ysub[1]) { 251cabdff1aSopenharmony_ci v->vc1dsp.sprite_v_double_twoscale(dst, src_h[0][0], src_h[0][1], ysub[0], 252cabdff1aSopenharmony_ci src_h[1][0], src_h[1][1], ysub[1], alpha, width); 253cabdff1aSopenharmony_ci } else if (ysub[0]) { 254cabdff1aSopenharmony_ci v->vc1dsp.sprite_v_double_onescale(dst, src_h[0][0], src_h[0][1], ysub[0], 255cabdff1aSopenharmony_ci src_h[1][0], alpha, width); 256cabdff1aSopenharmony_ci } else if (ysub[1]) { 257cabdff1aSopenharmony_ci v->vc1dsp.sprite_v_double_onescale(dst, src_h[1][0], src_h[1][1], ysub[1], 258cabdff1aSopenharmony_ci src_h[0][0], (1<<16)-1-alpha, width); 259cabdff1aSopenharmony_ci } else { 260cabdff1aSopenharmony_ci v->vc1dsp.sprite_v_double_noscale(dst, src_h[0][0], src_h[1][0], alpha, width); 261cabdff1aSopenharmony_ci } 262cabdff1aSopenharmony_ci } 263cabdff1aSopenharmony_ci } 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci if (!plane) { 266cabdff1aSopenharmony_ci for (i = 0; i <= v->two_sprites; i++) { 267cabdff1aSopenharmony_ci xoff[i] >>= 1; 268cabdff1aSopenharmony_ci yoff[i] >>= 1; 269cabdff1aSopenharmony_ci } 270cabdff1aSopenharmony_ci } 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ci} 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_cistatic int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) 277cabdff1aSopenharmony_ci{ 278cabdff1aSopenharmony_ci int ret; 279cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 280cabdff1aSopenharmony_ci AVCodecContext *avctx = s->avctx; 281cabdff1aSopenharmony_ci SpriteData sd; 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci memset(&sd, 0, sizeof(sd)); 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ci ret = vc1_parse_sprites(v, gb, &sd); 286cabdff1aSopenharmony_ci if (ret < 0) 287cabdff1aSopenharmony_ci return ret; 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_ci if (!s->current_picture.f || !s->current_picture.f->data[0]) { 290cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Got no sprites\n"); 291cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 292cabdff1aSopenharmony_ci } 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ci if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f->data[0])) { 295cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n"); 296cabdff1aSopenharmony_ci v->two_sprites = 0; 297cabdff1aSopenharmony_ci } 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci av_frame_unref(v->sprite_output_frame); 300cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, v->sprite_output_frame, 0)) < 0) 301cabdff1aSopenharmony_ci return ret; 302cabdff1aSopenharmony_ci 303cabdff1aSopenharmony_ci vc1_draw_sprites(v, &sd); 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci return 0; 306cabdff1aSopenharmony_ci} 307cabdff1aSopenharmony_ci 308cabdff1aSopenharmony_cistatic void vc1_sprite_flush(AVCodecContext *avctx) 309cabdff1aSopenharmony_ci{ 310cabdff1aSopenharmony_ci VC1Context *v = avctx->priv_data; 311cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 312cabdff1aSopenharmony_ci AVFrame *f = s->current_picture.f; 313cabdff1aSopenharmony_ci int plane, i; 314cabdff1aSopenharmony_ci 315cabdff1aSopenharmony_ci /* Windows Media Image codecs have a convergence interval of two keyframes. 316cabdff1aSopenharmony_ci Since we can't enforce it, clear to black the missing sprite. This is 317cabdff1aSopenharmony_ci wrong but it looks better than doing nothing. */ 318cabdff1aSopenharmony_ci 319cabdff1aSopenharmony_ci if (f && f->data[0]) 320cabdff1aSopenharmony_ci for (plane = 0; plane < (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY ? 1 : 3); plane++) 321cabdff1aSopenharmony_ci for (i = 0; i < v->sprite_height>>!!plane; i++) 322cabdff1aSopenharmony_ci memset(f->data[plane] + i * f->linesize[plane], 323cabdff1aSopenharmony_ci plane ? 128 : 0, f->linesize[plane]); 324cabdff1aSopenharmony_ci} 325cabdff1aSopenharmony_ci 326cabdff1aSopenharmony_ci#endif 327cabdff1aSopenharmony_ci 328cabdff1aSopenharmony_ciav_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) 329cabdff1aSopenharmony_ci{ 330cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 331cabdff1aSopenharmony_ci int i, ret = AVERROR(ENOMEM); 332cabdff1aSopenharmony_ci int mb_height = FFALIGN(s->mb_height, 2); 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_ci /* Allocate mb bitplanes */ 335cabdff1aSopenharmony_ci v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height); 336cabdff1aSopenharmony_ci v->direct_mb_plane = av_malloc (s->mb_stride * mb_height); 337cabdff1aSopenharmony_ci v->forward_mb_plane = av_malloc (s->mb_stride * mb_height); 338cabdff1aSopenharmony_ci v->fieldtx_plane = av_mallocz(s->mb_stride * mb_height); 339cabdff1aSopenharmony_ci v->acpred_plane = av_malloc (s->mb_stride * mb_height); 340cabdff1aSopenharmony_ci v->over_flags_plane = av_malloc (s->mb_stride * mb_height); 341cabdff1aSopenharmony_ci if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->forward_mb_plane || 342cabdff1aSopenharmony_ci !v->fieldtx_plane || !v->acpred_plane || !v->over_flags_plane) 343cabdff1aSopenharmony_ci goto error; 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_ci v->n_allocated_blks = s->mb_width + 2; 346cabdff1aSopenharmony_ci v->block = av_malloc(sizeof(*v->block) * v->n_allocated_blks); 347cabdff1aSopenharmony_ci v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 3 * s->mb_stride); 348cabdff1aSopenharmony_ci if (!v->block || !v->cbp_base) 349cabdff1aSopenharmony_ci goto error; 350cabdff1aSopenharmony_ci v->cbp = v->cbp_base + 2 * s->mb_stride; 351cabdff1aSopenharmony_ci v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 3 * s->mb_stride); 352cabdff1aSopenharmony_ci if (!v->ttblk_base) 353cabdff1aSopenharmony_ci goto error; 354cabdff1aSopenharmony_ci v->ttblk = v->ttblk_base + 2 * s->mb_stride; 355cabdff1aSopenharmony_ci v->is_intra_base = av_mallocz(sizeof(v->is_intra_base[0]) * 3 * s->mb_stride); 356cabdff1aSopenharmony_ci if (!v->is_intra_base) 357cabdff1aSopenharmony_ci goto error; 358cabdff1aSopenharmony_ci v->is_intra = v->is_intra_base + 2 * s->mb_stride; 359cabdff1aSopenharmony_ci v->luma_mv_base = av_mallocz(sizeof(v->luma_mv_base[0]) * 3 * s->mb_stride); 360cabdff1aSopenharmony_ci if (!v->luma_mv_base) 361cabdff1aSopenharmony_ci goto error; 362cabdff1aSopenharmony_ci v->luma_mv = v->luma_mv_base + 2 * s->mb_stride; 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci /* allocate block type info in that way so it could be used with s->block_index[] */ 365cabdff1aSopenharmony_ci v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); 366cabdff1aSopenharmony_ci if (!v->mb_type_base) 367cabdff1aSopenharmony_ci goto error; 368cabdff1aSopenharmony_ci v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; 369cabdff1aSopenharmony_ci v->mb_type[1] = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1; 370cabdff1aSopenharmony_ci v->mb_type[2] = v->mb_type[1] + s->mb_stride * (mb_height + 1); 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci /* allocate memory to store block level MV info */ 373cabdff1aSopenharmony_ci v->blk_mv_type_base = av_mallocz( s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); 374cabdff1aSopenharmony_ci if (!v->blk_mv_type_base) 375cabdff1aSopenharmony_ci goto error; 376cabdff1aSopenharmony_ci v->blk_mv_type = v->blk_mv_type_base + s->b8_stride + 1; 377cabdff1aSopenharmony_ci v->mv_f_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2)); 378cabdff1aSopenharmony_ci if (!v->mv_f_base) 379cabdff1aSopenharmony_ci goto error; 380cabdff1aSopenharmony_ci v->mv_f[0] = v->mv_f_base + s->b8_stride + 1; 381cabdff1aSopenharmony_ci v->mv_f[1] = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); 382cabdff1aSopenharmony_ci v->mv_f_next_base = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2)); 383cabdff1aSopenharmony_ci if (!v->mv_f_next_base) 384cabdff1aSopenharmony_ci goto error; 385cabdff1aSopenharmony_ci v->mv_f_next[0] = v->mv_f_next_base + s->b8_stride + 1; 386cabdff1aSopenharmony_ci v->mv_f_next[1] = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); 387cabdff1aSopenharmony_ci 388cabdff1aSopenharmony_ci if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { 389cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 390cabdff1aSopenharmony_ci if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) 391cabdff1aSopenharmony_ci goto error; 392cabdff1aSopenharmony_ci } 393cabdff1aSopenharmony_ci 394cabdff1aSopenharmony_ci ret = ff_intrax8_common_init(s->avctx, &v->x8, &s->idsp, 395cabdff1aSopenharmony_ci s->block, s->block_last_index, 396cabdff1aSopenharmony_ci s->mb_width, s->mb_height); 397cabdff1aSopenharmony_ci if (ret < 0) 398cabdff1aSopenharmony_ci goto error; 399cabdff1aSopenharmony_ci 400cabdff1aSopenharmony_ci return 0; 401cabdff1aSopenharmony_ci 402cabdff1aSopenharmony_cierror: 403cabdff1aSopenharmony_ci ff_vc1_decode_end(s->avctx); 404cabdff1aSopenharmony_ci return ret; 405cabdff1aSopenharmony_ci} 406cabdff1aSopenharmony_ci 407cabdff1aSopenharmony_ciav_cold void ff_vc1_init_transposed_scantables(VC1Context *v) 408cabdff1aSopenharmony_ci{ 409cabdff1aSopenharmony_ci int i; 410cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) { 411cabdff1aSopenharmony_ci#define transpose(x) (((x) >> 3) | (((x) & 7) << 3)) 412cabdff1aSopenharmony_ci v->zz_8x8[0][i] = transpose(ff_wmv1_scantable[0][i]); 413cabdff1aSopenharmony_ci v->zz_8x8[1][i] = transpose(ff_wmv1_scantable[1][i]); 414cabdff1aSopenharmony_ci v->zz_8x8[2][i] = transpose(ff_wmv1_scantable[2][i]); 415cabdff1aSopenharmony_ci v->zz_8x8[3][i] = transpose(ff_wmv1_scantable[3][i]); 416cabdff1aSopenharmony_ci v->zzi_8x8[i] = transpose(ff_vc1_adv_interlaced_8x8_zz[i]); 417cabdff1aSopenharmony_ci } 418cabdff1aSopenharmony_ci v->left_blk_sh = 0; 419cabdff1aSopenharmony_ci v->top_blk_sh = 3; 420cabdff1aSopenharmony_ci} 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_ci/** Initialize a VC1/WMV3 decoder 423cabdff1aSopenharmony_ci * @todo TODO: Handle VC-1 IDUs (Transport level?) 424cabdff1aSopenharmony_ci * @todo TODO: Decipher remaining bits in extra_data 425cabdff1aSopenharmony_ci */ 426cabdff1aSopenharmony_cistatic av_cold int vc1_decode_init(AVCodecContext *avctx) 427cabdff1aSopenharmony_ci{ 428cabdff1aSopenharmony_ci VC1Context *v = avctx->priv_data; 429cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 430cabdff1aSopenharmony_ci GetBitContext gb; 431cabdff1aSopenharmony_ci int ret; 432cabdff1aSopenharmony_ci 433cabdff1aSopenharmony_ci /* save the container output size for WMImage */ 434cabdff1aSopenharmony_ci v->output_width = avctx->width; 435cabdff1aSopenharmony_ci v->output_height = avctx->height; 436cabdff1aSopenharmony_ci 437cabdff1aSopenharmony_ci if (!avctx->extradata_size || !avctx->extradata) 438cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 439cabdff1aSopenharmony_ci v->s.avctx = avctx; 440cabdff1aSopenharmony_ci 441cabdff1aSopenharmony_ci ff_vc1_init_common(v); 442cabdff1aSopenharmony_ci 443cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) { 444cabdff1aSopenharmony_ci int count = 0; 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci // looks like WMV3 has a sequence header stored in the extradata 447cabdff1aSopenharmony_ci // advanced sequence header may be before the first frame 448cabdff1aSopenharmony_ci // the last byte of the extradata is a version number, 1 for the 449cabdff1aSopenharmony_ci // samples we can decode 450cabdff1aSopenharmony_ci 451cabdff1aSopenharmony_ci ret = init_get_bits8(&gb, avctx->extradata, avctx->extradata_size); 452cabdff1aSopenharmony_ci if (ret < 0) 453cabdff1aSopenharmony_ci return ret; 454cabdff1aSopenharmony_ci 455cabdff1aSopenharmony_ci if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) 456cabdff1aSopenharmony_ci return ret; 457cabdff1aSopenharmony_ci 458cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE && !v->res_sprite) { 459cabdff1aSopenharmony_ci avpriv_request_sample(avctx, "Non sprite WMV3IMAGE"); 460cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 461cabdff1aSopenharmony_ci } 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci count = avctx->extradata_size*8 - get_bits_count(&gb); 464cabdff1aSopenharmony_ci if (count > 0) { 465cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n", 466cabdff1aSopenharmony_ci count, get_bits_long(&gb, FFMIN(count, 32))); 467cabdff1aSopenharmony_ci } else if (count < 0) { 468cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); 469cabdff1aSopenharmony_ci } 470cabdff1aSopenharmony_ci } else { // VC1/WVC1/WVP2 471cabdff1aSopenharmony_ci const uint8_t *start = avctx->extradata; 472cabdff1aSopenharmony_ci uint8_t *end = avctx->extradata + avctx->extradata_size; 473cabdff1aSopenharmony_ci const uint8_t *next; 474cabdff1aSopenharmony_ci int size, buf2_size; 475cabdff1aSopenharmony_ci uint8_t *buf2 = NULL; 476cabdff1aSopenharmony_ci int seq_initialized = 0, ep_initialized = 0; 477cabdff1aSopenharmony_ci 478cabdff1aSopenharmony_ci if (avctx->extradata_size < 16) { 479cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size); 480cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 481cabdff1aSopenharmony_ci } 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_ci buf2 = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 484cabdff1aSopenharmony_ci if (!buf2) 485cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 486cabdff1aSopenharmony_ci 487cabdff1aSopenharmony_ci start = find_next_marker(start, end); // in WVC1 extradata first byte is its size, but can be 0 in mkv 488cabdff1aSopenharmony_ci next = start; 489cabdff1aSopenharmony_ci for (; next < end; start = next) { 490cabdff1aSopenharmony_ci next = find_next_marker(start + 4, end); 491cabdff1aSopenharmony_ci size = next - start - 4; 492cabdff1aSopenharmony_ci if (size <= 0) 493cabdff1aSopenharmony_ci continue; 494cabdff1aSopenharmony_ci buf2_size = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2); 495cabdff1aSopenharmony_ci init_get_bits(&gb, buf2, buf2_size * 8); 496cabdff1aSopenharmony_ci switch (AV_RB32(start)) { 497cabdff1aSopenharmony_ci case VC1_CODE_SEQHDR: 498cabdff1aSopenharmony_ci if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) { 499cabdff1aSopenharmony_ci av_free(buf2); 500cabdff1aSopenharmony_ci return ret; 501cabdff1aSopenharmony_ci } 502cabdff1aSopenharmony_ci seq_initialized = 1; 503cabdff1aSopenharmony_ci break; 504cabdff1aSopenharmony_ci case VC1_CODE_ENTRYPOINT: 505cabdff1aSopenharmony_ci if ((ret = ff_vc1_decode_entry_point(avctx, v, &gb)) < 0) { 506cabdff1aSopenharmony_ci av_free(buf2); 507cabdff1aSopenharmony_ci return ret; 508cabdff1aSopenharmony_ci } 509cabdff1aSopenharmony_ci ep_initialized = 1; 510cabdff1aSopenharmony_ci break; 511cabdff1aSopenharmony_ci } 512cabdff1aSopenharmony_ci } 513cabdff1aSopenharmony_ci av_free(buf2); 514cabdff1aSopenharmony_ci if (!seq_initialized || !ep_initialized) { 515cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); 516cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 517cabdff1aSopenharmony_ci } 518cabdff1aSopenharmony_ci v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE); 519cabdff1aSopenharmony_ci } 520cabdff1aSopenharmony_ci 521cabdff1aSopenharmony_ci avctx->profile = v->profile; 522cabdff1aSopenharmony_ci if (v->profile == PROFILE_ADVANCED) 523cabdff1aSopenharmony_ci avctx->level = v->level; 524cabdff1aSopenharmony_ci 525cabdff1aSopenharmony_ci if (!CONFIG_GRAY || !(avctx->flags & AV_CODEC_FLAG_GRAY)) 526cabdff1aSopenharmony_ci avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts); 527cabdff1aSopenharmony_ci else { 528cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_GRAY8; 529cabdff1aSopenharmony_ci if (avctx->color_range == AVCOL_RANGE_UNSPECIFIED) 530cabdff1aSopenharmony_ci avctx->color_range = AVCOL_RANGE_MPEG; 531cabdff1aSopenharmony_ci } 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_ci // ensure static VLC tables are initialized 534cabdff1aSopenharmony_ci if ((ret = ff_msmpeg4_decode_init(avctx)) < 0) 535cabdff1aSopenharmony_ci return ret; 536cabdff1aSopenharmony_ci if ((ret = ff_vc1_decode_init_alloc_tables(v)) < 0) 537cabdff1aSopenharmony_ci return ret; 538cabdff1aSopenharmony_ci // Hack to ensure the above functions will be called 539cabdff1aSopenharmony_ci // again once we know all necessary settings. 540cabdff1aSopenharmony_ci // That this is necessary might indicate a bug. 541cabdff1aSopenharmony_ci ff_vc1_decode_end(avctx); 542cabdff1aSopenharmony_ci 543cabdff1aSopenharmony_ci ff_blockdsp_init(&s->bdsp, avctx); 544cabdff1aSopenharmony_ci ff_h264chroma_init(&v->h264chroma, 8); 545cabdff1aSopenharmony_ci ff_qpeldsp_init(&s->qdsp); 546cabdff1aSopenharmony_ci 547cabdff1aSopenharmony_ci avctx->has_b_frames = !!avctx->max_b_frames; 548cabdff1aSopenharmony_ci 549cabdff1aSopenharmony_ci if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6) 550cabdff1aSopenharmony_ci avctx->color_primaries = v->color_prim; 551cabdff1aSopenharmony_ci if (v->transfer_char == 1 || v->transfer_char == 7) 552cabdff1aSopenharmony_ci avctx->color_trc = v->transfer_char; 553cabdff1aSopenharmony_ci if (v->matrix_coef == 1 || v->matrix_coef == 6 || v->matrix_coef == 7) 554cabdff1aSopenharmony_ci avctx->colorspace = v->matrix_coef; 555cabdff1aSopenharmony_ci 556cabdff1aSopenharmony_ci s->mb_width = (avctx->coded_width + 15) >> 4; 557cabdff1aSopenharmony_ci s->mb_height = (avctx->coded_height + 15) >> 4; 558cabdff1aSopenharmony_ci 559cabdff1aSopenharmony_ci if (v->profile == PROFILE_ADVANCED || v->res_fasttx) { 560cabdff1aSopenharmony_ci ff_vc1_init_transposed_scantables(v); 561cabdff1aSopenharmony_ci } else { 562cabdff1aSopenharmony_ci memcpy(v->zz_8x8, ff_wmv1_scantable, 4*64); 563cabdff1aSopenharmony_ci v->left_blk_sh = 3; 564cabdff1aSopenharmony_ci v->top_blk_sh = 0; 565cabdff1aSopenharmony_ci } 566cabdff1aSopenharmony_ci 567cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { 568cabdff1aSopenharmony_ci v->sprite_width = avctx->coded_width; 569cabdff1aSopenharmony_ci v->sprite_height = avctx->coded_height; 570cabdff1aSopenharmony_ci 571cabdff1aSopenharmony_ci avctx->coded_width = avctx->width = v->output_width; 572cabdff1aSopenharmony_ci avctx->coded_height = avctx->height = v->output_height; 573cabdff1aSopenharmony_ci 574cabdff1aSopenharmony_ci // prevent 16.16 overflows 575cabdff1aSopenharmony_ci if (v->sprite_width > 1 << 14 || 576cabdff1aSopenharmony_ci v->sprite_height > 1 << 14 || 577cabdff1aSopenharmony_ci v->output_width > 1 << 14 || 578cabdff1aSopenharmony_ci v->output_height > 1 << 14) { 579cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 580cabdff1aSopenharmony_ci } 581cabdff1aSopenharmony_ci 582cabdff1aSopenharmony_ci if ((v->sprite_width&1) || (v->sprite_height&1)) { 583cabdff1aSopenharmony_ci avpriv_request_sample(avctx, "odd sprites support"); 584cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 585cabdff1aSopenharmony_ci } 586cabdff1aSopenharmony_ci } 587cabdff1aSopenharmony_ci return 0; 588cabdff1aSopenharmony_ci} 589cabdff1aSopenharmony_ci 590cabdff1aSopenharmony_ci/** Close a VC1/WMV3 decoder 591cabdff1aSopenharmony_ci * @warning Initial try at using MpegEncContext stuff 592cabdff1aSopenharmony_ci */ 593cabdff1aSopenharmony_ciav_cold int ff_vc1_decode_end(AVCodecContext *avctx) 594cabdff1aSopenharmony_ci{ 595cabdff1aSopenharmony_ci VC1Context *v = avctx->priv_data; 596cabdff1aSopenharmony_ci int i; 597cabdff1aSopenharmony_ci 598cabdff1aSopenharmony_ci av_frame_free(&v->sprite_output_frame); 599cabdff1aSopenharmony_ci 600cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 601cabdff1aSopenharmony_ci av_freep(&v->sr_rows[i >> 1][i & 1]); 602cabdff1aSopenharmony_ci ff_mpv_common_end(&v->s); 603cabdff1aSopenharmony_ci av_freep(&v->mv_type_mb_plane); 604cabdff1aSopenharmony_ci av_freep(&v->direct_mb_plane); 605cabdff1aSopenharmony_ci av_freep(&v->forward_mb_plane); 606cabdff1aSopenharmony_ci av_freep(&v->fieldtx_plane); 607cabdff1aSopenharmony_ci av_freep(&v->acpred_plane); 608cabdff1aSopenharmony_ci av_freep(&v->over_flags_plane); 609cabdff1aSopenharmony_ci av_freep(&v->mb_type_base); 610cabdff1aSopenharmony_ci av_freep(&v->blk_mv_type_base); 611cabdff1aSopenharmony_ci av_freep(&v->mv_f_base); 612cabdff1aSopenharmony_ci av_freep(&v->mv_f_next_base); 613cabdff1aSopenharmony_ci av_freep(&v->block); 614cabdff1aSopenharmony_ci av_freep(&v->cbp_base); 615cabdff1aSopenharmony_ci av_freep(&v->ttblk_base); 616cabdff1aSopenharmony_ci av_freep(&v->is_intra_base); // FIXME use v->mb_type[] 617cabdff1aSopenharmony_ci av_freep(&v->luma_mv_base); 618cabdff1aSopenharmony_ci ff_intrax8_common_end(&v->x8); 619cabdff1aSopenharmony_ci return 0; 620cabdff1aSopenharmony_ci} 621cabdff1aSopenharmony_ci 622cabdff1aSopenharmony_ci 623cabdff1aSopenharmony_ci/** Decode a VC1/WMV3 frame 624cabdff1aSopenharmony_ci * @todo TODO: Handle VC-1 IDUs (Transport level?) 625cabdff1aSopenharmony_ci */ 626cabdff1aSopenharmony_cistatic int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict, 627cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 628cabdff1aSopenharmony_ci{ 629cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 630cabdff1aSopenharmony_ci int buf_size = avpkt->size, n_slices = 0, i, ret; 631cabdff1aSopenharmony_ci VC1Context *v = avctx->priv_data; 632cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 633cabdff1aSopenharmony_ci uint8_t *buf2 = NULL; 634cabdff1aSopenharmony_ci const uint8_t *buf_start = buf, *buf_start_second_field = NULL; 635cabdff1aSopenharmony_ci int mb_height, n_slices1=-1; 636cabdff1aSopenharmony_ci struct { 637cabdff1aSopenharmony_ci uint8_t *buf; 638cabdff1aSopenharmony_ci GetBitContext gb; 639cabdff1aSopenharmony_ci int mby_start; 640cabdff1aSopenharmony_ci const uint8_t *rawbuf; 641cabdff1aSopenharmony_ci int raw_size; 642cabdff1aSopenharmony_ci } *slices = NULL, *tmp; 643cabdff1aSopenharmony_ci 644cabdff1aSopenharmony_ci v->second_field = 0; 645cabdff1aSopenharmony_ci 646cabdff1aSopenharmony_ci if(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY) 647cabdff1aSopenharmony_ci s->low_delay = 1; 648cabdff1aSopenharmony_ci 649cabdff1aSopenharmony_ci /* no supplementary picture */ 650cabdff1aSopenharmony_ci if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { 651cabdff1aSopenharmony_ci /* special case for last picture */ 652cabdff1aSopenharmony_ci if (s->low_delay == 0 && s->next_picture_ptr) { 653cabdff1aSopenharmony_ci if ((ret = av_frame_ref(pict, s->next_picture_ptr->f)) < 0) 654cabdff1aSopenharmony_ci return ret; 655cabdff1aSopenharmony_ci s->next_picture_ptr = NULL; 656cabdff1aSopenharmony_ci 657cabdff1aSopenharmony_ci *got_frame = 1; 658cabdff1aSopenharmony_ci } 659cabdff1aSopenharmony_ci 660cabdff1aSopenharmony_ci return buf_size; 661cabdff1aSopenharmony_ci } 662cabdff1aSopenharmony_ci 663cabdff1aSopenharmony_ci //for advanced profile we may need to parse and unescape data 664cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { 665cabdff1aSopenharmony_ci int buf_size2 = 0; 666cabdff1aSopenharmony_ci buf2 = av_mallocz(buf_size + AV_INPUT_BUFFER_PADDING_SIZE); 667cabdff1aSopenharmony_ci if (!buf2) 668cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 669cabdff1aSopenharmony_ci 670cabdff1aSopenharmony_ci if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */ 671cabdff1aSopenharmony_ci const uint8_t *start, *end, *next; 672cabdff1aSopenharmony_ci int size; 673cabdff1aSopenharmony_ci 674cabdff1aSopenharmony_ci next = buf; 675cabdff1aSopenharmony_ci for (start = buf, end = buf + buf_size; next < end; start = next) { 676cabdff1aSopenharmony_ci next = find_next_marker(start + 4, end); 677cabdff1aSopenharmony_ci size = next - start - 4; 678cabdff1aSopenharmony_ci if (size <= 0) continue; 679cabdff1aSopenharmony_ci switch (AV_RB32(start)) { 680cabdff1aSopenharmony_ci case VC1_CODE_FRAME: 681cabdff1aSopenharmony_ci if (avctx->hwaccel) 682cabdff1aSopenharmony_ci buf_start = start; 683cabdff1aSopenharmony_ci buf_size2 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2); 684cabdff1aSopenharmony_ci break; 685cabdff1aSopenharmony_ci case VC1_CODE_FIELD: { 686cabdff1aSopenharmony_ci int buf_size3; 687cabdff1aSopenharmony_ci if (avctx->hwaccel) 688cabdff1aSopenharmony_ci buf_start_second_field = start; 689cabdff1aSopenharmony_ci tmp = av_realloc_array(slices, sizeof(*slices), n_slices+1); 690cabdff1aSopenharmony_ci if (!tmp) { 691cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 692cabdff1aSopenharmony_ci goto err; 693cabdff1aSopenharmony_ci } 694cabdff1aSopenharmony_ci slices = tmp; 695cabdff1aSopenharmony_ci slices[n_slices].buf = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); 696cabdff1aSopenharmony_ci if (!slices[n_slices].buf) { 697cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 698cabdff1aSopenharmony_ci goto err; 699cabdff1aSopenharmony_ci } 700cabdff1aSopenharmony_ci buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, 701cabdff1aSopenharmony_ci slices[n_slices].buf); 702cabdff1aSopenharmony_ci init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, 703cabdff1aSopenharmony_ci buf_size3 << 3); 704cabdff1aSopenharmony_ci slices[n_slices].mby_start = avctx->coded_height + 31 >> 5; 705cabdff1aSopenharmony_ci slices[n_slices].rawbuf = start; 706cabdff1aSopenharmony_ci slices[n_slices].raw_size = size + 4; 707cabdff1aSopenharmony_ci n_slices1 = n_slices - 1; // index of the last slice of the first field 708cabdff1aSopenharmony_ci n_slices++; 709cabdff1aSopenharmony_ci break; 710cabdff1aSopenharmony_ci } 711cabdff1aSopenharmony_ci case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ 712cabdff1aSopenharmony_ci buf_size2 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2); 713cabdff1aSopenharmony_ci init_get_bits(&s->gb, buf2, buf_size2 * 8); 714cabdff1aSopenharmony_ci ff_vc1_decode_entry_point(avctx, v, &s->gb); 715cabdff1aSopenharmony_ci break; 716cabdff1aSopenharmony_ci case VC1_CODE_SLICE: { 717cabdff1aSopenharmony_ci int buf_size3; 718cabdff1aSopenharmony_ci tmp = av_realloc_array(slices, sizeof(*slices), n_slices+1); 719cabdff1aSopenharmony_ci if (!tmp) { 720cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 721cabdff1aSopenharmony_ci goto err; 722cabdff1aSopenharmony_ci } 723cabdff1aSopenharmony_ci slices = tmp; 724cabdff1aSopenharmony_ci slices[n_slices].buf = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); 725cabdff1aSopenharmony_ci if (!slices[n_slices].buf) { 726cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 727cabdff1aSopenharmony_ci goto err; 728cabdff1aSopenharmony_ci } 729cabdff1aSopenharmony_ci buf_size3 = v->vc1dsp.vc1_unescape_buffer(start + 4, size, 730cabdff1aSopenharmony_ci slices[n_slices].buf); 731cabdff1aSopenharmony_ci init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, 732cabdff1aSopenharmony_ci buf_size3 << 3); 733cabdff1aSopenharmony_ci slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9); 734cabdff1aSopenharmony_ci slices[n_slices].rawbuf = start; 735cabdff1aSopenharmony_ci slices[n_slices].raw_size = size + 4; 736cabdff1aSopenharmony_ci n_slices++; 737cabdff1aSopenharmony_ci break; 738cabdff1aSopenharmony_ci } 739cabdff1aSopenharmony_ci } 740cabdff1aSopenharmony_ci } 741cabdff1aSopenharmony_ci } else if (v->interlace && ((buf[0] & 0xC0) == 0xC0)) { /* WVC1 interlaced stores both fields divided by marker */ 742cabdff1aSopenharmony_ci const uint8_t *divider; 743cabdff1aSopenharmony_ci int buf_size3; 744cabdff1aSopenharmony_ci 745cabdff1aSopenharmony_ci divider = find_next_marker(buf, buf + buf_size); 746cabdff1aSopenharmony_ci if ((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD) { 747cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); 748cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 749cabdff1aSopenharmony_ci goto err; 750cabdff1aSopenharmony_ci } else { // found field marker, unescape second field 751cabdff1aSopenharmony_ci if (avctx->hwaccel) 752cabdff1aSopenharmony_ci buf_start_second_field = divider; 753cabdff1aSopenharmony_ci tmp = av_realloc_array(slices, sizeof(*slices), n_slices+1); 754cabdff1aSopenharmony_ci if (!tmp) { 755cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 756cabdff1aSopenharmony_ci goto err; 757cabdff1aSopenharmony_ci } 758cabdff1aSopenharmony_ci slices = tmp; 759cabdff1aSopenharmony_ci slices[n_slices].buf = av_mallocz(buf_size + AV_INPUT_BUFFER_PADDING_SIZE); 760cabdff1aSopenharmony_ci if (!slices[n_slices].buf) { 761cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 762cabdff1aSopenharmony_ci goto err; 763cabdff1aSopenharmony_ci } 764cabdff1aSopenharmony_ci buf_size3 = v->vc1dsp.vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf); 765cabdff1aSopenharmony_ci init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, 766cabdff1aSopenharmony_ci buf_size3 << 3); 767cabdff1aSopenharmony_ci slices[n_slices].mby_start = s->mb_height + 1 >> 1; 768cabdff1aSopenharmony_ci slices[n_slices].rawbuf = divider; 769cabdff1aSopenharmony_ci slices[n_slices].raw_size = buf + buf_size - divider; 770cabdff1aSopenharmony_ci n_slices1 = n_slices - 1; 771cabdff1aSopenharmony_ci n_slices++; 772cabdff1aSopenharmony_ci } 773cabdff1aSopenharmony_ci buf_size2 = v->vc1dsp.vc1_unescape_buffer(buf, divider - buf, buf2); 774cabdff1aSopenharmony_ci } else { 775cabdff1aSopenharmony_ci buf_size2 = v->vc1dsp.vc1_unescape_buffer(buf, buf_size, buf2); 776cabdff1aSopenharmony_ci } 777cabdff1aSopenharmony_ci init_get_bits(&s->gb, buf2, buf_size2*8); 778cabdff1aSopenharmony_ci } else{ 779cabdff1aSopenharmony_ci ret = init_get_bits8(&s->gb, buf, buf_size); 780cabdff1aSopenharmony_ci if (ret < 0) 781cabdff1aSopenharmony_ci return ret; 782cabdff1aSopenharmony_ci } 783cabdff1aSopenharmony_ci 784cabdff1aSopenharmony_ci if (v->res_sprite) { 785cabdff1aSopenharmony_ci v->new_sprite = !get_bits1(&s->gb); 786cabdff1aSopenharmony_ci v->two_sprites = get_bits1(&s->gb); 787cabdff1aSopenharmony_ci /* res_sprite means a Windows Media Image stream, AV_CODEC_ID_*IMAGE means 788cabdff1aSopenharmony_ci we're using the sprite compositor. These are intentionally kept separate 789cabdff1aSopenharmony_ci so you can get the raw sprites by using the wmv3 decoder for WMVP or 790cabdff1aSopenharmony_ci the vc1 one for WVP2 */ 791cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { 792cabdff1aSopenharmony_ci if (v->new_sprite) { 793cabdff1aSopenharmony_ci // switch AVCodecContext parameters to those of the sprites 794cabdff1aSopenharmony_ci avctx->width = avctx->coded_width = v->sprite_width; 795cabdff1aSopenharmony_ci avctx->height = avctx->coded_height = v->sprite_height; 796cabdff1aSopenharmony_ci } else { 797cabdff1aSopenharmony_ci goto image; 798cabdff1aSopenharmony_ci } 799cabdff1aSopenharmony_ci } 800cabdff1aSopenharmony_ci } 801cabdff1aSopenharmony_ci 802cabdff1aSopenharmony_ci if (s->context_initialized && 803cabdff1aSopenharmony_ci (s->width != avctx->coded_width || 804cabdff1aSopenharmony_ci s->height != avctx->coded_height)) { 805cabdff1aSopenharmony_ci ff_vc1_decode_end(avctx); 806cabdff1aSopenharmony_ci } 807cabdff1aSopenharmony_ci 808cabdff1aSopenharmony_ci if (!s->context_initialized) { 809cabdff1aSopenharmony_ci if ((ret = ff_msmpeg4_decode_init(avctx)) < 0) 810cabdff1aSopenharmony_ci goto err; 811cabdff1aSopenharmony_ci if ((ret = ff_vc1_decode_init_alloc_tables(v)) < 0) { 812cabdff1aSopenharmony_ci ff_mpv_common_end(s); 813cabdff1aSopenharmony_ci goto err; 814cabdff1aSopenharmony_ci } 815cabdff1aSopenharmony_ci 816cabdff1aSopenharmony_ci s->low_delay = !avctx->has_b_frames || v->res_sprite; 817cabdff1aSopenharmony_ci 818cabdff1aSopenharmony_ci if (v->profile == PROFILE_ADVANCED) { 819cabdff1aSopenharmony_ci if(avctx->coded_width<=1 || avctx->coded_height<=1) { 820cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 821cabdff1aSopenharmony_ci goto err; 822cabdff1aSopenharmony_ci } 823cabdff1aSopenharmony_ci s->h_edge_pos = avctx->coded_width; 824cabdff1aSopenharmony_ci s->v_edge_pos = avctx->coded_height; 825cabdff1aSopenharmony_ci } 826cabdff1aSopenharmony_ci } 827cabdff1aSopenharmony_ci 828cabdff1aSopenharmony_ci // do parse frame header 829cabdff1aSopenharmony_ci v->pic_header_flag = 0; 830cabdff1aSopenharmony_ci v->first_pic_header_flag = 1; 831cabdff1aSopenharmony_ci if (v->profile < PROFILE_ADVANCED) { 832cabdff1aSopenharmony_ci if ((ret = ff_vc1_parse_frame_header(v, &s->gb)) < 0) { 833cabdff1aSopenharmony_ci goto err; 834cabdff1aSopenharmony_ci } 835cabdff1aSopenharmony_ci } else { 836cabdff1aSopenharmony_ci if ((ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { 837cabdff1aSopenharmony_ci goto err; 838cabdff1aSopenharmony_ci } 839cabdff1aSopenharmony_ci } 840cabdff1aSopenharmony_ci v->first_pic_header_flag = 0; 841cabdff1aSopenharmony_ci 842cabdff1aSopenharmony_ci if (avctx->debug & FF_DEBUG_PICT_INFO) 843cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_DEBUG, "pict_type: %c\n", av_get_picture_type_char(s->pict_type)); 844cabdff1aSopenharmony_ci 845cabdff1aSopenharmony_ci if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) 846cabdff1aSopenharmony_ci && s->pict_type != AV_PICTURE_TYPE_I) { 847cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n"); 848cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 849cabdff1aSopenharmony_ci goto err; 850cabdff1aSopenharmony_ci } 851cabdff1aSopenharmony_ci if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) 852cabdff1aSopenharmony_ci && v->field_mode) { 853cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected Frames not Fields\n"); 854cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 855cabdff1aSopenharmony_ci goto err; 856cabdff1aSopenharmony_ci } 857cabdff1aSopenharmony_ci if ((s->mb_height >> v->field_mode) == 0) { 858cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "image too short\n"); 859cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 860cabdff1aSopenharmony_ci goto err; 861cabdff1aSopenharmony_ci } 862cabdff1aSopenharmony_ci 863cabdff1aSopenharmony_ci // for skipping the frame 864cabdff1aSopenharmony_ci s->current_picture.f->pict_type = s->pict_type; 865cabdff1aSopenharmony_ci s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; 866cabdff1aSopenharmony_ci 867cabdff1aSopenharmony_ci /* skip B-frames if we don't have reference frames */ 868cabdff1aSopenharmony_ci if (!s->last_picture_ptr && s->pict_type == AV_PICTURE_TYPE_B) { 869cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_DEBUG, "Skipping B frame without reference frames\n"); 870cabdff1aSopenharmony_ci goto end; 871cabdff1aSopenharmony_ci } 872cabdff1aSopenharmony_ci if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) || 873cabdff1aSopenharmony_ci (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) || 874cabdff1aSopenharmony_ci avctx->skip_frame >= AVDISCARD_ALL) { 875cabdff1aSopenharmony_ci goto end; 876cabdff1aSopenharmony_ci } 877cabdff1aSopenharmony_ci 878cabdff1aSopenharmony_ci if ((ret = ff_mpv_frame_start(s, avctx)) < 0) { 879cabdff1aSopenharmony_ci goto err; 880cabdff1aSopenharmony_ci } 881cabdff1aSopenharmony_ci 882cabdff1aSopenharmony_ci v->s.current_picture_ptr->field_picture = v->field_mode; 883cabdff1aSopenharmony_ci v->s.current_picture_ptr->f->interlaced_frame = (v->fcm != PROGRESSIVE); 884cabdff1aSopenharmony_ci v->s.current_picture_ptr->f->top_field_first = v->tff; 885cabdff1aSopenharmony_ci 886cabdff1aSopenharmony_ci // process pulldown flags 887cabdff1aSopenharmony_ci s->current_picture_ptr->f->repeat_pict = 0; 888cabdff1aSopenharmony_ci // Pulldown flags are only valid when 'broadcast' has been set. 889cabdff1aSopenharmony_ci // So ticks_per_frame will be 2 890cabdff1aSopenharmony_ci if (v->rff) { 891cabdff1aSopenharmony_ci // repeat field 892cabdff1aSopenharmony_ci s->current_picture_ptr->f->repeat_pict = 1; 893cabdff1aSopenharmony_ci } else if (v->rptfrm) { 894cabdff1aSopenharmony_ci // repeat frames 895cabdff1aSopenharmony_ci s->current_picture_ptr->f->repeat_pict = v->rptfrm * 2; 896cabdff1aSopenharmony_ci } 897cabdff1aSopenharmony_ci 898cabdff1aSopenharmony_ci s->me.qpel_put = s->qdsp.put_qpel_pixels_tab; 899cabdff1aSopenharmony_ci s->me.qpel_avg = s->qdsp.avg_qpel_pixels_tab; 900cabdff1aSopenharmony_ci 901cabdff1aSopenharmony_ci if (avctx->hwaccel) { 902cabdff1aSopenharmony_ci s->mb_y = 0; 903cabdff1aSopenharmony_ci if (v->field_mode && buf_start_second_field) { 904cabdff1aSopenharmony_ci // decode first field 905cabdff1aSopenharmony_ci s->picture_structure = PICT_BOTTOM_FIELD - v->tff; 906cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, buf_start_second_field - buf_start)) < 0) 907cabdff1aSopenharmony_ci goto err; 908cabdff1aSopenharmony_ci 909cabdff1aSopenharmony_ci if (n_slices1 == -1) { 910cabdff1aSopenharmony_ci // no slices, decode the field as-is 911cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, buf_start_second_field - buf_start)) < 0) 912cabdff1aSopenharmony_ci goto err; 913cabdff1aSopenharmony_ci } else { 914cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].rawbuf - buf_start)) < 0) 915cabdff1aSopenharmony_ci goto err; 916cabdff1aSopenharmony_ci 917cabdff1aSopenharmony_ci for (i = 0 ; i < n_slices1 + 1; i++) { 918cabdff1aSopenharmony_ci s->gb = slices[i].gb; 919cabdff1aSopenharmony_ci s->mb_y = slices[i].mby_start; 920cabdff1aSopenharmony_ci 921cabdff1aSopenharmony_ci v->pic_header_flag = get_bits1(&s->gb); 922cabdff1aSopenharmony_ci if (v->pic_header_flag) { 923cabdff1aSopenharmony_ci if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { 924cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); 925cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 926cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 927cabdff1aSopenharmony_ci goto err; 928cabdff1aSopenharmony_ci continue; 929cabdff1aSopenharmony_ci } 930cabdff1aSopenharmony_ci } 931cabdff1aSopenharmony_ci 932cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0) 933cabdff1aSopenharmony_ci goto err; 934cabdff1aSopenharmony_ci } 935cabdff1aSopenharmony_ci } 936cabdff1aSopenharmony_ci 937cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) 938cabdff1aSopenharmony_ci goto err; 939cabdff1aSopenharmony_ci 940cabdff1aSopenharmony_ci // decode second field 941cabdff1aSopenharmony_ci s->gb = slices[n_slices1 + 1].gb; 942cabdff1aSopenharmony_ci s->mb_y = slices[n_slices1 + 1].mby_start; 943cabdff1aSopenharmony_ci s->picture_structure = PICT_TOP_FIELD + v->tff; 944cabdff1aSopenharmony_ci v->second_field = 1; 945cabdff1aSopenharmony_ci v->pic_header_flag = 0; 946cabdff1aSopenharmony_ci if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { 947cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "parsing header for second field failed"); 948cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 949cabdff1aSopenharmony_ci goto err; 950cabdff1aSopenharmony_ci } 951cabdff1aSopenharmony_ci v->s.current_picture_ptr->f->pict_type = v->s.pict_type; 952cabdff1aSopenharmony_ci 953cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->start_frame(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) 954cabdff1aSopenharmony_ci goto err; 955cabdff1aSopenharmony_ci 956cabdff1aSopenharmony_ci if (n_slices - n_slices1 == 2) { 957cabdff1aSopenharmony_ci // no slices, decode the field as-is 958cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, (buf + buf_size) - buf_start_second_field)) < 0) 959cabdff1aSopenharmony_ci goto err; 960cabdff1aSopenharmony_ci } else { 961cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start_second_field, slices[n_slices1 + 2].rawbuf - buf_start_second_field)) < 0) 962cabdff1aSopenharmony_ci goto err; 963cabdff1aSopenharmony_ci 964cabdff1aSopenharmony_ci for (i = n_slices1 + 2; i < n_slices; i++) { 965cabdff1aSopenharmony_ci s->gb = slices[i].gb; 966cabdff1aSopenharmony_ci s->mb_y = slices[i].mby_start; 967cabdff1aSopenharmony_ci 968cabdff1aSopenharmony_ci v->pic_header_flag = get_bits1(&s->gb); 969cabdff1aSopenharmony_ci if (v->pic_header_flag) { 970cabdff1aSopenharmony_ci if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { 971cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); 972cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 973cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 974cabdff1aSopenharmony_ci goto err; 975cabdff1aSopenharmony_ci continue; 976cabdff1aSopenharmony_ci } 977cabdff1aSopenharmony_ci } 978cabdff1aSopenharmony_ci 979cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0) 980cabdff1aSopenharmony_ci goto err; 981cabdff1aSopenharmony_ci } 982cabdff1aSopenharmony_ci } 983cabdff1aSopenharmony_ci 984cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) 985cabdff1aSopenharmony_ci goto err; 986cabdff1aSopenharmony_ci } else { 987cabdff1aSopenharmony_ci s->picture_structure = PICT_FRAME; 988cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->start_frame(avctx, buf_start, (buf + buf_size) - buf_start)) < 0) 989cabdff1aSopenharmony_ci goto err; 990cabdff1aSopenharmony_ci 991cabdff1aSopenharmony_ci if (n_slices == 0) { 992cabdff1aSopenharmony_ci // no slices, decode the frame as-is 993cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start)) < 0) 994cabdff1aSopenharmony_ci goto err; 995cabdff1aSopenharmony_ci } else { 996cabdff1aSopenharmony_ci // decode the frame part as the first slice 997cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, buf_start, slices[0].rawbuf - buf_start)) < 0) 998cabdff1aSopenharmony_ci goto err; 999cabdff1aSopenharmony_ci 1000cabdff1aSopenharmony_ci // and process the slices as additional slices afterwards 1001cabdff1aSopenharmony_ci for (i = 0 ; i < n_slices; i++) { 1002cabdff1aSopenharmony_ci s->gb = slices[i].gb; 1003cabdff1aSopenharmony_ci s->mb_y = slices[i].mby_start; 1004cabdff1aSopenharmony_ci 1005cabdff1aSopenharmony_ci v->pic_header_flag = get_bits1(&s->gb); 1006cabdff1aSopenharmony_ci if (v->pic_header_flag) { 1007cabdff1aSopenharmony_ci if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { 1008cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); 1009cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 1010cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 1011cabdff1aSopenharmony_ci goto err; 1012cabdff1aSopenharmony_ci continue; 1013cabdff1aSopenharmony_ci } 1014cabdff1aSopenharmony_ci } 1015cabdff1aSopenharmony_ci 1016cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->decode_slice(avctx, slices[i].rawbuf, slices[i].raw_size)) < 0) 1017cabdff1aSopenharmony_ci goto err; 1018cabdff1aSopenharmony_ci } 1019cabdff1aSopenharmony_ci } 1020cabdff1aSopenharmony_ci if ((ret = avctx->hwaccel->end_frame(avctx)) < 0) 1021cabdff1aSopenharmony_ci goto err; 1022cabdff1aSopenharmony_ci } 1023cabdff1aSopenharmony_ci } else { 1024cabdff1aSopenharmony_ci int header_ret = 0; 1025cabdff1aSopenharmony_ci 1026cabdff1aSopenharmony_ci ff_mpeg_er_frame_start(s); 1027cabdff1aSopenharmony_ci 1028cabdff1aSopenharmony_ci v->end_mb_x = s->mb_width; 1029cabdff1aSopenharmony_ci if (v->field_mode) { 1030cabdff1aSopenharmony_ci s->current_picture.f->linesize[0] <<= 1; 1031cabdff1aSopenharmony_ci s->current_picture.f->linesize[1] <<= 1; 1032cabdff1aSopenharmony_ci s->current_picture.f->linesize[2] <<= 1; 1033cabdff1aSopenharmony_ci s->linesize <<= 1; 1034cabdff1aSopenharmony_ci s->uvlinesize <<= 1; 1035cabdff1aSopenharmony_ci } 1036cabdff1aSopenharmony_ci mb_height = s->mb_height >> v->field_mode; 1037cabdff1aSopenharmony_ci 1038cabdff1aSopenharmony_ci av_assert0 (mb_height > 0); 1039cabdff1aSopenharmony_ci 1040cabdff1aSopenharmony_ci for (i = 0; i <= n_slices; i++) { 1041cabdff1aSopenharmony_ci if (i > 0 && slices[i - 1].mby_start >= mb_height) { 1042cabdff1aSopenharmony_ci if (v->field_mode <= 0) { 1043cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Slice %d starts beyond " 1044cabdff1aSopenharmony_ci "picture boundary (%d >= %d)\n", i, 1045cabdff1aSopenharmony_ci slices[i - 1].mby_start, mb_height); 1046cabdff1aSopenharmony_ci continue; 1047cabdff1aSopenharmony_ci } 1048cabdff1aSopenharmony_ci v->second_field = 1; 1049cabdff1aSopenharmony_ci av_assert0((s->mb_height & 1) == 0); 1050cabdff1aSopenharmony_ci v->blocks_off = s->b8_stride * (s->mb_height&~1); 1051cabdff1aSopenharmony_ci v->mb_off = s->mb_stride * s->mb_height >> 1; 1052cabdff1aSopenharmony_ci } else { 1053cabdff1aSopenharmony_ci v->second_field = 0; 1054cabdff1aSopenharmony_ci v->blocks_off = 0; 1055cabdff1aSopenharmony_ci v->mb_off = 0; 1056cabdff1aSopenharmony_ci } 1057cabdff1aSopenharmony_ci if (i) { 1058cabdff1aSopenharmony_ci v->pic_header_flag = 0; 1059cabdff1aSopenharmony_ci if (v->field_mode && i == n_slices1 + 2) { 1060cabdff1aSopenharmony_ci if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { 1061cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n"); 1062cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 1063cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 1064cabdff1aSopenharmony_ci goto err; 1065cabdff1aSopenharmony_ci continue; 1066cabdff1aSopenharmony_ci } 1067cabdff1aSopenharmony_ci } else if (get_bits1(&s->gb)) { 1068cabdff1aSopenharmony_ci v->pic_header_flag = 1; 1069cabdff1aSopenharmony_ci if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) { 1070cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); 1071cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 1072cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 1073cabdff1aSopenharmony_ci goto err; 1074cabdff1aSopenharmony_ci continue; 1075cabdff1aSopenharmony_ci } 1076cabdff1aSopenharmony_ci } 1077cabdff1aSopenharmony_ci } 1078cabdff1aSopenharmony_ci if (header_ret < 0) 1079cabdff1aSopenharmony_ci continue; 1080cabdff1aSopenharmony_ci s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height); 1081cabdff1aSopenharmony_ci if (!v->field_mode || v->second_field) 1082cabdff1aSopenharmony_ci s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); 1083cabdff1aSopenharmony_ci else { 1084cabdff1aSopenharmony_ci if (i >= n_slices) { 1085cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "first field slice count too large\n"); 1086cabdff1aSopenharmony_ci continue; 1087cabdff1aSopenharmony_ci } 1088cabdff1aSopenharmony_ci s->end_mb_y = (i == n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); 1089cabdff1aSopenharmony_ci } 1090cabdff1aSopenharmony_ci if (s->end_mb_y <= s->start_mb_y) { 1091cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y); 1092cabdff1aSopenharmony_ci continue; 1093cabdff1aSopenharmony_ci } 1094cabdff1aSopenharmony_ci if (((s->pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || 1095cabdff1aSopenharmony_ci (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)) && 1096cabdff1aSopenharmony_ci !v->cbpcy_vlc) { 1097cabdff1aSopenharmony_ci av_log(v->s.avctx, AV_LOG_ERROR, "missing cbpcy_vlc\n"); 1098cabdff1aSopenharmony_ci continue; 1099cabdff1aSopenharmony_ci } 1100cabdff1aSopenharmony_ci ff_vc1_decode_blocks(v); 1101cabdff1aSopenharmony_ci if (i != n_slices) { 1102cabdff1aSopenharmony_ci s->gb = slices[i].gb; 1103cabdff1aSopenharmony_ci } 1104cabdff1aSopenharmony_ci } 1105cabdff1aSopenharmony_ci if (v->field_mode) { 1106cabdff1aSopenharmony_ci v->second_field = 0; 1107cabdff1aSopenharmony_ci s->current_picture.f->linesize[0] >>= 1; 1108cabdff1aSopenharmony_ci s->current_picture.f->linesize[1] >>= 1; 1109cabdff1aSopenharmony_ci s->current_picture.f->linesize[2] >>= 1; 1110cabdff1aSopenharmony_ci s->linesize >>= 1; 1111cabdff1aSopenharmony_ci s->uvlinesize >>= 1; 1112cabdff1aSopenharmony_ci if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) { 1113cabdff1aSopenharmony_ci FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]); 1114cabdff1aSopenharmony_ci FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]); 1115cabdff1aSopenharmony_ci } 1116cabdff1aSopenharmony_ci } 1117cabdff1aSopenharmony_ci ff_dlog(s->avctx, "Consumed %i/%i bits\n", 1118cabdff1aSopenharmony_ci get_bits_count(&s->gb), s->gb.size_in_bits); 1119cabdff1aSopenharmony_ci// if (get_bits_count(&s->gb) > buf_size * 8) 1120cabdff1aSopenharmony_ci// return -1; 1121cabdff1aSopenharmony_ci if(s->er.error_occurred && s->pict_type == AV_PICTURE_TYPE_B) { 1122cabdff1aSopenharmony_ci ret = AVERROR_INVALIDDATA; 1123cabdff1aSopenharmony_ci goto err; 1124cabdff1aSopenharmony_ci } 1125cabdff1aSopenharmony_ci if ( !v->field_mode 1126cabdff1aSopenharmony_ci && avctx->codec_id != AV_CODEC_ID_WMV3IMAGE 1127cabdff1aSopenharmony_ci && avctx->codec_id != AV_CODEC_ID_VC1IMAGE) 1128cabdff1aSopenharmony_ci ff_er_frame_end(&s->er); 1129cabdff1aSopenharmony_ci } 1130cabdff1aSopenharmony_ci 1131cabdff1aSopenharmony_ci ff_mpv_frame_end(s); 1132cabdff1aSopenharmony_ci 1133cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { 1134cabdff1aSopenharmony_ciimage: 1135cabdff1aSopenharmony_ci avctx->width = avctx->coded_width = v->output_width; 1136cabdff1aSopenharmony_ci avctx->height = avctx->coded_height = v->output_height; 1137cabdff1aSopenharmony_ci if (avctx->skip_frame >= AVDISCARD_NONREF) 1138cabdff1aSopenharmony_ci goto end; 1139cabdff1aSopenharmony_ci if (!v->sprite_output_frame && 1140cabdff1aSopenharmony_ci !(v->sprite_output_frame = av_frame_alloc())) { 1141cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 1142cabdff1aSopenharmony_ci goto err; 1143cabdff1aSopenharmony_ci } 1144cabdff1aSopenharmony_ci#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER 1145cabdff1aSopenharmony_ci if ((ret = vc1_decode_sprites(v, &s->gb)) < 0) 1146cabdff1aSopenharmony_ci goto err; 1147cabdff1aSopenharmony_ci#endif 1148cabdff1aSopenharmony_ci if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0) 1149cabdff1aSopenharmony_ci goto err; 1150cabdff1aSopenharmony_ci *got_frame = 1; 1151cabdff1aSopenharmony_ci } else { 1152cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { 1153cabdff1aSopenharmony_ci if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0) 1154cabdff1aSopenharmony_ci goto err; 1155cabdff1aSopenharmony_ci if (!v->field_mode) 1156cabdff1aSopenharmony_ci ff_print_debug_info(s, s->current_picture_ptr, pict); 1157cabdff1aSopenharmony_ci *got_frame = 1; 1158cabdff1aSopenharmony_ci } else if (s->last_picture_ptr) { 1159cabdff1aSopenharmony_ci if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0) 1160cabdff1aSopenharmony_ci goto err; 1161cabdff1aSopenharmony_ci if (!v->field_mode) 1162cabdff1aSopenharmony_ci ff_print_debug_info(s, s->last_picture_ptr, pict); 1163cabdff1aSopenharmony_ci *got_frame = 1; 1164cabdff1aSopenharmony_ci } 1165cabdff1aSopenharmony_ci } 1166cabdff1aSopenharmony_ci 1167cabdff1aSopenharmony_ciend: 1168cabdff1aSopenharmony_ci av_free(buf2); 1169cabdff1aSopenharmony_ci for (i = 0; i < n_slices; i++) 1170cabdff1aSopenharmony_ci av_free(slices[i].buf); 1171cabdff1aSopenharmony_ci av_free(slices); 1172cabdff1aSopenharmony_ci return buf_size; 1173cabdff1aSopenharmony_ci 1174cabdff1aSopenharmony_cierr: 1175cabdff1aSopenharmony_ci av_free(buf2); 1176cabdff1aSopenharmony_ci for (i = 0; i < n_slices; i++) 1177cabdff1aSopenharmony_ci av_free(slices[i].buf); 1178cabdff1aSopenharmony_ci av_free(slices); 1179cabdff1aSopenharmony_ci return ret; 1180cabdff1aSopenharmony_ci} 1181cabdff1aSopenharmony_ci 1182cabdff1aSopenharmony_ci 1183cabdff1aSopenharmony_cistatic const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = { 1184cabdff1aSopenharmony_ci#if CONFIG_VC1_DXVA2_HWACCEL 1185cabdff1aSopenharmony_ci AV_PIX_FMT_DXVA2_VLD, 1186cabdff1aSopenharmony_ci#endif 1187cabdff1aSopenharmony_ci#if CONFIG_VC1_D3D11VA_HWACCEL 1188cabdff1aSopenharmony_ci AV_PIX_FMT_D3D11VA_VLD, 1189cabdff1aSopenharmony_ci AV_PIX_FMT_D3D11, 1190cabdff1aSopenharmony_ci#endif 1191cabdff1aSopenharmony_ci#if CONFIG_VC1_NVDEC_HWACCEL 1192cabdff1aSopenharmony_ci AV_PIX_FMT_CUDA, 1193cabdff1aSopenharmony_ci#endif 1194cabdff1aSopenharmony_ci#if CONFIG_VC1_VAAPI_HWACCEL 1195cabdff1aSopenharmony_ci AV_PIX_FMT_VAAPI, 1196cabdff1aSopenharmony_ci#endif 1197cabdff1aSopenharmony_ci#if CONFIG_VC1_VDPAU_HWACCEL 1198cabdff1aSopenharmony_ci AV_PIX_FMT_VDPAU, 1199cabdff1aSopenharmony_ci#endif 1200cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, 1201cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 1202cabdff1aSopenharmony_ci}; 1203cabdff1aSopenharmony_ci 1204cabdff1aSopenharmony_ciconst FFCodec ff_vc1_decoder = { 1205cabdff1aSopenharmony_ci .p.name = "vc1", 1206cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), 1207cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1208cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_VC1, 1209cabdff1aSopenharmony_ci .priv_data_size = sizeof(VC1Context), 1210cabdff1aSopenharmony_ci .init = vc1_decode_init, 1211cabdff1aSopenharmony_ci .close = ff_vc1_decode_end, 1212cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(vc1_decode_frame), 1213cabdff1aSopenharmony_ci .flush = ff_mpeg_flush, 1214cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, 1215cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 1216cabdff1aSopenharmony_ci .p.pix_fmts = vc1_hwaccel_pixfmt_list_420, 1217cabdff1aSopenharmony_ci .hw_configs = (const AVCodecHWConfigInternal *const []) { 1218cabdff1aSopenharmony_ci#if CONFIG_VC1_DXVA2_HWACCEL 1219cabdff1aSopenharmony_ci HWACCEL_DXVA2(vc1), 1220cabdff1aSopenharmony_ci#endif 1221cabdff1aSopenharmony_ci#if CONFIG_VC1_D3D11VA_HWACCEL 1222cabdff1aSopenharmony_ci HWACCEL_D3D11VA(vc1), 1223cabdff1aSopenharmony_ci#endif 1224cabdff1aSopenharmony_ci#if CONFIG_VC1_D3D11VA2_HWACCEL 1225cabdff1aSopenharmony_ci HWACCEL_D3D11VA2(vc1), 1226cabdff1aSopenharmony_ci#endif 1227cabdff1aSopenharmony_ci#if CONFIG_VC1_NVDEC_HWACCEL 1228cabdff1aSopenharmony_ci HWACCEL_NVDEC(vc1), 1229cabdff1aSopenharmony_ci#endif 1230cabdff1aSopenharmony_ci#if CONFIG_VC1_VAAPI_HWACCEL 1231cabdff1aSopenharmony_ci HWACCEL_VAAPI(vc1), 1232cabdff1aSopenharmony_ci#endif 1233cabdff1aSopenharmony_ci#if CONFIG_VC1_VDPAU_HWACCEL 1234cabdff1aSopenharmony_ci HWACCEL_VDPAU(vc1), 1235cabdff1aSopenharmony_ci#endif 1236cabdff1aSopenharmony_ci NULL 1237cabdff1aSopenharmony_ci }, 1238cabdff1aSopenharmony_ci .p.profiles = NULL_IF_CONFIG_SMALL(ff_vc1_profiles) 1239cabdff1aSopenharmony_ci}; 1240cabdff1aSopenharmony_ci 1241cabdff1aSopenharmony_ci#if CONFIG_WMV3_DECODER 1242cabdff1aSopenharmony_ciconst FFCodec ff_wmv3_decoder = { 1243cabdff1aSopenharmony_ci .p.name = "wmv3", 1244cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), 1245cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1246cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_WMV3, 1247cabdff1aSopenharmony_ci .priv_data_size = sizeof(VC1Context), 1248cabdff1aSopenharmony_ci .init = vc1_decode_init, 1249cabdff1aSopenharmony_ci .close = ff_vc1_decode_end, 1250cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(vc1_decode_frame), 1251cabdff1aSopenharmony_ci .flush = ff_mpeg_flush, 1252cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, 1253cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 1254cabdff1aSopenharmony_ci .p.pix_fmts = vc1_hwaccel_pixfmt_list_420, 1255cabdff1aSopenharmony_ci .hw_configs = (const AVCodecHWConfigInternal *const []) { 1256cabdff1aSopenharmony_ci#if CONFIG_WMV3_DXVA2_HWACCEL 1257cabdff1aSopenharmony_ci HWACCEL_DXVA2(wmv3), 1258cabdff1aSopenharmony_ci#endif 1259cabdff1aSopenharmony_ci#if CONFIG_WMV3_D3D11VA_HWACCEL 1260cabdff1aSopenharmony_ci HWACCEL_D3D11VA(wmv3), 1261cabdff1aSopenharmony_ci#endif 1262cabdff1aSopenharmony_ci#if CONFIG_WMV3_D3D11VA2_HWACCEL 1263cabdff1aSopenharmony_ci HWACCEL_D3D11VA2(wmv3), 1264cabdff1aSopenharmony_ci#endif 1265cabdff1aSopenharmony_ci#if CONFIG_WMV3_NVDEC_HWACCEL 1266cabdff1aSopenharmony_ci HWACCEL_NVDEC(wmv3), 1267cabdff1aSopenharmony_ci#endif 1268cabdff1aSopenharmony_ci#if CONFIG_WMV3_VAAPI_HWACCEL 1269cabdff1aSopenharmony_ci HWACCEL_VAAPI(wmv3), 1270cabdff1aSopenharmony_ci#endif 1271cabdff1aSopenharmony_ci#if CONFIG_WMV3_VDPAU_HWACCEL 1272cabdff1aSopenharmony_ci HWACCEL_VDPAU(wmv3), 1273cabdff1aSopenharmony_ci#endif 1274cabdff1aSopenharmony_ci NULL 1275cabdff1aSopenharmony_ci }, 1276cabdff1aSopenharmony_ci .p.profiles = NULL_IF_CONFIG_SMALL(ff_vc1_profiles) 1277cabdff1aSopenharmony_ci}; 1278cabdff1aSopenharmony_ci#endif 1279cabdff1aSopenharmony_ci 1280cabdff1aSopenharmony_ci#if CONFIG_WMV3IMAGE_DECODER 1281cabdff1aSopenharmony_ciconst FFCodec ff_wmv3image_decoder = { 1282cabdff1aSopenharmony_ci .p.name = "wmv3image", 1283cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"), 1284cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1285cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_WMV3IMAGE, 1286cabdff1aSopenharmony_ci .priv_data_size = sizeof(VC1Context), 1287cabdff1aSopenharmony_ci .init = vc1_decode_init, 1288cabdff1aSopenharmony_ci .close = ff_vc1_decode_end, 1289cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(vc1_decode_frame), 1290cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 1291cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 1292cabdff1aSopenharmony_ci .flush = vc1_sprite_flush, 1293cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 1294cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, 1295cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 1296cabdff1aSopenharmony_ci }, 1297cabdff1aSopenharmony_ci}; 1298cabdff1aSopenharmony_ci#endif 1299cabdff1aSopenharmony_ci 1300cabdff1aSopenharmony_ci#if CONFIG_VC1IMAGE_DECODER 1301cabdff1aSopenharmony_ciconst FFCodec ff_vc1image_decoder = { 1302cabdff1aSopenharmony_ci .p.name = "vc1image", 1303cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"), 1304cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1305cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_VC1IMAGE, 1306cabdff1aSopenharmony_ci .priv_data_size = sizeof(VC1Context), 1307cabdff1aSopenharmony_ci .init = vc1_decode_init, 1308cabdff1aSopenharmony_ci .close = ff_vc1_decode_end, 1309cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(vc1_decode_frame), 1310cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 1311cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 1312cabdff1aSopenharmony_ci .flush = vc1_sprite_flush, 1313cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 1314cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, 1315cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 1316cabdff1aSopenharmony_ci }, 1317cabdff1aSopenharmony_ci}; 1318cabdff1aSopenharmony_ci#endif 1319