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
100 DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
101 vaStatus = prot->CreateProtectedSession(ctx, config_id - DDI_CP_GEN_CONFIG_ATTRIBUTES_BASE, protected_session);
102 }
103 else
104 {
105 DDI_ASSERTMESSAGE("DDI: Invalid config_id");
106 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
107 }
108
109 DDI_FUNCTION_EXIT(vaStatus);
110 return vaStatus;
111
112 }
113
DdiMedia_DestroyProtectedSession(VADriverContextP ctx,VAProtectedSessionID protected_session)114 VAStatus DdiMediaProtected::DdiMedia_DestroyProtectedSession(
115 VADriverContextP ctx,
116 VAProtectedSessionID protected_session)
117 {
118 DDI_FUNCTION_ENTER();
119
120 DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
121
122 VAStatus vaStatus = VA_STATUS_SUCCESS;
123 uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
124 void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
125
126 if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
127 {
128 DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
129
130 DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
131 vaStatus = prot->DestroyProtectedSession(ctx, protected_session);
132 }
133 else
134 {
135 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
136 }
137
138 DDI_FUNCTION_EXIT(vaStatus);
139 return vaStatus;
140 }
141
DdiMedia_AttachProtectedSession(VADriverContextP ctx,VAContextID context,VAProtectedSessionID protected_session)142 VAStatus DdiMediaProtected::DdiMedia_AttachProtectedSession(
143 VADriverContextP ctx,
144 VAContextID context,
145 VAProtectedSessionID protected_session)
146 {
147 DDI_FUNCTION_ENTER();
148
149 DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
150
151 VAStatus vaStatus = VA_STATUS_SUCCESS;
152 uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
153 void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
154 DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
155
156 if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
157 {
158 DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
159
160 DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
161 vaStatus = prot->AttachProtectedSession(ctx, context, protected_session);
162 }
163 else
164 {
165 DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
166 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
167 }
168
169 DDI_FUNCTION_EXIT(vaStatus);
170 return vaStatus;
171 }
172
DdiMedia_DetachProtectedSession(VADriverContextP ctx,VAContextID context)173 VAStatus DdiMediaProtected::DdiMedia_DetachProtectedSession(
174 VADriverContextP ctx,
175 VAContextID context)
176 {
177 DDI_FUNCTION_ENTER();
178
179 DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
180
181 VAStatus vaStatus = VA_STATUS_SUCCESS;
182 if (context != 0)
183 {
184 uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
185 void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
186 DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
187 if (ctxType != DDI_MEDIA_CONTEXT_TYPE_DECODER &&
188 ctxType != DDI_MEDIA_CONTEXT_TYPE_ENCODER &&
189 ctxType != DDI_MEDIA_CONTEXT_TYPE_VP)
190 {
191 DDI_ASSERTMESSAGE("wrong context type %d", ctxType);
192 return VA_STATUS_ERROR_INVALID_CONTEXT;
193 }
194
195 DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
196 DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
197 vaStatus = prot->DetachProtectedSession(ctx, context);
198 }
199
200 DDI_FUNCTION_EXIT(vaStatus);
201 return vaStatus;
202 }
203
DdiMedia_ProtectedSessionExecute(VADriverContextP ctx,VAProtectedSessionID protected_session,VABufferID data)204 VAStatus DdiMediaProtected::DdiMedia_ProtectedSessionExecute(
205 VADriverContextP ctx,
206 VAProtectedSessionID protected_session,
207 VABufferID data)
208 {
209 DDI_FUNCTION_ENTER();
210
211 DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
212
213 VAStatus vaStatus = VA_STATUS_SUCCESS;
214 uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
215 void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
216 DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
217
218 if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
219 {
220 DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
221
222 DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
223 vaStatus = prot->ProtectedSessionExecute(ctx, protected_session, data);
224 }
225 else
226 {
227 DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
228 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
229 }
230
231 return vaStatus;
232 }
233
DdiMedia_ProtectedSessionCreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,uint32_t size,uint32_t num_elements,void * data,VABufferID * bufId)234 VAStatus DdiMediaProtected::DdiMedia_ProtectedSessionCreateBuffer(
235 VADriverContextP ctx,
236 VAContextID context,
237 VABufferType type,
238 uint32_t size,
239 uint32_t num_elements,
240 void *data,
241 VABufferID *bufId)
242 {
243 DDI_FUNCTION_ENTER();
244
245 DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
246
247 VAStatus vaStatus = VA_STATUS_SUCCESS;
248 uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
249 void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, context, &ctxType);
250 DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
251
252 if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
253 {
254 DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
255
256 DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
257 vaStatus = prot->ProtectedSessionCreateBuffer(ctx, context, type, size, num_elements, data, bufId);
258 }
259 else
260 {
261 DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
262 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
263 }
264
265 return vaStatus;
266 }
267
CreateProtectedSession(VADriverContextP ctx,VAConfigID config_id,VAProtectedSessionID * protected_session)268 VAStatus DdiMediaProtected::CreateProtectedSession(
269 VADriverContextP ctx,
270 VAConfigID config_id,
271 VAProtectedSessionID *protected_session)
272 {
273 return VA_STATUS_ERROR_UNIMPLEMENTED;
274 }
275
DestroyProtectedSession(VADriverContextP ctx,VAProtectedSessionID protected_session)276 VAStatus DdiMediaProtected::DestroyProtectedSession(
277 VADriverContextP ctx,
278 VAProtectedSessionID protected_session)
279 {
280 return VA_STATUS_ERROR_UNIMPLEMENTED;
281 }
282
AttachProtectedSession(VADriverContextP ctx,VAContextID context,VAProtectedSessionID protected_session)283 VAStatus DdiMediaProtected::AttachProtectedSession(
284 VADriverContextP ctx,
285 VAContextID context,
286 VAProtectedSessionID protected_session)
287 {
288 return VA_STATUS_ERROR_UNIMPLEMENTED;
289 }
290
DetachProtectedSession(VADriverContextP ctx,VAContextID context)291 VAStatus DdiMediaProtected::DetachProtectedSession(
292 VADriverContextP ctx,
293 VAContextID context)
294 {
295 return VA_STATUS_ERROR_UNIMPLEMENTED;
296 }
297
ProtectedSessionExecute(VADriverContextP ctx,VAProtectedSessionID protected_session,VABufferID data)298 VAStatus DdiMediaProtected::ProtectedSessionExecute(
299 VADriverContextP ctx,
300 VAProtectedSessionID protected_session,
301 VABufferID data)
302 {
303 return VA_STATUS_ERROR_UNIMPLEMENTED;
304 }
305
ProtectedSessionCreateBuffer(VADriverContextP ctx,VAProtectedSessionID protected_session,VABufferType type,uint32_t size,uint32_t num_elements,void * data,VABufferID * bufId)306 VAStatus DdiMediaProtected::ProtectedSessionCreateBuffer(
307 VADriverContextP ctx,
308 VAProtectedSessionID protected_session,
309 VABufferType type,
310 uint32_t size,
311 uint32_t num_elements,
312 void *data,
313 VABufferID *bufId)
314 {
315 return VA_STATUS_ERROR_UNIMPLEMENTED;
316 }
317
GetProtectedSurfaceTag(PDDI_MEDIA_CONTEXT media_ctx)318 uint64_t DdiMediaProtected::GetProtectedSurfaceTag(PDDI_MEDIA_CONTEXT media_ctx)
319 {
320 return 0;
321 }
322
DdiMedia_FreeProtectedSessionHeap(VADriverContextP ctx,PDDI_MEDIA_HEAP contextHeap,int32_t vaContextOffset,int32_t ctxNums)323 void DdiMedia_FreeProtectedSessionHeap(
324 VADriverContextP ctx,
325 PDDI_MEDIA_HEAP contextHeap,
326 int32_t vaContextOffset,
327 int32_t ctxNums)
328 {
329 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)contextHeap->pHeapBase;
330 if (nullptr == mediaContextHeapBase)
331 return;
332
333 for (int32_t elementId = 0; elementId < ctxNums; ++elementId)
334 {
335 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapElmt = &mediaContextHeapBase[elementId];
336 if (nullptr == mediaContextHeapElmt->pVaContext)
337 continue;
338 VAContextID vaCtxID = (VAContextID)(mediaContextHeapElmt->uiVaContextID + vaContextOffset);
339 DdiMediaProtected::DdiMedia_DestroyProtectedSession(ctx, vaCtxID);
340 }
341 }
342
DdiMedia_GetVaContextFromHeap(PDDI_MEDIA_HEAP mediaHeap,uint32_t index,PMEDIA_MUTEX_T mutex)343 static void* DdiMedia_GetVaContextFromHeap(
344 PDDI_MEDIA_HEAP mediaHeap,
345 uint32_t index,
346 PMEDIA_MUTEX_T mutex)
347 {
348 PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaCtxHeapElmt = nullptr;
349 void *context = nullptr;
350
351 DdiMediaUtil_LockMutex(mutex);
352 if(nullptr == mediaHeap || index >= mediaHeap->uiAllocatedHeapElements)
353 {
354 DdiMediaUtil_UnLockMutex(mutex);
355 return nullptr;
356 }
357 vaCtxHeapElmt = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaHeap->pHeapBase;
358 vaCtxHeapElmt += index;
359 context = vaCtxHeapElmt->pVaContext;
360 DdiMediaUtil_UnLockMutex(mutex);
361
362 return context;
363 }
364
DdiMedia_GetContextFromProtectedSessionID(VADriverContextP ctx,VAProtectedSessionID vaID,uint32_t * ctxType)365 void* DdiMedia_GetContextFromProtectedSessionID(
366 VADriverContextP ctx,
367 VAProtectedSessionID vaID,
368 uint32_t *ctxType)
369 {
370 PDDI_MEDIA_CONTEXT mediaCtx = nullptr;
371 uint32_t heap_index = 0, prot_index = 0;
372 void *pSession = nullptr;
373
374 DDI_CHK_NULL(ctx, "nullptr ctx", nullptr);
375 DDI_CHK_NULL(ctxType, "nullptr ctxType", nullptr);
376
377 mediaCtx = DdiMedia_GetMediaContext(ctx);
378 prot_index = vaID & DDI_MEDIA_MASK_VACONTEXTID;
379 heap_index = vaID & DDI_MEDIA_MASK_VAPROTECTEDSESSION_ID;
380
381 if ((vaID&DDI_MEDIA_MASK_VACONTEXT_TYPE) != DDI_MEDIA_VACONTEXTID_OFFSET_PROT)
382 {
383 DDI_ASSERTMESSAGE("Invalid protected session: 0x%x", vaID);
384 *ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
385 return nullptr;
386 }
387
388 // 0 ~ 0x8000000: LP context
389 // 0x8000000~0x10000000: CP context
390 if (prot_index < DDI_MEDIA_VACONTEXTID_OFFSET_PROT_CP)
391 {
392 DDI_VERBOSEMESSAGE("LP protected session detected: 0x%x", vaID);
393 *ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED_LINK;
394 return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, heap_index, &mediaCtx->ProtMutex);
395 }
396
397 DDI_VERBOSEMESSAGE("CP protected session detected: 0x%x", vaID);
398 *ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT;
399 return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, heap_index, &mediaCtx->ProtMutex);
400 }
401