struct ecore_ptt *ecore_ptt_acquire(struct ecore_hwfn *p_hwfn) { struct ecore_ptt *p_ptt; unsigned int i; /* Take the free PTT from the list */ for (i = 0; i < ECORE_BAR_ACQUIRE_TIMEOUT; i++) { OSAL_SPIN_LOCK(&p_hwfn->p_ptt_pool->lock); if (!OSAL_LIST_IS_EMPTY(&p_hwfn->p_ptt_pool->free_list)) { p_ptt = OSAL_LIST_FIRST_ENTRY( &p_hwfn->p_ptt_pool->free_list, struct ecore_ptt, list_entry); OSAL_LIST_REMOVE_ENTRY(&p_ptt->list_entry, &p_hwfn->p_ptt_pool->free_list); OSAL_SPIN_UNLOCK(&p_hwfn->p_ptt_pool->lock); DP_VERBOSE(p_hwfn, ECORE_MSG_HW, "allocated ptt %d\n", p_ptt->idx); return p_ptt; } OSAL_SPIN_UNLOCK(&p_hwfn->p_ptt_pool->lock); OSAL_MSLEEP(1); }
/****************************************************************************** 解码一帧 ******************************************************************************/ SINT32 iMediaSoftDEC_Decode(iMediaSDEC_CTX_S *pCtx, DEC_STREAM_PACKET_S *pPacket) { UINT32 i; SINT32 s32Ret; STRU_IVIDDEC_STREAM stStream; STRU_IVIDDEC_OUT_ARGS stDecOutArgs; STRU_IVIDEO_PICTURE *pstPic; IMAGE *pstImg; UINT8 *pu8Luma; UINT8 *pu8Chrom; UINT32 u32AspectRatio = 0; // aspect_ratio UINT32 u32FldFirst = 0; // 场序: 0=top first, 1=bottom first UINT32 u32SrcFmt = 0; // 逐行/隔行: 0=progressive, 1=interlaced UINT32 u32VideoFmt = 1; // 制式: 1=pal, 2=ntsc UINT32 u32CodType = 0; // 帧类型: 0=I, 1=P, 2=B /*UINT32 time1, time2, time3; UINT32 hit0,hit1, req0, req1;; */ static UINT32 *p1 = 0; static UINT32 last_image_id = -1; if (1 == pPacket->StreamPack[0].IsStreamEnd) { if (last_image_id >= 0 && last_image_id < iMediaSDEC_MAX_IMAGE_NUM) { (pVfmwToSvdecFun->pfnVfmwLastFrameNotify)(pCtx->ChanID, last_image_id); last_image_id = -1; } return iMediaSDEC_NOT_DEC; } /* y00226912 双核情况下,不断报警,暂时去掉不影响解码(修正?) if (p1 == 0) { MEM_RECORD_S MemRec; (pVfmwToSvdecFun->pfnVfmwMemMapRegisterAddr)(0x16800600, 0x400, &MemRec); // 查看L2 cache命中率 // MEM_MapRegisterAddr(0x16800600, 0x400, &MemRec); // 查看L2 cache命中率 p1 = (UINT32*)MemRec.VirAddr; } */ /* 解码输入参数 */ stStream.pucBuf = pPacket->StreamPack[0].VirAddr; stStream.uiNumBytes = pPacket->StreamPack[0].LenInByte; stStream.iPTS = (UINT32)pPacket->StreamPack[0].Pts; /* 调用iMedia库解码一帧码流 */ memset(&stDecOutArgs, 0, sizeof(stDecOutArgs)); s32Ret = IMedia_Viddec_FrameDecode(pCtx->CodecInstHandle, &stStream, &stDecOutArgs); #if 0 printk("IMedia_Viddec_FrameDecode return %d\n", s32Ret); printk("decode image properties:\n"); printk("%-20s :%d\n", "iErrorCode", stDecOutArgs.iErrorCode); printk("%-20s :%d\n", "uiBytesConsumed", stDecOutArgs.uiBytesConsumed); printk("%-20s :%d\n", "uiDisplayID", stDecOutArgs.uiDisplayID); printk("%-20s :%d\n", "iPTS", stDecOutArgs.iPTS); printk("%-20s :%d\n", "bLastFrameFlag", stDecOutArgs.bLastFrameFlag); printk("%-20s :%d\n", "usWidth", stDecOutArgs.stPicture.usWidth); printk("%-20s :%d\n", "usHeight", stDecOutArgs.stPicture.usHeight); printk("%-20s :%d\n", "usWidthPitch", stDecOutArgs.stPicture.usWidthPitch); printk("%-20s :%d\n", "eContentType", stDecOutArgs.stPicture.eContentType); printk("%-20s :%p\n", "y addr", stDecOutArgs.stPicture.apucBuf[0]); printk("%-20s :%p\n", "u addr", stDecOutArgs.stPicture.apucBuf[1]); printk("%-20s :%p\n", "v addr", stDecOutArgs.stPicture.apucBuf[2]); if (stDecOutArgs.stPicture.apucBuf[0] && stDecOutArgs.stPicture.apucBuf[1] && stDecOutArgs.stPicture.apucBuf[2]) { SaveYUV(stDecOutArgs.stPicture.usWidth, stDecOutArgs.stPicture.usHeight, stDecOutArgs.stPicture.apucBuf[0], stDecOutArgs.stPicture.apucBuf[1], stDecOutArgs.stPicture.apucBuf[2], stDecOutArgs.stPicture.usWidthPitch); } OSAL_MSLEEP(500); #endif /* 如果iMedia有图像输出,则将此图像读出,转换格式后写入到显示图像空间去,等待VO读取 */ if (stDecOutArgs.stPicture.apucBuf[0] && stDecOutArgs.stPicture.apucBuf[1] && stDecOutArgs.stPicture.apucBuf[2] && 0==s32Ret) { UINT32 bReversed = 0; /* 转换色色度格式, 使UV间插存放 */ pstPic = &stDecOutArgs.stPicture; pu8Chrom = pstPic->apucBuf[0] + pstPic->usWidthPitch * (UP_ALIGN_16(pstPic->usHeight) + 16); if ( (STD_VP6 == pCtx->eVidStd) || (STD_VP6F == pCtx->eVidStd) || (STD_VP6A == pCtx->eVidStd) ) { bReversed = pCtx->pstExtraData->StdExt.Vp6Ext.bReversed; } else { bReversed = 0; } if (1 == bReversed) { pu8Luma = pu8Chrom + pstPic->usWidthPitch * (UP_ALIGN_16(pstPic->usHeight) / 2); } else { pu8Luma = pstPic->apucBuf[0]; } ConvFormat(pstPic->usWidth/2, pstPic->usHeight/2, pstPic->usWidthPitch/2, pstPic->apucBuf[0], pstPic->apucBuf[1], pstPic->apucBuf[2], pu8Luma, pu8Chrom, bReversed); #ifdef ENV_ARMLINUX_KERNEL (pVfmwToSvdecFun->pfnVfmwKlibFlushCache)(pu8Luma, (pVfmwToSvdecFun->pfnVfmwMemVir2Phy)(pu8Luma), pstPic->usWidthPitch * pstPic->usHeight); (pVfmwToSvdecFun->pfnVfmwKlibFlushCache)(pu8Chrom, (pVfmwToSvdecFun->pfnVfmwMemVir2Phy)(pu8Chrom), pstPic->usWidthPitch * pstPic->usHeight / 2); // klib_flush_cache(pu8Luma, MEM_Vir2Phy(pu8Luma), pstPic->usWidthPitch * pstPic->usHeight); // klib_flush_cache(pu8Chrom, MEM_Vir2Phy(pu8Chrom), pstPic->usWidthPitch * pstPic->usHeight / 2); #endif /* 寻找一个空闲的IMAGE槽位存放刚刚解码的帧信息 */ for (i = 0; i < iMediaSDEC_MAX_IMAGE_NUM; i++) { if (0 == pCtx->ImageUsedFlag[i]) { break; } } /* 如果槽位占满: 将所有帧释放给解码库,然后清空IMAGE集 */ if (i >= iMediaSDEC_MAX_IMAGE_NUM) { for (i = 0; i < iMediaSDEC_MAX_IMAGE_NUM; i++) { iMediaSoftDEC_RecycleImage(pCtx, i); } i = 0; } pstImg = &pCtx->stImgs[i]; pstImg->image_id = i; pstImg->PTS = pCtx->pstExtraData->pts; pCtx->pstExtraData->pts = -1; pstImg->top_luma_phy_addr = bReversed ? iMediaSDEC_VIR_2_PHY(pu8Luma) : iMediaSDEC_VIR_2_PHY(pstPic->apucBuf[0]); pstImg->top_chrom_phy_addr = iMediaSDEC_VIR_2_PHY(pu8Chrom); pstImg->btm_luma_phy_addr = pstImg->top_luma_phy_addr + pstPic->usWidthPitch; pstImg->btm_chrom_phy_addr = pstImg->top_chrom_phy_addr + pstPic->usWidthPitch; pstImg->luma_2d_phy_addr = pstImg->top_luma_phy_addr; pstImg->luma_2d_vir_addr = pstPic->apucBuf[0]; pstImg->chrom_2d_phy_addr = pstImg->top_chrom_phy_addr; pstImg->chrom_2d_vir_addr = pu8Chrom; /* 设置宽高比的两个参数 */ SetAspectRatio(pstImg, (VDEC_DAR_E) u32AspectRatio); pstImg->format = ((u32AspectRatio&7)<<14) | ((u32FldFirst&0x3)<<12) | (3<<10) | ((u32SrcFmt&3)<<8) | ((u32VideoFmt&3)<<5) | ((0&7)<<2) // yuv420 | (u32CodType&3); pstImg->image_width = pstPic->usWidth; pstImg->image_height = pstPic->usHeight; pstImg->disp_width = pstPic->usWidth; pstImg->disp_height = pstPic->usHeight; pstImg->disp_center_x = pstPic->usWidth / 2; pstImg->disp_center_y = pstPic->usHeight / 2; pstImg->image_stride = pstPic->usWidthPitch; pstImg->frame_rate = 25 << 10; pstImg->error_level = 0; pstImg->ImageDnr.video_standard = pCtx->eVidStd; /* 将此图像插入输出队列 */ pCtx->ImageUsedFlag[i] = 1; memcpy(&pCtx->stVidPics[i], pstPic, sizeof(STRU_IVIDEO_PICTURE)); // if( VF_OK != InsertImgToVoQueue(pCtx->ChanID, pCtx->eVidStd, pCtx, &pCtx->ImageQue, pstImg)) if(VF_OK != (pVfmwToSvdecFun->pfnVfmwInsertImgToVoQueue)(pCtx->ChanID, pCtx->eVidStd, pCtx, &pCtx->ImageQue, pstImg)) { IMedia_Viddec_Control(pCtx->CodecInstHandle, IMEDIA_PICTURE_RELEASE, pstPic, NULL); pCtx->ImageUsedFlag[i] = 0; } else { last_image_id = pstImg->image_id; } } if (stDecOutArgs.uiBytesConsumed == 0) { return iMediaSDEC_NOT_DEC; } return iMediaSDEC_OK; }