| /* |
| * Copyright (c) 2017-2019, 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_avc_g12.cpp |
| //! \brief This file implements the C++ class/interface for Gen12 platform's AVC |
| //! DualPipe encoding to be used across CODECHAL components. |
| //! |
| #include "codechal_encode_avc_g12.h" |
| #include "codechal_mmc_encode_avc_g12.h" |
| #include "codechal_kernel_header_g12.h" |
| #include "codechal_kernel_hme_g12.h" |
| #include "mhw_render_g12_X.h" |
| #include "codeckrnheader.h" |
| #include "igcodeckrn_g12.h" |
| #include "media_user_settings_mgr_g12.h" |
| #if USE_CODECHAL_DEBUG_TOOL |
| #include "codechal_debug_encode_par_g12.h" |
| #include "mhw_vdbox_mfx_hwcmd_g12_X.h" |
| #include "mos_util_user_interface.h" |
| #endif |
| |
| enum MbencBindingTableOffset |
| { |
| mbencMfcAvcPakObj = 0, |
| mbencIndMvData = 1, |
| mbencBrcDistortion = 2, // For BRC distortion for I |
| mbencCurrY = 3, |
| mbencCurrUv = 4, |
| mbencMbSpecificData = 5, |
| mbencAuxVmeOut = 6, |
| mbencRefpicselectL0 = 7, |
| mbencMvDataFromMe = 8, |
| mbenc4xMeDistortion = 9, |
| mbencSlicemapData = 10, |
| mbencFwdMbData = 11, |
| mbencFwdMvData = 12, |
| mbencMbqp = 13, |
| mbencMbbrcConstData = 14, |
| mbencVmeInterPredCurrPicIdx0 = 15, |
| mbencVmeInterPredFwdPicIDX0 = 16, |
| mbencVmeInterPredBwdPicIDX00 = 17, |
| mbencVmeInterPredFwdPicIDX1 = 18, |
| mbencVmeInterPredBwdPicIDX10 = 19, |
| mbencVmeInterPredFwdPicIDX2 = 20, |
| mbencReserved0 = 21, |
| mbencVmeInterPredFwdPicIDX3 = 22, |
| mbencReserved1 = 23, |
| mbencVmeInterPredFwdPicIDX4 = 24, |
| mbencReserved2 = 25, |
| mbencVmeInterPredFwdPicIDX5 = 26, |
| mbencReserved3 = 27, |
| mbencVmeInterPredFwdPicIDX6 = 28, |
| mbencReserved4 = 29, |
| mbencVmeInterPredFwdPicIDX7 = 30, |
| mbencReserved5 = 31, |
| mbencVmeInterPredCurrPicIdx1 = 32, |
| mbencVmeInterPredBwdPicIDX01 = 33, |
| mbencReserved6 = 34, |
| mbencVmeInterPredBwdPicIDX11 = 35, |
| mbencReserved7 = 36, |
| mbencMbStats = 37, |
| mbencMadData = 38, |
| mbencBrcCurbeData = 39, |
| mbencForceNonskipMbMap = 40, |
| mbEncAdv = 41, |
| mbencSfdCostTable = 42, |
| mbencSwScoreboard = 43, |
| mbencNumSurfaces = 44 |
| }; |
| |
| enum WpBindingTableOffset |
| { |
| wpInputRefSurface = 0, |
| wpOutputScaledSurface = 1, |
| wpNumSurfaces = 2 |
| }; |
| |
| enum MbencIdOffset |
| { |
| mbencIOffset = 0, |
| mbencPOffset = 1, |
| mbencBOffset = 2, |
| mbencFrameTypeNum = 3 |
| }; |
| |
| // AVC MBEnc CURBE init data for TGL Kernel |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalIFrame[89] = |
| { |
| 0x00000082, 0x00000000, 0x00003910, 0x00a83000, 0x00000000, 0x28300000, 0x05000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x80800000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x00000080, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalIField[89] = |
| { |
| 0x00000082, 0x00000000, 0x00003910, 0x00a830c0, 0x02000000, 0x28300000, 0x05000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x80800000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x00000080, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalPFrame[89] = |
| { |
| 0x000000a3, 0x00000008, 0x00003910, 0x00ae3000, 0x30000000, 0x28300000, 0x05000000, 0x01400060, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x80010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x60000000, 0x000000a1, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000002, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalPField[89] = |
| { |
| 0x000000a3, 0x00000008, 0x00003910, 0x00ae30c0, 0x30000000, 0x28300000, 0x05000000, 0x01400060, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x80010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x000000a1, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000002, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalBFrame[89] = |
| { |
| 0x000000a3, 0x00200008, 0x00003910, 0x00aa7700, 0x50020000, 0x20200000, 0x05000000, 0xff400000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x01010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x60000000, 0x000000a1, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000002, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeNormalBField[89] = |
| { |
| 0x000000a3, 0x00200008, 0x00003919, 0x00aa77c0, 0x50020000, 0x20200000, 0x05000000, 0xff400000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x01010000, 0x00040c24, 0x00000000, 0xffff00ff, 0x40000000, 0x000000a1, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000002, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| // AVC I_DIST CURBE init data for TGL Kernel |
| const uint32_t CodechalEncodeAvcEncG12::MbencCurbe::m_mbEncCurbeIFrameDist[89] = |
| { |
| 0x00000082, 0x00200008, 0x001e3910, 0x00a83000, 0x90000000, 0x28300000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xff000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, |
| 0x80800000, 0x00000000, 0x00000800, 0xffff00ff, 0x40000000, 0x00000080, 0x00003900, 0x28300000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff |
| }; |
| |
| class CodechalEncodeAvcEncG12::WpCurbe |
| { |
| public: |
| WpCurbe() |
| { |
| memset((void *)&m_wpCurbeCmd, 0, sizeof(WpCurbe)); |
| } |
| |
| struct |
| { |
| // DW0 |
| union |
| { |
| struct |
| { |
| uint32_t m_defaultWeight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_defaultOffset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW0; |
| |
| // DW1 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi0XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi0YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW1; |
| |
| // DW2 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi0XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi0YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW2; |
| |
| // DW3 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi0Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi0Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW3; |
| |
| // DW4 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi1XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi1YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW4; |
| |
| // DW5 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi1XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi1YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW5; |
| |
| // DW6 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi1Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi1Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW6; |
| |
| // DW7 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi2XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi2YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW7; |
| |
| // DW8 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi2XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi2YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW8; |
| |
| // DW9 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi2Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi2Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW9; |
| |
| // DW10 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi3XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi3YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW10; |
| |
| // DW11 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi3XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi3YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW11; |
| |
| // DW12 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi3Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi3Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW12; |
| |
| // DW13 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi4XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi4YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW13; |
| |
| // DW14 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi4XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi4YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW14; |
| |
| // DW15 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi4Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi4Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW15; |
| |
| // DW16 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi5XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi5YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW16; |
| |
| // DW17 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi5XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi5YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW17; |
| |
| // DW18 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi5Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi5Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW18; |
| |
| // DW19 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi6XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi6YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW19; |
| |
| // DW20 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi6XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi6YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW20; |
| |
| // DW21 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi6Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi6Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW21; |
| |
| // DW22 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi7XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi7YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW22; |
| |
| // DW23 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi7XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi7YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW23; |
| |
| // DW24 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi7Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi7Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW24; |
| |
| // DW25 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi8XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi8YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW25; |
| |
| // DW26 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi8XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi8YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW26; |
| |
| // DW27 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi8Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi8Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW27; |
| |
| // DW28 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi9XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi9YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW28; |
| |
| // DW29 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi9XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi9YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW29; |
| |
| // DW30 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi9Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi9Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW30; |
| |
| // DW31 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi10XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi10YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW31; |
| |
| // DW32 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi10XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi10YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW32; |
| |
| // DW33 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi10Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi10Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW33; |
| |
| // DW34 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi11XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi11YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW34; |
| |
| // DW35 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi11XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi11YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW35; |
| |
| // DW36 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi11Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi11Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW36; |
| |
| // DW37 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi12XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi12YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW37; |
| |
| // DW38 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi12XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi12YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW38; |
| |
| // DW39 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi12Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi12Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW39; |
| |
| // DW40 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi13XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi13YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW40; |
| |
| // DW41 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi13XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi13YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW41; |
| |
| // DW42 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi13Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi13Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW42; |
| |
| // DW43 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi14XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi14YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW43; |
| |
| // DW44 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi14XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi14YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW44; |
| |
| // DW45 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi14Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi14Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW45; |
| |
| // DW46 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi15XLeft : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi15YTop : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW46; |
| |
| // DW47 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi15XRight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi15YBottom : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW47; |
| |
| // DW48 |
| union |
| { |
| struct |
| { |
| uint32_t m_roi15Weight : MOS_BITFIELD_RANGE(0, 15); |
| uint32_t m_roi15Offset : MOS_BITFIELD_RANGE(16, 31); |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW48; |
| |
| // DW49 |
| union |
| { |
| struct |
| { |
| uint32_t m_inputSurface; |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW49; |
| |
| // DW50 |
| union |
| { |
| struct |
| { |
| uint32_t m_outputSurface; |
| }; |
| struct |
| { |
| uint32_t m_value; |
| }; |
| } DW50; |
| } m_wpCurbeCmd; |
| }; |
| |
| static const uint32_t trellisQuantizationRounding[NUM_TARGET_USAGE_MODES] = |
| { |
| 0, 3, 0, 0, 0, 0, 0, 0 |
| }; |
| |
| const uint8_t CodechalEncodeAvcEncG12::m_QPAdjustmentDistThresholdMaxFrameThresholdIPB[576] = |
| { |
| 0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x00, 0x01, 0x02, 0x03, 0xff, |
| 0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xfe, 0xff, 0x00, 0x01, 0xfd, 0xfd, |
| 0xff, 0xff, 0x00, 0xfb, 0xfd, 0xfe, 0xff, 0xff, 0xfa, 0xfb, 0xfd, 0xfe, 0xff, 0x00, 0x04, 0x1e, |
| 0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x01, 0x02, 0x03, 0x05, 0x06, 0x01, 0x01, 0x02, 0x03, 0x05, 0x00, 0x01, 0x01, 0x02, 0x03, 0xff, |
| 0x00, 0x00, 0x01, 0x02, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff, |
| 0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x04, 0x1e, |
| 0x3c, 0x50, 0x78, 0x8c, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x01, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00, 0x01, 0x01, 0x02, 0xff, |
| 0x00, 0x00, 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0xfe, 0xff, |
| 0xff, 0xff, 0x00, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0xfb, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x02, 0x14, |
| 0x28, 0x46, 0x82, 0xa0, 0xc8, 0xff, 0x04, 0x04, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, |
| 0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, |
| 0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff, |
| 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, |
| 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, |
| 0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, |
| 0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff, |
| 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, |
| 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, |
| 0x03, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, |
| 0x01, 0x02, 0x02, 0x02, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xfe, 0xff, 0xff, |
| 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, |
| 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| }; |
| |
| const CODECHAL_ENCODE_AVC_IPCM_THRESHOLD CodechalEncodeAvcEncG12::m_IPCMThresholdTable[5] = |
| { |
| { 2, 3000 }, |
| { 4, 3600 }, |
| { 6, 5000 }, |
| { 10, 7500 }, |
| { 18, 9000 }, |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::m_intraModeCostForHighTextureMB[CODEC_AVC_NUM_QP] |
| { |
| 0x00000303, 0x00000304, 0x00000404, 0x00000405, 0x00000505, 0x00000506, 0x00000607, 0x00000708, |
| 0x00000809, 0x0000090a, 0x00000a0b, 0x00000b0c, 0x00000c0e, 0x00000e18, 0x00001819, 0x00001918, |
| 0x00001a19, 0x00001b19, 0x00001d19, 0x00001e18, 0x00002818, 0x00002918, 0x00002a18, 0x00002b19, |
| 0x00002d18, 0x00002e18, 0x00003818, 0x00003918, 0x00003a18, 0x00003b0f, 0x00003d0e, 0x00003e0e, |
| 0x0000480e, 0x0000490e, 0x00004a0e, 0x00004b0d, 0x00004d0d, 0x00004e0d, 0x0000580e, 0x0000590e, |
| 0x00005a0e, 0x00005b0d, 0x00005d0c, 0x00005e0b, 0x0000680a, 0x00006908, 0x00006a09, 0x00006b0a, |
| 0x00006d0b, 0x00006e0d, 0x0000780e, 0x00007918 |
| }; |
| |
| const uint16_t CodechalEncodeAvcEncG12::m_lambdaData[256] = { |
| 9, 7, 9, 6, 12, 8, 12, 8, 15, 10, 15, 9, 19, 13, 19, 12, 24, |
| 17, 24, 15, 30, 21, 30, 19, 38, 27, 38, 24, 48, 34, 48, 31, 60, 43, |
| 60, 39, 76, 54, 76, 49, 96, 68, 96, 62, 121, 85, 121, 78, 153, 108, 153, |
| 99, 193, 135, 193, 125, 243, 171, 243, 157, 306, 215, 307, 199, 385, 271, 387, 251, |
| 485, 342, 488, 317, 612, 431, 616, 400, 771, 543, 777, 505, 971, 684, 981, 638, 1224, |
| 862, 1237, 806, 1542, 1086, 1562, 1018, 1991, 1402, 1971, 1287, 2534, 1785, 2488, 1626, 3077, 2167, |
| 3141, 2054, 3982, 2805, 3966, 2596, 4887, 3442, 5007, 3281, 6154, 4335, 6322, 4148, 7783, 5482, 7984, |
| 5243, 9774, 6885, 10082, 6629, 12489, 8797, 12733, 8382, 15566, 10965, 16082, 10599, 19729, 13897, 20313, 13404, |
| 24797, 17467, 25660, 16954, 31313, 22057, 32415, 21445, 39458, 27795, 40953, 27129, 49594, 34935, 51742, 34323, 61440, |
| 43987, 61440, 43428, 61440, 55462, 61440, 54954, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, |
| 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, |
| 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, 61440, |
| 61440, 61440, 61440, 61440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, |
| }; |
| |
| const uint8_t CodechalEncodeAvcEncG12::m_ftQ25[64] = //27 value 4 dummy |
| { |
| 0, //qp=0 |
| 0, 0, 0, 0, 0, 0, //qp=1,2;3,4;5,6; |
| 1, 1, 3, 3, 6, 6, 8, 8, 11, 11, //qp=7,8;9,10;11,12;13,14;15;16 |
| 13, 13, 16, 16, 19, 19, 22, 22, 26, 26, //qp=17,18;19,20;21,22;23,24;25,26 |
| 30, 30, 34, 34, 39, 39, 44, 44, 50, 50, //qp=27,28;29,30;31,32;33,34;35,36 |
| 56, 56, 62, 62, 69, 69, 77, 77, 85, 85, //qp=37,38;39,40;41,42;43,44;45,46 |
| 94, 94, 104, 104, 115, 115, //qp=47,48;49,50;51 |
| 0, 0, 0, 0, 0, 0, 0, 0 //dummy |
| }; |
| |
| // AVC MBEnc RefCost tables, index [CodingType][QP] |
| // QP is from 0 - 51, pad it to 64 since BRC needs each subarray size to be 128bytes |
| const uint16_t CodechalEncodeAvcEncG12::m_refCostMultiRefQp[NUM_PIC_TYPES][64] = |
| { |
| // I-frame |
| { |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000 |
| }, |
| // P-slice |
| { |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000 |
| }, |
| //B-slice |
| { |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
| 0x0000, 0x0000, 0x0000, 0x0000 |
| } |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::m_multiPred[NUM_TARGET_USAGE_MODES] = |
| { |
| 0, 3, 3, 0, 0, 0, 0, 0 |
| }; |
| |
| const uint32_t CodechalEncodeAvcEncG12::m_multiRefDisableQPCheck[NUM_TARGET_USAGE_MODES] = |
| { |
| 0, 1, 0, 0, 0, 0, 0, 0 |
| }; |
| // clang-format on |
| |
| const int32_t CodechalEncodeAvcEncG12::m_brcBTCounts[CODECHAL_ENCODE_BRC_IDX_NUM] = { |
| CODECHAL_ENCODE_AVC_BRC_INIT_RESET_NUM_SURFACES, |
| frameBrcUpdateNumSurfaces, |
| CODECHAL_ENCODE_AVC_BRC_INIT_RESET_NUM_SURFACES, |
| mbencNumSurfaces, |
| CODECHAL_ENCODE_AVC_BRC_BLOCK_COPY_NUM_SURFACES, |
| mbBrcUpdateNumSurfaces |
| }; |
| |
| const int32_t CodechalEncodeAvcEncG12::m_brcCurbeSize[CODECHAL_ENCODE_BRC_IDX_NUM] = { |
| (sizeof(BrcInitResetCurbe)), |
| (sizeof(FrameBrcUpdateCurbe)), |
| (sizeof(BrcInitResetCurbe)), |
| (sizeof(MbencCurbe)), |
| 0, |
| (sizeof(MbBrcUpdateCurbe)) |
| }; |
| |
| class CodechalEncodeAvcEncG12::EncKernelHeader |
| { |
| public: |
| int m_kernelCount; |
| // Quality mode for Frame/Field |
| CODECHAL_KERNEL_HEADER m_mbEncQltyI; |
| CODECHAL_KERNEL_HEADER m_mbEncQltyP; |
| CODECHAL_KERNEL_HEADER m_mEncQltyB; |
| // Normal mode for Frame/Field |
| CODECHAL_KERNEL_HEADER m_mbEncNormI; |
| CODECHAL_KERNEL_HEADER m_mbEncNormP; |
| CODECHAL_KERNEL_HEADER m_mbEncNormB; |
| // Performance modes for Frame/Field |
| CODECHAL_KERNEL_HEADER m_mbEncPerfI; |
| CODECHAL_KERNEL_HEADER m_mbEncPerfP; |
| CODECHAL_KERNEL_HEADER m_mbEncPerfB; |
| // Modes for Frame/Field |
| CODECHAL_KERNEL_HEADER m_mbEncAdvI; |
| CODECHAL_KERNEL_HEADER m_mbEncAdvP; |
| CODECHAL_KERNEL_HEADER m_mbEncAdvB; |
| // BRC Init frame |
| CODECHAL_KERNEL_HEADER m_initFrameBrc; |
| // FrameBRC Update |
| CODECHAL_KERNEL_HEADER m_frameEncUpdate; |
| // BRC Reset frame |
| CODECHAL_KERNEL_HEADER m_brcResetFrame; |
| // BRC I Frame Distortion |
| CODECHAL_KERNEL_HEADER m_brcIFrameDist; |
| // BRCBlockCopy |
| CODECHAL_KERNEL_HEADER m_brcBlockCopy; |
| // MbBRC Update |
| CODECHAL_KERNEL_HEADER m_mbBrcUpdate; |
| //Weighted Prediction Kernel |
| CODECHAL_KERNEL_HEADER m_weightedPrediction; |
| // SW scoreboard initialization kernel |
| CODECHAL_KERNEL_HEADER m_initSwScoreboard; |
| }; |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::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); |
| |
| auto kernelHeaderTable = (EncKernelHeader *)binary; |
| auto invalidEntry = &(kernelHeaderTable->m_weightedPrediction) + 1; |
| auto nextKrnOffset = *krnSize; |
| |
| PCODECHAL_KERNEL_HEADER currKrnHeader = nullptr; |
| |
| if (operation == ENC_BRC) |
| { |
| currKrnHeader = &kernelHeaderTable->m_initFrameBrc; |
| } |
| else if (operation == ENC_MBENC) |
| { |
| currKrnHeader = &kernelHeaderTable->m_mbEncQltyI; |
| } |
| else if (operation == ENC_MBENC_ADV) |
| { |
| currKrnHeader = &kernelHeaderTable->m_mbEncAdvI; |
| } |
| else if (operation == ENC_WP) |
| { |
| currKrnHeader = &kernelHeaderTable->m_weightedPrediction; |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| currKrnHeader += krnStateIdx; |
| *((PCODECHAL_KERNEL_HEADER)krnHeader) = *currKrnHeader; |
| |
| auto nextKrnHeader = (currKrnHeader + 1); |
| if (nextKrnHeader < invalidEntry) |
| { |
| nextKrnOffset = nextKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT; |
| } |
| *krnSize = nextKrnOffset - (currKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); |
| |
| return eStatus; |
| } |
| |
| CodechalEncodeAvcEncG12::CodechalEncodeAvcEncG12( |
| CodechalHwInterface * hwInterface, |
| CodechalDebugInterface *debugInterface, |
| PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncodeAvcEnc(hwInterface, debugInterface, standardInfo), |
| m_sinlgePipeVeState(nullptr) |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_ASSERT(m_osInterface); |
| |
| Mos_CheckVirtualEngineSupported(m_osInterface, false, true); |
| |
| // Virtual Engine is enabled in default. |
| Mos_SetVirtualEngineSupported(m_osInterface, true); |
| |
| bKernelTrellis = true; |
| bExtendedMvCostRange = true; |
| bBrcSplitEnable = true; |
| bDecoupleMbEncCurbeFromBRC = true; |
| bHighTextureModeCostEnable = true; |
| bMvDataNeededByBRC = false; |
| |
| this->pfnGetKernelHeaderAndSize = CodechalEncodeAvcEncG12::GetKernelHeaderAndSize; |
| |
| m_cmKernelEnable = true; |
| m_mbStatsSupported = true; |
| m_useCommonKernel = true; |
| |
| m_kernelBase = (uint8_t *)IGCODECKRN_G12; |
| m_kuidCommon = IDR_CODEC_HME_DS_SCOREBOARD_KERNEL; |
| AddIshSize(m_kuid, m_kernelBase); |
| AddIshSize(m_kuidCommon, m_kernelBase); |
| |
| m_vdboxOneDefaultUsed = true; |
| |
| Mos_CheckVirtualEngineSupported(m_osInterface, false, false); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(m_encodeParState = MOS_New(CodechalDebugEncodeParG12, this)); |
| CreateAvcPar(); |
| ) |
| } |
| |
| CodechalEncodeAvcEncG12::~CodechalEncodeAvcEncG12() |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MOS_Delete(m_intraDistKernel); |
| |
| if (m_swScoreboardState) |
| { |
| MOS_Delete(m_swScoreboardState); |
| m_swScoreboardState = nullptr; |
| } |
| |
| if (m_sinlgePipeVeState) |
| { |
| MOS_FreeMemAndSetNull(m_sinlgePipeVeState); |
| } |
| |
| CODECHAL_DEBUG_TOOL( |
| DestroyAvcPar(); |
| MOS_Delete(m_encodeParState); |
| ) |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::MbEncKernel(bool mbEncIFrameDistInUse) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| uint8_t ppsIdx = m_avcSliceParams->pic_parameter_set_id; |
| uint8_t spsIdx = m_avcPicParams[ppsIdx]->seq_parameter_set_id; |
| auto refList = &m_refList[0]; |
| auto currRefList = m_refList[m_currReconstructedPic.FrameIdx]; |
| bool use45DegreePattern = false; |
| bool roiEnabled = (m_avcPicParams[ppsIdx]->NumROI > 0) ? true : false; |
| uint8_t refPicListIdx = m_avcSliceParams[ppsIdx].RefPicList[0][0].FrameIdx; |
| uint8_t refFrameListIdx = m_avcPicParam[ppsIdx].RefFrameList[refPicListIdx].FrameIdx; |
| bool dirtyRoiEnabled = (m_pictureCodingType == P_TYPE |
| && m_avcPicParams[ppsIdx]->NumDirtyROI > 0 |
| && m_prevReconFrameIdx == refFrameListIdx); |
| |
| // Two flags(bMbConstDataBufferNeeded, bMbQpBufferNeeded) |
| // would be used as there are two buffers and not all cases need both the buffers |
| // Constant Data buffer needed for MBBRC, MBQP, ROI, RollingIntraRefresh |
| // Please note that this surface needs to be programmed for |
| // all usage cases(including CQP cases) because DWord13 includes mode cost for high texture MB?s cost. |
| bool mbConstDataBufferInUse = bMbBrcEnabled || bMbQpDataEnabled || roiEnabled || dirtyRoiEnabled || |
| m_avcPicParam->EnableRollingIntraRefresh || bHighTextureModeCostEnable; |
| |
| bool mbQpBufferInUse = bMbBrcEnabled || bBrcRoiEnabled || bMbQpDataEnabled; |
| |
| if (m_feiEnable) |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcFeiPicParams); |
| mbConstDataBufferInUse |= m_avcFeiPicParams->bMBQp; |
| mbQpBufferInUse |= m_avcFeiPicParams->bMBQp; |
| } |
| |
| // MFE MBEnc kernel handles several frames from different streams in one submission. |
| // All the streams use the same HW/OS/StateHeap interfaces during this submssion. |
| // All the streams use the kernel state from the first stream. |
| // The first stream allocates the DSH and SSH, send the binding table. |
| // The last stream sets mfe curbe, prepare and submit the command buffer. |
| // All the streams set their own curbe surfaces and surface states. |
| CODECHAL_ENCODE_AVC_BINDING_TABLE_MBENC origMbEncBindingTable; |
| if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| auto mfeEncodeSharedState = m_mfeEncodeSharedState; |
| if (m_mfeFirstStream) |
| { |
| mfeEncodeSharedState->pHwInterface = m_hwInterface; |
| mfeEncodeSharedState->pOsInterface = m_osInterface; |
| m_hwInterface->GetRenderInterface()->m_stateHeapInterface = m_stateHeapInterface; |
| m_osInterface->pfnResetOsStates(m_osInterface); |
| } |
| else |
| { |
| m_hwInterface = mfeEncodeSharedState->pHwInterface; |
| m_osInterface = mfeEncodeSharedState->pOsInterface; |
| m_stateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface; |
| |
| m_osInterface = m_osInterface; |
| } |
| // Set maximum width/height, it is used for initializing media walker parameters |
| // during submitting the command buffer at the last stream. |
| if (m_picWidthInMb > mfeEncodeSharedState->dwPicWidthInMB) |
| { |
| mfeEncodeSharedState->dwPicWidthInMB = m_picWidthInMb; |
| } |
| if (m_frameFieldHeightInMb > mfeEncodeSharedState->dwPicHeightInMB) |
| { |
| mfeEncodeSharedState->dwPicHeightInMB = m_frameFieldHeightInMb; |
| } |
| if (m_sliceHeight > mfeEncodeSharedState->sliceHeight) |
| { |
| mfeEncodeSharedState->sliceHeight = m_sliceHeight; |
| } |
| |
| m_osInterface->pfnSetGpuContext(m_osInterface, m_renderContext); |
| CODECHAL_DEBUG_TOOL( |
| m_debugInterface->m_osInterface = m_osInterface;) |
| // bookkeeping the original binding table |
| origMbEncBindingTable = MbEncBindingTable; |
| } |
| |
| PerfTagSetting perfTag; |
| perfTag.Value = 0; |
| perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; |
| perfTag.CallType = (mbEncIFrameDistInUse && !m_singleTaskPhaseSupported) ? |
| CODECHAL_ENCODE_PERFTAG_CALL_INTRA_DIST : CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL; |
| perfTag.PictureCodingType = m_pictureCodingType; |
| m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); |
| |
| CODECHAL_MEDIA_STATE_TYPE encFunctionType; |
| if (mbEncIFrameDistInUse) |
| { |
| encFunctionType = CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST; |
| } |
| else if (bUseMbEncAdvKernel) |
| { |
| encFunctionType = CODECHAL_MEDIA_STATE_ENC_ADV; |
| } |
| else if (m_kernelMode == encodeNormalMode) |
| { |
| encFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL; |
| } |
| else if (m_kernelMode == encodePerformanceMode) |
| { |
| encFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE; |
| } |
| else |
| { |
| encFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY; |
| } |
| |
| // Initialize DSH kernel region |
| PMHW_KERNEL_STATE kernelState; |
| if (mbEncIFrameDistInUse) |
| { |
| kernelState = &BrcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST]; |
| } |
| else if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| kernelState = &mfeMbEncKernelState; |
| } |
| else |
| { |
| CodechalEncodeIdOffsetParams idOffsetParams; |
| MOS_ZeroMemory(&idOffsetParams, sizeof(idOffsetParams)); |
| idOffsetParams.Standard = m_standard; |
| idOffsetParams.EncFunctionType = encFunctionType; |
| idOffsetParams.wPictureCodingType = m_pictureCodingType; |
| idOffsetParams.ucDmvPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag; |
| idOffsetParams.interlacedField = CodecHal_PictureIsField(m_currOriginalPic); |
| |
| uint32_t krnStateIdx; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetMbEncKernelStateIdx( |
| &idOffsetParams, |
| &krnStateIdx)); |
| kernelState = &pMbEncKernelStates[krnStateIdx]; |
| } |
| |
| // All the streams use the kernel state from the first stream. |
| if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| if (m_mfeFirstStream) |
| { |
| m_mfeEncodeSharedState->pMfeMbEncKernelState = kernelState; |
| } |
| else |
| { |
| kernelState = m_mfeEncodeSharedState->pMfeMbEncKernelState; |
| } |
| } |
| |
| // If Single Task Phase is not enabled, use BT count for the kernel state. |
| if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported || |
| (IsMfeMbEncEnabled(mbEncIFrameDistInUse) && m_mfeFirstStream)) |
| { |
| uint32_t maxBtCount = m_singleTaskPhaseSupported ? |
| m_maxBtCount : kernelState->KernelParams.iBTCount; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( |
| m_stateHeapInterface, |
| maxBtCount)); |
| m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); |
| } |
| |
| // Allocate DSH and SSH for the first stream, which will be passed to other streams through the shared kernel state. |
| if ((IsMfeMbEncEnabled(mbEncIFrameDistInUse) && m_mfeFirstStream) || |
| (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) && !bMbEncCurbeSetInBrcUpdate)) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( |
| m_stateHeapInterface, |
| kernelState, |
| false, |
| 0, |
| false, |
| m_storeData)); |
| |
| MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; |
| MOS_ZeroMemory(&idParams, sizeof(idParams)); |
| idParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( |
| m_stateHeapInterface, |
| 1, |
| &idParams)); |
| } |
| |
| if (bMbEncCurbeSetInBrcUpdate) |
| { |
| if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| // If BRC update was used to set up the DSH & SSH, SSH only needs to |
| // be obtained if single task phase is enabled because the same SSH |
| // could not be shared between BRC update and MbEnc |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( |
| m_stateHeapInterface, |
| kernelState, |
| true, |
| 0, |
| m_singleTaskPhaseSupported, |
| m_storeData)); |
| } |
| } |
| else |
| { |
| // Setup AVC Curbe |
| CODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS mbEncCurbeParams; |
| MOS_ZeroMemory(&mbEncCurbeParams, sizeof(mbEncCurbeParams)); |
| mbEncCurbeParams.pPicParams = m_avcPicParams[ppsIdx]; |
| mbEncCurbeParams.pSeqParams = m_avcSeqParams[spsIdx]; |
| mbEncCurbeParams.pSlcParams = m_avcSliceParams; |
| mbEncCurbeParams.ppRefList = &(m_refList[0]); |
| mbEncCurbeParams.pPicIdx = &(m_picIdx[0]); |
| mbEncCurbeParams.bRoiEnabled = roiEnabled; |
| mbEncCurbeParams.bDirtyRoiEnabled = dirtyRoiEnabled; |
| mbEncCurbeParams.bMbEncIFrameDistEnabled = mbEncIFrameDistInUse; |
| mbEncCurbeParams.pdwBlockBasedSkipEn = &dwMbEncBlockBasedSkipEn; |
| if (mbEncIFrameDistInUse) |
| { |
| mbEncCurbeParams.bBrcEnabled = false; |
| mbEncCurbeParams.wPicWidthInMb = (uint16_t)m_downscaledWidthInMb4x; |
| mbEncCurbeParams.wFieldFrameHeightInMb = (uint16_t)m_downscaledFrameFieldHeightInMb4x; |
| mbEncCurbeParams.usSliceHeight = (m_sliceHeight + SCALE_FACTOR_4x - 1) / SCALE_FACTOR_4x; |
| } |
| else |
| { |
| mbEncCurbeParams.bBrcEnabled = bBrcEnabled; |
| mbEncCurbeParams.wPicWidthInMb = m_picWidthInMb; |
| mbEncCurbeParams.wFieldFrameHeightInMb = m_frameFieldHeightInMb; |
| mbEncCurbeParams.usSliceHeight = (m_arbitraryNumMbsInSlice) ? |
| m_frameFieldHeightInMb : m_sliceHeight; |
| mbEncCurbeParams.bUseMbEncAdvKernel = bUseMbEncAdvKernel; |
| } |
| mbEncCurbeParams.pKernelState = kernelState; |
| mbEncCurbeParams.pAvcQCParams = m_avcQCParams; |
| mbEncCurbeParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled; |
| mbEncCurbeParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled; |
| mbEncCurbeParams.bApdatvieSearchWindowSizeEnabled = bApdatvieSearchWindowEnable; |
| mbEncCurbeParams.bSquareRollingIEnabled = bSquareRollingIEnabled; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMbEnc( |
| &mbEncCurbeParams)); |
| } |
| |
| if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| // Set MFE specific curbe in the last stream |
| // MFE MBEnc specific curbe is different from the normal MBEnc curbe which is passed |
| // to MFE MBEnc kernel as a surface. |
| if (m_mfeLastStream) |
| { |
| CODECHAL_ENCODE_AVC_MFE_MBENC_CURBE_PARAMS mfeMbEncCurbeParams; |
| MOS_ZeroMemory(&mfeMbEncCurbeParams, sizeof(mfeMbEncCurbeParams)); |
| mfeMbEncCurbeParams.submitNumber = m_mfeEncodeParams.submitNumber; |
| mfeMbEncCurbeParams.pKernelState = kernelState; |
| mfeMbEncCurbeParams.pBindingTable = &MbEncBindingTable; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeAvcMfeMbEnc(&mfeMbEncCurbeParams)); |
| } |
| // Change the binding table according to the index during this submission |
| UpdateMfeMbEncBindingTable(m_mfeEncodeParams.submitIndex); |
| } |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_DSH_TYPE, |
| kernelState)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( |
| encFunctionType, |
| kernelState)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_ISH_TYPE, |
| kernelState)); |
| ) |
| |
| for (uint8_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) |
| { |
| if (m_picIdx[i].bValid) |
| { |
| uint8_t index = m_picIdx[i].ucPicIdx; |
| refList[index]->sRefBuffer = m_userFlags.bUseRawPicForRef ? |
| refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer; |
| |
| CodecHalGetResourceInfo(m_osInterface, &refList[index]->sRefBuffer); |
| } |
| } |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| MOS_ZeroMemory(&cmdBuffer, sizeof(cmdBuffer)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| // For MFE, All the commands are sent in the last stream and can not be sent in different streams |
| // since CmdBuffer is zeroed for each stream and cmd buffer pointer is reset. |
| if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeLastStream) |
| { |
| SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); |
| sendKernelCmdsParams.EncFunctionType = encFunctionType; |
| sendKernelCmdsParams.ucDmvPredFlag = |
| m_avcSliceParams->direct_spatial_mv_pred_flag; |
| sendKernelCmdsParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); |
| } |
| |
| // Set up MB BRC Constant Data Buffer if there is QP change within a frame |
| if (mbConstDataBufferInUse) |
| { |
| CODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS initMbBrcConstantDataBufferParams; |
| |
| MOS_ZeroMemory(&initMbBrcConstantDataBufferParams, sizeof(initMbBrcConstantDataBufferParams)); |
| initMbBrcConstantDataBufferParams.pOsInterface = m_osInterface; |
| initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer = |
| &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx]; |
| initMbBrcConstantDataBufferParams.dwMbEncBlockBasedSkipEn = dwMbEncBlockBasedSkipEn; |
| initMbBrcConstantDataBufferParams.pPicParams = m_avcPicParams[ppsIdx]; |
| initMbBrcConstantDataBufferParams.wPictureCodingType = m_pictureCodingType; |
| initMbBrcConstantDataBufferParams.bSkipBiasAdjustmentEnable = m_skipBiasAdjustmentEnable; |
| initMbBrcConstantDataBufferParams.bAdaptiveIntraScalingEnable = bAdaptiveIntraScalingEnable; |
| initMbBrcConstantDataBufferParams.bOldModeCostEnable = bOldModeCostEnable; |
| initMbBrcConstantDataBufferParams.pAvcQCParams = m_avcQCParams; |
| initMbBrcConstantDataBufferParams.bEnableKernelTrellis = bKernelTrellis && m_trellisQuantParams.dwTqEnabled; |
| |
| // Kernel controlled Trellis Quantization |
| if (bKernelTrellis && m_trellisQuantParams.dwTqEnabled) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CalcLambdaTable( |
| m_pictureCodingType, |
| &initMbBrcConstantDataBufferParams.Lambda[0][0])); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMbBrcConstantDataBuffer(&initMbBrcConstantDataBufferParams)); |
| |
| //dump MbBrcLut |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| initMbBrcConstantDataBufferParams.presBrcConstantDataBuffer, |
| CodechalDbgAttr::attrOutput, |
| "MbBrcLut", |
| 16 * (CODEC_AVC_NUM_QP) * sizeof(uint32_t), |
| 0, |
| CODECHAL_MEDIA_STATE_ENC_QUALITY))); |
| } |
| |
| // Add binding table |
| // For MFE first stream sends binding table since the function zeros the whole SSH. |
| // If last stream sends binding table it will clean the surface states from other streams. |
| if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeFirstStream) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( |
| m_stateHeapInterface, |
| kernelState)); |
| } |
| |
| //Add surface states |
| CODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS mbEncSurfaceParams; |
| MOS_ZeroMemory(&mbEncSurfaceParams, sizeof(mbEncSurfaceParams)); |
| mbEncSurfaceParams.MediaStateType = encFunctionType; |
| mbEncSurfaceParams.pAvcSlcParams = m_avcSliceParams; |
| mbEncSurfaceParams.ppRefList = &m_refList[0]; |
| mbEncSurfaceParams.pAvcPicIdx = &m_picIdx[0]; |
| mbEncSurfaceParams.pCurrOriginalPic = &m_currOriginalPic; |
| mbEncSurfaceParams.pCurrReconstructedPic = &m_currReconstructedPic; |
| mbEncSurfaceParams.wPictureCodingType = m_pictureCodingType; |
| mbEncSurfaceParams.psCurrPicSurface = mbEncIFrameDistInUse ? m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : m_rawSurfaceToEnc; |
| if (mbEncIFrameDistInUse && CodecHal_PictureIsBottomField(m_currOriginalPic)) |
| { |
| mbEncSurfaceParams.dwCurrPicSurfaceOffset = m_scaledBottomFieldOffset; |
| } |
| mbEncSurfaceParams.dwMbCodeBottomFieldOffset = (uint32_t)m_mbcodeBottomFieldOffset; |
| mbEncSurfaceParams.dwMvBottomFieldOffset = (uint32_t)m_mvBottomFieldOffset; |
| mbEncSurfaceParams.ps4xMeMvDataBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer); |
| mbEncSurfaceParams.ps4xMeDistortionBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer); |
| mbEncSurfaceParams.dwMeMvBottomFieldOffset = m_hmeKernel->Get4xMeMvBottomFieldOffset(); |
| mbEncSurfaceParams.dwMeDistortionBottomFieldOffset = m_hmeKernel->GetDistortionBottomFieldOffset(); |
| mbEncSurfaceParams.psMeBrcDistortionBuffer = &BrcBuffers.sMeBrcDistortionBuffer; |
| mbEncSurfaceParams.dwMeBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset; |
| mbEncSurfaceParams.dwRefPicSelectBottomFieldOffset = (uint32_t)ulRefPicSelectBottomFieldOffset; |
| mbEncSurfaceParams.dwFrameWidthInMb = (uint32_t)m_picWidthInMb; |
| mbEncSurfaceParams.dwFrameFieldHeightInMb = (uint32_t)m_frameFieldHeightInMb; |
| mbEncSurfaceParams.dwFrameHeightInMb = (uint32_t)m_picHeightInMb; |
| // Interleaved input surfaces |
| mbEncSurfaceParams.dwVerticalLineStride = m_verticalLineStride; |
| mbEncSurfaceParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset; |
| // Vertical line stride is not used for the case of scaled surfaces saved as separate fields |
| if (!m_fieldScalingOutputInterleaved && mbEncIFrameDistInUse) |
| { |
| mbEncSurfaceParams.dwVerticalLineStride = 0; |
| mbEncSurfaceParams.dwVerticalLineStrideOffset = 0; |
| } |
| mbEncSurfaceParams.bHmeEnabled = m_hmeSupported; |
| mbEncSurfaceParams.bMbEncIFrameDistInUse = mbEncIFrameDistInUse; |
| mbEncSurfaceParams.presMbBrcConstDataBuffer = &BrcBuffers.resMbBrcConstDataBuffer[m_currRecycledBufIdx]; |
| mbEncSurfaceParams.psMbQpBuffer = |
| bMbQpDataEnabled ? &sMbQpDataSurface : &BrcBuffers.sBrcMbQpBuffer; |
| mbEncSurfaceParams.dwMbQpBottomFieldOffset = bMbQpDataEnabled ? 0 : BrcBuffers.dwBrcMbQpBottomFieldOffset; |
| mbEncSurfaceParams.bUsedAsRef = |
| m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef; |
| mbEncSurfaceParams.presMADDataBuffer = &m_resMadDataBuffer[m_currMadBufferIdx]; |
| mbEncSurfaceParams.bMbQpBufferInUse = mbQpBufferInUse; |
| mbEncSurfaceParams.bMbSpecificDataEnabled = bMbSpecificDataEnabled; |
| mbEncSurfaceParams.presMbSpecificDataBuffer = &resMbSpecificDataBuffer[m_currRecycledBufIdx]; |
| mbEncSurfaceParams.bMbConstDataBufferInUse = mbConstDataBufferInUse; |
| mbEncSurfaceParams.bMADEnabled = mbEncIFrameDistInUse ? false : m_madEnabled; |
| mbEncSurfaceParams.bUseMbEncAdvKernel = mbEncIFrameDistInUse ? false : bUseMbEncAdvKernel; |
| mbEncSurfaceParams.presMbEncCurbeBuffer = |
| (mbEncIFrameDistInUse && bUseMbEncAdvKernel) ? nullptr : &BrcBuffers.resMbEncAdvancedDsh; |
| mbEncSurfaceParams.presMbEncBRCBuffer = &BrcBuffers.resMbEncBrcBuffer; |
| |
| if (IsMfeMbEncEnabled(mbEncIFrameDistInUse) || bDecoupleMbEncCurbeFromBRC) |
| { |
| mbEncSurfaceParams.dwMbEncBRCBufferSize = m_mbencBrcBufferSize; |
| } |
| |
| mbEncSurfaceParams.bUseAdvancedDsh = bAdvancedDshInUse; |
| mbEncSurfaceParams.bBrcEnabled = bBrcEnabled; |
| mbEncSurfaceParams.bArbitraryNumMbsInSlice = m_arbitraryNumMbsInSlice; |
| mbEncSurfaceParams.psSliceMapSurface = &m_sliceMapSurface[m_currRecycledBufIdx]; |
| mbEncSurfaceParams.dwSliceMapBottomFieldOffset = (uint32_t)m_sliceMapBottomFieldOffset; |
| mbEncSurfaceParams.pMbEncBindingTable = &MbEncBindingTable; |
| mbEncSurfaceParams.pKernelState = kernelState; |
| |
| if (m_mbStatsSupported) |
| { |
| mbEncSurfaceParams.bMBVProcStatsEnabled = m_flatnessCheckEnabled || |
| m_adaptiveTransformDecisionEnabled || |
| bMbBrcEnabled || |
| bMbQpDataEnabled; |
| mbEncSurfaceParams.presMBVProcStatsBuffer = &m_resMbStatsBuffer; |
| mbEncSurfaceParams.dwMBVProcStatsBottomFieldOffset = m_mbStatsBottomFieldOffset; |
| } |
| else |
| { |
| mbEncSurfaceParams.bFlatnessCheckEnabled = m_flatnessCheckEnabled; |
| mbEncSurfaceParams.psFlatnessCheckSurface = &m_flatnessCheckSurface; |
| mbEncSurfaceParams.dwFlatnessCheckBottomFieldOffset = (uint32_t)m_flatnessCheckBottomFieldOffset; |
| } |
| |
| // Set up pFeiPicParams |
| mbEncSurfaceParams.pFeiPicParams = m_avcFeiPicParams; |
| |
| mbEncSurfaceParams.bMbDisableSkipMapEnabled = bMbDisableSkipMapEnabled; |
| mbEncSurfaceParams.psMbDisableSkipMapSurface = psMbDisableSkipMapSurface; |
| |
| if (bUseWeightedSurfaceForL0 || bUseWeightedSurfaceForL1) |
| { |
| if (!m_wpUseCommonKernel) |
| { |
| mbEncSurfaceParams.pWeightedPredOutputPicSelectList = &WeightedPredOutputPicSelectList[0]; |
| } |
| mbEncSurfaceParams.bUseWeightedSurfaceForL0 = bUseWeightedSurfaceForL0; |
| mbEncSurfaceParams.bUseWeightedSurfaceForL1 = bUseWeightedSurfaceForL1; |
| } |
| |
| // Clear the MAD buffer -- the kernel requires it to be 0 as it accumulates the result |
| if (mbEncSurfaceParams.bMADEnabled) |
| { |
| // set lock flag to WRITE_ONLY |
| MOS_LOCK_PARAMS lockFlags; |
| MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); |
| lockFlags.WriteOnly = 1; |
| |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, |
| mbEncSurfaceParams.presMADDataBuffer, |
| &lockFlags); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| MOS_ZeroMemory(data, CODECHAL_MAD_BUFFER_SIZE); |
| |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| mbEncSurfaceParams.presMADDataBuffer); |
| |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &m_resMadDataBuffer[m_currMadBufferIdx], |
| CodechalDbgAttr::attrOutput, |
| "MADRead", |
| CODECHAL_MAD_BUFFER_SIZE, |
| 0, |
| encFunctionType))); |
| } |
| |
| // static frame detection buffer |
| mbEncSurfaceParams.bStaticFrameDetectionEnabled = bStaticFrameDetectionEnable && m_hmeEnabled; |
| mbEncSurfaceParams.presSFDOutputBuffer = &resSFDOutputBuffer[0]; |
| if (m_pictureCodingType == P_TYPE) |
| { |
| mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTablePFrameBuffer; |
| } |
| else if (m_pictureCodingType == B_TYPE) |
| { |
| mbEncSurfaceParams.presSFDCostTableBuffer = &resSFDCostTableBFrameBuffer; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendAvcMbEncSurfaces(&cmdBuffer, &mbEncSurfaceParams)); |
| |
| // For MFE, only one walker processes frame in parallel through color bits. |
| if (!IsMfeMbEncEnabled(mbEncIFrameDistInUse) || m_mfeLastStream) |
| { |
| uint32_t resolutionX = mbEncIFrameDistInUse ? |
| m_downscaledWidthInMb4x : (uint32_t)m_picWidthInMb; |
| uint32_t resolutionY = mbEncIFrameDistInUse ? |
| m_downscaledFrameFieldHeightInMb4x : (uint32_t)m_frameFieldHeightInMb; |
| |
| CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; |
| MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); |
| walkerCodecParams.WalkerMode = m_walkerMode; |
| walkerCodecParams.bUseScoreboard = m_useHwScoreboard; |
| walkerCodecParams.wPictureCodingType = m_pictureCodingType; |
| walkerCodecParams.bMbEncIFrameDistInUse = mbEncIFrameDistInUse; |
| walkerCodecParams.bMbaff = m_mbaffEnabled; |
| walkerCodecParams.bDirectSpatialMVPredFlag = m_avcSliceParams->direct_spatial_mv_pred_flag; |
| walkerCodecParams.bColorbitSupported = (m_colorbitSupported && !m_arbitraryNumMbsInSlice) ? m_cmKernelEnable : false; |
| |
| if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| walkerCodecParams.dwNumSlices = m_mfeEncodeParams.submitNumber; // MFE use color bit to handle frames in parallel |
| walkerCodecParams.WalkerDegree = CODECHAL_26_DEGREE; // MFE use 26 degree dependency |
| walkerCodecParams.dwResolutionX = m_mfeEncodeSharedState->dwPicWidthInMB; |
| walkerCodecParams.dwResolutionY = m_mfeEncodeSharedState->dwPicHeightInMB; |
| walkerCodecParams.usSliceHeight = m_mfeEncodeSharedState->sliceHeight; |
| } |
| else |
| { |
| walkerCodecParams.dwResolutionX = resolutionX; |
| walkerCodecParams.dwResolutionY = resolutionY; |
| walkerCodecParams.dwNumSlices = m_numSlices; |
| walkerCodecParams.usSliceHeight = m_sliceHeight; |
| } |
| walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported; |
| walkerCodecParams.ucGroupId = m_groupId; |
| |
| MHW_WALKER_PARAMS walkerParams; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( |
| m_hwInterface, |
| &walkerParams, |
| &walkerCodecParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd( |
| &cmdBuffer, |
| &walkerParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); |
| |
| // Add dump for MBEnc surface state heap here |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_SSH_TYPE, |
| kernelState)); |
| ) |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( |
| m_stateHeapInterface, |
| kernelState)); |
| if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( |
| m_stateHeapInterface)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| encFunctionType, |
| nullptr))); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| if ((!m_singleTaskPhaseSupported || m_lastTaskInPhase)) |
| { |
| m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); |
| m_lastTaskInPhase = false; |
| } |
| } |
| |
| currRefList->ucMADBufferIdx = m_currMadBufferIdx; |
| currRefList->bMADEnabled = m_madEnabled; |
| |
| if (IsMfeMbEncEnabled(mbEncIFrameDistInUse)) |
| { |
| m_stateHeapInterface = m_origStateHeapInterface; |
| m_hwInterface = m_origHwInterface; |
| m_osInterface = m_origOsInterface; |
| |
| MbEncBindingTable = origMbEncBindingTable; |
| |
| CODECHAL_DEBUG_TOOL( |
| m_debugInterface->m_osInterface = m_osInterface;) |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetAndPopulateVEHintParams( |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (!MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| return eStatus; |
| } |
| |
| if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface)) |
| { |
| MOS_VIRTUALENGINE_SET_PARAMS vesetParams; |
| MOS_ZeroMemory(&vesetParams, sizeof(vesetParams)); |
| vesetParams.bNeedSyncWithPrevious = true; |
| vesetParams.bSFCInUse = false; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_SetHintParams(m_sinlgePipeVeState, &vesetParams)); |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_PopulateHintParams(m_sinlgePipeVeState, cmdBuffer, true)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SubmitCommandBuffer( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| int32_t nullRendering) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetAndPopulateVEHintParams(cmdBuffer)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, nullRendering)); |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::ExecuteKernelFunctions() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| auto slcParams = m_avcSliceParams; |
| auto slcType = Slice_Type[slcParams->slice_type]; |
| |
| CODECHAL_DEBUG_TOOL( |
| // CodecHal_DbgMapSurfaceFormatToDumpFormat(m_rawSurfaceToEnc->Format, &dumpType); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| m_rawSurfaceToEnc, |
| CodechalDbgAttr::attrEncodeRawInputSurface, |
| "SrcSurf"))); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscDsState); |
| |
| // Scaling, BRC Init/Reset and HME are included in the same task phase |
| m_lastEncPhase = false; |
| m_firstTaskInPhase = true; |
| |
| // BRC init/reset needs to be called before HME since it will reset the Brc Distortion surface |
| if (bBrcEnabled && (bBrcInit || bBrcReset)) |
| { |
| bool cscEnabled = m_cscDsState->RequireCsc() && m_firstField; |
| m_lastTaskInPhase = !(cscEnabled || m_scalingEnabled || m_16xMeSupported || m_hmeEnabled); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcInitResetKernel()); |
| } |
| |
| UpdateSSDSliceCount(); |
| |
| if (m_firstField) |
| { |
| // Csc, Downscaling, and/or 10-bit to 8-bit conversion |
| CodechalEncodeCscDs::KernelParams cscScalingKernelParams; |
| memset((void *)&cscScalingKernelParams, 0, sizeof(cscScalingKernelParams)); |
| cscScalingKernelParams.bLastTaskInPhaseCSC = |
| cscScalingKernelParams.bLastTaskInPhase4xDS = !(m_16xMeSupported || m_hmeEnabled); |
| cscScalingKernelParams.bLastTaskInPhase16xDS = !(m_32xMeSupported || m_hmeEnabled); |
| cscScalingKernelParams.bLastTaskInPhase32xDS = !m_hmeEnabled; |
| cscScalingKernelParams.inputColorSpace = m_avcSeqParam->InputColorSpace; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->KernelFunctions(&cscScalingKernelParams)); |
| } |
| |
| if (m_hmeKernel && m_hmeKernel->Is4xMeEnabled()) |
| { |
| CodechalKernelHme::CurbeParam curbeParam = {}; |
| curbeParam.subPelMode = 3; |
| curbeParam.currOriginalPic = m_avcPicParam->CurrOriginalPic; |
| curbeParam.qpPrimeY = m_avcPicParam->pic_init_qp_minus26 + 26 + m_avcSliceParams->slice_qp_delta; |
| curbeParam.targetUsage = m_avcSeqParam->TargetUsage; |
| curbeParam.maxMvLen = CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level); |
| curbeParam.numRefIdxL0Minus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1; |
| curbeParam.numRefIdxL1Minus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1; |
| |
| auto slcParams = m_avcSliceParams; |
| curbeParam.list0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0); |
| curbeParam.list0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1); |
| curbeParam.list0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2); |
| curbeParam.list0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3); |
| curbeParam.list0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4); |
| curbeParam.list0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5); |
| curbeParam.list0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6); |
| curbeParam.list0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7); |
| curbeParam.list1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0); |
| curbeParam.list1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1); |
| |
| CodechalKernelHme::SurfaceParams surfaceParam = {}; |
| surfaceParam.mbaffEnabled = m_mbaffEnabled; |
| surfaceParam.numRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1; |
| surfaceParam.numRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1; |
| surfaceParam.verticalLineStride = m_verticalLineStride; |
| surfaceParam.verticalLineStrideOffset = m_verticalLineStrideOffset; |
| surfaceParam.meBrcDistortionBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset; |
| surfaceParam.refList = &m_refList[0]; |
| surfaceParam.picIdx = &m_picIdx[0]; |
| surfaceParam.currOriginalPic = &m_currOriginalPic; |
| surfaceParam.refL0List = &(m_avcSliceParams->RefPicList[LIST_0][0]); |
| surfaceParam.refL1List = &(m_avcSliceParams->RefPicList[LIST_1][0]); |
| surfaceParam.meBrcDistortionBuffer = &BrcBuffers.sMeBrcDistortionBuffer; |
| |
| if (m_hmeKernel->Is16xMeEnabled()) |
| { |
| m_lastTaskInPhase = false; |
| if (m_hmeKernel->Is32xMeEnabled()) |
| { |
| surfaceParam.downScaledWidthInMb = m_downscaledWidthInMb32x; |
| surfaceParam.downScaledHeightInMb = m_downscaledFrameFieldHeightInMb32x; |
| surfaceParam.downScaledBottomFieldOffset = m_scaled32xBottomFieldOffset; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel32x)); |
| } |
| surfaceParam.downScaledWidthInMb = m_downscaledWidthInMb16x; |
| surfaceParam.downScaledHeightInMb = m_downscaledFrameFieldHeightInMb16x; |
| surfaceParam.downScaledBottomFieldOffset = m_scaled16xBottomFieldOffset; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel16x)); |
| } |
| surfaceParam.downScaledWidthInMb = m_downscaledWidthInMb4x; |
| surfaceParam.downScaledHeightInMb = m_downscaledFrameFieldHeightInMb4x; |
| surfaceParam.downScaledBottomFieldOffset = m_scaledBottomFieldOffset; |
| |
| m_lastTaskInPhase = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Execute(curbeParam, surfaceParam, CodechalKernelHme::HmeLevel::hmeLevel4x)); |
| } |
| |
| // Scaling and HME are not dependent on the output from PAK |
| if (m_waitForPak && m_semaphoreObjCount && !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse)) |
| { |
| // Wait on PAK |
| auto syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; |
| syncParams.uiSemaphoreCount = m_semaphoreObjCount; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| m_semaphoreObjCount = 0; //reset |
| } |
| |
| // BRC and MbEnc are included in the same task phase |
| m_lastEncPhase = true; |
| m_firstTaskInPhase = true; |
| |
| // Initialize software scoreboard used by MBEnc kernel |
| // Decide dependency pattern |
| CodechalEncodeSwScoreboard::KernelParams swScoreboardKernelParames; |
| memset((void *)&swScoreboardKernelParames, 0, sizeof(swScoreboardKernelParames)); |
| |
| if (m_pictureCodingType == I_TYPE || |
| (m_pictureCodingType == B_TYPE && !m_avcSliceParams->direct_spatial_mv_pred_flag)) // I or B-temporal |
| { |
| swScoreboardKernelParames.surfaceIndex = dependencyWavefront45Degree; |
| m_swScoreboardState->SetDependencyPattern(dependencyWavefront45Degree); |
| } |
| else //P or B-spatial |
| { |
| swScoreboardKernelParames.surfaceIndex = dependencyWavefront26Degree; |
| m_swScoreboardState->SetDependencyPattern(dependencyWavefront26Degree); |
| } |
| |
| m_swScoreboardState->SetCurSwScoreboardSurfaceIndex(swScoreboardKernelParames.surfaceIndex); |
| |
| // Call SW scoreboard Init kernel |
| swScoreboardKernelParames.scoreboardWidth = m_picWidthInMb; |
| swScoreboardKernelParames.scoreboardHeight = m_frameFieldHeightInMb; |
| swScoreboardKernelParames.swScoreboardSurfaceWidth = swScoreboardKernelParames.scoreboardWidth * 4; |
| swScoreboardKernelParames.swScoreboardSurfaceHeight = swScoreboardKernelParames.scoreboardHeight; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_swScoreboardState->Execute(&swScoreboardKernelParames)); |
| |
| // Dump BrcDist 4X_ME buffer here because it will be overwritten in BrcFrameUpdateKernel |
| CODECHAL_DEBUG_TOOL( |
| if (m_hmeEnabled && bBrcDistortionBufferSupported) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &BrcBuffers.sMeBrcDistortionBuffer.OsResource, |
| CodechalDbgAttr::attrOutput, |
| "BrcDist", |
| BrcBuffers.sMeBrcDistortionBuffer.dwPitch * BrcBuffers.sMeBrcDistortionBuffer.dwHeight, |
| BrcBuffers.dwMeBrcDistortionBottomFieldOffset, |
| CODECHAL_MEDIA_STATE_4X_ME)); |
| }) |
| |
| if (bBrcEnabled) |
| { |
| if (bMbEncIFrameDistEnabled) |
| { |
| CodechalKernelIntraDist::CurbeParam curbeParam; |
| curbeParam.downScaledWidthInMb4x = m_downscaledWidthInMb4x; |
| curbeParam.downScaledHeightInMb4x = m_downscaledFrameFieldHeightInMb4x; |
| CodechalKernelIntraDist::SurfaceParams surfaceParam; |
| surfaceParam.input4xDsSurface = |
| surfaceParam.input4xDsVmeSurface = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER); |
| surfaceParam.intraDistSurface = &BrcBuffers.sMeBrcDistortionBuffer; |
| surfaceParam.intraDistBottomFieldOffset = BrcBuffers.dwMeBrcDistortionBottomFieldOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_intraDistKernel->Execute(curbeParam, surfaceParam)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcFrameUpdateKernel()); |
| if (bBrcSplitEnable && bMbBrcEnabled) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(BrcMbUpdateKernel()); |
| } |
| |
| // Reset buffer ID used for BRC kernel performance reports |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| } |
| |
| bUseWeightedSurfaceForL0 = false; |
| bUseWeightedSurfaceForL1 = false; |
| |
| if (bWeightedPredictionSupported && |
| ((((slcType == SLICE_P) || (slcType == SLICE_SP)) && (m_avcPicParam->weighted_pred_flag)) || |
| (((slcType == SLICE_B)) && (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE)))) |
| { |
| uint8_t idx; |
| // Weighted Prediction to be applied for L0 |
| for (idx = 0; idx < (m_avcPicParam->num_ref_idx_l0_active_minus1 + 1); idx++) |
| { |
| if ((slcParams->luma_weight_flag[LIST_0] & (1 << idx)) && (idx < CODEC_AVC_MAX_FORWARD_WP_FRAME)) |
| { |
| //Weighted Prediction for ith forward reference frame |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(false, idx)); |
| } |
| } |
| |
| if (((slcType == SLICE_B)) && |
| (m_avcPicParam->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE)) |
| { |
| for (idx = 0; idx < (m_avcPicParam->num_ref_idx_l1_active_minus1 + 1); idx++) |
| { |
| // Weighted Pred to be applied for L1 |
| if ((slcParams->luma_weight_flag[LIST_1] & 1 << idx) && (idx < CODEC_AVC_MAX_BACKWARD_WP_FRAME)) |
| { |
| //Weighted Prediction for ith backward reference frame |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(WPKernel(false, idx)); |
| } |
| } |
| } |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| |
| MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData; |
| |
| // Weighted prediction for L0 Reporting |
| userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__; |
| userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL0; |
| userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L0_IN_USE_ID; |
| MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1); |
| |
| // Weighted prediction for L1 Reporting |
| userFeatureWriteData = __NULL_USER_FEATURE_VALUE_WRITE_DATA__; |
| userFeatureWriteData.Value.i32Data = bUseWeightedSurfaceForL1; |
| userFeatureWriteData.ValueID = __MEDIA_USER_FEATURE_VALUE_WEIGHTED_PREDICTION_L1_IN_USE_ID; |
| MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1); |
| |
| #endif // _DEBUG || _RELEASE_INTERNAL |
| |
| m_lastTaskInPhase = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(MbEncKernel(false)); |
| |
| // Reset buffer ID used for MbEnc kernel performance reports |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| |
| if (!Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse)) |
| { |
| auto syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); |
| } |
| |
| if (m_madEnabled) |
| { |
| m_currMadBufferIdx = (m_currMadBufferIdx + 1) % CODECHAL_ENCODE_MAX_NUM_MAD_BUFFERS; |
| } |
| |
| // Reset after BRC Init has been processed |
| bBrcInit = false; |
| |
| m_setRequestedEUSlices = false; |
| |
| CODECHAL_DEBUG_TOOL(KernelDebugDumps()); |
| |
| if (bBrcEnabled) |
| { |
| bMbEncCurbeSetInBrcUpdate = false; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::GenericEncodePictureLevel(PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| auto trellisQuantParams = &m_trellisQuantParams; |
| |
| PerfTagSetting perfTag; |
| perfTag.Value = 0; |
| perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; |
| perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE; |
| perfTag.PictureCodingType = m_pictureCodingType; |
| m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams; |
| MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS)); |
| forceWakeupParams.bMFXPowerWellControl = true; |
| forceWakeupParams.bMFXPowerWellControlMask = true; |
| forceWakeupParams.bHEVCPowerWellControl = false; |
| forceWakeupParams.bHEVCPowerWellControlMask = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd( |
| &cmdBuffer, |
| &forceWakeupParams)); |
| |
| // set MFX_PIPE_MODE_SELECT values |
| MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; |
| pipeModeSelectParams.Mode = m_mode; |
| pipeModeSelectParams.bStreamOutEnabled = (m_currPass != m_numPasses);// Disable Stream Out for final pass; its important for multiple passes, because , next pass will take the qp from stream out |
| |
| pipeModeSelectParams.bDeblockerStreamOutEnable = params->bDeblockerStreamOutEnable; |
| pipeModeSelectParams.bPostDeblockOutEnable = params->bPostDeblockOutEnable; |
| pipeModeSelectParams.bPreDeblockOutEnable = params->bPreDeblockOutEnable; |
| pipeModeSelectParams.bDynamicSliceEnable = m_avcSeqParam->EnableSliceLevelRateCtrl; |
| |
| // set MFX_PIPE_BUF_ADDR_STATE values |
| MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams; |
| pipeBufAddrParams.Mode = m_mode; |
| pipeBufAddrParams.psPreDeblockSurface = params->psPreDeblockSurface; |
| pipeBufAddrParams.psPostDeblockSurface = params->psPostDeblockSurface; |
| pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak; |
| pipeBufAddrParams.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx]; |
| pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer; |
| pipeBufAddrParams.presMfdIntraRowStoreScratchBuffer = &m_intraRowStoreScratchBuffer; |
| pipeBufAddrParams.presMacroblockIldbStreamOutBuffer1 = params->presMacroblockIldbStreamOutBuffer1; |
| pipeBufAddrParams.presMacroblockIldbStreamOutBuffer2 = params->presMacroblockIldbStreamOutBuffer2; |
| |
| CODECHAL_DEBUG_TOOL( |
| // PAK Input Raw Surface |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| m_rawSurfaceToPak, |
| CodechalDbgAttr::attrEncodeRawInputSurface, |
| "PAK_Input_SrcSurf")); |
| ) |
| |
| auto firstValidFrame = &m_reconSurface.OsResource; |
| |
| // Setting invalid entries to nullptr |
| for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) |
| { |
| pipeBufAddrParams.presReferences[i] = nullptr; |
| } |
| |
| uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME; |
| |
| for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) |
| { |
| if (m_picIdx[i].bValid) |
| { |
| uint8_t picIdx = m_picIdx[i].ucPicIdx; |
| uint8_t frameStoreId = m_refList[picIdx]->ucFrameId; |
| |
| CodecHalGetResourceInfo( |
| m_osInterface, |
| &(m_refList[picIdx]->sRefReconBuffer)); |
| pipeBufAddrParams.presReferences[frameStoreId] = |
| &(m_refList[picIdx]->sRefReconBuffer.OsResource); |
| |
| if (picIdx < firstValidFrameId) |
| { |
| firstValidFrameId = picIdx; |
| firstValidFrame = pipeBufAddrParams.presReferences[picIdx]; |
| } |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface); |
| MOS_SURFACE refSurface; |
| |
| MOS_ZeroMemory(&refSurface, sizeof(refSurface)); |
| refSurface.Format = Format_NV12; |
| refSurface.OsResource = *(pipeBufAddrParams.presReferences[frameStoreId]); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( |
| m_osInterface, |
| &refSurface)); |
| |
| m_debugInterface->m_refIndex = frameStoreId; |
| std::string refSurfName = "RefSurf" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &refSurface, |
| CodechalDbgAttr::attrReferenceSurfaces, |
| refSurfName.data()));) |
| } |
| } |
| |
| for (uint32_t i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++) |
| { |
| // error concealment for the unset reference addresses |
| if (!pipeBufAddrParams.presReferences[i]) |
| { |
| pipeBufAddrParams.presReferences[i] = firstValidFrame; |
| } |
| } |
| |
| if (m_sliceSizeStreamoutSupported) |
| { |
| pipeBufAddrParams.presSliceSizeStreamOutBuffer = &m_pakSliceSizeStreamoutBuffer; |
| } |
| |
| // set MFX_IND_OBJ_BASE_ADDR_STATE values |
| MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams; |
| MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams)); |
| indObjBaseAddrParams.Mode = CODECHAL_ENCODE_MODE_AVC; |
| |
| indObjBaseAddrParams.presMvObjectBuffer = &m_resMvDataSurface; |
| indObjBaseAddrParams.dwMvObjectOffset = m_mvBottomFieldOffset; |
| indObjBaseAddrParams.dwMvObjectSize = m_mvDataSize; |
| indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer; |
| indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound; |
| |
| // set MFX_BSP_BUF_BASE_ADDR_STATE values |
| MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams; |
| MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams)); |
| bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer; |
| |
| MHW_VDBOX_QM_PARAMS qmParams; |
| qmParams.Standard = CODECHAL_AVC; |
| qmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists; |
| |
| MHW_VDBOX_QM_PARAMS fqmParams; |
| fqmParams.Standard = CODECHAL_AVC; |
| fqmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIQWeightScaleLists; |
| |
| // Add AVC Direct Mode command |
| MHW_VDBOX_AVC_DIRECTMODE_PARAMS directmodeParams; |
| MOS_ZeroMemory(&directmodeParams, sizeof(directmodeParams)); |
| directmodeParams.CurrPic = m_avcPicParam->CurrReconstructedPic; |
| directmodeParams.isEncode = true; |
| directmodeParams.uiUsedForReferenceFlags = 0xFFFFFFFF; |
| directmodeParams.pAvcPicIdx = &(m_picIdx[0]); |
| directmodeParams.avcRefList = (void**)m_refList; |
| directmodeParams.bPicIdRemappingInUse = false; |
| directmodeParams.bDisableDmvBuffers = true; |
| |
| // PAK cmd buffer header insertion for 1) non STF 2) STF (except VDEnc BRC case inserted in HuC cmd buffer) |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| bool requestFrameTracking = false; |
| |
| m_hwInterface->m_numRequestedEuSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold && |
| m_targetUsage <= m_ssdTargetUsageThreshold) ? |
| m_sliceShutdownRequestState : m_sliceShutdownDefaultState; |
| |
| // Send command buffer header at the beginning (OS dependent) |
| // frame tracking tag is only added in the last command buffer header |
| requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); |
| |
| m_hwInterface->m_numRequestedEuSlices = CODECHAL_SLICE_SHUTDOWN_DEFAULT; |
| } |
| |
| if (m_currPass) |
| { |
| MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams; |
| // Insert conditional batch buffer end |
| MOS_ZeroMemory( |
| &miConditionalBatchBufferEndParams, |
| sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS)); |
| |
| miConditionalBatchBufferEndParams.presSemaphoreBuffer = |
| &m_encodeStatusBuf.resStatusBuffer; |
| miConditionalBatchBufferEndParams.dwOffset = |
| (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) + |
| m_encodeStatusBuf.dwImageStatusMaskOffset + |
| (sizeof(uint32_t) * 2); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd( |
| &cmdBuffer, |
| &miConditionalBatchBufferEndParams)); |
| } |
| |
| if (!m_currPass && m_osInterface->bTagResourceSync) |
| { |
| // This is a short term WA to solve the sync tag issue: the sync tag write for PAK is inserted at the end of 2nd pass PAK BB |
| // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning |
| // of the BB and keep the current frame's tag at the end of the BB. There will be a delay for tag update but it should be fine |
| // as long as Dec/VP/Enc won't depend on this PAK so soon. |
| MHW_MI_STORE_DATA_PARAMS params; |
| MOS_RESOURCE globalGpuContextSyncTagBuffer; |
| uint32_t value; |
| |
| CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource( |
| m_osInterface, |
| &globalGpuContextSyncTagBuffer)); |
| |
| value = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal); |
| params.pOsResource = &globalGpuContextSyncTagBuffer; |
| params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal); |
| params.dwValue = (value > 0) ? (value - 1) : 0; |
| CODECHAL_HW_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, ¶ms)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams)); |
| |
| // set MFX_SURFACE_STATE values |
| // Ref surface |
| MHW_VDBOX_SURFACE_PARAMS reconSurfaceParams; |
| MOS_ZeroMemory(&reconSurfaceParams, sizeof(reconSurfaceParams)); |
| reconSurfaceParams.Mode = m_mode; |
| reconSurfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID; |
| reconSurfaceParams.psSurface = &m_reconSurface; |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceState(&reconSurfaceParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &reconSurfaceParams)); |
| |
| // Src surface |
| MHW_VDBOX_SURFACE_PARAMS surfaceParams; |
| MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams)); |
| surfaceParams.Mode = m_mode; |
| surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID; |
| surfaceParams.psSurface = m_rawSurfaceToPak; |
| surfaceParams.bDisplayFormatSwizzle = m_avcPicParam->bDisplayFormatSwizzle; |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceState(&surfaceParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams)); |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetPipeBufAddr(&pipeBufAddrParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams)); |
| |
| if (params->bBrcEnabled && m_avcSeqParam->RateControlMethod != RATECONTROL_ICQ) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( |
| &cmdBuffer, |
| params->pImgStateBatchBuffer)); |
| } |
| else |
| { |
| //Set MFX_AVC_IMG_STATE command |
| MHW_VDBOX_AVC_IMG_PARAMS imageStateParams; |
| imageStateParams.ucCurrPass = m_currPass; |
| imageStateParams.pEncodeAvcPicParams = m_avcPicParam; |
| imageStateParams.pEncodeAvcSeqParams = m_avcSeqParam; |
| imageStateParams.pEncodeAvcSliceParams = m_avcSliceParams; |
| if (CodecHalIsFeiEncode(m_codecFunction) && m_avcFeiPicParams && m_avcFeiPicParams->dwMaxFrameSize) |
| { |
| imageStateParams.pDeltaQp = m_avcFeiPicParams->pDeltaQp; |
| imageStateParams.dwMaxFrameSize = m_avcFeiPicParams->dwMaxFrameSize; |
| } |
| imageStateParams.wPicWidthInMb = m_picWidthInMb; |
| imageStateParams.wPicHeightInMb = m_picHeightInMb; |
| imageStateParams.ppRefList = &(m_refList[0]); |
| imageStateParams.dwTqEnabled = trellisQuantParams->dwTqEnabled; |
| imageStateParams.dwTqRounding = trellisQuantParams->dwTqRounding; |
| imageStateParams.ucKernelMode = m_kernelMode; |
| imageStateParams.wSlcHeightInMb = m_sliceHeight; |
| imageStateParams.dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level); |
| imageStateParams.bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported; |
| |
| if (m_currPass && (m_currPass == m_numPasses)) |
| { |
| // Enable IPCM pass, excluding VDENC BRC case |
| imageStateParams.bIPCMPass = true; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(&cmdBuffer, nullptr, &imageStateParams)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam( |
| &cmdBuffer, |
| nullptr)); |
| ) |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(&cmdBuffer, &directmodeParams)); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SceneChangeReport(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS params) |
| { |
| |
| MHW_MI_COPY_MEM_MEM_PARAMS copyMemMemParams; |
| uint32_t offset = (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) |
| + (sizeof(uint32_t) * 2) + m_encodeStatusBuf.dwSceneChangedOffset; |
| |
| MOS_ZeroMemory(©MemMemParams, sizeof(copyMemMemParams)); |
| copyMemMemParams.presSrc = params->presBrcHistoryBuffer; |
| copyMemMemParams.dwSrcOffset = brcHistoryBufferOffsetSceneChanged; |
| copyMemMemParams.presDst = &m_encodeStatusBuf.resStatusBuffer; |
| copyMemMemParams.dwDstOffset = offset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd( |
| cmdBuffer, |
| ©MemMemParams)); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitializeState() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcEnc::InitializeState()); |
| |
| m_brcHistoryBufferSize = m_initBrcHistoryBufferSize; |
| m_mbencBrcBufferSize = m_initMbencBrcBufferSize; |
| m_forceBrcMbStatsEnabled = true; |
| m_useHwScoreboard = false; |
| |
| dwBrcConstantSurfaceWidth = m_brcConstantsurfaceWidth; |
| dwBrcConstantSurfaceHeight = m_brcConstantsurfaceHeight; |
| |
| // create intra distortion kernel |
| m_intraDistKernel = MOS_New(CodechalKernelIntraDist, this); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_intraDistKernel); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_intraDistKernel->Initialize( |
| GetCommonKernelHeaderAndSizeG12, |
| m_kernelBase, |
| m_kuidCommon)); |
| |
| // Create SW scoreboard init kernel state |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_swScoreboardState = MOS_New(CodechalEncodeSwScoreboardG12, this)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_swScoreboardState->InitKernelState()); |
| |
| if (MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| m_sinlgePipeVeState = (PCODECHAL_ENCODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_ENCODE_SINGLEPIPE_VIRTUALENGINE_STATE)); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_sinlgePipeVeState); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_InitInterface(m_hwInterface, m_sinlgePipeVeState)); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitMmcState() |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| #ifdef _MMC_SUPPORTED |
| m_mmcState = MOS_New(CodechalMmcEncodeAvcG12, m_hwInterface, this); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState); |
| #endif |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateBrc() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| uint8_t* kernelBinary; |
| uint32_t kernelSize; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, m_kuid, &kernelBinary, &kernelSize)); |
| |
| CODECHAL_KERNEL_HEADER currKrnHeader; |
| for (uint32_t krnStateIdx = 0; krnStateIdx < CODECHAL_ENCODE_BRC_IDX_NUM; krnStateIdx++) |
| { |
| auto kernelStatePtr = &BrcKernelStates[krnStateIdx]; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetKernelHeaderAndSize( |
| kernelBinary, |
| ENC_BRC, |
| krnStateIdx, |
| (void*)&currKrnHeader, |
| &kernelSize)); |
| |
| kernelStatePtr->KernelParams.iBTCount = m_brcBTCounts[krnStateIdx]; |
| kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads; |
| kernelStatePtr->KernelParams.iCurbeLength = m_brcCurbeSize[krnStateIdx]; |
| kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH; |
| kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT; |
| kernelStatePtr->KernelParams.iIdCount = 1; |
| |
| kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData(); |
| kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); |
| kernelStatePtr->KernelParams.iSize = kernelSize; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested( |
| m_stateHeapInterface, |
| kernelStatePtr->KernelParams.iBTCount, |
| &kernelStatePtr->dwSshSize, |
| &kernelStatePtr->dwBindingTableSize)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr)); |
| } |
| |
| // Until a better way can be found, maintain old binding table structures |
| auto bindingTable = &BrcUpdateBindingTable; |
| bindingTable->dwFrameBrcHistoryBuffer = frameBrcUpdateHistory; |
| bindingTable->dwFrameBrcPakStatisticsOutputBuffer = frameBrcUpdatePakStatisticsOutput; |
| bindingTable->dwFrameBrcImageStateReadBuffer = frameBrcUpdateImageStateRead; |
| bindingTable->dwFrameBrcImageStateWriteBuffer = frameBrcUpdateImageStateWrite; |
| |
| bindingTable->dwFrameBrcMbEncCurbeWriteData = frameBrcUpdateMbencCurbeWrite; |
| bindingTable->dwFrameBrcDistortionBuffer = frameBrcUpdateDistortion; |
| bindingTable->dwFrameBrcConstantData = frameBrcUpdateConstantData; |
| bindingTable->dwFrameBrcMbStatBuffer = frameBrcUpdateMbStat; |
| bindingTable->dwFrameBrcMvDataBuffer = frameBrcUpdateMvStat; |
| |
| bindingTable->dwMbBrcHistoryBuffer = mbBrcUpdateHistory; |
| bindingTable->dwMbBrcMbQpBuffer = mbBrcUpdateMbQp; |
| bindingTable->dwMbBrcROISurface = mbBrcUpdateRoi; |
| bindingTable->dwMbBrcMbStatBuffer = mbBrcUpdateMbStat; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::GetTrellisQuantization( |
| PCODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS params, |
| PCODECHAL_ENCODE_AVC_TQ_PARAMS trellisQuantParams) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(trellisQuantParams); |
| |
| trellisQuantParams->dwTqEnabled = TrellisQuantizationEnable[params->ucTargetUsage]; |
| trellisQuantParams->dwTqRounding = |
| trellisQuantParams->dwTqEnabled ? trellisQuantizationRounding[params->ucTargetUsage] : 0; |
| |
| // If AdaptiveTrellisQuantization is enabled then disable trellis quantization for |
| // B-frames with QP > 26 only in CQP mode |
| if (trellisQuantParams->dwTqEnabled && EnableAdaptiveTrellisQuantization[params->ucTargetUsage] && |
| params->wPictureCodingType == B_TYPE && !params->bBrcEnabled && params->ucQP > 26) |
| { |
| trellisQuantParams->dwTqEnabled = 0; |
| trellisQuantParams->dwTqRounding = 0; |
| } |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::GetMbEncKernelStateIdx(CodechalEncodeIdOffsetParams* params, uint32_t* kernelOffset) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(kernelOffset); |
| |
| *kernelOffset = mbencIOffset; |
| |
| if (params->EncFunctionType == CODECHAL_MEDIA_STATE_ENC_ADV) |
| { |
| *kernelOffset += m_mbencNumTargetUsages * mbencFrameTypeNum; |
| } |
| else |
| { |
| if (params->EncFunctionType == CODECHAL_MEDIA_STATE_ENC_NORMAL) |
| { |
| *kernelOffset += mbencFrameTypeNum; |
| } |
| else if (params->EncFunctionType == CODECHAL_MEDIA_STATE_ENC_PERFORMANCE) |
| { |
| *kernelOffset += mbencFrameTypeNum * 2; |
| } |
| } |
| |
| if (params->wPictureCodingType == P_TYPE) |
| { |
| *kernelOffset += mbencPOffset; |
| } |
| else if (params->wPictureCodingType == B_TYPE) |
| { |
| *kernelOffset += mbencBOffset; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateMbEnc() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| dwNumMbEncEncKrnStates = m_mbencNumTargetUsages * mbencFrameTypeNum; |
| dwNumMbEncEncKrnStates += mbencFrameTypeNum; |
| pMbEncKernelStates = MOS_NewArray(MHW_KERNEL_STATE, dwNumMbEncEncKrnStates); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pMbEncKernelStates); |
| |
| auto kernelStatePtr = pMbEncKernelStates; |
| |
| uint8_t* kernelBinary; |
| uint32_t kernelSize; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, m_kuid, &kernelBinary, &kernelSize)); |
| CODECHAL_KERNEL_HEADER currKrnHeader; |
| |
| for (uint32_t krnStateIdx = 0; krnStateIdx < dwNumMbEncEncKrnStates; krnStateIdx++) |
| { |
| bool kernelState = (krnStateIdx >= m_mbencNumTargetUsages * mbencFrameTypeNum); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetKernelHeaderAndSize( |
| kernelBinary, |
| (kernelState ? ENC_MBENC_ADV : ENC_MBENC), |
| (kernelState ? krnStateIdx - m_mbencNumTargetUsages * mbencFrameTypeNum : krnStateIdx), |
| &currKrnHeader, |
| &kernelSize)); |
| |
| kernelStatePtr->KernelParams.iBTCount = mbencNumSurfaces; |
| kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads; |
| kernelStatePtr->KernelParams.iCurbeLength = sizeof(CodechalEncodeAvcEncG12::MbencCurbe); |
| kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH; |
| kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT; |
| kernelStatePtr->KernelParams.iIdCount = 1; |
| |
| kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData(); |
| kernelStatePtr->KernelParams.pBinary = |
| kernelBinary + |
| (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); |
| kernelStatePtr->KernelParams.iSize = kernelSize; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested( |
| m_stateHeapInterface, |
| kernelStatePtr->KernelParams.iBTCount, |
| &kernelStatePtr->dwSshSize, |
| &kernelStatePtr->dwBindingTableSize)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr)); |
| |
| kernelStatePtr++; |
| } |
| |
| // Until a better way can be found, maintain old binding table structures |
| auto bindingTable = &MbEncBindingTable; |
| |
| bindingTable->dwAvcMBEncMfcAvcPakObj = mbencMfcAvcPakObj; |
| bindingTable->dwAvcMBEncIndMVData = mbencIndMvData; |
| bindingTable->dwAvcMBEncBRCDist = mbencBrcDistortion; |
| bindingTable->dwAvcMBEncCurrY = mbencCurrY; |
| bindingTable->dwAvcMBEncCurrUV = mbencCurrUv; |
| bindingTable->dwAvcMBEncMbSpecificData = mbencMbSpecificData; |
| |
| bindingTable->dwAvcMBEncRefPicSelectL0 = mbencRefpicselectL0; |
| bindingTable->dwAvcMBEncMVDataFromME = mbencMvDataFromMe; |
| bindingTable->dwAvcMBEncMEDist = mbenc4xMeDistortion; |
| bindingTable->dwAvcMBEncSliceMapData = mbencSlicemapData; |
| bindingTable->dwAvcMBEncBwdRefMBData = mbencFwdMbData; |
| bindingTable->dwAvcMBEncBwdRefMVData = mbencFwdMvData; |
| bindingTable->dwAvcMBEncMbBrcConstData = mbencMbbrcConstData; |
| bindingTable->dwAvcMBEncMBStats = mbencMbStats; |
| bindingTable->dwAvcMBEncMADData = mbencMadData; |
| bindingTable->dwAvcMBEncMbNonSkipMap = mbencForceNonskipMbMap; |
| bindingTable->dwAvcMBEncAdv = mbEncAdv; |
| bindingTable->dwAvcMbEncBRCCurbeData = mbencBrcCurbeData; |
| bindingTable->dwAvcMBEncStaticDetectionCostTable = mbencSfdCostTable; |
| |
| // Frame |
| bindingTable->dwAvcMBEncMbQpFrame = mbencMbqp; |
| bindingTable->dwAvcMBEncCurrPicFrame[0] = mbencVmeInterPredCurrPicIdx0; |
| bindingTable->dwAvcMBEncFwdPicFrame[0] = mbencVmeInterPredFwdPicIDX0; |
| bindingTable->dwAvcMBEncBwdPicFrame[0] = mbencVmeInterPredBwdPicIDX00; |
| bindingTable->dwAvcMBEncFwdPicFrame[1] = mbencVmeInterPredFwdPicIDX1; |
| bindingTable->dwAvcMBEncBwdPicFrame[1] = mbencVmeInterPredBwdPicIDX10; |
| bindingTable->dwAvcMBEncFwdPicFrame[2] = mbencVmeInterPredFwdPicIDX2; |
| bindingTable->dwAvcMBEncFwdPicFrame[3] = mbencVmeInterPredFwdPicIDX3; |
| bindingTable->dwAvcMBEncFwdPicFrame[4] = mbencVmeInterPredFwdPicIDX4; |
| bindingTable->dwAvcMBEncFwdPicFrame[5] = mbencVmeInterPredFwdPicIDX5; |
| bindingTable->dwAvcMBEncFwdPicFrame[6] = mbencVmeInterPredFwdPicIDX6; |
| bindingTable->dwAvcMBEncFwdPicFrame[7] = mbencVmeInterPredFwdPicIDX7; |
| bindingTable->dwAvcMBEncCurrPicFrame[1] = mbencVmeInterPredCurrPicIdx1; |
| bindingTable->dwAvcMBEncBwdPicFrame[2] = mbencVmeInterPredBwdPicIDX01; |
| bindingTable->dwAvcMBEncBwdPicFrame[3] = mbencVmeInterPredBwdPicIDX11; |
| |
| // Field |
| bindingTable->dwAvcMBEncMbQpField = mbencMbqp; |
| bindingTable->dwAvcMBEncFieldCurrPic[0] = mbencVmeInterPredCurrPicIdx0; |
| bindingTable->dwAvcMBEncFwdPicTopField[0] = mbencVmeInterPredFwdPicIDX0; |
| bindingTable->dwAvcMBEncBwdPicTopField[0] = mbencVmeInterPredBwdPicIDX00; |
| bindingTable->dwAvcMBEncFwdPicBotField[0] = mbencVmeInterPredFwdPicIDX0; |
| bindingTable->dwAvcMBEncBwdPicBotField[0] = mbencVmeInterPredBwdPicIDX00; |
| bindingTable->dwAvcMBEncFwdPicTopField[1] = mbencVmeInterPredFwdPicIDX1; |
| bindingTable->dwAvcMBEncBwdPicTopField[1] = mbencVmeInterPredBwdPicIDX10; |
| bindingTable->dwAvcMBEncFwdPicBotField[1] = mbencVmeInterPredFwdPicIDX1; |
| bindingTable->dwAvcMBEncBwdPicBotField[1] = mbencVmeInterPredBwdPicIDX10; |
| bindingTable->dwAvcMBEncFwdPicTopField[2] = mbencVmeInterPredFwdPicIDX2; |
| bindingTable->dwAvcMBEncFwdPicBotField[2] = mbencVmeInterPredFwdPicIDX2; |
| bindingTable->dwAvcMBEncFwdPicTopField[3] = mbencVmeInterPredFwdPicIDX3; |
| bindingTable->dwAvcMBEncFwdPicBotField[3] = mbencVmeInterPredFwdPicIDX3; |
| bindingTable->dwAvcMBEncFwdPicTopField[4] = mbencVmeInterPredFwdPicIDX4; |
| bindingTable->dwAvcMBEncFwdPicBotField[4] = mbencVmeInterPredFwdPicIDX4; |
| bindingTable->dwAvcMBEncFwdPicTopField[5] = mbencVmeInterPredFwdPicIDX5; |
| bindingTable->dwAvcMBEncFwdPicBotField[5] = mbencVmeInterPredFwdPicIDX5; |
| bindingTable->dwAvcMBEncFwdPicTopField[6] = mbencVmeInterPredFwdPicIDX6; |
| bindingTable->dwAvcMBEncFwdPicBotField[6] = mbencVmeInterPredFwdPicIDX6; |
| bindingTable->dwAvcMBEncFwdPicTopField[7] = mbencVmeInterPredFwdPicIDX7; |
| bindingTable->dwAvcMBEncFwdPicBotField[7] = mbencVmeInterPredFwdPicIDX7; |
| bindingTable->dwAvcMBEncFieldCurrPic[1] = mbencVmeInterPredCurrPicIdx1; |
| bindingTable->dwAvcMBEncBwdPicTopField[2] = mbencVmeInterPredBwdPicIDX01; |
| bindingTable->dwAvcMBEncBwdPicBotField[2] = mbencVmeInterPredBwdPicIDX01; |
| bindingTable->dwAvcMBEncBwdPicTopField[3] = mbencVmeInterPredBwdPicIDX11; |
| bindingTable->dwAvcMBEncBwdPicBotField[3] = mbencVmeInterPredBwdPicIDX11; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitMbBrcConstantDataBuffer(PCODECHAL_ENCODE_AVC_INIT_MBBRC_CONSTANT_DATA_BUFFER_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOsInterface); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->presBrcConstantDataBuffer); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcEnc::InitMbBrcConstantDataBuffer(params)); |
| |
| if (params->wPictureCodingType == I_TYPE) |
| { |
| MOS_LOCK_PARAMS lockFlags; |
| memset(&lockFlags, 0, sizeof(MOS_LOCK_PARAMS)); |
| lockFlags.WriteOnly = 1; |
| |
| uint32_t *dataPtr = (uint32_t *)params->pOsInterface->pfnLockResource( |
| params->pOsInterface, |
| params->presBrcConstantDataBuffer, |
| &lockFlags); |
| if (dataPtr == nullptr) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| return eStatus; |
| } |
| |
| // Update MbBrcConstantDataBuffer with high texture cost |
| for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++) |
| { |
| // Writing to DW13 in each sub-array of 16 DWs |
| *(dataPtr + 13) = (uint32_t)m_intraModeCostForHighTextureMB[qp]; |
| // 16 DWs per QP value |
| dataPtr += 16; |
| } |
| |
| params->pOsInterface->pfnUnlockResource( |
| params->pOsInterface, |
| params->presBrcConstantDataBuffer); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateWP() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| pWPKernelState = MOS_New(MHW_KERNEL_STATE); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pWPKernelState); |
| |
| auto kernelStatePtr = pWPKernelState; |
| |
| uint8_t* kernelBinary; |
| uint32_t kernelSize; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetKernelBinaryAndSize(m_kernelBase, m_kuid, &kernelBinary, &kernelSize)); |
| |
| CODECHAL_KERNEL_HEADER currKrnHeader; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize( |
| kernelBinary, |
| ENC_WP, |
| 0, |
| &currKrnHeader, |
| &kernelSize)); |
| kernelStatePtr->KernelParams.iBTCount = wpNumSurfaces; |
| kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads; |
| kernelStatePtr->KernelParams.iCurbeLength = sizeof(CodechalEncodeAvcEncG12::WpCurbe); |
| kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH; |
| kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT; |
| kernelStatePtr->KernelParams.iIdCount = 1; |
| kernelStatePtr->KernelParams.iInlineDataLength = 0; |
| |
| kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData(); |
| kernelStatePtr->KernelParams.pBinary = kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT); |
| kernelStatePtr->KernelParams.iSize = kernelSize; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested( |
| m_stateHeapInterface, |
| kernelStatePtr->KernelParams.iBTCount, |
| &kernelStatePtr->dwSshSize, |
| &kernelStatePtr->dwBindingTableSize)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitBrcConstantBuffer(PCODECHAL_ENCODE_AVC_INIT_BRC_CONSTANT_BUFFER_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOsInterface); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams); |
| |
| uint8_t tableIdx = params->wPictureCodingType - 1; |
| |
| if (tableIdx >= 3) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Invalid input parameter."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| MOS_LOCK_PARAMS lockFlags; |
| memset(&lockFlags, 0, sizeof(MOS_LOCK_PARAMS)); |
| lockFlags.WriteOnly = 1; |
| auto dataPtr = (uint8_t*)params->pOsInterface->pfnLockResource( |
| params->pOsInterface, |
| ¶ms->sBrcConstantDataBuffer.OsResource, |
| &lockFlags); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dataPtr); |
| |
| memset(dataPtr, 0, params->sBrcConstantDataBuffer.dwWidth * params->sBrcConstantDataBuffer.dwHeight); |
| |
| // Fill surface with QP Adjustment table, Distortion threshold table, MaxFrame threshold table, Distortion QP Adjustment Table |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| sizeof(m_QPAdjustmentDistThresholdMaxFrameThresholdIPB), |
| (void*)m_QPAdjustmentDistThresholdMaxFrameThresholdIPB, |
| sizeof(m_QPAdjustmentDistThresholdMaxFrameThresholdIPB)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| |
| dataPtr += sizeof(m_QPAdjustmentDistThresholdMaxFrameThresholdIPB); |
| |
| bool blockBasedSkipEn = params->dwMbEncBlockBasedSkipEn ? true : false; |
| bool transform_8x8_mode_flag = params->pPicParams->transform_8x8_mode_flag ? true : false; |
| |
| // Fill surface with Skip Threshold Table |
| switch (params->wPictureCodingType) |
| { |
| case P_TYPE: |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceEarlySkipTableSize, |
| (void*)&SkipVal_P_Common[blockBasedSkipEn][transform_8x8_mode_flag][0], |
| m_brcConstantsurfaceEarlySkipTableSize); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| break; |
| case B_TYPE: |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceEarlySkipTableSize, |
| (void*)&SkipVal_B_Common[blockBasedSkipEn][transform_8x8_mode_flag][0], |
| m_brcConstantsurfaceEarlySkipTableSize); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| break; |
| default: |
| // do nothing for I TYPE |
| break; |
| } |
| |
| if ((params->wPictureCodingType != I_TYPE) && (params->pAvcQCParams != nullptr) && (params->pAvcQCParams->NonFTQSkipThresholdLUTInput)) |
| { |
| for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++) |
| { |
| *(dataPtr + 1 + (qp * 2)) = (uint8_t)CalcSkipVal((params->dwMbEncBlockBasedSkipEn ? true : false), |
| (params->pPicParams->transform_8x8_mode_flag ? true : false), |
| params->pAvcQCParams->NonFTQSkipThresholdLUT[qp]); |
| } |
| } |
| |
| dataPtr += m_brcConstantsurfaceEarlySkipTableSize; |
| |
| // Fill surface with QP list |
| |
| // Initialize to -1 (0xff) |
| memset(dataPtr, 0xff, m_brcConstantsurfaceQpList0); |
| memset(dataPtr + m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved, |
| 0xff, m_brcConstantsurfaceQpList1); |
| |
| switch (params->wPictureCodingType) |
| { |
| case B_TYPE: |
| dataPtr += (m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved); |
| |
| for (uint8_t refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l1_active_minus1; refIdx++) |
| { |
| CODEC_PICTURE refPic = params->pAvcSlcParams->RefPicList[LIST_1][refIdx]; |
| if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid) |
| { |
| *(dataPtr + refIdx) = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx; |
| } |
| } |
| dataPtr -= (m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved); |
| // break statement omitted intentionally |
| case P_TYPE: |
| for (uint8_t refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l0_active_minus1; refIdx++) |
| { |
| CODEC_PICTURE refPic = params->pAvcSlcParams->RefPicList[LIST_0][refIdx]; |
| if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid) |
| { |
| *(dataPtr + refIdx) = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx; |
| } |
| } |
| break; |
| default: |
| // do nothing for I type |
| break; |
| } |
| |
| dataPtr += (m_brcConstantsurfaceQpList0 + m_brcConstantsurfaceQpList0Reserved + |
| m_brcConstantsurfaceQpList1 + m_brcConstantsurfaceQpList1Reserved); |
| |
| // Fill surface with Mode cost and MV cost |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceModeMvCostSize, |
| (void*)ModeMvCost_Cm[tableIdx], |
| m_brcConstantsurfaceModeMvCostSize); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| |
| // If old mode cost is used the update the table |
| if (params->wPictureCodingType == I_TYPE && params->bOldModeCostEnable) |
| { |
| auto dataTemp = (uint32_t *)dataPtr; |
| for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++) |
| { |
| // Writing to DW0 in each sub-array of 16 DWs |
| *dataTemp = (uint32_t)OldIntraModeCost_Cm_Common[qp]; |
| dataTemp += 16; |
| } |
| } |
| |
| if (params->pAvcQCParams) |
| { |
| for (uint8_t qp = 0; qp < CODEC_AVC_NUM_QP; qp++) |
| { |
| if (params->pAvcQCParams->FTQSkipThresholdLUTInput) |
| { |
| // clang-format off |
| *(dataPtr + (qp * 32) + 24) = |
| *(dataPtr + (qp * 32) + 25) = |
| *(dataPtr + (qp * 32) + 27) = |
| *(dataPtr + (qp * 32) + 28) = |
| *(dataPtr + (qp * 32) + 29) = |
| *(dataPtr + (qp * 32) + 30) = |
| *(dataPtr + (qp * 32) + 31) = params->pAvcQCParams->FTQSkipThresholdLUT[qp]; |
| // clang-format on |
| } |
| } |
| } |
| |
| dataPtr += m_brcConstantsurfaceModeMvCostSize; |
| |
| // Fill surface with Refcost |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceRefcostSize, |
| (void*)&m_refCostMultiRefQp[tableIdx][0], |
| m_brcConstantsurfaceRefcostSize); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| dataPtr += m_brcConstantsurfaceRefcostSize; |
| |
| //Fill surface with Intra cost scaling Factor |
| if (params->bAdaptiveIntraScalingEnable) |
| { |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceIntracostScalingFactor, |
| (void*)&AdaptiveIntraScalingFactor_Cm_Common[0], |
| m_brcConstantsurfaceIntracostScalingFactor); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| } |
| else |
| { |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceIntracostScalingFactor, |
| (void*)&IntraScalingFactor_Cm_Common[0], |
| m_brcConstantsurfaceIntracostScalingFactor); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| } |
| |
| dataPtr += m_brcConstantsurfaceIntracostScalingFactor; |
| |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceLambdaSize, |
| (void*)&m_lambdaData[0], |
| m_brcConstantsurfaceLambdaSize); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| |
| dataPtr += m_brcConstantsurfaceLambdaSize; |
| |
| eStatus = MOS_SecureMemcpy( |
| dataPtr, |
| m_brcConstantsurfaceFtq25Size, |
| (void*)&m_ftQ25[0], |
| m_brcConstantsurfaceFtq25Size); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| |
| params->pOsInterface->pfnUnlockResource( |
| params->pOsInterface, |
| ¶ms->sBrcConstantDataBuffer.OsResource); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcMbEnc(PCODECHAL_ENCODE_AVC_MBENC_CURBE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pPicParams); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSlcParams); |
| |
| auto picParams = params->pPicParams; |
| auto seqParams = params->pSeqParams; |
| auto slcParams = params->pSlcParams; |
| |
| CODECHAL_ENCODE_ASSERT(seqParams->TargetUsage < NUM_TARGET_USAGE_MODES); |
| |
| uint8_t meMethod = (m_pictureCodingType == B_TYPE) ? m_bMeMethodGeneric[seqParams->TargetUsage] : m_meMethodGeneric[seqParams->TargetUsage]; |
| // set sliceQP to MAX_SLICE_QP for MbEnc kernel, we can use it to verify whether QP is changed or not |
| uint8_t sliceQP = (params->bUseMbEncAdvKernel && params->bBrcEnabled) ? CODECHAL_ENCODE_AVC_MAX_SLICE_QP : picParams->pic_init_qp_minus26 + 26 + slcParams->slice_qp_delta; |
| bool framePicture = CodecHal_PictureIsFrame(picParams->CurrOriginalPic); |
| bool bottomField = CodecHal_PictureIsBottomField(picParams->CurrOriginalPic); |
| |
| CodechalEncodeAvcEncG12::MbencCurbe::MBEncCurbeInitType curbeInitType; |
| if (params->bMbEncIFrameDistEnabled) |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeIDist; |
| } |
| else |
| { |
| switch (m_pictureCodingType) |
| { |
| case I_TYPE: |
| if (framePicture) |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeIFrame; |
| } |
| else |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeIField; |
| } |
| break; |
| |
| case P_TYPE: |
| if (framePicture) |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typePFrame; |
| } |
| else |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typePField; |
| } |
| break; |
| case B_TYPE: |
| if (framePicture) |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeBFrame; |
| } |
| else |
| { |
| curbeInitType = CodechalEncodeAvcEncG12::MbencCurbe::typeBField; |
| } |
| break; |
| default: |
| CODECHAL_ENCODE_ASSERTMESSAGE("Invalid picture coding type."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| return eStatus; |
| } |
| } |
| |
| CodechalEncodeAvcEncG12::MbencCurbe cmd; |
| cmd.SetDefaultMbencCurbe(curbeInitType); |
| // r1 |
| cmd.m_curbe.DW0.m_adaptiveEn = |
| cmd.m_curbe.DW37.m_adaptiveEn = EnableAdaptiveSearch[seqParams->TargetUsage]; |
| cmd.m_curbe.DW0.m_t8x8FlagForInterEn = |
| cmd.m_curbe.DW37.m_t8x8FlagForInterEn = picParams->transform_8x8_mode_flag; |
| cmd.m_curbe.DW2.m_lenSP = MaxLenSP[seqParams->TargetUsage]; |
| |
| cmd.m_curbe.DW1.m_extendedMvCostRange = bExtendedMvCostRange; |
| cmd.m_curbe.DW36.m_mbInputEnable = bMbSpecificDataEnabled; |
| |
| cmd.m_curbe.DW38.m_lenSP = 0; // MBZ |
| cmd.m_curbe.DW3.m_srcAccess = |
| cmd.m_curbe.DW3.m_refAccess = framePicture ? 0 : 1; |
| if (m_pictureCodingType != I_TYPE && bFTQEnable) |
| { |
| if (m_pictureCodingType == P_TYPE) |
| { |
| cmd.m_curbe.DW3.m_fTEnable = FTQBasedSkip[seqParams->TargetUsage] & 0x01; |
| } |
| else // B_TYPE |
| { |
| cmd.m_curbe.DW3.m_fTEnable = (FTQBasedSkip[seqParams->TargetUsage] >> 1) & 0x01; |
| } |
| } |
| else |
| { |
| cmd.m_curbe.DW3.m_fTEnable = 0; |
| } |
| if (picParams->UserFlags.bDisableSubMBPartition) |
| { |
| cmd.m_curbe.DW3.m_subMbPartMask = CODECHAL_ENCODE_AVC_DISABLE_4X4_SUB_MB_PARTITION | CODECHAL_ENCODE_AVC_DISABLE_4X8_SUB_MB_PARTITION | CODECHAL_ENCODE_AVC_DISABLE_8X4_SUB_MB_PARTITION; |
| } |
| cmd.m_curbe.DW2.m_picWidth = params->wPicWidthInMb; |
| cmd.m_curbe.DW4.m_picHeightMinus1 = params->wFieldFrameHeightInMb - 1; |
| cmd.m_curbe.DW4.m_fieldParityFlag = cmd.m_curbe.DW7.m_srcFieldPolarity = bottomField ? 1 : 0; |
| cmd.m_curbe.DW4.m_enableFBRBypass = bFBRBypassEnable; |
| cmd.m_curbe.DW4.m_enableIntraCostScalingForStaticFrame = params->bStaticFrameDetectionEnabled; |
| cmd.m_curbe.DW4.m_bCurFldIDR = framePicture ? 0 : (picParams->bIdrPic || m_firstFieldIdrPic); |
| cmd.m_curbe.DW4.m_constrainedIntraPredFlag = picParams->constrained_intra_pred_flag; |
| cmd.m_curbe.DW4.m_hmeEnable = m_hmeEnabled; |
| cmd.m_curbe.DW4.m_pictureType = m_pictureCodingType - 1; |
| cmd.m_curbe.DW4.m_useActualRefQPValue = m_hmeEnabled ? (m_multiRefDisableQPCheck[seqParams->TargetUsage] == 0) : false; |
| cmd.m_curbe.DW5.m_sliceMbHeight = params->usSliceHeight; |
| cmd.m_curbe.DW7.m_intraPartMask = picParams->transform_8x8_mode_flag ? 0 : 0x2; // Disable 8x8 if flag is not set |
| |
| // r2 |
| if (params->bMbEncIFrameDistEnabled) |
| { |
| cmd.m_curbe.DW6.m_batchBufferEnd = 0; |
| } |
| else |
| { |
| uint8_t tableIdx = m_pictureCodingType - 1; |
| eStatus = MOS_SecureMemcpy(&(cmd.m_curbe.ModeMvCost), 8 * sizeof(uint32_t), ModeMvCost_Cm[tableIdx][sliceQP], 8 * sizeof(uint32_t)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| |
| if (m_pictureCodingType == I_TYPE && bOldModeCostEnable) |
| { |
| // Old intra mode cost needs to be used if bOldModeCostEnable is 1 |
| cmd.m_curbe.ModeMvCost.DW8.m_value = OldIntraModeCost_Cm_Common[sliceQP]; |
| } |
| else if (m_skipBiasAdjustmentEnable) |
| { |
| // Load different MvCost for P picture when SkipBiasAdjustment is enabled |
| // No need to check for P picture as the flag is only enabled for P picture |
| cmd.m_curbe.ModeMvCost.DW11.m_value = MvCost_PSkipAdjustment_Cm_Common[sliceQP]; |
| } |
| } |
| |
| uint8_t tableIdx; |
| // r3 & r4 |
| if (params->bMbEncIFrameDistEnabled) |
| { |
| cmd.m_curbe.SPDelta.DW31.m_intraComputeType = 1; |
| } |
| else |
| { |
| tableIdx = (m_pictureCodingType == B_TYPE) ? 1 : 0; |
| eStatus = MOS_SecureMemcpy(&(cmd.m_curbe.SPDelta), 16 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][meMethod], 16 * sizeof(uint32_t)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| } |
| |
| // r5 |
| if (m_pictureCodingType == P_TYPE) |
| { |
| cmd.m_curbe.DW32.m_skipVal = SkipVal_P_Common |
| [cmd.m_curbe.DW3.m_blockBasedSkipEnable] |
| [picParams->transform_8x8_mode_flag] |
| [sliceQP]; |
| } |
| else if (m_pictureCodingType == B_TYPE) |
| { |
| cmd.m_curbe.DW32.m_skipVal = SkipVal_B_Common |
| [cmd.m_curbe.DW3.m_blockBasedSkipEnable] |
| [picParams->transform_8x8_mode_flag] |
| [sliceQP]; |
| } |
| |
| cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeY = sliceQP; |
| // m_qpPrimeCb and m_qpPrimeCr are not used by Kernel. Following settings are for CModel matching. |
| cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCb = sliceQP; |
| cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCr = sliceQP; |
| cmd.m_curbe.ModeMvCost.DW13.m_targetSizeInWord = 0xff; // hardcoded for BRC disabled |
| |
| if (bMultiPredEnable && (m_pictureCodingType != I_TYPE)) |
| { |
| switch (m_multiPred[seqParams->TargetUsage]) |
| { |
| case 0: // Disable multipred for both P & B picture types |
| cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| cmd.m_curbe.DW32.m_multiPredL1Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| break; |
| |
| case 1: // Enable multipred for P pictures only |
| cmd.m_curbe.DW32.m_multiPredL0Disable = (m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| cmd.m_curbe.DW32.m_multiPredL1Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| break; |
| |
| case 2: // Enable multipred for B pictures only |
| cmd.m_curbe.DW32.m_multiPredL0Disable = (m_pictureCodingType == B_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| cmd.m_curbe.DW32.m_multiPredL1Disable = (m_pictureCodingType == B_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| break; |
| |
| case 3: // Enable multipred for both P & B picture types |
| cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE; |
| cmd.m_curbe.DW32.m_multiPredL1Disable = (m_pictureCodingType == B_TYPE) ? CODECHAL_ENCODE_AVC_MULTIPRED_ENABLE : CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| break; |
| } |
| } |
| else |
| { |
| cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| cmd.m_curbe.DW32.m_multiPredL1Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| } |
| |
| if (!framePicture) |
| { |
| if (m_pictureCodingType != I_TYPE) |
| { |
| cmd.m_curbe.DW34.m_list0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0); |
| cmd.m_curbe.DW34.m_list0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1); |
| cmd.m_curbe.DW34.m_list0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2); |
| cmd.m_curbe.DW34.m_list0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3); |
| cmd.m_curbe.DW34.m_list0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4); |
| cmd.m_curbe.DW34.m_list0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5); |
| cmd.m_curbe.DW34.m_list0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6); |
| cmd.m_curbe.DW34.m_list0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7); |
| } |
| if (m_pictureCodingType == B_TYPE) |
| { |
| cmd.m_curbe.DW34.m_list1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0); |
| cmd.m_curbe.DW34.m_list1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1); |
| } |
| } |
| |
| if (m_adaptiveTransformDecisionEnabled) |
| { |
| if (m_pictureCodingType != I_TYPE) |
| { |
| cmd.m_curbe.DW34.m_enableAdaptiveTxDecision = true; |
| } |
| cmd.m_curbe.DW60.m_txDecisonThreshold = m_adaptiveTxDecisionThreshold; |
| } |
| |
| if (m_adaptiveTransformDecisionEnabled || m_flatnessCheckEnabled) |
| { |
| cmd.m_curbe.DW60.m_mbTextureThreshold = m_mbTextureThreshold; |
| } |
| |
| if (m_pictureCodingType == B_TYPE) |
| { |
| cmd.m_curbe.DW34.m_list1RefID0FrameFieldFlag = GetRefPicFieldFlag(params, LIST_1, CODECHAL_ENCODE_REF_ID_0); |
| cmd.m_curbe.DW34.m_list1RefID1FrameFieldFlag = GetRefPicFieldFlag(params, LIST_1, CODECHAL_ENCODE_REF_ID_1); |
| cmd.m_curbe.DW34.m_bDirectMode = slcParams->direct_spatial_mv_pred_flag; |
| } |
| |
| cmd.m_curbe.DW34.m_enablePerMBStaticCheck = params->bStaticFrameDetectionEnabled; |
| cmd.m_curbe.DW34.m_enableAdaptiveSearchWindowSize = params->bApdatvieSearchWindowSizeEnabled; |
| cmd.m_curbe.DW34.m_removeIntraRefreshOverlap = picParams->bDisableRollingIntraRefreshOverlap; |
| cmd.m_curbe.DW34.m_bOriginalBff = framePicture ? 0 : ((m_firstField && (bottomField)) || (!m_firstField && (!bottomField))); |
| cmd.m_curbe.DW34.m_enableMBFlatnessChkOptimization = m_flatnessCheckEnabled; |
| cmd.m_curbe.DW34.m_roiEnableFlag = params->bRoiEnabled; |
| cmd.m_curbe.DW34.m_madEnableFlag = m_madEnabled; |
| cmd.m_curbe.DW34.m_mbBrcEnable = bMbBrcEnabled || bMbQpDataEnabled; |
| cmd.m_curbe.DW34.m_arbitraryNumMbsPerSlice = m_arbitraryNumMbsInSlice; |
| cmd.m_curbe.DW34.m_tqEnable = m_trellisQuantParams.dwTqEnabled; //Enabled for KBL |
| cmd.m_curbe.DW34.m_forceNonSkipMbEnable = params->bMbDisableSkipMapEnabled; |
| if (params->pAvcQCParams && !cmd.m_curbe.DW34.m_forceNonSkipMbEnable) // ignore DisableEncSkipCheck if Mb Disable Skip Map is available |
| { |
| cmd.m_curbe.DW34.m_disableEncSkipCheck = params->pAvcQCParams->skipCheckDisable; |
| } |
| cmd.m_curbe.DW34.m_cqpFlag = !bBrcEnabled; // 1 - Rate Control is CQP, 0 - Rate Control is BRC |
| cmd.m_curbe.DW36.m_checkAllFractionalEnable = bCAFEnable; |
| cmd.m_curbe.DW38.m_refThreshold = m_refThreshold; |
| cmd.m_curbe.DW39.m_hmeRefWindowsCombThreshold = (m_pictureCodingType == B_TYPE) ? HMEBCombineLen[seqParams->TargetUsage] : HMECombineLen[seqParams->TargetUsage]; |
| |
| // Default:2 used for MBBRC (MB QP Surface width and height are 4x downscaled picture in MB unit * 4 bytes) |
| // 0 used for MBQP data surface (MB QP Surface width and height are same as the input picture size in MB unit * 1bytes) |
| // BRC use split kernel, MB QP surface is same size as input picture |
| cmd.m_curbe.DW47.m_mbQpReadFactor = (bMbBrcEnabled || bMbQpDataEnabled) ? 0 : 2; |
| |
| // Those fields are not really used for I_dist kernel |
| if (params->bMbEncIFrameDistEnabled) |
| { |
| cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeY = 0; |
| cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCb = 0; |
| cmd.m_curbe.ModeMvCost.DW13.m_qpPrimeCr = 0; |
| cmd.m_curbe.DW33.m_intra16x16NonDCPredPenalty = 0; |
| cmd.m_curbe.DW33.m_intra4x4NonDCPredPenalty = 0; |
| cmd.m_curbe.DW33.m_intra8x8NonDCPredPenalty = 0; |
| } |
| |
| //r6 |
| if (cmd.m_curbe.DW4.m_useActualRefQPValue) |
| { |
| cmd.m_curbe.DW44.m_actualQPValueForRefID0List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_0); |
| cmd.m_curbe.DW44.m_actualQPValueForRefID1List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_1); |
| cmd.m_curbe.DW44.m_actualQPValueForRefID2List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_2); |
| cmd.m_curbe.DW44.m_actualQPValueForRefID3List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_3); |
| cmd.m_curbe.DW45.m_actualQPValueForRefID4List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_4); |
| cmd.m_curbe.DW45.m_actualQPValueForRefID5List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_5); |
| cmd.m_curbe.DW45.m_actualQPValueForRefID6List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_6); |
| cmd.m_curbe.DW45.m_actualQPValueForRefID7List0 = AVCGetQPValueFromRefList(params, LIST_0, CODECHAL_ENCODE_REF_ID_7); |
| cmd.m_curbe.DW46.m_actualQPValueForRefID0List1 = AVCGetQPValueFromRefList(params, LIST_1, CODECHAL_ENCODE_REF_ID_0); |
| cmd.m_curbe.DW46.m_actualQPValueForRefID1List1 = AVCGetQPValueFromRefList(params, LIST_1, CODECHAL_ENCODE_REF_ID_1); |
| } |
| |
| tableIdx = m_pictureCodingType - 1; |
| cmd.m_curbe.DW46.m_refCost = m_refCostMultiRefQp[tableIdx][sliceQP]; |
| |
| // Picture Coding Type dependent parameters |
| if (m_pictureCodingType == I_TYPE) |
| { |
| cmd.m_curbe.DW0.m_skipModeEn = 0; |
| cmd.m_curbe.DW37.m_skipModeEn = 0; |
| cmd.m_curbe.DW36.m_hmeCombineOverlap = 0; |
| cmd.m_curbe.DW47.m_intraCostSF = 16; // This is not used but recommended to set this to 16 by Kernel team |
| cmd.m_curbe.DW34.m_enableDirectBiasAdjustment = 0; |
| } |
| else if (m_pictureCodingType == P_TYPE) |
| { |
| cmd.m_curbe.DW1.m_maxNumMVs = GetMaxMvsPer2Mb(seqParams->Level) / 2; |
| cmd.m_curbe.DW3.m_bmeDisableFBR = 1; |
| cmd.m_curbe.DW5.m_refWidth = SearchX[seqParams->TargetUsage]; |
| cmd.m_curbe.DW5.m_refHeight = SearchY[seqParams->TargetUsage]; |
| cmd.m_curbe.DW7.m_nonSkipZMvAdded = 1; |
| cmd.m_curbe.DW7.m_nonSkipModeAdded = 1; |
| cmd.m_curbe.DW7.m_skipCenterMask = 1; |
| cmd.m_curbe.DW47.m_intraCostSF = bAdaptiveIntraScalingEnable ? AdaptiveIntraScalingFactor_Cm_Common[sliceQP] : IntraScalingFactor_Cm_Common[sliceQP]; |
| cmd.m_curbe.DW47.m_maxVmvR = (framePicture) ? CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) * 4 : (CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) >> 1) * 4; |
| cmd.m_curbe.DW36.m_hmeCombineOverlap = 1; |
| cmd.m_curbe.DW36.m_numRefIdxL0MinusOne = bMultiPredEnable ? slcParams->num_ref_idx_l0_active_minus1 : 0; |
| cmd.m_curbe.DW39.m_refWidth = SearchX[seqParams->TargetUsage]; |
| cmd.m_curbe.DW39.m_refHeight = SearchY[seqParams->TargetUsage]; |
| cmd.m_curbe.DW34.m_enableDirectBiasAdjustment = 0; |
| if (params->pAvcQCParams) |
| { |
| cmd.m_curbe.DW34.m_enableGlobalMotionBiasAdjustment = params->pAvcQCParams->globalMotionBiasAdjustmentEnable; |
| } |
| } |
| else |
| { |
| // B_TYPE |
| cmd.m_curbe.DW1.m_maxNumMVs = GetMaxMvsPer2Mb(seqParams->Level) / 2; |
| cmd.m_curbe.DW1.m_biWeight = m_biWeight; |
| cmd.m_curbe.DW3.m_searchCtrl = 7; |
| cmd.m_curbe.DW3.m_skipType = 1; |
| cmd.m_curbe.DW5.m_refWidth = BSearchX[seqParams->TargetUsage]; |
| cmd.m_curbe.DW5.m_refHeight = BSearchY[seqParams->TargetUsage]; |
| cmd.m_curbe.DW7.m_skipCenterMask = 0xFF; |
| cmd.m_curbe.DW47.m_intraCostSF = |
| bAdaptiveIntraScalingEnable ? AdaptiveIntraScalingFactor_Cm_Common[sliceQP] : IntraScalingFactor_Cm_Common[sliceQP]; |
| cmd.m_curbe.DW47.m_maxVmvR = (framePicture) ? CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) * 4 : (CodecHalAvcEncode_GetMaxMvLen(seqParams->Level) >> 1) * 4; |
| cmd.m_curbe.DW36.m_hmeCombineOverlap = 1; |
| // Checking if the forward frame (List 1 index 0) is a short term reference |
| { |
| auto codecHalPic = params->pSlcParams->RefPicList[LIST_1][0]; |
| if (codecHalPic.PicFlags != PICTURE_INVALID && |
| codecHalPic.FrameIdx != CODECHAL_ENCODE_AVC_INVALID_PIC_ID && |
| params->pPicIdx[codecHalPic.FrameIdx].bValid) |
| { |
| // Although its name is FWD, it actually means the future frame or the backward reference frame |
| cmd.m_curbe.DW36.m_isFwdFrameShortTermRef = CodecHal_PictureIsShortTermRef(params->pPicParams->RefFrameList[codecHalPic.FrameIdx]); |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Invalid backward reference frame."); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| return eStatus; |
| } |
| } |
| cmd.m_curbe.DW36.m_numRefIdxL0MinusOne = bMultiPredEnable ? slcParams->num_ref_idx_l0_active_minus1 : 0; |
| cmd.m_curbe.DW36.m_numRefIdxL1MinusOne = bMultiPredEnable ? slcParams->num_ref_idx_l1_active_minus1 : 0; |
| cmd.m_curbe.DW39.m_refWidth = BSearchX[seqParams->TargetUsage]; |
| cmd.m_curbe.DW39.m_refHeight = BSearchY[seqParams->TargetUsage]; |
| cmd.m_curbe.DW40.m_distScaleFactorRefID0List0 = m_distScaleFactorList0[0]; |
| cmd.m_curbe.DW40.m_distScaleFactorRefID1List0 = m_distScaleFactorList0[1]; |
| cmd.m_curbe.DW41.m_distScaleFactorRefID2List0 = m_distScaleFactorList0[2]; |
| cmd.m_curbe.DW41.m_distScaleFactorRefID3List0 = m_distScaleFactorList0[3]; |
| cmd.m_curbe.DW42.m_distScaleFactorRefID4List0 = m_distScaleFactorList0[4]; |
| cmd.m_curbe.DW42.m_distScaleFactorRefID5List0 = m_distScaleFactorList0[5]; |
| cmd.m_curbe.DW43.m_distScaleFactorRefID6List0 = m_distScaleFactorList0[6]; |
| cmd.m_curbe.DW43.m_distScaleFactorRefID7List0 = m_distScaleFactorList0[7]; |
| if (params->pAvcQCParams) |
| { |
| cmd.m_curbe.DW34.m_enableDirectBiasAdjustment = params->pAvcQCParams->directBiasAdjustmentEnable; |
| if (cmd.m_curbe.DW34.m_enableDirectBiasAdjustment) |
| { |
| cmd.m_curbe.DW7.m_nonSkipModeAdded = 1; |
| cmd.m_curbe.DW7.m_nonSkipZMvAdded = 1; |
| } |
| |
| cmd.m_curbe.DW34.m_enableGlobalMotionBiasAdjustment = params->pAvcQCParams->globalMotionBiasAdjustmentEnable; |
| } |
| } |
| |
| *params->pdwBlockBasedSkipEn = cmd.m_curbe.DW3.m_blockBasedSkipEnable; |
| |
| if (picParams->EnableRollingIntraRefresh) |
| { |
| cmd.m_curbe.DW34.m_IntraRefreshEn = picParams->EnableRollingIntraRefresh; |
| |
| /* Multiple predictor should be completely disabled for the RollingI feature. This does not lead to much quality drop for P frames especially for TU as 1 */ |
| cmd.m_curbe.DW32.m_multiPredL0Disable = CODECHAL_ENCODE_AVC_MULTIPRED_DISABLE; |
| |
| /* Pass the same IntraRefreshUnit to the kernel w/o the adjustment by -1, so as to have an overlap of one MB row or column of Intra macroblocks |
| across one P frame to another P frame, as needed by the RollingI algo */ |
| if (ROLLING_I_SQUARE == picParams->EnableRollingIntraRefresh && RATECONTROL_CQP != seqParams->RateControlMethod) |
| { |
| /*BRC update kernel updates these CURBE to MBEnc*/ |
| cmd.m_curbe.DW4.m_enableIntraRefresh = false; |
| cmd.m_curbe.DW34.m_IntraRefreshEn = ROLLING_I_DISABLED; |
| cmd.m_curbe.DW48.m_IntraRefreshMBx = 0; /* MB column number */ |
| cmd.m_curbe.DW61.m_IntraRefreshMBy = 0; /* MB row number */ |
| } |
| else |
| { |
| cmd.m_curbe.DW4.m_enableIntraRefresh = true; |
| cmd.m_curbe.DW34.m_IntraRefreshEn = picParams->EnableRollingIntraRefresh; |
| cmd.m_curbe.DW48.m_IntraRefreshMBx = picParams->IntraRefreshMBx; /* MB column number */ |
| cmd.m_curbe.DW61.m_IntraRefreshMBy = picParams->IntraRefreshMBy; /* MB row number */ |
| } |
| cmd.m_curbe.DW48.m_IntraRefreshUnitInMBMinus1 = picParams->IntraRefreshUnitinMB; |
| cmd.m_curbe.DW48.m_IntraRefreshQPDelta = picParams->IntraRefreshQPDelta; |
| } |
| else |
| { |
| cmd.m_curbe.DW34.m_IntraRefreshEn = 0; |
| } |
| |
| if (params->bRoiEnabled) |
| { |
| cmd.m_curbe.DW49.m_roi1XLeft = picParams->ROI[0].Left; |
| cmd.m_curbe.DW49.m_roi1YTop = picParams->ROI[0].Top; |
| cmd.m_curbe.DW50.m_roi1XRight = picParams->ROI[0].Right; |
| cmd.m_curbe.DW50.m_roi1YBottom = picParams->ROI[0].Bottom; |
| |
| cmd.m_curbe.DW51.m_roi2XLeft = picParams->ROI[1].Left; |
| cmd.m_curbe.DW51.m_roi2YTop = picParams->ROI[1].Top; |
| cmd.m_curbe.DW52.m_roi2XRight = picParams->ROI[1].Right; |
| cmd.m_curbe.DW52.m_roi2YBottom = picParams->ROI[1].Bottom; |
| |
| cmd.m_curbe.DW53.m_roi3XLeft = picParams->ROI[2].Left; |
| cmd.m_curbe.DW53.m_roi3YTop = picParams->ROI[2].Top; |
| cmd.m_curbe.DW54.m_roi3XRight = picParams->ROI[2].Right; |
| cmd.m_curbe.DW54.m_roi3YBottom = picParams->ROI[2].Bottom; |
| |
| cmd.m_curbe.DW55.m_roi4XLeft = picParams->ROI[3].Left; |
| cmd.m_curbe.DW55.m_roi4YTop = picParams->ROI[3].Top; |
| cmd.m_curbe.DW56.m_roi4XRight = picParams->ROI[3].Right; |
| cmd.m_curbe.DW56.m_roi4YBottom = picParams->ROI[3].Bottom; |
| |
| if (bBrcEnabled == false) |
| { |
| uint16_t numROI = picParams->NumROI; |
| int8_t priorityLevelOrDQp[CODECHAL_ENCODE_AVC_MAX_ROI_NUMBER] = {0}; |
| |
| // cqp case |
| for (unsigned int i = 0; i < numROI; i += 1) |
| { |
| int8_t dQpRoi = picParams->ROI[i].PriorityLevelOrDQp; |
| |
| // clip qp roi in order to have (qp + qpY) in range [0, 51] |
| priorityLevelOrDQp[i] = (int8_t)CodecHal_Clip3(-sliceQP, CODECHAL_ENCODE_AVC_MAX_SLICE_QP - sliceQP, dQpRoi); |
| } |
| |
| cmd.m_curbe.DW57.m_roi1dQpPrimeY = priorityLevelOrDQp[0]; |
| cmd.m_curbe.DW57.m_roi2dQpPrimeY = priorityLevelOrDQp[1]; |
| cmd.m_curbe.DW57.m_roi3dQpPrimeY = priorityLevelOrDQp[2]; |
| cmd.m_curbe.DW57.m_roi4dQpPrimeY = priorityLevelOrDQp[3]; |
| } |
| else |
| { |
| // kernel does not support BRC case |
| cmd.m_curbe.DW34.m_roiEnableFlag = 0; |
| } |
| } |
| else if (params->bDirtyRoiEnabled) |
| { |
| // enable Dirty Rect flag |
| cmd.m_curbe.DW4.m_enableDirtyRect = true; |
| |
| cmd.m_curbe.DW49.m_roi1XLeft = params->pPicParams->DirtyROI[0].Left; |
| cmd.m_curbe.DW49.m_roi1YTop = params->pPicParams->DirtyROI[0].Top; |
| cmd.m_curbe.DW50.m_roi1XRight = params->pPicParams->DirtyROI[0].Right; |
| cmd.m_curbe.DW50.m_roi1YBottom = params->pPicParams->DirtyROI[0].Bottom; |
| |
| cmd.m_curbe.DW51.m_roi2XLeft = params->pPicParams->DirtyROI[1].Left; |
| cmd.m_curbe.DW51.m_roi2YTop = params->pPicParams->DirtyROI[1].Top; |
| cmd.m_curbe.DW52.m_roi2XRight = params->pPicParams->DirtyROI[1].Right; |
| cmd.m_curbe.DW52.m_roi2YBottom = params->pPicParams->DirtyROI[1].Bottom; |
| |
| cmd.m_curbe.DW53.m_roi3XLeft = params->pPicParams->DirtyROI[2].Left; |
| cmd.m_curbe.DW53.m_roi3YTop = params->pPicParams->DirtyROI[2].Top; |
| cmd.m_curbe.DW54.m_roi3XRight = params->pPicParams->DirtyROI[2].Right; |
| cmd.m_curbe.DW54.m_roi3YBottom = params->pPicParams->DirtyROI[2].Bottom; |
| |
| cmd.m_curbe.DW55.m_roi4XLeft = params->pPicParams->DirtyROI[3].Left; |
| cmd.m_curbe.DW55.m_roi4YTop = params->pPicParams->DirtyROI[3].Top; |
| cmd.m_curbe.DW56.m_roi4XRight = params->pPicParams->DirtyROI[3].Right; |
| cmd.m_curbe.DW56.m_roi4YBottom = params->pPicParams->DirtyROI[3].Bottom; |
| } |
| |
| if (m_trellisQuantParams.dwTqEnabled) |
| { |
| // Lambda values for TQ |
| if (m_pictureCodingType == I_TYPE) |
| { |
| cmd.m_curbe.DW58.m_value = TQ_LAMBDA_I_FRAME[sliceQP][0]; |
| cmd.m_curbe.DW59.m_value = TQ_LAMBDA_I_FRAME[sliceQP][1]; |
| } |
| else if (m_pictureCodingType == P_TYPE) |
| { |
| cmd.m_curbe.DW58.m_value = TQ_LAMBDA_P_FRAME[sliceQP][0]; |
| cmd.m_curbe.DW59.m_value = TQ_LAMBDA_P_FRAME[sliceQP][1]; |
| } |
| else |
| { |
| cmd.m_curbe.DW58.m_value = TQ_LAMBDA_B_FRAME[sliceQP][0]; |
| cmd.m_curbe.DW59.m_value = TQ_LAMBDA_B_FRAME[sliceQP][1]; |
| } |
| |
| MHW_VDBOX_AVC_SLICE_STATE sliceState; |
| MOS_ZeroMemory(&sliceState, sizeof(sliceState)); |
| sliceState.pEncodeAvcSeqParams = seqParams; |
| sliceState.pEncodeAvcPicParams = picParams; |
| sliceState.pEncodeAvcSliceParams = slcParams; |
| |
| // check if Lambda is greater than max value |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetInterRounding(&sliceState)); |
| |
| if (cmd.m_curbe.DW58.m_lambda8x8Inter > m_maxLambda) |
| { |
| cmd.m_curbe.DW58.m_lambda8x8Inter = 0xf000 + sliceState.dwRoundingValue; |
| } |
| |
| if (cmd.m_curbe.DW58.m_lambda8x8Intra > m_maxLambda) |
| { |
| cmd.m_curbe.DW58.m_lambda8x8Intra = 0xf000 + m_defaultTrellisQuantIntraRounding; |
| } |
| |
| // check if Lambda is greater than max value |
| if (cmd.m_curbe.DW59.m_lambdaInter > m_maxLambda) |
| { |
| cmd.m_curbe.DW59.m_lambdaInter = 0xf000 + sliceState.dwRoundingValue; |
| } |
| |
| if (cmd.m_curbe.DW59.m_lambdaIntra > m_maxLambda) |
| { |
| cmd.m_curbe.DW59.m_lambdaIntra = 0xf000 + m_defaultTrellisQuantIntraRounding; |
| } |
| } |
| |
| //IPCM QP and threshold |
| cmd.m_curbe.DW62.m_IPCMQP0 = m_IPCMThresholdTable[0].QP; |
| cmd.m_curbe.DW62.m_IPCMQP1 = m_IPCMThresholdTable[1].QP; |
| cmd.m_curbe.DW62.m_IPCMQP2 = m_IPCMThresholdTable[2].QP; |
| cmd.m_curbe.DW62.m_IPCMQP3 = m_IPCMThresholdTable[3].QP; |
| cmd.m_curbe.DW63.m_IPCMQP4 = m_IPCMThresholdTable[4].QP; |
| |
| cmd.m_curbe.DW63.m_IPCMThresh0 = m_IPCMThresholdTable[0].Threshold; |
| cmd.m_curbe.DW64.m_IPCMThresh1 = m_IPCMThresholdTable[1].Threshold; |
| cmd.m_curbe.DW64.m_IPCMThresh2 = m_IPCMThresholdTable[2].Threshold; |
| cmd.m_curbe.DW65.m_IPCMThresh3 = m_IPCMThresholdTable[3].Threshold; |
| cmd.m_curbe.DW65.m_IPCMThresh4 = m_IPCMThresholdTable[4].Threshold; |
| |
| cmd.m_curbe.DW66.m_mbDataSurfIndex = mbencMfcAvcPakObj; |
| cmd.m_curbe.DW67.m_mvDataSurfIndex = mbencIndMvData; |
| cmd.m_curbe.DW68.m_IDistSurfIndex = mbencBrcDistortion; |
| cmd.m_curbe.DW69.m_srcYSurfIndex = mbencCurrY; |
| cmd.m_curbe.DW70.m_mbSpecificDataSurfIndex = mbencMbSpecificData; |
| cmd.m_curbe.DW71.m_auxVmeOutSurfIndex = mbencAuxVmeOut; |
| cmd.m_curbe.DW72.m_currRefPicSelSurfIndex = mbencRefpicselectL0; |
| cmd.m_curbe.DW73.m_hmeMVPredFwdBwdSurfIndex = mbencMvDataFromMe; |
| cmd.m_curbe.DW74.m_hmeDistSurfIndex = mbenc4xMeDistortion; |
| cmd.m_curbe.DW75.m_sliceMapSurfIndex = mbencSlicemapData; |
| cmd.m_curbe.DW76.m_fwdFrmMBDataSurfIndex = mbencFwdMbData; |
| cmd.m_curbe.DW77.m_fwdFrmMVSurfIndex = mbencFwdMvData; |
| cmd.m_curbe.DW78.m_mbQPBuffer = mbencMbqp; |
| cmd.m_curbe.DW79.m_mbBRCLut = mbencMbbrcConstData; |
| cmd.m_curbe.DW80.m_vmeInterPredictionSurfIndex = mbencVmeInterPredCurrPicIdx0; |
| cmd.m_curbe.DW81.m_vmeInterPredictionMRSurfIndex = mbencVmeInterPredCurrPicIdx1; |
| cmd.m_curbe.DW82.m_mbStatsSurfIndex = mbencMbStats; |
| cmd.m_curbe.DW83.m_madSurfIndex = mbencMadData; |
| cmd.m_curbe.DW84.m_brcCurbeSurfIndex = mbencBrcCurbeData; |
| cmd.m_curbe.DW85.m_forceNonSkipMBmapSurface = mbencForceNonskipMbMap; |
| cmd.m_curbe.DW86.m_reservedIndex = mbEncAdv; |
| cmd.m_curbe.DW87.m_staticDetectionCostTableIndex = mbencSfdCostTable; |
| cmd.m_curbe.DW88.m_swScoreboardIndex = mbencSwScoreboard; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( |
| &cmd, |
| params->pKernelState->dwCurbeOffset, |
| sizeof(cmd))); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateEncParam( |
| meMethod, |
| &cmd)); |
| ) |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcWP(PCODECHAL_ENCODE_AVC_WP_CURBE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| int16_t weight; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| |
| auto slcParams = m_avcSliceParams; |
| auto seqParams = m_avcSeqParam; |
| auto kernelState = pWPKernelState; |
| CODECHAL_ENCODE_ASSERT(seqParams->TargetUsage < NUM_TARGET_USAGE_MODES); |
| |
| CodechalEncodeAvcEncG12::WpCurbe cmd; |
| |
| /* Weights[i][j][k][m] is interpreted as: |
| |
| i refers to reference picture list 0 or 1; |
| j refers to reference list entry 0-31; |
| k refers to data for the luma (Y) component when it is 0, the Cb chroma component when it is 1 and the Cr chroma component when it is 2; |
| m refers to weight when it is 0 and offset when it is 1 |
| */ |
| weight = slcParams->Weights[params->RefPicListIdx][params->WPIdx][0][0]; |
| cmd.m_wpCurbeCmd.DW0.m_defaultWeight = (weight << 6) >> (slcParams->luma_log2_weight_denom); |
| cmd.m_wpCurbeCmd.DW0.m_defaultOffset = slcParams->Weights[params->RefPicListIdx][0][0][1]; |
| |
| cmd.m_wpCurbeCmd.DW49.m_inputSurface = wpInputRefSurface; |
| cmd.m_wpCurbeCmd.DW50.m_outputSurface = wpOutputScaledSurface; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData( |
| &cmd, |
| kernelState->dwCurbeOffset, |
| sizeof(cmd))); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcBrcInitReset(PCODECHAL_ENCODE_AVC_BRC_INIT_RESET_CURBE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| |
| auto seqParams = m_avcSeqParam; |
| auto vuiParams = m_avcVuiParams; |
| uint32_t profileLevelMaxFrame; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_GetProfileLevelMaxFrameSize( |
| seqParams, |
| this, |
| (uint32_t*)&profileLevelMaxFrame)); |
| |
| BrcInitResetCurbe curbe; |
| curbe.m_brcInitResetCurbeCmd.m_dw0.m_profileLevelMaxFrame = profileLevelMaxFrame; |
| curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = seqParams->InitVBVBufferFullnessInBit; |
| curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits = seqParams->VBVBufferSizeInBit; |
| curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = seqParams->TargetBitRate; |
| curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate = seqParams->MaxBitRate; |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_gopP = |
| (seqParams->GopRefDist) ? ((seqParams->GopPicSize - 1) / seqParams->GopRefDist) : 0; |
| curbe.m_brcInitResetCurbeCmd.m_dw9.m_gopB = seqParams->GopPicSize - 1 - curbe.m_brcInitResetCurbeCmd.m_dw8.m_gopP; |
| curbe.m_brcInitResetCurbeCmd.m_dw9.m_frameWidthInBytes = m_frameWidth; |
| curbe.m_brcInitResetCurbeCmd.m_dw10.m_frameHeightInBytes = m_frameHeight; |
| curbe.m_brcInitResetCurbeCmd.m_dw12.m_noSlices = m_numSlices; |
| |
| curbe.m_brcInitResetCurbeCmd.m_dw32.m_surfaceIndexHistorybuffer = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_HISTORY; |
| curbe.m_brcInitResetCurbeCmd.m_dw33.m_surfaceIndexDistortionbuffer = CODECHAL_ENCODE_AVC_BRC_INIT_RESET_DISTORTION; |
| |
| // if VUI present, VUI data has high priority |
| if (seqParams->vui_parameters_present_flag && seqParams->RateControlMethod != RATECONTROL_AVBR) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate = |
| ((vuiParams->bit_rate_value_minus1[0] + 1) << (6 + vuiParams->bit_rate_scale)); |
| |
| if (seqParams->RateControlMethod == RATECONTROL_CBR) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate; |
| } |
| } |
| |
| curbe.m_brcInitResetCurbeCmd.m_dw6.m_frameRateM = seqParams->FramesPer100Sec; |
| curbe.m_brcInitResetCurbeCmd.m_dw7.m_frameRateD = 100; |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = (CodecHal_PictureIsFrame(m_currOriginalPic)) ? 0 : CODECHAL_ENCODE_BRCINIT_FIELD_PIC; |
| // MBBRC should be skipped when BRC ROI is on |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag |= (bMbBrcEnabled && !bBrcRoiEnabled) ? 0 : CODECHAL_ENCODE_BRCINIT_DISABLE_MBBRC; |
| |
| if (seqParams->RateControlMethod == RATECONTROL_CBR) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate = curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate; |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISCBR; |
| } |
| else if (seqParams->RateControlMethod == RATECONTROL_VBR) |
| { |
| if (curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate < curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate; // Use max bit rate for HRD compliance |
| } |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISVBR; |
| } |
| else if (seqParams->RateControlMethod == RATECONTROL_AVBR) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISAVBR; |
| // For AVBR, max bitrate = target bitrate, |
| curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate = curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate; |
| } |
| else if (seqParams->RateControlMethod == RATECONTROL_ICQ) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISICQ; |
| curbe.m_brcInitResetCurbeCmd.m_dw23.m_aCQP = seqParams->ICQQualityFactor; |
| } |
| else if (seqParams->RateControlMethod == RATECONTROL_VCM) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISVCM; |
| } |
| else if (seqParams->RateControlMethod == RATECONTROL_QVBR) |
| { |
| if (curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate < curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate = curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate; // Use max bit rate for HRD compliance |
| } |
| curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag = curbe.m_brcInitResetCurbeCmd.m_dw8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISQVBR; |
| // use ICQQualityFactor to determine the larger Qp for each MB |
| curbe.m_brcInitResetCurbeCmd.m_dw23.m_aCQP = seqParams->ICQQualityFactor; |
| } |
| |
| curbe.m_brcInitResetCurbeCmd.m_dw10.m_avbrAccuracy = usAVBRAccuracy; |
| curbe.m_brcInitResetCurbeCmd.m_dw11.m_avbrConvergence = usAVBRConvergence; |
| |
| // Set dynamic thresholds |
| double inputBitsPerFrame = |
| ((double)(curbe.m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate) * (double)(curbe.m_brcInitResetCurbeCmd.m_dw7.m_frameRateD) / |
| (double)(curbe.m_brcInitResetCurbeCmd.m_dw6.m_frameRateM)); |
| if (CodecHal_PictureIsField(m_currOriginalPic)) |
| { |
| inputBitsPerFrame *= 0.5; |
| } |
| |
| if (curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits == 0) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits = (uint32_t)inputBitsPerFrame * 4; |
| } |
| |
| if (curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits == 0) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = 7 * curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits / 8; |
| } |
| if (curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits < (uint32_t)(inputBitsPerFrame * 2)) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = (uint32_t)(inputBitsPerFrame * 2); |
| } |
| if (curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits > curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits) |
| { |
| curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits; |
| } |
| |
| if (seqParams->RateControlMethod == RATECONTROL_AVBR) |
| { |
| // For AVBR, Buffer size = 2*Bitrate, InitVBV = 0.75 * BufferSize |
| curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits = 2 * seqParams->TargetBitRate; |
| curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits = (uint32_t)(0.75 * curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits); |
| } |
| |
| double bpsRatio = inputBitsPerFrame / ((double)(curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits) / 30); |
| bpsRatio = (bpsRatio < 0.1) ? 0.1 : (bpsRatio > 3.5) ? 3.5 : bpsRatio; |
| |
| curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold0ForPandB = (uint32_t)(-50 * pow(0.90, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold1ForPandB = (uint32_t)(-50 * pow(0.66, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold2ForPandB = (uint32_t)(-50 * pow(0.46, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw16.m_deviationThreshold3ForPandB = (uint32_t)(-50 * pow(0.3, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold4ForPandB = (uint32_t)(50 * pow(0.3, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold5ForPandB = (uint32_t)(50 * pow(0.46, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold6ForPandB = (uint32_t)(50 * pow(0.7, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw17.m_deviationThreshold7ForPandB = (uint32_t)(50 * pow(0.9, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold0ForVBR = (uint32_t)(-50 * pow(0.9, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold1ForVBR = (uint32_t)(-50 * pow(0.7, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold2ForVBR = (uint32_t)(-50 * pow(0.5, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw18.m_deviationThreshold3ForVBR = (uint32_t)(-50 * pow(0.3, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold4ForVBR = (uint32_t)(100 * pow(0.4, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold5ForVBR = (uint32_t)(100 * pow(0.5, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold6ForVBR = (uint32_t)(100 * pow(0.75, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw19.m_deviationThreshold7ForVBR = (uint32_t)(100 * pow(0.9, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold0ForI = (uint32_t)(-50 * pow(0.8, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold1ForI = (uint32_t)(-50 * pow(0.6, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold2ForI = (uint32_t)(-50 * pow(0.34, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw20.m_deviationThreshold3ForI = (uint32_t)(-50 * pow(0.2, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold4ForI = (uint32_t)(50 * pow(0.2, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold5ForI = (uint32_t)(50 * pow(0.4, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold6ForI = (uint32_t)(50 * pow(0.66, bpsRatio)); |
| curbe.m_brcInitResetCurbeCmd.m_dw21.m_deviationThreshold7ForI = (uint32_t)(50 * pow(0.9, bpsRatio)); |
| |
| curbe.m_brcInitResetCurbeCmd.m_dw22.m_slidingWindowSize = dwSlidingWindowSize; |
| |
| if (bBrcInit) |
| { |
| *params->pdBrcInitCurrentTargetBufFullInBits = curbe.m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits; |
| } |
| |
| *params->pdwBrcInitResetBufSizeInBits = curbe.m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits; |
| *params->pdBrcInitResetInputBitsPerFrame = inputBitsPerFrame; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( |
| &curbe.m_brcInitResetCurbeCmd, |
| params->pKernelState->dwCurbeOffset, |
| sizeof(curbe.m_brcInitResetCurbeCmd))); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcInitParam( |
| &curbe.m_brcInitResetCurbeCmd)); |
| ) |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcFrameBrcUpdate(PCODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); |
| |
| CodechalEncodeAvcEncG12::FrameBrcUpdateCurbe cmd; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_targetSizeFlag = 0; |
| if (*params->pdBrcInitCurrentTargetBufFullInBits > (double)dwBrcInitResetBufSizeInBits) |
| { |
| *params->pdBrcInitCurrentTargetBufFullInBits -= (double)dwBrcInitResetBufSizeInBits; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_targetSizeFlag = 1; |
| } |
| |
| // skipped frame handling |
| if (params->dwNumSkipFrames) |
| { |
| // pass num/size of skipped frames to update BRC |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_numSkipFrames = params->dwNumSkipFrames; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw7.m_sizeSkipFrames = params->dwSizeSkipFrames; |
| |
| // account for skipped frame in calculating CurrentTargetBufFullInBits |
| *params->pdBrcInitCurrentTargetBufFullInBits += dBrcInitResetInputBitsPerFrame * params->dwNumSkipFrames; |
| } |
| |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw0.m_targetSize = (uint32_t)(*params->pdBrcInitCurrentTargetBufFullInBits); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw1.m_frameNumber = m_storeData - 1; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw2.m_sizeofPicHeaders = m_headerBytesInserted << 3; // kernel uses how many bits instead of bytes |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_currFrameType = |
| ((m_pictureCodingType - 2) < 0) ? 2 : (m_pictureCodingType - 2); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag = |
| (CodecHal_PictureIsTopField(m_currOriginalPic)) ? brcUpdateIsField : ((CodecHal_PictureIsBottomField(m_currOriginalPic)) ? (brcUpdateIsField | brcUpdateIsBottomField) : 0); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag |= (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) ? brcUpdateIsReference : 0; |
| |
| if (bMultiRefQpEnabled) |
| { |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag |= brcUpdateIsActualQp; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw14.m_qpIndexOfCurPic = m_currOriginalPic.FrameIdx; |
| } |
| |
| auto seqParams = m_avcSeqParam; |
| auto picParams = m_avcPicParam; |
| auto slcParams = m_avcSliceParams; |
| |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_brcFlag |= seqParams->bAutoMaxPBFrameSizeForSceneChange ? brcUpdateAutoPbFrameSize : 0; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw5.m_maxNumPAKs = m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_minimumQP = params->ucMinQP; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_maximumQP = params->ucMaxQP; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_enableForceToSkip = (bForceToSkipEnable && !m_avcPicParam->bDisableFrameSkip); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_enableSlidingWindow = (seqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_enableExtremLowDelay = (seqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw6.m_disableVarCompute = bBRCVarCompuBypass; |
| |
| *params->pdBrcInitCurrentTargetBufFullInBits += dBrcInitResetInputBitsPerFrame; |
| |
| if (seqParams->RateControlMethod == RATECONTROL_AVBR) |
| { |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw3.m_startGAdjFrame0 = (uint32_t)((10 * usAVBRConvergence) / (double)150); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw3.m_startGAdjFrame1 = (uint32_t)((50 * usAVBRConvergence) / (double)150); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw4.m_startGAdjFrame2 = (uint32_t)((100 * usAVBRConvergence) / (double)150); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw4.m_startGAdjFrame3 = (uint32_t)((150 * usAVBRConvergence) / (double)150); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw11.m_gRateRatioThreshold0 = (uint32_t)((100 - (usAVBRAccuracy / (double)30) * (100 - 40))); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw11.m_gRateRatioThreshold1 = (uint32_t)((100 - (usAVBRAccuracy / (double)30) * (100 - 75))); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold2 = (uint32_t)((100 - (usAVBRAccuracy / (double)30) * (100 - 97))); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold3 = (uint32_t)((100 + (usAVBRAccuracy / (double)30) * (103 - 100))); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold4 = (uint32_t)((100 + (usAVBRAccuracy / (double)30) * (125 - 100))); |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw12.m_gRateRatioThreshold5 = (uint32_t)((100 + (usAVBRAccuracy / (double)30) * (160 - 100))); |
| } |
| |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw15.m_enableROI = params->ucEnableROI; |
| |
| MHW_VDBOX_AVC_SLICE_STATE sliceState; |
| MOS_ZeroMemory(&sliceState, sizeof(sliceState)); |
| sliceState.pEncodeAvcSeqParams = seqParams; |
| sliceState.pEncodeAvcPicParams = picParams; |
| sliceState.pEncodeAvcSliceParams = slcParams; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetInterRounding(&sliceState)); |
| |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw15.m_roundingIntra = 5; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw15.m_roundingInter = sliceState.dwRoundingValue; |
| |
| uint32_t profileLevelMaxFrame; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_GetProfileLevelMaxFrameSize( |
| seqParams, |
| this, |
| (uint32_t*)&profileLevelMaxFrame)); |
| |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw19.m_userMaxFrame = profileLevelMaxFrame; |
| |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw24.m_surfaceIndexBRCHistorybuffer = frameBrcUpdateHistory; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw25.m_surfaceIndexPreciousPAKStatisticsOutputbuffer = frameBrcUpdatePakStatisticsOutput; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw26.m_surfaceIndexAVCIMGStateInputbuffer = frameBrcUpdateImageStateRead; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw27.m_surfaceIndexAVCIMGStateOutputbuffer = frameBrcUpdateImageStateWrite; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw28.m_surfaceIndexAVC_Encbuffer = frameBrcUpdateMbencCurbeWrite; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw29.m_surfaceIndexAVCDistortionbuffer = frameBrcUpdateDistortion; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw30.m_surfaceIndexBRCConstdatabuffer = frameBrcUpdateConstantData; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw31.m_surfaceIndexMBStatsbuffer = frameBrcUpdateMbStat; |
| cmd.m_frameBrcUpdateCurbeCmd.m_dw32.m_surfaceIndexMotionVectorbuffer = frameBrcUpdateMvStat; |
| auto pStateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface; |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pStateHeapInterface); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( |
| &cmd.m_frameBrcUpdateCurbeCmd, |
| params->pKernelState->dwCurbeOffset, |
| sizeof(cmd.m_frameBrcUpdateCurbeCmd))); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateBrcUpdateParam( |
| &cmd.m_frameBrcUpdateCurbeCmd)); |
| ) |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetCurbeAvcMbBrcUpdate(PCODECHAL_ENCODE_AVC_BRC_UPDATE_CURBE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); |
| |
| CodechalEncodeAvcEncG12::MbBrcUpdateCurbe curbe; |
| |
| // BRC curbe requires: 2 for I-frame, 0 for P-frame, 1 for B-frame |
| curbe.m_mbBrcUpdateCurbeCmd.DW0.m_currFrameType = (m_pictureCodingType + 1) % 3; |
| if (params->ucEnableROI) |
| { |
| if (bROIValueInDeltaQP) |
| { |
| curbe.m_mbBrcUpdateCurbeCmd.DW0.m_enableROI = 2; // 1-Enabled ROI priority, 2-Enable ROI QP Delta, 0- disabled |
| curbe.m_mbBrcUpdateCurbeCmd.DW0.m_roiRatio = 0; |
| } |
| else |
| { |
| curbe.m_mbBrcUpdateCurbeCmd.DW0.m_enableROI = 1; // 1-Enabled ROI priority, 2-Enable ROI QP Delta, 0- disabled |
| |
| uint32_t roiSize = 0; |
| uint32_t roiRatio = 0; |
| |
| for (uint32_t i = 0; i < m_avcPicParam->NumROI; ++i) |
| { |
| CODECHAL_ENCODE_VERBOSEMESSAGE("ROI[%d] = {%d, %d, %d, %d} {%d}, size = %d", |
| i, |
| m_avcPicParam->ROI[i].Left, |
| m_avcPicParam->ROI[i].Top, |
| m_avcPicParam->ROI[i].Bottom, |
| m_avcPicParam->ROI[i].Right, |
| m_avcPicParam->ROI[i].PriorityLevelOrDQp, |
| (CODECHAL_MACROBLOCK_HEIGHT * MOS_ABS(m_avcPicParam->ROI[i].Top - |
| m_avcPicParam->ROI[i].Bottom)) * |
| (CODECHAL_MACROBLOCK_WIDTH * MOS_ABS(m_avcPicParam->ROI[i].Right - m_avcPicParam->ROI[i].Left))); |
| roiSize += (CODECHAL_MACROBLOCK_HEIGHT * MOS_ABS(m_avcPicParam->ROI[i].Top - m_avcPicParam->ROI[i].Bottom)) * |
| (CODECHAL_MACROBLOCK_WIDTH * MOS_ABS(m_avcPicParam->ROI[i].Right - m_avcPicParam->ROI[i].Left)); |
| } |
| |
| if (roiSize) |
| { |
| uint32_t numMBs = m_picWidthInMb * m_picHeightInMb; |
| roiRatio = 2 * (numMBs * 256 / roiSize - 1); |
| roiRatio = MOS_MIN(51, roiRatio); // clip QP from 0-51 |
| } |
| CODECHAL_ENCODE_VERBOSEMESSAGE("m_roiRatio = %d", roiRatio); |
| curbe.m_mbBrcUpdateCurbeCmd.DW0.m_roiRatio = roiRatio; |
| } |
| } |
| else |
| { |
| curbe.m_mbBrcUpdateCurbeCmd.DW0.m_roiRatio = 0; |
| } |
| |
| curbe.m_mbBrcUpdateCurbeCmd.DW8.m_historyBufferIndex = mbBrcUpdateHistory; |
| curbe.m_mbBrcUpdateCurbeCmd.DW9.m_mbqpBufferIndex = mbBrcUpdateMbQp; |
| curbe.m_mbBrcUpdateCurbeCmd.DW10.m_roiBufferIndex = mbBrcUpdateRoi; |
| curbe.m_mbBrcUpdateCurbeCmd.DW11.m_mbStatisticalBufferIndex = mbBrcUpdateMbStat; |
| auto pStateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface; |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pStateHeapInterface); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( |
| &curbe, |
| params->pKernelState->dwCurbeOffset, |
| sizeof(curbe))); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::UserFeatureKeyReport() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcEnc::UserFeatureKeyReport()); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| |
| // VE2.0 Reporting |
| CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENABLE_ENCODE_VE_CTXSCHEDULING_ID, MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface)); |
| |
| #endif // _DEBUG || _RELEASE_INTERNAL |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SendAvcMbEncSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_MBENC_SURFACE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSlcParams); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->ppRefList); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrOriginalPic); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrReconstructedPic); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->psCurrPicSurface); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcPicIdx); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pMbEncBindingTable); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); |
| |
| bool currFieldPicture = CodecHal_PictureIsField(*(params->pCurrOriginalPic)) ? 1 : 0; |
| bool currBottomField = CodecHal_PictureIsBottomField(*(params->pCurrOriginalPic)) ? 1 : 0; |
| uint32_t refMbCodeBottomFieldOffset = |
| params->dwFrameFieldHeightInMb * params->dwFrameWidthInMb * 64; |
| uint32_t refMvBottomFieldOffset = |
| MOS_ALIGN_CEIL(params->dwFrameFieldHeightInMb * params->dwFrameWidthInMb * (32 * 4), 0x1000); |
| |
| uint8_t vdirection, refVDirection; |
| if (params->bMbEncIFrameDistInUse) |
| { |
| vdirection = CODECHAL_VDIRECTION_FRAME; |
| } |
| else |
| { |
| vdirection = (CodecHal_PictureIsFrame(*(params->pCurrOriginalPic))) ? CODECHAL_VDIRECTION_FRAME : (currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD; |
| } |
| |
| // PAK Obj command buffer |
| uint32_t size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 16 * 4; // 11DW + 5DW padding |
| auto kernelState = params->pKernelState; |
| auto mbEncBindingTable = params->pMbEncBindingTable; |
| auto currPicRefListEntry = params->ppRefList[params->pCurrReconstructedPic->FrameIdx]; |
| auto mbCodeBuffer = &currPicRefListEntry->resRefMbCodeBuffer; |
| auto mvDataBuffer = &currPicRefListEntry->resRefMvDataBuffer; |
| |
| CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = mbCodeBuffer; |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.dwOffset = params->dwMbCodeBottomFieldOffset; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMfcAvcPakObj; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // MV data buffer |
| size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 32 * 4; |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = mvDataBuffer; |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.dwOffset = params->dwMvBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncIndMVData; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // Current Picture Y |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; // Use media block RW for DP 2D surface access |
| surfaceCodecParams.bUseUVPlane = true; |
| surfaceCodecParams.psSurface = params->psCurrPicSurface; |
| surfaceCodecParams.dwOffset = params->dwCurrPicSurfaceOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncCurrY; |
| surfaceCodecParams.dwUVBindingTableOffset = mbEncBindingTable->dwAvcMBEncCurrUV; |
| surfaceCodecParams.dwVerticalLineStride = params->dwVerticalLineStride; |
| surfaceCodecParams.dwVerticalLineStrideOffset = params->dwVerticalLineStrideOffset; |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // AVC_ME MV data buffer |
| if (params->bHmeEnabled) |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeMvDataBuffer); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->ps4xMeMvDataBuffer; |
| surfaceCodecParams.dwOffset = params->dwMeMvBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMVDataFromME; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeDistortionBuffer); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->ps4xMeDistortionBuffer; |
| surfaceCodecParams.dwOffset = params->dwMeDistortionBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMEDist; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->bMbConstDataBufferInUse) |
| { |
| // 16 DWs per QP value |
| size = 16 * 52 * sizeof(uint32_t); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = params->presMbBrcConstDataBuffer; |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MB_BRC_CONST_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMbBrcConstData; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->bMbQpBufferInUse) |
| { |
| // AVC MB BRC QP buffer |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->psMbQpBuffer; |
| surfaceCodecParams.dwOffset = params->dwMbQpBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = currFieldPicture ? mbEncBindingTable->dwAvcMBEncMbQpField : mbEncBindingTable->dwAvcMBEncMbQpFrame; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->bMbSpecificDataEnabled) |
| { |
| size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * sizeof(CODECHAL_ENCODE_AVC_MB_SPECIFIC_PARAMS); |
| CODECHAL_ENCODE_VERBOSEMESSAGE("Send MB specific surface, size = %d", size); |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.presBuffer = params->presMbSpecificDataBuffer; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMbSpecificData; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| // Current Picture Y - VME |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.psSurface = params->psCurrPicSurface; |
| surfaceCodecParams.dwOffset = params->dwCurrPicSurfaceOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = currFieldPicture ? mbEncBindingTable->dwAvcMBEncFieldCurrPic[0] : mbEncBindingTable->dwAvcMBEncCurrPicFrame[0]; |
| surfaceCodecParams.ucVDirection = vdirection; |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| surfaceCodecParams.dwBindingTableOffset = currFieldPicture ? mbEncBindingTable->dwAvcMBEncFieldCurrPic[1] : mbEncBindingTable->dwAvcMBEncCurrPicFrame[1]; |
| surfaceCodecParams.ucVDirection = vdirection; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // Setup references 1...n |
| // LIST 0 references |
| uint8_t refIdx; |
| for (refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l0_active_minus1; refIdx++) |
| { |
| auto refPic = params->pAvcSlcParams->RefPicList[LIST_0][refIdx]; |
| uint32_t refMbCodeBottomFieldOffsetUsed; |
| uint32_t refMvBottomFieldOffsetUsed; |
| uint32_t refBindingTableOffset; |
| if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid) |
| { |
| uint8_t refPicIdx = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx; |
| bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false; |
| // Program the surface based on current picture's field/frame mode |
| if (currFieldPicture) // if current picture is field |
| { |
| if (refBottomField) |
| { |
| refVDirection = CODECHAL_VDIRECTION_BOT_FIELD; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicBotField[refIdx]; |
| } |
| else |
| { |
| refVDirection = CODECHAL_VDIRECTION_TOP_FIELD; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicTopField[refIdx]; |
| } |
| } |
| else // if current picture is frame |
| { |
| refVDirection = CODECHAL_VDIRECTION_FRAME; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicFrame[refIdx]; |
| } |
| |
| // Picture Y VME |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| if ((0 == refIdx) && (params->bUseWeightedSurfaceForL0)) |
| { |
| surfaceCodecParams.psSurface = ¶ms->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L0_START + refIdx].sBuffer; |
| } |
| else |
| { |
| surfaceCodecParams.psSurface = ¶ms->ppRefList[refPicIdx]->sRefBuffer; |
| } |
| surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16; |
| surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16; |
| |
| surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset; |
| surfaceCodecParams.ucVDirection = refVDirection; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| |
| #if 1 |
| for (refIdx = (params->pAvcSlcParams->num_ref_idx_l0_active_minus1 + 1); refIdx < CODECHAL_ENCODE_NUM_MAX_VME_L0_REF; refIdx++) |
| { |
| auto refPic = params->pAvcSlcParams->RefPicList[LIST_0][0]; |
| uint32_t refMbCodeBottomFieldOffsetUsed; |
| uint32_t refMvBottomFieldOffsetUsed; |
| uint32_t refBindingTableOffset; |
| if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid) |
| { |
| uint8_t refPicIdx = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx; |
| bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false; |
| // Program the surface based on current picture's field/frame mode |
| if (currFieldPicture) // if current picture is field |
| { |
| if (refBottomField) |
| { |
| refVDirection = CODECHAL_VDIRECTION_BOT_FIELD; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicBotField[refIdx]; |
| } |
| else |
| { |
| refVDirection = CODECHAL_VDIRECTION_TOP_FIELD; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicTopField[refIdx]; |
| } |
| } |
| else // if current picture is frame |
| { |
| refVDirection = CODECHAL_VDIRECTION_FRAME; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncFwdPicFrame[refIdx]; |
| } |
| |
| // Picture Y VME |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| if ((0 == refIdx) && (params->bUseWeightedSurfaceForL0)) |
| { |
| surfaceCodecParams.psSurface = ¶ms->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L0_START + refIdx].sBuffer; |
| } |
| else |
| { |
| surfaceCodecParams.psSurface = ¶ms->ppRefList[refPicIdx]->sRefBuffer; |
| } |
| surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16; |
| surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16; |
| |
| surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset; |
| surfaceCodecParams.ucVDirection = refVDirection; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| |
| if (params->pAvcSlcParams->num_ref_idx_l1_active_minus1 == 0) |
| { |
| for (refIdx = 0; refIdx <= MOS_MIN(params->pAvcSlcParams->num_ref_idx_l0_active_minus1, 1); refIdx++) |
| { |
| auto refPic = params->pAvcSlcParams->RefPicList[LIST_0][refIdx]; |
| uint32_t refMbCodeBottomFieldOffsetUsed; |
| uint32_t refMvBottomFieldOffsetUsed; |
| uint32_t refBindingTableOffset; |
| if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid) |
| { |
| uint8_t refPicIdx = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx; |
| bool refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? true : false; |
| // Program the surface based on current picture's field/frame mode |
| if (currFieldPicture) // if current picture is field |
| { |
| if (refBottomField) |
| { |
| refVDirection = CODECHAL_VDIRECTION_BOT_FIELD; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicBotField[refIdx]; |
| } |
| else |
| { |
| refVDirection = CODECHAL_VDIRECTION_TOP_FIELD; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicTopField[refIdx]; |
| } |
| } |
| else // if current picture is frame |
| { |
| refVDirection = CODECHAL_VDIRECTION_FRAME; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicFrame[refIdx]; |
| } |
| |
| // Picture Y VME |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| if ((0 == refIdx) && (params->bUseWeightedSurfaceForL0)) |
| { |
| surfaceCodecParams.psSurface = ¶ms->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L0_START + refIdx].sBuffer; |
| } |
| else |
| { |
| surfaceCodecParams.psSurface = ¶ms->ppRefList[refPicIdx]->sRefBuffer; |
| } |
| surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16; |
| surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16; |
| |
| surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset; |
| surfaceCodecParams.ucVDirection = refVDirection; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| } |
| #endif |
| |
| // Setup references 1...n |
| // LIST 1 references |
| uint32_t curbeSize; |
| for (refIdx = 0; refIdx <= params->pAvcSlcParams->num_ref_idx_l1_active_minus1; refIdx++) |
| { |
| if (!currFieldPicture && refIdx > 0) |
| { |
| // Only 1 LIST 1 reference required here since only single ref is supported in frame case |
| break; |
| } |
| |
| auto refPic = params->pAvcSlcParams->RefPicList[LIST_1][refIdx]; |
| uint32_t refMbCodeBottomFieldOffsetUsed; |
| uint32_t refMvBottomFieldOffsetUsed; |
| uint32_t refBindingTableOffset; |
| bool refBottomField; |
| uint8_t refPicIdx; |
| if (!CodecHal_PictureIsInvalid(refPic) && params->pAvcPicIdx[refPic.FrameIdx].bValid) |
| { |
| refPicIdx = params->pAvcPicIdx[refPic.FrameIdx].ucPicIdx; |
| refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0; |
| // Program the surface based on current picture's field/frame mode |
| if (currFieldPicture) // if current picture is field |
| { |
| if (refBottomField) |
| { |
| refVDirection = CODECHAL_VDIRECTION_BOT_FIELD; |
| refMbCodeBottomFieldOffsetUsed = refMbCodeBottomFieldOffset; |
| refMvBottomFieldOffsetUsed = refMvBottomFieldOffset; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicBotField[refIdx]; |
| } |
| else |
| { |
| refVDirection = CODECHAL_VDIRECTION_TOP_FIELD; |
| refMbCodeBottomFieldOffsetUsed = 0; |
| refMvBottomFieldOffsetUsed = 0; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicTopField[refIdx]; |
| } |
| } |
| else // if current picture is frame |
| { |
| refVDirection = CODECHAL_VDIRECTION_FRAME; |
| refMbCodeBottomFieldOffsetUsed = 0; |
| refMvBottomFieldOffsetUsed = 0; |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicFrame[refIdx]; |
| } |
| |
| // Picture Y VME |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| if ((0 == refIdx) && (params->bUseWeightedSurfaceForL1)) |
| { |
| surfaceCodecParams.psSurface = ¶ms->pWeightedPredOutputPicSelectList[CODEC_AVC_WP_OUTPUT_L1_START + refIdx].sBuffer; |
| } |
| else |
| { |
| surfaceCodecParams.psSurface = ¶ms->ppRefList[refPicIdx]->sRefBuffer; |
| } |
| surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16; |
| surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16; |
| |
| surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset; |
| surfaceCodecParams.ucVDirection = refVDirection; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| if (refIdx == 0) |
| { |
| // MB data buffer |
| size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 16 * 4; |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.presBuffer = ¶ms->ppRefList[refPicIdx]->resRefMbCodeBuffer; |
| surfaceCodecParams.dwOffset = refMbCodeBottomFieldOffsetUsed; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdRefMBData; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // MV data buffer |
| size = params->dwFrameWidthInMb * params->dwFrameFieldHeightInMb * 32 * 4; |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.presBuffer = ¶ms->ppRefList[refPicIdx]->resRefMvDataBuffer; |
| surfaceCodecParams.dwOffset = refMvBottomFieldOffsetUsed; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdRefMVData; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (refIdx < CODECHAL_ENCODE_NUM_MAX_VME_L1_REF) |
| { |
| if (currFieldPicture) |
| { |
| // The binding table contains multiple entries for IDX0 backwards references |
| if (refBottomField) |
| { |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicBotField[refIdx + CODECHAL_ENCODE_NUM_MAX_VME_L1_REF]; |
| } |
| else |
| { |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicTopField[refIdx + CODECHAL_ENCODE_NUM_MAX_VME_L1_REF]; |
| } |
| } |
| else |
| { |
| refBindingTableOffset = mbEncBindingTable->dwAvcMBEncBwdPicFrame[refIdx + CODECHAL_ENCODE_NUM_MAX_VME_L1_REF]; |
| } |
| |
| // Picture Y VME |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.dwWidthInUse = params->dwFrameWidthInMb * 16; |
| surfaceCodecParams.dwHeightInUse = params->dwFrameHeightInMb * 16; |
| surfaceCodecParams.psSurface = ¶ms->ppRefList[refPicIdx]->sRefBuffer; |
| surfaceCodecParams.dwBindingTableOffset = refBindingTableOffset; |
| surfaceCodecParams.ucVDirection = refVDirection; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| } |
| |
| // BRC distortion data buffer for I frame |
| if (params->bMbEncIFrameDistInUse) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->psMeBrcDistortionBuffer; |
| surfaceCodecParams.dwOffset = params->dwMeBrcDistortionBottomFieldOffset; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncBRCDist; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| // RefPicSelect of Current Picture |
| if (params->bUsedAsRef) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = &currPicRefListEntry->pRefPicSelectListEntry->sBuffer; |
| surfaceCodecParams.psSurface->dwHeight = MOS_ALIGN_CEIL(surfaceCodecParams.psSurface->dwHeight, 8); |
| surfaceCodecParams.dwOffset = params->dwRefPicSelectBottomFieldOffset; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncRefPicSelectL0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->bMBVProcStatsEnabled) |
| { |
| size = params->dwFrameWidthInMb * |
| (currFieldPicture ? params->dwFrameFieldHeightInMb : params->dwFrameHeightInMb) * |
| 16 * sizeof(uint32_t); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.presBuffer = params->presMBVProcStatsBuffer; |
| surfaceCodecParams.dwOffset = currBottomField ? params->dwMBVProcStatsBottomFieldOffset : 0; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMBStats; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| else if (params->bFlatnessCheckEnabled) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->psFlatnessCheckSurface; |
| surfaceCodecParams.dwOffset = currBottomField ? params->dwFlatnessCheckBottomFieldOffset : 0; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncFlatnessChk; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE].Value; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->bMADEnabled) |
| { |
| size = CODECHAL_MAD_BUFFER_SIZE; |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bRawSurface = true; |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.presBuffer = params->presMADDataBuffer; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMADData; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MAD_ENCODE].Value; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->dwMbEncBRCBufferSize > 0) |
| { |
| // MbEnc BRC buffer - write only |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = params->presMbEncBRCBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(params->dwMbEncBRCBufferSize); |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMbEncBRCCurbeData; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE].Value; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| else |
| { |
| if (params->bUseMbEncAdvKernel) |
| { |
| // For BRC the new BRC surface is used |
| if (params->bUseAdvancedDsh) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = params->presMbEncCurbeBuffer; |
| curbeSize = MOS_ALIGN_CEIL( |
| params->pKernelState->KernelParams.iCurbeLength, |
| m_hwInterface->GetRenderInterface()->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()); |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(curbeSize); |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMbEncBRCCurbeData; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE].Value; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| else // For CQP the DSH CURBE is used |
| { |
| MOS_RESOURCE *dsh = nullptr; |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = params->pKernelState->m_dshRegion.GetResource()); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = dsh; |
| surfaceCodecParams.dwOffset = |
| params->pKernelState->m_dshRegion.GetOffset() + |
| params->pKernelState->dwCurbeOffset; |
| curbeSize = MOS_ALIGN_CEIL( |
| params->pKernelState->KernelParams.iCurbeLength, |
| m_hwInterface->GetRenderInterface()->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()); |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(curbeSize); |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMbEncBRCCurbeData; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE].Value; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| } |
| |
| if (params->bArbitraryNumMbsInSlice) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->psSliceMapSurface; |
| surfaceCodecParams.bRenderTarget = false; |
| surfaceCodecParams.bIsWritable = false; |
| surfaceCodecParams.dwOffset = currBottomField ? params->dwSliceMapBottomFieldOffset : 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_SLICE_MAP_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncSliceMapData; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (!params->bMbEncIFrameDistInUse) |
| { |
| if (params->bMbDisableSkipMapEnabled) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->psMbDisableSkipMapSurface; |
| surfaceCodecParams.dwOffset = 0; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncMbNonSkipMap; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_MBDISABLE_SKIPMAP_CODEC].Value; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| if (params->bStaticFrameDetectionEnabled) |
| { |
| // static frame cost table surface |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = params->presSFDCostTableBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(m_sfdCostTableBufferSize); |
| surfaceCodecParams.dwOffset = 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbEncBindingTable->dwAvcMBEncStaticDetectionCostTable; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = m_swScoreboardState->GetCurSwScoreboardSurface(); |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.dwOffset = 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = mbencSwScoreboard; |
| surfaceCodecParams.bUse32UINTSurfaceFormat = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SendAvcWPSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_WP_SURFACE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->psInputRefBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->psOutputScaledBuffer); |
| |
| CODECHAL_SURFACE_CODEC_PARAMS surfaceParams; |
| memset((void *)&surfaceParams, 0, sizeof(surfaceParams)); |
| surfaceParams.bIs2DSurface = true; |
| surfaceParams.bMediaBlockRW = true; |
| surfaceParams.psSurface = params->psInputRefBuffer; // Input surface |
| surfaceParams.bIsWritable = false; |
| surfaceParams.bRenderTarget = false; |
| surfaceParams.dwBindingTableOffset = wpInputRefSurface; |
| surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE].Value; |
| surfaceParams.dwVerticalLineStride = params->dwVerticalLineStride; |
| surfaceParams.dwVerticalLineStrideOffset = params->dwVerticalLineStrideOffset; |
| surfaceParams.ucVDirection = params->ucVDirection; |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceParams)); |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceParams, |
| params->pKernelState)); |
| |
| memset((void *)&surfaceParams, 0, sizeof(surfaceParams)); |
| surfaceParams.bIs2DSurface = true; |
| surfaceParams.bMediaBlockRW = true; |
| surfaceParams.psSurface = params->psOutputScaledBuffer; // output surface |
| surfaceParams.bIsWritable = true; |
| surfaceParams.bRenderTarget = true; |
| surfaceParams.dwBindingTableOffset = wpOutputScaledSurface; |
| surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE].Value; |
| surfaceParams.dwVerticalLineStride = params->dwVerticalLineStride; |
| surfaceParams.dwVerticalLineStrideOffset = params->dwVerticalLineStrideOffset; |
| surfaceParams.ucVDirection = params->ucVDirection; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceParams, |
| params->pKernelState)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SendAvcBrcFrameUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBrcBuffers); |
| |
| // BRC history buffer |
| CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; |
| auto kernelState = params->pKernelState; |
| auto brcUpdateBindingTable = params->pBrcUpdateBindingTable; |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = ¶ms->pBrcBuffers->resBrcHistoryBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(params->dwBrcHistoryBufferSize); |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcHistoryBuffer; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // PAK Statistics buffer |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = ¶ms->pBrcBuffers->resBrcPakStatisticBuffer[0]; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(params->dwBrcPakStatisticsSize); |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_PAK_STATS_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcPakStatisticsOutputBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // PAK IMG_STATEs buffer - read only |
| uint32_t size = MOS_BYTES_TO_DWORDS(BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses()); |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = ¶ms->pBrcBuffers->resBrcImageStatesReadBuffer[params->ucCurrRecycledBufIdx]; |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcImageStateReadBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // PAK IMG_STATEs buffer - write only |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = ¶ms->pBrcBuffers->resBrcImageStatesWriteBuffer; |
| surfaceCodecParams.dwSize = size; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcImageStateWriteBuffer; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| if (params->dwMbEncBRCBufferSize > 0) |
| { |
| // MbEnc BRC buffer - write only |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = ¶ms->pBrcBuffers->resMbEncBrcBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(params->dwMbEncBRCBufferSize); |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MBENC_BRC_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMbEncCurbeWriteData; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| else |
| { |
| PMHW_KERNEL_STATE mbEncKernelState; |
| CODECHAL_ENCODE_CHK_NULL_RETURN(mbEncKernelState = params->pBrcBuffers->pMbEncKernelStateInUse); |
| |
| MOS_RESOURCE *dsh = nullptr; |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = mbEncKernelState->m_dshRegion.GetResource()); |
| |
| // BRC ENC CURBE Buffer - read only |
| size = MOS_ALIGN_CEIL( |
| mbEncKernelState->KernelParams.iCurbeLength, |
| m_renderEngineInterface->m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment()); |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = dsh; |
| surfaceCodecParams.dwOffset = |
| mbEncKernelState->m_dshRegion.GetOffset() + |
| mbEncKernelState->dwCurbeOffset; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(size); |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMbEncCurbeReadBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // BRC ENC CURBE Buffer - write only |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| if (params->bUseAdvancedDsh) |
| { |
| surfaceCodecParams.presBuffer = params->presMbEncCurbeBuffer; |
| } |
| else |
| { |
| surfaceCodecParams.presBuffer = dsh; |
| surfaceCodecParams.dwOffset = |
| mbEncKernelState->m_dshRegion.GetOffset() + |
| mbEncKernelState->dwCurbeOffset; |
| } |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(size); |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMbEncCurbeWriteData; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| // AVC_ME BRC Distortion data buffer - input/output |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = ¶ms->pBrcBuffers->sMeBrcDistortionBuffer; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value; |
| surfaceCodecParams.dwOffset = params->pBrcBuffers->dwMeBrcDistortionBottomFieldOffset; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcDistortionBuffer; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.bIsWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // BRC Constant Data Surface |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = ¶ms->pBrcBuffers->sBrcConstantDataBuffer[params->ucCurrRecycledBufIdx]; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_CONSTANT_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcConstantData; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // MBStat buffer - input |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = params->presMbStatBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(m_hwInterface->m_avcMbStatBufferSize); |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_MB_STATS_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMbStatBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // MV data buffer |
| if (params->psMvDataBuffer) |
| { |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = params->psMvDataBuffer; |
| surfaceCodecParams.dwOffset = params->dwMvBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwFrameBrcMvDataBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SendAvcBrcMbUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_BRC_UPDATE_SURFACE_PARAMS params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBrcBuffers); |
| |
| // BRC history buffer |
| auto kernelState = params->pKernelState; |
| auto brcUpdateBindingTable = params->pBrcUpdateBindingTable; |
| CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = ¶ms->pBrcBuffers->resBrcHistoryBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(params->dwBrcHistoryBufferSize); |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwMbBrcHistoryBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| // AVC MB QP data buffer |
| if (params->bMbBrcEnabled) |
| { |
| params->pBrcBuffers->sBrcMbQpBuffer.dwHeight = MOS_ALIGN_CEIL((params->dwDownscaledFrameFieldHeightInMb4x << 2), 8); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.psSurface = ¶ms->pBrcBuffers->sBrcMbQpBuffer; |
| surfaceCodecParams.dwOffset = params->pBrcBuffers->dwBrcMbQpBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwMbBrcMbQpBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| // BRC ROI feature |
| if (params->bBrcRoiEnabled) |
| { |
| params->psRoiSurface->dwHeight = MOS_ALIGN_CEIL((params->dwDownscaledFrameFieldHeightInMb4x << 2), 8); |
| |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.bIsWritable = false; |
| surfaceCodecParams.bRenderTarget = true; |
| surfaceCodecParams.psSurface = params->psRoiSurface; |
| surfaceCodecParams.dwOffset = 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ROI_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwMbBrcROISurface; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| // MBStat buffer |
| memset((void *)&surfaceCodecParams, 0, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.presBuffer = params->presMbStatBuffer; |
| surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(m_hwInterface->m_avcMbStatBufferSize); |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_MB_STATS_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = brcUpdateBindingTable->dwMbBrcMbStatBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetGpuCtxCreatOption() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface)) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::SetGpuCtxCreatOption()); |
| } |
| else |
| { |
| m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_gpuCtxCreatOpt); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalEncodeSinglePipeVE_ConstructParmsForGpuCtxCreation( |
| m_sinlgePipeVeState, |
| (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt)); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SetupROISurface() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MOS_LOCK_PARAMS readOnly; |
| memset(&readOnly, 0, sizeof(readOnly)); |
| readOnly.ReadOnly = 1; |
| uint32_t * dataPtr = (uint32_t *)m_osInterface->pfnLockResource(m_osInterface, &BrcBuffers.sBrcRoiSurface.OsResource, &readOnly); |
| if (!dataPtr) |
| { |
| eStatus = MOS_STATUS_INVALID_HANDLE; |
| return eStatus; |
| } |
| |
| uint32_t bufferWidthInByte = BrcBuffers.sBrcRoiSurface.dwPitch; |
| uint32_t bufferHeightInByte = MOS_ALIGN_CEIL((m_downscaledHeightInMb4x << 2), 8); |
| uint32_t numMBs = m_picWidthInMb * m_picHeightInMb; |
| for (uint32_t uMB = 0; uMB <= numMBs; uMB++) |
| { |
| int32_t curMbY = uMB / m_picWidthInMb; |
| int32_t curMbX = uMB - curMbY * m_picWidthInMb; |
| |
| uint32_t outdata = 0; |
| for (int32_t roiIdx = (m_avcPicParam->NumROI - 1); roiIdx >= 0; roiIdx--) |
| { |
| int32_t qpLevel; |
| if (bROIValueInDeltaQP) |
| { |
| qpLevel = -m_avcPicParam->ROI[roiIdx].PriorityLevelOrDQp; |
| } |
| else |
| { |
| // QP Level sent to ROI surface is (priority * 6) |
| qpLevel = m_avcPicParam->ROI[roiIdx].PriorityLevelOrDQp * 6; |
| } |
| |
| if (qpLevel == 0) |
| { |
| continue; |
| } |
| |
| if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right) && |
| (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom)) |
| { |
| outdata = 15 | ((qpLevel & 0xFF) << 8); |
| } |
| else if (bROISmoothEnabled) |
| { |
| if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left - 1) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right + 1) && |
| (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top - 1) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom + 1)) |
| { |
| outdata = 14 | ((qpLevel & 0xFF) << 8); |
| } |
| else if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left - 2) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right + 2) && |
| (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top - 2) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom + 2)) |
| { |
| outdata = 13 | ((qpLevel & 0xFF) << 8); |
| } |
| else if ((curMbX >= (int32_t)m_avcPicParam->ROI[roiIdx].Left - 3) && (curMbX < (int32_t)m_avcPicParam->ROI[roiIdx].Right + 3) && |
| (curMbY >= (int32_t)m_avcPicParam->ROI[roiIdx].Top - 3) && (curMbY < (int32_t)m_avcPicParam->ROI[roiIdx].Bottom + 3)) |
| { |
| outdata = 12 | ((qpLevel & 0xFF) << 8); |
| } |
| } |
| } |
| dataPtr[(curMbY * (bufferWidthInByte >> 2)) + curMbX] = outdata; |
| } |
| |
| m_osInterface->pfnUnlockResource(m_osInterface, &BrcBuffers.sBrcRoiSurface.OsResource); |
| |
| uint32_t bufferSize = bufferWidthInByte * bufferHeightInByte; |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &BrcBuffers.sBrcRoiSurface.OsResource, |
| CodechalDbgAttr::attrInput, |
| "ROI", |
| bufferSize, |
| 0, |
| CODECHAL_MEDIA_STATE_MB_BRC_UPDATE))); |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::SendPrologWithFrameTracking( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| bool frameTracking, |
| MHW_MI_MMIOREGISTERS *mmioRegister) |
| { |
| if (MOS_VE_SUPPORTED(m_osInterface) && cmdBuffer->Attributes.pAttriVe) |
| { |
| PMOS_CMD_BUF_ATTRI_VE attriExt = |
| (PMOS_CMD_BUF_ATTRI_VE)(cmdBuffer->Attributes.pAttriVe); |
| attriExt->bUseVirtualEngineHint = true; |
| attriExt->VEngineHintParams.NeedSyncWithPrevious = 1; |
| } |
| |
| return CodechalEncodeAvcEnc::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister); |
| } |
| |
| void CodechalEncodeAvcEncG12::ResizeOnResChange() |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CodechalEncoderState::ResizeOnResChange(); |
| |
| // need to re-allocate surfaces according to resolution |
| m_swScoreboardState->ReleaseResources(); |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::InitKernelStateMe() |
| { |
| m_hmeKernel = MOS_New(CodechalKernelHmeG12, this); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_hmeKernel); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->Initialize( |
| GetCommonKernelHeaderAndSizeG12, |
| m_kernelBase, |
| m_kuidCommon)); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::UpdateCmdBufAttribute( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| bool renderEngineInUse) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| // should not be there. Will remove it in the next change |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| if (MOS_VE_SUPPORTED(m_osInterface)) |
| { |
| PMOS_CMD_BUF_ATTRI_VE attriExt = |
| (PMOS_CMD_BUF_ATTRI_VE)(cmdBuffer->Attributes.pAttriVe); |
| |
| memset((void *)attriExt, 0, sizeof(MOS_CMD_BUF_ATTRI_VE)); |
| attriExt->bUseVirtualEngineHint = |
| attriExt->VEngineHintParams.NeedSyncWithPrevious = !renderEngineInUse; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::AddMediaVfeCmd( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| SendKernelCmdsParams *params) |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| |
| MHW_VFE_PARAMS_G12 vfeParams = {}; |
| vfeParams.pKernelState = params->pKernelState; |
| vfeParams.eVfeSliceDisable = MHW_VFE_SLICE_ALL; |
| vfeParams.dwMaximumNumberofThreads = m_encodeVfeMaxThreads; |
| vfeParams.bFusedEuDispatch = false; // legacy mode |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaVfeCmd(cmdBuffer, &vfeParams)); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| #if USE_CODECHAL_DEBUG_TOOL |
| MOS_STATUS CodechalEncodeAvcEncG12::KernelDebugDumps() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| CODECHAL_DEBUG_TOOL( |
| if (m_hmeEnabled) { |
| CODECHAL_ME_OUTPUT_PARAMS meOutputParams; |
| |
| memset((void *)&meOutputParams, 0, sizeof(meOutputParams)); |
| meOutputParams.psMeMvBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer); |
| meOutputParams.psMeDistortionBuffer = |
| m_4xMeDistortionBufferSupported ? |
| m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : nullptr; |
| meOutputParams.b16xMeInUse = false; |
| meOutputParams.b32xMeInUse = false; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &meOutputParams.psMeMvBuffer->OsResource, |
| CodechalDbgAttr::attrOutput, |
| "MvData", |
| meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch, |
| CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) * (m_downscaledFrameFieldHeightInMb4x * 4) : 0, |
| CODECHAL_MEDIA_STATE_4X_ME)); |
| |
| if (meOutputParams.psMeDistortionBuffer) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &meOutputParams.psMeDistortionBuffer->OsResource, |
| CodechalDbgAttr::attrOutput, |
| "MeDist", |
| meOutputParams.psMeDistortionBuffer->dwHeight *meOutputParams.psMeDistortionBuffer->dwPitch, |
| m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset, |
| CODECHAL_MEDIA_STATE_4X_ME)); |
| } |
| |
| if (m_16xMeEnabled) |
| { |
| meOutputParams.psMeMvBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me16xMvDataBuffer); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN( |
| m_debugInterface->DumpBuffer( |
| &meOutputParams.psMeMvBuffer->OsResource, |
| CodechalDbgAttr::attrOutput, |
| "MvData", |
| meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch, |
| CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) * (m_downscaledFrameFieldHeightInMb16x * 4) : 0, |
| CODECHAL_MEDIA_STATE_16X_ME)); |
| |
| if (m_32xMeEnabled) |
| { |
| meOutputParams.psMeMvBuffer = m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me32xMvDataBuffer); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN( |
| m_debugInterface->DumpBuffer( |
| &meOutputParams.psMeMvBuffer->OsResource, |
| CodechalDbgAttr::attrOutput, |
| "MvData", |
| meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch, |
| CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64) * (m_downscaledFrameFieldHeightInMb16x * 4) : 0, |
| CODECHAL_MEDIA_STATE_32X_ME)); |
| } |
| } |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &BrcBuffers.resBrcImageStatesWriteBuffer, |
| CodechalDbgAttr::attrOutput, |
| "ImgStateWrite", |
| BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(), |
| 0, |
| CODECHAL_MEDIA_STATE_BRC_UPDATE)); |
| |
| if (!Mos_ResourceIsNull(&BrcBuffers.sBrcMbQpBuffer.OsResource)) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &BrcBuffers.sBrcMbQpBuffer.OsResource, |
| CodechalDbgAttr::attrOutput, |
| "MbQp", |
| BrcBuffers.sBrcMbQpBuffer.dwPitch*BrcBuffers.sBrcMbQpBuffer.dwHeight, |
| BrcBuffers.dwBrcMbQpBottomFieldOffset, |
| CODECHAL_MEDIA_STATE_MB_BRC_UPDATE)); |
| } |
| if (bMbBrcEnabled) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &BrcBuffers.resBrcHistoryBuffer, |
| CodechalDbgAttr::attrOutput, |
| "HistoryWrite", |
| m_brcHistoryBufferSize, |
| 0, |
| CODECHAL_MEDIA_STATE_MB_BRC_UPDATE)); |
| } |
| if (BrcBuffers.pMbEncKernelStateInUse) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( |
| CODECHAL_MEDIA_STATE_BRC_UPDATE, |
| BrcBuffers.pMbEncKernelStateInUse)); |
| } |
| if (m_mbencBrcBufferSize > 0) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &BrcBuffers.resMbEncBrcBuffer, |
| CodechalDbgAttr::attrOutput, |
| "MbEncBRCWrite", |
| m_mbencBrcBufferSize, |
| 0, |
| CODECHAL_MEDIA_STATE_BRC_UPDATE)); |
| } |
| |
| if (m_mbStatsSupported) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &m_resMbStatsBuffer, |
| CodechalDbgAttr::attrOutput, |
| "MBStatsSurf", |
| m_picWidthInMb * m_frameFieldHeightInMb * 16 * sizeof(uint32_t), |
| CodecHal_PictureIsBottomField(m_currOriginalPic) ? m_mbStatsBottomFieldOffset : 0, |
| CODECHAL_MEDIA_STATE_4X_SCALING)); |
| } |
| |
| else if (m_flatnessCheckEnabled) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &m_flatnessCheckSurface.OsResource, |
| CodechalDbgAttr::attrOutput, |
| "FlatnessChkSurf", |
| ((CodecHal_PictureIsField(m_currOriginalPic)) ? m_flatnessCheckSurface.dwHeight / 2 : m_flatnessCheckSurface.dwHeight) * m_flatnessCheckSurface.dwPitch, |
| CodecHal_PictureIsBottomField(m_currOriginalPic) ? (m_flatnessCheckSurface.dwPitch * m_flatnessCheckSurface.dwHeight >> 1) : 0, |
| CODECHAL_MEDIA_STATE_4X_SCALING)); |
| } |
| if (bMbQpDataEnabled) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &sMbQpDataSurface.OsResource, |
| CodechalDbgAttr::attrInput, |
| "MbQp", |
| sMbQpDataSurface.dwHeight*sMbQpDataSurface.dwPitch, |
| 0, |
| CODECHAL_MEDIA_STATE_ENC_QUALITY)); |
| } |
| |
| if (bMbSpecificDataEnabled) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &resMbSpecificDataBuffer[m_currRecycledBufIdx], |
| CodechalDbgAttr::attrInput, |
| "MbSpecificData", |
| m_picWidthInMb*m_frameFieldHeightInMb * 16, |
| 0, |
| CODECHAL_MEDIA_STATE_ENC_QUALITY)); |
| } |
| |
| uint8_t index; |
| CODEC_PICTURE refPic; |
| if (bUseWeightedSurfaceForL0) { |
| refPic = m_avcSliceParams->RefPicList[LIST_0][0]; |
| index = m_picIdx[refPic.FrameIdx].ucPicIdx; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &m_refList[index]->sRefBuffer, |
| CodechalDbgAttr::attrEncodeRawInputSurface, |
| "WP_In_L0")); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &WeightedPredOutputPicSelectList[LIST_0].sBuffer, |
| CodechalDbgAttr::attrEncodeRawInputSurface, |
| "WP_Out_L0")); |
| |
| } if (bUseWeightedSurfaceForL1) { |
| |
| refPic = m_avcSliceParams->RefPicList[LIST_1][0]; |
| index = m_picIdx[refPic.FrameIdx].ucPicIdx; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &m_refList[index]->sRefBuffer, |
| CodechalDbgAttr::attrEncodeRawInputSurface, |
| "WP_In_L1")); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &WeightedPredOutputPicSelectList[LIST_1].sBuffer, |
| CodechalDbgAttr::attrEncodeRawInputSurface, |
| "WP_Out_L1")); |
| } |
| |
| if (m_feiEnable) { |
| if (m_avcFeiPicParams->bMBQp) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &m_avcFeiPicParams->resMBQp, |
| CodechalDbgAttr::attrInput, |
| "MbQp", |
| m_picWidthInMb * m_frameFieldHeightInMb + 3, |
| 0, |
| CODECHAL_MEDIA_STATE_ENC_QUALITY)); |
| } |
| if (m_avcFeiPicParams->MVPredictorEnable) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &m_avcFeiPicParams->resMVPredictor, |
| CodechalDbgAttr::attrInput, |
| "MvPredictor", |
| m_picWidthInMb * m_frameFieldHeightInMb * 40, |
| 0, |
| CODECHAL_MEDIA_STATE_ENC_QUALITY)); |
| } |
| } |
| if (m_arbitraryNumMbsInSlice) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &m_sliceMapSurface[m_currRecycledBufIdx].OsResource, |
| CodechalDbgAttr::attrInput, |
| "SliceMapSurf", |
| m_sliceMapSurface[m_currRecycledBufIdx].dwPitch * m_frameFieldHeightInMb, |
| 0, |
| CODECHAL_MEDIA_STATE_ENC_QUALITY)); |
| } |
| |
| // Dump SW scoreboard surface |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| &(m_swScoreboardState->GetCurSwScoreboardSurface())->OsResource, |
| CodechalDbgAttr::attrOutput, |
| "Out", |
| (m_swScoreboardState->GetCurSwScoreboardSurface())->dwHeight * (m_swScoreboardState->GetCurSwScoreboardSurface())->dwPitch, |
| 0, |
| CODECHAL_MEDIA_STATE_SW_SCOREBOARD_INIT));) |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::PopulateBrcInitParam( |
| void *cmd) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_CHK_NULL(m_debugInterface); |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| CodechalEncodeAvcEncG12::BrcInitResetCurbe *curbe = (CodechalEncodeAvcEncG12::BrcInitResetCurbe *)cmd; |
| |
| if (m_pictureCodingType == I_TYPE) |
| { |
| m_avcPar->MBBRCEnable = bMbBrcEnabled; |
| m_avcPar->MBRC = bMbBrcEnabled; |
| m_avcPar->BitRate = curbe->m_brcInitResetCurbeCmd.m_dw3.m_averageBitRate; |
| m_avcPar->InitVbvFullnessInBit = curbe->m_brcInitResetCurbeCmd.m_dw1.m_initBufFullInBits; |
| m_avcPar->MaxBitRate = curbe->m_brcInitResetCurbeCmd.m_dw4.m_maxBitRate; |
| m_avcPar->VbvSzInBit = curbe->m_brcInitResetCurbeCmd.m_dw2.m_bufSizeInBits; |
| m_avcPar->AvbrAccuracy = curbe->m_brcInitResetCurbeCmd.m_dw10.m_avbrAccuracy; |
| m_avcPar->AvbrConvergence = curbe->m_brcInitResetCurbeCmd.m_dw11.m_avbrConvergence; |
| m_avcPar->SlidingWindowSize = curbe->m_brcInitResetCurbeCmd.m_dw22.m_slidingWindowSize; |
| m_avcPar->LongTermInterval = curbe->m_brcInitResetCurbeCmd.m_dw24.m_longTermInterval; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::PopulateBrcUpdateParam( |
| void *cmd) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_CHK_NULL(m_debugInterface); |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| CodechalEncodeAvcEncG12::FrameBrcUpdateCurbe *curbe = (CodechalEncodeAvcEncG12::FrameBrcUpdateCurbe *)cmd; |
| |
| if (m_pictureCodingType == I_TYPE) |
| { |
| m_avcPar->EnableMultipass = (curbe->m_frameBrcUpdateCurbeCmd.m_dw5.m_maxNumPAKs > 0) ? 1 : 0; |
| m_avcPar->MaxNumPakPasses = curbe->m_frameBrcUpdateCurbeCmd.m_dw5.m_maxNumPAKs; |
| m_avcPar->SlidingWindowEnable = curbe->m_frameBrcUpdateCurbeCmd.m_dw6.m_enableSlidingWindow; |
| m_avcPar->FrameSkipEnable = curbe->m_frameBrcUpdateCurbeCmd.m_dw6.m_enableForceToSkip; |
| m_avcPar->UserMaxFrame = curbe->m_frameBrcUpdateCurbeCmd.m_dw19.m_userMaxFrame; |
| } |
| else |
| { |
| m_avcPar->UserMaxFrameP = curbe->m_frameBrcUpdateCurbeCmd.m_dw19.m_userMaxFrame; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::PopulateEncParam( |
| uint8_t meMethod, |
| void *cmd) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_CHK_NULL(m_debugInterface); |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MbencCurbe *curbe = (MbencCurbe *)cmd; |
| |
| if (m_pictureCodingType == I_TYPE) |
| { |
| m_avcPar->MRDisableQPCheck = MRDisableQPCheck[m_targetUsage]; |
| m_avcPar->AllFractional = |
| CODECHAL_ENCODE_AVC_AllFractional_Common[m_targetUsage & 0x7]; |
| m_avcPar->DisableAllFractionalCheckForHighRes = |
| CODECHAL_ENCODE_AVC_DisableAllFractionalCheckForHighRes_Common[m_targetUsage & 0x7]; |
| m_avcPar->EnableAdaptiveSearch = curbe->m_curbe.DW37.m_adaptiveEn; |
| m_avcPar->EnableFBRBypass = curbe->m_curbe.DW4.m_enableFBRBypass; |
| m_avcPar->BlockBasedSkip = curbe->m_curbe.DW3.m_blockBasedSkipEnable; |
| m_avcPar->MADEnableFlag = curbe->m_curbe.DW34.m_madEnableFlag; |
| m_avcPar->MBTextureThreshold = curbe->m_curbe.DW60.m_mbTextureThreshold; |
| m_avcPar->EnableMBFlatnessCheckOptimization = curbe->m_curbe.DW34.m_enableMBFlatnessChkOptimization; |
| m_avcPar->EnableArbitrarySliceSize = curbe->m_curbe.DW34.m_arbitraryNumMbsPerSlice; |
| m_avcPar->RefThresh = curbe->m_curbe.DW38.m_refThreshold; |
| m_avcPar->EnableWavefrontOptimization = curbe->m_curbe.DW4.m_enableWavefrontOptimization; |
| m_avcPar->MaxLenSP = curbe->m_curbe.DW2.m_lenSP; |
| m_avcPar->DisableExtendedMvCostRange = !curbe->m_curbe.DW1.m_extendedMvCostRange; |
| } |
| else if (m_pictureCodingType == P_TYPE) |
| { |
| m_avcPar->MEMethod = meMethod; |
| m_avcPar->HMECombineLen = HMECombineLen[m_targetUsage]; |
| m_avcPar->FTQBasedSkip = FTQBasedSkip[m_targetUsage]; |
| m_avcPar->MultiplePred = MultiPred[m_targetUsage]; |
| m_avcPar->EnableAdaptiveIntraScaling = bAdaptiveIntraScalingEnable; |
| m_avcPar->StaticFrameIntraCostScalingRatioP = 240; |
| m_avcPar->SubPelMode = curbe->m_curbe.DW3.m_subPelMode; |
| m_avcPar->HMECombineOverlap = curbe->m_curbe.DW36.m_hmeCombineOverlap; |
| m_avcPar->SearchX = curbe->m_curbe.DW5.m_refWidth; |
| m_avcPar->SearchY = curbe->m_curbe.DW5.m_refHeight; |
| m_avcPar->SearchControl = curbe->m_curbe.DW3.m_searchCtrl; |
| m_avcPar->EnableAdaptiveTxDecision = curbe->m_curbe.DW34.m_enableAdaptiveTxDecision; |
| m_avcPar->TxDecisionThr = curbe->m_curbe.DW60.m_txDecisonThreshold; |
| m_avcPar->EnablePerMBStaticCheck = curbe->m_curbe.DW34.m_enablePerMBStaticCheck; |
| m_avcPar->EnableAdaptiveSearchWindowSize = curbe->m_curbe.DW34.m_enableAdaptiveSearchWindowSize; |
| m_avcPar->EnableIntraCostScalingForStaticFrame = curbe->m_curbe.DW4.m_enableIntraCostScalingForStaticFrame; |
| m_avcPar->BiMixDisable = curbe->m_curbe.DW0.m_biMixDis; |
| m_avcPar->SurvivedSkipCost = (curbe->m_curbe.DW7.m_nonSkipZMvAdded << 1) + curbe->m_curbe.DW7.m_nonSkipModeAdded; |
| m_avcPar->UniMixDisable = curbe->m_curbe.DW1.m_uniMixDisable; |
| } |
| else if (m_pictureCodingType == B_TYPE) |
| { |
| m_avcPar->BMEMethod = meMethod; |
| m_avcPar->HMEBCombineLen = HMEBCombineLen[m_targetUsage]; |
| m_avcPar->StaticFrameIntraCostScalingRatioB = 200; |
| m_avcPar->BSearchX = curbe->m_curbe.DW5.m_refWidth; |
| m_avcPar->BSearchY = curbe->m_curbe.DW5.m_refHeight; |
| m_avcPar->BSearchControl = curbe->m_curbe.DW3.m_searchCtrl; |
| m_avcPar->BSkipType = curbe->m_curbe.DW3.m_skipType; |
| m_avcPar->DirectMode = curbe->m_curbe.DW34.m_bDirectMode; |
| m_avcPar->BiWeight = curbe->m_curbe.DW1.m_biWeight; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalEncodeAvcEncG12::PopulatePakParam( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| PMHW_BATCH_BUFFER secondLevelBatchBuffer) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_CHK_NULL(m_debugInterface); |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| uint8_t *data = nullptr; |
| MOS_LOCK_PARAMS lockFlags; |
| MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); |
| lockFlags.ReadOnly = 1; |
| |
| if (cmdBuffer != nullptr) |
| { |
| data = (uint8_t*)(cmdBuffer->pCmdPtr - (mhw_vdbox_mfx_g12_X::MFX_AVC_IMG_STATE_CMD::byteSize / sizeof(uint32_t))); |
| } |
| else if (secondLevelBatchBuffer != nullptr) |
| { |
| data = secondLevelBatchBuffer->pData; |
| } |
| else |
| { |
| data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx], &lockFlags); |
| } |
| |
| CODECHAL_DEBUG_CHK_NULL(data); |
| |
| mhw_vdbox_mfx_g12_X::MFX_AVC_IMG_STATE_CMD mfxCmd; |
| mfxCmd = *(mhw_vdbox_mfx_g12_X::MFX_AVC_IMG_STATE_CMD *)(data); |
| |
| if (m_pictureCodingType == I_TYPE) |
| { |
| m_avcPar->TrellisQuantizationEnable = mfxCmd.DW5.TrellisQuantizationEnabledTqenb; |
| m_avcPar->EnableAdaptiveTrellisQuantization = mfxCmd.DW5.TrellisQuantizationEnabledTqenb; |
| m_avcPar->TrellisQuantizationRounding = mfxCmd.DW5.TrellisQuantizationRoundingTqr; |
| m_avcPar->TrellisQuantizationChromaDisable = mfxCmd.DW5.TrellisQuantizationChromaDisableTqchromadisable; |
| m_avcPar->ExtendedRhoDomainEn = mfxCmd.DW17.ExtendedRhodomainStatisticsEnable; |
| } |
| |
| if (data && (cmdBuffer == nullptr) && (secondLevelBatchBuffer == nullptr)) |
| { |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &BrcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx]); |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| #endif |