blob: 98b934a0e3912d33fa0569d4ba530476569e4554 [file] [log] [blame]
/*
* Copyright (c) 2020, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file media_ddi_prot.cpp
//! \brief The class implementation of DdiMediaProtected base for all protected session
//!
#include "codec_def_common_encode.h"
#include "codec_def_encode_jpeg.h"
#include "media_libva_util.h"
#include "media_libva_caps.h"
#include "media_libva.h"
#include "media_libva_caps_cp_interface.h"
#include "media_ddi_prot.h"
static bool isDefaultRegistered = DdiProtectedFactory::Register<DdiMediaProtected>(DDI_PROTECTED_DEFAULT);
static bool isProtectedContentRegistered = DdiProtectedFactory::Register<DdiMediaProtected>(DDI_PROTECTED_CONTENT);
std::map<uint32_t, DdiMediaProtected*> DdiMediaProtected::_impl;
DdiMediaProtected* DdiMediaProtected::GetInstance(uint32_t id)
{
if (_impl[id] == nullptr)
{
_impl[id] = DdiProtectedFactory::Create(id);
if (_impl[id] == nullptr)
{
DDI_ASSERTMESSAGE("DdiProtectedFactory::Create fail with id=%d", id);
return nullptr;
}
}
return _impl[id];
}
void DdiMediaProtected::FreeInstances()
{
std::map<uint32_t, DdiMediaProtected*>::iterator it;
for (it = _impl.begin(); it != _impl.end(); it++)
{
MOS_Delete(it->second);
}
}
bool DdiMediaProtected::CheckEntrypointSupported(VAEntrypoint entrypoint)
{
return false;
}
bool DdiMediaProtected::CheckAttribList(
VAProfile profile,
VAEntrypoint entrypoint,
VAConfigAttrib* attrib,
uint32_t numAttribs)
{
return false;
}
VAStatus DdiMediaProtected::DdiMedia_CreateProtectedSession(
VADriverContextP ctx,
VAConfigID config_id,
VAProtectedSessionID *protected_session)
{
DDI_FUNCTION_ENTER();
DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(protected_session, "nullptr protected_session", VA_STATUS_ERROR_INVALID_PARAMETER);
VAStatus vaStatus = VA_STATUS_SUCCESS;
PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx);
DDI_CHK_NULL(mediaDrvCtx, "nullptr mediaDrvCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(mediaDrvCtx->m_caps, "nullptr mediaDrvCtx->m_caps", VA_STATUS_ERROR_INVALID_CONTEXT);
MediaLibvaCapsCpInterface *cpCaps = mediaDrvCtx->m_caps->GetCpCaps();
DDI_CHK_NULL(cpCaps, "nullptr cpCaps", VA_STATUS_ERROR_INVALID_CONTEXT);
if (cpCaps->IsCpConfigId(config_id))
{
DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
vaStatus = prot->CreateProtectedSession(ctx, config_id - DDI_CP_GEN_CONFIG_ATTRIBUTES_BASE, protected_session);
}
else
{
DDI_ASSERTMESSAGE("DDI: Invalid config_id");
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
}
DDI_FUNCTION_EXIT(vaStatus);
return vaStatus;
}
VAStatus DdiMediaProtected::DdiMedia_DestroyProtectedSession(
VADriverContextP ctx,
VAProtectedSessionID protected_session)
{
DDI_FUNCTION_ENTER();
DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
VAStatus vaStatus = VA_STATUS_SUCCESS;
uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
{
DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
vaStatus = prot->DestroyProtectedSession(ctx, protected_session);
}
else
{
vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
}
DDI_FUNCTION_EXIT(vaStatus);
return vaStatus;
}
VAStatus DdiMediaProtected::DdiMedia_AttachProtectedSession(
VADriverContextP ctx,
VAContextID context,
VAProtectedSessionID protected_session)
{
DDI_FUNCTION_ENTER();
DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
VAStatus vaStatus = VA_STATUS_SUCCESS;
uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
{
DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
vaStatus = prot->AttachProtectedSession(ctx, context, protected_session);
}
else
{
DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
}
DDI_FUNCTION_EXIT(vaStatus);
return vaStatus;
}
VAStatus DdiMediaProtected::DdiMedia_DetachProtectedSession(
VADriverContextP ctx,
VAContextID context)
{
DDI_FUNCTION_ENTER();
DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
VAStatus vaStatus = VA_STATUS_SUCCESS;
if (context != 0)
{
uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
if (ctxType != DDI_MEDIA_CONTEXT_TYPE_DECODER &&
ctxType != DDI_MEDIA_CONTEXT_TYPE_ENCODER &&
ctxType != DDI_MEDIA_CONTEXT_TYPE_VP)
{
DDI_ASSERTMESSAGE("wrong context type %d", ctxType);
return VA_STATUS_ERROR_INVALID_CONTEXT;
}
DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
vaStatus = prot->DetachProtectedSession(ctx, context);
}
DDI_FUNCTION_EXIT(vaStatus);
return vaStatus;
}
VAStatus DdiMediaProtected::DdiMedia_ProtectedSessionExecute(
VADriverContextP ctx,
VAProtectedSessionID protected_session,
VABufferID data)
{
DDI_FUNCTION_ENTER();
DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
VAStatus vaStatus = VA_STATUS_SUCCESS;
uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, protected_session, &ctxType);
DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
{
DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
vaStatus = prot->ProtectedSessionExecute(ctx, protected_session, data);
}
else
{
DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
}
return vaStatus;
}
VAStatus DdiMediaProtected::DdiMedia_ProtectedSessionCreateBuffer(
VADriverContextP ctx,
VAContextID context,
VABufferType type,
uint32_t size,
uint32_t num_elements,
void *data,
VABufferID *bufId)
{
DDI_FUNCTION_ENTER();
DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
VAStatus vaStatus = VA_STATUS_SUCCESS;
uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
void *ctxPtr = DdiMedia_GetContextFromProtectedSessionID(ctx, context, &ctxType);
DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT);
if (ctxType == DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT)
{
DdiMediaProtected *prot = DdiMediaProtected::GetInstance(DDI_PROTECTED_CONTENT);
DDI_CHK_NULL(prot, "nullptr prot", VA_STATUS_ERROR_ALLOCATION_FAILED);
vaStatus = prot->ProtectedSessionCreateBuffer(ctx, context, type, size, num_elements, data, bufId);
}
else
{
DDI_ASSERTMESSAGE("DDI: Invalid protected_session");
vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
}
return vaStatus;
}
VAStatus DdiMediaProtected::CreateProtectedSession(
VADriverContextP ctx,
VAConfigID config_id,
VAProtectedSessionID *protected_session)
{
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus DdiMediaProtected::DestroyProtectedSession(
VADriverContextP ctx,
VAProtectedSessionID protected_session)
{
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus DdiMediaProtected::AttachProtectedSession(
VADriverContextP ctx,
VAContextID context,
VAProtectedSessionID protected_session)
{
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus DdiMediaProtected::DetachProtectedSession(
VADriverContextP ctx,
VAContextID context)
{
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus DdiMediaProtected::ProtectedSessionExecute(
VADriverContextP ctx,
VAProtectedSessionID protected_session,
VABufferID data)
{
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
VAStatus DdiMediaProtected::ProtectedSessionCreateBuffer(
VADriverContextP ctx,
VAProtectedSessionID protected_session,
VABufferType type,
uint32_t size,
uint32_t num_elements,
void *data,
VABufferID *bufId)
{
return VA_STATUS_ERROR_UNIMPLEMENTED;
}
uint64_t DdiMediaProtected::GetProtectedSurfaceTag(PDDI_MEDIA_CONTEXT media_ctx)
{
return 0;
}
void DdiMedia_FreeProtectedSessionHeap(
VADriverContextP ctx,
PDDI_MEDIA_HEAP contextHeap,
int32_t vaContextOffset,
int32_t ctxNums)
{
PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)contextHeap->pHeapBase;
if (nullptr == mediaContextHeapBase)
return;
for (int32_t elementId = 0; elementId < ctxNums; ++elementId)
{
PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT mediaContextHeapElmt = &mediaContextHeapBase[elementId];
if (nullptr == mediaContextHeapElmt->pVaContext)
continue;
VAContextID vaCtxID = (VAContextID)(mediaContextHeapElmt->uiVaContextID + vaContextOffset);
DdiMediaProtected::DdiMedia_DestroyProtectedSession(ctx, vaCtxID);
}
}
static void* DdiMedia_GetVaContextFromHeap(
PDDI_MEDIA_HEAP mediaHeap,
uint32_t index,
PMEDIA_MUTEX_T mutex)
{
PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaCtxHeapElmt = nullptr;
void *context = nullptr;
DdiMediaUtil_LockMutex(mutex);
if(nullptr == mediaHeap || index >= mediaHeap->uiAllocatedHeapElements)
{
DdiMediaUtil_UnLockMutex(mutex);
return nullptr;
}
vaCtxHeapElmt = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaHeap->pHeapBase;
vaCtxHeapElmt += index;
context = vaCtxHeapElmt->pVaContext;
DdiMediaUtil_UnLockMutex(mutex);
return context;
}
void* DdiMedia_GetContextFromProtectedSessionID(
VADriverContextP ctx,
VAProtectedSessionID vaID,
uint32_t *ctxType)
{
PDDI_MEDIA_CONTEXT mediaCtx = nullptr;
uint32_t heap_index = 0, prot_index = 0;
void *pSession = nullptr;
DDI_CHK_NULL(ctx, "nullptr ctx", nullptr);
DDI_CHK_NULL(ctxType, "nullptr ctxType", nullptr);
mediaCtx = DdiMedia_GetMediaContext(ctx);
prot_index = vaID & DDI_MEDIA_MASK_VACONTEXTID;
heap_index = vaID & DDI_MEDIA_MASK_VAPROTECTEDSESSION_ID;
if ((vaID&DDI_MEDIA_MASK_VACONTEXT_TYPE) != DDI_MEDIA_VACONTEXTID_OFFSET_PROT)
{
DDI_ASSERTMESSAGE("Invalid protected session: 0x%x", vaID);
*ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
return nullptr;
}
// 0 ~ 0x8000000: LP context
// 0x8000000~0x10000000: CP context
if (prot_index < DDI_MEDIA_VACONTEXTID_OFFSET_PROT_CP)
{
DDI_VERBOSEMESSAGE("LP protected session detected: 0x%x", vaID);
*ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED_LINK;
return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, heap_index, &mediaCtx->ProtMutex);
}
DDI_VERBOSEMESSAGE("CP protected session detected: 0x%x", vaID);
*ctxType = DDI_MEDIA_CONTEXT_TYPE_PROTECTED_CONTENT;
return DdiMedia_GetVaContextFromHeap(mediaCtx->pProtCtxHeap, heap_index, &mediaCtx->ProtMutex);
}