1 /*
2 * Copyright (c) 2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_hevc_vdenc_roi.h
24 //! \brief implementation of ROI feature of HEVC VDENC
25
26 #include "encode_hevc_vdenc_roi_huc_forceqp.h"
27 #include "mos_defs.h"
28
29 namespace encode
30 {
31
HucForceQpROI(EncodeAllocator * allocator,MediaFeatureManager * featureManager,PMOS_INTERFACE osInterface)32 HucForceQpROI::HucForceQpROI(
33 EncodeAllocator *allocator, MediaFeatureManager *featureManager, PMOS_INTERFACE osInterface) :
34 RoiStrategy(allocator, featureManager, osInterface)
35 {
36 if (m_recycle != nullptr)
37 {
38 MOS_ALLOC_GFXRES_PARAMS allocParams;
39 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
40 allocParams.Type = MOS_GFXRES_BUFFER;
41 allocParams.TileType = MOS_TILE_LINEAR;
42 allocParams.Format = Format_Buffer;
43 allocParams.dwBytes = m_deltaQpRoiBufferSize;
44 allocParams.pBufName = "Delta QP for ROI Buffer";
45 allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
46 m_recycle->RegisterResource(
47 RecycleResId::HucRoiDeltaQpBuffer, allocParams);
48
49 allocParams.dwBytes = m_roiStreamInBufferSize;
50 allocParams.pBufName = "Output ROI Streamin Buffer";
51 allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
52 m_recycle->RegisterResource(
53 RecycleResId::HucRoiOutputBuffer, allocParams);
54 }
55 }
SetupRoi(RoiOverlap & overlap)56 MOS_STATUS HucForceQpROI::SetupRoi(RoiOverlap &overlap)
57 {
58 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
59
60 ENCODE_FUNC_CALL();
61
62 ENCODE_CHK_NULL_RETURN(m_allocator);
63 ENCODE_CHK_NULL_RETURN(m_basicFeature);
64 ENCODE_CHK_NULL_RETURN(m_recycle);
65
66 uint32_t frameIndex = m_basicFeature->m_frameNum;
67
68 m_deltaQpBuffer = m_recycle->GetBuffer(
69 RecycleResId::HucRoiDeltaQpBuffer, frameIndex);
70 ENCODE_CHK_NULL_RETURN(m_deltaQpBuffer);
71
72 m_hucRoiOutput = m_recycle->GetBuffer(
73 RecycleResId::HucRoiOutputBuffer, frameIndex);
74 ENCODE_CHK_NULL_RETURN(m_hucRoiOutput);
75
76 DeltaQpForRoi *deltaQpData = (DeltaQpForRoi *)
77 m_allocator->LockResourceForWrite(m_deltaQpBuffer);
78 ENCODE_CHK_NULL_RETURN(deltaQpData);
79
80 MOS_ZeroMemory(deltaQpData, m_deltaQpRoiBufferSize);
81
82 uint32_t streamInWidth = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 64) / 32);
83 uint32_t streamInHeight = (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 64) / 32);
84 uint32_t deltaQpBufWidth = (MOS_ALIGN_CEIL(m_basicFeature->m_frameWidth, 32) / 32);
85 uint32_t deltaQpBufHeight = (MOS_ALIGN_CEIL(m_basicFeature->m_frameHeight, 32) / 32);
86 bool cu64Align = true;
87
88 for (auto i = m_numRoi - 1; i >= 0; i--)
89 {
90 //Check if the region is with in the borders
91 uint16_t top = (uint16_t)
92 CodecHal_Clip3(0, (deltaQpBufHeight - 1), m_roiRegions[i].Top);
93 uint16_t bottom = (uint16_t)
94 CodecHal_Clip3(0, deltaQpBufHeight, m_roiRegions[i].Bottom);
95 uint16_t left = (uint16_t)
96 CodecHal_Clip3(0, (deltaQpBufWidth - 1), m_roiRegions[i].Left);
97 uint16_t right = (uint16_t)
98 CodecHal_Clip3(0, deltaQpBufWidth, m_roiRegions[i].Right);
99
100 //Check if all the sides of ROI regions are aligned to 64CU
101 if ((top % 2 == 1) ||
102 (bottom % 2 == 1) ||
103 (left % 2 == 1) ||
104 (right % 2 == 1))
105 {
106 cu64Align = false;
107 }
108 }
109
110 for (auto i = m_numRoi - 1; i >= 0; i--)
111 {
112 //Check if the region is with in the borders
113 uint16_t top = (uint16_t)
114 CodecHal_Clip3(0, (deltaQpBufHeight - 1), m_roiRegions[i].Top);
115 uint16_t bottom = (uint16_t)
116 CodecHal_Clip3(0, deltaQpBufHeight, m_roiRegions[i].Bottom);
117 uint16_t left = (uint16_t)
118 CodecHal_Clip3(0, (deltaQpBufWidth - 1), m_roiRegions[i].Left);
119 uint16_t right = (uint16_t)
120 CodecHal_Clip3(0, deltaQpBufWidth, m_roiRegions[i].Right);
121
122 std::vector<uint32_t> lcuVector;
123 GetLCUsInRoiRegion(streamInWidth, top, bottom, left, right, lcuVector);
124
125 // Set ROI Delta QP
126 for (uint32_t lcuOffset : lcuVector)
127 {
128 (deltaQpData + lcuOffset)->iDeltaQp =
129 m_roiRegions[i].PriorityLevelOrDQp;
130 }
131 }
132
133 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(m_deltaQpBuffer));
134
135
136 int32_t streamInNumCUs = streamInWidth * streamInHeight;
137 for (auto i = 0; i < streamInNumCUs; i++)
138 {
139 overlap.MarkLcu(i, cu64Align ?
140 RoiOverlap::mkRoiBk : RoiOverlap::mkRoiBkNone64Align);
141 }
142
143 return eStatus;
144 }
145
146 }