X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvdpau_hevc.c;h=c17de0c5d03b17663c2ecd563dfd131ebb2e5834;hb=b9fff6e15e73dc995695db9be8db084238cca14c;hp=421135bce25bfc3eadb77bbf4f059bf349493504;hpb=493240a522fca34882601fbeeda4e17aa40a0303;p=ffmpeg diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index 421135bce25..c17de0c5d03 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -26,9 +26,11 @@ #include "internal.h" #include "hevc_data.h" #include "hevcdec.h" -#include "hwaccel.h" +#include "hwconfig.h" #include "vdpau.h" #include "vdpau_internal.h" +#include "h265_profile_level.h" + static int vdpau_hevc_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) @@ -38,6 +40,9 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx, struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; VdpPictureInfoHEVC *info = &pic_ctx->info.hevc; +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + VdpPictureInfoHEVC444 *info2 = &pic_ctx->info.hevc_444; +#endif const HEVCSPS *sps = h->ps.sps; const HEVCPPS *pps = h->ps.pps; @@ -355,6 +360,41 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx, } } +#ifdef VDP_YCBCR_FORMAT_Y_U_V_444 + if (sps->sps_range_extension_flag) { + info2->sps_range_extension_flag = 1; + info2->transformSkipRotationEnableFlag = sps->transform_skip_rotation_enabled_flag; + info2->transformSkipContextEnableFlag = sps->transform_skip_context_enabled_flag; + info2->implicitRdpcmEnableFlag = sps->implicit_rdpcm_enabled_flag; + info2->explicitRdpcmEnableFlag = sps->explicit_rdpcm_enabled_flag; + info2->extendedPrecisionProcessingFlag = sps->extended_precision_processing_flag; + info2->intraSmoothingDisabledFlag = sps->intra_smoothing_disabled_flag; + info2->highPrecisionOffsetsEnableFlag = sps->high_precision_offsets_enabled_flag; + info2->persistentRiceAdaptationEnableFlag = sps->persistent_rice_adaptation_enabled_flag; + info2->cabacBypassAlignmentEnableFlag = sps->cabac_bypass_alignment_enabled_flag; + } else { + info2->sps_range_extension_flag = 0; + } + if (pps->pps_range_extensions_flag) { + info2->pps_range_extension_flag = 1; + info2->log2MaxTransformSkipSize = pps->log2_max_transform_skip_block_size; + info2->crossComponentPredictionEnableFlag = pps->cross_component_prediction_enabled_flag; + info2->chromaQpAdjustmentEnableFlag = pps->chroma_qp_offset_list_enabled_flag; + info2->diffCuChromaQpAdjustmentDepth = pps->diff_cu_chroma_qp_offset_depth; + info2->chromaQpAdjustmentTableSize = pps->chroma_qp_offset_list_len_minus1 + 1; + info2->log2SaoOffsetScaleLuma = pps->log2_sao_offset_scale_luma; + info2->log2SaoOffsetScaleChroma = pps->log2_sao_offset_scale_chroma; + for (ssize_t i = 0; i < info2->chromaQpAdjustmentTableSize; i++) + { + info2->cb_qp_adjustment[i] = pps->cb_qp_offset_list[i]; + info2->cr_qp_adjustment[i] = pps->cr_qp_offset_list[i]; + } + + } else { + info2->pps_range_extension_flag = 0; + } +#endif + return ff_vdpau_common_start_frame(pic_ctx, buffer, size); } @@ -391,10 +431,93 @@ static int vdpau_hevc_end_frame(AVCodecContext *avctx) return 0; } + + +static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h265_raw_ptl) +{ + h265_raw_ptl->general_profile_space = general_ptl->profile_space; + h265_raw_ptl->general_tier_flag = general_ptl->tier_flag; + h265_raw_ptl->general_profile_idc = general_ptl->profile_idc; + + memcpy(h265_raw_ptl->general_profile_compatibility_flag, + general_ptl->profile_compatibility_flag, 32 * sizeof(uint8_t)); + +#define copy_field(name) h265_raw_ptl->general_ ## name = general_ptl->name + copy_field(progressive_source_flag); + copy_field(interlaced_source_flag); + copy_field(non_packed_constraint_flag); + copy_field(frame_only_constraint_flag); + copy_field(max_12bit_constraint_flag); + copy_field(max_10bit_constraint_flag); + copy_field(max_8bit_constraint_flag); + copy_field(max_422chroma_constraint_flag); + copy_field(max_420chroma_constraint_flag); + copy_field(max_monochrome_constraint_flag); + copy_field(intra_constraint_flag); + copy_field(one_picture_only_constraint_flag); + copy_field(lower_bit_rate_constraint_flag); + copy_field(max_14bit_constraint_flag); + copy_field(inbld_flag); + copy_field(level_idc); +#undef copy_field + + return 0; +} + +/* + * Find exact vdpau_profile for HEVC Range Extension + */ +static int vdpau_hevc_parse_rext_profile(AVCodecContext *avctx, VdpDecoderProfile *vdp_profile) +{ + const HEVCContext *h = avctx->priv_data; + const HEVCSPS *sps = h->ps.sps; + const PTL *ptl = &sps->ptl; + const PTLCommon *general_ptl = &ptl->general_ptl; + const H265ProfileDescriptor *profile; + H265RawProfileTierLevel h265_raw_ptl = {0}; + + /* convert PTLCommon to H265RawProfileTierLevel */ + ptl_convert(general_ptl, &h265_raw_ptl); + + profile = ff_h265_get_profile(&h265_raw_ptl); + if (!profile) { + av_log(avctx, AV_LOG_WARNING, "HEVC profile is not found.\n"); + if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH) { + // Default to selecting Main profile if profile mismatch is allowed + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN; + return 0; + } else + return AVERROR(ENOTSUP); + } + + if (!strcmp(profile->name, "Main 12") || + !strcmp(profile->name, "Main 12 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_12; +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444 + else if (!strcmp(profile->name, "Main 4:4:4") || + !strcmp(profile->name, "Main 4:4:4 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444; +#endif +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444_10 + else if (!strcmp(profile->name, "Main 4:4:4 10") || + !strcmp(profile->name, "Main 4:4:4 10 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_10; + else if (!strcmp(profile->name, "Main 4:4:4 12") || + !strcmp(profile->name, "Main 4:4:4 12 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_12; +#endif + else + return AVERROR(ENOTSUP); + + return 0; +} + + static int vdpau_hevc_init(AVCodecContext *avctx) { VdpDecoderProfile profile; uint32_t level = avctx->level; + int ret; switch (avctx->profile) { case FF_PROFILE_HEVC_MAIN: @@ -406,6 +529,11 @@ static int vdpau_hevc_init(AVCodecContext *avctx) case FF_PROFILE_HEVC_MAIN_STILL_PICTURE: profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL; break; + case FF_PROFILE_HEVC_REXT: + ret = vdpau_hevc_parse_rext_profile(avctx, &profile); + if (ret) + return AVERROR(ENOTSUP); + break; default: return AVERROR(ENOTSUP); }