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 }