| /* |
| * Copyright (c) 2009-2021, 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_libva.cpp |
| //! \brief libva(and its extension) interface implementaion. |
| //! |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <fcntl.h> |
| #include <sys/mman.h> |
| #include <sys/ioctl.h> |
| #include <unistd.h> |
| |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| #include <X11/Xutil.h> |
| #endif |
| |
| #include <linux/fb.h> |
| |
| #include "media_libva.h" |
| |
| #include "media_libva_util.h" |
| #include "media_libva_decoder.h" |
| #include "media_libva_encoder.h" |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| #include "media_libva_putsurface_linux.h" |
| #endif |
| #include "media_libva_vp.h" |
| #include "media_ddi_prot.h" |
| #include "mos_os.h" |
| |
| #include "hwinfo_linux.h" |
| #include "mediamemdecomp.h" |
| #include "mos_solo_generic.h" |
| #include "media_libva_caps.h" |
| #include "media_interfaces_mmd.h" |
| #include "media_interfaces_mcpy.h" |
| #include "media_user_settings_mgr.h" |
| #include "cplib_utils.h" |
| #include "media_interfaces.h" |
| #include "mos_interface.h" |
| #include "drm_fourcc.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| extern VAStatus DdiDestroyContextCM (VADriverContextP vaDrvCtx, VAContextID vaCtxID); |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| extern template class MediaInterfacesFactory<MhwInterfaces>; |
| |
| VAProcFilterType vp_supported_filters[DDI_VP_MAX_NUM_FILTERS] = { |
| VAProcFilterNoiseReduction, |
| VAProcFilterDeinterlacing, |
| VAProcFilterSharpening, |
| VAProcFilterColorBalance, |
| VAProcFilterSkinToneEnhancement, |
| VAProcFilterTotalColorCorrection, |
| VAProcFilterHVSNoiseReduction, |
| VAProcFilterHighDynamicRangeToneMapping |
| }; |
| |
| VAProcColorStandardType vp_input_color_std[DDI_VP_NUM_INPUT_COLOR_STD] = { |
| VAProcColorStandardBT601, |
| VAProcColorStandardBT709, |
| VAProcColorStandardSRGB, |
| VAProcColorStandardSTRGB, |
| VAProcColorStandardBT2020, |
| VAProcColorStandardExplicit |
| }; |
| |
| VAProcColorStandardType vp_output_color_std[DDI_VP_NUM_OUT_COLOR_STD] = { |
| VAProcColorStandardBT601, |
| VAProcColorStandardBT709, |
| VAProcColorStandardSRGB, |
| VAProcColorStandardSTRGB, |
| VAProcColorStandardBT2020, |
| VAProcColorStandardExplicit |
| }; |
| |
| static VAStatus DdiMedia_DestroyContext ( |
| VADriverContextP ctx, |
| VAContextID context); |
| |
| // Making this API public since media_libva_vp.c calls this |
| VAStatus DdiMedia_MapBuffer ( |
| VADriverContextP ctx, |
| VABufferID buf_id, /* in */ |
| void **pbuf /* out */ |
| ); |
| |
| VAStatus DdiMedia_UnmapBuffer ( |
| VADriverContextP ctx, |
| VABufferID buf_id /* in */ |
| ); |
| |
| //! |
| //! \brief Destroy buffer |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] buffer_id |
| //! VA buffer ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_DestroyBuffer ( |
| VADriverContextP ctx, |
| VABufferID buffer_id |
| ); |
| |
| VAStatus DdiMedia_DestroyImage ( |
| VADriverContextP ctx, |
| VAImageID image |
| ); |
| |
| static PDDI_MEDIA_CONTEXT DdiMedia_CreateMediaDriverContext() |
| { |
| PDDI_MEDIA_CONTEXT mediaCtx; |
| |
| mediaCtx = (PDDI_MEDIA_CONTEXT)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_CONTEXT)); |
| |
| return mediaCtx; |
| } |
| |
| // refine this for decoder later |
| static bool DdiMedia_ReleaseSliceControlBuffer( |
| uint32_t ctxType, |
| void *ctx, |
| DDI_MEDIA_BUFFER *buf) |
| { |
| DDI_UNUSED(buf); |
| |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| { |
| PDDI_DECODE_CONTEXT decCtx; |
| |
| decCtx = DdiDecode_GetDecContextFromPVOID(ctx); |
| DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(decCtx->BufMgr); |
| |
| switch (decCtx->wMode) |
| { |
| case CODECHAL_DECODE_MODE_AVCVLD: |
| if(decCtx->bShortFormatInUse) |
| { |
| if(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base == nullptr) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264 == nullptr) |
| { |
| return false; |
| } |
| } |
| break; |
| case CODECHAL_DECODE_MODE_MPEG2VLD: |
| if(bufMgr->Codec_Param.Codec_Param_MPEG2.pVASliceParaBufMPEG2 == nullptr) |
| { |
| return false; |
| } |
| break; |
| case CODECHAL_DECODE_MODE_VC1VLD: |
| if(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 == nullptr) |
| { |
| return false; |
| } |
| break; |
| case CODECHAL_DECODE_MODE_JPEG: |
| if(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG == nullptr) |
| { |
| return false; |
| } |
| break; |
| case CODECHAL_DECODE_MODE_VP8VLD: |
| if(bufMgr->Codec_Param.Codec_Param_VP8.pVASliceParaBufVP8 == nullptr) |
| { |
| return false; |
| } |
| break; |
| case CODECHAL_DECODE_MODE_HEVCVLD: |
| if(decCtx->bShortFormatInUse) |
| { |
| if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC == nullptr) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC == nullptr && |
| bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext == nullptr) |
| { |
| return false; |
| } |
| } |
| break; |
| case CODECHAL_DECODE_MODE_VP9VLD: |
| if(bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9 == nullptr) |
| { |
| return false; |
| } |
| break; |
| default: |
| return false; |
| } |
| break; |
| } |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| break; |
| default: |
| break; |
| } |
| |
| return true; |
| } |
| |
| static bool DdiMedia_ReleaseBpBuffer( |
| DDI_CODEC_COM_BUFFER_MGR *bufMgr, |
| DDI_MEDIA_BUFFER *buf) |
| { |
| DDI_UNUSED(bufMgr); |
| DDI_UNUSED(buf); |
| return true; |
| } |
| |
| static bool DdiMedia_ReleaseBsBuffer( |
| DDI_CODEC_COM_BUFFER_MGR *bufMgr, |
| DDI_MEDIA_BUFFER *buf) |
| { |
| if ((bufMgr == nullptr) || (buf == nullptr)) |
| { |
| return true; |
| } |
| |
| if (buf->format == Media_Format_CPU) |
| { |
| for(uint32_t i = 0; i < bufMgr->dwNumSliceData; i++) |
| { |
| if(bufMgr->pSliceData[i].pBaseAddress == buf->pData) |
| { |
| DdiMediaUtil_FreeBuffer(buf); |
| bufMgr->pSliceData[i].pBaseAddress = nullptr; |
| if (bufMgr->pSliceData[i].pMappedGPUBuffer != nullptr) |
| { |
| DdiMediaUtil_UnlockBuffer(bufMgr->pSliceData[i].pMappedGPUBuffer); |
| if (bufMgr->pSliceData[i].pMappedGPUBuffer->bMapped == false) |
| { |
| DdiMediaUtil_FreeBuffer(bufMgr->pSliceData[i].pMappedGPUBuffer); |
| MOS_FreeMemory(bufMgr->pSliceData[i].pMappedGPUBuffer); |
| } |
| } |
| MOS_ZeroMemory((void*)(&(bufMgr->pSliceData[i])), sizeof(bufMgr->pSliceData[0])); |
| bufMgr->dwNumSliceData --; |
| return true; |
| } |
| } |
| return false; |
| } |
| else |
| { |
| if (bufMgr->dwNumSliceData) |
| bufMgr->dwNumSliceData--; |
| } |
| return true; |
| } |
| |
| static uint32_t DdiMedia_CreateRenderTarget( |
| PDDI_MEDIA_CONTEXT mediaDrvCtx, |
| DDI_MEDIA_FORMAT mediaFormat, |
| uint32_t width, |
| uint32_t height, |
| DDI_MEDIA_SURFACE_DESCRIPTOR *surfDesc, |
| uint32_t surfaceUsageHint, |
| int memType |
| ) |
| { |
| DdiMediaUtil_LockMutex(&mediaDrvCtx->SurfaceMutex); |
| |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceElement = DdiMediaUtil_AllocPMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap); |
| if (nullptr == surfaceElement) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex); |
| return VA_INVALID_ID; |
| } |
| |
| surfaceElement->pSurface = (DDI_MEDIA_SURFACE *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE)); |
| if (nullptr == surfaceElement->pSurface) |
| { |
| DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap, surfaceElement->uiVaSurfaceID); |
| DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex); |
| return VA_INVALID_ID; |
| } |
| |
| surfaceElement->pSurface->pMediaCtx = mediaDrvCtx; |
| surfaceElement->pSurface->iWidth = width; |
| surfaceElement->pSurface->iHeight = height; |
| surfaceElement->pSurface->pSurfDesc = surfDesc; |
| surfaceElement->pSurface->format = mediaFormat; |
| surfaceElement->pSurface->uiLockedBufID = VA_INVALID_ID; |
| surfaceElement->pSurface->uiLockedImageID = VA_INVALID_ID; |
| surfaceElement->pSurface->surfaceUsageHint= surfaceUsageHint; |
| surfaceElement->pSurface->memType = memType; |
| |
| if(DdiMediaUtil_CreateSurface(surfaceElement->pSurface, mediaDrvCtx)!= VA_STATUS_SUCCESS) |
| { |
| MOS_FreeMemory(surfaceElement->pSurface); |
| DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaDrvCtx->pSurfaceHeap, surfaceElement->uiVaSurfaceID); |
| DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex); |
| return VA_INVALID_ID; |
| } |
| |
| mediaDrvCtx->uiNumSurfaces++; |
| uint32_t surfaceID = surfaceElement->uiVaSurfaceID; |
| DdiMediaUtil_UnLockMutex(&mediaDrvCtx->SurfaceMutex); |
| return surfaceID; |
| } |
| |
| VAStatus |
| DdiMedia_HybridQueryBufferAttributes ( |
| VADisplay dpy, |
| VAContextID context, |
| VABufferType bufferType, |
| void *outputData, |
| uint32_t *outputDataLen |
| ) |
| { |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Set Frame ID |
| //! |
| //! \param [in] dpy |
| //! VA display |
| //! \param [in] surface |
| //! VA surface ID |
| //! \param [in] frame_id |
| //! Frame ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_SetFrameID( |
| VADisplay dpy, |
| VASurfaceID surface, |
| uint32_t frame_id |
| ) |
| { |
| VADriverContextP ctx = (((VADisplayContextP)dpy)->pDriverContext); |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| mediaSurface->frame_idx = frame_id; |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Convert media format to OS format |
| //! |
| //! \param [in] format |
| //! Ddi media format |
| //! |
| //! \return Os format if call sucesss,else |
| //! VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT if fail |
| //! |
| int32_t DdiMedia_MediaFormatToOsFormat(DDI_MEDIA_FORMAT format) |
| { |
| switch (format) |
| { |
| case Media_Format_X8R8G8B8: |
| return VA_FOURCC_XRGB; |
| case Media_Format_X8B8G8R8: |
| return VA_FOURCC_XBGR; |
| case Media_Format_A8B8G8R8: |
| return VA_FOURCC_ABGR; |
| case Media_Format_R10G10B10A2: |
| return VA_FOURCC_A2B10G10R10; |
| case Media_Format_R8G8B8A8: |
| return VA_FOURCC_RGBA; |
| case Media_Format_A8R8G8B8: |
| return VA_FOURCC_ARGB; |
| case Media_Format_B10G10R10A2: |
| return VA_FOURCC_A2R10G10B10; |
| case Media_Format_R10G10B10X2: |
| return VA_FOURCC_X2B10G10R10; |
| case Media_Format_B10G10R10X2: |
| return VA_FOURCC_X2R10G10B10; |
| case Media_Format_R5G6B5: |
| return VA_FOURCC_R5G6B5; |
| case Media_Format_R8G8B8: |
| return VA_FOURCC_R8G8B8; |
| case Media_Format_NV12: |
| return VA_FOURCC_NV12; |
| case Media_Format_NV21: |
| return VA_FOURCC_NV21; |
| case Media_Format_YUY2: |
| return VA_FOURCC_YUY2; |
| case Media_Format_UYVY: |
| return VA_FOURCC_UYVY; |
| case Media_Format_YV12: |
| return VA_FOURCC_YV12; |
| case Media_Format_IYUV: |
| return VA_FOURCC_IYUV; |
| case Media_Format_I420: |
| return VA_FOURCC_I420; |
| case Media_Format_400P: |
| return VA_FOURCC('4','0','0','P'); |
| case Media_Format_IMC3: |
| return VA_FOURCC_IMC3; |
| case Media_Format_422H: |
| return VA_FOURCC_422H; |
| case Media_Format_422V: |
| return VA_FOURCC_422V; |
| case Media_Format_411P: |
| return VA_FOURCC_411P; |
| case Media_Format_444P: |
| return VA_FOURCC_444P; |
| case Media_Format_RGBP: |
| return VA_FOURCC_RGBP; |
| case Media_Format_BGRP: |
| return VA_FOURCC_BGRP; |
| case Media_Format_Buffer: |
| return VA_FOURCC_P208; |
| case Media_Format_P010: |
| return VA_FOURCC_P010; |
| case Media_Format_P012: |
| return VA_FOURCC_P012; |
| case Media_Format_P016: |
| return VA_FOURCC_P016; |
| case Media_Format_Y210: |
| return VA_FOURCC_Y210; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y212: |
| return VA_FOURCC_Y212; |
| #endif |
| case Media_Format_Y216: |
| return VA_FOURCC_Y216; |
| case Media_Format_AYUV: |
| return VA_FOURCC_AYUV; |
| case Media_Format_Y410: |
| return VA_FOURCC_Y410; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y412: |
| return VA_FOURCC_Y412; |
| #endif |
| case Media_Format_Y416: |
| return VA_FOURCC_Y416; |
| case Media_Format_Y8: |
| return VA_FOURCC_Y8; |
| case Media_Format_Y16S: |
| return VA_FOURCC_Y16; |
| case Media_Format_Y16U: |
| return VA_FOURCC_Y16; |
| case Media_Format_VYUY: |
| return VA_FOURCC_VYUY; |
| case Media_Format_YVYU: |
| return VA_FOURCC_YVYU; |
| case Media_Format_A16R16G16B16: |
| return VA_FOURCC_ARGB64; |
| case Media_Format_A16B16G16R16: |
| return VA_FOURCC_ABGR64; |
| |
| default: |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| } |
| |
| //! |
| //! \brief Convert Os format to media format |
| //! |
| //! \param [in] fourcc |
| //! FourCC |
| //! \param [in] rtformatType |
| //! Rt format type |
| //! |
| //! \return DDI_MEDIA_FORMAT |
| //! Ddi media format |
| //! |
| DDI_MEDIA_FORMAT DdiMedia_OsFormatToMediaFormat(int32_t fourcc, int32_t rtformatType) |
| { |
| switch (fourcc) |
| { |
| case VA_FOURCC_A2R10G10B10: |
| return Media_Format_B10G10R10A2; |
| case VA_FOURCC_A2B10G10R10: |
| return Media_Format_R10G10B10A2; |
| case VA_FOURCC_X2R10G10B10: |
| return Media_Format_B10G10R10X2; |
| case VA_FOURCC_X2B10G10R10: |
| return Media_Format_R10G10B10X2; |
| case VA_FOURCC_BGRA: |
| case VA_FOURCC_ARGB: |
| #ifdef VA_RT_FORMAT_RGB32_10BPP |
| if(VA_RT_FORMAT_RGB32_10BPP == rtformatType) |
| { |
| return Media_Format_B10G10R10A2; |
| } |
| #endif |
| return Media_Format_A8R8G8B8; |
| case VA_FOURCC_RGBA: |
| #ifdef VA_RT_FORMAT_RGB32_10BPP |
| if(VA_RT_FORMAT_RGB32_10BPP == rtformatType) |
| { |
| return Media_Format_R10G10B10A2; |
| } |
| #endif |
| return Media_Format_R8G8B8A8; |
| case VA_FOURCC_ABGR: |
| #ifdef VA_RT_FORMAT_RGB32_10BPP |
| if(VA_RT_FORMAT_RGB32_10BPP == rtformatType) |
| { |
| return Media_Format_R10G10B10A2; |
| } |
| #endif |
| return Media_Format_A8B8G8R8; |
| case VA_FOURCC_BGRX: |
| case VA_FOURCC_XRGB: |
| return Media_Format_X8R8G8B8; |
| case VA_FOURCC_XBGR: |
| case VA_FOURCC_RGBX: |
| return Media_Format_X8B8G8R8; |
| case VA_FOURCC_R5G6B5: |
| return Media_Format_R5G6B5; |
| case VA_FOURCC_R8G8B8: |
| return Media_Format_R8G8B8; |
| case VA_FOURCC_NV12: |
| return Media_Format_NV12; |
| case VA_FOURCC_NV21: |
| return Media_Format_NV21; |
| case VA_FOURCC_YUY2: |
| return Media_Format_YUY2; |
| case VA_FOURCC_UYVY: |
| return Media_Format_UYVY; |
| case VA_FOURCC_YV12: |
| return Media_Format_YV12; |
| case VA_FOURCC_IYUV: |
| return Media_Format_IYUV; |
| case VA_FOURCC_I420: |
| return Media_Format_I420; |
| case VA_FOURCC_422H: |
| return Media_Format_422H; |
| case VA_FOURCC_422V: |
| return Media_Format_422V; |
| case VA_FOURCC('4','0','0','P'): |
| case VA_FOURCC_Y800: |
| return Media_Format_400P; |
| case VA_FOURCC_411P: |
| return Media_Format_411P; |
| case VA_FOURCC_IMC3: |
| return Media_Format_IMC3; |
| case VA_FOURCC_444P: |
| return Media_Format_444P; |
| case VA_FOURCC_BGRP: |
| return Media_Format_BGRP; |
| case VA_FOURCC_RGBP: |
| return Media_Format_RGBP; |
| case VA_FOURCC_P208: |
| return Media_Format_Buffer; |
| case VA_FOURCC_P010: |
| return Media_Format_P010; |
| case VA_FOURCC_P012: |
| return Media_Format_P012; |
| case VA_FOURCC_P016: |
| return Media_Format_P016; |
| case VA_FOURCC_Y210: |
| return Media_Format_Y210; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212: |
| return Media_Format_Y212; |
| #endif |
| case VA_FOURCC_Y216: |
| return Media_Format_Y216; |
| case VA_FOURCC_AYUV: |
| return Media_Format_AYUV; |
| case VA_FOURCC_Y410: |
| return Media_Format_Y410; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y412: |
| return Media_Format_Y412; |
| #endif |
| case VA_FOURCC_Y416: |
| return Media_Format_Y416; |
| case VA_FOURCC_Y8: |
| return Media_Format_Y8; |
| case VA_FOURCC_Y16: |
| return Media_Format_Y16S; |
| case VA_FOURCC_VYUY: |
| return Media_Format_VYUY; |
| case VA_FOURCC_YVYU: |
| return Media_Format_YVYU; |
| case VA_FOURCC_ARGB64: |
| return Media_Format_A16R16G16B16; |
| case VA_FOURCC_ABGR64: |
| return Media_Format_A16B16G16R16; |
| |
| default: |
| return Media_Format_Count; |
| } |
| } |
| |
| static VAStatus DdiMedia_GetChromaPitchHeight( |
| uint32_t fourcc, |
| uint32_t pitch, |
| uint32_t height, |
| uint32_t *chromaPitch, |
| uint32_t *chromaHeight) |
| { |
| DDI_CHK_NULL(chromaPitch, "nullptr chromaPitch", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(chromaHeight, "nullptr chromaHeight", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| switch(fourcc) |
| { |
| case VA_FOURCC_NV12: |
| case VA_FOURCC_P010: |
| case VA_FOURCC_P012: |
| case VA_FOURCC_P016: |
| *chromaHeight = MOS_ALIGN_CEIL(height, 2) / 2; |
| *chromaPitch = pitch; |
| break; |
| case VA_FOURCC_I420: |
| case VA_FOURCC_YV12: |
| *chromaHeight = MOS_ALIGN_CEIL(height, 2) / 2; |
| *chromaPitch = MOS_ALIGN_CEIL(pitch, 2) / 2; |
| break; |
| case VA_FOURCC_411P: |
| case VA_FOURCC_422H: |
| case VA_FOURCC_444P: |
| *chromaHeight = height; |
| *chromaPitch = pitch; |
| break; |
| case VA_FOURCC_422V: |
| case VA_FOURCC_IMC3: |
| *chromaHeight = MOS_ALIGN_CEIL(height, 2) / 2; |
| *chromaPitch = pitch; |
| break; |
| default: |
| *chromaPitch = 0; |
| *chromaHeight = 0; |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| |
| #define X11_LIB_NAME "libX11.so.6" |
| |
| /* |
| * Close opened libX11.so lib, free related function table. |
| */ |
| static void DdiMedia_DestroyX11Connection( |
| PDDI_MEDIA_CONTEXT mediaCtx |
| ) |
| { |
| if (nullptr == mediaCtx || nullptr == mediaCtx->X11FuncTable) |
| { |
| return; |
| } |
| |
| MOS_FreeLibrary(mediaCtx->X11FuncTable->pX11LibHandle); |
| MOS_FreeMemory(mediaCtx->X11FuncTable); |
| mediaCtx->X11FuncTable = nullptr; |
| |
| return; |
| } |
| |
| /* |
| * dlopen libX11.so, setup the function table, which is used by |
| * DdiCodec_PutSurface (Linux) so far. |
| */ |
| static VAStatus DdiMedia_ConnectX11( |
| PDDI_MEDIA_CONTEXT mediaCtx |
| ) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| mediaCtx->X11FuncTable = (PDDI_X11_FUNC_TABLE)MOS_AllocAndZeroMemory(sizeof(DDI_X11_FUNC_TABLE)); |
| DDI_CHK_NULL(mediaCtx->X11FuncTable, "Allocation Failed for X11FuncTable", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| HMODULE h_module = nullptr; |
| MOS_STATUS mos_status = MOS_LoadLibrary(X11_LIB_NAME, &h_module); |
| if (MOS_STATUS_SUCCESS != mos_status || nullptr == h_module) |
| { |
| DdiMedia_DestroyX11Connection(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| mediaCtx->X11FuncTable->pX11LibHandle = h_module; |
| |
| mediaCtx->X11FuncTable->pfnXCreateGC = |
| MOS_GetProcAddress(h_module, "XCreateGC"); |
| mediaCtx->X11FuncTable->pfnXFreeGC = |
| MOS_GetProcAddress(h_module, "XFreeGC"); |
| mediaCtx->X11FuncTable->pfnXCreateImage = |
| MOS_GetProcAddress(h_module, "XCreateImage"); |
| mediaCtx->X11FuncTable->pfnXDestroyImage = |
| MOS_GetProcAddress(h_module, "XDestroyImage"); |
| mediaCtx->X11FuncTable->pfnXPutImage = |
| MOS_GetProcAddress(h_module, "XPutImage"); |
| |
| if (nullptr == mediaCtx->X11FuncTable->pfnXCreateGC || |
| nullptr == mediaCtx->X11FuncTable->pfnXFreeGC || |
| nullptr == mediaCtx->X11FuncTable->pfnXCreateImage || |
| nullptr == mediaCtx->X11FuncTable->pfnXDestroyImage || |
| nullptr == mediaCtx->X11FuncTable->pfnXPutImage) |
| { |
| DdiMedia_DestroyX11Connection(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| #endif |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| //! \Free allocated surfaceheap elements |
| //! \params |
| //! [in] PDDI_MEDIA_CONTEXT |
| //! [out] none |
| //! \returns |
| ///////////////////////////////////////////////////////////////////////////// |
| static void DdiMedia_FreeSurfaceHeapElements(PDDI_MEDIA_CONTEXT mediaCtx) |
| { |
| if (nullptr == mediaCtx) |
| return; |
| PDDI_MEDIA_HEAP surfaceHeap = mediaCtx->pSurfaceHeap; |
| |
| if (nullptr == surfaceHeap) |
| return; |
| |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapBase = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase; |
| if (nullptr == mediaSurfaceHeapBase) |
| return; |
| |
| int32_t surfaceNums = mediaCtx->uiNumSurfaces; |
| for (int32_t elementId = 0; elementId < surfaceNums; elementId++) |
| { |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = &mediaSurfaceHeapBase[elementId]; |
| if (nullptr == mediaSurfaceHeapElmt->pSurface) |
| continue; |
| |
| DdiMediaUtil_FreeSurface(mediaSurfaceHeapElmt->pSurface); |
| MOS_FreeMemory(mediaSurfaceHeapElmt->pSurface); |
| DdiMediaUtil_ReleasePMediaSurfaceFromHeap(surfaceHeap,mediaSurfaceHeapElmt->uiVaSurfaceID); |
| mediaCtx->uiNumSurfaces--; |
| } |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| //! \Free allocated bufferheap elements |
| //! \params |
| //! [in] VADriverContextP |
| //! [out] none |
| //! \returns |
| ///////////////////////////////////////////////////////////////////////////// |
| static void DdiMedia_FreeBufferHeapElements(VADriverContextP ctx) |
| { |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| if (nullptr == mediaCtx) |
| return; |
| |
| PDDI_MEDIA_HEAP bufferHeap = mediaCtx->pBufferHeap; |
| if (nullptr == bufferHeap) |
| return; |
| |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase; |
| if (nullptr == mediaBufferHeapBase) |
| return; |
| |
| int32_t bufNums = mediaCtx->uiNumBufs; |
| for (int32_t elementId = 0; bufNums > 0; ++elementId) |
| { |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt = &mediaBufferHeapBase[elementId]; |
| if (nullptr == mediaBufferHeapElmt->pBuffer) |
| continue; |
| DdiMedia_DestroyBuffer(ctx,mediaBufferHeapElmt->uiVaBufferID); |
| //Ensure the non-empty buffer to be destroyed. |
| --bufNums; |
| } |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| //! \Free allocated Imageheap elements |
| //! \params |
| //! [in] VADriverContextP |
| //! [out] none |
| //! \returns |
| ///////////////////////////////////////////////////////////////////////////// |
| static void DdiMedia_FreeImageHeapElements(VADriverContextP ctx) |
| { |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| if (nullptr == mediaCtx) |
| return; |
| |
| PDDI_MEDIA_HEAP imageHeap = mediaCtx->pImageHeap; |
| if (nullptr == imageHeap) |
| return; |
| |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT mediaImageHeapBase = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase; |
| if (nullptr == mediaImageHeapBase) |
| return; |
| |
| int32_t imageNums = mediaCtx->uiNumImages; |
| for (int32_t elementId = 0; elementId < imageNums; ++elementId) |
| { |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT mediaImageHeapElmt = &mediaImageHeapBase[elementId]; |
| if (nullptr == mediaImageHeapElmt->pImage) |
| continue; |
| DdiMedia_DestroyImage(ctx,mediaImageHeapElmt->uiVaImageID); |
| } |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| //! \Execute free allocated bufferheap elements for FreeContextHeapElements function |
| //! \params |
| //! [in] VADriverContextP |
| //! [in] PDDI_MEDIA_HEAP |
| //! [out] none |
| //! \returns |
| ///////////////////////////////////////////////////////////////////////////// |
| static void DdiMedia_FreeContextHeap(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); |
| DdiMedia_DestroyContext(ctx,vaCtxID); |
| } |
| |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| //! \Free allocated contextheap elements |
| //! \params |
| //! [in] VADriverContextP |
| //! [out] none |
| //! \returns |
| ///////////////////////////////////////////////////////////////////////////// |
| static void DdiMedia_FreeContextHeapElements(VADriverContextP ctx) |
| { |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| if (nullptr == mediaCtx) |
| return; |
| |
| //Free EncoderContext |
| PDDI_MEDIA_HEAP encoderContextHeap = mediaCtx->pEncoderCtxHeap; |
| int32_t encCtxNums = mediaCtx->uiNumEncoders; |
| if (nullptr != encoderContextHeap) |
| DdiMedia_FreeContextHeap(ctx,encoderContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_ENCODER,encCtxNums); |
| |
| //Free DecoderContext |
| PDDI_MEDIA_HEAP decoderContextHeap = mediaCtx->pDecoderCtxHeap; |
| int32_t decCtxNums = mediaCtx->uiNumDecoders; |
| if (nullptr != decoderContextHeap) |
| DdiMedia_FreeContextHeap(ctx,decoderContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_DECODER,decCtxNums); |
| |
| //Free VpContext |
| PDDI_MEDIA_HEAP vpContextHeap = mediaCtx->pVpCtxHeap; |
| int32_t vpctxNums = mediaCtx->uiNumVPs; |
| if (nullptr != vpContextHeap) |
| DdiMedia_FreeContextHeap(ctx,vpContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_VP,vpctxNums); |
| |
| //Free ProtContext |
| PDDI_MEDIA_HEAP protContextHeap = mediaCtx->pProtCtxHeap; |
| int32_t protCtxNums = mediaCtx->uiNumProts; |
| if (nullptr != protContextHeap) |
| DdiMedia_FreeProtectedSessionHeap(ctx,protContextHeap,DDI_MEDIA_VACONTEXTID_OFFSET_PROT,protCtxNums); |
| |
| //Free MfeContext |
| PDDI_MEDIA_HEAP mfeContextHeap = mediaCtx->pMfeCtxHeap; |
| int32_t mfeCtxNums = mediaCtx->uiNumMfes; |
| if (nullptr != mfeContextHeap) |
| DdiMedia_FreeContextHeap(ctx, mfeContextHeap, DDI_MEDIA_VACONTEXTID_OFFSET_MFE, mfeCtxNums); |
| |
| // Free media memory decompression data structure |
| if (!mediaCtx->m_apoMosEnabled && mediaCtx->pMediaMemDecompState) |
| { |
| MediaMemDecompBaseState *mediaMemCompState = |
| static_cast<MediaMemDecompBaseState*>(mediaCtx->pMediaMemDecompState); |
| MOS_Delete(mediaMemCompState); |
| } |
| mediaCtx->pMediaMemDecompState = nullptr; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| //! \Free allocated ContextCM elements |
| //! \params |
| //! [in] VADriverContextP |
| //! [out] none |
| //! \returns |
| ///////////////////////////////////////////////////////////////////////////// |
| static void DdiMedia_FreeContextCMElements(VADriverContextP ctx) |
| { |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| if (nullptr == mediaCtx) |
| return; |
| |
| int32_t cmnums = mediaCtx->uiNumCMs; |
| for (int32_t elementId = 0; elementId < cmnums; elementId++) |
| { |
| VAContextID vaCtxID = elementId + DDI_MEDIA_VACONTEXTID_OFFSET_CM; |
| DdiDestroyContextCM(ctx,vaCtxID); |
| } |
| } |
| |
| //! |
| //! \brief Get VA image from VA image ID |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to ddi media context |
| //! \param [in] imageID |
| //! VA image ID |
| //! |
| //! \return VAImage* |
| //! Pointer to VAImage |
| //! |
| VAImage* DdiMedia_GetVAImageFromVAImageID (PDDI_MEDIA_CONTEXT mediaCtx, VAImageID imageID) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr); |
| |
| uint32_t i = (uint32_t)imageID; |
| DDI_CHK_LESS(i, mediaCtx->pImageHeap->uiAllocatedHeapElements, "invalid image id", nullptr); |
| DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex); |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT imageElement = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)mediaCtx->pImageHeap->pHeapBase; |
| imageElement += i; |
| VAImage *vaImage = imageElement->pImage; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex); |
| |
| return vaImage; |
| } |
| |
| //! |
| //! \brief Get ctx from VA buffer ID |
| //! |
| //! \param [in] mediaCtx |
| //! pddi media context |
| //! \param [in] bufferID |
| //! VA Buffer ID |
| //! |
| //! \return void* |
| //! Pointer to buffer heap element context |
| //! |
| void* DdiMedia_GetCtxFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", nullptr); |
| |
| uint32_t i = (uint32_t)bufferID; |
| DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", nullptr); |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase; |
| bufHeapElement += i; |
| void *temp = bufHeapElement->pCtx; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| |
| return temp; |
| } |
| |
| //! |
| //! \brief Get ctx type from VA buffer ID |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to ddi media context |
| //! \param [in] bufferID |
| //! VA buffer ID |
| //! |
| //! \return uint32_t |
| //1 Context type |
| //! |
| uint32_t DdiMedia_GetCtxTypeFromVABufferID (PDDI_MEDIA_CONTEXT mediaCtx, VABufferID bufferID) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", DDI_MEDIA_CONTEXT_TYPE_NONE); |
| |
| uint32_t i = (uint32_t)bufferID; |
| DDI_CHK_LESS(i, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "invalid buffer id", DDI_MEDIA_CONTEXT_TYPE_NONE); |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufHeapElement = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)mediaCtx->pBufferHeap->pHeapBase; |
| bufHeapElement += i; |
| uint32_t ctxType = bufHeapElement->uiCtxType; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| |
| return ctxType; |
| |
| } |
| |
| //! |
| //! \brief Destroy image from VA image ID |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to ddi media context |
| //! \param [in] imageID |
| //! VA image ID |
| //! |
| //! \return bool |
| //! True if destroy image from VA image ID, else fail |
| //! |
| bool DdiMedia_DestroyImageFromVAImageID (PDDI_MEDIA_CONTEXT mediaCtx, VAImageID imageID) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", false); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex); |
| DdiMediaUtil_ReleasePVAImageFromHeap(mediaCtx->pImageHeap, (uint32_t)imageID); |
| mediaCtx->uiNumImages--; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex); |
| return true; |
| } |
| #ifdef _MMC_SUPPORTED |
| //! |
| //! \brief Decompress internal media memory |
| //! |
| //! \param [in] mosCtx |
| //! Pointer to mos context |
| //! \param [in] osResource |
| //! Pointer mos resource |
| //! |
| void DdiMedia_MediaMemoryDecompressInternal(PMOS_CONTEXT mosCtx, PMOS_RESOURCE osResource) |
| { |
| DDI_CHK_NULL(mosCtx, "nullptr mosCtx",); |
| DDI_CHK_NULL(osResource, "nullptr osResource",); |
| DDI_ASSERT(osResource); |
| |
| MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState); |
| |
| if (mosCtx->m_apoMosEnabled && !mediaMemDecompState) |
| { |
| DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", ); |
| } |
| |
| if (!mediaMemDecompState) |
| { |
| mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx)); |
| *mosCtx->ppMediaMemDecompState = mediaMemDecompState; |
| } |
| |
| if (mediaMemDecompState) |
| { |
| mediaMemDecompState->MemoryDecompress(osResource); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("Invalid memory decompression state."); |
| } |
| } |
| |
| //! |
| //! \brief copy internal media surface to another surface |
| //! |
| //! \param [in] mosCtx |
| //! Pointer to mos context |
| //! \param [in] inputOsResource |
| //! Pointer input mos resource |
| //! \param [in] outputOsResource |
| //! Pointer output mos resource |
| //! \param [in] boutputcompressed |
| //! output can be compressed or not |
| //! |
| void DdiMedia_MediaMemoryCopyInternal(PMOS_CONTEXT mosCtx, PMOS_RESOURCE inputOsResource, PMOS_RESOURCE outputOsResource, bool boutputcompressed) |
| { |
| DDI_CHK_NULL(mosCtx, "nullptr mosCtx",); |
| DDI_CHK_NULL(inputOsResource, "nullptr input osResource",); |
| DDI_CHK_NULL(outputOsResource, "nullptr output osResource",); |
| DDI_ASSERT(inputOsResource); |
| DDI_ASSERT(outputOsResource); |
| |
| MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState); |
| |
| if (mosCtx->m_apoMosEnabled && !mediaMemDecompState) |
| { |
| DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", ); |
| } |
| |
| if (!mediaMemDecompState) |
| { |
| mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx)); |
| *mosCtx->ppMediaMemDecompState = mediaMemDecompState; |
| } |
| |
| if (mediaMemDecompState) |
| { |
| mediaMemDecompState->MediaMemoryCopy(inputOsResource, outputOsResource, boutputcompressed); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("Invalid memory decompression state."); |
| } |
| } |
| |
| //! |
| //! \brief copy internal media surface/buffer to another surface/buffer |
| //! |
| //! \param [in] mosCtx |
| //! Pointer to mos context |
| //! \param [in] inputOsResource |
| //! Pointer input mos resource |
| //! \param [in] outputOsResource |
| //! Pointer output mos resource |
| //! \param [in] boutputcompressed |
| //! output can be compressed or not |
| //! \param [in] copyWidth |
| //! The 2D surface Width |
| //! \param [in] copyHeight |
| //! The 2D surface height |
| //! \param [in] copyInputOffset |
| //! The offset of copied surface from |
| //! \param [in] copyOutputOffset |
| //! The offset of copied to |
| //! |
| void DdiMedia_MediaMemoryCopy2DInternal(PMOS_CONTEXT mosCtx, PMOS_RESOURCE inputOsResource, PMOS_RESOURCE outputOsResource, uint32_t copyWidth, uint32_t copyHeight, uint32_t copyInputOffset, uint32_t copyOutputOffset, uint32_t bpp, bool boutputcompressed) |
| { |
| DDI_CHK_NULL(mosCtx, "nullptr mosCtx",); |
| DDI_CHK_NULL(inputOsResource, "nullptr input osResource",); |
| DDI_CHK_NULL(outputOsResource, "nullptr output osResource",); |
| DDI_ASSERT(inputOsResource); |
| DDI_ASSERT(outputOsResource); |
| |
| MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState); |
| |
| if (mosCtx->m_apoMosEnabled && !mediaMemDecompState) |
| { |
| DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", ); |
| } |
| |
| if (!mediaMemDecompState) |
| { |
| mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx)); |
| *mosCtx->ppMediaMemDecompState = mediaMemDecompState; |
| } |
| |
| if (mediaMemDecompState) |
| { |
| mediaMemDecompState->MediaMemoryCopy2D( |
| inputOsResource, |
| outputOsResource, |
| copyWidth, |
| copyHeight, |
| copyInputOffset, |
| copyOutputOffset, |
| bpp, |
| boutputcompressed); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("Invalid memory decompression state."); |
| } |
| } |
| |
| //! |
| //! \brief Tile/Linear format conversion for media surface/buffer |
| //! |
| //! \param [in] mosCtx |
| //! Pointer to mos context |
| //! \param [in] inputOsResource |
| //! Pointer input mos resource |
| //! \param [in] outputOsResource |
| //! Pointer output mos resource |
| //! \param [in] copyWidth |
| //! The 2D surface Width |
| //! \param [in] copyHeight |
| //! The 2D surface height |
| //! \param [in] copyInputOffset |
| //! The offset of copied surface from |
| //! \param [in] copyOutputOffset |
| //! The offset of copied to |
| //! \param [in] isTileToLinear |
| //! Convertion direction, true: tile->linear, false: linear->tile |
| //! \param [in] outputCompressed |
| //! output can be compressed or not |
| //! |
| VAStatus DdiMedia_MediaMemoryTileConvertInternal( |
| PMOS_CONTEXT mosCtx, |
| PMOS_RESOURCE inputOsResource, |
| PMOS_RESOURCE outputOsResource, |
| uint32_t copyWidth, |
| uint32_t copyHeight, |
| uint32_t copyInputOffset, |
| uint32_t copyOutputOffset, |
| bool isTileToLinear, |
| bool outputCompressed) |
| { |
| DDI_CHK_NULL(mosCtx, "nullptr mosCtx", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(inputOsResource, "nullptr input osResource", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(outputOsResource, "nullptr output osResource", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_ASSERT(inputOsResource); |
| DDI_ASSERT(outputOsResource); |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| MediaMemDecompBaseState *mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(*mosCtx->ppMediaMemDecompState); |
| |
| if (mosCtx->m_apoMosEnabled && !mediaMemDecompState) |
| { |
| DDI_CHK_NULL(mediaMemDecompState, "nullptr mediaMemDecompState", VA_STATUS_ERROR_INVALID_PARAMETER); |
| } |
| |
| if (!mediaMemDecompState) |
| { |
| mediaMemDecompState = static_cast<MediaMemDecompBaseState*>(MmdDevice::CreateFactory(mosCtx)); |
| *mosCtx->ppMediaMemDecompState = mediaMemDecompState; |
| } |
| |
| DDI_CHK_NULL(mediaMemDecompState, "Invalid memory decompression state", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| MOS_STATUS mosStatus = mediaMemDecompState->MediaMemoryTileConvert( |
| inputOsResource, |
| outputOsResource, |
| copyWidth, |
| copyHeight, |
| copyInputOffset, |
| copyOutputOffset, |
| isTileToLinear, |
| outputCompressed); |
| if (mosStatus != MOS_STATUS_SUCCESS) |
| { |
| vaStatus = VA_STATUS_ERROR_UNKNOWN; |
| } |
| |
| return vaStatus; |
| } |
| #endif |
| |
| //! |
| //! \brief Decompress a compressed surface. |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to ddi media context |
| //! \param [in] mediaSurface |
| //! Ddi media surface |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_MediaMemoryDecompress(PDDI_MEDIA_CONTEXT mediaCtx, DDI_MEDIA_SURFACE *mediaSurface) |
| { |
| DDI_CHK_NULL(mediaCtx, "Null mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| GMM_RESOURCE_FLAG GmmFlags; |
| |
| MOS_ZeroMemory(&GmmFlags, sizeof(GmmFlags)); |
| GmmFlags = mediaSurface->pGmmResourceInfo->GetResFlags(); |
| |
| if (((GmmFlags.Gpu.MMC || |
| GmmFlags.Gpu.CCS) && |
| GmmFlags.Info.MediaCompressed) || |
| mediaSurface->pGmmResourceInfo->IsMediaMemoryCompressed(0)) |
| { |
| #ifdef _MMC_SUPPORTED |
| MOS_CONTEXT mosCtx; |
| MOS_RESOURCE surface; |
| DdiCpInterface *pCpDdiInterface; |
| |
| MOS_ZeroMemory(&mosCtx, sizeof(mosCtx)); |
| MOS_ZeroMemory(&surface, sizeof(surface)); |
| |
| mosCtx.bufmgr = mediaCtx->pDrmBufMgr; |
| mosCtx.m_gpuContextMgr = mediaCtx->m_gpuContextMgr; |
| mosCtx.m_cmdBufMgr = mediaCtx->m_cmdBufMgr; |
| mosCtx.fd = mediaCtx->fd; |
| mosCtx.iDeviceId = mediaCtx->iDeviceId; |
| mosCtx.SkuTable = mediaCtx->SkuTable; |
| mosCtx.WaTable = mediaCtx->WaTable; |
| mosCtx.gtSystemInfo = *mediaCtx->pGtSystemInfo; |
| mosCtx.platform = mediaCtx->platform; |
| |
| mosCtx.ppMediaMemDecompState = &mediaCtx->pMediaMemDecompState; |
| mosCtx.pfnMemoryDecompress = mediaCtx->pfnMemoryDecompress; |
| mosCtx.pfnMediaMemoryCopy = mediaCtx->pfnMediaMemoryCopy; |
| mosCtx.pfnMediaMemoryCopy2D = mediaCtx->pfnMediaMemoryCopy2D; |
| mosCtx.gtSystemInfo = *mediaCtx->pGtSystemInfo; |
| mosCtx.m_auxTableMgr = mediaCtx->m_auxTableMgr; |
| mosCtx.pGmmClientContext = mediaCtx->pGmmClientContext; |
| |
| mosCtx.m_osDeviceContext = mediaCtx->m_osDeviceContext; |
| mosCtx.m_apoMosEnabled = mediaCtx->m_apoMosEnabled; |
| |
| pCpDdiInterface = Create_DdiCpInterface(mosCtx); |
| |
| if (nullptr == pCpDdiInterface) |
| { |
| vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| else |
| { |
| DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex); |
| |
| DdiMedia_MediaSurfaceToMosResource(mediaSurface, &surface); |
| DdiMedia_MediaMemoryDecompressInternal(&mosCtx, &surface); |
| |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| |
| if (pCpDdiInterface) |
| { |
| Delete_DdiCpInterface(pCpDdiInterface); |
| pCpDdiInterface = NULL; |
| } |
| } |
| #else |
| vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; |
| DDI_ASSERTMESSAGE("MMC unsupported! [%d].", vaStatus); |
| #endif |
| } |
| |
| return vaStatus; |
| } |
| |
| /* |
| * Initialize the library |
| */ |
| |
| // Global mutex |
| MEDIA_MUTEX_T GlobalMutex = MEDIA_MUTEX_INITIALIZER; |
| |
| //! |
| //! \brief Initialize |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to DDI media driver context |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| static VAStatus DdiMedia_HeapInitialize( |
| PDDI_MEDIA_CONTEXT mediaCtx) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| // Heap initialization here |
| mediaCtx->pSurfaceHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr pSurfaceHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pSurfaceHeap->uiHeapElementSize = sizeof(DDI_MEDIA_SURFACE_HEAP_ELEMENT); |
| |
| mediaCtx->pBufferHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr BufferHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pBufferHeap->uiHeapElementSize = sizeof(DDI_MEDIA_BUFFER_HEAP_ELEMENT); |
| |
| mediaCtx->pImageHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pImageHeap, "nullptr ImageHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pImageHeap->uiHeapElementSize = sizeof(DDI_MEDIA_IMAGE_HEAP_ELEMENT); |
| |
| mediaCtx->pDecoderCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pDecoderCtxHeap, "nullptr DecoderCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pDecoderCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT); |
| |
| mediaCtx->pEncoderCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pEncoderCtxHeap, "nullptr EncoderCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pEncoderCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT); |
| |
| mediaCtx->pVpCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pVpCtxHeap, "nullptr VpCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pVpCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT); |
| |
| mediaCtx->pProtCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pProtCtxHeap, "nullptr pProtCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pProtCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT); |
| |
| mediaCtx->pCmCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pCmCtxHeap, "nullptr CmCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pCmCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT); |
| |
| mediaCtx->pMfeCtxHeap = (DDI_MEDIA_HEAP *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_HEAP)); |
| DDI_CHK_NULL(mediaCtx->pMfeCtxHeap, "nullptr MfeCtxHeap", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| mediaCtx->pMfeCtxHeap->uiHeapElementSize = sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT); |
| |
| // init the mutexs |
| DdiMediaUtil_InitMutex(&mediaCtx->SurfaceMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->BufferMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->ImageMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->DecoderMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->EncoderMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->VpMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->ProtMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->CmMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->MfeMutex); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Initialize |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to DDI media driver context |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| static VAStatus DdiMedia_HeapDestroy( |
| PDDI_MEDIA_CONTEXT mediaCtx) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| // destroy heaps |
| MOS_FreeMemory(mediaCtx->pSurfaceHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pSurfaceHeap); |
| |
| MOS_FreeMemory(mediaCtx->pBufferHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pBufferHeap); |
| |
| MOS_FreeMemory(mediaCtx->pImageHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pImageHeap); |
| |
| MOS_FreeMemory(mediaCtx->pDecoderCtxHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pDecoderCtxHeap); |
| |
| MOS_FreeMemory(mediaCtx->pEncoderCtxHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pEncoderCtxHeap); |
| |
| MOS_FreeMemory(mediaCtx->pVpCtxHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pVpCtxHeap); |
| |
| MOS_FreeMemory(mediaCtx->pProtCtxHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pProtCtxHeap); |
| |
| MOS_FreeMemory(mediaCtx->pCmCtxHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pCmCtxHeap); |
| |
| MOS_FreeMemory(mediaCtx->pMfeCtxHeap->pHeapBase); |
| MOS_FreeMemory(mediaCtx->pMfeCtxHeap); |
| // destroy the mutexs |
| DdiMediaUtil_DestroyMutex(&mediaCtx->SurfaceMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->BufferMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->ImageMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->DecoderMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->EncoderMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->VpMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->ProtMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->CmMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->MfeMutex); |
| |
| //resource checking |
| if (mediaCtx->uiNumSurfaces != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the surfaces."); |
| } |
| if (mediaCtx->uiNumBufs != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the buffers."); |
| } |
| if (mediaCtx->uiNumImages != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the images."); |
| } |
| if (mediaCtx->uiNumDecoders != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the decoders."); |
| } |
| if (mediaCtx->uiNumEncoders != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the encoders."); |
| } |
| if (mediaCtx->uiNumVPs != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the VPs."); |
| } |
| if (mediaCtx->uiNumProts != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the Prots."); |
| } |
| if (mediaCtx->uiNumCMs != 0) |
| { |
| DDI_ASSERTMESSAGE("APP does not destroy all the CMs."); |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Free for media context |
| //! |
| //! \param [in] mediaCtx |
| //! Pointer to ddi media context |
| //! |
| void FreeForMediaContext(PDDI_MEDIA_CONTEXT mediaCtx) |
| { |
| DdiMediaUtil_UnLockMutex(&GlobalMutex); |
| |
| if (mediaCtx) |
| { |
| mediaCtx->SkuTable.reset(); |
| mediaCtx->WaTable.reset(); |
| MOS_FreeMemory(mediaCtx->pSurfaceHeap); |
| MOS_FreeMemory(mediaCtx->pBufferHeap); |
| MOS_FreeMemory(mediaCtx->pImageHeap); |
| MOS_FreeMemory(mediaCtx->pDecoderCtxHeap); |
| MOS_FreeMemory(mediaCtx->pEncoderCtxHeap); |
| MOS_FreeMemory(mediaCtx->pVpCtxHeap); |
| MOS_FreeMemory(mediaCtx->pProtCtxHeap); |
| MOS_FreeMemory(mediaCtx->pMfeCtxHeap); |
| MOS_FreeMemory(mediaCtx); |
| } |
| |
| return; |
| } |
| |
| void DestroyMediaContextMutex(PDDI_MEDIA_CONTEXT mediaCtx) |
| { |
| // destroy the mutexs |
| DdiMediaUtil_DestroyMutex(&mediaCtx->SurfaceMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->BufferMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->ImageMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->DecoderMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->EncoderMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->VpMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->CmMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->MfeMutex); |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceRenderMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceSwapBufferMutex); |
| #endif |
| return; |
| } |
| |
| //! |
| //! \brief Initialize |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [out] major_version |
| //! Major version |
| //! \param [out] minor_version |
| //! Minor version |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia__Initialize ( |
| VADriverContextP ctx, |
| int32_t *major_version, /* out */ |
| int32_t *minor_version /* out */ |
| ) |
| { |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| // ATRACE code in <cutils/trace.h> started from KitKat, version = 440 |
| // ENABLE_TRACE is defined only for eng build so release build won't leak perf data |
| // thus trace code enabled only on KitKat (and newer) && eng build |
| #if ANDROID_VERSION > 439 && defined(ENABLE_ATRACE) |
| char switch_value[PROPERTY_VALUE_MAX]; |
| |
| property_get("debug.DdiCodec_.umd", switch_value, "0"); |
| atrace_switch = atoi(switch_value); |
| #endif |
| #endif |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| struct drm_state *pDRMState = (struct drm_state *)ctx->drm_state; |
| DDI_CHK_NULL(pDRMState, "nullptr pDRMState", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| // If libva failes to open the graphics card, try to open it again within Media Driver |
| if(pDRMState->fd < 0 || pDRMState->fd == 0 ) |
| { |
| DDI_ASSERTMESSAGE("DDI:LIBVA Wrapper doesn't pass file descriptor for graphics adaptor, trying to open the graphics... "); |
| pDRMState->fd = DdiMediaUtil_OpenGraphicsAdaptor((char *)DEVICE_NAME); |
| if (pDRMState->fd < 0) { |
| DDI_ASSERTMESSAGE("DDI: Still failed to open the graphic adaptor, return failure"); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| } |
| int32_t devicefd = pDRMState->fd; |
| |
| if(major_version) |
| { |
| *major_version = VA_MAJOR_VERSION; |
| } |
| |
| if(minor_version) |
| { |
| *minor_version = VA_MINOR_VERSION; |
| } |
| |
| DdiMediaUtil_LockMutex(&GlobalMutex); |
| // media context is already created, return directly to support multiple entry |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| if(mediaCtx) |
| { |
| mediaCtx->uiRef++; |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| mediaCtx = DdiMedia_CreateMediaDriverContext(); |
| if (nullptr == mediaCtx) |
| { |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| mediaCtx->uiRef++; |
| ctx->pDriverData = (void *)mediaCtx; |
| mediaCtx->fd = devicefd; |
| |
| mediaCtx->m_apoMosEnabled = SetupApoMosSwitch(devicefd); |
| |
| mediaCtx->cpLibWasLoaded = CPLibUtils::LoadCPLib(ctx); |
| if (!mediaCtx->cpLibWasLoaded) |
| { |
| DDI_NORMALMESSAGE("CPLIB is not loaded."); |
| } |
| |
| #ifdef _MMC_SUPPORTED |
| mediaCtx->pfnMemoryDecompress = DdiMedia_MediaMemoryDecompressInternal; |
| mediaCtx->pfnMediaMemoryCopy = DdiMedia_MediaMemoryCopyInternal; |
| mediaCtx->pfnMediaMemoryCopy2D = DdiMedia_MediaMemoryCopy2DInternal; |
| mediaCtx->pfnMediaMemoryTileConvert = DdiMedia_MediaMemoryTileConvertInternal; |
| #endif |
| mediaCtx->modularizedGpuCtxEnabled = true; |
| |
| if (mediaCtx->m_apoMosEnabled) |
| { |
| MOS_CONTEXT mosCtx = {}; |
| mosCtx.fd = mediaCtx->fd; |
| mosCtx.m_apoMosEnabled = mediaCtx->m_apoMosEnabled; |
| |
| MosInterface::InitOsUtilities(&mosCtx); |
| |
| mediaCtx->pGtSystemInfo = (MEDIA_SYSTEM_INFO *)MOS_AllocAndZeroMemory(sizeof(MEDIA_SYSTEM_INFO)); |
| if (nullptr == mediaCtx->pGtSystemInfo) |
| { |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| if (MosInterface::CreateOsDeviceContext(&mosCtx, &mediaCtx->m_osDeviceContext) != MOS_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Unable to create MOS device context."); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| mediaCtx->pDrmBufMgr = mosCtx.bufmgr; |
| mediaCtx->iDeviceId = mosCtx.iDeviceId; |
| mediaCtx->SkuTable = mosCtx.SkuTable; |
| mediaCtx->WaTable = mosCtx.WaTable; |
| *mediaCtx->pGtSystemInfo = mosCtx.gtSystemInfo; |
| mediaCtx->platform = mosCtx.platform; |
| mediaCtx->m_auxTableMgr = mosCtx.m_auxTableMgr; |
| mediaCtx->pGmmClientContext = mosCtx.pGmmClientContext; |
| mediaCtx->m_useSwSwizzling = mosCtx.bUseSwSwizzling; |
| mediaCtx->m_tileYFlag = mosCtx.bTileYFlag; |
| mediaCtx->bIsAtomSOC = mosCtx.bIsAtomSOC; |
| #ifdef _MMC_SUPPORTED |
| if (mosCtx.ppMediaMemDecompState == nullptr) |
| { |
| DDI_ASSERTMESSAGE("media decomp state is null."); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| mediaCtx->pMediaMemDecompState = *mosCtx.ppMediaMemDecompState; |
| #endif |
| mediaCtx->pMediaCopyState = *mosCtx.ppMediaCopyState; |
| } |
| else if (mediaCtx->modularizedGpuCtxEnabled) |
| { |
| // prepare m_osContext |
| MosUtilities::MosUtilitiesInit(nullptr); |
| //Read user feature key here for Per Utility Tool Enabling |
| |
| if (!g_perfutility->bPerfUtilityKey) |
| { |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_PERF_UTILITY_TOOL_ENABLE_ID, |
| &UserFeatureData, |
| nullptr); |
| g_perfutility->dwPerfUtilityIsEnabled = UserFeatureData.i32Data; |
| |
| char sFilePath[MOS_MAX_PERF_FILENAME_LEN + 1] = ""; |
| MOS_USER_FEATURE_VALUE_DATA perfFilePath; |
| MOS_STATUS eStatus_Perf = MOS_STATUS_SUCCESS; |
| |
| MOS_ZeroMemory(&perfFilePath, sizeof(perfFilePath)); |
| perfFilePath.StringData.pStringData = sFilePath; |
| eStatus_Perf = MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_PERF_OUTPUT_DIRECTORY_ID, |
| &perfFilePath, |
| nullptr); |
| if (eStatus_Perf == MOS_STATUS_SUCCESS) |
| { |
| g_perfutility->setupFilePath(sFilePath); |
| } |
| else |
| { |
| g_perfutility->setupFilePath(); |
| } |
| |
| g_perfutility->bPerfUtilityKey = true; |
| } |
| |
| mediaCtx->pDrmBufMgr = mos_bufmgr_gem_init(mediaCtx->fd, DDI_CODEC_BATCH_BUFFER_SIZE); |
| if (nullptr == mediaCtx->pDrmBufMgr) |
| { |
| DDI_ASSERTMESSAGE("DDI:No able to allocate buffer manager, fd=0x%d", mediaCtx->fd); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| mos_bufmgr_gem_enable_reuse(mediaCtx->pDrmBufMgr); |
| |
| //Latency reducation:replace HWGetDeviceID to get device using ioctl from drm. |
| mediaCtx->iDeviceId = mos_bufmgr_gem_get_devid(mediaCtx->pDrmBufMgr); |
| |
| //TO--DO, apo set it to FALSE by default, to remove the logic in apo mos controlled by it???? |
| mediaCtx->bIsAtomSOC = IS_ATOMSOC(mediaCtx->iDeviceId); |
| |
| MEDIA_FEATURE_TABLE *skuTable = &mediaCtx->SkuTable; |
| MEDIA_WA_TABLE * waTable = &mediaCtx->WaTable; |
| skuTable->reset(); |
| waTable->reset(); |
| // get Sku/Wa tables and platform information |
| PLATFORM platform = {}; |
| // Allocate memory for Media System Info |
| mediaCtx->pGtSystemInfo = (MEDIA_SYSTEM_INFO *)MOS_AllocAndZeroMemory(sizeof(MEDIA_SYSTEM_INFO)); |
| if (nullptr == mediaCtx->pGtSystemInfo) |
| { |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| MOS_STATUS eStatus = HWInfo_GetGfxInfo(mediaCtx->fd, mediaCtx->pDrmBufMgr, &platform, skuTable, waTable, mediaCtx->pGtSystemInfo); |
| if (MOS_STATUS_SUCCESS != eStatus) |
| { |
| DDI_ASSERTMESSAGE("Fatal error - unsuccesfull Sku/Wa/GtSystemInfo initialization"); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| mediaCtx->platform = platform; |
| |
| MOS_TraceSetupInfo( |
| (VA_MAJOR_VERSION << 16) | VA_MINOR_VERSION, |
| platform.eProductFamily, |
| platform.eRenderCoreFamily, |
| (platform.usRevId << 16) | platform.usDeviceID); |
| |
| //TO--DO, gen12+ still need this wa????, not porting yet |
| if (MEDIA_IS_SKU(skuTable, FtrEnableMediaKernels) == 0) |
| { |
| MEDIA_WR_WA(waTable, WaHucStreamoutOnlyDisable, 0); |
| } |
| MediaUserSettingsMgr::MediaUserSettingsInit(platform.eProductFamily); |
| |
| GMM_SKU_FEATURE_TABLE gmmSkuTable; |
| memset(&gmmSkuTable, 0, sizeof(gmmSkuTable)); |
| |
| GMM_WA_TABLE gmmWaTable; |
| memset(&gmmWaTable, 0, sizeof(gmmWaTable)); |
| |
| GMM_GT_SYSTEM_INFO gmmGtInfo; |
| memset(&gmmGtInfo, 0, sizeof(gmmGtInfo)); |
| |
| eStatus = HWInfo_GetGmmInfo(mediaCtx->fd, &gmmSkuTable, &gmmWaTable, &gmmGtInfo); |
| if (MOS_STATUS_SUCCESS != eStatus) |
| { |
| DDI_ASSERTMESSAGE("Fatal error - unsuccesfull Gmm Sku/Wa/GtSystemInfo initialization"); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| eStatus = Mos_Solo_DdiInitializeDeviceId( |
| (void *)mediaCtx->pDrmBufMgr, |
| &mediaCtx->SkuTable, |
| &mediaCtx->WaTable, |
| &gmmSkuTable, |
| &gmmWaTable, |
| &gmmGtInfo, |
| &mediaCtx->iDeviceId, |
| &mediaCtx->fd, |
| &mediaCtx->platform); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| GMM_STATUS gmmStatus = OpenGmm(&mediaCtx->GmmFuncs); |
| if (gmmStatus != GMM_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("gmm init failed."); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| // init GMM context |
| gmmStatus = mediaCtx->GmmFuncs.pfnCreateSingletonContext(mediaCtx->platform, |
| &gmmSkuTable, |
| &gmmWaTable, |
| &gmmGtInfo); |
| |
| if (gmmStatus != GMM_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("gmm init failed."); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| // Create GMM Client Context |
| mediaCtx->pGmmClientContext = mediaCtx->GmmFuncs.pfnCreateClientContext((GMM_CLIENT)GMM_LIBVA_LINUX); |
| |
| // Create GMM page table manager |
| mediaCtx->m_auxTableMgr = AuxTableMgr::CreateAuxTableMgr(mediaCtx->pDrmBufMgr, &mediaCtx->SkuTable); |
| |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_SIM_ENABLE_ID, |
| &UserFeatureData, |
| nullptr); |
| #endif |
| |
| mediaCtx->m_useSwSwizzling = UserFeatureData.i32Data || MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrUseSwSwizzling); |
| mediaCtx->m_tileYFlag = MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrTileY); |
| |
| mediaCtx->m_osContext = OsContext::GetOsContextObject(); |
| if (mediaCtx->m_osContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to get the active OS context."); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| // fill in the mos context struct as input to initialize m_osContext |
| MOS_CONTEXT mosCtx = {}; |
| mosCtx.bufmgr = mediaCtx->pDrmBufMgr; |
| mosCtx.fd = mediaCtx->fd; |
| mosCtx.iDeviceId = mediaCtx->iDeviceId; |
| mosCtx.SkuTable = mediaCtx->SkuTable; |
| mosCtx.WaTable = mediaCtx->WaTable; |
| mosCtx.gtSystemInfo = *mediaCtx->pGtSystemInfo; |
| mosCtx.platform = mediaCtx->platform; |
| mosCtx.ppMediaMemDecompState = &mediaCtx->pMediaMemDecompState; |
| mosCtx.pfnMemoryDecompress = mediaCtx->pfnMemoryDecompress; |
| mosCtx.pfnMediaMemoryCopy = mediaCtx->pfnMediaMemoryCopy; |
| mosCtx.pfnMediaMemoryCopy2D = mediaCtx->pfnMediaMemoryCopy2D; |
| mosCtx.ppMediaCopyState = &mediaCtx->pMediaCopyState; |
| mosCtx.m_auxTableMgr = mediaCtx->m_auxTableMgr; |
| mosCtx.pGmmClientContext = mediaCtx->pGmmClientContext; |
| |
| eStatus = mediaCtx->m_osContext->Init(&mosCtx); |
| if (MOS_STATUS_SUCCESS != eStatus) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to initialize OS context."); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| // Prepare the command buffer manager |
| mediaCtx->m_cmdBufMgr = CmdBufMgr::GetObject(); |
| if (mediaCtx->m_cmdBufMgr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE(" nullptr returned by CmdBufMgr::GetObject"); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| MOS_STATUS ret = mediaCtx->m_cmdBufMgr->Initialize(mediaCtx->m_osContext, COMMAND_BUFFER_SIZE/2); |
| if (ret != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE(" cmdBufMgr Initialization failed"); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| // Prepare the gpu Context manager |
| mediaCtx->m_gpuContextMgr = GpuContextMgr::GetObject(mediaCtx->pGtSystemInfo, mediaCtx->m_osContext); |
| if (mediaCtx->m_gpuContextMgr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE(" nullptr returned by GpuContextMgr::GetObject"); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE(" Invalid mos module state"); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| if (DdiMedia_HeapInitialize(mediaCtx) != VA_STATUS_SUCCESS) |
| { |
| DestroyMediaContextMutex(mediaCtx); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| //Caps need platform and sku table, especially in MediaLibvaCapsCp::IsDecEncryptionSupported |
| mediaCtx->m_caps = MediaLibvaCaps::CreateMediaLibvaCaps(mediaCtx); |
| if (!mediaCtx->m_caps) |
| { |
| DDI_ASSERTMESSAGE("Caps create failed. Not supported GFX device."); |
| DestroyMediaContextMutex(mediaCtx); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| if (mediaCtx->m_caps->Init() != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Caps init failed. Not supported GFX device."); |
| MOS_Delete(mediaCtx->m_caps); |
| mediaCtx->m_caps = nullptr; |
| DestroyMediaContextMutex(mediaCtx); |
| FreeForMediaContext(mediaCtx); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| ctx->max_image_formats = mediaCtx->m_caps->GetImageFormatsMaxNum(); |
| |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| DdiMediaUtil_InitMutex(&mediaCtx->PutSurfaceRenderMutex); |
| DdiMediaUtil_InitMutex(&mediaCtx->PutSurfaceSwapBufferMutex); |
| |
| // try to open X11 lib, if fail, assume no X11 environment |
| if (VA_STATUS_SUCCESS != DdiMedia_ConnectX11(mediaCtx)) |
| { |
| // assume no X11 environment. In current implementation, |
| // PutSurface (Linux) needs X11 support, so just replace |
| // it with a dummy version. DdiCodec_PutSurfaceDummy() will |
| // return VA_STATUS_ERROR_UNIMPLEMENTED directly. |
| ctx->vtable->vaPutSurface = NULL; |
| } |
| output_dri_init(ctx); |
| #endif |
| |
| if (VA_STATUS_SUCCESS != DdiMediaUtil_SetMediaResetEnableFlag(mediaCtx)) |
| { |
| mediaCtx->bMediaResetEnable = false; |
| } |
| |
| DdiMediaUtil_UnLockMutex(&GlobalMutex); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /* |
| * After this call, all library internal resources will be cleaned up |
| */ |
| static VAStatus DdiMedia_Terminate ( |
| VADriverContextP ctx |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DdiMediaUtil_LockMutex(&GlobalMutex); |
| |
| #if !defined(ANDROID) && defined(X11_FOUND) |
| DdiMedia_DestroyX11Connection(mediaCtx); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceRenderMutex); |
| DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceSwapBufferMutex); |
| |
| if (mediaCtx->m_caps) |
| { |
| if (mediaCtx->dri_output != nullptr) { |
| if (mediaCtx->dri_output->handle) |
| dso_close(mediaCtx->dri_output->handle); |
| |
| free(mediaCtx->dri_output); |
| mediaCtx->dri_output = nullptr; |
| } |
| } |
| #endif |
| |
| if (mediaCtx->m_caps) |
| { |
| MOS_Delete(mediaCtx->m_caps); |
| mediaCtx->m_caps = nullptr; |
| } |
| //destory resources |
| DdiMedia_FreeSurfaceHeapElements(mediaCtx); |
| DdiMedia_FreeBufferHeapElements(ctx); |
| DdiMedia_FreeImageHeapElements(ctx); |
| DdiMedia_FreeContextHeapElements(ctx); |
| DdiMedia_FreeContextCMElements(ctx); |
| |
| DdiMedia_HeapDestroy(mediaCtx); |
| DdiMediaProtected::FreeInstances(); |
| |
| if (mediaCtx->m_apoMosEnabled) |
| { |
| MosInterface::DestroyOsDeviceContext(mediaCtx->m_osDeviceContext); |
| mediaCtx->m_osDeviceContext = MOS_INVALID_HANDLE; |
| MOS_FreeMemory(mediaCtx->pGtSystemInfo); |
| MosInterface::CloseOsUtilities(nullptr); |
| } |
| else if (mediaCtx->modularizedGpuCtxEnabled) |
| { |
| if (mediaCtx->m_auxTableMgr != nullptr) |
| { |
| MOS_Delete(mediaCtx->m_auxTableMgr); |
| mediaCtx->m_auxTableMgr = nullptr; |
| } |
| |
| if (mediaCtx->m_gpuContextMgr) |
| { |
| mediaCtx->m_gpuContextMgr->CleanUp(); |
| MOS_Delete(mediaCtx->m_gpuContextMgr); |
| } |
| |
| if (mediaCtx->m_cmdBufMgr) |
| { |
| mediaCtx->m_cmdBufMgr->CleanUp(); |
| MOS_Delete(mediaCtx->m_cmdBufMgr); |
| } |
| |
| if (mediaCtx->m_osContext) |
| { |
| mediaCtx->m_osContext->CleanUp(); |
| MOS_Delete(mediaCtx->m_osContext); |
| } |
| |
| // destroy libdrm buffer manager |
| mos_bufmgr_destroy(mediaCtx->pDrmBufMgr); |
| |
| // Destroy memory allocated to store Media System Info |
| MOS_FreeMemory(mediaCtx->pGtSystemInfo); |
| // Free GMM memory. |
| mediaCtx->GmmFuncs.pfnDeleteClientContext(mediaCtx->pGmmClientContext); |
| mediaCtx->GmmFuncs.pfnDestroySingletonContext(); |
| MosUtilities::MosUtilitiesClose(nullptr); |
| } |
| |
| if (mediaCtx->uiRef > 1) |
| { |
| mediaCtx->uiRef--; |
| DdiMediaUtil_UnLockMutex(&GlobalMutex); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| mediaCtx->SkuTable.reset(); |
| mediaCtx->WaTable.reset(); |
| |
| if (mediaCtx->cpLibWasLoaded) |
| { |
| CPLibUtils::UnloadCPLib(ctx); |
| } |
| |
| // release media driver context, ctx creation is behind the mos_utilities_init |
| // If free earilier than MOS_utilities_close, memnja count error. |
| MOS_FreeMemory(mediaCtx); |
| mediaCtx = nullptr; |
| ctx->pDriverData = nullptr; |
| |
| DdiMediaUtil_UnLockMutex(&GlobalMutex); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /* |
| * Query supported entrypoints for a given profile |
| * The caller must provide an "entrypoint_list" array that can hold at |
| * least vaMaxNumEntrypoints() entries. The actual number of entrypoints |
| * returned in "entrypoint_list" is returned in "num_entrypoints". |
| */ |
| static VAStatus DdiMedia_QueryConfigEntrypoints( |
| VADriverContextP ctx, |
| VAProfile profile, |
| VAEntrypoint *entrypoint_list, |
| int32_t *num_entrypoints |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PERF_UTILITY_START_ONCE("First Frame Time", PERF_MOS, PERF_LEVEL_DDI); |
| |
| DDI_CHK_NULL(ctx, "nullptr Ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(entrypoint_list, "nullptr entrypoint_list", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(num_entrypoints, "nullptr num_entrypoints", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| return mediaCtx->m_caps->QueryConfigEntrypoints(profile, |
| entrypoint_list, num_entrypoints); |
| } |
| |
| /* |
| * Query supported profiles |
| * The caller must provide a "profile_list" array that can hold at |
| * least vaMaxNumProfile() entries. The actual number of profiles |
| * returned in "profile_list" is returned in "num_profile". |
| */ |
| static VAStatus DdiMedia_QueryConfigProfiles ( |
| VADriverContextP ctx, |
| VAProfile *profile_list, |
| int32_t *num_profiles |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr Ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(profile_list, "nullptr profile_list", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(num_profiles, "nullptr num_profiles", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| return mediaCtx->m_caps->QueryConfigProfiles(profile_list, num_profiles); |
| } |
| |
| /* |
| * Query all attributes for a given configuration |
| * The profile of the configuration is returned in "profile" |
| * The entrypoint of the configuration is returned in "entrypoint" |
| * The caller must provide an "attrib_list" array that can hold at least |
| * vaMaxNumConfigAttributes() entries. The actual number of attributes |
| * returned in "attrib_list" is returned in "num_attribs" |
| */ |
| static VAStatus DdiMedia_QueryConfigAttributes ( |
| VADriverContextP ctx, |
| VAConfigID config_id, |
| VAProfile *profile, |
| VAEntrypoint *entrypoint, |
| VAConfigAttrib *attrib_list, |
| int32_t *num_attribs |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(profile, "nullptr profile", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(entrypoint, "nullptr entrypoint", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(ctx, "nullptr Ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(num_attribs, "nullptr num_attribs", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| return mediaCtx->m_caps->QueryConfigAttributes( |
| config_id, profile, entrypoint, attrib_list, num_attribs); |
| } |
| |
| /* |
| * Create a configuration for the encode/decode/vp pipeline |
| * it passes in the attribute list that specifies the attributes it cares |
| * about, with the rest taking default values. |
| */ |
| static VAStatus DdiMedia_CreateConfig ( |
| VADriverContextP ctx, |
| VAProfile profile, |
| VAEntrypoint entrypoint, |
| VAConfigAttrib *attrib_list, |
| int32_t num_attribs, |
| VAConfigID *config_id |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(config_id, "nullptr config_id", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| return mediaCtx->m_caps->CreateConfig( |
| profile, entrypoint, attrib_list, num_attribs, config_id); |
| } |
| |
| /* |
| * Free resources associated with a given config |
| */ |
| static VAStatus DdiMedia_DestroyConfig ( |
| VADriverContextP ctx, |
| VAConfigID config_id |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| return mediaCtx->m_caps->DestroyConfig(config_id); |
| } |
| |
| /* |
| * Get attributes for a given profile/entrypoint pair |
| * The caller must provide an "attrib_list" with all attributes to be |
| * retrieved. Upon return, the attributes in "attrib_list" have been |
| * updated with their value. Unknown attributes or attributes that are |
| * not supported for the given profile/entrypoint pair will have their |
| * value set to VA_ATTRIB_NOT_SUPPORTED |
| */ |
| static VAStatus DdiMedia_GetConfigAttributes( |
| VADriverContextP ctx, |
| VAProfile profile, |
| VAEntrypoint entrypoint, |
| VAConfigAttrib *attrib_list, |
| int32_t num_attribs |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| return mediaCtx->m_caps->GetConfigAttributes( |
| profile, entrypoint, attrib_list, num_attribs); |
| } |
| |
| static VAStatus DdiMedia_CreateSurfaces ( |
| VADriverContextP ctx, |
| int32_t width, |
| int32_t height, |
| int32_t format, |
| int32_t num_surfaces, |
| VASurfaceID *surfaces |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| int32_t event[] = {width, height, format}; |
| MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LARGER(num_surfaces, 0, "Invalid num_surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(surfaces, "nullptr surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(width, 0, "Invalid width", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(height, 0, "Invalid height", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaDrvCtx, "nullptr mediaDrvCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if( format != VA_RT_FORMAT_YUV420 || |
| format != VA_RT_FORMAT_YUV422 || |
| format != VA_RT_FORMAT_YUV444 || |
| format != VA_RT_FORMAT_YUV400 || |
| format != VA_RT_FORMAT_YUV411) |
| { |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| |
| DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(VA_FOURCC_NV12,format); |
| |
| height = MOS_ALIGN_CEIL(height, 16); |
| for(int32_t i = 0; i < num_surfaces; i++) |
| { |
| VASurfaceID vaSurfaceID = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaDrvCtx, mediaFmt, width, height, nullptr, VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC, MOS_MEMPOOL_VIDEOMEMORY); |
| if (VA_INVALID_ID != vaSurfaceID) |
| surfaces[i] = vaSurfaceID; |
| else |
| { |
| // here to release the successful allocated surfaces? |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_END, &num_surfaces, sizeof(int32_t), surfaces, num_surfaces*sizeof(VAGenericID)); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /* |
| * vaDestroySurfaces - Destroy resources associated with surfaces. |
| * Surfaces can only be destroyed after the context associated has been |
| * destroyed. |
| * dpy: display |
| * surfaces: array of surfaces to destroy |
| * num_surfaces: number of surfaces in the array to be destroyed. |
| */ |
| static VAStatus DdiMedia_DestroySurfaces ( |
| VADriverContextP ctx, |
| VASurfaceID *surfaces, |
| int32_t num_surfaces |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL (ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LARGER(num_surfaces, 0, "Invalid num_surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL (surfaces, "nullptr surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| MOS_TraceEventExt(EVENT_VA_FREE_SURFACE, EVENT_TYPE_START, &num_surfaces, sizeof(int32_t), surfaces, num_surfaces*sizeof(VAGenericID)); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL (mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL (mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_SURFACE surface = nullptr; |
| for(int32_t i = 0; i < num_surfaces; i++) |
| { |
| DDI_CHK_LESS((uint32_t)surfaces[i], mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE); |
| surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surfaces[i]); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| if(surface->pCurrentFrameSemaphore) |
| { |
| DdiMediaUtil_WaitSemaphore(surface->pCurrentFrameSemaphore); |
| DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore); |
| } |
| if(surface->pReferenceFrameSemaphore) |
| { |
| DdiMediaUtil_WaitSemaphore(surface->pReferenceFrameSemaphore); |
| DdiMediaUtil_PostSemaphore(surface->pReferenceFrameSemaphore); |
| } |
| } |
| |
| for(int32_t i = 0; i < num_surfaces; i++) |
| { |
| DDI_CHK_LESS((uint32_t)surfaces[i], mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE); |
| surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surfaces[i]); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| if(surface->pCurrentFrameSemaphore) |
| { |
| DdiMediaUtil_DestroySemaphore(surface->pCurrentFrameSemaphore); |
| surface->pCurrentFrameSemaphore = nullptr; |
| } |
| |
| if(surface->pReferenceFrameSemaphore) |
| { |
| DdiMediaUtil_DestroySemaphore(surface->pReferenceFrameSemaphore); |
| surface->pReferenceFrameSemaphore = nullptr; |
| } |
| |
| DdiMediaUtil_UnRegisterRTSurfaces(ctx, surface); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex); |
| DdiMediaUtil_FreeSurface(surface); |
| MOS_FreeMemory(surface); |
| DdiMediaUtil_ReleasePMediaSurfaceFromHeap(mediaCtx->pSurfaceHeap, (uint32_t)surfaces[i]); |
| mediaCtx->uiNumSurfaces--; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_FREE_SURFACE, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus |
| DdiMedia_CreateSurfaces2( |
| VADriverContextP ctx, |
| uint32_t format, |
| uint32_t width, |
| uint32_t height, |
| VASurfaceID *surfaces, |
| uint32_t num_surfaces, |
| VASurfaceAttrib *attrib_list, |
| uint32_t num_attribs |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| uint32_t event[] = {width, height, format}; |
| MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0); |
| |
| DDI_CHK_NULL (ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LARGER(num_surfaces, 0, "Invalid num_surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL (surfaces, "nullptr surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(width, 0, "Invalid width", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(height, 0, "Invalid height", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| if(num_attribs > 0) |
| { |
| DDI_CHK_NULL(attrib_list, "nullptr attrib_list", VA_STATUS_ERROR_INVALID_PARAMETER); |
| } |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| int32_t expected_fourcc = VA_FOURCC_NV12; |
| switch(format) |
| { |
| case VA_RT_FORMAT_YUV420: |
| expected_fourcc = VA_FOURCC_NV12; |
| break; |
| case VA_RT_FORMAT_YUV420_12: |
| expected_fourcc = VA_FOURCC_P012; |
| break; |
| case VA_RT_FORMAT_YUV422: |
| expected_fourcc = VA_FOURCC_YUY2; |
| break; |
| case VA_RT_FORMAT_YUV422_10: |
| expected_fourcc = VA_FOURCC_Y210; |
| break; |
| case VA_RT_FORMAT_YUV422_12: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| expected_fourcc = VA_FOURCC_Y212; |
| #else |
| expected_fourcc = VA_FOURCC_Y216; |
| #endif |
| break; |
| case VA_RT_FORMAT_YUV444: |
| expected_fourcc = VA_FOURCC_444P; |
| break; |
| case VA_RT_FORMAT_YUV444_10: |
| expected_fourcc = VA_FOURCC_Y410; |
| break; |
| case VA_RT_FORMAT_YUV444_12: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| expected_fourcc = VA_FOURCC_Y412; |
| #else |
| expected_fourcc = VA_FOURCC_Y416; |
| #endif |
| break; |
| case VA_RT_FORMAT_YUV411: |
| expected_fourcc = VA_FOURCC_411P; |
| break; |
| case VA_RT_FORMAT_YUV400: |
| expected_fourcc = VA_FOURCC('4','0','0','P'); |
| break; |
| case VA_RT_FORMAT_YUV420_10BPP: |
| expected_fourcc = VA_FOURCC_P010; |
| break; |
| case VA_RT_FORMAT_RGB16: |
| expected_fourcc = VA_FOURCC_R5G6B5; |
| break; |
| case VA_RT_FORMAT_RGB32: |
| expected_fourcc = VA_FOURCC_BGRA; |
| break; |
| case VA_RT_FORMAT_RGBP: |
| expected_fourcc = VA_FOURCC_RGBP; |
| break; |
| #ifdef VA_RT_FORMAT_RGB32_10BPP |
| case VA_RT_FORMAT_RGB32_10BPP: |
| expected_fourcc = VA_FOURCC_BGRA; |
| break; |
| #endif |
| #if 1 //added for having MDF sanity test pass, will be removed after MDF formal patch checked in |
| case VA_FOURCC_NV12: |
| expected_fourcc = VA_FOURCC_NV12; |
| break; |
| case VA_FOURCC_NV21: |
| expected_fourcc = VA_FOURCC_NV21; |
| break; |
| case VA_FOURCC_ABGR: |
| expected_fourcc = VA_FOURCC_ABGR; |
| break; |
| case VA_FOURCC_ARGB: |
| expected_fourcc = VA_FOURCC_ARGB; |
| break; |
| case VA_FOURCC_XBGR: |
| expected_fourcc = VA_FOURCC_XBGR; |
| break; |
| case VA_FOURCC_XRGB: |
| expected_fourcc = VA_FOURCC_XRGB; |
| break; |
| case VA_FOURCC_R5G6B5: |
| expected_fourcc = VA_FOURCC_R5G6B5; |
| break; |
| case VA_FOURCC_R8G8B8: |
| expected_fourcc = VA_FOURCC_R8G8B8; |
| break; |
| case VA_FOURCC_YUY2: |
| expected_fourcc = VA_FOURCC_YUY2; |
| break; |
| case VA_FOURCC_YV12: |
| expected_fourcc = VA_FOURCC_YV12; |
| break; |
| case VA_FOURCC_422H: |
| expected_fourcc = VA_FOURCC_422H; |
| break; |
| case VA_FOURCC_422V: |
| expected_fourcc = VA_FOURCC_422V; |
| break; |
| case VA_FOURCC_P208: |
| expected_fourcc = VA_FOURCC_P208; |
| break; |
| case VA_FOURCC_P010: |
| expected_fourcc = VA_FOURCC_P010; |
| break; |
| case VA_FOURCC_P012: |
| expected_fourcc = VA_FOURCC_P012; |
| break; |
| case VA_FOURCC_P016: |
| expected_fourcc = VA_FOURCC_P016; |
| break; |
| case VA_FOURCC_Y210: |
| expected_fourcc = VA_FOURCC_Y210; |
| break; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212: |
| expected_fourcc = VA_FOURCC_Y212; |
| break; |
| #endif |
| case VA_FOURCC_Y216: |
| expected_fourcc = VA_FOURCC_Y216; |
| break; |
| case VA_FOURCC_AYUV: |
| expected_fourcc = VA_FOURCC_AYUV; |
| break; |
| case VA_FOURCC_Y410: |
| expected_fourcc = VA_FOURCC_Y410; |
| break; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y412: |
| expected_fourcc = VA_FOURCC_Y412; |
| break; |
| #endif |
| case VA_FOURCC_Y416: |
| expected_fourcc = VA_FOURCC_Y416; |
| break; |
| case VA_FOURCC_I420: |
| expected_fourcc = VA_FOURCC_I420; |
| break; |
| #endif |
| default: |
| DDI_ASSERTMESSAGE("Invalid VAConfigAttribRTFormat: 0x%x. Please uses the format defined in libva/va.h", format); |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| |
| VASurfaceAttribExternalBuffers externalBufDescripor; |
| VADRMPRIMESurfaceDescriptor drmPrimeSurfaceDescriptor; |
| MOS_ZeroMemory(&externalBufDescripor, sizeof(VASurfaceAttribExternalBuffers)); |
| MOS_ZeroMemory(&drmPrimeSurfaceDescriptor, sizeof(VADRMPRIMESurfaceDescriptor)); |
| |
| int32_t memTypeFlag = VA_SURFACE_ATTRIB_MEM_TYPE_VA; |
| int32_t descFlag = 0; |
| uint32_t surfaceUsageHint = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC; |
| bool surfDescProvided = false; |
| bool surfIsUserPtr = false; |
| |
| for (uint32_t i = 0; i < num_attribs && attrib_list; i++) |
| { |
| if (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE) |
| { |
| switch (attrib_list[i].type) |
| { |
| case VASurfaceAttribUsageHint: |
| DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypeInteger); |
| surfaceUsageHint = attrib_list[i].value.value.i; |
| break; |
| case VASurfaceAttribPixelFormat: |
| DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypeInteger); |
| expected_fourcc = attrib_list[i].value.value.i; |
| break; |
| case VASurfaceAttribMemoryType: |
| DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypeInteger); |
| if ((attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA) || |
| (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM) || |
| (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME) || |
| (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) || |
| (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)) |
| { |
| memTypeFlag = attrib_list[i].value.value.i; |
| surfIsUserPtr = (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("Not supported external buffer type."); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| break; |
| case (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor: |
| DDI_ASSERT(attrib_list[i].value.type == VAGenericValueTypePointer); |
| if( nullptr == attrib_list[i].value.value.p ) |
| { |
| DDI_ASSERTMESSAGE("Invalid VASurfaceAttribExternalBuffers used."); |
| //remove the check for libva-utils conformance test, need libva-utils change cases |
| //after libva-utils fix the case, return VA_STATUS_ERROR_INVALID_PARAMETER; |
| break; |
| } |
| surfDescProvided = true; |
| if (memTypeFlag == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) |
| { |
| MOS_SecureMemcpy(&drmPrimeSurfaceDescriptor, sizeof(VADRMPRIMESurfaceDescriptor), attrib_list[i].value.value.p, sizeof(VADRMPRIMESurfaceDescriptor)); |
| expected_fourcc = drmPrimeSurfaceDescriptor.fourcc; |
| width = drmPrimeSurfaceDescriptor.width; |
| height = drmPrimeSurfaceDescriptor.height; |
| } |
| else |
| { |
| MOS_SecureMemcpy(&externalBufDescripor, sizeof(VASurfaceAttribExternalBuffers), attrib_list[i].value.value.p, sizeof(VASurfaceAttribExternalBuffers)); |
| |
| expected_fourcc = externalBufDescripor.pixel_format; |
| width = externalBufDescripor.width; |
| height = externalBufDescripor.height; |
| // the following code is for backward compatible and it will be removed in the future |
| // new implemention should use VASurfaceAttribMemoryType attrib and set its value to VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
| if ((externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM )|| |
| (externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)|| |
| (externalBufDescripor.flags & VA_SURFACE_EXTBUF_DESC_PROTECTED)|| |
| (externalBufDescripor.flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING)) |
| { |
| if (externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM) |
| { |
| memTypeFlag = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; |
| } |
| else if (externalBufDescripor.flags & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME) |
| { |
| memTypeFlag = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; |
| } |
| |
| descFlag = (externalBufDescripor.flags & ~(VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM | VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)); |
| surfIsUserPtr = false; |
| } |
| } |
| |
| break; |
| default: |
| DDI_ASSERTMESSAGE("Unsupported type."); |
| break; |
| } |
| } |
| } |
| |
| DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(expected_fourcc,format); |
| if (mediaFmt == Media_Format_Count) |
| { |
| DDI_ASSERTMESSAGE("DDI: unsupported surface type in DdiMedia_CreateSurfaces2."); |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| |
| for (uint32_t i = 0; i < num_surfaces; i++) |
| { |
| PDDI_MEDIA_SURFACE_DESCRIPTOR surfDesc = nullptr; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (surfDescProvided == true) |
| { |
| surfDesc = (PDDI_MEDIA_SURFACE_DESCRIPTOR)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE_DESCRIPTOR)); |
| if (surfDesc == nullptr) |
| { |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| surfDesc->uiFlags = descFlag; |
| surfDesc->uiVaMemType = memTypeFlag; |
| |
| if (memTypeFlag == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) |
| { |
| surfDesc->ulBuffer = drmPrimeSurfaceDescriptor.objects[0].fd; |
| surfDesc->modifier = drmPrimeSurfaceDescriptor.objects[0].drm_format_modifier; |
| surfDesc->uiSize = drmPrimeSurfaceDescriptor.objects[0].size; |
| surfDesc->uiBuffserSize = drmPrimeSurfaceDescriptor.objects[0].size; |
| surfDesc->uiPlanes = drmPrimeSurfaceDescriptor.layers[0].num_planes; |
| eStatus = MOS_SecureMemcpy(surfDesc->uiPitches, sizeof(surfDesc->uiPitches), drmPrimeSurfaceDescriptor.layers[0].pitch, sizeof(drmPrimeSurfaceDescriptor.layers[0].pitch)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_VERBOSEMESSAGE("DDI:Failed to copy surface buffer data!"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| eStatus = MOS_SecureMemcpy(surfDesc->uiOffsets, sizeof(surfDesc->uiOffsets), drmPrimeSurfaceDescriptor.layers[0].offset, sizeof(drmPrimeSurfaceDescriptor.layers[0].offset)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_VERBOSEMESSAGE("DDI:Failed to copy surface buffer data!"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| else if (memTypeFlag != VA_SURFACE_ATTRIB_MEM_TYPE_VA) { |
| surfDesc->uiPlanes = externalBufDescripor.num_planes; |
| surfDesc->ulBuffer = externalBufDescripor.buffers[i]; |
| surfDesc->uiSize = externalBufDescripor.data_size; |
| surfDesc->uiBuffserSize = externalBufDescripor.data_size; |
| |
| eStatus = MOS_SecureMemcpy(surfDesc->uiPitches, sizeof(surfDesc->uiPitches), externalBufDescripor.pitches, sizeof(externalBufDescripor.pitches)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_VERBOSEMESSAGE("DDI:Failed to copy surface buffer data!"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| eStatus = MOS_SecureMemcpy(surfDesc->uiOffsets, sizeof(surfDesc->uiOffsets), externalBufDescripor.offsets, sizeof(externalBufDescripor.offsets)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_VERBOSEMESSAGE("DDI:Failed to copy surface buffer data!"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| if( surfIsUserPtr ) |
| { |
| surfDesc->uiTile = I915_TILING_NONE; |
| if (surfDesc->ulBuffer % 4096 != 0) |
| { |
| MOS_FreeMemory(surfDesc); |
| DDI_VERBOSEMESSAGE("Buffer Address is invalid"); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| } |
| } |
| } |
| VASurfaceID vaSurfaceID = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaCtx, mediaFmt, width, height, surfDesc, surfaceUsageHint, MOS_MEMPOOL_VIDEOMEMORY); |
| if (VA_INVALID_ID != vaSurfaceID) |
| { |
| surfaces[i] = vaSurfaceID; |
| } |
| else |
| { |
| // here to release the successful allocated surfaces? |
| if( nullptr != surfDesc ) |
| { |
| MOS_FreeMemory(surfDesc); |
| } |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_END, &num_surfaces, sizeof(uint32_t), surfaces, num_surfaces*sizeof(VAGenericID)); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus DdiMedia_CreateMfeContextInternal( |
| VADriverContextP ctx, |
| VAMFContextID *mfe_context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaDrvCtx, "nullptr pMediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mfe_context, "nullptr mfe_context", VA_STATUS_ERROR_INVALID_PARAMETER); |
| *mfe_context = DDI_MEDIA_INVALID_VACONTEXTID; |
| |
| if (!mediaDrvCtx->m_caps->IsMfeSupportedOnPlatform(mediaDrvCtx->platform)) |
| { |
| DDI_VERBOSEMESSAGE("MFE is not supported on the platform!"); |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)MOS_AllocAndZeroMemory(sizeof(DDI_ENCODE_MFE_CONTEXT)); |
| if (nullptr == encodeMfeContext) |
| { |
| MOS_FreeMemory(encodeMfeContext); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| DdiMediaUtil_LockMutex(&mediaDrvCtx->MfeMutex); |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapElmt = DdiMediaUtil_AllocPVAContextFromHeap(mediaDrvCtx->pMfeCtxHeap); |
| if (nullptr == vaContextHeapElmt) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaDrvCtx->MfeMutex); |
| MOS_FreeMemory(encodeMfeContext); |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| |
| vaContextHeapElmt->pVaContext = (void*)encodeMfeContext; |
| mediaDrvCtx->uiNumMfes++; |
| *mfe_context = (VAMFContextID)(vaContextHeapElmt->uiVaContextID + DDI_MEDIA_VACONTEXTID_OFFSET_MFE); |
| DdiMediaUtil_UnLockMutex(&mediaDrvCtx->MfeMutex); |
| |
| // Create shared state, which is used by all the sub contexts |
| MfeSharedState *mfeEncodeSharedState = (MfeSharedState*)MOS_AllocAndZeroMemory(sizeof(MfeSharedState)); |
| if (nullptr == mfeEncodeSharedState) |
| { |
| MOS_FreeMemory(encodeMfeContext); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| encodeMfeContext->mfeEncodeSharedState = mfeEncodeSharedState; |
| |
| DdiMediaUtil_InitMutex(&encodeMfeContext->encodeMfeMutex); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus DdiMedia_DestoryMfeContext ( |
| VADriverContextP ctx, |
| VAMFContextID mfe_context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)DdiMedia_GetContextFromContextID(ctx, mfe_context, &ctxType); |
| DDI_CHK_NULL(encodeMfeContext, "nullptr encodeMfeContext", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| // Release std::vector memory |
| encodeMfeContext->pDdiEncodeContexts.clear(); |
| encodeMfeContext->pDdiEncodeContexts.shrink_to_fit(); |
| |
| encodeMfeContext->mfeEncodeSharedState->encoders.clear(); |
| encodeMfeContext->mfeEncodeSharedState->encoders.shrink_to_fit(); |
| |
| DdiMediaUtil_DestroyMutex(&encodeMfeContext->encodeMfeMutex); |
| MOS_FreeMemory(encodeMfeContext->mfeEncodeSharedState); |
| MOS_FreeMemory(encodeMfeContext); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->MfeMutex); |
| DdiMediaUtil_ReleasePVAContextFromHeap(mediaCtx->pMfeCtxHeap, (mfe_context & DDI_MEDIA_MASK_VACONTEXTID)); |
| mediaCtx->uiNumMfes--; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->MfeMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus DdiMedia_AddContextInternal( |
| VADriverContextP ctx, |
| VAContextID context, |
| VAMFContextID mfe_context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)DdiMedia_GetContextFromContextID(ctx, mfe_context, &ctxType); |
| DDI_CHK_NULL(encodeMfeContext, "nullptr encodeMfeContext", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if (ctxType != DDI_MEDIA_CONTEXT_TYPE_MFE) |
| { |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| PDDI_ENCODE_CONTEXT encodeContext = DdiEncode_GetEncContextFromContextID(ctx, context); |
| DDI_CHK_NULL(encodeContext, "nullptr encodeContext", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| CodechalEncoderState *encoder = dynamic_cast<CodechalEncoderState *>(encodeContext->pCodecHal); |
| DDI_CHK_NULL(encoder, "nullptr codechal encoder", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if (!mediaCtx->m_caps->IsMfeSupportedEntrypoint(encodeContext->vaEntrypoint)) |
| { |
| return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; |
| } |
| |
| if (!mediaCtx->m_caps->IsMfeSupportedProfile(encodeContext->vaProfile)) |
| { |
| return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; |
| } |
| |
| DdiMediaUtil_LockMutex(&encodeMfeContext->encodeMfeMutex); |
| encodeMfeContext->pDdiEncodeContexts.push_back(encodeContext); |
| |
| if (encodeMfeContext->currentStreamId == 0) |
| { |
| encodeMfeContext->isFEI = (encodeContext->vaEntrypoint == VAEntrypointFEI) ? true : false; |
| } |
| |
| //MFE cannot support legacy and FEI together |
| if ((encodeContext->vaEntrypoint != VAEntrypointFEI && encodeMfeContext->isFEI) || |
| (encodeContext->vaEntrypoint == VAEntrypointFEI && !encodeMfeContext->isFEI)) |
| { |
| DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex); |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| |
| encoder->m_mfeEnabled = true; |
| // Assign one unique id to this sub context/stream |
| encoder->m_mfeEncodeParams.streamId = encodeMfeContext->currentStreamId; |
| |
| MOS_STATUS eStatus = encoder->SetMfeSharedState(encodeMfeContext->mfeEncodeSharedState); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE( |
| "Failed to set MFE Shared State for encoder #%d", |
| encodeMfeContext->currentStreamId); |
| |
| encoder->m_mfeEnabled = false; |
| |
| DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| encodeMfeContext->currentStreamId++; |
| DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus DdiMedia_ReleaseContextInternal( |
| VADriverContextP ctx, |
| VAContextID context, |
| VAMFContextID mfe_context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| PDDI_ENCODE_MFE_CONTEXT encodeMfeContext = (PDDI_ENCODE_MFE_CONTEXT)DdiMedia_GetContextFromContextID(ctx, mfe_context, &ctxType); |
| DDI_CHK_NULL(encodeMfeContext, "nullptr encodeMfeContext", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if (ctxType != DDI_MEDIA_CONTEXT_TYPE_MFE || |
| encodeMfeContext->pDdiEncodeContexts.size() == 0) |
| { |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| PDDI_ENCODE_CONTEXT encodeContext = DdiEncode_GetEncContextFromContextID(ctx, context); |
| DDI_CHK_NULL(encodeMfeContext, "nullptr encodeContext", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| bool contextErased = false; |
| DdiMediaUtil_LockMutex(&encodeMfeContext->encodeMfeMutex); |
| for (uint32_t i = 0; i < encodeMfeContext->pDdiEncodeContexts.size(); i++) |
| { |
| if (encodeMfeContext->pDdiEncodeContexts[i] == encodeContext) |
| { |
| encodeMfeContext->pDdiEncodeContexts.erase(encodeMfeContext->pDdiEncodeContexts.begin() + i); |
| contextErased = true; |
| break; |
| } |
| } |
| |
| if (!contextErased) |
| { |
| DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| DdiMediaUtil_UnLockMutex(&encodeMfeContext->encodeMfeMutex); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static VAStatus DdiMedia_CreateContext ( |
| VADriverContextP ctx, |
| VAConfigID config_id, |
| int32_t picture_width, |
| int32_t picture_height, |
| int32_t flag, |
| VASurfaceID *render_targets, |
| int32_t num_render_targets, |
| VAContextID *context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(context, "nullptr context", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaDrvCtx, "nullptr mediaDrvCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if(num_render_targets > 0) |
| { |
| DDI_CHK_NULL(render_targets, "nullptr render_targets", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(mediaDrvCtx->pSurfaceHeap, "nullptr mediaDrvCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| for(int32_t i = 0; i < num_render_targets; i++) |
| { |
| uint32_t surfaceId = (uint32_t)render_targets[i]; |
| DDI_CHK_LESS(surfaceId, mediaDrvCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid Surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| } |
| } |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| if(mediaDrvCtx->m_caps->IsDecConfigId(config_id)) |
| { |
| vaStatus = DdiDecode_CreateContext(ctx, config_id - DDI_CODEC_GEN_CONFIG_ATTRIBUTES_DEC_BASE, picture_width, picture_height, flag, render_targets, num_render_targets, context); |
| } |
| else if(mediaDrvCtx->m_caps->IsEncConfigId(config_id)) |
| { |
| vaStatus = DdiEncode_CreateContext(ctx, config_id - DDI_CODEC_GEN_CONFIG_ATTRIBUTES_ENC_BASE, picture_width, picture_height, flag, render_targets, num_render_targets, context); |
| } |
| else if(mediaDrvCtx->m_caps->IsVpConfigId(config_id)) |
| { |
| vaStatus = DdiVp_CreateContext(ctx, config_id - DDI_VP_GEN_CONFIG_ATTRIBUTES_BASE, picture_width, picture_height, flag, render_targets, num_render_targets, context); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("DDI: Invalid config_id"); |
| vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; |
| } |
| |
| return vaStatus; |
| } |
| |
| static VAStatus DdiMedia_DestroyContext ( |
| VADriverContextP ctx, |
| VAContextID context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType); |
| |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| return DdiDecode_DestroyContext(ctx, context); |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| return DdiEncode_DestroyContext(ctx, context); |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| return DdiVp_DestroyContext(ctx, context); |
| case DDI_MEDIA_CONTEXT_TYPE_MFE: |
| return DdiMedia_DestoryMfeContext(ctx, context); |
| default: |
| DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_DestroyContext."); |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| } |
| |
| static VAStatus DdiMedia_CreateBuffer ( |
| VADriverContextP ctx, |
| VAContextID context, |
| VABufferType type, |
| uint32_t size, |
| uint32_t num_elements, |
| void *data, |
| VABufferID *bufId |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| int32_t event[] = {size, num_elements, type}; |
| MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_START, event, sizeof(event), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(bufId, "nullptr buf_id", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(size, 0, "Invalid size", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| 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); |
| |
| *bufId = VA_INVALID_ID; |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| VAStatus va = VA_STATUS_SUCCESS; |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| va = DdiDecode_CreateBuffer(ctx, DdiDecode_GetDecContextFromPVOID(ctxPtr), type, size, num_elements, data, bufId); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| va = DdiEncode_CreateBuffer(ctx, context, type, size, num_elements, data, bufId); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| va = DdiVp_CreateBuffer(ctx, ctxPtr, type, size, num_elements, data, bufId); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_PROTECTED: |
| va = DdiMediaProtected::DdiMedia_ProtectedSessionCreateBuffer(ctx, context, type, size, num_elements, data, bufId); |
| break; |
| default: |
| va = VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_END, bufId, sizeof(bufId), nullptr, 0); |
| return va; |
| } |
| |
| /* |
| * Convey to the server how many valid elements are in the buffer. |
| * e.g. if multiple slice parameters are being held in a single buffer, |
| * this will communicate to the server the number of slice parameters |
| * that are valid in the buffer. |
| */ |
| static VAStatus DdiMedia_BufferSetNumElements ( |
| VADriverContextP ctx, |
| VABufferID buf_id, |
| uint32_t num_elements |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buf_id", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(buf, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| // only for VASliceParameterBufferType of buffer, the number of elements can be greater than 1 |
| if(buf->uiType != VASliceParameterBufferType && |
| num_elements > 1) |
| { |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| if(buf->uiType == VASliceParameterBufferType && |
| buf->uiNumElements < num_elements) |
| { |
| MOS_FreeMemory(buf->pData); |
| buf->iSize = buf->iSize / buf->uiNumElements; |
| buf->pData = (uint8_t*)MOS_AllocAndZeroMemory(buf->iSize * num_elements); |
| buf->iSize = buf->iSize * num_elements; |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Map data store of the buffer into the client's address space |
| //! vaCreateBuffer() needs to be called with "data" set to nullptr before |
| //! calling vaMapBuffer() |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] buf_id |
| //! VA buffer ID |
| //! \param [out] pbuf |
| //! Pointer to buffer |
| //! \param [in] flag |
| //! Flag |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_MapBufferInternal ( |
| VADriverContextP ctx, |
| VABufferID buf_id, |
| void **pbuf, |
| uint32_t flag |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_START, &buf_id, sizeof(buf_id), &flag, sizeof(flag)); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(pbuf, "nullptr pbuf", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| // The context is nullptr when the buffer is created from DdiMedia_DeriveImage |
| // So doesn't need to check the context for all cases |
| // Only check the context in dec/enc mode |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| uint32_t ctxType = DdiMedia_GetCtxTypeFromVABufferID(mediaCtx, buf_id); |
| void *ctxPtr = nullptr; |
| DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr; |
| PDDI_ENCODE_CONTEXT encCtx = nullptr; |
| PDDI_DECODE_CONTEXT decCtx = nullptr; |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| case DDI_MEDIA_CONTEXT_TYPE_PROTECTED: |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr); |
| bufMgr = &(decCtx->BufMgr); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr); |
| DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| bufMgr = &(encCtx->BufMgr); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_MEDIA: |
| break; |
| default: |
| return VA_STATUS_ERROR_INVALID_BUFFER; |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_INFO, &ctxType, sizeof(ctxType), &buf->uiType, sizeof(uint32_t)); |
| switch ((int32_t)buf->uiType) |
| { |
| case VASliceDataBufferType: |
| case VAProtectedSliceDataBufferType: |
| case VABitPlaneBufferType: |
| *pbuf = (void *)(buf->pData + buf->uiOffset); |
| break; |
| |
| case VASliceParameterBufferType: |
| ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr); |
| bufMgr = &(decCtx->BufMgr); |
| switch (decCtx->wMode) |
| { |
| case CODECHAL_DECODE_MODE_AVCVLD: |
| if(decCtx->bShortFormatInUse) |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264Base) + buf->uiOffset); |
| else |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_H264.pVASliceParaBufH264) + buf->uiOffset); |
| break; |
| case CODECHAL_DECODE_MODE_MPEG2VLD: |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_MPEG2.pVASliceParaBufMPEG2) + buf->uiOffset); |
| break; |
| case CODECHAL_DECODE_MODE_VC1VLD: |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1) + buf->uiOffset); |
| break; |
| case CODECHAL_DECODE_MODE_JPEG: |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_JPEG.pVASliceParaBufJPEG) + buf->uiOffset); |
| break; |
| case CODECHAL_DECODE_MODE_VP8VLD: |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VP8.pVASliceParaBufVP8) + buf->uiOffset); |
| break; |
| case CODECHAL_DECODE_MODE_HEVCVLD: |
| if(decCtx->bShortFormatInUse) |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufBaseHEVC) + buf->uiOffset); |
| else |
| { |
| if(!decCtx->m_ddiDecode->IsRextProfile()) |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVC) + buf->uiOffset); |
| else |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_HEVC.pVASliceParaBufHEVCRext) + buf->uiOffset); |
| } |
| break; |
| case CODECHAL_DECODE_MODE_VP9VLD: |
| *pbuf = (void *)((uint8_t*)(bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9) + buf->uiOffset); |
| break; |
| case CODECHAL_DECODE_MODE_AV1VLD: |
| *pbuf = (void *)((uint8_t*)(bufMgr->pCodecSlcParamReserved) + buf->uiOffset); |
| break; |
| default: |
| break; |
| } |
| break; |
| |
| case VAEncCodedBufferType: |
| DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if( DdiEncode_CodedBufferExistInStatusReport( encCtx, buf ) ) |
| { |
| vaStatus = DdiEncode_StatusReport(encCtx, buf, pbuf); |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return vaStatus; |
| } |
| // so far a coded buffer that has NOT been added into status report is skipped frame in non-CP case |
| // but this can change in future if new usage models come up |
| encCtx->BufMgr.pCodedBufferSegment->buf = DdiMediaUtil_LockBuffer(buf, flag); |
| encCtx->BufMgr.pCodedBufferSegment->size = buf->iSize; |
| *pbuf = encCtx->BufMgr.pCodedBufferSegment; |
| |
| break; |
| |
| case VAStatsStatisticsBufferType: |
| case VAStatsStatisticsBottomFieldBufferType: |
| case VAStatsMVBufferType: |
| { |
| DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT) |
| DDI_ENCODE_PRE_ENC_BUFFER_TYPE idx = (buf->uiType == VAStatsMVBufferType) ? PRE_ENC_BUFFER_TYPE_MVDATA : |
| ((buf->uiType == VAStatsStatisticsBufferType) ? PRE_ENC_BUFFER_TYPE_STATS |
| : PRE_ENC_BUFFER_TYPE_STATS_BOT); |
| if((encCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC) && DdiEncode_PreEncBufferExistInStatusReport( encCtx, buf, idx)) |
| { |
| vaStatus = DdiEncode_PreEncStatusReport(encCtx, buf, pbuf); |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return vaStatus; |
| } |
| if(buf->bo) |
| { |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| } |
| break; |
| } |
| case VAStatsMVPredictorBufferType: |
| case VAEncFEIMBControlBufferType: |
| case VAEncFEIMVPredictorBufferType: |
| case VAEncQPBufferType: |
| if(buf->bo) |
| { |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| } |
| break; |
| case VADecodeStreamoutBufferType: |
| if(buf->bo) |
| { |
| uint32_t timeout_NS = 100000000; |
| while (0 != mos_gem_bo_wait(buf->bo, timeout_NS)) |
| { |
| // Just loop while gem_bo_wait times-out. |
| } |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| } |
| break; |
| case VAEncFEIMVBufferType: |
| case VAEncFEIMBCodeBufferType: |
| case VAEncFEICURecordBufferType: |
| case VAEncFEICTBCmdBufferType: |
| case VAEncFEIDistortionBufferType: |
| { |
| DDI_CHK_NULL(encCtx, "nullptr encCtx", VA_STATUS_ERROR_INVALID_CONTEXT) |
| if(encCtx->wModeType == CODECHAL_ENCODE_MODE_AVC) |
| { |
| CodecEncodeAvcFeiPicParams *feiPicParams = (CodecEncodeAvcFeiPicParams *)encCtx->pFeiPicParams; |
| |
| DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEIMVBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA : |
| ((buf->uiType == VAEncFEIMBCodeBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE : |
| FEI_ENC_BUFFER_TYPE_DISTORTION); |
| if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC) && DdiEncode_EncBufferExistInStatusReport( encCtx, buf, idx)) |
| { |
| vaStatus = DdiEncode_EncStatusReport(encCtx, buf, pbuf); |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return vaStatus; |
| } |
| } |
| else if(encCtx->wModeType == CODECHAL_ENCODE_MODE_HEVC) |
| |
| { |
| CodecEncodeHevcFeiPicParams *feiPicParams = (CodecEncodeHevcFeiPicParams *)encCtx->pFeiPicParams; |
| DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEICTBCmdBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA : |
| ((buf->uiType == VAEncFEICURecordBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE : |
| FEI_ENC_BUFFER_TYPE_DISTORTION); |
| if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC) && DdiEncode_EncBufferExistInStatusReport( encCtx, buf, idx)) |
| { |
| vaStatus = DdiEncode_EncStatusReport(encCtx, buf, pbuf); |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return vaStatus; |
| } |
| } |
| if(buf->bo) |
| { |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| } |
| } |
| break; |
| case VAStatsStatisticsParameterBufferType: |
| *pbuf = (void *)(buf->pData + buf->uiOffset); |
| break; |
| case VAEncMacroblockMapBufferType: |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| if (nullptr == (*pbuf)) |
| { |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| else |
| { |
| return VA_STATUS_SUCCESS; |
| } |
| break; |
| |
| case VAProbabilityBufferType: |
| *pbuf = (void *)(buf->pData + buf->uiOffset); |
| |
| break; |
| |
| case VAEncMacroblockDisableSkipMapBufferType: |
| if(buf->bo) |
| { |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| } |
| break; |
| |
| case VAImageBufferType: |
| default: |
| if((buf->format != Media_Format_CPU) && (DdiMedia_MediaFormatToOsFormat(buf->format) != VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT)) |
| { |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| // A critical section starts. |
| // Make sure not to bailout with a return until the section ends. |
| |
| if (nullptr != buf->pSurface && Media_Format_CPU != buf->format) |
| { |
| vaStatus = DdiMedia_MediaMemoryDecompress(mediaCtx, buf->pSurface); |
| } |
| |
| if (VA_STATUS_SUCCESS == vaStatus) |
| { |
| *pbuf = DdiMediaUtil_LockBuffer(buf, flag); |
| |
| if (nullptr == *pbuf) |
| { |
| vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| |
| // The critical section ends. |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| } |
| else |
| { |
| *pbuf = (void *)(buf->pData + buf->uiOffset); |
| } |
| break; |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_MAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return vaStatus; |
| } |
| |
| VAStatus DdiMedia_MapBuffer ( |
| VADriverContextP ctx, |
| VABufferID buf_id, |
| void **pbuf |
| ) |
| { |
| return DdiMedia_MapBufferInternal(ctx, buf_id, pbuf, MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY); |
| } |
| |
| /* |
| * After client making changes to a mapped data store, it needs to |
| * "Unmap" it to let the server know that the data is ready to be |
| * consumed by the server |
| */ |
| VAStatus DdiMedia_UnmapBuffer ( |
| VADriverContextP ctx, |
| VABufferID buf_id |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_UNMAP, EVENT_TYPE_START, &buf_id, sizeof(buf_id), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL( mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buf_id", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| // The context is nullptr when the buffer is created from DdiMedia_DeriveImage |
| // So doesn't need to check the context for all cases |
| // Only check the context in dec/enc mode |
| void *ctxPtr = nullptr; |
| uint32_t ctxType = DdiMedia_GetCtxTypeFromVABufferID(mediaCtx, buf_id); |
| DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr; |
| PDDI_DECODE_CONTEXT decCtx = nullptr; |
| PDDI_ENCODE_CONTEXT encCtx = nullptr; |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| case DDI_MEDIA_CONTEXT_TYPE_PROTECTED: |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr); |
| bufMgr = &(decCtx->BufMgr); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr); |
| bufMgr = &(encCtx->BufMgr); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_MEDIA: |
| break; |
| default: |
| return VA_STATUS_ERROR_INVALID_BUFFER; |
| } |
| |
| switch ((int32_t)buf->uiType) |
| { |
| case VASliceDataBufferType: |
| case VAProtectedSliceDataBufferType: |
| case VABitPlaneBufferType: |
| break; |
| case VAEncCodedBufferType: |
| case VAStatsStatisticsBufferType: |
| case VAStatsStatisticsBottomFieldBufferType: |
| case VAStatsMVBufferType: |
| case VAStatsMVPredictorBufferType: |
| case VAEncFEIMBControlBufferType: |
| case VAEncFEIMVPredictorBufferType: |
| case VAEncFEIMVBufferType: |
| case VAEncFEIMBCodeBufferType: |
| case VAEncFEICURecordBufferType: |
| case VAEncFEICTBCmdBufferType: |
| case VAEncFEIDistortionBufferType: |
| case VAEncQPBufferType: |
| case VADecodeStreamoutBufferType: |
| if(buf->bo) |
| { |
| DdiMediaUtil_UnlockBuffer(buf); |
| } |
| break; |
| case VAEncMacroblockDisableSkipMapBufferType: |
| if(buf->bo) |
| { |
| DdiMediaUtil_UnlockBuffer(buf); |
| } |
| break; |
| |
| case VAImageBufferType: |
| default: |
| if((buf->format != Media_Format_CPU) &&(DdiMedia_MediaFormatToOsFormat(buf->format) != VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT)) |
| { |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| DdiMediaUtil_UnlockBuffer(buf); |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| } |
| break; |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_UNMAP, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /* |
| * After this call, the buffer is deleted and this buffer_id is no longer valid |
| * Only call this if the buffer is not going to be passed to vaRenderBuffer |
| */ |
| VAStatus DdiMedia_DestroyBuffer ( |
| VADriverContextP ctx, |
| VABufferID buffer_id |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_START, &buffer_id, sizeof(buffer_id), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid bufferId", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffer_id); |
| DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| void *ctxPtr = DdiMedia_GetCtxFromVABufferID(mediaCtx, buffer_id); |
| uint32_t ctxType = DdiMedia_GetCtxTypeFromVABufferID(mediaCtx, buffer_id); |
| |
| DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr; |
| PDDI_ENCODE_CONTEXT encCtx = nullptr; |
| PDDI_DECODE_CONTEXT decCtx = nullptr; |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| decCtx = DdiDecode_GetDecContextFromPVOID(ctxPtr); |
| bufMgr = &(decCtx->BufMgr); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| DDI_CHK_NULL(ctxPtr, "nullptr ctxPtr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr); |
| bufMgr = &(encCtx->BufMgr); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_MEDIA: |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_PROTECTED: |
| break; |
| default: |
| return VA_STATUS_ERROR_INVALID_BUFFER; |
| } |
| switch ((int32_t)buf->uiType) |
| { |
| case VASliceDataBufferType: |
| case VAProtectedSliceDataBufferType: |
| DdiMedia_ReleaseBsBuffer(bufMgr, buf); |
| break; |
| case VABitPlaneBufferType: |
| DdiMedia_ReleaseBpBuffer(bufMgr, buf); |
| break; |
| case VAProbabilityBufferType: |
| DdiMedia_ReleaseBpBuffer(bufMgr, buf); |
| break; |
| |
| case VASliceParameterBufferType: |
| DdiMedia_ReleaseSliceControlBuffer(ctxType, ctxPtr, buf); |
| break; |
| case VAPictureParameterBufferType: |
| break; |
| case VAImageBufferType: |
| if(buf->format == Media_Format_CPU) |
| { |
| MOS_FreeMemory(buf->pData); |
| } |
| else |
| { |
| DdiMediaUtil_UnRefBufObjInMediaBuffer(buf); |
| |
| if (buf->uiExportcount) { |
| buf->bPostponedBufFree = true; |
| MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| } |
| break; |
| case VAProcPipelineParameterBufferType: |
| case VAProcFilterParameterBufferType: |
| MOS_FreeMemory(buf->pData); |
| break; |
| case VASubsetsParameterBufferType: |
| case VAIQMatrixBufferType: |
| case VAHuffmanTableBufferType: |
| case VAEncSliceParameterBufferType: |
| case VAEncPictureParameterBufferType: |
| case VAEncSequenceParameterBufferType: |
| case VAEncPackedHeaderDataBufferType: |
| case VAEncPackedHeaderParameterBufferType: |
| MOS_FreeMemory(buf->pData); |
| break; |
| case VAEncMacroblockMapBufferType: |
| DdiMediaUtil_FreeBuffer(buf); |
| break; |
| #ifdef ENABLE_ENC_UNLIMITED_OUTPUT |
| case VAEncCodedBufferType: |
| if(nullptr == encCtx) |
| { |
| encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr); |
| if(nullptr == encCtx) |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| DdiMediaUtil_FreeBuffer(buf); |
| break; |
| #endif |
| case VAStatsStatisticsParameterBufferType: |
| MOS_FreeMemory(buf->pData); |
| break; |
| case VAStatsStatisticsBufferType: |
| case VAStatsStatisticsBottomFieldBufferType: |
| case VAStatsMVBufferType: |
| { |
| if(nullptr == encCtx) |
| { |
| encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr); |
| if(nullptr == encCtx) |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| if(encCtx->codecFunction == CODECHAL_FUNCTION_FEI_PRE_ENC) |
| { |
| DDI_ENCODE_PRE_ENC_BUFFER_TYPE idx = (buf->uiType == VAStatsMVBufferType) ? PRE_ENC_BUFFER_TYPE_MVDATA : |
| ((buf->uiType == VAStatsStatisticsBufferType) ? PRE_ENC_BUFFER_TYPE_STATS |
| : PRE_ENC_BUFFER_TYPE_STATS_BOT); |
| DdiEncode_RemoveFromPreEncStatusReportQueue(encCtx, buf, idx); |
| } |
| } |
| DdiMediaUtil_FreeBuffer(buf); |
| break; |
| case VAStatsMVPredictorBufferType: |
| case VAEncFEIMBControlBufferType: |
| case VAEncFEIMVPredictorBufferType: |
| case VAEncQPBufferType: |
| case VADecodeStreamoutBufferType: |
| DdiMediaUtil_FreeBuffer(buf); |
| break; |
| case VAEncFEIMVBufferType: |
| case VAEncFEIMBCodeBufferType: |
| case VAEncFEICURecordBufferType: |
| case VAEncFEICTBCmdBufferType: |
| case VAEncFEIDistortionBufferType: |
| { |
| if(nullptr == encCtx) |
| { |
| encCtx = DdiEncode_GetEncContextFromPVOID(ctxPtr); |
| if(nullptr == encCtx) |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| if(encCtx->wModeType == CODECHAL_ENCODE_MODE_AVC) |
| { |
| CodecEncodeAvcFeiPicParams *feiPicParams; |
| feiPicParams = (CodecEncodeAvcFeiPicParams *)(encCtx->pFeiPicParams); |
| if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)) |
| { |
| DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEIMVBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA : |
| ((buf->uiType == VAEncFEIMBCodeBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE : |
| FEI_ENC_BUFFER_TYPE_DISTORTION); |
| DdiEncode_RemoveFromEncStatusReportQueue(encCtx, buf, idx); |
| } |
| |
| } |
| else if(encCtx->wModeType == CODECHAL_ENCODE_MODE_HEVC) |
| { |
| CodecEncodeHevcFeiPicParams *feiPicParams; |
| feiPicParams = (CodecEncodeHevcFeiPicParams *)(encCtx->pFeiPicParams); |
| if((feiPicParams != nullptr) && (encCtx->codecFunction == CODECHAL_FUNCTION_FEI_ENC)) |
| { |
| DDI_ENCODE_FEI_ENC_BUFFER_TYPE idx = (buf->uiType == VAEncFEICTBCmdBufferType) ? FEI_ENC_BUFFER_TYPE_MVDATA : |
| ((buf->uiType == VAEncFEICURecordBufferType) ? FEI_ENC_BUFFER_TYPE_MBCODE : |
| FEI_ENC_BUFFER_TYPE_DISTORTION); |
| DdiEncode_RemoveFromEncStatusReportQueue(encCtx, buf, idx); |
| } |
| } |
| } |
| DdiMediaUtil_FreeBuffer(buf); |
| break; |
| default: // do not handle any un-listed buffer type |
| MOS_FreeMemory(buf->pData); |
| break; |
| //return va_STATUS_SUCCESS; |
| } |
| MOS_FreeMemory(buf); |
| |
| DdiMedia_DestroyBufFromVABufferID(mediaCtx, buffer_id); |
| MOS_TraceEventExt(EVENT_VA_FREE_BUFFER, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /* |
| * Get ready to decode a picture to a target surface |
| */ |
| static VAStatus DdiMedia_BeginPicture ( |
| VADriverContextP ctx, |
| VAContextID context, |
| VASurfaceID render_target |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)render_target, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "render_target", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType); |
| uint32_t event[] = {(uint32_t)context, ctxType, (uint32_t)render_target}; |
| MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0); |
| |
| PDDI_MEDIA_SURFACE surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex); |
| surface->curCtxType = ctxType; |
| surface->curStatusReportQueryState = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_PENDING; |
| if(ctxType == DDI_MEDIA_CONTEXT_TYPE_VP) |
| { |
| surface->curStatusReport.vpp.status = VPREP_NOTAVAILABLE; |
| } |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| return DdiDecode_BeginPicture(ctx, context, render_target); |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| return DdiEncode_BeginPicture(ctx, context, render_target); |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| return DdiVp_BeginPicture(ctx, context, render_target); |
| default: |
| DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_BeginPicture."); |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| } |
| |
| /* |
| * Send decode buffers to the server. |
| * Buffers are automatically destroyed afterwards |
| */ |
| static VAStatus DdiMedia_RenderPicture ( |
| VADriverContextP ctx, |
| VAContextID context, |
| VABufferID *buffers, |
| int32_t num_buffers |
| ) |
| { |
| |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL( ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL( buffers, "nullptr buffers", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(num_buffers, 0, "Invalid number buffers", VA_STATUS_ERROR_INVALID_PARAMETER); |
| uint32_t event[] = {(uint32_t)context, (uint32_t)num_buffers}; |
| MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_INFO, event, sizeof(event), buffers, num_buffers*sizeof(VAGenericID)); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| for(int32_t i = 0; i < num_buffers; i++) |
| { |
| DDI_CHK_LESS((uint32_t)buffers[i], mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid Buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| } |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType); |
| |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| return DdiDecode_RenderPicture(ctx, context, buffers, num_buffers); |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| return DdiEncode_RenderPicture(ctx, context, buffers, num_buffers); |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| return DdiVp_RenderPicture(ctx, context, buffers, num_buffers); |
| default: |
| DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_RenderPicture."); |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| |
| } |
| |
| /* |
| * Make the end of rendering for a picture. |
| * The server should start processing all pending operations for this |
| * surface. This call is non-blocking. The client can start another |
| * Begin/Render/End sequence on a different render target. |
| */ |
| static VAStatus DdiMedia_EndPicture ( |
| VADriverContextP ctx, |
| VAContextID context |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType); |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| switch (ctxType) |
| { |
| case DDI_MEDIA_CONTEXT_TYPE_DECODER: |
| vaStatus = DdiDecode_EndPicture(ctx, context); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_ENCODER: |
| vaStatus = DdiEncode_EndPicture(ctx, context); |
| break; |
| case DDI_MEDIA_CONTEXT_TYPE_VP: |
| vaStatus = DdiVp_EndPicture(ctx, context); |
| break; |
| default: |
| DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_EndPicture."); |
| vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_END, &context, sizeof(context), &vaStatus, sizeof(vaStatus)); |
| PERF_UTILITY_STOP_ONCE("First Frame Time", PERF_MOS, PERF_LEVEL_DDI); |
| |
| return vaStatus; |
| } |
| |
| static VAStatus DdiMedia_StatusCheck ( |
| PDDI_MEDIA_CONTEXT mediaCtx, |
| DDI_MEDIA_SURFACE *surface, |
| VASurfaceID surface_id |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| uint32_t i = 0; |
| PDDI_DECODE_CONTEXT decCtx = (PDDI_DECODE_CONTEXT)surface->pDecCtx; |
| if (decCtx && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER) |
| { |
| DdiMediaUtil_LockGuard guard(&mediaCtx->SurfaceMutex); |
| |
| Codechal *codecHal = decCtx->pCodecHal; |
| //return success just avoid vaDestroyContext is ahead of vaSyncSurface |
| DDI_CHK_NULL(codecHal, "nullptr decCtx->pCodecHal", VA_STATUS_SUCCESS); |
| |
| //return success just avoid vaDestroyContext is ahead of vaSyncSurface |
| if (codecHal->IsApogeiosEnabled()) |
| { |
| DecodePipelineAdapter *decoder = dynamic_cast<DecodePipelineAdapter *>(codecHal); |
| DDI_CHK_NULL(decoder, "nullptr (DecodePipelineAdapter *decoder) ", VA_STATUS_SUCCESS); |
| return DdiDecode_StatusReport(mediaCtx, decoder, surface); |
| } |
| else |
| { |
| CodechalDecode *decoder = dynamic_cast<CodechalDecode *>(codecHal); |
| DDI_CHK_NULL(decoder, "nullptr (CodechalDecode *decoder)", VA_STATUS_SUCCESS); |
| return DdiDecode_StatusReport(mediaCtx, decoder, surface); |
| } |
| } |
| |
| if (surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_VP) |
| { |
| PDDI_VP_CONTEXT vpCtx = (PDDI_VP_CONTEXT)surface->pVpCtx; |
| DDI_CHK_NULL(vpCtx , "nullptr vpCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(vpCtx->pVpHal ,"nullptr vpCtx->pVpHal", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| QUERY_STATUS_REPORT_APP tempVpReport; |
| MOS_ZeroMemory(&tempVpReport, sizeof(QUERY_STATUS_REPORT_APP)); |
| |
| // Get reported surfaces' count |
| uint32_t tableLen = 0; |
| vpCtx->pVpHal->GetStatusReportEntryLength(&tableLen); |
| |
| if (tableLen > 0 && surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_PENDING) |
| { |
| // Query the status for all of surfaces which have finished |
| for(i = 0; i < tableLen; i++) |
| { |
| MOS_ZeroMemory(&tempVpReport, sizeof(QUERY_STATUS_REPORT_APP)); |
| vpCtx->pVpHal->GetStatusReport(&tempVpReport, 1); |
| |
| // StatusFeedBackID is last time submitted Target Surface ID which is set in BeginPicture, |
| // So we can know the report is for which surface here. |
| DDI_MEDIA_SURFACE *tempSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, tempVpReport.StatusFeedBackID); |
| if(tempSurface == nullptr) |
| { |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| // Update the status of the surface which is reported. |
| tempSurface->curStatusReport.vpp.status = (uint32_t)tempVpReport.dwStatus; |
| tempSurface->curStatusReportQueryState = DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED; |
| |
| if(tempVpReport.StatusFeedBackID == surface_id) |
| { |
| break; |
| } |
| } |
| } |
| |
| if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED) |
| { |
| if(surface->curStatusReport.vpp.status == VPREP_OK) |
| { |
| return VA_STATUS_SUCCESS; |
| } |
| else if(surface->curStatusReport.vpp.status == VPREP_NOTREADY) |
| { |
| return mediaCtx->bMediaResetEnable ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_HW_BUSY; |
| } |
| else |
| { |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| else |
| { |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| |
| return VA_STATUS_SUCCESS; |
| |
| } |
| |
| /* |
| * This function blocks until all pending operations on the render target |
| * have been completed. Upon return it is safe to use the render target for a |
| * different picture. |
| */ |
| static VAStatus DdiMedia_SyncSurface ( |
| VADriverContextP ctx, |
| VASurfaceID render_target |
| ) |
| { |
| PERF_UTILITY_AUTO(__FUNCTION__, "ENCODE", "DDI"); |
| |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, &render_target, sizeof(VAGenericID), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_LESS((uint32_t)render_target, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid render_target", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_CONTEXT); |
| if (surface->pCurrentFrameSemaphore) |
| { |
| DdiMediaUtil_WaitSemaphore(surface->pCurrentFrameSemaphore); |
| DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore); |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_INFO, surface->bo? &surface->bo->handle:nullptr, sizeof(uint32_t), nullptr, 0); |
| // check the bo here? |
| // zero is a expected return value |
| uint32_t timeout_NS = 100000000; |
| while (0 != mos_gem_bo_wait(surface->bo, timeout_NS)) |
| { |
| // Just loop while gem_bo_wait times-out. |
| } |
| |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return DdiMedia_StatusCheck(mediaCtx, surface, render_target); |
| } |
| |
| #if VA_CHECK_VERSION(1, 9, 0) |
| /* |
| * This function blocks until all pending operations on the surface have been |
| * completed or exceed timeout. Upon return it is safe to use the render target for a |
| * different picture. |
| */ |
| static VAStatus DdiMedia_SyncSurface2 ( |
| VADriverContextP ctx, |
| VASurfaceID surface_id, |
| uint64_t timeout_ns |
| ) |
| { |
| PERF_UTILITY_AUTO(__FUNCTION__, "ENCODE", "DDI"); |
| |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, &surface_id, sizeof(VAGenericID), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_LESS((uint32_t)surface_id, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid render_target", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface_id); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_CONTEXT); |
| if (surface->pCurrentFrameSemaphore) |
| { |
| DdiMediaUtil_WaitSemaphore(surface->pCurrentFrameSemaphore); |
| DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore); |
| } |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_INFO, surface->bo? &surface->bo->handle:nullptr, sizeof(uint32_t), nullptr, 0); |
| |
| if (timeout_ns == VA_TIMEOUT_INFINITE) |
| { |
| // zero is an expected return value when not hit timeout |
| auto ret = mos_gem_bo_wait(surface->bo, DDI_BO_INFINITE_TIMEOUT); |
| if (0 != ret) |
| { |
| DDI_NORMALMESSAGE("vaSyncSurface2: surface is still used by HW\n\r"); |
| return VA_STATUS_ERROR_TIMEDOUT; |
| } |
| } |
| else |
| { |
| int64_t timeoutBoWait1 = 0; |
| int64_t timeoutBoWait2 = 0; |
| if (timeout_ns >= DDI_BO_MAX_TIMEOUT) |
| { |
| timeoutBoWait1 = DDI_BO_MAX_TIMEOUT - 1; |
| timeoutBoWait2 = timeout_ns - DDI_BO_MAX_TIMEOUT + 1; |
| } |
| else |
| { |
| timeoutBoWait1 = (int64_t)timeout_ns; |
| } |
| |
| // zero is an expected return value when not hit timeout |
| auto ret = mos_gem_bo_wait(surface->bo, timeoutBoWait1); |
| if (0 != ret) |
| { |
| if (timeoutBoWait2) |
| { |
| ret = mos_gem_bo_wait(surface->bo, timeoutBoWait2); |
| } |
| if (0 != ret) |
| { |
| DDI_NORMALMESSAGE("vaSyncSurface2: surface is still used by HW\n\r"); |
| return VA_STATUS_ERROR_TIMEDOUT; |
| } |
| } |
| } |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return DdiMedia_StatusCheck(mediaCtx, surface, surface_id); |
| } |
| |
| /* |
| * This function blocks until all pending operations on the buffer have been |
| * completed or exceed timeout. Upon return it is safe to use the render target for a |
| * different picture. |
| */ |
| static VAStatus DdiMedia_SyncBuffer ( |
| VADriverContextP ctx, |
| VABufferID buf_id, |
| uint64_t timeout_ns |
| ) |
| { |
| PERF_UTILITY_AUTO(__FUNCTION__, "ENCODE", "DDI"); |
| |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_START, &buf_id, sizeof(buf_id), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| DDI_MEDIA_BUFFER *buffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_INFO, buffer->bo? &buffer->bo->handle:nullptr, sizeof(uint32_t), nullptr, 0); |
| if (timeout_ns == VA_TIMEOUT_INFINITE) |
| { |
| // zero is a expected return value when not hit timeout |
| auto ret = mos_gem_bo_wait(buffer->bo, DDI_BO_INFINITE_TIMEOUT); |
| if (0 != ret) |
| { |
| DDI_NORMALMESSAGE("vaSyncBuffer: buffer is still used by HW\n\r"); |
| return VA_STATUS_ERROR_TIMEDOUT; |
| } |
| } |
| else |
| { |
| int64_t timeoutBoWait1 = 0; |
| int64_t timeoutBoWait2 = 0; |
| if (timeout_ns >= DDI_BO_MAX_TIMEOUT) |
| { |
| timeoutBoWait1 = DDI_BO_MAX_TIMEOUT - 1; |
| timeoutBoWait2 = timeout_ns - DDI_BO_MAX_TIMEOUT + 1; |
| } |
| else |
| { |
| timeoutBoWait1 = (int64_t)timeout_ns; |
| } |
| |
| // zero is a expected return value when not hit timeout |
| auto ret = mos_gem_bo_wait(buffer->bo, timeoutBoWait1); |
| if (0 != ret) |
| { |
| if (timeoutBoWait2) |
| { |
| ret = mos_gem_bo_wait(buffer->bo, timeoutBoWait2); |
| } |
| if (0 != ret) |
| { |
| DDI_NORMALMESSAGE("vaSyncBuffer: buffer is still used by HW\n\r"); |
| return VA_STATUS_ERROR_TIMEDOUT; |
| } |
| } |
| } |
| MOS_TraceEventExt(EVENT_VA_SYNC, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| #endif |
| /* |
| * Find out any pending ops on the render target |
| */ |
| static VAStatus DdiMedia_QuerySurfaceStatus ( |
| VADriverContextP ctx, |
| VASurfaceID render_target, |
| VASurfaceStatus *status |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(status, "nullptr status", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_LESS((uint32_t)render_target, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid render_target", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| if (surface->pCurrentFrameSemaphore) |
| { |
| if(DdiMediaUtil_TryWaitSemaphore(surface->pCurrentFrameSemaphore) == 0) |
| { |
| DdiMediaUtil_PostSemaphore(surface->pCurrentFrameSemaphore); |
| } |
| else |
| { |
| // Return busy state if the surface is not submitted |
| *status = VASurfaceRendering; |
| return VA_STATUS_SUCCESS; |
| } |
| } |
| |
| // Query the busy state of bo. |
| // check the bo here? |
| if(mos_bo_busy(surface->bo)) |
| { |
| // busy |
| *status = VASurfaceRendering; |
| } |
| else |
| { |
| // idle |
| *status = VASurfaceReady; |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Report MB error info |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] render_target |
| //! VA surface ID |
| //! \param [in] error_status |
| //! Error status |
| //! \param [out] error_info |
| //! Information on error |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_QuerySurfaceError( |
| VADriverContextP ctx, |
| VASurfaceID render_target, |
| VAStatus error_status, |
| void **error_info /*out*/ |
| ) |
| { |
| DDI_UNUSED(error_status); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL( ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT ); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL( mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, render_target); |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| PDDI_DECODE_CONTEXT decCtx = (PDDI_DECODE_CONTEXT)surface->pDecCtx; |
| DDI_CHK_NULL( decCtx, "nullptr surface->pDecCtx", VA_STATUS_ERROR_INVALID_CONTEXT ); |
| |
| VASurfaceDecodeMBErrors *surfaceErrors = decCtx->vaSurfDecErrOutput; |
| DDI_CHK_NULL(surfaceErrors , "nullptr surfaceErrors", VA_STATUS_ERROR_INVALID_CONTEXT ); |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->SurfaceMutex); |
| if (surface->curStatusReportQueryState == DDI_MEDIA_STATUS_REPORT_QUERY_STATE_COMPLETED) |
| { |
| if (error_status != -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER && |
| surface->curStatusReport.decode.status == CODECHAL_STATUS_ERROR) |
| { |
| surfaceErrors[1].status = -1; |
| surfaceErrors[0].status = 2; |
| surfaceErrors[0].start_mb = 0; |
| surfaceErrors[0].end_mb = 0; |
| surfaceErrors[0].num_mb = surface->curStatusReport.decode.errMbNum; |
| surfaceErrors[0].decode_error_type = VADecodeMBError; |
| *error_info = surfaceErrors; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| if (error_status == -1 && surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_DECODER) |
| //&& surface->curStatusReport.decode.status == CODECHAL_STATUS_SUCCESSFUL) // get the crc value whatever the status is |
| { |
| CodechalDecode *decoder = dynamic_cast<CodechalDecode *>(decCtx->pCodecHal); |
| |
| if (nullptr == decoder) |
| { |
| DDI_ASSERTMESSAGE("nullptr codechal decoder"); |
| vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; |
| } |
| else |
| { |
| if (decoder->GetStandard() != CODECHAL_AVC) |
| { |
| vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| else |
| { |
| *error_info = (void *)&surface->curStatusReport.decode.crcValue; |
| } |
| } |
| |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| return vaStatus; |
| } |
| |
| if (surface->curCtxType == DDI_MEDIA_CONTEXT_TYPE_VP && |
| surface->curStatusReport.vpp.status == CODECHAL_STATUS_ERROR) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| } |
| |
| surfaceErrors[0].status = -1; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->SurfaceMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief End picture process for cenc query |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] context |
| //! VA context ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| |
| /* |
| * Query surface attributes for the supplied config |
| */ |
| static VAStatus |
| DdiMedia_QuerySurfaceAttributes( |
| VADriverContextP ctx, |
| VAConfigID config_id, |
| VASurfaceAttrib *attrib_list, |
| uint32_t *num_attribs |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(num_attribs, "nullptr num_attribs", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| return mediaCtx->m_caps->QuerySurfaceAttributes(config_id, |
| attrib_list, num_attribs); |
| } |
| |
| static VAStatus DdiMedia_PutSurface( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| void* draw, /* Drawable of window system */ |
| int16_t srcx, |
| int16_t srcy, |
| uint16_t srcw, |
| uint16_t srch, |
| int16_t destx, |
| int16_t desty, |
| uint16_t destw, |
| uint16_t desth, |
| VARectangle *cliprects, /* client supplied clip list */ |
| uint32_t number_cliprects, /* number of clip rects in the clip list */ |
| uint32_t flags /* de-interlacing flags */ |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_PARAMETER); |
| if(number_cliprects > 0) |
| { |
| DDI_CHK_NULL(cliprects, "nullptr cliprects", VA_STATUS_ERROR_INVALID_PARAMETER); |
| } |
| |
| void *vpCtx = nullptr; |
| PDDI_MEDIA_CONTEXT mediaDrvCtx = DdiMedia_GetMediaContext(ctx); |
| |
| DDI_CHK_NULL(mediaDrvCtx, "nullptr mediaDrvCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaDrvCtx->pSurfaceHeap, "nullptr mediaDrvCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_LESS((uint32_t)surface, mediaDrvCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| if (nullptr != mediaDrvCtx->pVpCtxHeap->pHeapBase) |
| { |
| uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE; |
| vpCtx = DdiMedia_GetContextFromContextID(ctx, (VAContextID)(0 + DDI_MEDIA_VACONTEXTID_OFFSET_VP), &ctxType); |
| } |
| |
| #if defined(ANDROID) || !defined(X11_FOUND) |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| #else |
| if(nullptr == vpCtx) |
| { |
| VAContextID context = VA_INVALID_ID; |
| VAStatus vaStatus = DdiVp_CreateContext(ctx, 0, 0, 0, 0, 0, 0, &context); |
| DDI_CHK_RET(vaStatus, "Create VP Context failed"); |
| } |
| return DdiCodec_PutSurfaceLinuxHW(ctx, surface, draw, srcx, srcy, srcw, srch, destx, desty, destw, desth, cliprects, number_cliprects, flags); |
| #endif |
| |
| } |
| |
| /* List all the VAImageFormats supported during vaCreateSurfaces |
| * It can be used by vaQueryImageFormats and other functions |
| */ |
| /* |
| * Query supported image formats |
| * The caller must provide a "format_list" array that can hold at |
| * least vaMaxNumImageFormats() entries. The actual number of formats |
| * returned in "format_list" is returned in "num_formats". |
| */ |
| static VAStatus DdiMedia_QueryImageFormats ( |
| VADriverContextP ctx, |
| VAImageFormat *format_list, |
| int32_t *num_formats |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr pointer.", VA_STATUS_ERROR_INVALID_PARAMETER); |
| return mediaCtx->m_caps->QueryImageFormats(format_list, num_formats); |
| } |
| |
| //! |
| //! \brief Create an image |
| //! |
| //! \param [in] ctx |
| //! Driver context |
| //! \param [in] format |
| //! The format of image |
| //! \param [in] width |
| //! The width of the image |
| //! \param [in] height |
| //! The height of the image |
| //! \param [out] image |
| //! The generated image |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_CreateImage( |
| VADriverContextP ctx, |
| VAImageFormat *format, |
| int32_t width, |
| int32_t height, |
| VAImage *image /* out */ |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "Invalid context!", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(format, "Invalid format!", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(image, "Invalid image!", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(width, 0, "Invalid width!", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_LARGER(height, 0, "Invalid height!", VA_STATUS_ERROR_INVALID_PARAMETER); |
| int32_t event[] = {width, height, format->fourcc}; |
| MOS_TraceEventExt(EVENT_VA_IMAGE, EVENT_TYPE_START, event, sizeof(event), nullptr, 0); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(mediaCtx->pGmmClientContext, "nullptr mediaCtx->pGmmClientContext.", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| VAImage *vaimg = (VAImage*)MOS_AllocAndZeroMemory(sizeof(VAImage)); |
| DDI_CHK_NULL(vaimg, "Insufficient to allocate an VAImage.", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| GMM_RESCREATE_PARAMS gmmParams; |
| GMM_RESOURCE_INFO *gmmResourceInfo; |
| MOS_ZeroMemory(&gmmParams, sizeof(gmmParams)); |
| |
| gmmParams.BaseWidth = width; |
| gmmParams.BaseHeight = height; |
| gmmParams.ArraySize = 1; |
| gmmParams.Type = RESOURCE_2D; |
| gmmParams.Flags.Gpu.Video = true; |
| gmmParams.Format = mediaCtx->m_caps->ConvertFourccToGmmFmt(format->fourcc); |
| |
| if (gmmParams.Format == GMM_FORMAT_INVALID) |
| { |
| MOS_FreeMemory(vaimg); |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| gmmResourceInfo = mediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams); |
| if(nullptr == gmmResourceInfo) |
| { |
| DDI_ASSERTMESSAGE("Gmm Create Resource Failed."); |
| MOS_FreeMemory(vaimg); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| // Get offset from GMM |
| GMM_REQ_OFFSET_INFO reqInfo = {0}; |
| reqInfo.Plane = GMM_PLANE_U; |
| reqInfo.ReqRender = 1; |
| gmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetU = reqInfo.Render.Offset; |
| MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO)); |
| reqInfo.Plane = GMM_PLANE_V; |
| reqInfo.ReqRender = 1; |
| gmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetV = reqInfo.Render.Offset; |
| uint32_t size = (uint32_t)gmmResourceInfo->GetSizeSurface(); |
| uint32_t pitch = (uint32_t)gmmResourceInfo->GetRenderPitch(); |
| vaimg->format = *format; |
| vaimg->format.byte_order = VA_LSB_FIRST; |
| vaimg->width = width; |
| vaimg->height = height; |
| vaimg->data_size = size; |
| |
| mediaCtx->pGmmClientContext->DestroyResInfoObject(gmmResourceInfo); |
| |
| switch(format->fourcc) |
| { |
| case VA_FOURCC_RGBA: |
| case VA_FOURCC_BGRA: |
| case VA_FOURCC_ARGB: |
| case VA_FOURCC_ABGR: |
| case VA_FOURCC_BGRX: |
| case VA_FOURCC_RGBX: |
| case VA_FOURCC_XRGB: |
| case VA_FOURCC_XBGR: |
| case VA_FOURCC_A2R10G10B10: |
| case VA_FOURCC_A2B10G10R10: |
| case VA_FOURCC_X2R10G10B10: |
| case VA_FOURCC_X2B10G10R10: |
| case VA_FOURCC_R8G8B8: |
| case VA_FOURCC_RGB565: |
| case VA_FOURCC_UYVY: |
| case VA_FOURCC_YUY2: |
| case VA_FOURCC_VYUY: |
| case VA_FOURCC_YVYU: |
| case VA_FOURCC_AYUV: |
| case VA_FOURCC_Y210: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212: |
| #endif |
| case VA_FOURCC_Y216: |
| case VA_FOURCC_Y410: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y412: |
| #endif |
| case VA_FOURCC_Y416: |
| case VA_FOURCC_Y800: |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = pitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case VA_FOURCC_NV12: |
| case VA_FOURCC_NV21: |
| case VA_FOURCC_P010: |
| case VA_FOURCC_P012: |
| case VA_FOURCC_P016: |
| vaimg->num_planes = 2; |
| vaimg->pitches[0] = pitch; |
| vaimg->pitches[1] = pitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = offsetU; |
| break; |
| case VA_FOURCC_YV12: |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = pitch; |
| vaimg->pitches[1] = pitch / 2; |
| vaimg->pitches[2] = pitch / 2; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = offsetV; |
| vaimg->offsets[2] = offsetU; |
| break; |
| case VA_FOURCC_I420: |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = pitch; |
| vaimg->pitches[1] = pitch / 2; |
| vaimg->pitches[2] = pitch / 2; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = offsetU; |
| vaimg->offsets[2] = offsetV; |
| break; |
| case VA_FOURCC_IMC3: |
| case VA_FOURCC_411P: |
| case VA_FOURCC_422V: |
| case VA_FOURCC_422H: |
| case VA_FOURCC_444P: |
| case VA_FOURCC_RGBP: |
| case VA_FOURCC_BGRP: |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = pitch; |
| vaimg->pitches[1] = pitch; |
| vaimg->pitches[2] = pitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = offsetU; |
| vaimg->offsets[2] = offsetV; |
| break; |
| default: |
| MOS_FreeMemory(vaimg); |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| DDI_MEDIA_BUFFER *buf = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER)); |
| if (nullptr == buf) |
| { |
| MOS_FreeMemory(vaimg); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| buf->uiNumElements = 1; |
| buf->iSize = vaimg->data_size; |
| buf->uiType = VAImageBufferType; |
| buf->format = Media_Format_CPU;//DdiCodec_OsFormatToMediaFormat(vaimg->format.fourcc); //Media_Format_Buffer; |
| buf->uiOffset = 0; |
| buf->pMediaCtx = mediaCtx; |
| |
| //Put Image in untiled buffer for better CPU access? |
| VAStatus status= DdiMediaUtil_CreateBuffer(buf, mediaCtx->pDrmBufMgr); |
| if((status != VA_STATUS_SUCCESS)) |
| { |
| MOS_FreeMemory(vaimg); |
| MOS_FreeMemory(buf); |
| return status; |
| } |
| buf->TileType = I915_TILING_NONE; |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufferHeapElement = DdiMediaUtil_AllocPMediaBufferFromHeap(mediaCtx->pBufferHeap); |
| |
| if (nullptr == bufferHeapElement) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| MOS_FreeMemory(vaimg); |
| DdiMediaUtil_FreeBuffer(buf); |
| MOS_FreeMemory(buf); |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| |
| bufferHeapElement->pBuffer = buf; |
| bufferHeapElement->pCtx = nullptr; |
| bufferHeapElement->uiCtxType = DDI_MEDIA_CONTEXT_TYPE_MEDIA; |
| |
| vaimg->buf = bufferHeapElement->uiVaBufferID; |
| mediaCtx->uiNumBufs++; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex); |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT imageHeapElement = DdiMediaUtil_AllocPVAImageFromHeap(mediaCtx->pImageHeap); |
| if (nullptr == imageHeapElement) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex); |
| MOS_FreeMemory(vaimg); |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| imageHeapElement->pImage = vaimg; |
| mediaCtx->uiNumImages++; |
| vaimg->image_id = imageHeapElement->uiVaImageID; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex); |
| |
| *image = *vaimg; |
| MOS_TraceEventExt(EVENT_VA_IMAGE, EVENT_TYPE_END, &vaimg->image_id, sizeof(VAGenericID), nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Derive image |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] surface |
| //! VA surface ID |
| //! \param [in] image |
| //! VA image |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_DeriveImage ( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| VAImage *image |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_DERIVE, EVENT_TYPE_START, nullptr, 0, nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(image, "nullptr image", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| VAImage *vaimg = (VAImage*)MOS_AllocAndZeroMemory(sizeof(VAImage)); |
| DDI_CHK_NULL(vaimg, "nullptr vaimg", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| if (mediaSurface->pCurrentFrameSemaphore) |
| { |
| DdiMediaUtil_WaitSemaphore(mediaSurface->pCurrentFrameSemaphore); |
| DdiMediaUtil_PostSemaphore(mediaSurface->pCurrentFrameSemaphore); |
| } |
| DdiMediaUtil_LockMutex(&mediaCtx->ImageMutex); |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT imageHeapElement = DdiMediaUtil_AllocPVAImageFromHeap(mediaCtx->pImageHeap); |
| if (nullptr == imageHeapElement) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex); |
| MOS_FreeMemory(vaimg); |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| imageHeapElement->pImage = vaimg; |
| mediaCtx->uiNumImages++; |
| vaimg->image_id = imageHeapElement->uiVaImageID; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->ImageMutex); |
| |
| vaimg->format.fourcc = DdiMedia_MediaFormatToOsFormat(mediaSurface->format); |
| vaimg->width = mediaSurface->iWidth; |
| vaimg->height = mediaSurface->iRealHeight; |
| vaimg->format.byte_order = VA_LSB_FIRST; |
| |
| GMM_RESOURCE_INFO *gmmResourceInfo = mediaSurface->pGmmResourceInfo; |
| GMM_REQ_OFFSET_INFO reqInfo = {0}; |
| reqInfo.Plane = GMM_PLANE_U; |
| reqInfo.ReqRender = 1; |
| gmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetU = reqInfo.Render.Offset; |
| MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO)); |
| reqInfo.Plane = GMM_PLANE_V; |
| reqInfo.ReqRender = 1; |
| gmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetV = reqInfo.Render.Offset; |
| vaimg->data_size = (uint32_t)gmmResourceInfo->GetSizeSurface(); |
| |
| switch( mediaSurface->format ) |
| { |
| case Media_Format_YV12: |
| case Media_Format_I420: |
| vaimg->format.bits_per_pixel = 12; |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch / 2; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = vaimg->offsets[1] + vaimg->pitches[1] * MOS_ALIGN_CEIL(mediaSurface->iHeight, 2) / 2; |
| break; |
| case Media_Format_A8B8G8R8: |
| case Media_Format_R8G8B8A8: |
| case Media_Format_A8R8G8B8: |
| vaimg->format.bits_per_pixel = 32; |
| vaimg->format.alpha_mask = RGB_8BIT_ALPHAMASK; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_X8R8G8B8: |
| case Media_Format_X8B8G8R8: |
| vaimg->format.bits_per_pixel = 32; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_R10G10B10A2: |
| case Media_Format_B10G10R10A2: |
| vaimg->format.bits_per_pixel = 32; |
| vaimg->format.alpha_mask = RGB_10BIT_ALPHAMASK; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_R10G10B10X2: |
| case Media_Format_B10G10R10X2: |
| vaimg->format.bits_per_pixel = 32; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_R5G6B5: |
| vaimg->format.bits_per_pixel = 16; |
| vaimg->data_size = mediaSurface->iPitch * mediaSurface->iHeight; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_R8G8B8: |
| vaimg->format.bits_per_pixel = 24; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_YUY2: |
| case Media_Format_UYVY: |
| vaimg->format.bits_per_pixel = 16; |
| vaimg->data_size = mediaSurface->iPitch * mediaSurface->iHeight; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_400P: |
| vaimg->format.bits_per_pixel = 8; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| case Media_Format_444P: |
| case Media_Format_RGBP: |
| case Media_Format_BGRP: |
| vaimg->format.bits_per_pixel = 24; |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = mediaSurface->iHeight * mediaSurface->iPitch * 2; |
| break; |
| case Media_Format_IMC3: |
| vaimg->format.bits_per_pixel = 12; |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = mediaSurface->iHeight * mediaSurface->iPitch * 3 / 2; |
| break; |
| case Media_Format_411P: |
| vaimg->format.bits_per_pixel = 12; |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = mediaSurface->iHeight * mediaSurface->iPitch * 2; |
| break; |
| case Media_Format_422V: |
| vaimg->format.bits_per_pixel = 16; |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = mediaSurface->iHeight * mediaSurface->iPitch * 3 / 2; |
| break; |
| case Media_Format_422H: |
| vaimg->format.bits_per_pixel = 16; |
| vaimg->num_planes = 3; |
| vaimg->pitches[0] = |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = mediaSurface->iHeight * mediaSurface->iPitch * 2; |
| break; |
| case Media_Format_P010: |
| case Media_Format_P012: |
| case Media_Format_P016: |
| vaimg->format.bits_per_pixel = 24; |
| vaimg->num_planes = 2; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = vaimg->offsets[1] + 2; |
| break; |
| case Media_Format_Y410: |
| case Media_Format_AYUV: |
| case Media_Format_Y210: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y212: |
| #endif |
| case Media_Format_Y216: |
| vaimg->format.bits_per_pixel = 32; |
| vaimg->data_size = mediaSurface->iPitch * mediaSurface->iHeight; |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y412: |
| #endif |
| case Media_Format_Y416: |
| vaimg->format.bits_per_pixel = 64; // packed format [alpha, Y, U, V], 16 bits per channel |
| vaimg->num_planes = 1; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| break; |
| default: |
| vaimg->format.bits_per_pixel = 12; |
| vaimg->num_planes = 2; |
| vaimg->pitches[0] = mediaSurface->iPitch; |
| vaimg->pitches[1] = |
| vaimg->pitches[2] = mediaSurface->iPitch; |
| vaimg->offsets[0] = 0; |
| if(MEDIA_IS_WA(&mediaCtx->WaTable, WaDisableGmmLibOffsetInDeriveImage)) |
| { |
| vaimg->offsets[1] = mediaSurface->iHeight * mediaSurface->iPitch; |
| vaimg->offsets[2] = vaimg->offsets[1] + 1; |
| } |
| else |
| { |
| vaimg->offsets[1] = offsetU; |
| vaimg->offsets[2] = offsetV; |
| } |
| break; |
| } |
| |
| mediaCtx->m_caps->PopulateColorMaskInfo(&vaimg->format); |
| |
| DDI_MEDIA_BUFFER *buf = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER)); |
| if (buf == nullptr) |
| { |
| MOS_FreeMemory(vaimg); |
| MOS_FreeMemory(buf); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| buf->uiNumElements = 1; |
| buf->iSize = vaimg->data_size; |
| buf->uiType = VAImageBufferType; |
| buf->format = mediaSurface->format; |
| buf->uiOffset = 0; |
| |
| buf->bo = mediaSurface->bo; |
| buf->format = mediaSurface->format; |
| buf->TileType = mediaSurface->TileType; |
| buf->pSurface = mediaSurface; |
| mos_bo_reference(mediaSurface->bo); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT bufferHeapElement = DdiMediaUtil_AllocPMediaBufferFromHeap(mediaCtx->pBufferHeap); |
| |
| if (nullptr == bufferHeapElement) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| MOS_FreeMemory(vaimg); |
| MOS_FreeMemory(buf); |
| return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; |
| } |
| bufferHeapElement->pBuffer = buf; |
| bufferHeapElement->pCtx = nullptr; |
| bufferHeapElement->uiCtxType = DDI_MEDIA_CONTEXT_TYPE_MEDIA; |
| |
| vaimg->buf = bufferHeapElement->uiVaBufferID; |
| mediaCtx->uiNumBufs++; |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| |
| *image = *vaimg; |
| |
| MOS_TraceEventExt(EVENT_VA_DERIVE, EVENT_TYPE_END, &surface, sizeof(surface), &vaimg->image_id, sizeof(VAGenericID)); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Free allocated surfaceheap elements |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] image |
| //! VA image ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_DestroyImage ( |
| VADriverContextP ctx, |
| VAImageID image) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_FREE_IMAGE, EVENT_TYPE_START, &image, sizeof(image), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| |
| DDI_CHK_NULL(mediaCtx, "nullptr Media", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pImageHeap, "nullptr mediaCtx->pImageHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)image, mediaCtx->pImageHeap->uiAllocatedHeapElements, "Invalid image", VA_STATUS_ERROR_INVALID_IMAGE); |
| |
| VAImage *vaImage = DdiMedia_GetVAImageFromVAImageID(mediaCtx, image); |
| if (vaImage == nullptr) |
| { |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| DdiMedia_DestroyBuffer(ctx, vaImage->buf); |
| MOS_FreeMemory(vaImage); |
| |
| DdiMedia_DestroyImageFromVAImageID(mediaCtx, image); |
| |
| MOS_TraceEventExt(EVENT_VA_FREE_IMAGE, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Set image palette |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] image |
| //! VA image ID |
| //! \param [in] palette |
| //! Palette |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED if call success, else fail reason |
| //! |
| VAStatus DdiMedia_SetImagePalette( |
| VADriverContextP ctx, |
| VAImageID image, |
| unsigned char *palette |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(image); |
| DDI_UNUSED(palette); |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| VAStatus SwizzleSurface(PDDI_MEDIA_CONTEXT mediaCtx, PGMM_RESOURCE_INFO pGmmResInfo, void *pLockedAddr, uint32_t TileType, uint8_t* pResourceBase, bool bUpload) |
| { |
| uint32_t uiSize, uiPitch; |
| GMM_RES_COPY_BLT gmmResCopyBlt; |
| uint32_t uiPicHeight; |
| uint32_t ulSwizzledSize; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| DDI_CHK_NULL(pGmmResInfo, "pGmmResInfo is NULL", VA_STATUS_ERROR_OPERATION_FAILED); |
| DDI_CHK_NULL(pLockedAddr, "pLockedAddr is NULL", VA_STATUS_ERROR_OPERATION_FAILED); |
| DDI_CHK_NULL(pResourceBase, "pResourceBase is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| memset(&gmmResCopyBlt, 0x0, sizeof(GMM_RES_COPY_BLT)); |
| uiPicHeight = pGmmResInfo->GetBaseHeight(); |
| uiSize = pGmmResInfo->GetSizeSurface(); |
| uiPitch = pGmmResInfo->GetRenderPitch(); |
| gmmResCopyBlt.Gpu.pData = pLockedAddr; |
| gmmResCopyBlt.Sys.pData = pResourceBase; |
| gmmResCopyBlt.Sys.RowPitch = uiPitch; |
| gmmResCopyBlt.Sys.BufferSize = uiSize; |
| gmmResCopyBlt.Sys.SlicePitch = uiSize; |
| gmmResCopyBlt.Blt.Slices = 1; |
| gmmResCopyBlt.Blt.Upload = bUpload; |
| |
| if(mediaCtx->pGmmClientContext->IsPlanar(pGmmResInfo->GetResourceFormat()) == true) |
| { |
| gmmResCopyBlt.Blt.Width = pGmmResInfo->GetBaseWidth(); |
| gmmResCopyBlt.Blt.Height = uiSize/uiPitch; |
| } |
| |
| pGmmResInfo->CpuBlt(&gmmResCopyBlt); |
| |
| return vaStatus; |
| } |
| |
| //! |
| //! \brief Copy plane from src to dst row by row when src and dst strides are different |
| //! |
| //! \param [in] dst |
| //! Destination plane |
| //! \param [in] dstPitch |
| //! Destination plane pitch |
| //! \param [in] src |
| //! Source plane |
| //! \param [in] srcPitch |
| //! Source plane pitch |
| //! \param [in] height |
| //! Plane hight |
| //! |
| static void DdiMedia_CopyPlane( |
| uint8_t *dst, |
| uint32_t dstPitch, |
| uint8_t *src, |
| uint32_t srcPitch, |
| uint32_t height) |
| { |
| uint32_t rowSize = std::min(dstPitch, srcPitch); |
| for (int y = 0; y < height; y += 1) |
| { |
| memcpy(dst, src, rowSize); |
| dst += dstPitch; |
| src += srcPitch; |
| } |
| } |
| |
| //! |
| //! \brief Copy data from surface to image |
| //! |
| //! \param [in] ctx |
| //! Input driver context |
| //! \param [in] surface |
| //! Pointer to surface |
| //! \param [in] image |
| //! Pointer to image |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| static VAStatus DdiMedia_CopySurfaceToImage( |
| VADriverContextP ctx, |
| DDI_MEDIA_SURFACE *surface, |
| VAImage *image) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(surface, "nullptr meida surface.", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| //Lock Surface |
| if ((Media_Format_CPU != surface->format)) |
| { |
| vaStatus = DdiMedia_MediaMemoryDecompress(mediaCtx, surface); |
| |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_NORMALMESSAGE("surface Decompression fail, continue next steps."); |
| } |
| } |
| void *surfData = DdiMediaUtil_LockSurface(surface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_NO_SWIZZLE)); |
| if (surfData == nullptr) |
| { |
| DDI_ASSERTMESSAGE("nullptr surfData."); |
| return vaStatus; |
| } |
| |
| void *imageData = nullptr; |
| vaStatus = DdiMedia_MapBuffer(ctx, image->buf, &imageData); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Failed to map buffer."); |
| DdiMediaUtil_UnlockSurface(surface); |
| return vaStatus; |
| } |
| |
| uint8_t *ySrc = nullptr; |
| uint8_t *yDst = (uint8_t*)imageData; |
| uint8_t *swizzleData = (uint8_t*)MOS_AllocMemory(surface->data_size); |
| |
| if (!surface->pMediaCtx->bIsAtomSOC && surface->TileType != I915_TILING_NONE) |
| { |
| SwizzleSurface(surface->pMediaCtx, surface->pGmmResourceInfo, surfData, (MOS_TILE_TYPE)surface->TileType, (uint8_t *)swizzleData, false); |
| ySrc = swizzleData; |
| } |
| else |
| { |
| ySrc = (uint8_t*)surfData; |
| } |
| |
| DdiMedia_CopyPlane(yDst, image->pitches[0], ySrc, surface->iPitch, image->height); |
| if (image->num_planes > 1) |
| { |
| uint8_t *uSrc = ySrc + surface->iPitch * surface->iHeight; |
| uint8_t *uDst = yDst + image->offsets[1]; |
| uint32_t chromaPitch = 0; |
| uint32_t chromaHeight = 0; |
| uint32_t imageChromaPitch = 0; |
| uint32_t imageChromaHeight = 0; |
| DdiMedia_GetChromaPitchHeight(DdiMedia_MediaFormatToOsFormat(surface->format), surface->iPitch, surface->iHeight, &chromaPitch, &chromaHeight); |
| DdiMedia_GetChromaPitchHeight(image->format.fourcc, image->pitches[0], image->height, &imageChromaPitch, &imageChromaHeight); |
| DdiMedia_CopyPlane(uDst, image->pitches[1], uSrc, chromaPitch, imageChromaHeight); |
| |
| if(image->num_planes > 2) |
| { |
| uint8_t *vSrc = uSrc + chromaPitch * chromaHeight; |
| uint8_t *vDst = yDst + image->offsets[2]; |
| DdiMedia_CopyPlane(vDst, image->pitches[2], vSrc, chromaPitch, imageChromaHeight); |
| } |
| } |
| |
| MOS_FreeMemory(swizzleData); |
| |
| vaStatus = DdiMedia_UnmapBuffer(ctx, image->buf); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Failed to unmap buffer."); |
| DdiMediaUtil_UnlockSurface(surface); |
| return vaStatus; |
| } |
| |
| DdiMediaUtil_UnlockSurface(surface); |
| |
| return vaStatus; |
| } |
| |
| //! |
| //! \brief Retrive surface data into a VAImage |
| //! \details Image must be in a format supported by the implementation |
| //! |
| //! \param [in] ctx |
| //! Input driver context |
| //! \param [in] surface |
| //! Input surface ID of source |
| //! \param [in] x |
| //! X offset of the wanted region |
| //! \param [in] y |
| //! Y offset of the wanted region |
| //! \param [in] width |
| //! Width of the wanted region |
| //! \param [in] height |
| //! Height of the wanted region |
| //! \param [in] image |
| //! The image ID of the source image |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_GetImage( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| int32_t x, /* coordinates of the upper left source pixel */ |
| int32_t y, |
| uint32_t width, /* width and height of the region */ |
| uint32_t height, |
| VAImageID image |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| uint32_t event[] = {surface, x, y, width, height, image}; |
| MOS_TraceEventExt(EVENT_VA_GET, EVENT_TYPE_START, &event, sizeof(event), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pImageHeap, "nullptr mediaCtx->pImageHeap.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface.", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_LESS((uint32_t)image, mediaCtx->pImageHeap->uiAllocatedHeapElements, "Invalid image.", VA_STATUS_ERROR_INVALID_IMAGE); |
| |
| VAImage *vaimg = DdiMedia_GetVAImageFromVAImageID(mediaCtx, image); |
| DDI_CHK_NULL(vaimg, "nullptr vaimg.", VA_STATUS_ERROR_INVALID_IMAGE); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, vaimg->buf); |
| DDI_CHK_NULL(buf, "nullptr buf.", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| DDI_MEDIA_SURFACE *inputSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface); |
| DDI_CHK_NULL(inputSurface, "nullptr inputSurface.", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(inputSurface->bo, "nullptr inputSurface->bo.", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| #ifndef _FULL_OPEN_SOURCE |
| VASurfaceID target_surface = VA_INVALID_SURFACE; |
| VASurfaceID output_surface = surface; |
| |
| if (inputSurface->format != DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.alpha_mask) || |
| width != vaimg->width || height != vaimg->height || |
| (MEDIA_IS_WA(&mediaCtx->WaTable, WaEnableVPPCopy) && |
| vaimg->format.fourcc != VA_FOURCC_444P && |
| vaimg->format.fourcc != VA_FOURCC_422V && |
| vaimg->format.fourcc != VA_FOURCC_422H)) |
| { |
| VAContextID context = VA_INVALID_ID; |
| //Create VP Context. |
| vaStatus = DdiVp_CreateContext(ctx, 0, 0, 0, 0, 0, 0, &context); |
| DDI_CHK_RET(vaStatus, "Create VP Context failed."); |
| |
| //Create target surface for VP pipeline. |
| DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.fourcc); |
| if (mediaFmt == Media_Format_Count) |
| { |
| DDI_ASSERTMESSAGE("Unsupported surface type."); |
| DdiVp_DestroyContext(ctx, context); |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| PDDI_MEDIA_SURFACE_DESCRIPTOR surfDesc = (PDDI_MEDIA_SURFACE_DESCRIPTOR)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_SURFACE_DESCRIPTOR)); |
| if (!surfDesc) { |
| DDI_ASSERTMESSAGE("nullptr surfDesc."); |
| DdiVp_DestroyContext(ctx, context); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| surfDesc->uiVaMemType = VA_SURFACE_ATTRIB_MEM_TYPE_VA; |
| int memType = MOS_MEMPOOL_VIDEOMEMORY; |
| if (MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory)) |
| { |
| memType = MOS_MEMPOOL_SYSTEMMEMORY; |
| } |
| target_surface = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaCtx, mediaFmt, vaimg->width, vaimg->height, surfDesc, VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC, memType); |
| if (VA_INVALID_SURFACE == target_surface) |
| { |
| DDI_ASSERTMESSAGE("Create temp surface failed."); |
| DdiVp_DestroyContext(ctx, context); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| VARectangle srcRect, dstRect; |
| srcRect.x = x; |
| srcRect.y = y; |
| srcRect.width = width; |
| srcRect.height = height; |
| dstRect.x = 0; |
| dstRect.y = 0; |
| dstRect.width = vaimg->width; |
| dstRect.height = vaimg->height; |
| |
| //Execute VP pipeline. |
| vaStatus = DdiVp_VideoProcessPipeline(ctx, context, surface, &srcRect, target_surface, &dstRect); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("VP Pipeline failed."); |
| DdiMedia_DestroySurfaces(ctx, &target_surface, 1); |
| DdiVp_DestroyContext(ctx, context); |
| return vaStatus; |
| } |
| vaStatus = DdiMedia_SyncSurface(ctx, target_surface); |
| vaStatus = DdiVp_DestroyContext(ctx, context); |
| output_surface = target_surface; |
| } |
| |
| //Get Media Surface from output surface ID |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, output_surface); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(mediaSurface->bo, "nullptr mediaSurface->bo.", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| vaStatus = DdiMedia_CopySurfaceToImage(ctx, mediaSurface, vaimg); |
| |
| if (vaStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Failed to copy surface to image buffer data!"); |
| if(target_surface != VA_INVALID_SURFACE) |
| { |
| DdiMedia_DestroySurfaces(ctx, &target_surface, 1); |
| } |
| return vaStatus; |
| } |
| |
| //Destroy temp surface if created |
| if(target_surface != VA_INVALID_SURFACE) |
| { |
| DdiMedia_DestroySurfaces(ctx, &target_surface, 1); |
| } |
| #else |
| vaStatus = DdiMedia_CopySurfaceToImage(ctx, inputSurface, vaimg); |
| DDI_CHK_RET(vaStatus, "Copy surface to image failed."); |
| #endif |
| MOS_TraceEventExt(EVENT_VA_GET, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Copy data from a VAImage to a surface |
| //! \details Image must be in a format supported by the implementation |
| //! |
| //! \param [in] ctx |
| //! Input driver context |
| //! \param [in] surface |
| //! Surface ID of destination |
| //! \param [in] image |
| //! The image ID of the destination image |
| //! \param [in] src_x |
| //! Source x offset of the image region |
| //! \param [in] src_y |
| //! Source y offset of the image region |
| //! \param [in] src_width |
| //! Source width offset of the image region |
| //! \param [in] src_height |
| //! Source height offset of the image region |
| //! \param [in] dest_x |
| //! Destination x offset of the surface region |
| //! \param [in] dest_y |
| //! Destination y offset of the surface region |
| //! \param [in] dest_width |
| //! Destination width offset of the surface region |
| //! \param [in] dest_height |
| //! Destination height offset of the surface region |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_PutImage( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| VAImageID image, |
| int32_t src_x, |
| int32_t src_y, |
| uint32_t src_width, |
| uint32_t src_height, |
| int32_t dest_x, |
| int32_t dest_y, |
| uint32_t dest_width, |
| uint32_t dest_height |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| uint32_t event[] = {surface, image, src_x, src_y, src_width, src_height, dest_x, dest_y, dest_width, dest_height}; |
| MOS_TraceEventExt(EVENT_VA_PUT, EVENT_TYPE_START, &event, sizeof(event), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pImageHeap, "nullptr mediaCtx->pImageHeap.", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface.", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_LESS((uint32_t)image, mediaCtx->pImageHeap->uiAllocatedHeapElements, "Invalid image.", VA_STATUS_ERROR_INVALID_IMAGE); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(mediaSurface->bo, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| if (mediaSurface->pCurrentFrameSemaphore) |
| { |
| DdiMediaUtil_WaitSemaphore(mediaSurface->pCurrentFrameSemaphore); |
| DdiMediaUtil_PostSemaphore(mediaSurface->pCurrentFrameSemaphore); |
| } |
| |
| VAImage *vaimg = DdiMedia_GetVAImageFromVAImageID(mediaCtx, image); |
| DDI_CHK_NULL(vaimg, "Invalid image.", VA_STATUS_ERROR_INVALID_IMAGE); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, vaimg->buf); |
| DDI_CHK_NULL(buf, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| void *imageData = nullptr; |
| |
| vaStatus = DdiMedia_MapBuffer(ctx, vaimg->buf, &imageData); |
| DDI_CHK_RET(vaStatus, "MapBuffer failed."); |
| DDI_CHK_NULL(imageData, "nullptr imageData.", VA_STATUS_ERROR_INVALID_IMAGE); |
| |
| // VP Pipeline will be called for CSC/Scaling if the surface format or data size is not consistent with image. |
| if (mediaSurface->format != DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.alpha_mask) || |
| dest_width != src_width || dest_height != src_height || |
| src_x != 0 || dest_x != 0 || src_y != 0 || dest_y != 0) |
| { |
| VAContextID context = VA_INVALID_ID; |
| |
| //Create VP Context. |
| vaStatus = DdiVp_CreateContext(ctx, 0, 0, 0, 0, 0, 0, &context); |
| DDI_CHK_RET(vaStatus, "Create VP Context failed"); |
| |
| //Create temp surface for VP pipeline. |
| DDI_MEDIA_FORMAT mediaFmt = DdiMedia_OsFormatToMediaFormat(vaimg->format.fourcc, vaimg->format.fourcc); |
| if (mediaFmt == Media_Format_Count) |
| { |
| DDI_ASSERTMESSAGE("Unsupported surface type."); |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| |
| int memType = MOS_MEMPOOL_VIDEOMEMORY; |
| if (MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory)) |
| { |
| memType = MOS_MEMPOOL_SYSTEMMEMORY; |
| } |
| VASurfaceID tempSurface = (VASurfaceID)DdiMedia_CreateRenderTarget(mediaCtx, mediaFmt, vaimg->width, vaimg->height, nullptr, VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ, memType); |
| if (tempSurface == VA_INVALID_ID) |
| { |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| DDI_MEDIA_SURFACE *tempMediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, tempSurface); |
| DDI_CHK_NULL(tempMediaSurface, "nullptr tempMediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| //Lock Surface |
| void *tempSurfData = DdiMediaUtil_LockSurface(tempMediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY)); |
| if (nullptr == tempSurfData) |
| { |
| DdiMedia_DestroySurfaces(ctx, &tempSurface, 1); |
| return VA_STATUS_ERROR_SURFACE_BUSY; |
| } |
| |
| //Copy data from image to temp surferce |
| MOS_STATUS eStatus = MOS_SecureMemcpy(tempSurfData, vaimg->data_size, imageData, vaimg->data_size); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Failed to copy image to surface buffer."); |
| DdiMediaUtil_UnlockSurface(tempMediaSurface); |
| DdiMedia_DestroySurfaces(ctx, &tempSurface, 1); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| vaStatus = DdiMedia_UnmapBuffer(ctx, vaimg->buf); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Failed to unmap buffer."); |
| DdiMediaUtil_UnlockSurface(tempMediaSurface); |
| DdiMedia_DestroySurfaces(ctx, &tempSurface, 1); |
| return vaStatus; |
| } |
| |
| DdiMediaUtil_UnlockSurface(tempMediaSurface); |
| |
| VARectangle srcRect, dstRect; |
| srcRect.x = src_x; |
| srcRect.y = src_y; |
| srcRect.width = src_width; |
| srcRect.height = src_height; |
| dstRect.x = dest_x; |
| dstRect.y = dest_y; |
| dstRect.width = dest_width; |
| dstRect.height = dest_height; |
| |
| //Execute VP pipeline. |
| vaStatus = DdiVp_VideoProcessPipeline(ctx, context, tempSurface, &srcRect, surface, &dstRect); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("VP Pipeline failed."); |
| DdiMedia_DestroySurfaces(ctx, &tempSurface, 1); |
| return vaStatus; |
| } |
| |
| vaStatus = DdiMedia_SyncSurface(ctx, tempSurface); |
| DdiMedia_DestroySurfaces(ctx, &tempSurface, 1); |
| vaStatus = DdiVp_DestroyContext(ctx, context); |
| } |
| else |
| { |
| //Lock Surface |
| if ((nullptr != buf->pSurface) && (Media_Format_CPU != mediaSurface->format)) |
| { |
| vaStatus = DdiMedia_MediaMemoryDecompress(mediaCtx, mediaSurface); |
| |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_NORMALMESSAGE("surface Decompression fail, continue next steps."); |
| } |
| } |
| |
| void *surfData = DdiMediaUtil_LockSurface(mediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY)); |
| if (nullptr == surfData) |
| { |
| DDI_ASSERTMESSAGE("Failed to lock surface."); |
| return VA_STATUS_ERROR_SURFACE_BUSY; |
| } |
| |
| if (src_width == dest_width && src_height == dest_height && |
| src_width == vaimg->width && src_height == vaimg->height && |
| src_width == mediaSurface->iWidth && src_height == mediaSurface->iHeight && |
| mediaSurface->data_size == vaimg->data_size) |
| { |
| //Copy data from image to surface |
| MOS_STATUS eStatus = MOS_SecureMemcpy(surfData, vaimg->data_size, imageData, vaimg->data_size); |
| DDI_CHK_CONDITION((eStatus != MOS_STATUS_SUCCESS), "Failed to copy image to surface buffer.", VA_STATUS_ERROR_OPERATION_FAILED); |
| } |
| else |
| { |
| uint8_t *ySrc = (uint8_t *)imageData + vaimg->offsets[0]; |
| uint8_t *yDst = (uint8_t *)surfData; |
| DdiMedia_CopyPlane(yDst, mediaSurface->iPitch, ySrc, vaimg->pitches[0], src_height); |
| |
| if (vaimg->num_planes > 1) |
| { |
| DDI_MEDIA_SURFACE uPlane = *mediaSurface; |
| |
| uPlane.iWidth = src_width; |
| uPlane.iRealHeight = src_height; |
| uPlane.iHeight = src_height; |
| uint32_t chromaHeight = 0; |
| uint32_t chromaPitch = 0; |
| DdiMedia_GetChromaPitchHeight(DdiMedia_MediaFormatToOsFormat(uPlane.format), uPlane.iPitch, uPlane.iHeight, &chromaPitch, &chromaHeight); |
| |
| uint8_t *uSrc = (uint8_t *)imageData + vaimg->offsets[1]; |
| uint8_t *uDst = yDst + mediaSurface->iPitch * mediaSurface->iHeight; |
| DdiMedia_CopyPlane(uDst, chromaPitch, uSrc, vaimg->pitches[1], chromaHeight); |
| if (vaimg->num_planes > 2) |
| { |
| uint8_t *vSrc = (uint8_t *)imageData + vaimg->offsets[2]; |
| uint8_t *vDst = uDst + chromaPitch * chromaHeight; |
| DdiMedia_CopyPlane(vDst, chromaPitch, vSrc, vaimg->pitches[2], chromaHeight); |
| } |
| } |
| } |
| |
| vaStatus = DdiMedia_UnmapBuffer(ctx, vaimg->buf); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Failed to unmap buffer."); |
| DdiMediaUtil_UnlockSurface(mediaSurface); |
| return vaStatus; |
| } |
| |
| DdiMediaUtil_UnlockSurface(mediaSurface); |
| } |
| MOS_TraceEventExt(EVENT_VA_PUT, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Query subpicture formats |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] format_list |
| //! VA image format |
| //! \param [in] flags |
| //! Flags |
| //! \param [in] num_formats |
| //! Number of formats |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_QuerySubpictureFormats( |
| VADriverContextP ctx, |
| VAImageFormat *format_list, |
| uint32_t *flags, |
| uint32_t *num_formats) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(format_list); |
| DDI_UNUSED(flags); |
| DDI_UNUSED(num_formats); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Create subpicture |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] image |
| //! VA image ID |
| //! \param [out] subpicture |
| //! VA subpicture ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_CreateSubpicture( |
| VADriverContextP ctx, |
| VAImageID image, |
| VASubpictureID *subpicture /* out */ |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(image); |
| DDI_UNUSED(subpicture); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Destroy subpicture |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] subpicture |
| //! VA subpicture ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_DestroySubpicture( |
| VADriverContextP ctx, |
| VASubpictureID subpicture |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(subpicture); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Set subpicture image |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] subpicture |
| //! VA subpicture ID |
| //! \param [in] image |
| //! VA image ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_SetSubpictureImage( |
| VADriverContextP ctx, |
| VASubpictureID subpicture, |
| VAImageID image |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(subpicture); |
| DDI_UNUSED(image); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Set subpicture chrome key |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] subpicture |
| //! VA subpicture ID |
| //! \param [in] chromakey_min |
| //! Minimum chroma key |
| //! \param [in] chromakey_max |
| //! Maximum chroma key |
| //! \param [in] chromakey_mask |
| //! Chromakey mask |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_SetSubpictureChromakey( |
| VADriverContextP ctx, |
| VASubpictureID subpicture, |
| uint32_t chromakey_min, |
| uint32_t chromakey_max, |
| uint32_t chromakey_mask |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(subpicture); |
| DDI_UNUSED(chromakey_min); |
| DDI_UNUSED(chromakey_max); |
| DDI_UNUSED(chromakey_mask); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief set subpicture global alpha |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] subpicture |
| //! VA subpicture ID |
| //! \param [in] global_alpha |
| //! Global alpha |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| VAStatus DdiMedia_SetSubpictureGlobalAlpha( |
| VADriverContextP ctx, |
| VASubpictureID subpicture, |
| float global_alpha |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(subpicture); |
| DDI_UNUSED(global_alpha); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Associate subpicture |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] subpicture |
| //! VA subpicture ID |
| //! \param [in] target_surfaces |
| //! VA surface ID |
| //! \param [in] num_surfaces |
| //! Number of surfaces |
| //! \param [in] src_x |
| //! Source x of the region |
| //! \param [in] src_y |
| //! Source y of the region |
| //! \param [in] src_width |
| //! Source width of the region |
| //! \param [in] src_height |
| //! Source height of the region |
| //! \param [in] dest_x |
| //! Destination x |
| //! \param [in] dest_y |
| //! Destination y |
| //! \param [in] dest_width |
| //! Destination width |
| //! \param [in] dest_height |
| //! Destination height |
| //! \param [in] flags |
| //! Flags |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_AssociateSubpicture( |
| VADriverContextP ctx, |
| VASubpictureID subpicture, |
| VASurfaceID *target_surfaces, |
| int32_t num_surfaces, |
| int16_t src_x, /* upper left offset in subpicture */ |
| int16_t src_y, |
| uint16_t src_width, |
| uint16_t src_height, |
| int16_t dest_x, /* upper left offset in surface */ |
| int16_t dest_y, |
| uint16_t dest_width, |
| uint16_t dest_height, |
| /* |
| * whether to enable chroma-keying or global-alpha |
| * see VA_SUBPICTURE_XXX values |
| */ |
| uint32_t flags |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(subpicture); |
| DDI_UNUSED(target_surfaces); |
| DDI_UNUSED(num_surfaces); |
| DDI_UNUSED(src_x); |
| DDI_UNUSED(src_y); |
| DDI_UNUSED(src_width); |
| DDI_UNUSED(src_height); |
| DDI_UNUSED(dest_x); |
| DDI_UNUSED(dest_y); |
| DDI_UNUSED(dest_width); |
| DDI_UNUSED(dest_height); |
| DDI_UNUSED(flags); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Deassociate subpicture |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] subpicture |
| //! VA subpicture ID |
| //! \param [in] target_surfaces |
| //! VA surface ID |
| //! \param [in] num_surfaces |
| //! Number of surfaces |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_DeassociateSubpicture( |
| VADriverContextP ctx, |
| VASubpictureID subpicture, |
| VASurfaceID *target_surfaces, |
| int32_t num_surfaces |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(subpicture); |
| DDI_UNUSED(target_surfaces); |
| DDI_UNUSED(num_surfaces); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Query display attributes |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] attr_list |
| //! VA display attribute |
| //! \param [in] num_attributes |
| //! Number of attributes |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_QueryDisplayAttributes( |
| VADriverContextP ctx, |
| VADisplayAttribute *attr_list, |
| int32_t *num_attributes) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(attr_list); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| if (num_attributes) |
| *num_attributes = 0; |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get display attributes |
| //! \details This function returns the current attribute values in "attr_list". |
| //! Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field |
| //! from vaQueryDisplayAttributes() can have their values retrieved. |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] attr_list |
| //! VA display attribute |
| //! \param [in] num_attributes |
| //! Number of attributes |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_GetDisplayAttributes( |
| VADriverContextP ctx, |
| VADisplayAttribute *attr_list, |
| int32_t num_attributes) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(attr_list); |
| DDI_UNUSED(num_attributes); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Set display attributes |
| //! \details Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field |
| //! from vaQueryDisplayAttributes() can be set. If the attribute is not settable or |
| //! the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] attr_list |
| //! VA display attribute |
| //! \param [in] num_attributes |
| //! Number of attributes |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_ERROR_UNIMPLEMENTED |
| //! |
| VAStatus DdiMedia_SetDisplayAttributes( |
| VADriverContextP ctx, |
| VADisplayAttribute *attr_list, |
| int32_t num_attributes) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(attr_list); |
| DDI_UNUSED(num_attributes); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| return VA_STATUS_ERROR_UNIMPLEMENTED; |
| } |
| |
| //! |
| //! \brief Query processing rate |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] config_id |
| //! VA configuration ID |
| //! \param [in] proc_buf |
| //! VA processing rate parameter |
| //! \param [out] processing_rate |
| //! Processing rate |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus |
| DdiMedia_QueryProcessingRate( |
| VADriverContextP ctx, |
| VAConfigID config_id, |
| VAProcessingRateParameter *proc_buf, |
| uint32_t *processing_rate /* output parameter */) |
| { |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(proc_buf, "nullptr proc_buf", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(processing_rate, "nullptr processing_rate", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->m_caps, "nullptr m_caps", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| return mediaCtx->m_caps->QueryProcessingRate(config_id, |
| proc_buf, processing_rate); |
| } |
| |
| //! |
| //! \brief media copy internal |
| //! |
| //! \param [in] mosCtx |
| //! Pointer to mos context |
| //! \param [in] src |
| //! VA copy mos resource src. |
| //! \param [in] dst |
| //! VA copy mos resrouce dst. |
| //! \param [in] option |
| //! VA copy option, copy mode. |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus |
| DdiMedia_CopyInternal( |
| PMOS_CONTEXT mosCtx, |
| PMOS_RESOURCE src, |
| PMOS_RESOURCE dst, |
| uint32_t copy_mode |
| ) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| MOS_STATUS mosStatus = MOS_STATUS_UNINITIALIZED; |
| DDI_CHK_NULL(mosCtx, "nullptr mosCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(src, "nullptr input osResource", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(dst, "nullptr output osResource", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| MediaCopyBaseState *mediaCopyState = static_cast<MediaCopyBaseState*>(*mosCtx->ppMediaCopyState); |
| |
| if (!mediaCopyState) |
| { |
| mediaCopyState = static_cast<MediaCopyBaseState*>(McpyDevice::CreateFactory(mosCtx)); |
| *mosCtx->ppMediaCopyState = mediaCopyState; |
| } |
| |
| DDI_CHK_NULL(mediaCopyState, "Invalid mediaCopy State", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| mosStatus = mediaCopyState->SurfaceCopy(src, dst, (MCPY_METHOD)copy_mode); |
| if (mosStatus != MOS_STATUS_SUCCESS) |
| { |
| vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| return vaStatus; |
| } |
| |
| #if VA_CHECK_VERSION(1,10,0) |
| //! |
| //! \brief media copy |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] dst_obj |
| //! VA copy object dst. |
| //! \param [in] src_obj |
| //! VA copy object src. |
| //! \param [in] option |
| //! VA copy option, copy mode. |
| //! \param [in] sync_handle |
| //! VA copy sync handle |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus |
| DdiMedia_Copy( |
| VADriverContextP ctx, |
| VACopyObject *dst_obj, |
| VACopyObject *src_obj, |
| VACopyOption option |
| ) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| MOS_CONTEXT mosCtx; |
| MOS_RESOURCE src, dst; |
| DdiCpInterface *pCpDdiInterface = nullptr; |
| PDDI_MEDIA_SURFACE src_surface = nullptr; |
| PDDI_MEDIA_SURFACE dst_surface = nullptr; |
| PDDI_MEDIA_BUFFER src_buffer = nullptr; |
| PDDI_MEDIA_BUFFER dst_buffer = nullptr; |
| |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(dst_obj, "nullptr copy dst", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(src_obj, "nullptr copy src", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| if (dst_obj->obj_type == VACopyObjectSurface) |
| { |
| DDI_CHK_LESS((uint32_t)dst_obj->object.surface_id, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "copy_dst", VA_STATUS_ERROR_INVALID_SURFACE); |
| dst_surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, dst_obj->object.surface_id); |
| DDI_CHK_NULL(dst_surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(dst_surface->pGmmResourceInfo, "nullptr dst_surface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| MOS_ZeroMemory(&dst, sizeof(dst)); |
| DdiMedia_MediaSurfaceToMosResource(dst_surface, &dst); |
| } |
| else if (dst_obj->obj_type == VACopyObjectBuffer) |
| { |
| DDI_CHK_LESS((uint32_t)dst_obj->object.buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid copy dst buf_id", VA_STATUS_ERROR_INVALID_BUFFER); |
| dst_buffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, dst_obj->object.buffer_id); |
| DDI_CHK_NULL(dst_buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(dst_buffer->pGmmResourceInfo, "nullptr dst_buffer->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| MOS_ZeroMemory(&dst, sizeof(dst)); |
| DdiMedia_MediaBufferToMosResource(dst_buffer, &dst); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("DDI: unsupported src copy object in DdiMedia_copy."); |
| } |
| |
| if (src_obj->obj_type == VACopyObjectSurface) |
| { |
| DDI_CHK_LESS((uint32_t)src_obj->object.surface_id, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "copy_src", VA_STATUS_ERROR_INVALID_SURFACE); |
| src_surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, src_obj->object.surface_id); |
| DDI_CHK_NULL(src_surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(src_surface->pGmmResourceInfo, "nullptr src_surface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| MOS_ZeroMemory(&src, sizeof(src)); |
| DdiMedia_MediaSurfaceToMosResource(src_surface, &src); |
| } |
| else if (src_obj->obj_type == VACopyObjectBuffer) |
| { |
| DDI_CHK_LESS((uint32_t)src_obj->object.buffer_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid copy dst buf_id", VA_STATUS_ERROR_INVALID_BUFFER); |
| src_buffer = DdiMedia_GetBufferFromVABufferID(mediaCtx, src_obj->object.buffer_id); |
| DDI_CHK_NULL(src_buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(src_buffer->pGmmResourceInfo, "nullptr src_buffer->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| MOS_ZeroMemory(&src, sizeof(src)); |
| DdiMedia_MediaBufferToMosResource(src_buffer, &src); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("DDI: unsupported dst copy object in DdiMedia_copy."); |
| } |
| |
| MOS_ZeroMemory(&mosCtx, sizeof(mosCtx)); |
| |
| mosCtx.bufmgr = mediaCtx->pDrmBufMgr; |
| mosCtx.m_gpuContextMgr = mediaCtx->m_gpuContextMgr; |
| mosCtx.m_cmdBufMgr = mediaCtx->m_cmdBufMgr; |
| mosCtx.fd = mediaCtx->fd; |
| mosCtx.iDeviceId = mediaCtx->iDeviceId; |
| mosCtx.SkuTable = mediaCtx->SkuTable; |
| mosCtx.WaTable = mediaCtx->WaTable; |
| mosCtx.gtSystemInfo = *mediaCtx->pGtSystemInfo; |
| mosCtx.platform = mediaCtx->platform; |
| |
| mosCtx.ppMediaCopyState = &mediaCtx->pMediaCopyState; |
| mosCtx.gtSystemInfo = *mediaCtx->pGtSystemInfo; |
| mosCtx.m_auxTableMgr = mediaCtx->m_auxTableMgr; |
| mosCtx.pGmmClientContext = mediaCtx->pGmmClientContext; |
| |
| mosCtx.m_osDeviceContext = mediaCtx->m_osDeviceContext; |
| mosCtx.m_apoMosEnabled = mediaCtx->m_apoMosEnabled; |
| |
| pCpDdiInterface = Create_DdiCpInterface(mosCtx); |
| |
| if (nullptr == pCpDdiInterface) |
| { |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| vaStatus = DdiMedia_CopyInternal(&mosCtx, &src, &dst, option.bits.va_copy_mode); |
| |
| if ((option.bits.va_copy_sync == VA_EXEC_SYNC) && dst_surface) |
| { |
| uint32_t timeout_NS = 100000000; |
| while (0 != mos_gem_bo_wait(dst_surface->bo, timeout_NS)) |
| { |
| // Just loop while gem_bo_wait times-out. |
| } |
| } |
| |
| if (pCpDdiInterface) |
| { |
| Delete_DdiCpInterface(pCpDdiInterface); |
| pCpDdiInterface = NULL; |
| } |
| |
| return vaStatus; |
| } |
| #endif |
| |
| //! |
| //! \brief Check for buffer info |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] buf_id |
| //! VA buffer ID |
| //! \param [out] type |
| //! VA buffer type |
| //! \param [out] size |
| //! Size |
| //! \param [out] num_elements |
| //! Number of elements |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_BufferInfo ( |
| VADriverContextP ctx, |
| VABufferID buf_id, |
| VABufferType *type, |
| uint32_t *size, |
| uint32_t *num_elements) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(type, "nullptr type", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(size, "nullptr size", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(num_elements, "nullptr num_elements", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| if (nullptr == mediaCtx) |
| return VA_STATUS_ERROR_INVALID_CONTEXT; |
| |
| DDI_CHK_NULL(mediaCtx->pBufferHeap, "nullptr mediaCtx->pBufferHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)buf_id, mediaCtx->pBufferHeap->uiAllocatedHeapElements, "Invalid buf_id", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| if (nullptr == buf) |
| { |
| return VA_STATUS_ERROR_INVALID_BUFFER; |
| } |
| |
| *type = (VABufferType)buf->uiType; |
| *size = buf->iSize / buf->uiNumElements; |
| *num_elements = buf->uiNumElements; |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Lock surface |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] surface |
| //! VA surface ID |
| //! \param [out] fourcc |
| //! FourCC |
| //! \param [out] luma_stride |
| //! Luma stride |
| //! \param [out] chroma_u_stride |
| //! Chroma U stride |
| //! \param [out] chroma_v_stride |
| //! Chroma V stride |
| //! \param [out] luma_offset |
| //! Luma offset |
| //! \param [out] chroma_u_offset |
| //! Chroma U offset |
| //! \param [out] chroma_v_offset |
| //! Chroma V offset |
| //! \param [out] buffer_name |
| //! Buffer name |
| //! \param [out] buffer |
| //! Buffer |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_LockSurface ( |
| VADriverContextP ctx, |
| VASurfaceID surface, |
| uint32_t *fourcc, |
| uint32_t *luma_stride, |
| uint32_t *chroma_u_stride, |
| uint32_t *chroma_v_stride, |
| uint32_t *luma_offset, |
| uint32_t *chroma_u_offset, |
| uint32_t *chroma_v_offset, |
| uint32_t *buffer_name, |
| void **buffer ) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_LOCK, EVENT_TYPE_START, &surface, sizeof(surface), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr context", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(fourcc, "nullptr fourcc", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(luma_stride, "nullptr luma_stride", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(chroma_u_stride, "nullptr chroma_u_stride", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(chroma_v_stride, "nullptr chroma_v_stride", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(luma_offset, "nullptr luma_offset", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(chroma_u_offset, "nullptr chroma_u_offset", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(chroma_v_offset, "nullptr chroma_v_offset", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(buffer_name, "nullptr buffer_name", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr Media", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface); |
| |
| #ifdef _MMC_SUPPORTED |
| // Decompress surface is needed |
| DdiMedia_MediaMemoryDecompress(mediaCtx, mediaSurface); |
| #endif |
| |
| if (nullptr == mediaSurface) |
| { |
| // Surface is absent. |
| buffer = nullptr; |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| } |
| |
| if (mediaSurface->uiLockedImageID != VA_INVALID_ID) |
| { |
| // Surface is locked already. |
| buffer = nullptr; |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| VAImage tmpImage; |
| tmpImage.image_id = VA_INVALID_ID; |
| VAStatus vaStatus = DdiMedia_DeriveImage(ctx,surface,&tmpImage); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| buffer = nullptr; |
| return vaStatus; |
| } |
| |
| mediaSurface->uiLockedImageID = tmpImage.image_id; |
| |
| vaStatus = DdiMedia_MapBuffer(ctx,tmpImage.buf,buffer); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| buffer = nullptr; |
| return vaStatus; |
| } |
| |
| mediaSurface->uiLockedBufID = tmpImage.buf; |
| |
| *fourcc = tmpImage.format.fourcc; |
| *luma_offset = tmpImage.offsets[0]; |
| *luma_stride = tmpImage.pitches[0]; |
| *chroma_u_offset = tmpImage.offsets[1]; |
| *chroma_u_stride = tmpImage.pitches[1]; |
| *chroma_v_offset = tmpImage.offsets[2]; |
| *chroma_v_stride = tmpImage.pitches[2]; |
| *buffer_name = tmpImage.buf; |
| |
| MOS_TraceEventExt(EVENT_VA_LOCK, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Unlock surface |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] surface |
| //! VA surface ID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_UnlockSurface ( |
| VADriverContextP ctx, |
| VASurfaceID surface) |
| { |
| DDI_FUNCTION_ENTER(); |
| MOS_TraceEventExt(EVENT_VA_UNLOCK, EVENT_TYPE_START, &surface, sizeof(surface), nullptr, 0); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| if (mediaSurface->uiLockedImageID == VA_INVALID_ID) |
| { |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| VABufferID bufID = (VABufferID)(mediaSurface->uiLockedBufID); |
| VAStatus vaStatus = DdiMedia_UnmapBuffer(ctx, bufID); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| return vaStatus; |
| } |
| mediaSurface->uiLockedBufID = VA_INVALID_ID; |
| |
| VAImageID imageID = (VAImageID)(mediaSurface->uiLockedImageID); |
| vaStatus = DdiMedia_DestroyImage(ctx,imageID); |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| return vaStatus; |
| } |
| mediaSurface->uiLockedImageID = VA_INVALID_ID; |
| |
| MOS_TraceEventExt(EVENT_VA_UNLOCK, EVENT_TYPE_END, nullptr, 0, nullptr, 0); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Query video proc filters |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] context |
| //! VA context ID |
| //! \param [in] filters |
| //! VA proc filter type |
| //! \param [in] num_filters |
| //! Number of filters |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus |
| DdiMedia_QueryVideoProcFilters( |
| VADriverContextP ctx, |
| VAContextID context, |
| VAProcFilterType *filters, |
| uint32_t *num_filters) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(context); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(filters, "nullptr filters", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(num_filters, "nullptr num_filters", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| uint32_t max_num_filters = DDI_VP_MAX_NUM_FILTERS; |
| // check if array size is less than VP_MAX_NUM_FILTERS |
| if(*num_filters < max_num_filters) |
| { |
| DDI_NORMALMESSAGE("num_filters %d < max_num_filters %d. Probably caused by Libva version upgrade!", *num_filters, max_num_filters); |
| } |
| |
| // Set the filters |
| uint32_t i = 0; |
| while(i < *num_filters && i < DDI_VP_MAX_NUM_FILTERS) |
| { |
| filters[i] = vp_supported_filters[i]; |
| i++; |
| } |
| |
| // Tell the app how many valid filters are filled in the array |
| *num_filters = DDI_VP_MAX_NUM_FILTERS; |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Query video processing filter capabilities. |
| //! The real implementation is in media_libva_vp.c, since it needs to use some definitions in vphal.h. |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] context |
| //! VA context ID |
| //! \param [in] type |
| //! VA proc filter type |
| //! \param [inout] filter_caps |
| //! FIlter caps |
| //! \param [inout] num_filter_caps |
| //! Number of filter caps |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus |
| DdiMedia_QueryVideoProcFilterCaps( |
| VADriverContextP ctx, |
| VAContextID context, |
| VAProcFilterType type, |
| void *filter_caps, |
| uint32_t *num_filter_caps |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| return DdiVp_QueryVideoProcFilterCaps(ctx, context, type, filter_caps, num_filter_caps); |
| } |
| |
| //! |
| //! \brief Query video proc pipeline caps |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] context |
| //! VA context ID |
| //! \param [in] filters |
| //! VA buffer ID |
| //! \param [in] num_filters |
| //! Number of filters |
| //! \param [in] pipeline_caps |
| //! VA proc pipeline caps |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus |
| DdiMedia_QueryVideoProcPipelineCaps( |
| VADriverContextP ctx, |
| VAContextID context, |
| VABufferID *filters, |
| uint32_t num_filters, |
| VAProcPipelineCaps *pipeline_caps |
| ) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(pipeline_caps, "nullptr pipeline_caps", VA_STATUS_ERROR_INVALID_PARAMETER); |
| if (num_filters > 0) |
| DDI_CHK_NULL(filters, "nullptr filters", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| pipeline_caps->pipeline_flags = VA_PROC_PIPELINE_FAST; |
| pipeline_caps->filter_flags = 0; |
| pipeline_caps->rotation_flags = (1 << VA_ROTATION_NONE) | (1 << VA_ROTATION_90) | (1 << VA_ROTATION_180) | (1 << VA_ROTATION_270); |
| pipeline_caps->mirror_flags = VA_MIRROR_HORIZONTAL | VA_MIRROR_VERTICAL; |
| pipeline_caps->blend_flags = VA_BLEND_GLOBAL_ALPHA | VA_BLEND_PREMULTIPLIED_ALPHA | VA_BLEND_LUMA_KEY; |
| pipeline_caps->num_forward_references = DDI_CODEC_NUM_FWD_REF; |
| pipeline_caps->num_backward_references = DDI_CODEC_NUM_BK_REF; |
| pipeline_caps->input_color_standards = vp_input_color_std; |
| pipeline_caps->num_input_color_standards = DDI_VP_NUM_INPUT_COLOR_STD; |
| pipeline_caps->output_color_standards = vp_output_color_std; |
| pipeline_caps->num_output_color_standards = DDI_VP_NUM_OUT_COLOR_STD; |
| |
| if ((context & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_DECODER) |
| { |
| //Decode+SFC, go SFC path, the restriction here is the capability of SFC |
| pipeline_caps->num_input_pixel_formats = 1; |
| pipeline_caps->input_pixel_format[0] = VA_FOURCC_NV12; |
| pipeline_caps->num_output_pixel_formats = 1; |
| pipeline_caps->output_pixel_format[0] = VA_FOURCC_NV12; |
| if((MEDIA_IS_SKU(&(mediaCtx->SkuTable), FtrHCP2SFCPipe))) |
| { |
| pipeline_caps->max_input_width = DDI_DECODE_HCP_SFC_MAX_WIDTH; |
| pipeline_caps->max_input_height = DDI_DECODE_HCP_SFC_MAX_HEIGHT; |
| } |
| else |
| { |
| pipeline_caps->max_input_width = DDI_DECODE_SFC_MAX_WIDTH; |
| pipeline_caps->max_input_height = DDI_DECODE_SFC_MAX_HEIGHT; |
| } |
| pipeline_caps->min_input_width = DDI_DECODE_SFC_MIN_WIDTH; |
| pipeline_caps->min_input_height = DDI_DECODE_SFC_MIN_HEIGHT; |
| pipeline_caps->max_output_width = DDI_DECODE_SFC_MAX_WIDTH; |
| pipeline_caps->max_output_height = DDI_DECODE_SFC_MAX_HEIGHT; |
| pipeline_caps->min_output_width = DDI_DECODE_SFC_MIN_WIDTH; |
| pipeline_caps->min_output_height = DDI_DECODE_SFC_MIN_HEIGHT; |
| } |
| else if ((context & DDI_MEDIA_MASK_VACONTEXT_TYPE) == DDI_MEDIA_VACONTEXTID_OFFSET_VP) |
| { |
| if(mediaCtx->platform.eRenderCoreFamily <= IGFX_GEN8_CORE) |
| { |
| //Capability of Gen8- platform |
| pipeline_caps->max_input_width = VP_MAX_PIC_WIDTH_Gen8; |
| pipeline_caps->max_input_height = VP_MAX_PIC_HEIGHT_Gen8; |
| pipeline_caps->max_output_width = VP_MAX_PIC_WIDTH_Gen8; |
| pipeline_caps->max_output_height = VP_MAX_PIC_HEIGHT_Gen8; |
| }else |
| { |
| //Capability of Gen9+ platform |
| pipeline_caps->max_input_width = VP_MAX_PIC_WIDTH; |
| pipeline_caps->max_input_height = VP_MAX_PIC_HEIGHT; |
| pipeline_caps->max_output_width = VP_MAX_PIC_WIDTH; |
| pipeline_caps->max_output_height = VP_MAX_PIC_HEIGHT; |
| } |
| pipeline_caps->min_input_width = VP_MIN_PIC_WIDTH; |
| pipeline_caps->min_input_height = VP_MIN_PIC_HEIGHT; |
| pipeline_caps->min_output_width = VP_MIN_PIC_WIDTH; |
| pipeline_caps->min_output_height = VP_MIN_PIC_WIDTH; |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| /** |
| * \brief Get surface attributes for the supplied config. |
| * |
| * This function retrieves the surface attributes matching the supplied |
| * config. The caller shall provide an \c attrib_list with all attributes |
| * to be retrieved. Upon successful return, the attributes in \c attrib_list |
| * are updated with the requested value. Unknown attributes or attributes |
| * that are not supported for the given config will have their \c flags |
| * field set to \c VA_SURFACE_ATTRIB_NOT_SUPPORTED. |
| * |
| * param[in] ctx the VA display |
| * param[in] config the config identifying a codec or a video |
| * processing pipeline |
| * param[out] attrib_list the list of attributes on output, with at |
| * least \c type fields filled in, and possibly \c value fields whenever |
| * necessary.The updated list of attributes and flags on output |
| * param[in] num_attribs the number of attributes supplied in the |
| * \c attrib_list array |
| */ |
| VAStatus DdiMedia_GetSurfaceAttributes( |
| VADriverContextP ctx, |
| VAConfigID config, |
| VASurfaceAttrib *attrib_list, |
| uint32_t num_attribs |
| ) |
| { |
| DDI_UNUSED(ctx); |
| DDI_UNUSED(config); |
| DDI_UNUSED(attrib_list); |
| DDI_UNUSED(num_attribs); |
| |
| DDI_FUNCTION_ENTER(); |
| |
| VAStatus vaStatus = VA_STATUS_ERROR_UNIMPLEMENTED; |
| |
| return vaStatus; |
| } |
| |
| //! |
| //! \brief Aquire buffer handle |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] buf_id |
| //! VA buffer ID |
| //! \param [in] buf_info |
| //! VA buffer Info |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_AcquireBufferHandle( |
| VADriverContextP ctx, |
| VABufferID buf_id, |
| VABufferInfo *buf_info) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(buf_info, "nullptr buf_info", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "Invalid Media ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(buf, "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(buf->bo, "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| // If user did not specify memtype he want's we use something we prefer, we prefer PRIME |
| if (!buf_info->mem_type) |
| { |
| buf_info->mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; |
| } |
| // now chekcing memtype whether we support it |
| if ((buf_info->mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME) && |
| (buf_info->mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)) |
| { |
| return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE; |
| } |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| // already acquired? |
| if (buf->uiExportcount) |
| { // yes, already acquired |
| // can't provide access thru another memtype |
| if (buf->uiMemtype != buf_info->mem_type) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| } |
| else |
| { // no, not acquired - doing this now |
| switch (buf_info->mem_type) { |
| case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: { |
| uint32_t flink = 0; |
| if (mos_bo_flink(buf->bo, &flink) != 0) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| return VA_STATUS_ERROR_INVALID_BUFFER; |
| } |
| buf->handle = (intptr_t)flink; |
| break; |
| } |
| case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { |
| int32_t prime_fd = 0; |
| if (mos_bo_gem_export_to_prime(buf->bo, &prime_fd) != 0) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| return VA_STATUS_ERROR_INVALID_BUFFER; |
| } |
| |
| buf->handle = (intptr_t)prime_fd; |
| break; |
| } |
| } |
| // saving memtepy which was provided to the user |
| buf->uiMemtype = buf_info->mem_type; |
| } |
| |
| ++buf->uiExportcount; |
| mos_bo_reference(buf->bo); |
| |
| buf_info->type = buf->uiType; |
| buf_info->handle = buf->handle; |
| buf_info->mem_size = buf->uiNumElements * buf->iSize; |
| |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Release buffer handle |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! \param [in] buf_id |
| //! VA bufferID |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_ReleaseBufferHandle( |
| VADriverContextP ctx, |
| VABufferID buf_id) |
| { |
| DDI_FUNCTION_ENTER(); |
| |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "Invalid Media ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buf_id); |
| DDI_CHK_NULL(buf, "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(buf->bo, "Invalid Media Buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| DdiMediaUtil_LockMutex(&mediaCtx->BufferMutex); |
| if (!buf->uiMemtype || !buf->uiExportcount) |
| { |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| return VA_STATUS_SUCCESS; |
| } |
| mos_bo_unreference(buf->bo); |
| --buf->uiExportcount; |
| |
| if (!buf->uiExportcount) { |
| switch (buf->uiMemtype) { |
| case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { |
| close((intptr_t)buf->handle); |
| break; |
| } |
| } |
| buf->uiMemtype = 0; |
| } |
| DdiMediaUtil_UnLockMutex(&mediaCtx->BufferMutex); |
| |
| if (!buf->uiExportcount && buf->bPostponedBufFree) { |
| MOS_FreeMemory(buf); |
| DdiMedia_DestroyBufFromVABufferID(mediaCtx, buf_id); |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| static uint32_t DdiMedia_GetPlaneNum(PDDI_MEDIA_SURFACE mediaSurface, bool hasAuxPlane) |
| { |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| uint32_t fourcc = DdiMedia_MediaFormatToOsFormat(mediaSurface->format); |
| uint32_t plane_num = 0; |
| switch(fourcc) |
| { |
| case VA_FOURCC_NV12: |
| case VA_FOURCC_NV21: |
| case VA_FOURCC_P010: |
| case VA_FOURCC_P012: |
| case VA_FOURCC_P016: |
| plane_num = hasAuxPlane ? 4 : 2; |
| break; |
| plane_num = hasAuxPlane ? 4 : 2; |
| break; |
| case VA_FOURCC_I420: |
| case VA_FOURCC_YV12: |
| case VA_FOURCC_411P: |
| case VA_FOURCC_422H: |
| case VA_FOURCC_422V: |
| case VA_FOURCC_444P: |
| case VA_FOURCC_IMC3: |
| case VA_FOURCC_RGBP: |
| case VA_FOURCC_BGRP: |
| plane_num = 3; |
| break; |
| case VA_FOURCC_YUY2: |
| case VA_FOURCC_UYVY: |
| case VA_FOURCC_YVYU: |
| case VA_FOURCC_VYUY: |
| case VA_FOURCC_Y800: |
| case VA_FOURCC_Y210: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212: |
| #endif |
| case VA_FOURCC_Y216: |
| case VA_FOURCC_Y410: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y412: |
| #endif |
| case VA_FOURCC_Y416: |
| case VA_FOURCC_AYUV: |
| case VA_FOURCC_RGBA: |
| case VA_FOURCC_RGBX: |
| case VA_FOURCC_BGRA: |
| case VA_FOURCC_BGRX: |
| case VA_FOURCC_ARGB: |
| case VA_FOURCC_ABGR: |
| case VA_FOURCC_XRGB: |
| case VA_FOURCC_XBGR: |
| case VA_FOURCC_RGB565: |
| case VA_FOURCC_R8G8B8: |
| case VA_FOURCC_A2R10G10B10: |
| case VA_FOURCC_A2B10G10R10: |
| case VA_FOURCC_X2R10G10B10: |
| case VA_FOURCC_X2B10G10R10: |
| plane_num = hasAuxPlane ? 2 : 1; |
| break; |
| default: |
| DDI_ASSERTMESSAGE("Unsupported format.\n"); |
| } |
| return plane_num; |
| } |
| |
| static uint32_t DdiMedia_GetDrmFormatOfSeparatePlane(uint32_t fourcc, int plane) |
| { |
| if (plane == 0) |
| { |
| switch (fourcc) |
| { |
| case VA_FOURCC_NV12: |
| case VA_FOURCC_I420: |
| case VA_FOURCC_YV12: |
| case VA_FOURCC_YV16: |
| case VA_FOURCC_Y800: |
| case VA_FOURCC_RGBP: |
| case VA_FOURCC_BGRP: |
| return DRM_FORMAT_R8; |
| case VA_FOURCC_P010: |
| case VA_FOURCC_P012: |
| case VA_FOURCC_P016: |
| case VA_FOURCC_I010: |
| return DRM_FORMAT_R16; |
| |
| case VA_FOURCC_YUY2: |
| return DRM_FORMAT_YUYV; |
| case VA_FOURCC_YVYU: |
| return DRM_FORMAT_YVYU; |
| case VA_FOURCC_VYUY: |
| return DRM_FORMAT_VYUY; |
| case VA_FOURCC_UYVY: |
| return DRM_FORMAT_UYVY; |
| case VA_FOURCC_AYUV: |
| return DRM_FORMAT_AYUV; |
| case VA_FOURCC_Y210: |
| return DRM_FORMAT_Y210; |
| case VA_FOURCC_Y216: |
| return DRM_FORMAT_Y216; |
| case VA_FOURCC_Y410: |
| return DRM_FORMAT_Y410; |
| case VA_FOURCC_Y416: |
| return DRM_FORMAT_Y416; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212: |
| return DRM_FORMAT_Y216; |
| case VA_FOURCC_Y412: |
| return DRM_FORMAT_Y416; |
| #endif |
| |
| case VA_FOURCC_ARGB: |
| return DRM_FORMAT_ARGB8888; |
| case VA_FOURCC_ABGR: |
| return DRM_FORMAT_ABGR8888; |
| case VA_FOURCC_RGBA: |
| return DRM_FORMAT_RGBA8888; |
| case VA_FOURCC_BGRA: |
| return DRM_FORMAT_BGRA8888; |
| case VA_FOURCC_XRGB: |
| return DRM_FORMAT_XRGB8888; |
| case VA_FOURCC_XBGR: |
| return DRM_FORMAT_XBGR8888; |
| case VA_FOURCC_RGBX: |
| return DRM_FORMAT_RGBX8888; |
| case VA_FOURCC_BGRX: |
| return DRM_FORMAT_BGRX8888; |
| case VA_FOURCC_A2R10G10B10: |
| return DRM_FORMAT_ARGB2101010; |
| case VA_FOURCC_A2B10G10R10: |
| return DRM_FORMAT_ABGR2101010; |
| case VA_FOURCC_X2R10G10B10: |
| return DRM_FORMAT_XRGB2101010; |
| case VA_FOURCC_X2B10G10R10: |
| return DRM_FORMAT_XBGR2101010; |
| } |
| } |
| else |
| { |
| switch (fourcc) |
| { |
| case VA_FOURCC_NV12: |
| return DRM_FORMAT_GR88; |
| case VA_FOURCC_I420: |
| case VA_FOURCC_YV12: |
| case VA_FOURCC_YV16: |
| case VA_FOURCC_RGBP: |
| case VA_FOURCC_BGRP: |
| return DRM_FORMAT_R8; |
| case VA_FOURCC_P010: |
| case VA_FOURCC_P012: |
| case VA_FOURCC_P016: |
| return DRM_FORMAT_GR1616; |
| case VA_FOURCC_I010: |
| return DRM_FORMAT_R16; |
| } |
| } |
| return 0; |
| } |
| |
| static uint32_t DdiMedia_GetDrmFormatOfCompositeObject(uint32_t fourcc) |
| { |
| switch (fourcc) |
| { |
| case VA_FOURCC_NV12: |
| return DRM_FORMAT_NV12; |
| case VA_FOURCC_I420: |
| return DRM_FORMAT_YUV420; |
| case VA_FOURCC_YV12: |
| return DRM_FORMAT_YVU420; |
| case VA_FOURCC_YV16: |
| return DRM_FORMAT_YVU422; |
| case VA_FOURCC_YUY2: |
| return DRM_FORMAT_YUYV; |
| case VA_FOURCC_YVYU: |
| return DRM_FORMAT_YVYU; |
| case VA_FOURCC_VYUY: |
| return DRM_FORMAT_VYUY; |
| case VA_FOURCC_UYVY: |
| return DRM_FORMAT_UYVY; |
| case VA_FOURCC_Y210: |
| return DRM_FORMAT_Y210; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212: |
| return DRM_FORMAT_Y216; |
| #endif |
| case VA_FOURCC_Y216: |
| return DRM_FORMAT_Y216; |
| case VA_FOURCC_Y410: |
| return DRM_FORMAT_Y410; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y412: |
| return DRM_FORMAT_Y416; |
| #endif |
| case VA_FOURCC_Y416: |
| return DRM_FORMAT_Y416; |
| case VA_FOURCC_Y800: |
| return DRM_FORMAT_R8; |
| case VA_FOURCC_P010: |
| return DRM_FORMAT_P010; |
| case VA_FOURCC_P012: |
| return DRM_FORMAT_P016; |
| case VA_FOURCC_P016: |
| return DRM_FORMAT_P016; |
| case VA_FOURCC_ARGB: |
| return DRM_FORMAT_ARGB8888; |
| case VA_FOURCC_ABGR: |
| return DRM_FORMAT_ABGR8888; |
| case VA_FOURCC_RGBA: |
| return DRM_FORMAT_RGBA8888; |
| case VA_FOURCC_BGRA: |
| return DRM_FORMAT_BGRA8888; |
| case VA_FOURCC_XRGB: |
| return DRM_FORMAT_XRGB8888; |
| case VA_FOURCC_XBGR: |
| return DRM_FORMAT_XBGR8888; |
| case VA_FOURCC_RGBX: |
| return DRM_FORMAT_RGBX8888; |
| case VA_FOURCC_BGRX: |
| return DRM_FORMAT_BGRX8888; |
| case VA_FOURCC_A2R10G10B10: |
| return DRM_FORMAT_ARGB2101010; |
| case VA_FOURCC_A2B10G10R10: |
| return DRM_FORMAT_ABGR2101010; |
| case VA_FOURCC_X2R10G10B10: |
| return DRM_FORMAT_XRGB2101010; |
| case VA_FOURCC_X2B10G10R10: |
| return DRM_FORMAT_XBGR2101010; |
| } |
| return 0; |
| } |
| |
| |
| //! |
| //! \brief API for export surface handle to other component |
| //! |
| //! \param [in] dpy |
| //! VA display. |
| //! \param [in] surface_id |
| //! Surface to export. |
| //! \param [in] mem_type |
| //! Memory type to export to. |
| //! \param [in] flags |
| //! Combination of flags to apply |
| //!\param [out] descriptor |
| //!Pointer to the descriptor structure to fill |
| //!with the handle details. The type of this structure depends on |
| //!the value of mem_type. |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus DdiMedia_ExportSurfaceHandle( |
| VADriverContextP ctx, |
| VASurfaceID surface_id, |
| uint32_t mem_type, |
| uint32_t flags, |
| void * descriptor) |
| { |
| DDI_CHK_NULL(descriptor, "nullptr descriptor", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)(surface_id), mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface_id); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(mediaSurface->bo, "nullptr mediaSurface->bo", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) { |
| DDI_ASSERTMESSAGE("vaExportSurfaceHandle: memory type %08x is not supported.\n", mem_type); |
| return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE; |
| } |
| |
| if (mos_bo_gem_export_to_prime(mediaSurface->bo, (int32_t*)&mediaSurface->name)) |
| { |
| DDI_ASSERTMESSAGE("Failed drm_intel_gem_export_to_prime operation!!!\n"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| |
| VADRMPRIMESurfaceDescriptor *desc = (VADRMPRIMESurfaceDescriptor *)descriptor; |
| desc->fourcc = DdiMedia_MediaFormatToOsFormat(mediaSurface->format); |
| if(desc->fourcc == VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT) |
| { |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| desc->width = mediaSurface->iWidth; |
| desc->height = mediaSurface->iRealHeight; |
| desc->num_objects = 1; |
| desc->objects[0].fd = mediaSurface->name; |
| desc->objects[0].size = mediaSurface->pGmmResourceInfo->GetSizeSurface(); |
| |
| // Prepare Compression info for export surface handle |
| GMM_RESOURCE_FLAG GmmFlags = {0}; |
| bool bMmcEnabled = false; |
| GmmFlags = mediaSurface->pGmmResourceInfo->GetResFlags(); |
| |
| if ((GmmFlags.Gpu.MMC || |
| GmmFlags.Gpu.CCS) && |
| (GmmFlags.Info.MediaCompressed || |
| GmmFlags.Info.RenderCompressed)) |
| { |
| bMmcEnabled = true; |
| } |
| else |
| { |
| bMmcEnabled = false; |
| } |
| |
| switch (mediaSurface->TileType) { |
| case I915_TILING_X: |
| desc->objects[0].drm_format_modifier = I915_FORMAT_MOD_X_TILED; |
| break; |
| case I915_TILING_Y: |
| if (mediaCtx->m_auxTableMgr && bMmcEnabled) |
| { |
| desc->objects[0].drm_format_modifier = GmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS : |
| (GmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS : I915_FORMAT_MOD_Y_TILED); |
| }else |
| { |
| desc->objects[0].drm_format_modifier = I915_FORMAT_MOD_Y_TILED; |
| } |
| break; |
| case I915_TILING_NONE: |
| default: |
| desc->objects[0].drm_format_modifier = DRM_FORMAT_MOD_NONE; |
| } |
| |
| int composite_object = flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS; |
| |
| uint32_t formats[4]; |
| bool hasAuxPlane = (mediaCtx->m_auxTableMgr)? true: false; |
| uint32_t num_planes = DdiMedia_GetPlaneNum(mediaSurface, hasAuxPlane); |
| if(composite_object) |
| { |
| formats[0] = DdiMedia_GetDrmFormatOfCompositeObject(desc->fourcc); |
| if(!formats[0]) |
| { |
| DDI_ASSERTMESSAGE("vaExportSurfaceHandle: fourcc %08x is not supported for export as a composite object.\n", desc->fourcc); |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| } |
| } |
| else |
| { |
| for (int i = 0; i < num_planes; i++) |
| { |
| formats[i] = DdiMedia_GetDrmFormatOfSeparatePlane(desc->fourcc,i); |
| if (!formats[i]) |
| { |
| DDI_ASSERTMESSAGE("vaExportSurfaceHandle: fourcc %08x is not supported for export as separate planes.\n", desc->fourcc); |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| } |
| } |
| } |
| |
| uint32_t pitch, height, chromaPitch, chromaHeight = 0; |
| pitch = mediaSurface->iPitch; |
| height = mediaSurface->iRealHeight; |
| DdiMedia_GetChromaPitchHeight(desc->fourcc, pitch, height, &chromaPitch, &chromaHeight); |
| |
| // Get offset from GMM |
| GMM_REQ_OFFSET_INFO reqInfo = {0}; |
| reqInfo.Plane = GMM_PLANE_Y; |
| reqInfo.ReqRender = 1; |
| mediaSurface->pGmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetY = reqInfo.Render.Offset; |
| MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO)); |
| reqInfo.Plane = GMM_PLANE_U; |
| reqInfo.ReqRender = 1; |
| mediaSurface->pGmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetU = reqInfo.Render.Offset; |
| MOS_ZeroMemory(&reqInfo, sizeof(GMM_REQ_OFFSET_INFO)); |
| reqInfo.Plane = GMM_PLANE_V; |
| reqInfo.ReqRender = 1; |
| mediaSurface->pGmmResourceInfo->GetOffset(reqInfo); |
| uint32_t offsetV = reqInfo.Render.Offset; |
| uint32_t auxOffsetY = (uint32_t)mediaSurface->pGmmResourceInfo->GetPlanarAuxOffset(0, GMM_AUX_Y_CCS); |
| uint32_t auxOffsetUV = (uint32_t)mediaSurface->pGmmResourceInfo->GetPlanarAuxOffset(0, GMM_AUX_UV_CCS); |
| |
| if (composite_object) { |
| desc->num_layers = 1; |
| desc->layers[0].drm_format = formats[0]; |
| desc->layers[0].num_planes = num_planes; |
| if (mediaCtx->m_auxTableMgr) |
| { |
| // For semi-planar formats like NV12, CCS planes follow the Y and UV planes, |
| // i.e. planes 0 and 1 are used for Y and UV surfaces, planes 2 and 3 for the respective CCS. |
| for (int i = 0; i < num_planes/2; i++) |
| { |
| desc->layers[0].object_index[2*i] = 0; |
| desc->layers[0].object_index[2*i+1] = 0; |
| if (i == 0) |
| { |
| // Y plane |
| desc->layers[0].offset[i] = offsetY; |
| desc->layers[0].pitch[i] = mediaSurface->iPitch; |
| // Y aux plane |
| desc->layers[0].offset[i + num_planes/2] = auxOffsetY; |
| desc->layers[0].pitch[i + num_planes/2] = mediaSurface->iPitch/8; |
| } |
| else |
| { |
| // UV plane |
| desc->layers[0].offset[i] = offsetU; |
| desc->layers[0].pitch[i] = mediaSurface->iPitch; |
| // UV aux plane |
| desc->layers[0].offset[i + num_planes/2] = auxOffsetUV; |
| desc->layers[0].pitch[i + num_planes/2] = mediaSurface->iPitch/8; |
| } |
| } |
| }else |
| { |
| for (int i = 0; i < num_planes; i++) |
| { |
| desc->layers[0].object_index[i] = 0; |
| switch(i) |
| { |
| case 0: |
| desc->layers[0].offset[i] = offsetY; |
| desc->layers[0].pitch[i] = pitch; |
| break; |
| case 1: |
| if (desc->fourcc == VA_FOURCC_YV12) |
| { |
| desc->layers[0].offset[i] = offsetV; |
| } |
| else |
| { |
| desc->layers[0].offset[i] = offsetU; |
| } |
| desc->layers[0].pitch[i] = chromaPitch; |
| break; |
| case 2: |
| if (desc->fourcc == VA_FOURCC_YV12) |
| { |
| desc->layers[0].offset[i] = offsetU; |
| } |
| else |
| { |
| desc->layers[0].offset[i] = offsetV; |
| } |
| desc->layers[0].pitch[i] = chromaPitch; |
| break; |
| default: |
| DDI_ASSERTMESSAGE("vaExportSurfaceHandle: invalid plan numbers"); |
| } |
| } |
| } |
| } |
| else |
| { |
| if (mediaCtx->m_auxTableMgr) |
| { |
| desc->num_layers = num_planes / 2; |
| |
| for (int i = 0; i < desc->num_layers; i++) |
| { |
| desc->layers[i].drm_format = formats[i]; |
| desc->layers[i].num_planes = 2; |
| |
| desc->layers[i].object_index[0] = 0; |
| |
| if (i == 0) |
| { |
| desc->layers[i].offset[0] = offsetY; |
| desc->layers[i].offset[1] = auxOffsetY; |
| desc->layers[i].pitch[0] = mediaSurface->iPitch; |
| desc->layers[i].pitch[1] = mediaSurface->iPitch/8; |
| } |
| else |
| { |
| desc->layers[i].offset[0] = offsetU; |
| desc->layers[i].offset[1] = auxOffsetUV; |
| desc->layers[i].pitch[0] = mediaSurface->iPitch; |
| desc->layers[i].pitch[1] = mediaSurface->iPitch/8; |
| } |
| } |
| }else |
| { |
| desc->num_layers = num_planes; |
| |
| for (int i = 0; i < num_planes; i++) |
| { |
| desc->layers[i].drm_format = formats[i]; |
| desc->layers[i].num_planes = 1; |
| |
| desc->layers[i].object_index[0] = 0; |
| |
| switch(i) |
| { |
| case 0: |
| desc->layers[i].offset[0] = offsetY; |
| desc->layers[i].pitch[0] = pitch; |
| break; |
| case 1: |
| if (desc->fourcc == VA_FOURCC_YV12) |
| { |
| desc->layers[i].offset[0] = offsetV; |
| } |
| else |
| { |
| desc->layers[i].offset[0] = offsetU; |
| } |
| desc->layers[i].pitch[0] = chromaPitch; |
| break; |
| case 2: |
| if (desc->fourcc == VA_FOURCC_YV12) |
| { |
| desc->layers[i].offset[0] = offsetU; |
| } |
| else |
| { |
| desc->layers[i].offset[0] = offsetV; |
| } |
| desc->layers[i].pitch[0] = chromaPitch; |
| break; |
| default: |
| DDI_ASSERTMESSAGE("vaExportSurfaceHandle: invalid plan numbers"); |
| } |
| } |
| } |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Init VA driver 0.31 |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| VAStatus __vaDriverInit(VADriverContextP ctx ) |
| { |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| struct VADriverVTable *pVTable = DDI_CODEC_GET_VTABLE(ctx); |
| DDI_CHK_NULL(pVTable, "nullptr pVTable", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| struct VADriverVTableVPP *pVTableVpp = DDI_CODEC_GET_VTABLE_VPP(ctx); |
| DDI_CHK_NULL(pVTableVpp, "nullptr pVTableVpp", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| #if VA_CHECK_VERSION(1,11,0) |
| struct VADriverVTableProt *pVTableProt = DDI_CODEC_GET_VTABLE_PROT(ctx); |
| DDI_CHK_NULL(pVTableProt, "nullptr pVTableProt", VA_STATUS_ERROR_INVALID_CONTEXT); |
| #endif |
| |
| ctx->pDriverData = nullptr; |
| ctx->version_major = VA_MAJOR_VERSION; |
| ctx->version_minor = VA_MINOR_VERSION; |
| ctx->max_profiles = DDI_CODEC_GEN_MAX_PROFILES; |
| ctx->max_entrypoints = DDI_CODEC_GEN_MAX_ENTRYPOINTS; |
| ctx->max_attributes = (int32_t)VAConfigAttribTypeMax; |
| ctx->max_subpic_formats = DDI_CODEC_GEN_MAX_SUBPIC_FORMATS; |
| ctx->max_display_attributes = DDI_CODEC_GEN_MAX_DISPLAY_ATTRIBUTES ; |
| ctx->str_vendor = DDI_CODEC_GEN_STR_VENDOR; |
| ctx->vtable_tpi = nullptr; |
| |
| pVTable->vaTerminate = DdiMedia_Terminate; |
| pVTable->vaQueryConfigEntrypoints = DdiMedia_QueryConfigEntrypoints; |
| pVTable->vaQueryConfigProfiles = DdiMedia_QueryConfigProfiles; |
| pVTable->vaQueryConfigAttributes = DdiMedia_QueryConfigAttributes; |
| pVTable->vaCreateConfig = DdiMedia_CreateConfig; |
| pVTable->vaDestroyConfig = DdiMedia_DestroyConfig; |
| pVTable->vaGetConfigAttributes = DdiMedia_GetConfigAttributes; |
| |
| pVTable->vaCreateSurfaces = DdiMedia_CreateSurfaces; |
| pVTable->vaDestroySurfaces = DdiMedia_DestroySurfaces; |
| pVTable->vaCreateSurfaces2 = DdiMedia_CreateSurfaces2; |
| |
| pVTable->vaCreateContext = DdiMedia_CreateContext; |
| pVTable->vaDestroyContext = DdiMedia_DestroyContext; |
| pVTable->vaCreateBuffer = DdiMedia_CreateBuffer; |
| pVTable->vaBufferSetNumElements = DdiMedia_BufferSetNumElements; |
| pVTable->vaMapBuffer = DdiMedia_MapBuffer; |
| pVTable->vaUnmapBuffer = DdiMedia_UnmapBuffer; |
| pVTable->vaDestroyBuffer = DdiMedia_DestroyBuffer; |
| pVTable->vaBeginPicture = DdiMedia_BeginPicture; |
| pVTable->vaRenderPicture = DdiMedia_RenderPicture; |
| pVTable->vaEndPicture = DdiMedia_EndPicture; |
| pVTable->vaSyncSurface = DdiMedia_SyncSurface; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| pVTable->vaSyncSurface2 = DdiMedia_SyncSurface2; |
| pVTable->vaSyncBuffer = DdiMedia_SyncBuffer; |
| #endif |
| pVTable->vaQuerySurfaceStatus = DdiMedia_QuerySurfaceStatus; |
| pVTable->vaQuerySurfaceError = DdiMedia_QuerySurfaceError; |
| pVTable->vaQuerySurfaceAttributes = DdiMedia_QuerySurfaceAttributes; |
| pVTable->vaPutSurface = DdiMedia_PutSurface; |
| pVTable->vaQueryImageFormats = DdiMedia_QueryImageFormats; |
| |
| pVTable->vaCreateImage = DdiMedia_CreateImage; |
| pVTable->vaDeriveImage = DdiMedia_DeriveImage; |
| pVTable->vaDestroyImage = DdiMedia_DestroyImage; |
| pVTable->vaSetImagePalette = DdiMedia_SetImagePalette; |
| pVTable->vaGetImage = DdiMedia_GetImage; |
| pVTable->vaPutImage = DdiMedia_PutImage; |
| pVTable->vaQuerySubpictureFormats = DdiMedia_QuerySubpictureFormats; |
| pVTable->vaCreateSubpicture = DdiMedia_CreateSubpicture; |
| pVTable->vaDestroySubpicture = DdiMedia_DestroySubpicture; |
| pVTable->vaSetSubpictureImage = DdiMedia_SetSubpictureImage; |
| pVTable->vaSetSubpictureChromakey = DdiMedia_SetSubpictureChromakey; |
| pVTable->vaSetSubpictureGlobalAlpha = DdiMedia_SetSubpictureGlobalAlpha; |
| pVTable->vaAssociateSubpicture = DdiMedia_AssociateSubpicture; |
| pVTable->vaDeassociateSubpicture = DdiMedia_DeassociateSubpicture; |
| pVTable->vaQueryDisplayAttributes = DdiMedia_QueryDisplayAttributes; |
| pVTable->vaGetDisplayAttributes = DdiMedia_GetDisplayAttributes; |
| pVTable->vaSetDisplayAttributes = DdiMedia_SetDisplayAttributes; |
| pVTable->vaQueryProcessingRate = DdiMedia_QueryProcessingRate; |
| #if VA_CHECK_VERSION(1,10,0) |
| pVTable->vaCopy = DdiMedia_Copy; |
| #endif |
| |
| // vaTrace |
| pVTable->vaBufferInfo = DdiMedia_BufferInfo; |
| pVTable->vaLockSurface = DdiMedia_LockSurface; |
| pVTable->vaUnlockSurface = DdiMedia_UnlockSurface; |
| |
| pVTableVpp->vaQueryVideoProcFilters = DdiMedia_QueryVideoProcFilters; |
| pVTableVpp->vaQueryVideoProcFilterCaps = DdiMedia_QueryVideoProcFilterCaps; |
| pVTableVpp->vaQueryVideoProcPipelineCaps = DdiMedia_QueryVideoProcPipelineCaps; |
| |
| #if VA_CHECK_VERSION(1,11,0) |
| pVTableProt->vaCreateProtectedSession = DdiMediaProtected::DdiMedia_CreateProtectedSession; |
| pVTableProt->vaDestroyProtectedSession = DdiMediaProtected::DdiMedia_DestroyProtectedSession; |
| pVTableProt->vaAttachProtectedSession = DdiMediaProtected::DdiMedia_AttachProtectedSession; |
| pVTableProt->vaDetachProtectedSession = DdiMediaProtected::DdiMedia_DetachProtectedSession; |
| pVTableProt->vaProtectedSessionExecute = DdiMediaProtected::DdiMedia_ProtectedSessionExecute; |
| #endif |
| |
| //pVTable->vaSetSurfaceAttributes = DdiMedia_SetSurfaceAttributes; |
| pVTable->vaGetSurfaceAttributes = DdiMedia_GetSurfaceAttributes; |
| //Export PRIMEFD/FLINK to application for buffer sharing with OpenCL/GL |
| pVTable->vaAcquireBufferHandle = DdiMedia_AcquireBufferHandle; |
| pVTable->vaReleaseBufferHandle = DdiMedia_ReleaseBufferHandle; |
| pVTable->vaExportSurfaceHandle = DdiMedia_ExportSurfaceHandle; |
| #ifndef ANDROID |
| pVTable->vaCreateMFContext = DdiMedia_CreateMfeContextInternal; |
| pVTable->vaMFAddContext = DdiMedia_AddContextInternal; |
| pVTable->vaMFReleaseContext = DdiMedia_ReleaseContextInternal; |
| pVTable->vaMFSubmit = DdiEncode_MfeSubmit; |
| #endif |
| return DdiMedia__Initialize(ctx, nullptr, nullptr); |
| } |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| //! |
| //! \brief Get VA_MAJOR_VERSION and VA_MINOR_VERSION from libva |
| //! To form the function name in the format of _vaDriverInit_[VA_MAJOR_VERSION]_[VA_MINOR_VERSION] |
| //! |
| #define VA_DRV_INIT_DEF(_major,_minor) __vaDriverInit_##_major##_##_minor |
| #define VA_DRV_INIT_FUNC(va_major_version, va_minor_version) VA_DRV_INIT_DEF(va_major_version,va_minor_version) |
| #define VA_DRV_INIT_FUC_NAME VA_DRV_INIT_FUNC(VA_MAJOR_VERSION,VA_MINOR_VERSION) |
| |
| //! |
| //! \brief VA driver init function name |
| //! |
| //! \param [in] ctx |
| //! Pointer to VA driver context |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| MEDIAAPI_EXPORT VAStatus VA_DRV_INIT_FUC_NAME(VADriverContextP ctx ) |
| { |
| return __vaDriverInit(ctx); |
| } |
| |
| //! |
| //! \brief Private API for openCL |
| //! |
| //! \param [in] dpy |
| //! VA display |
| //! \param [in] surface |
| //! VA surface ID |
| //! \param [in] prime_fd |
| //! Prime fd |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| MEDIAAPI_EXPORT VAStatus DdiMedia_ExtGetSurfaceHandle( |
| VADisplay dpy, |
| VASurfaceID *surface, |
| int32_t *prime_fd) |
| { |
| DDI_CHK_NULL(dpy, "nullptr dpy", VA_STATUS_ERROR_INVALID_DISPLAY); |
| DDI_CHK_NULL(surface, "nullptr surfaces", VA_STATUS_ERROR_INVALID_PARAMETER); |
| DDI_CHK_NULL(prime_fd, "nullptr id", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| VADriverContextP ctx = ((VADisplayContextP)dpy)->pDriverContext; |
| DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "nullptr mediaCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_LESS((uint32_t)(*surface), mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaces", VA_STATUS_ERROR_INVALID_SURFACE); |
| |
| DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, *surface); |
| if (mediaSurface) |
| { |
| if (mediaSurface->bo) |
| { |
| int32_t ret = mos_bo_gem_export_to_prime(mediaSurface->bo, (int32_t*)&mediaSurface->name); |
| if (ret) |
| { |
| //LOGE("Failed drm_intel_gem_export_to_prime operation!!!\n"); |
| return VA_STATUS_ERROR_OPERATION_FAILED; |
| } |
| } |
| } |
| else |
| { |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| } |
| |
| *prime_fd = mediaSurface->name; |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Map buffer 2 |
| //! |
| //! \param [in] dpy |
| //! VA display |
| //! \param [in] buf_id |
| //! VA buffer ID |
| //! \param [out] pbuf |
| //! Pointer to buffer |
| //! \param [in] flag |
| //! Flag |
| //! |
| //! \return VAStatus |
| //! VA_STATUS_SUCCESS if success, else fail reason |
| //! |
| MEDIAAPI_EXPORT VAStatus DdiMedia_MapBuffer2( |
| VADisplay dpy, |
| VABufferID buf_id, |
| void **pbuf, |
| int32_t flag |
| ) |
| { |
| DDI_CHK_NULL(dpy, "nullptr dpy", VA_STATUS_ERROR_INVALID_DISPLAY); |
| |
| VADriverContextP ctx = ((VADisplayContextP)dpy)->pDriverContext; |
| |
| if ((flag == 0) || (flag & ~(MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY))) |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| |
| return DdiMedia_MapBufferInternal(ctx, buf_id, pbuf, flag); |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |