1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * VC-1 HW decode acceleration through VA API 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (C) 2008-2009 Splitted-Desktop Systems 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "config_components.h" 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#include "hwconfig.h" 26cabdff1aSopenharmony_ci#include "mpegvideodec.h" 27cabdff1aSopenharmony_ci#include "vaapi_decode.h" 28cabdff1aSopenharmony_ci#include "vc1.h" 29cabdff1aSopenharmony_ci#include "vc1data.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci/** Translate FFmpeg MV modes to VA API */ 32cabdff1aSopenharmony_cistatic int get_VAMvModeVC1(enum MVModes mv_mode) 33cabdff1aSopenharmony_ci{ 34cabdff1aSopenharmony_ci switch (mv_mode) { 35cabdff1aSopenharmony_ci case MV_PMODE_1MV_HPEL_BILIN: return VAMvMode1MvHalfPelBilinear; 36cabdff1aSopenharmony_ci case MV_PMODE_1MV: return VAMvMode1Mv; 37cabdff1aSopenharmony_ci case MV_PMODE_1MV_HPEL: return VAMvMode1MvHalfPel; 38cabdff1aSopenharmony_ci case MV_PMODE_MIXED_MV: return VAMvModeMixedMv; 39cabdff1aSopenharmony_ci case MV_PMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation; 40cabdff1aSopenharmony_ci } 41cabdff1aSopenharmony_ci return 0; 42cabdff1aSopenharmony_ci} 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci/** Check whether the MVTYPEMB bitplane is present */ 45cabdff1aSopenharmony_cistatic inline int vc1_has_MVTYPEMB_bitplane(const VC1Context *v) 46cabdff1aSopenharmony_ci{ 47cabdff1aSopenharmony_ci if (v->mv_type_is_raw) 48cabdff1aSopenharmony_ci return 0; 49cabdff1aSopenharmony_ci return v->fcm == PROGRESSIVE && 50cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && 51cabdff1aSopenharmony_ci (v->mv_mode == MV_PMODE_MIXED_MV || 52cabdff1aSopenharmony_ci (v->mv_mode == MV_PMODE_INTENSITY_COMP && 53cabdff1aSopenharmony_ci v->mv_mode2 == MV_PMODE_MIXED_MV)); 54cabdff1aSopenharmony_ci} 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci/** Check whether the SKIPMB bitplane is present */ 57cabdff1aSopenharmony_cistatic inline int vc1_has_SKIPMB_bitplane(const VC1Context *v) 58cabdff1aSopenharmony_ci{ 59cabdff1aSopenharmony_ci if (v->skip_is_raw) 60cabdff1aSopenharmony_ci return 0; 61cabdff1aSopenharmony_ci return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && 62cabdff1aSopenharmony_ci ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || 63cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type)); 64cabdff1aSopenharmony_ci} 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci/** Check whether the DIRECTMB bitplane is present */ 67cabdff1aSopenharmony_cistatic inline int vc1_has_DIRECTMB_bitplane(const VC1Context *v) 68cabdff1aSopenharmony_ci{ 69cabdff1aSopenharmony_ci if (v->dmb_is_raw) 70cabdff1aSopenharmony_ci return 0; 71cabdff1aSopenharmony_ci return (v->fcm == PROGRESSIVE || v->fcm == ILACE_FRAME) && 72cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); 73cabdff1aSopenharmony_ci} 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci/** Check whether the ACPRED bitplane is present */ 76cabdff1aSopenharmony_cistatic inline int vc1_has_ACPRED_bitplane(const VC1Context *v) 77cabdff1aSopenharmony_ci{ 78cabdff1aSopenharmony_ci if (v->acpred_is_raw) 79cabdff1aSopenharmony_ci return 0; 80cabdff1aSopenharmony_ci return v->profile == PROFILE_ADVANCED && 81cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_I || 82cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && v->bi_type)); 83cabdff1aSopenharmony_ci} 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci/** Check whether the OVERFLAGS bitplane is present */ 86cabdff1aSopenharmony_cistatic inline int vc1_has_OVERFLAGS_bitplane(const VC1Context *v) 87cabdff1aSopenharmony_ci{ 88cabdff1aSopenharmony_ci if (v->overflg_is_raw) 89cabdff1aSopenharmony_ci return 0; 90cabdff1aSopenharmony_ci return v->profile == PROFILE_ADVANCED && 91cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_I || 92cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && v->bi_type)) && 93cabdff1aSopenharmony_ci (v->overlap && v->pq <= 8) && 94cabdff1aSopenharmony_ci v->condover == CONDOVER_SELECT; 95cabdff1aSopenharmony_ci} 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci/** Check whether the FIELDTX bitplane is present */ 98cabdff1aSopenharmony_cistatic inline int vc1_has_FIELDTX_bitplane(const VC1Context *v) 99cabdff1aSopenharmony_ci{ 100cabdff1aSopenharmony_ci if (v->fieldtx_is_raw) 101cabdff1aSopenharmony_ci return 0; 102cabdff1aSopenharmony_ci return v->fcm == ILACE_FRAME && 103cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_I || 104cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && v->bi_type)); 105cabdff1aSopenharmony_ci} 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci/** Check whether the FORWARDMB bitplane is present */ 108cabdff1aSopenharmony_cistatic inline int vc1_has_FORWARDMB_bitplane(const VC1Context *v) 109cabdff1aSopenharmony_ci{ 110cabdff1aSopenharmony_ci if (v->fmb_is_raw) 111cabdff1aSopenharmony_ci return 0; 112cabdff1aSopenharmony_ci return v->fcm == ILACE_FIELD && 113cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type); 114cabdff1aSopenharmony_ci} 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci/** Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ 117cabdff1aSopenharmony_cistatic int vc1_get_PTYPE(const VC1Context *v) 118cabdff1aSopenharmony_ci{ 119cabdff1aSopenharmony_ci const MpegEncContext *s = &v->s; 120cabdff1aSopenharmony_ci switch (s->pict_type) { 121cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_I: return 0; 122cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_P: return v->p_frame_skipped ? 4 : 1; 123cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_B: return v->bi_type ? 3 : 2; 124cabdff1aSopenharmony_ci } 125cabdff1aSopenharmony_ci return 0; 126cabdff1aSopenharmony_ci} 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci/** Reconstruct bitstream FPTYPE (9.1.1.42, index into Table-105) */ 129cabdff1aSopenharmony_cistatic int vc1_get_FPTYPE(const VC1Context *v) 130cabdff1aSopenharmony_ci{ 131cabdff1aSopenharmony_ci const MpegEncContext *s = &v->s; 132cabdff1aSopenharmony_ci switch (s->pict_type) { 133cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_I: return 0; 134cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_P: return 3; 135cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_B: return v->bi_type ? 7 : 4; 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci return 0; 138cabdff1aSopenharmony_ci} 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci/** Reconstruct bitstream MVMODE (7.1.1.32) */ 141cabdff1aSopenharmony_cistatic inline VAMvModeVC1 vc1_get_MVMODE(const VC1Context *v) 142cabdff1aSopenharmony_ci{ 143cabdff1aSopenharmony_ci if ((v->fcm == PROGRESSIVE || v->fcm == ILACE_FIELD) && 144cabdff1aSopenharmony_ci ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) || 145cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_B && !v->bi_type))) 146cabdff1aSopenharmony_ci return get_VAMvModeVC1(v->mv_mode); 147cabdff1aSopenharmony_ci return 0; 148cabdff1aSopenharmony_ci} 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci/** Reconstruct bitstream MVMODE2 (7.1.1.33) */ 151cabdff1aSopenharmony_cistatic inline VAMvModeVC1 vc1_get_MVMODE2(const VC1Context *v) 152cabdff1aSopenharmony_ci{ 153cabdff1aSopenharmony_ci if ((v->fcm == PROGRESSIVE || v->fcm == ILACE_FIELD) && 154cabdff1aSopenharmony_ci (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && 155cabdff1aSopenharmony_ci v->mv_mode == MV_PMODE_INTENSITY_COMP) 156cabdff1aSopenharmony_ci return get_VAMvModeVC1(v->mv_mode2); 157cabdff1aSopenharmony_ci return 0; 158cabdff1aSopenharmony_ci} 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ciav_unused static inline int vc1_get_INTCOMPFIELD(const VC1Context *v) 161cabdff1aSopenharmony_ci{ 162cabdff1aSopenharmony_ci if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && 163cabdff1aSopenharmony_ci v->fcm == ILACE_FIELD && 164cabdff1aSopenharmony_ci v->mv_mode == MV_PMODE_INTENSITY_COMP) 165cabdff1aSopenharmony_ci switch (v->intcompfield) { 166cabdff1aSopenharmony_ci case 1: return 1; 167cabdff1aSopenharmony_ci case 2: return 2; 168cabdff1aSopenharmony_ci case 3: return 0; 169cabdff1aSopenharmony_ci } 170cabdff1aSopenharmony_ci return 0; 171cabdff1aSopenharmony_ci} 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_cistatic inline int vc1_get_LUMSCALE(const VC1Context *v) 174cabdff1aSopenharmony_ci{ 175cabdff1aSopenharmony_ci if (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) { 176cabdff1aSopenharmony_ci if ((v->fcm == PROGRESSIVE && v->mv_mode == MV_PMODE_INTENSITY_COMP) || 177cabdff1aSopenharmony_ci (v->fcm == ILACE_FRAME && v->intcomp)) 178cabdff1aSopenharmony_ci return v->lumscale; 179cabdff1aSopenharmony_ci else if (v->fcm == ILACE_FIELD && v->mv_mode == MV_PMODE_INTENSITY_COMP) 180cabdff1aSopenharmony_ci switch (v->intcompfield) { 181cabdff1aSopenharmony_ci case 1: return v->lumscale; 182cabdff1aSopenharmony_ci case 2: return v->lumscale2; 183cabdff1aSopenharmony_ci case 3: return v->lumscale; 184cabdff1aSopenharmony_ci } 185cabdff1aSopenharmony_ci } 186cabdff1aSopenharmony_ci return 0; 187cabdff1aSopenharmony_ci} 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic inline int vc1_get_LUMSHIFT(const VC1Context *v) 190cabdff1aSopenharmony_ci{ 191cabdff1aSopenharmony_ci if (v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) { 192cabdff1aSopenharmony_ci if ((v->fcm == PROGRESSIVE && v->mv_mode == MV_PMODE_INTENSITY_COMP) || 193cabdff1aSopenharmony_ci (v->fcm == ILACE_FRAME && v->intcomp)) 194cabdff1aSopenharmony_ci return v->lumshift; 195cabdff1aSopenharmony_ci else if (v->fcm == ILACE_FIELD && v->mv_mode == MV_PMODE_INTENSITY_COMP) 196cabdff1aSopenharmony_ci switch (v->intcompfield) { 197cabdff1aSopenharmony_ci case 1: return v->lumshift; 198cabdff1aSopenharmony_ci case 2: return v->lumshift2; 199cabdff1aSopenharmony_ci case 3: return v->lumshift; 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci return 0; 203cabdff1aSopenharmony_ci} 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ciav_unused static inline int vc1_get_LUMSCALE2(const VC1Context *v) 206cabdff1aSopenharmony_ci{ 207cabdff1aSopenharmony_ci if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && 208cabdff1aSopenharmony_ci v->fcm == ILACE_FIELD && 209cabdff1aSopenharmony_ci v->mv_mode == MV_PMODE_INTENSITY_COMP && 210cabdff1aSopenharmony_ci v->intcompfield == 3) 211cabdff1aSopenharmony_ci return v->lumscale2; 212cabdff1aSopenharmony_ci return 0; 213cabdff1aSopenharmony_ci} 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ciav_unused static inline int vc1_get_LUMSHIFT2(const VC1Context *v) 216cabdff1aSopenharmony_ci{ 217cabdff1aSopenharmony_ci if ((v->s.pict_type == AV_PICTURE_TYPE_P && !v->p_frame_skipped) && 218cabdff1aSopenharmony_ci v->fcm == ILACE_FIELD && 219cabdff1aSopenharmony_ci v->mv_mode == MV_PMODE_INTENSITY_COMP && 220cabdff1aSopenharmony_ci v->intcompfield == 3) 221cabdff1aSopenharmony_ci return v->lumshift2; 222cabdff1aSopenharmony_ci return 0; 223cabdff1aSopenharmony_ci} 224cabdff1aSopenharmony_ci 225cabdff1aSopenharmony_ci/** Reconstruct bitstream TTFRM (7.1.1.41, Table-53) */ 226cabdff1aSopenharmony_cistatic inline int vc1_get_TTFRM(const VC1Context *v) 227cabdff1aSopenharmony_ci{ 228cabdff1aSopenharmony_ci switch (v->ttfrm) { 229cabdff1aSopenharmony_ci case TT_8X8: return 0; 230cabdff1aSopenharmony_ci case TT_8X4: return 1; 231cabdff1aSopenharmony_ci case TT_4X8: return 2; 232cabdff1aSopenharmony_ci case TT_4X4: return 3; 233cabdff1aSopenharmony_ci } 234cabdff1aSopenharmony_ci return 0; 235cabdff1aSopenharmony_ci} 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci/** Pack FFmpeg bitplanes into a VABitPlaneBuffer element */ 238cabdff1aSopenharmony_cistatic inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride) 239cabdff1aSopenharmony_ci{ 240cabdff1aSopenharmony_ci const int bitplane_index = n / 2; 241cabdff1aSopenharmony_ci const int ff_bp_index = y * stride + x; 242cabdff1aSopenharmony_ci uint8_t v = 0; 243cabdff1aSopenharmony_ci if (ff_bp[0]) 244cabdff1aSopenharmony_ci v = ff_bp[0][ff_bp_index]; 245cabdff1aSopenharmony_ci if (ff_bp[1]) 246cabdff1aSopenharmony_ci v |= ff_bp[1][ff_bp_index] << 1; 247cabdff1aSopenharmony_ci if (ff_bp[2]) 248cabdff1aSopenharmony_ci v |= ff_bp[2][ff_bp_index] << 2; 249cabdff1aSopenharmony_ci bitplane[bitplane_index] = (bitplane[bitplane_index] << 4) | v; 250cabdff1aSopenharmony_ci} 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_cistatic int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) 253cabdff1aSopenharmony_ci{ 254cabdff1aSopenharmony_ci const VC1Context *v = avctx->priv_data; 255cabdff1aSopenharmony_ci const MpegEncContext *s = &v->s; 256cabdff1aSopenharmony_ci VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; 257cabdff1aSopenharmony_ci VAPictureParameterBufferVC1 pic_param; 258cabdff1aSopenharmony_ci int err; 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci pic->output_surface = ff_vaapi_get_surface_id(s->current_picture_ptr->f); 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci pic_param = (VAPictureParameterBufferVC1) { 263cabdff1aSopenharmony_ci .forward_reference_picture = VA_INVALID_ID, 264cabdff1aSopenharmony_ci .backward_reference_picture = VA_INVALID_ID, 265cabdff1aSopenharmony_ci .inloop_decoded_picture = VA_INVALID_ID, 266cabdff1aSopenharmony_ci .sequence_fields.bits = { 267cabdff1aSopenharmony_ci .pulldown = v->broadcast, 268cabdff1aSopenharmony_ci .interlace = v->interlace, 269cabdff1aSopenharmony_ci .tfcntrflag = v->tfcntrflag, 270cabdff1aSopenharmony_ci .finterpflag = v->finterpflag, 271cabdff1aSopenharmony_ci .psf = v->psf, 272cabdff1aSopenharmony_ci .multires = v->multires, 273cabdff1aSopenharmony_ci .overlap = v->overlap, 274cabdff1aSopenharmony_ci .syncmarker = v->resync_marker, 275cabdff1aSopenharmony_ci .rangered = v->rangered, 276cabdff1aSopenharmony_ci .max_b_frames = s->avctx->max_b_frames, 277cabdff1aSopenharmony_ci .profile = v->profile, 278cabdff1aSopenharmony_ci }, 279cabdff1aSopenharmony_ci .coded_width = s->avctx->coded_width, 280cabdff1aSopenharmony_ci .coded_height = s->avctx->coded_height, 281cabdff1aSopenharmony_ci .entrypoint_fields.bits = { 282cabdff1aSopenharmony_ci .broken_link = v->broken_link, 283cabdff1aSopenharmony_ci .closed_entry = v->closed_entry, 284cabdff1aSopenharmony_ci .panscan_flag = v->panscanflag, 285cabdff1aSopenharmony_ci .loopfilter = s->loop_filter, 286cabdff1aSopenharmony_ci }, 287cabdff1aSopenharmony_ci .conditional_overlap_flag = v->condover, 288cabdff1aSopenharmony_ci .fast_uvmc_flag = v->fastuvmc, 289cabdff1aSopenharmony_ci .range_mapping_fields.bits = { 290cabdff1aSopenharmony_ci .luma_flag = v->range_mapy_flag, 291cabdff1aSopenharmony_ci .luma = v->range_mapy, 292cabdff1aSopenharmony_ci .chroma_flag = v->range_mapuv_flag, 293cabdff1aSopenharmony_ci .chroma = v->range_mapuv, 294cabdff1aSopenharmony_ci }, 295cabdff1aSopenharmony_ci .b_picture_fraction = v->bfraction_lut_index, 296cabdff1aSopenharmony_ci .cbp_table = (v->fcm == PROGRESSIVE ? v->cbptab : v->icbptab), 297cabdff1aSopenharmony_ci .mb_mode_table = v->mbmodetab, 298cabdff1aSopenharmony_ci .range_reduction_frame = v->rangeredfrm, 299cabdff1aSopenharmony_ci .rounding_control = v->rnd, 300cabdff1aSopenharmony_ci .post_processing = v->postproc, 301cabdff1aSopenharmony_ci .picture_resolution_index = v->respic, 302cabdff1aSopenharmony_ci .picture_fields.bits = { 303cabdff1aSopenharmony_ci .picture_type = (v->fcm == ILACE_FIELD ? vc1_get_FPTYPE(v) : vc1_get_PTYPE(v)), 304cabdff1aSopenharmony_ci .frame_coding_mode = v->fcm, 305cabdff1aSopenharmony_ci .top_field_first = v->tff, 306cabdff1aSopenharmony_ci .is_first_field = !v->second_field, 307cabdff1aSopenharmony_ci .intensity_compensation = v->intcomp, 308cabdff1aSopenharmony_ci }, 309cabdff1aSopenharmony_ci .luma_scale = vc1_get_LUMSCALE(v), 310cabdff1aSopenharmony_ci .luma_shift = vc1_get_LUMSHIFT(v), 311cabdff1aSopenharmony_ci#if VA_CHECK_VERSION(1, 1, 0) 312cabdff1aSopenharmony_ci .luma_scale2 = vc1_get_LUMSCALE2(v), 313cabdff1aSopenharmony_ci .luma_shift2 = vc1_get_LUMSHIFT2(v), 314cabdff1aSopenharmony_ci .intensity_compensation_field = vc1_get_INTCOMPFIELD(v), 315cabdff1aSopenharmony_ci#endif 316cabdff1aSopenharmony_ci .raw_coding.flags = { 317cabdff1aSopenharmony_ci .mv_type_mb = v->mv_type_is_raw, 318cabdff1aSopenharmony_ci .direct_mb = v->dmb_is_raw, 319cabdff1aSopenharmony_ci .skip_mb = v->skip_is_raw, 320cabdff1aSopenharmony_ci .field_tx = v->fieldtx_is_raw, 321cabdff1aSopenharmony_ci .forward_mb = v->fmb_is_raw, 322cabdff1aSopenharmony_ci .ac_pred = v->acpred_is_raw, 323cabdff1aSopenharmony_ci .overflags = v->overflg_is_raw, 324cabdff1aSopenharmony_ci }, 325cabdff1aSopenharmony_ci .bitplane_present.flags = { 326cabdff1aSopenharmony_ci .bp_mv_type_mb = vc1_has_MVTYPEMB_bitplane(v), 327cabdff1aSopenharmony_ci .bp_direct_mb = vc1_has_DIRECTMB_bitplane(v), 328cabdff1aSopenharmony_ci .bp_skip_mb = vc1_has_SKIPMB_bitplane(v), 329cabdff1aSopenharmony_ci .bp_field_tx = vc1_has_FIELDTX_bitplane(v), 330cabdff1aSopenharmony_ci .bp_forward_mb = vc1_has_FORWARDMB_bitplane(v), 331cabdff1aSopenharmony_ci .bp_ac_pred = vc1_has_ACPRED_bitplane(v), 332cabdff1aSopenharmony_ci .bp_overflags = vc1_has_OVERFLAGS_bitplane(v), 333cabdff1aSopenharmony_ci }, 334cabdff1aSopenharmony_ci .reference_fields.bits = { 335cabdff1aSopenharmony_ci .reference_distance_flag = v->refdist_flag, 336cabdff1aSopenharmony_ci .reference_distance = v->refdist, 337cabdff1aSopenharmony_ci .num_reference_pictures = v->numref, 338cabdff1aSopenharmony_ci .reference_field_pic_indicator = v->reffield, 339cabdff1aSopenharmony_ci }, 340cabdff1aSopenharmony_ci .mv_fields.bits = { 341cabdff1aSopenharmony_ci .mv_mode = vc1_get_MVMODE(v), 342cabdff1aSopenharmony_ci .mv_mode2 = vc1_get_MVMODE2(v), 343cabdff1aSopenharmony_ci .mv_table = (v->fcm == PROGRESSIVE ? s->mv_table_index : v->imvtab), 344cabdff1aSopenharmony_ci .two_mv_block_pattern_table = v->twomvbptab, 345cabdff1aSopenharmony_ci .four_mv_switch = v->fourmvswitch, 346cabdff1aSopenharmony_ci .four_mv_block_pattern_table = v->fourmvbptab, 347cabdff1aSopenharmony_ci .extended_mv_flag = v->extended_mv, 348cabdff1aSopenharmony_ci .extended_mv_range = v->mvrange, 349cabdff1aSopenharmony_ci .extended_dmv_flag = v->extended_dmv, 350cabdff1aSopenharmony_ci .extended_dmv_range = v->dmvrange, 351cabdff1aSopenharmony_ci }, 352cabdff1aSopenharmony_ci .pic_quantizer_fields.bits = { 353cabdff1aSopenharmony_ci .dquant = v->dquant, 354cabdff1aSopenharmony_ci .quantizer = v->quantizer_mode, 355cabdff1aSopenharmony_ci .half_qp = v->halfpq, 356cabdff1aSopenharmony_ci .pic_quantizer_scale = v->pq, 357cabdff1aSopenharmony_ci .pic_quantizer_type = v->pquantizer, 358cabdff1aSopenharmony_ci .dq_frame = v->dquantfrm, 359cabdff1aSopenharmony_ci .dq_profile = v->dqprofile, 360cabdff1aSopenharmony_ci .dq_sb_edge = v->dqprofile == DQPROFILE_SINGLE_EDGE ? v->dqsbedge : 0, 361cabdff1aSopenharmony_ci .dq_db_edge = v->dqprofile == DQPROFILE_DOUBLE_EDGES ? v->dqsbedge : 0, 362cabdff1aSopenharmony_ci .dq_binary_level = v->dqbilevel, 363cabdff1aSopenharmony_ci .alt_pic_quantizer = v->altpq, 364cabdff1aSopenharmony_ci }, 365cabdff1aSopenharmony_ci .transform_fields.bits = { 366cabdff1aSopenharmony_ci .variable_sized_transform_flag = v->vstransform, 367cabdff1aSopenharmony_ci .mb_level_transform_type_flag = v->ttmbf, 368cabdff1aSopenharmony_ci .frame_level_transform_type = vc1_get_TTFRM(v), 369cabdff1aSopenharmony_ci .transform_ac_codingset_idx1 = v->c_ac_table_index, 370cabdff1aSopenharmony_ci .transform_ac_codingset_idx2 = v->y_ac_table_index, 371cabdff1aSopenharmony_ci .intra_transform_dc_table = v->s.dc_table_index, 372cabdff1aSopenharmony_ci }, 373cabdff1aSopenharmony_ci }; 374cabdff1aSopenharmony_ci 375cabdff1aSopenharmony_ci switch (s->pict_type) { 376cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_B: 377cabdff1aSopenharmony_ci pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_picture.f); 378cabdff1aSopenharmony_ci // fall-through 379cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_P: 380cabdff1aSopenharmony_ci pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_picture.f); 381cabdff1aSopenharmony_ci break; 382cabdff1aSopenharmony_ci } 383cabdff1aSopenharmony_ci 384cabdff1aSopenharmony_ci err = ff_vaapi_decode_make_param_buffer(avctx, pic, 385cabdff1aSopenharmony_ci VAPictureParameterBufferType, 386cabdff1aSopenharmony_ci &pic_param, sizeof(pic_param)); 387cabdff1aSopenharmony_ci if (err) 388cabdff1aSopenharmony_ci goto fail; 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci if (pic_param.bitplane_present.value & 0x7f) { 391cabdff1aSopenharmony_ci uint8_t *bitplane; 392cabdff1aSopenharmony_ci const uint8_t *ff_bp[3]; 393cabdff1aSopenharmony_ci int x, y, n; 394cabdff1aSopenharmony_ci size_t size = (s->mb_width * s->mb_height + 1) / 2; 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_ci bitplane = av_mallocz(size); 397cabdff1aSopenharmony_ci if (!bitplane) { 398cabdff1aSopenharmony_ci err = AVERROR(ENOMEM); 399cabdff1aSopenharmony_ci goto fail; 400cabdff1aSopenharmony_ci } 401cabdff1aSopenharmony_ci 402cabdff1aSopenharmony_ci switch (s->pict_type) { 403cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_P: 404cabdff1aSopenharmony_ci ff_bp[0] = pic_param.bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; 405cabdff1aSopenharmony_ci ff_bp[1] = pic_param.bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; 406cabdff1aSopenharmony_ci ff_bp[2] = pic_param.bitplane_present.flags.bp_mv_type_mb ? v->mv_type_mb_plane : NULL; 407cabdff1aSopenharmony_ci break; 408cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_B: 409cabdff1aSopenharmony_ci if (!v->bi_type) { 410cabdff1aSopenharmony_ci ff_bp[0] = pic_param.bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; 411cabdff1aSopenharmony_ci ff_bp[1] = pic_param.bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; 412cabdff1aSopenharmony_ci ff_bp[2] = pic_param.bitplane_present.flags.bp_forward_mb ? v->forward_mb_plane : NULL; 413cabdff1aSopenharmony_ci break; 414cabdff1aSopenharmony_ci } 415cabdff1aSopenharmony_ci /* fall-through (BI-type) */ 416cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_I: 417cabdff1aSopenharmony_ci ff_bp[0] = pic_param.bitplane_present.flags.bp_field_tx ? v->fieldtx_plane : NULL; 418cabdff1aSopenharmony_ci ff_bp[1] = pic_param.bitplane_present.flags.bp_ac_pred ? v->acpred_plane : NULL; 419cabdff1aSopenharmony_ci ff_bp[2] = pic_param.bitplane_present.flags.bp_overflags ? v->over_flags_plane : NULL; 420cabdff1aSopenharmony_ci break; 421cabdff1aSopenharmony_ci default: 422cabdff1aSopenharmony_ci ff_bp[0] = NULL; 423cabdff1aSopenharmony_ci ff_bp[1] = NULL; 424cabdff1aSopenharmony_ci ff_bp[2] = NULL; 425cabdff1aSopenharmony_ci break; 426cabdff1aSopenharmony_ci } 427cabdff1aSopenharmony_ci 428cabdff1aSopenharmony_ci n = 0; 429cabdff1aSopenharmony_ci for (y = 0; y < s->mb_height; y++) 430cabdff1aSopenharmony_ci for (x = 0; x < s->mb_width; x++, n++) 431cabdff1aSopenharmony_ci vc1_pack_bitplanes(bitplane, n, ff_bp, x, y, s->mb_stride); 432cabdff1aSopenharmony_ci if (n & 1) /* move last nibble to the high order */ 433cabdff1aSopenharmony_ci bitplane[n/2] <<= 4; 434cabdff1aSopenharmony_ci 435cabdff1aSopenharmony_ci err = ff_vaapi_decode_make_param_buffer(avctx, pic, 436cabdff1aSopenharmony_ci VABitPlaneBufferType, 437cabdff1aSopenharmony_ci bitplane, size); 438cabdff1aSopenharmony_ci av_free(bitplane); 439cabdff1aSopenharmony_ci if (err) 440cabdff1aSopenharmony_ci goto fail; 441cabdff1aSopenharmony_ci } 442cabdff1aSopenharmony_ci return 0; 443cabdff1aSopenharmony_ci 444cabdff1aSopenharmony_cifail: 445cabdff1aSopenharmony_ci ff_vaapi_decode_cancel(avctx, pic); 446cabdff1aSopenharmony_ci return err; 447cabdff1aSopenharmony_ci} 448cabdff1aSopenharmony_ci 449cabdff1aSopenharmony_cistatic int vaapi_vc1_end_frame(AVCodecContext *avctx) 450cabdff1aSopenharmony_ci{ 451cabdff1aSopenharmony_ci VC1Context *v = avctx->priv_data; 452cabdff1aSopenharmony_ci MpegEncContext *s = &v->s; 453cabdff1aSopenharmony_ci VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; 454cabdff1aSopenharmony_ci int ret; 455cabdff1aSopenharmony_ci 456cabdff1aSopenharmony_ci ret = ff_vaapi_decode_issue(avctx, pic); 457cabdff1aSopenharmony_ci if (ret < 0) 458cabdff1aSopenharmony_ci goto fail; 459cabdff1aSopenharmony_ci 460cabdff1aSopenharmony_ci ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); 461cabdff1aSopenharmony_ci 462cabdff1aSopenharmony_cifail: 463cabdff1aSopenharmony_ci return ret; 464cabdff1aSopenharmony_ci} 465cabdff1aSopenharmony_ci 466cabdff1aSopenharmony_cistatic int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) 467cabdff1aSopenharmony_ci{ 468cabdff1aSopenharmony_ci const VC1Context *v = avctx->priv_data; 469cabdff1aSopenharmony_ci const MpegEncContext *s = &v->s; 470cabdff1aSopenharmony_ci VAAPIDecodePicture *pic = s->current_picture_ptr->hwaccel_picture_private; 471cabdff1aSopenharmony_ci VASliceParameterBufferVC1 slice_param; 472cabdff1aSopenharmony_ci int mb_height; 473cabdff1aSopenharmony_ci int err; 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ci /* Current bit buffer is beyond any marker for VC-1, so skip it */ 476cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_VC1 && IS_MARKER(AV_RB32(buffer))) { 477cabdff1aSopenharmony_ci buffer += 4; 478cabdff1aSopenharmony_ci size -= 4; 479cabdff1aSopenharmony_ci } 480cabdff1aSopenharmony_ci 481cabdff1aSopenharmony_ci if (v->fcm == ILACE_FIELD) 482cabdff1aSopenharmony_ci mb_height = avctx->coded_height + 31 >> 5; 483cabdff1aSopenharmony_ci else 484cabdff1aSopenharmony_ci mb_height = avctx->coded_height + 15 >> 4; 485cabdff1aSopenharmony_ci 486cabdff1aSopenharmony_ci slice_param = (VASliceParameterBufferVC1) { 487cabdff1aSopenharmony_ci .slice_data_size = size, 488cabdff1aSopenharmony_ci .slice_data_offset = 0, 489cabdff1aSopenharmony_ci .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, 490cabdff1aSopenharmony_ci .macroblock_offset = get_bits_count(&s->gb), 491cabdff1aSopenharmony_ci .slice_vertical_position = s->mb_y % mb_height, 492cabdff1aSopenharmony_ci }; 493cabdff1aSopenharmony_ci 494cabdff1aSopenharmony_ci err = ff_vaapi_decode_make_slice_buffer(avctx, pic, 495cabdff1aSopenharmony_ci &slice_param, sizeof(slice_param), 496cabdff1aSopenharmony_ci buffer, size); 497cabdff1aSopenharmony_ci if (err < 0) { 498cabdff1aSopenharmony_ci ff_vaapi_decode_cancel(avctx, pic); 499cabdff1aSopenharmony_ci return err; 500cabdff1aSopenharmony_ci } 501cabdff1aSopenharmony_ci 502cabdff1aSopenharmony_ci return 0; 503cabdff1aSopenharmony_ci} 504cabdff1aSopenharmony_ci 505cabdff1aSopenharmony_ci#if CONFIG_WMV3_VAAPI_HWACCEL 506cabdff1aSopenharmony_ciconst AVHWAccel ff_wmv3_vaapi_hwaccel = { 507cabdff1aSopenharmony_ci .name = "wmv3_vaapi", 508cabdff1aSopenharmony_ci .type = AVMEDIA_TYPE_VIDEO, 509cabdff1aSopenharmony_ci .id = AV_CODEC_ID_WMV3, 510cabdff1aSopenharmony_ci .pix_fmt = AV_PIX_FMT_VAAPI, 511cabdff1aSopenharmony_ci .start_frame = &vaapi_vc1_start_frame, 512cabdff1aSopenharmony_ci .end_frame = &vaapi_vc1_end_frame, 513cabdff1aSopenharmony_ci .decode_slice = &vaapi_vc1_decode_slice, 514cabdff1aSopenharmony_ci .frame_priv_data_size = sizeof(VAAPIDecodePicture), 515cabdff1aSopenharmony_ci .init = &ff_vaapi_decode_init, 516cabdff1aSopenharmony_ci .uninit = &ff_vaapi_decode_uninit, 517cabdff1aSopenharmony_ci .frame_params = &ff_vaapi_common_frame_params, 518cabdff1aSopenharmony_ci .priv_data_size = sizeof(VAAPIDecodeContext), 519cabdff1aSopenharmony_ci .caps_internal = HWACCEL_CAP_ASYNC_SAFE, 520cabdff1aSopenharmony_ci}; 521cabdff1aSopenharmony_ci#endif 522cabdff1aSopenharmony_ci 523cabdff1aSopenharmony_ciconst AVHWAccel ff_vc1_vaapi_hwaccel = { 524cabdff1aSopenharmony_ci .name = "vc1_vaapi", 525cabdff1aSopenharmony_ci .type = AVMEDIA_TYPE_VIDEO, 526cabdff1aSopenharmony_ci .id = AV_CODEC_ID_VC1, 527cabdff1aSopenharmony_ci .pix_fmt = AV_PIX_FMT_VAAPI, 528cabdff1aSopenharmony_ci .start_frame = &vaapi_vc1_start_frame, 529cabdff1aSopenharmony_ci .end_frame = &vaapi_vc1_end_frame, 530cabdff1aSopenharmony_ci .decode_slice = &vaapi_vc1_decode_slice, 531cabdff1aSopenharmony_ci .frame_priv_data_size = sizeof(VAAPIDecodePicture), 532cabdff1aSopenharmony_ci .init = &ff_vaapi_decode_init, 533cabdff1aSopenharmony_ci .uninit = &ff_vaapi_decode_uninit, 534cabdff1aSopenharmony_ci .frame_params = &ff_vaapi_common_frame_params, 535cabdff1aSopenharmony_ci .priv_data_size = sizeof(VAAPIDecodeContext), 536cabdff1aSopenharmony_ci .caps_internal = HWACCEL_CAP_ASYNC_SAFE, 537cabdff1aSopenharmony_ci}; 538