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