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_overlap.cpp
24 //! \brief    Implemetation of the ROI overlap
25 //!
26 
27 #include "encode_hevc_vdenc_roi_strategy.h"
28 #include "encode_hevc_vdenc_roi_overlap.h"
29 
30 namespace encode
31 {
~RoiOverlap()32 RoiOverlap::~RoiOverlap()
33 {
34     MOS_FreeMemory(m_overlapMap);
35     m_overlapMap = nullptr;
36 }
37 
Update(uint32_t lcuNumber)38 void RoiOverlap::Update(uint32_t lcuNumber)
39 {
40     if (m_lcuNumber < lcuNumber)
41     {
42         MOS_FreeMemory(m_overlapMap);
43         m_overlapMap = nullptr;
44         m_lcuNumber  = lcuNumber;
45     }
46 
47     if (m_overlapMap == nullptr)
48     {
49         m_overlapMap = (uint16_t *)
50             MOS_AllocMemory(lcuNumber * sizeof(uint16_t));
51     }
52 
53     MOS_ZeroMemory(m_overlapMap, m_lcuNumber * sizeof(uint16_t));
54 }
55 
CanWriteMark(uint32_t lcu,OverlapMarker marker)56 bool RoiOverlap::CanWriteMark(uint32_t lcu, OverlapMarker marker)
57 {
58     if (m_overlapMap == nullptr || lcu >= m_lcuNumber)
59     {
60         return false;
61     }
62 
63     // Avoid ROI background overwrite the marker write by
64     // others(Dirty ROI or ROI forground)
65     if ((marker == mkRoiBk || marker == mkRoiBkNone64Align) &&
66         m_overlapMap[lcu] > 0)
67     {
68         return false;
69     }
70 
71     // Avoid ROI forground overwrite Dirty ROI forground data
72     if ((marker == mkRoi || marker == mkRoiNone64Align) &&
73         (m_overlapMap[lcu] == mkDirtyRoi ||
74             m_overlapMap[lcu] == mkDirtyRoiNone64Align))
75     {
76         return false;
77     }
78 
79     return true;
80 }
81 
MarkLcu(uint32_t lcu,OverlapMarker marker,int32_t roiRegionIndex)82 void RoiOverlap::MarkLcu(
83     uint32_t lcu,
84     OverlapMarker marker,
85     int32_t roiRegionIndex)
86 {
87     if (CanWriteMark(lcu, marker))
88     {
89         m_overlapMap[lcu] =
90             ((marker & m_maskOverlapMarker) |
91             ((roiRegionIndex & m_maskRoiRegionIndex) <<
92                 m_bitNumberOfOverlapMarker));
93     }
94 }
MarkLcu(uint32_t lcu,OverlapMarker marker)95 void RoiOverlap::MarkLcu(uint32_t lcu, OverlapMarker marker)
96 {
97     if (CanWriteMark(lcu, marker))
98     {
99         m_overlapMap[lcu] =
100             ((marker & m_maskOverlapMarker) |
101             (m_maskRoiRegionIndex << m_bitNumberOfOverlapMarker));
102     }
103 }
104 
WriteStreaminData(RoiStrategy * roi,RoiStrategy * dirtyRoi,uint8_t * streaminBuffer)105 MOS_STATUS RoiOverlap::WriteStreaminData(
106     RoiStrategy *roi,
107     RoiStrategy *dirtyRoi,
108     uint8_t *streaminBuffer)
109 {
110     ENCODE_CHK_NULL_RETURN(streaminBuffer);
111     ENCODE_CHK_NULL_RETURN(m_overlapMap);
112 
113     for (uint32_t i = 0; i < m_lcuNumber; i++)
114     {
115         OverlapMarker marker = GetMarker(m_overlapMap[i]);
116         uint32_t      roiRegionIndex = GetRoiRegionIndex(m_overlapMap[i]);
117 
118         if (IsRoiMarker(marker))
119         {
120             ENCODE_CHK_NULL_RETURN(roi);
121 
122             roi->WriteStreaminData(
123                 i, marker, roiRegionIndex, streaminBuffer);
124 
125         }
126         else if (IsDirtyRoiMarker(marker))
127         {
128             ENCODE_CHK_NULL_RETURN(dirtyRoi);
129             dirtyRoi->WriteStreaminData(
130                 i, marker, roiRegionIndex, streaminBuffer);
131         }
132     }
133     return MOS_STATUS_SUCCESS;
134 }
135 
136 }  // namespace encode