#include #include #include #include #include #include #include #include #include #include #include #define IF_MALLOC_FAIL(ptr) \ if(NULL == ptr) \ { \ aloge("fatal error! malloc fail! error(%s)", strerror(errno)); \ return ERR_RGN_NOMEM; \ } typedef struct { MPP_CHN_S mChn; RGN_CHN_ATTR_S mRgnChnAttr; struct list_head mList; }RegionAttachChnInfo; typedef struct { RGN_HANDLE mRgnHandle; //[0,RGN_HANDLE_MAX) RGN_ATTR_S mRgnAttr; BOOL mbSetBmp; BITMAP_S mBmp; //pthread_mutex_t mLock; struct list_head mAttachChnList; //RegionAttachChnInfo struct list_head mList; }RegionInfo; typedef struct { struct list_head mRegionList; //element type: RegionInfo pthread_mutex_t mLock; } RegionManager; static RegionManager *gpRegionManager = NULL; ERRORTYPE RegionManager_Construct(void) { int ret; if (gpRegionManager != NULL) { return SUCCESS; } gpRegionManager = (RegionManager*)malloc(sizeof(RegionManager)); IF_MALLOC_FAIL(gpRegionManager); ret = pthread_mutex_init(&gpRegionManager->mLock, NULL); if (ret != 0) { aloge("fatal error! mutex init fail"); free(gpRegionManager); gpRegionManager = NULL; return FAILURE; } INIT_LIST_HEAD(&gpRegionManager->mRegionList); return SUCCESS; } ERRORTYPE RegionManager_Destruct(void) { if (gpRegionManager != NULL) { if (!list_empty(&gpRegionManager->mRegionList)) { aloge("fatal error! some regions still exist when destroy RegionManager!"); RegionInfo *pEntry; list_for_each_entry(pEntry, &gpRegionManager->mRegionList, mList) { alogd("rgn handle:%d, type:%d", pEntry->mRgnHandle, pEntry->mRgnAttr.enType); if(!list_empty(&pEntry->mAttachChnList)) { RegionAttachChnInfo *pRgnAttachChnEntry; list_for_each_entry(pRgnAttachChnEntry, &pEntry->mAttachChnList, mList) { alogd("attachChn[%d-%d-%d], rgnType:%d", pRgnAttachChnEntry->mChn.mModId, pRgnAttachChnEntry->mChn.mDevId, pRgnAttachChnEntry->mChn.mChnId, pRgnAttachChnEntry->mRgnChnAttr.enType); } } } } pthread_mutex_destroy(&gpRegionManager->mLock); free(gpRegionManager); gpRegionManager = NULL; } return SUCCESS; } static ERRORTYPE searchExistRegion_l(RGN_HANDLE Handle, RegionInfo** ppRegion) { ERRORTYPE ret = FAILURE; RegionInfo* pEntry; if (gpRegionManager == NULL) { return FAILURE; } list_for_each_entry(pEntry, &gpRegionManager->mRegionList, mList) { if(pEntry->mRgnHandle == Handle) { if(ppRegion) { *ppRegion = pEntry; } ret = SUCCESS; break; } } return ret; } static ERRORTYPE searchExistRegion(RGN_HANDLE Handle, RegionInfo** ppRegion) { ERRORTYPE ret = FAILURE; RegionInfo* pEntry; if (gpRegionManager == NULL) { return FAILURE; } pthread_mutex_lock(&gpRegionManager->mLock); ret = searchExistRegion_l(Handle, ppRegion); pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } static ERRORTYPE addRegion_l(RegionInfo *pRegion) { if (gpRegionManager == NULL) { return FAILURE; } list_add_tail(&pRegion->mList, &gpRegionManager->mRegionList); return SUCCESS; } static ERRORTYPE addRegion(RegionInfo *pRegion) { if (gpRegionManager == NULL) { return FAILURE; } pthread_mutex_lock(&gpRegionManager->mLock); ERRORTYPE ret = addRegion_l(pRegion); pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } static ERRORTYPE removeRegion_l(RegionInfo *pRegion) { if (gpRegionManager == NULL) { return FAILURE; } list_del(&pRegion->mList); return SUCCESS; } static ERRORTYPE removeRegion(RegionInfo *pRegion) { if (gpRegionManager == NULL) { return FAILURE; } pthread_mutex_lock(&gpRegionManager->mLock); removeRegion_l(pRegion); pthread_mutex_unlock(&gpRegionManager->mLock); return SUCCESS; } static RegionInfo* RegionInfo_Construct() { RegionInfo *pRegion = (RegionInfo*)malloc(sizeof(RegionInfo)); if(NULL == pRegion) { aloge("fatal error! malloc fail[%s]!", strerror(errno)); return NULL; } memset(pRegion, 0, sizeof(RegionInfo)); // int ret = pthread_mutex_init(&pRegion->mLock, NULL); // if (ret != 0) // { // aloge("fatal error! mutex init fail"); // free(pRegion); // return NULL; // } INIT_LIST_HEAD(&pRegion->mAttachChnList); return pRegion; } static void RegionInfo_Destruct(RegionInfo *pRegion) { int cnt = 0; struct list_head *pList; list_for_each(pList, &pRegion->mAttachChnList) { cnt++; } if(cnt > 0) { aloge("fatal error! region still has [%d] attach channels!", cnt); } if(pRegion->mBmp.mpData) { free(pRegion->mBmp.mpData); pRegion->mBmp.mpData = NULL; } //pthread_mutex_destroy(&pRegion->mLock); free(pRegion); } static ERRORTYPE RGN_SetRegions(const MPP_CHN_S *mpp_chn, RgnChnAttachDetailPack *rgn_pack) { ERRORTYPE ret = FAILURE; switch (mpp_chn->mModId) { case MOD_ID_VIU: #if (MPPCFG_VI == OPTION_VI_ENABLE) ret = AW_MPI_VI_SetRegions(mpp_chn->mDevId, rgn_pack); #endif break; case MOD_ID_VENC: #if (MPPCFG_VENC == OPTION_VENC_ENABLE) ret = AW_MPI_VENC_SetRegions(mpp_chn->mChnId, rgn_pack); #endif break; default: aloge("fatal error! impossible moduleType[0x%x]", mpp_chn->mModId); break; } return ret; } static ERRORTYPE RGN_DeleteRegions(const MPP_CHN_S *mpp_chn, RgnChnAttachDetailPack *rgn_pack) { ERRORTYPE ret = FAILURE; switch (mpp_chn->mModId) { case MOD_ID_VIU: #if (MPPCFG_VI == OPTION_VI_ENABLE) ret = AW_MPI_VI_DeleteRegions(mpp_chn->mDevId, rgn_pack); #endif break; case MOD_ID_VENC: #if (MPPCFG_VENC == OPTION_VENC_ENABLE) ret = AW_MPI_VENC_DeleteRegions(mpp_chn->mChnId, rgn_pack); #endif break; default: aloge("fatal error! impossible moduleType[0x%x]", mpp_chn->mModId); break; } return ret; } static ERRORTYPE RGN_UpdateRegionChnAttr(RGN_HANDLE Handle, const MPP_CHN_S *mpp_chn, const RGN_CHN_ATTR_S *rgn_attr) { ERRORTYPE ret = FAILURE; switch (mpp_chn->mModId) { case MOD_ID_VIU: #if (MPPCFG_VI == OPTION_VI_ENABLE) ret = AW_MPI_VI_UpdateRegionChnAttr(mpp_chn->mDevId, Handle, rgn_attr); #endif break; case MOD_ID_VENC: #if (MPPCFG_VENC == OPTION_VENC_ENABLE) ret = AW_MPI_VENC_UpdateRegionChnAttr(mpp_chn->mChnId, Handle, rgn_attr); #endif break; default: aloge("fatal error! impossible moduleType[0x%x]", mpp_chn->mModId); break; } return ret; } static ERRORTYPE RGN_SetBitMap(RGN_HANDLE Handle, const MPP_CHN_S *mpp_chn, BITMAP_S *bitmap) { ERRORTYPE ret = FAILURE; switch (mpp_chn->mModId) { case MOD_ID_VIU: #if (MPPCFG_VI == OPTION_VI_ENABLE) ret = AW_MPI_VI_UpdateOverlayBitmap(mpp_chn->mDevId, Handle, bitmap); #endif break; case MOD_ID_VENC: #if (MPPCFG_VENC == OPTION_VENC_ENABLE) ret = AW_MPI_VENC_UpdateOverlayBitmap(mpp_chn->mChnId, Handle, bitmap); #endif break; default: aloge("fatal error! modId[0x%x] don't support attach region!", mpp_chn->mModId); break; } return ret; } ERRORTYPE RGN_DetachFromChn_l(RegionInfo *pRegion, const MPP_CHN_S *pstChn) { ERRORTYPE ret = SUCCESS; int nCnt = 0; RegionAttachChnInfo *pEntry, *pDstChn; list_for_each_entry(pEntry, &pRegion->mAttachChnList, mList) { if(pEntry->mChn.mModId == pstChn->mModId && pEntry->mChn.mDevId == pstChn->mDevId && pEntry->mChn.mChnId == pstChn->mChnId) { if(0 == nCnt) { pDstChn = pEntry; } nCnt++; } } if(nCnt <= 0) { aloge("fatal error! regionHandle[%d] not find chn[%d][%d][%d]?", pRegion->mRgnHandle, pstChn->mModId, pstChn->mDevId, pstChn->mChnId); return ERR_RGN_UNEXIST; } if(nCnt > 1) { aloge("fatal error! more [%d]same channel?", nCnt); } RgnChnAttachDetailPack stPack; memset(&stPack, 0, sizeof(RgnChnAttachDetailPack)); stPack.nNum = 1; stPack.RgnChnAttachDetailArray[0].nHandle = pRegion->mRgnHandle; /*if(MOD_ID_VIU == pDstChn->mChn.mModId) { AW_MPI_VI_DeleteRegions(pDstChn->mChn.mDevId, &stPack); } else if(MOD_ID_VENC == pDstChn->mChn.mModId) { AW_MPI_VENC_DeleteRegions(pDstChn->mChn.mChnId, &stPack); } else { aloge("fatal error! impossible moduleType[0x%x]", pstChn->mModId); }*/ RGN_DeleteRegions(&pDstChn->mChn, &stPack); //delete from chnList list_del(&pDstChn->mList); free(pDstChn); return SUCCESS; } ERRORTYPE AW_MPI_RGN_Create(RGN_HANDLE Handle, const RGN_ATTR_S *pstRegion) { if(!(Handle>=0 && Handle enType != OVERLAY_RGN && pstRegion->enType != COVER_RGN && pstRegion->enType != ORL_RGN) { aloge("fatal error! illegal rgnType[0x%x]!", pstRegion->enType); return ERR_RGN_ILLEGAL_PARAM; } pthread_mutex_lock(&gpRegionManager->mLock); if(SUCCESS == searchExistRegion_l(Handle, NULL)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_EXIST; } BOOL bNeedMatch = FALSE; BOOL bCanAdd = TRUE; PIXEL_FORMAT_E nOverlayPixelFmt; if(pstRegion->enType == OVERLAY_RGN) { bNeedMatch = TRUE; nOverlayPixelFmt = pstRegion->unAttr.stOverlay.mPixelFmt; } if(bNeedMatch) { RegionInfo *pEntry; list_for_each_entry(pEntry, &gpRegionManager->mRegionList, mList) { if(pEntry->mRgnAttr.enType == OVERLAY_RGN) { if(nOverlayPixelFmt != pEntry->mRgnAttr.unAttr.stOverlay.mPixelFmt) { aloge("fatal error! new overlay pixel format[0x%x] is unmatch [0x%x], can't add!", nOverlayPixelFmt, pEntry->mRgnAttr.unAttr.stOverlay.mPixelFmt); bCanAdd = FALSE; } break; } } } if(bCanAdd) { RegionInfo *pNode = RegionInfo_Construct(); pNode->mRgnHandle = Handle; pNode->mRgnAttr = *pstRegion; addRegion_l(pNode); pthread_mutex_unlock(&gpRegionManager->mLock); return SUCCESS; } else { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_ILLEGAL_PARAM; } } ERRORTYPE AW_MPI_RGN_Destroy(RGN_HANDLE Handle) { ERRORTYPE ret; if(!(Handle>=0 && HandlemLock); RegionInfo *pRegion; if(SUCCESS != searchExistRegion_l(Handle, &pRegion)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } //pthread_mutex_lock(&pRegion->mLock); if(!list_empty(&pRegion->mAttachChnList)) { int cnt = 0; RegionAttachChnInfo *pEntry, *pTmp; list_for_each_entry_safe(pEntry, pTmp, &pRegion->mAttachChnList, mList) { RGN_DetachFromChn_l(pRegion, &pEntry->mChn); cnt++; } alogd("detach region from [%d] channels!", cnt); } //pthread_mutex_unlock(&pRegion->mLock); removeRegion_l(pRegion); RegionInfo_Destruct(pRegion); pthread_mutex_unlock(&gpRegionManager->mLock); return SUCCESS; } ERRORTYPE AW_MPI_RGN_GetAttr(RGN_HANDLE Handle, RGN_ATTR_S *pstRegion) { if(!(Handle>=0 && Handle mRgnAttr; return SUCCESS; } /** * must set rgn attr before setBitmap, or else bitmap will be invalid. * if has been attached to channels, can't set attr. */ ERRORTYPE AW_MPI_RGN_SetAttr(RGN_HANDLE Handle, const RGN_ATTR_S *pstRegion) { ERRORTYPE ret = SUCCESS; if(!(Handle>=0 && Handle mLock); if(SUCCESS != searchExistRegion_l(Handle, &pRegion)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } //pthread_mutex_lock(&pRegion->mLock); if(list_empty(&pRegion->mAttachChnList)) { if(pRegion->mbSetBmp) { alogw("Be careful! Bitmap will release before set attr!"); if(pRegion->mBmp.mpData) { free(pRegion->mBmp.mpData); pRegion->mBmp.mpData = NULL; } memset(&pRegion->mBmp, 0, sizeof(BITMAP_S)); pRegion->mbSetBmp = FALSE; } pRegion->mRgnAttr = *pstRegion; } else { alogw("Be careful! region has attach to channel, can't set region attribute!"); ret = ERR_RGN_BUSY; } //pthread_mutex_unlock(&pRegion->mLock); pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } /** * If setBitmap again, the previous one will be release, and will update every channel which has been attached. */ ERRORTYPE AW_MPI_RGN_SetBitMap(RGN_HANDLE Handle, const BITMAP_S *pstBitmap) { ERRORTYPE ret = SUCCESS; if(!(Handle>=0 && Handle mLock); if(SUCCESS != searchExistRegion_l(Handle, &pRegion)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } if(OVERLAY_RGN != pRegion->mRgnAttr.enType) { aloge("fatal error! RgnType[0x%x] is not overlay!", pRegion->mRgnAttr.enType); pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_NOT_PERM; } if(NULL == pstBitmap) { aloge("fatal error! bitmap can't be NULL!"); pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_ILLEGAL_PARAM; } if(pstBitmap->mPixelFormat != pRegion->mRgnAttr.unAttr.stOverlay.mPixelFmt) { aloge("fatal error! bitmap pixFmt[0x%x] != region pixFmt[0x%x]!", pstBitmap->mPixelFormat, pRegion->mRgnAttr.unAttr.stOverlay.mPixelFmt); pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_ILLEGAL_PARAM; } if(pstBitmap->mWidth != pRegion->mRgnAttr.unAttr.stOverlay.mSize.Width || pstBitmap->mHeight != pRegion->mRgnAttr.unAttr.stOverlay.mSize.Height) { alogw("Be careful! bitmap size[%dx%d] != region size[%dx%d], need update region size", pstBitmap->mWidth, pstBitmap->mHeight, pRegion->mRgnAttr.unAttr.stOverlay.mSize.Width, pRegion->mRgnAttr.unAttr.stOverlay.mSize.Height); pRegion->mRgnAttr.unAttr.stOverlay.mSize.Width = pstBitmap->mWidth; pRegion->mRgnAttr.unAttr.stOverlay.mSize.Height = pstBitmap->mHeight; //return ERR_RGN_ILLEGAL_PARAM; } void* pBmpDataWaitFree = NULL; //pthread_mutex_lock(&pRegion->mLock); if(pRegion->mbSetBmp) { alogv("Be careful! set bmp again!"); if(pRegion->mBmp.mpData) { //free(pRegion->mBmp.mpData); pBmpDataWaitFree = pRegion->mBmp.mpData; pRegion->mBmp.mpData = NULL; } //memset(&pRegion->mBmp, 0, sizeof(BITMAP_S)); pRegion->mbSetBmp = FALSE; } pRegion->mBmp = *pstBitmap; int nSize = BITMAP_S_GetdataSize(pstBitmap); pRegion->mBmp.mpData = malloc(nSize); IF_MALLOC_FAIL(pRegion->mBmp.mpData); memcpy(pRegion->mBmp.mpData, pstBitmap->mpData, nSize); pRegion->mbSetBmp = TRUE; if(!list_empty(&pRegion->mAttachChnList)) { int cnt = 0; RegionAttachChnInfo *pAttachChnInfo; list_for_each_entry(pAttachChnInfo, &pRegion->mAttachChnList, mList) { /*if(MOD_ID_VIU == pAttachChnInfo->mChn.mModId) { ret = AW_MPI_VI_UpdateOverlayBitmap(pAttachChnInfo->mChn.mDevId, Handle, &pRegion->mBmp); } else if(MOD_ID_VENC == pAttachChnInfo->mChn.mModId) { ret = AW_MPI_VENC_UpdateOverlayBitmap(pAttachChnInfo->mChn.mChnId, Handle, &pRegion->mBmp); } else { aloge("fatal error! modId[0x%x] don't support attach region!", pAttachChnInfo->mChn.mModId); ret = ERR_RGN_ILLEGAL_PARAM; }*/ ret = RGN_SetBitMap(Handle, &pAttachChnInfo->mChn, &pRegion->mBmp); if (ret != SUCCESS) { aloge("fatal error! module 0x%x set bitmap fail:0x!", pAttachChnInfo->mChn.mModId, ret); ret = ERR_RGN_ILLEGAL_PARAM; } cnt++; } alogv("update region to [%d] channels!", cnt); } //pthread_mutex_unlock(&pRegion->mLock); if(pBmpDataWaitFree) { free(pBmpDataWaitFree); pBmpDataWaitFree = NULL; } pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } /** check if Handle and RgnChnAttr are valid when attached to dstMppChn. @param[out] ppRegionInfo pRegionInfo that caller gets. @return ERR_RGN_INVALID_CHNID: handle is wrong. ERR_RGN_UNEXIST: handle does not exist in gpRegionManager->mRegionList. ERR_RGN_EXIST: attach_dst_channel already exists. ERR_RGN_ILLEGAL_PARAM: region type is not match. SUCCESS: Handle, RgnChnAttr and dstChn are all valid. */ static ERRORTYPE CheckRgnChnAttachValid_l(RGN_HANDLE Handle, const MPP_CHN_S *pstChn, const RGN_CHN_ATTR_S *pstChnAttr, RegionInfo **ppRegionInfo) { ERRORTYPE ret = SUCCESS; if(!(Handle>=0 && Handle enType != pRegion->mRgnAttr.enType) { aloge("fatal error! RGN_CHN_ATTR's RGNType[0x%x] != RGN_ATTR's RGNType[0x%x]", pstChnAttr->enType, pRegion->mRgnAttr.enType); return ERR_RGN_ILLEGAL_PARAM; } //pthread_mutex_lock(&pRegion->mLock); BOOL bExist = FALSE; RegionAttachChnInfo *pChnEntry; list_for_each_entry(pChnEntry, &pRegion->mAttachChnList, mList) { if(pChnEntry->mChn.mModId == pstChn->mModId && pChnEntry->mChn.mDevId == pstChn->mDevId && pChnEntry->mChn.mChnId == pstChn->mChnId) { alogw("Be careful! attach dst channel[0x%x-0x%x-0x%x] is exist, can't attach again!", pChnEntry->mChn.mModId, pChnEntry->mChn.mDevId, pChnEntry->mChn.mChnId); bExist = TRUE; break; } } //pthread_mutex_unlock(&pRegion->mLock); if(bExist) { return ERR_RGN_EXIST; } else { if(ppRegionInfo) { *ppRegionInfo = pRegion; } return SUCCESS; } } ERRORTYPE AW_MPI_RGN_AttachToChn(RGN_HANDLE Handle, const MPP_CHN_S *pstChn, const RGN_CHN_ATTR_S *pstChnAttr) { ERRORTYPE ret = SUCCESS; RegionInfo *pRegion = NULL; pthread_mutex_lock(&gpRegionManager->mLock); ret = CheckRgnChnAttachValid_l(Handle, pstChn, pstChnAttr, &pRegion); if(ret != SUCCESS) { pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } BOOL bAddFlag = FALSE; RgnChnAttachDetailPack stPack; memset(&stPack, 0, sizeof(RgnChnAttachDetailPack)); stPack.nNum = 1; stPack.RgnChnAttachDetailArray[0].nHandle = Handle; stPack.RgnChnAttachDetailArray[0].pRgnAttr = &pRegion->mRgnAttr; stPack.RgnChnAttachDetailArray[0].pRgnChnAttr = (RGN_CHN_ATTR_S*)pstChnAttr; stPack.RgnChnAttachDetailArray[0].pBmp = pRegion->mbSetBmp?&pRegion->mBmp:NULL; //set chn /*if(MOD_ID_VIU == pstChn->mModId) { if(SUCCESS == AW_MPI_VI_SetRegions(pstChn->mDevId, &stPack)) { bAddFlag = TRUE; } } else if(MOD_ID_VENC == pstChn->mModId) { if(SUCCESS == AW_MPI_VENC_SetRegions(pstChn->mChnId, &stPack)) { bAddFlag = TRUE; } } else { aloge("fatal error! impossible moduleType[0x%x]", pstChn->mModId); }*/ ret = RGN_SetRegions(pstChn, &stPack); if (ret == SUCCESS) { bAddFlag = TRUE; } else { aloge("fatal error! module 0x%x set regions fail:0x%x!", pstChn->mModId, ret); } //add to list if(bAddFlag) { RegionAttachChnInfo *pAttachChnInfo = (RegionAttachChnInfo*)malloc(sizeof(RegionAttachChnInfo)); IF_MALLOC_FAIL(pAttachChnInfo); memset(pAttachChnInfo, 0, sizeof(RegionAttachChnInfo)); pAttachChnInfo->mChn = *pstChn; pAttachChnInfo->mRgnChnAttr = *pstChnAttr; list_add_tail(&pAttachChnInfo->mList, &pRegion->mAttachChnList); ret = SUCCESS; } else { ret = ERR_RGN_ILLEGAL_PARAM; } pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } ERRORTYPE AW_MPI_RGN_DetachFromChn(RGN_HANDLE Handle, const MPP_CHN_S *pstChn) { ERRORTYPE ret = SUCCESS; if(!(Handle>=0 && Handle mLock); RegionInfo *pRegion; if(SUCCESS != searchExistRegion_l(Handle, &pRegion)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } //pthread_mutex_lock(&pRegion->mLock); RGN_DetachFromChn_l(pRegion, pstChn); //pthread_mutex_unlock(&pRegion->mLock); pthread_mutex_unlock(&gpRegionManager->mLock); return SUCCESS; } /** pack region channel attach infos to one param to send them together, then mpi_region can display them simultaneously. @return ERR_RGN_ILLEGAL_PARAM SUCCESS */ ERRORTYPE AW_MPI_RGN_PackAttachToChn(RgnChnAttachPack *pstAttachPack, const MPP_CHN_S *pstChn) { ERRORTYPE ret = SUCCESS; RegionInfo *pRegionArray[RGN_PACK_MAX_ELEM_CNT] = {NULL}; if(pstAttachPack->nNum <= 0) { alogd("no RgnChnAttach"); return SUCCESS; } pthread_mutex_lock(&gpRegionManager->mLock); int i; for(i=0; inNum; i++) { ret = CheckRgnChnAttachValid_l(pstAttachPack->RgnChnAttachArray[i].nHandle, pstChn, &pstAttachPack->RgnChnAttachArray[i].stRgnChnAttr, &pRegionArray[i]); if(ret != SUCCESS) { alogw("RgnChnAttach[%d] is wrong", i); break; } } if(i != pstAttachPack->nNum) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_ILLEGAL_PARAM; } BOOL bAddFlag = FALSE; RgnChnAttachDetailPack stPack; memset(&stPack, 0, sizeof(RgnChnAttachDetailPack)); stPack.nNum = pstAttachPack->nNum; for(i=0; imRgnHandle; stPack.RgnChnAttachDetailArray[i].pRgnAttr = &pRegionArray[i]->mRgnAttr; stPack.RgnChnAttachDetailArray[i].pRgnChnAttr = &pstAttachPack->RgnChnAttachArray[i].stRgnChnAttr; stPack.RgnChnAttachDetailArray[i].pBmp = pRegionArray[i]->mbSetBmp?&pRegionArray[i]->mBmp:NULL; } //set chn /*if(MOD_ID_VIU == pstChn->mModId) { ret = AW_MPI_VI_SetRegions(pstChn->mDevId, &stPack); if(SUCCESS == ret) { bAddFlag = TRUE; } else { aloge("fatal error! vi set regions fail:0x%x", ret); } } else if(MOD_ID_VENC == pstChn->mModId) { ret = AW_MPI_VENC_SetRegions(pstChn->mChnId, &stPack); if(SUCCESS == ret) { bAddFlag = TRUE; } else { aloge("fatal error! venc set regions fail:0x%x", ret); } } else { aloge("fatal error! impossible moduleType[0x%x]", pstChn->mModId); }*/ ret = RGN_SetRegions(pstChn, &stPack); if (ret == SUCCESS) { bAddFlag = TRUE; } else { aloge("fatal error! module 0x%x set regions fail:0x%x!", pstChn->mModId, ret); } //add to list if(bAddFlag) { for(i=0; inNum; i++) { if(pstAttachPack->RgnChnAttachArray[i].nHandle != pRegionArray[i]->mRgnHandle) { aloge("fatal error! check rgn handle %d:%d!=%d", i, pstAttachPack->RgnChnAttachArray[i].nHandle, pRegionArray[i]->mRgnHandle); } RegionAttachChnInfo *pAttachChnInfo = (RegionAttachChnInfo*)malloc(sizeof(RegionAttachChnInfo)); if(NULL == pAttachChnInfo) { aloge("fatal error! malloc fail"); } memset(pAttachChnInfo, 0, sizeof(RegionAttachChnInfo)); pAttachChnInfo->mChn = *pstChn; pAttachChnInfo->mRgnChnAttr = pstAttachPack->RgnChnAttachArray[i].stRgnChnAttr; list_add_tail(&pAttachChnInfo->mList, &pRegionArray[i]->mAttachChnList); } ret = SUCCESS; } else { ret = ERR_RGN_ILLEGAL_PARAM; } pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } /** detach several regions from dstChn simultaneously. @param[in] pstDetachPack setting RgnChnAttachInfo->nHandle is enough, no need set RgnChnAttachInfo->stRgnChnAttr. @return ERR_RGN_ILLEGAL_PARAM ERR_RGN_UNEXIST SUCCESS */ ERRORTYPE AW_MPI_RGN_PackDetachFromChn(RgnChnAttachPack *pstDetachPack, const MPP_CHN_S *pstChn) { ERRORTYPE ret = SUCCESS; if(NULL == pstChn) { return ERR_RGN_ILLEGAL_PARAM; } if(0 == pstDetachPack->nNum) { //alogd("no region need be detach, return."); return ret; } RegionInfo *pRegionArray[RGN_PACK_MAX_ELEM_CNT] = {NULL}; RegionAttachChnInfo *pRgnAttachChnArray[RGN_PACK_MAX_ELEM_CNT] = {NULL}; pthread_mutex_lock(&gpRegionManager->mLock); int i; for(i=0; inNum; i++) { if(!(pstDetachPack->RgnChnAttachArray[i].nHandle>=0 && pstDetachPack->RgnChnAttachArray[i].nHandleRgnChnAttachArray[i].nHandle); ret = ERR_RGN_ILLEGAL_PARAM; break; } if(SUCCESS != searchExistRegion_l(pstDetachPack->RgnChnAttachArray[i].nHandle, &pRegionArray[i])) { aloge("fatal error! RgnHandle[%d-%d] unexist!", i, pstDetachPack->RgnChnAttachArray[i].nHandle); ret = ERR_RGN_UNEXIST; break; } int nCnt = 0; RegionAttachChnInfo *pEntry; list_for_each_entry(pEntry, &pRegionArray[i]->mAttachChnList, mList) { if(pEntry->mChn.mModId == pstChn->mModId && pEntry->mChn.mDevId == pstChn->mDevId && pEntry->mChn.mChnId == pstChn->mChnId) { if(0 == nCnt) { pRgnAttachChnArray[i] = pEntry; } nCnt++; } } if(nCnt <= 0) { aloge("fatal error! regionHandle[%d-%d] not find chn[%d-%d-%d]?", i, pstDetachPack->RgnChnAttachArray[i].nHandle, pstChn->mModId, pstChn->mDevId, pstChn->mChnId); ret = ERR_RGN_UNEXIST; break; } if(nCnt > 1) { aloge("fatal error! regionHandle[%d-%d] has more [%d]same dstChn[%d-%d-%d]?", i, pstDetachPack->RgnChnAttachArray[i].nHandle, nCnt, pstChn->mModId, pstChn->mDevId, pstChn->mChnId); ret = ERR_RGN_ILLEGAL_PARAM; break; } } if(i != pstDetachPack->nNum) { pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } RgnChnAttachDetailPack stPack; memset(&stPack, 0, sizeof(RgnChnAttachDetailPack)); stPack.nNum = pstDetachPack->nNum; for(i=0; iRgnChnAttachArray[i].nHandle; } /*if(MOD_ID_VIU == pstChn->mModId) { ret = AW_MPI_VI_DeleteRegions(pstChn->mDevId, &stPack); if(ret != SUCCESS) { aloge("fatal error! vi delete regions fail:0x%x", ret); } } else if(MOD_ID_VENC == pstChn->mModId) { ret = AW_MPI_VENC_DeleteRegions(pstChn->mChnId, &stPack); if(ret != SUCCESS) { aloge("fatal error! venc delete regions fail:0x%x", ret); } } else { aloge("fatal error! impossible moduleType[0x%x]", pstChn->mModId); }*/ ret = RGN_DeleteRegions(pstChn, &stPack); if (ret != SUCCESS) { aloge("fatal error! module 0x%x delete regions fail:0x%x!", pstChn->mModId, ret); } //delete from chnList for(i=0; inNum; i++) { list_del(&pRgnAttachChnArray[i]->mList); free(pRgnAttachChnArray[i]); pRgnAttachChnArray[i] = NULL; } pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } ERRORTYPE AW_MPI_RGN_SetDisplayAttr(RGN_HANDLE Handle, const MPP_CHN_S *pstChn, const RGN_CHN_ATTR_S *pstChnAttr) { ERRORTYPE ret = SUCCESS; if(!(Handle>=0 && Handle mLock); if(SUCCESS != searchExistRegion_l(Handle, &pRegion)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } //pthread_mutex_lock(&pRegion->mLock); int nCnt = 0; RegionAttachChnInfo *pEntry, *pDstChn; list_for_each_entry(pEntry, &pRegion->mAttachChnList, mList) { if(pEntry->mChn.mModId == pstChn->mModId && pEntry->mChn.mDevId == pstChn->mDevId && pEntry->mChn.mChnId == pstChn->mChnId) { if(0 == nCnt) { pDstChn = pEntry; } nCnt++; } } if(nCnt <= 0) { aloge("fatal error! not find chn[%d][%d][%d]?", pstChn->mModId, pstChn->mDevId, pstChn->mChnId); //pthread_mutex_unlock(&pRegion->mLock); pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } if(nCnt > 1) { aloge("fatal error! more [%d]same channels?", nCnt); } if(pDstChn->mRgnChnAttr.enType != pstChnAttr->enType) { aloge("fatal error! rgn type [0x%x] != [0x%x]?", pDstChn->mRgnChnAttr.enType, pstChnAttr->enType); pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_ILLEGAL_PARAM; } /*if(MOD_ID_VIU == pDstChn->mChn.mModId) { ret = AW_MPI_VI_UpdateRegionChnAttr(pDstChn->mChn.mDevId, Handle, pstChnAttr); if(SUCCESS == ret) { pDstChn->mRgnChnAttr = *pstChnAttr; } } else if(MOD_ID_VENC == pDstChn->mChn.mModId) { ret = AW_MPI_VENC_UpdateRegionChnAttr(pDstChn->mChn.mChnId, Handle, pstChnAttr); if(SUCCESS == ret) { pDstChn->mRgnChnAttr = *pstChnAttr; } } else { aloge("fatal error! impossible moduleType[0x%x]", pstChn->mModId); ret = ERR_RGN_ILLEGAL_PARAM; }*/ ret = RGN_UpdateRegionChnAttr(Handle, &pDstChn->mChn, pstChnAttr); if (ret != SUCCESS) { aloge("fatal error! module 0x%x set display attr fail:0x%x!", pstChn->mModId, ret); } //pthread_mutex_unlock(&pRegion->mLock); pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } ERRORTYPE AW_MPI_RGN_GetDisplayAttr(RGN_HANDLE Handle, const MPP_CHN_S *pstChn, RGN_CHN_ATTR_S *pstChnAttr) { ERRORTYPE ret = SUCCESS; if(!(Handle>=0 && Handle mLock); if(SUCCESS != searchExistRegion_l(Handle, &pRegion)) { pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } //pthread_mutex_lock(&pRegion->mLock); int nCnt = 0; RegionAttachChnInfo *pEntry, *pDstChn; list_for_each_entry(pEntry, &pRegion->mAttachChnList, mList) { if(pEntry->mChn.mModId == pstChn->mModId && pEntry->mChn.mDevId == pstChn->mDevId && pEntry->mChn.mChnId == pstChn->mChnId) { if(0 == nCnt) { pDstChn = pEntry; } nCnt++; } } if(nCnt <= 0) { aloge("fatal error! not find chn[%d][%d][%d]?", pstChn->mModId, pstChn->mDevId, pstChn->mChnId); //pthread_mutex_unlock(&pRegion->mLock); pthread_mutex_unlock(&gpRegionManager->mLock); return ERR_RGN_UNEXIST; } if(nCnt > 1) { aloge("fatal error! more [%d]same channels?", nCnt); } *pstChnAttr = pDstChn->mRgnChnAttr; //pthread_mutex_unlock(&pRegion->mLock); pthread_mutex_unlock(&gpRegionManager->mLock); return ret; } //ERRORTYPE AW_MPI_RGN_SetAttachField(RGN_HANDLE Handle, VIDEO_FIELD_E enAttachField); //ERRORTYPE AW_MPI_RGN_GetAttachField(RGN_HANDLE Handle, VIDEO_FIELD_E *penAttachField); //ERRORTYPE AW_MPI_RGN_GetCanvasInfo(RGN_HANDLE Handle, RGN_CANVAS_INFO_S *pstCanvasInfo); //ERRORTYPE AW_MPI_RGN_UpdateCanvas(RGN_HANDLE Handle);