| /* |
| * Copyright (c) 2017, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| //! |
| //! \file codechal_encode_hevc_g9_skl.cpp |
| //! \brief HEVC dual-pipe encoder for GEN9 SKL. |
| //! |
| |
| #include "codechal_encode_hevc_g9_skl.h" |
| #include "igcodeckrn_g9.h" |
| |
| //! HEVC encoder kernel header structure for G9 SKL |
| struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL |
| { |
| int nKernelCount; //!< Total number of kernels |
| |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_2xDownSampling_Kernel; //!< 2x down sampling kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_32x32_PU_ModeDecision_Kernel; //!< Intra 32x32 PU mode decision kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_16x16_PU_SADComputation_Kernel; //!< Intra 16x16 PU SAD computation kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_16x16_PU_ModeDecision_Kernel; //!< Intra 16x16 PU mode decision kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_8x8_PU_Kernel; //!< Intra 8x8 PU mode decision kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_8x8_PU_FMode_Kernel; //!< Intra 8x8 PU final mode decision kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_PB_32x32_PU_IntraCheck; //!< P/B 32x32 PU intra mode check kernel |
| CODECHAL_KERNEL_HEADER HEVC_LCUEnc_PB_MB; //!< P/B MbEnc Kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_DS4HME; //!< 4x Scaling kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_P_HME; //!< P frame HME kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_B_HME; //!< B frame HME kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_COARSE; //!< Intra coarse kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Init; //!< BRC init kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Reset; //!< BRC reset kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Update; //!< BRC update kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_LCU_Update; //!< BRC LCU update kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_PB_Pak; //!< P/B frame PAK kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_PB_Adv; //!< P/B frame Adv kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Blockcopy; //!< BRC blockcopy kerenel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_DS_Combined; //!< Down scale and format conversion kernel |
| CODECHAL_KERNEL_HEADER HEVC_LCUEnc_P_MB; //!< P frame MbEnc kernel |
| CODECHAL_KERNEL_HEADER Hevc_LCUEnc_P_Adv; //!< P frame Adv kernel |
| }; |
| |
| //! \brief typedef of struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL |
| using PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL = struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL*; |
| |
| MOS_STATUS CodechalEncHevcStateG9Skl::GetKernelHeaderAndSize( |
| void *binary, |
| EncOperation operation, |
| uint32_t krnStateIdx, |
| void *krnHeader, |
| uint32_t *krnSize) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(binary); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(krnHeader); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(krnSize); |
| |
| PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL kernelHeaderTable = (PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL)binary; |
| PCODECHAL_KERNEL_HEADER currKrnHeader = nullptr; |
| |
| if (operation == ENC_SCALING4X) |
| { |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_DS4HME; |
| } |
| else if (operation == ENC_ME) |
| { |
| // SKL supports P frame. P HME index CODECHAL_ENCODE_ME_IDX_P is 0 and B HME index CODECHAL_ENCODE_ME_IDX_B is 1 |
| if (krnStateIdx == 0) |
| { |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_P_HME; |
| } |
| else |
| { |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_B_HME; |
| } |
| } |
| else if (operation == ENC_BRC) |
| { |
| switch (krnStateIdx) |
| { |
| case CODECHAL_HEVC_BRC_COARSE_INTRA: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_COARSE; |
| break; |
| |
| case CODECHAL_HEVC_BRC_INIT: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Init; |
| break; |
| |
| case CODECHAL_HEVC_BRC_RESET: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Reset; |
| break; |
| |
| case CODECHAL_HEVC_BRC_FRAME_UPDATE: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Update; |
| break; |
| |
| case CODECHAL_HEVC_BRC_LCU_UPDATE: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_LCU_Update; |
| break; |
| |
| default: |
| CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported BRC mode requested"); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| return eStatus; |
| } |
| } |
| else if (operation == ENC_MBENC) |
| { |
| switch (krnStateIdx) |
| { |
| case CODECHAL_HEVC_MBENC_2xSCALING: |
| case CODECHAL_HEVC_MBENC_32x32MD: |
| case CODECHAL_HEVC_MBENC_16x16SAD: |
| case CODECHAL_HEVC_MBENC_16x16MD: |
| case CODECHAL_HEVC_MBENC_8x8PU: |
| case CODECHAL_HEVC_MBENC_8x8FMODE: |
| case CODECHAL_HEVC_MBENC_32x32INTRACHECK: |
| case CODECHAL_HEVC_MBENC_BENC: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_2xDownSampling_Kernel; |
| currKrnHeader += krnStateIdx; |
| break; |
| |
| case CODECHAL_HEVC_MBENC_BPAK: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_PB_Pak; |
| break; |
| |
| case CODECHAL_HEVC_MBENC_ADV: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_PB_Adv; |
| break; |
| |
| case CODECHAL_HEVC_MBENC_DS_COMBINED: |
| // Ignore this kernel on SKL. |
| *krnSize = 0; |
| return eStatus; |
| |
| case CODECHAL_HEVC_MBENC_PENC: |
| currKrnHeader = &kernelHeaderTable->HEVC_LCUEnc_P_MB; |
| break; |
| |
| case CODECHAL_HEVC_MBENC_ADV_P: |
| currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_P_Adv; |
| break; |
| |
| default: |
| CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested"); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| return eStatus; |
| } |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested"); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| return eStatus; |
| } |
| |
| *((PCODECHAL_KERNEL_HEADER)krnHeader) = *currKrnHeader; |
| |
| PCODECHAL_KERNEL_HEADER nextKrnHeader = (currKrnHeader + 1); |
| PCODECHAL_KERNEL_HEADER invalidEntry = (PCODECHAL_KERNEL_HEADER)(((uint8_t*)binary) + sizeof(*kernelHeaderTable)); |
| uint32_t nextKrnOffset = *krnSize; |
| |
| if (nextKrnHeader < invalidEntry) |
| { |
| nextKrnOffset = nextKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT; |
| } |
| *krnSize = nextKrnOffset - (currKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); |
| |
| return eStatus; |
| } |
| |
| void CodechalEncHevcStateG9Skl::UpdateSSDSliceCount() |
| { |
| CodechalEncodeHevcBase::UpdateSSDSliceCount(); |
| |
| uint32_t sliceCount; |
| if (m_frameHeight * m_frameWidth >= 3840 * 2160 && m_targetUsage <= 4) |
| { |
| sliceCount = 0; |
| } |
| else |
| { |
| sliceCount = 2; |
| } |
| |
| if (m_osInterface->pfnSetSliceCount) |
| { |
| m_osInterface->pfnSetSliceCount(m_osInterface, &sliceCount); |
| } |
| } |
| |
| MOS_STATUS CodechalEncHevcStateG9Skl::Initialize(CodechalSetting * settings) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| // common initilization |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncHevcStateG9::Initialize(settings)); |
| |
| m_cscDsState->EnableMmc(); |
| |
| return eStatus; |
| } |
| |
| CodechalEncHevcStateG9Skl::CodechalEncHevcStateG9Skl( |
| CodechalHwInterface* hwInterface, |
| CodechalDebugInterface* debugInterface, |
| PCODECHAL_STANDARD_INFO standardInfo) |
| :CodechalEncHevcStateG9(hwInterface, debugInterface, standardInfo) |
| { |
| m_kernelBase = (uint8_t *)IGCODECKRN_G9; |
| pfnGetKernelHeaderAndSize = GetKernelHeaderAndSize; |
| m_noMeKernelForPFrame = false; |
| |
| MOS_STATUS eStatus = InitMhw(); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("HEVC encoder MHW initialization failed."); |
| } |
| } |
| |