1 /*
2 * Copyright (c) 2022, 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     ddi_coedc_base_specific.cpp
24 //! \brief    Defines base class for softlet DDI codec encode/decoder.
25 //!
26 
27 #include "ddi_codec_base_specific.h"
28 #include "media_libva_util_next.h"
29 
30 namespace codec
31 {
GetRenderTargetID(DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,DDI_MEDIA_SURFACE * surface)32 int32_t DdiCodecBase::GetRenderTargetID(DDI_CODEC_RENDER_TARGET_TABLE *rtTbl, DDI_MEDIA_SURFACE *surface)
33 {
34     if((nullptr == surface) || (nullptr == rtTbl))
35     {
36         return DDI_CODEC_INVALID_FRAME_INDEX;
37     }
38 
39     if (0 == rtTbl->iNumRenderTargets)
40     {
41         return DDI_CODEC_INVALID_FRAME_INDEX;
42     }
43 
44     for(int32_t i = 0; i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; i++)
45     {
46         if(rtTbl->pRT[i] == surface)
47         {
48             return i;
49         }
50     }
51     return DDI_CODEC_INVALID_FRAME_INDEX;
52 }
53 
RegisterRTSurfaces(DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,DDI_MEDIA_SURFACE * surface)54 VAStatus DdiCodecBase::RegisterRTSurfaces(DDI_CODEC_RENDER_TARGET_TABLE *rtTbl, DDI_MEDIA_SURFACE *surface)
55 {
56     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_PARAMETER);
57     DDI_CHK_NULL(rtTbl, "nullptr rtTbl", VA_STATUS_ERROR_INVALID_PARAMETER);
58 
59     int32_t i = 0;
60     uint32_t emptyEntry = DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT + 1;
61     for (i = 0; i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; i++)
62     {
63         if (rtTbl->pRT[i] == surface)
64         {
65             //pCurrRT has already been registered
66             emptyEntry = DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT + 1;
67             break;
68         }
69         else if ((rtTbl->pRT[i] == nullptr) && (emptyEntry == (DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT + 1)))
70         {
71             //find the first empty entry
72             emptyEntry = i;
73         }
74     }
75 
76     if (emptyEntry < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT)
77     {
78         i = emptyEntry;
79     }
80     //if pCurrRT has not registered in pRT, add it into the array
81     if (i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT)
82     {
83         if (emptyEntry < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT)
84         {
85             rtTbl->pRT[emptyEntry] = surface;
86             rtTbl->ucRTFlag[emptyEntry] = SURFACE_STATE_ACTIVE_IN_CURFRAME;
87             rtTbl->iNumRenderTargets++;
88         }
89         else
90         {
91             rtTbl->ucRTFlag[i] = SURFACE_STATE_ACTIVE_IN_CURFRAME;
92         }
93     }
94     else
95     {
96         uint32_t j = 0;
97         for(j = 0; j < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; j ++)
98         {
99             if(rtTbl->ucRTFlag[j] == SURFACE_STATE_INACTIVE)
100             {
101                 rtTbl->pRT[j] = surface;
102                 rtTbl->ucRTFlag[j] = SURFACE_STATE_ACTIVE_IN_CURFRAME;
103                 break;
104             }
105         }
106         if(j == DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT)
107         {
108             DDI_VERBOSEMESSAGE("RT table is full, and have no one can be resued");
109             return VA_STATUS_ERROR_INVALID_PARAMETER;
110         }
111     }
112 
113     return VA_STATUS_SUCCESS;
114 }
115 
ClearRefList(DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,bool withDpb)116 VAStatus DdiCodecBase::ClearRefList(DDI_CODEC_RENDER_TARGET_TABLE *rtTbl, bool withDpb)
117 {
118     DDI_CHK_NULL(rtTbl, "nullptr rtTbl", VA_STATUS_ERROR_INVALID_PARAMETER);
119 
120     if(withDpb)
121     {
122         for(int32_t i = 0; i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; i ++)
123         {
124             if(rtTbl->ucRTFlag[i] == SURFACE_STATE_ACTIVE_IN_LASTFRAME)
125             {
126                 rtTbl->ucRTFlag[i] = SURFACE_STATE_INACTIVE;
127             }
128             else if(rtTbl->ucRTFlag[i] == SURFACE_STATE_ACTIVE_IN_CURFRAME)
129             {
130                 rtTbl->ucRTFlag[i] = SURFACE_STATE_ACTIVE_IN_LASTFRAME;
131             }
132         }
133     }
134     else
135     {
136         for(int32_t i = 0; i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; i ++)
137         {
138             if(rtTbl->ucRTFlag[i])
139             {
140                rtTbl->ucRTFlag[i] --;
141             }
142         }
143     }
144     return VA_STATUS_SUCCESS;
145 }
146 
UpdateRegisteredRTSurfaceFlag(DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,DDI_MEDIA_SURFACE * surface)147 VAStatus DdiCodecBase::UpdateRegisteredRTSurfaceFlag(DDI_CODEC_RENDER_TARGET_TABLE *rtTbl, DDI_MEDIA_SURFACE *surface)
148 {
149     DDI_CHK_NULL(rtTbl, "nullptr rtTbl", VA_STATUS_ERROR_INVALID_PARAMETER);
150     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_PARAMETER);
151 
152     for(int32_t i = 0; i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; i ++)
153     {
154         if(rtTbl->pRT[i] == surface)
155         {
156             rtTbl->ucRTFlag[i] = SURFACE_STATE_ACTIVE_IN_CURFRAME;
157             return VA_STATUS_SUCCESS;
158         }
159     }
160     DDI_VERBOSEMESSAGE("frame was not registered in the RTtbl");
161     return VA_STATUS_ERROR_INVALID_PARAMETER;
162 }
163 
UnRegisterRTSurfaces(DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,DDI_MEDIA_SURFACE * surface)164 VAStatus DdiCodecBase::UnRegisterRTSurfaces(DDI_CODEC_RENDER_TARGET_TABLE *rtTbl, DDI_MEDIA_SURFACE *surface)
165 {
166     DDI_CHK_NULL(rtTbl, "nullptr rtTbl", VA_STATUS_ERROR_INVALID_PARAMETER);
167     DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_PARAMETER);
168 
169     uint32_t i;
170 
171     for (i = 0; i < DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT; i++)
172     {
173         if (rtTbl->pRT[i] == surface)
174         {
175             rtTbl->pRT[i] = nullptr;
176             rtTbl->ucRTFlag[i] = SURFACE_STATE_INACTIVE;
177             rtTbl->iNumRenderTargets--;
178             break;
179         }
180     }
181     if (i == DDI_MEDIA_MAX_SURFACE_NUMBER_CONTEXT)
182     {
183         DDI_VERBOSEMESSAGE("The surface to be unregistered can not find in RTtbl!");
184         return VA_STATUS_ERROR_INVALID_PARAMETER;
185     }
186     return VA_STATUS_SUCCESS;
187 }
188 
189 }
190