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