xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/cp/ddi/media_ddi_prot.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2020, 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_prot.cpp
24 //! \brief    The class implementation of DdiMediaProtected base for all protected session
25 //!
26 
27 #include "codec_def_common_encode.h"
28 #include "codec_def_encode_jpeg.h"
29 #include "media_libva_util.h"
30 #include "media_libva_caps.h"
31 #include "media_libva.h"
32 #include "media_libva_caps_cp_interface.h"
33 #include "media_ddi_prot.h"
34 
35 static bool isDefaultRegistered = DdiProtectedFactory::Register<DdiMediaProtected>(DDI_PROTECTED_DEFAULT);
36 static bool isProtectedContentRegistered = DdiProtectedFactory::Register<DdiMediaProtected>(DDI_PROTECTED_CONTENT);
37 
38 std::map<uint32_t, DdiMediaProtected*> DdiMediaProtected::_impl;
39 
GetInstance(uint32_t id)40 DdiMediaProtected* DdiMediaProtected::GetInstance(uint32_t id)
41 {
42     if (_impl[id] == nullptr)
43     {
44         _impl[id] = DdiProtectedFactory::Create(id);
45         if (_impl[id] == nullptr)
46         {
47             DDI_ASSERTMESSAGE("DdiProtectedFactory::Create fail with id=%d", id);
48             return nullptr;
49         }
50     }
51 
52     return _impl[id];
53 }
54 
FreeInstances()55 void DdiMediaProtected::FreeInstances()
56 {
57     std::map<uint32_t, DdiMediaProtected*>::iterator it;
58     for (it = _impl.begin(); it != _impl.end(); it++)
59     {
60         MOS_Delete(it->second);
61     }
62 }
63 
CheckEntrypointSupported(VAEntrypoint entrypoint)64 bool DdiMediaProtected::CheckEntrypointSupported(VAEntrypoint entrypoint)
65 {
66     return false;
67 }
68 
CheckAttribList(VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib,uint32_t numAttribs)69 bool DdiMediaProtected::CheckAttribList(
70     VAProfile profile,
71     VAEntrypoint entrypoint,
72     VAConfigAttrib* attrib,
73     uint32_t numAttribs)
74 {
75     return false;
76 }
77 
DdiMedia_CreateProtectedSession(VADriverContextP ctx,VAConfigID config_id,VAProtectedSessionID * protected_session)78 VAStatus DdiMediaProtected::DdiMedia_CreateProtectedSession(
79     VADriverContextP        ctx,
80     VAConfigID              config_id,
81     VAProtectedSessionID    *protected_session)
82 {
83     DDI_FUNCTION_ENTER();
84 
85     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
86     DDI_CHK_NULL(protected_session, "nullptr protected_session",    VA_STATUS_ERROR_INVALID_PARAMETER);
87 
88     VAStatus vaStatus = VA_STATUS_SUCCESS;
89     PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx);
90     DDI_CHK_NULL(mediaDrvCtx, "nullptr mediaDrvCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
91     DDI_CHK_NULL(mediaDrvCtx->m_caps, "nullptr mediaDrvCtx->m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
92 
93     MediaLibvaCapsCpInterface *cpCaps = mediaDrvCtx->m_caps->GetCpCaps();
94     DDI_CHK_NULL(cpCaps, "nullptr cpCaps", VA_STATUS_ERROR_INVALID_CONTEXT);
95 
96     if (cpCaps->IsCpConfigId(config_id))
97     {
98         DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
99         DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
100         vaStatus = prot->CreateProtectedSession(ctx, config_id - DDI_CP_GEN_CONFIG_ATTRIBUTES_BASE, protected_session);
101     }
102     else
103     {
104         DDI_ASSERTMESSAGE("DDI: Invalid config_id");
105         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
106     }
107 
108     DDI_FUNCTION_EXIT(vaStatus);
109     return vaStatus;
110 
111 }
112 
DdiMedia_DestroyProtectedSession(VADriverContextP ctx,VAProtectedSessionID protected_session)113 VAStatus DdiMediaProtected::DdiMedia_DestroyProtectedSession(
114     VADriverContextP        ctx,
115     VAProtectedSessionID    protected_session)
116 {
117     DDI_FUNCTION_ENTER();
118 
119     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
120 
121     VAStatus vaStatus = VA_STATUS_SUCCESS;
122     uint32_t            ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
123     void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
124     DDI_CHK_NULL(ctxPtr, "nullptr prot", VA_STATUS_ERROR_INVALID_CONTEXT);
125 
126     if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
127     {
128         DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
129         DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
130         vaStatus = prot->DestroyProtectedSession(ctx, protected_session);
131     }
132     else
133     {
134         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
135     }
136 
137     DDI_FUNCTION_EXIT(vaStatus);
138     return vaStatus;
139 }
140 
DdiMedia_AttachProtectedSession(VADriverContextP ctx,VAContextID context,VAProtectedSessionID protected_session)141 VAStatus DdiMediaProtected::DdiMedia_AttachProtectedSession(
142     VADriverContextP        ctx,
143     VAContextID             context,
144     VAProtectedSessionID    protected_session)
145 {
146     DDI_FUNCTION_ENTER();
147 
148     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
149 
150     VAStatus vaStatus = VA_STATUS_SUCCESS;
151     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
152     void     *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
153     DDI_CHK_NULL(ctxPtr,      "nullptr ctxPtr",     VA_STATUS_ERROR_INVALID_CONTEXT);
154 
155     if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
156     {
157         DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
158         DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
159         vaStatus = prot->AttachProtectedSession(ctx, context, protected_session);
160     }
161     else
162     {
163         DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
164         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
165     }
166 
167     DDI_FUNCTION_EXIT(vaStatus);
168     return vaStatus;
169 }
170 
DdiMedia_DetachProtectedSession(VADriverContextP ctx,VAContextID context)171 VAStatus DdiMediaProtected::DdiMedia_DetachProtectedSession(
172     VADriverContextP        ctx,
173     VAContextID             context)
174 {
175     DDI_FUNCTION_ENTER();
176 
177     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
178 
179     VAStatus vaStatus = VA_STATUS_SUCCESS;
180     if (context != 0)
181     {
182         uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
183         void     *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
184         DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
185         if (ctxType != DDI_MEDIA_CONTEXT_TYPE_DECODER &&
186             ctxType != DDI_MEDIA_CONTEXT_TYPE_ENCODER &&
187             ctxType != DDI_MEDIA_CONTEXT_TYPE_VP)
188         {
189             DDI_ASSERTMESSAGE("wrong context type %d", ctxType);
190             return VA_STATUS_ERROR_INVALID_CONTEXT;
191         }
192 
193         DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
194         DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
195         vaStatus = prot->DetachProtectedSession(ctx, context);
196     }
197 
198     DDI_FUNCTION_EXIT(vaStatus);
199     return vaStatus;
200 }
201 
DdiMedia_ProtectedSessionExecute(VADriverContextP ctx,VAProtectedSessionID protected_session,VABufferID data)202 VAStatus DdiMediaProtected::DdiMedia_ProtectedSessionExecute(
203     VADriverContextP        ctx,
204     VAProtectedSessionID    protected_session,
205     VABufferID              data)
206 {
207     DDI_FUNCTION_ENTER();
208 
209     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
210 
211     VAStatus vaStatus = VA_STATUS_SUCCESS;
212     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
213     void     *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
214     DDI_CHK_NULL(ctxPtr,      "nullptr ctxPtr",     VA_STATUS_ERROR_INVALID_CONTEXT);
215 
216     if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
217     {
218         DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
219         DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
220         vaStatus = prot->ProtectedSessionExecute(ctx, protected_session, data);
221     }
222     else
223     {
224         DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
225         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
226     }
227 
228     return vaStatus;
229 }
230 
DdiMedia_ProtectedSessionCreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,uint32_t size,uint32_t num_elements,void * data,VABufferID * bufId)231 VAStatus DdiMediaProtected::DdiMedia_ProtectedSessionCreateBuffer(
232     VADriverContextP        ctx,
233     VAContextID             context,
234     VABufferType            type,
235     uint32_t                size,
236     uint32_t                num_elements,
237     void                    *data,
238     VABufferID              *bufId)
239 {
240     DDI_FUNCTION_ENTER();
241 
242     DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
243     DDI_CHK_NULL(data, "nullptr data", VA_STATUS_ERROR_INVALID_PARAMETER);
244     DDI_CHK_NULL(bufId, "nullptr bufId", VA_STATUS_ERROR_INVALID_PARAMETER);
245 
246     VAStatus vaStatus = VA_STATUS_SUCCESS;
247     uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
248     void     *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, context, &ctxType);
249     DDI_CHK_NULL(ctxPtr,      "nullptr ctxPtr",     VA_STATUS_ERROR_INVALID_CONTEXT);
250 
251     if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
252     {
253         DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
254         DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
255         vaStatus = prot->ProtectedSessionCreateBuffer(ctx, context, type, size, num_elements, data, bufId);
256     }
257     else
258     {
259         DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
260         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
261     }
262 
263     return vaStatus;
264 }
265 
CreateProtectedSession(VADriverContextP ctx,VAConfigID config_id,VAProtectedSessionID * protected_session)266 VAStatus DdiMediaProtected::CreateProtectedSession(
267     VADriverContextP        ctx,
268     VAConfigID              config_id,
269     VAProtectedSessionID    *protected_session)
270 {
271     return VA_STATUS_ERROR_UNIMPLEMENTED;
272 }
273 
DestroyProtectedSession(VADriverContextP ctx,VAProtectedSessionID protected_session)274 VAStatus DdiMediaProtected::DestroyProtectedSession(
275     VADriverContextP        ctx,
276     VAProtectedSessionID    protected_session)
277 {
278     return VA_STATUS_ERROR_UNIMPLEMENTED;
279 }
280 
AttachProtectedSession(VADriverContextP ctx,VAContextID context,VAProtectedSessionID protected_session)281 VAStatus DdiMediaProtected::AttachProtectedSession(
282     VADriverContextP        ctx,
283     VAContextID             context,
284     VAProtectedSessionID    protected_session)
285 {
286     return VA_STATUS_ERROR_UNIMPLEMENTED;
287 }
288 
DetachProtectedSession(VADriverContextP ctx,VAContextID context)289 VAStatus DdiMediaProtected::DetachProtectedSession(
290     VADriverContextP        ctx,
291     VAContextID             context)
292 {
293     return VA_STATUS_ERROR_UNIMPLEMENTED;
294 }
295 
ProtectedSessionExecute(VADriverContextP ctx,VAProtectedSessionID protected_session,VABufferID data)296 VAStatus DdiMediaProtected::ProtectedSessionExecute(
297     VADriverContextP        ctx,
298     VAProtectedSessionID    protected_session,
299     VABufferID              data)
300 {
301     return VA_STATUS_ERROR_UNIMPLEMENTED;
302 }
303 
ProtectedSessionCreateBuffer(VADriverContextP ctx,VAProtectedSessionID protected_session,VABufferType type,uint32_t size,uint32_t num_elements,void * data,VABufferID * bufId)304 VAStatus DdiMediaProtected::ProtectedSessionCreateBuffer(
305     VADriverContextP        ctx,
306     VAProtectedSessionID    protected_session,
307     VABufferType            type,
308     uint32_t                size,
309     uint32_t                num_elements,
310     void                    *data,
311     VABufferID              *bufId)
312 {
313     return VA_STATUS_ERROR_UNIMPLEMENTED;
314 }
315 
GetProtectedSurfaceTag(PDDI_MEDIA_CONTEXT media_ctx)316 uint64_t DdiMediaProtected::GetProtectedSurfaceTag(PDDI_MEDIA_CONTEXT media_ctx)
317 {
318     return 0;
319 }
320 
DdiMedia_FreeProtectedSessionHeap(VADriverContextP ctx,PDDI_MEDIA_HEAP contextHeap,int32_t vaContextOffset,int32_t ctxNums)321 void DdiMedia_FreeProtectedSessionHeap(
322     VADriverContextP ctx,
323     PDDI_MEDIA_HEAP contextHeap,
324     int32_t vaContextOffset,
325     int32_t ctxNums)
326 {
327     if (nullptr == ctx || nullptr == contextHeap)
328     {
329         DDI_ASSERTMESSAGE("DDI: Invalid input arguments");
330         return;
331     }
332 
333     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)contextHeap->pHeapBase;
334     if (nullptr == mediaContextHeapBase)
335         return;
336 
337     for (int32_t elementId = 0; ctxNums > 0  && elementId < contextHeap->uiAllocatedHeapElements; ++elementId)
338     {
339         PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapElmt = &mediaContextHeapBase[elementId];
340         if (nullptr != mediaContextHeapElmt)
341         {
342             if (nullptr == mediaContextHeapElmt->pVaContext)
343                 continue;
344             VAContextID vaCtxID = (VAContextID)(mediaContextHeapElmt->uiVaContextID + vaContextOffset);
345             DdiMediaProtected::DdiMedia_DestroyProtectedSession(ctx, vaCtxID);
346         }
347         else
348         {
349             DDI_ASSERTMESSAGE("DDI: Invalid mediaContextHeapElmt");
350         }
351         ctxNums--;
352     }
353 }
354 
DdiMedia_GetVaContextFromHeap(PDDI_MEDIA_HEAP mediaHeap,uint32_t index,PMEDIA_MUTEX_T mutex)355 static void* DdiMedia_GetVaContextFromHeap(
356     PDDI_MEDIA_HEAP mediaHeap,
357     uint32_t index,
358     PMEDIA_MUTEX_T mutex)
359 {
360     if (nullptr == mutex)
361     {
362         DDI_ASSERTMESSAGE("DDI: Invalid input arguments");
363         return nullptr;
364     }
365 
366     PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT  vaCtxHeapElmt = nullptr;
367     void                              *context = nullptr;
368 
369     DdiMediaUtil_LockMutex(mutex);
370     if(nullptr == mediaHeap || index >= mediaHeap->uiAllocatedHeapElements)
371     {
372         DdiMediaUtil_UnLockMutex(mutex);
373         return nullptr;
374     }
375     vaCtxHeapElmt  = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaHeap->pHeapBase;
376     vaCtxHeapElmt += index;
377     context        = vaCtxHeapElmt->pVaContext;
378     DdiMediaUtil_UnLockMutex(mutex);
379 
380     return context;
381 }
382 
DdiMedia_GetContextFromProtectedSessionID(VADriverContextP ctx,VAProtectedSessionID vaID,uint32_t * ctxType)383 void* DdiMedia_GetContextFromProtectedSessionID(
384     VADriverContextP ctx,
385     VAProtectedSessionID vaID,
386     uint32_t *ctxType)
387 {
388     PDDI_MEDIA_CONTEXT       mediaCtx = nullptr;
389     uint32_t                 heap_index = 0, prot_index = 0;
390     void                     *pSession = nullptr;
391 
392     DDI_CHK_NULL(ctx, "nullptr ctx", nullptr);
393     DDI_CHK_NULL(ctxType, "nullptr ctxType", nullptr);
394 
395     mediaCtx  = DdiMedia_GetMediaContext(ctx);
396     prot_index    = vaID & DDI_MEDIA_MASK_VACONTEXTID;
397     heap_index    = vaID & DDI_MEDIA_MASK_VAPROTECTEDSESSION_ID;
398 
399     if ((vaID&DDI_MEDIA_MASK_VACONTEXT_TYPE) != DDI_MEDIA_VACONTEXTID_OFFSET_PROT)
400     {
401         DDI_ASSERTMESSAGE("Invalid protected session: 0x%x", vaID);
402         *ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
403         return nullptr;
404     }
405 
406     // 0        ~ 0x8000000: LP context
407     // 0x8000000~0x10000000: CP context
408     if (prot_index < DDI_MEDIA_VACONTEXTID_OFFSET_PROT_CP)
409     {
410         DDI_VERBOSEMESSAGE("LP protected session detected: 0x%x", vaID);
411         *ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED_LINK;
412         return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, heap_index, &mediaCtx->ProtMutex);
413     }
414 
415     DDI_VERBOSEMESSAGE("CP protected session detected: 0x%x", vaID);
416     *ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT;
417     return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, heap_index, &mediaCtx->ProtMutex);
418 }
419