Hi,
I am working to get multichannel decoder use case in DVR RDK using Link API's. And I have few issues.
Here is the use case code.
#include <demos/link_api_demos/common/chains.h>
#include <mcfw/interfaces/ti_venc.h>
static SystemVideo_Ivahd2ChMap_Tbl systemVid_encDecIvaChMapTbl =
{
.isPopulated = 1,
.ivaMap[0] =
{
.EncNumCh = 10,
.EncChList = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0 , 0, 0},
.DecNumCh = 0,
.DecChList = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
.ivaMap[1] =
{
.EncNumCh = 0,
.EncChList = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
.DecNumCh = 12,
.DecChList = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0 , 0, 0},
},
.ivaMap[2] =
{
.EncNumCh = 6,
.EncChList = {10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
.DecNumCh = 4,
.DecChList = {12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
};
Void test(Chains_Ctrl *chainsCfg)
{
//write file to disk
CaptureLink_CreateParams capturePrm;
CaptureLink_VipInstParams *pCaptureInstPrm;
CaptureLink_OutParams *pCaptureOutPrm;
DupLink_CreateParams dup1Prm;
DupLink_CreateParams dup2Prm;
SwMsLink_CreateParams swMsPrm[2];
DisplayLink_CreateParams displayPrm[2];
IpcLink_CreateParams ipcOutVpssPrm;
IpcLink_CreateParams ipcInVideoPrm;
EncLink_CreateParams encPrm;
IpcBitsOutLinkRTOS_CreateParams ipcBitsOutVideoPrm;
IpcBitsInLinkHLOS_CreateParams ipcBitsInHostPrm;
//read file to processor
MergeLink_CreateParams mergePrm;
IpcBitsOutLinkHLOS_CreateParams ipcBitsOutHostPrm;
IpcBitsInLinkRTOS_CreateParams ipcBitsInVideoPrm;
DecLink_CreateParams decPrm;
IpcLink_CreateParams ipcOutVideoPrm;
IpcLink_CreateParams ipcInVpssPrm;
//write file to disk
UInt32 captureId, vipInstId;
UInt32 dup1Id,dup2Id,mergeId;
UInt32 swMsId[2];
UInt32 displayId[2];
UInt32 ipcOutVpssId;
UInt32 ipcInVideoId;
UInt32 encId;
UInt32 ipcBitsOutVideoId;
UInt32 ipcBitsInHostId;
//read file to processor
UInt32 ipcBitsOutHostId;
UInt32 ipcBitsInVideoId;
UInt32 decId;
UInt32 ipcOutVideoId;
UInt32 ipcInVpssId;
UInt32 i;
char ch;
//write file to disk
CHAINS_INIT_STRUCT(CaptureLink_CreateParams,capturePrm);
CHAINS_INIT_STRUCT(SwMsLink_CreateParams,swMsPrm[0]);
CHAINS_INIT_STRUCT(DisplayLink_CreateParams,displayPrm[0]);
CHAINS_INIT_STRUCT(IpcLink_CreateParams,ipcOutVpssPrm);
CHAINS_INIT_STRUCT(IpcLink_CreateParams,ipcInVideoPrm);
CHAINS_INIT_STRUCT(EncLink_CreateParams,encPrm);
CHAINS_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams,ipcBitsOutVideoPrm);
CHAINS_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams,ipcBitsInHostPrm);
//read file to processor
CHAINS_INIT_STRUCT(IpcBitsOutLinkHLOS_CreateParams,ipcBitsOutHostPrm);
CHAINS_INIT_STRUCT(IpcBitsInLinkRTOS_CreateParams,ipcBitsInVideoPrm);
CHAINS_INIT_STRUCT(DecLink_CreateParams, decPrm);
CHAINS_INIT_STRUCT(IpcLink_CreateParams,ipcOutVideoPrm);
CHAINS_INIT_STRUCT(IpcLink_CreateParams,ipcInVpssPrm);
CHAINS_INIT_STRUCT(SwMsLink_CreateParams, swMsPrm[1]);
CHAINS_INIT_STRUCT(DisplayLink_CreateParams,displayPrm[1]);
//write file to disk
captureId = SYSTEM_LINK_ID_CAPTURE;
dup1Id = SYSTEM_VPSS_LINK_ID_DUP_0;
dup2Id = SYSTEM_VPSS_LINK_ID_DUP_1;
mergeId = SYSTEM_VPSS_LINK_ID_MERGE_0;
swMsId[0] = SYSTEM_LINK_ID_SW_MS_MULTI_INST_0;
displayId[0] = SYSTEM_LINK_ID_DISPLAY_0;
encId = SYSTEM_LINK_ID_VENC_0;
ipcOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0;
ipcInVideoId = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0;
ipcBitsOutVideoId = SYSTEM_VIDEO_LINK_ID_IPC_BITS_OUT_0;
ipcBitsInHostId = SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0;
//read file to processor
ipcBitsOutHostId = SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0;
ipcBitsInVideoId = SYSTEM_VIDEO_LINK_ID_IPC_BITS_IN_0;
decId = SYSTEM_LINK_ID_VDEC_0;
ipcOutVideoId = SYSTEM_VIDEO_LINK_ID_IPC_OUT_M3_0;
ipcInVpssId = SYSTEM_VPSS_LINK_ID_IPC_IN_M3_0;
swMsId[1] = SYSTEM_LINK_ID_SW_MS_MULTI_INST_1;
displayId[1] = SYSTEM_LINK_ID_DISPLAY_1;
System_linkControl(SYSTEM_LINK_ID_M3VIDEO,SYSTEM_COMMON_CMD_SET_CH2IVAHD_MAP_TBL,&systemVid_encDecIvaChMapTbl,sizeof(SystemVideo_Ivahd2ChMap_Tbl),TRUE);
capturePrm.numVipInst = 1;
capturePrm.tilerEnable = TRUE;
capturePrm.numBufsPerCh = 16;
capturePrm.numExtraBufs = 0;
capturePrm.maxBlindAreasPerCh = 0;
capturePrm.isPalMode = FALSE;
capturePrm.enableSdCrop = FALSE;
capturePrm.doCropInCapture = FALSE;
for(i=0; i<capturePrm.numVipInst; i++)
{
vipInstId = SYSTEM_CAPTURE_INST_VIP0_PORTA + 2*i;
pCaptureInstPrm = &capturePrm.vipInst[i];
pCaptureInstPrm->vipInstId = vipInstId%SYSTEM_CAPTURE_INST_MAX;
pCaptureInstPrm->videoDecoderId = SYSTEM_DEVICE_VID_DEC_SII9233A_DRV;
pCaptureInstPrm->inDataFormat = SYSTEM_DF_YUV422P;
pCaptureInstPrm->standard = chainsCfg->displayRes[i];
pCaptureInstPrm->numOutput = 1;
pCaptureInstPrm->numChPerOutput = 1;
pCaptureInstPrm->frameCaptureMode = FALSE;
pCaptureInstPrm->fieldsMerged = FALSE;
pCaptureOutPrm = &pCaptureInstPrm->outParams[0];
pCaptureOutPrm->dataFormat = SYSTEM_DF_YUV420SP_UV;
pCaptureOutPrm->scEnable = FALSE;
pCaptureOutPrm->scOutWidth = chainsCfg->channelConf[i].width;
pCaptureOutPrm->scOutHeight = chainsCfg->channelConf[i].height;
pCaptureOutPrm->outQueId = 0;
}
capturePrm.outQueParams[0].nextLink = dup1Id;
System_linkCreate(captureId, &capturePrm, sizeof(capturePrm));
chainsCfg->displayRes[0] = capturePrm.vipInst[0].standard;
Vsys_getResSize(chainsCfg->displayRes[0], &chainsCfg->channelConf[0].width, &chainsCfg->channelConf[0].height);
Vsys_getResRate(chainsCfg->displayRes[0], &chainsCfg->channelConf[0].frameRate);
//captrue OK~
Chains_displayCtrlInit(chainsCfg->displayRes);
dup1Prm.inQueParams.prevLinkId = captureId;
dup1Prm.inQueParams.prevLinkQueId = 0;
dup1Prm.numOutQue = 2;
dup1Prm.outQueParams[0].nextLink = mergeId;
dup1Prm.outQueParams[1].nextLink = ipcOutVpssId;
dup1Prm.notifyNextLink = TRUE;
ipcOutVpssPrm.inQueParams.prevLinkId = dup1Id;
ipcOutVpssPrm.inQueParams.prevLinkQueId = 1;
ipcOutVpssPrm.numOutQue = 1;
ipcOutVpssPrm.outQueParams[0].nextLink = ipcInVideoId;
ipcOutVpssPrm.notifyNextLink = FALSE;
ipcOutVpssPrm.notifyPrevLink = TRUE;
ipcOutVpssPrm.noNotifyMode = TRUE;
ipcInVideoPrm.inQueParams.prevLinkId = ipcOutVpssId;
ipcInVideoPrm.inQueParams.prevLinkQueId = 0;
ipcInVideoPrm.numOutQue = 1;
ipcInVideoPrm.outQueParams[0].nextLink = encId;
ipcInVideoPrm.notifyNextLink = TRUE;
ipcInVideoPrm.notifyPrevLink = FALSE;
ipcInVideoPrm.noNotifyMode = TRUE;
for (i=0; i<1; i++) {
encPrm.chCreateParams[i].format = chainsCfg->channelConf[i].encFormat;
encPrm.chCreateParams[i].profile = chainsCfg->channelConf[i].encProfile;
encPrm.chCreateParams[i].dataLayout = IVIDEO_FIELD_SEPARATED;
encPrm.chCreateParams[i].fieldMergeEncodeEnable = FALSE;
encPrm.chCreateParams[i].enableAnalyticinfo = FALSE;
encPrm.chCreateParams[i].enableWaterMarking = FALSE;
encPrm.chCreateParams[i].encodingPreset = XDM_USER_DEFINED;
encPrm.chCreateParams[i].rateControlPreset = IVIDEO_USER_DEFINED;
encPrm.chCreateParams[i].enableHighSpeed = FALSE;
encPrm.chCreateParams[i].defaultDynamicParams.interFrameInterval = 1;
encPrm.chCreateParams[i].defaultDynamicParams.intraFrameInterval = chainsCfg->channelConf[i].intraFrameInterval;
encPrm.chCreateParams[i].defaultDynamicParams.inputFrameRate = chainsCfg->channelConf[i].frameRate;
encPrm.chCreateParams[i].defaultDynamicParams.targetFrameRate = chainsCfg->channelConf[i].encFrameRate;
encPrm.chCreateParams[i].defaultDynamicParams.targetBitRate = chainsCfg->channelConf[i].bitRate;
encPrm.chCreateParams[i].defaultDynamicParams.mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
encPrm.chCreateParams[i].defaultDynamicParams.rcAlg = chainsCfg->channelConf[i].rateCtrl;
encPrm.chCreateParams[i].defaultDynamicParams.qpMin = 0;
encPrm.chCreateParams[i].defaultDynamicParams.qpMax = 51;
encPrm.chCreateParams[i].defaultDynamicParams.qpInit = -1;
encPrm.chCreateParams[i].defaultDynamicParams.vbrDuration = 8;
encPrm.chCreateParams[i].defaultDynamicParams.vbrSensitivity = 0;
}
encPrm.inQueParams.prevLinkId = ipcInVideoId;
encPrm.inQueParams.prevLinkQueId= 0;
encPrm.outQueParams.nextLink = ipcBitsOutVideoId;
encPrm.numBufPerCh[0] = 0;
ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkId = encId;
ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkQueId = 0;
ipcBitsOutVideoPrm.baseCreateParams.numOutQue = 1;
ipcBitsOutVideoPrm.baseCreateParams.outQueParams[0].nextLink = ipcBitsInHostId;
Chains_ipcBitsInitCreateParams_BitsOutRTOS(&ipcBitsOutVideoPrm,TRUE);
ipcBitsInHostPrm.baseCreateParams.inQueParams.prevLinkId = ipcBitsOutVideoId;
ipcBitsInHostPrm.baseCreateParams.inQueParams.prevLinkQueId = 0;
Chains_ipcBitsInitCreateParams_BitsInHLOS(&ipcBitsInHostPrm);
System_linkCreate(dup1Id, &dup1Prm, sizeof(dup1Prm));
System_linkCreate(ipcOutVpssId, &ipcOutVpssPrm, sizeof(ipcOutVpssPrm));
System_linkCreate(ipcInVideoId, &ipcInVideoPrm, sizeof(ipcInVideoPrm));
System_linkCreate(encId, &encPrm, sizeof(encPrm));
System_linkCreate(ipcBitsOutVideoId, &ipcBitsOutVideoPrm, sizeof(ipcBitsOutVideoPrm));
System_linkCreate(ipcBitsInHostId, &ipcBitsInHostPrm, sizeof(ipcBitsInHostPrm));
System_LinkInfo bitsProducerLinkInfo;
System_linkGetInfo(ipcBitsInHostId,&bitsProducerLinkInfo);
OSA_assert(bitsProducerLinkInfo.numQue = 1);
ipcBitsOutHostPrm.baseCreateParams.numOutQue = 1;
ipcBitsOutHostPrm.baseCreateParams.outQueParams[0].nextLink = ipcBitsInVideoId;
Chains_ipcBitsInitCreateParams_BitsOutHLOS(&ipcBitsOutHostPrm,&bitsProducerLinkInfo.queInfo[0]);
ipcBitsInVideoPrm.baseCreateParams.inQueParams.prevLinkId = ipcBitsOutHostId;
ipcBitsInVideoPrm.baseCreateParams.inQueParams.prevLinkQueId = 0;
ipcBitsInVideoPrm.baseCreateParams.numOutQue = 1;
ipcBitsInVideoPrm.baseCreateParams.outQueParams[0].nextLink = decId;
Chains_ipcBitsInitCreateParams_BitsInRTOS(&ipcBitsInVideoPrm,TRUE);
for (i=0; i<1; i++) {
decPrm.chCreateParams[i].format = chainsCfg->channelConf[i].encFormat;
decPrm.chCreateParams[i].profile = IH264VDEC_PROFILE_ANY;
decPrm.chCreateParams[i].targetMaxWidth = chainsCfg->channelConf[i].width;
decPrm.chCreateParams[i].targetMaxHeight = chainsCfg->channelConf[i].height;
decPrm.chCreateParams[i].fieldMergeDecodeEnable = FALSE;
decPrm.chCreateParams[i].numBufPerCh = 6;
decPrm.chCreateParams[i].defaultDynamicParams.targetFrameRate = chainsCfg->channelConf[i].encFrameRate;
decPrm.chCreateParams[i].defaultDynamicParams.targetBitRate = chainsCfg->channelConf[i].bitRate;
}
decPrm.inQueParams.prevLinkId = ipcBitsInVideoId;
decPrm.inQueParams.prevLinkQueId = 0;
decPrm.outQueParams.nextLink = ipcOutVideoId;
decPrm.tilerEnable = TRUE;
ipcOutVideoPrm.inQueParams.prevLinkId = decId;
ipcOutVideoPrm.inQueParams.prevLinkQueId = 0;
ipcOutVideoPrm.numOutQue = 1;
ipcOutVideoPrm.outQueParams[0].nextLink = ipcInVpssId;
ipcOutVideoPrm.notifyNextLink = FALSE;
ipcOutVideoPrm.notifyPrevLink = TRUE;
ipcOutVideoPrm.noNotifyMode = TRUE;
ipcInVpssPrm.inQueParams.prevLinkId = ipcOutVideoId;
ipcInVpssPrm.inQueParams.prevLinkQueId = 0;
ipcInVpssPrm.numOutQue = 1;
ipcInVpssPrm.outQueParams[0].nextLink = mergeId;
ipcInVpssPrm.notifyNextLink = TRUE;
ipcInVpssPrm.notifyPrevLink = FALSE;
ipcInVpssPrm.noNotifyMode = TRUE;
mergePrm.numInQue = 2;
mergePrm.inQueParams[0].prevLinkId = dup1Id;
mergePrm.inQueParams[0].prevLinkQueId = 0;
mergePrm.inQueParams[1].prevLinkId = ipcInVpssId;
mergePrm.inQueParams[1].prevLinkQueId = 0;
mergePrm.outQueParams.nextLink = swMsId[0];
mergePrm.notifyNextLink = TRUE;
dup2Prm.inQueParams.prevLinkId = mergeId;
dup2Prm.inQueParams.prevLinkQueId = 0;
dup2Prm.numOutQue = 2;
dup2Prm.outQueParams[0].nextLink = swMsId[0];
dup2Prm.outQueParams[1].nextLink = swMsId[1];
dup2Prm.notifyNextLink = TRUE;
for (i=0; i<1; i++) {
swMsPrm[i].numSwMsInst =1;
swMsPrm[i].swMsInstId[0] =SYSTEM_SW_MS_SC_INST_SC5;
swMsPrm[i].inQueParams.prevLinkId = dup2Id;
swMsPrm[i].inQueParams.prevLinkQueId = i;
swMsPrm[i].outQueParams.nextLink = displayId[i];
swMsPrm[i].lineSkipMode = FALSE;
swMsPrm[i].enableLayoutGridDraw = FALSE;
swMsPrm[i].layoutPrm.outputFPS = chainsCfg->channelConf[0].frameRate;
swMsPrm[i].maxInputQueLen = SYSTEM_SW_MS_DEFAULT_INPUT_QUE_LEN;
swMsPrm[i].maxOutRes = chainsCfg->displayRes[0];
swMsPrm[i].numOutBuf = 0;
Chains_swMsSetLayoutParams(1, &swMsPrm[i]);
displayPrm[i].displayRes = chainsCfg->displayRes[0];
displayPrm[i].numInputQueues = 1;
displayPrm[i].activeQueue = 0;
displayPrm[i].inQueParams[0].prevLinkId = swMsId[i];
displayPrm[i].inQueParams[0].prevLinkQueId = 0;
displayPrm[i].forceFieldSeparatedInputMode = FALSE;
}
System_linkCreate(mergeId,&mergePrm,sizeof(mergePrm));
System_linkCreate(ipcBitsOutHostId,&ipcBitsOutHostPrm,sizeof(ipcBitsOutHostPrm));
System_linkCreate(ipcBitsInVideoId,&ipcBitsInVideoPrm,sizeof(ipcBitsInVideoPrm));
System_linkCreate(decId, &decPrm, sizeof(decPrm));
System_linkCreate(ipcOutVideoId, &ipcOutVideoPrm, sizeof(ipcOutVideoPrm));
System_linkCreate(ipcInVpssId , &ipcInVpssPrm , sizeof(ipcInVpssPrm));
System_linkCreate(dup2Id,&dup2Prm,sizeof(dup2Prm));
for (i=0; i<1; i++) {
System_linkCreate(swMsId[i], &swMsPrm[i], sizeof(swMsPrm[i]));
System_linkCreate(displayId[i], &displayPrm[i], sizeof(displayPrm[i]));
}
Chains_memPrintHeapStatus();
{
for (i=0; i<1; i++) {
System_linkStart(displayId[i]);
System_linkStart(swMsId[i]);
}
System_linkStart(dup2Id);
System_linkStart(ipcInVpssId);
System_linkStart(ipcOutVideoId);
System_linkStart(decId);
System_linkStart(ipcBitsInVideoId);
System_linkStart(ipcBitsOutHostId);
System_linkStart(mergeId);
System_linkStart(ipcBitsInHostId);
System_linkStart(ipcBitsOutVideoId);
System_linkStart(encId);
System_linkStart(ipcInVideoId);
System_linkStart(ipcOutVpssId);
System_linkStart(dup1Id);
System_linkStart(captureId);
while(1)
{
ch = Chains_menuRunTime();
printf("%c\n",ch);
if(ch=='0')
break;
if(ch=='v')
System_linkControl(captureId, CAPTURE_LINK_CMD_FORCE_RESET, NULL, 0, TRUE);
if(ch=='p')
System_linkControl(captureId, CAPTURE_LINK_CMD_PRINT_ADV_STATISTICS, NULL, 0, TRUE);
if(ch=='w') demo_write_diskStop();
if(ch=='j') demo_write_diskInit();
if(ch=='r') demo_read_fileStop();
if(ch=='k') demo_read_fileInit();
if(ch=='f') forward_seconds(55);
if(ch=='b') backward_seconds(59);
}
// Chains_ipcBitsStop();
demo_write_diskStop();
demo_read_fileStop();
System_linkStop(captureId);
System_linkStop(dup1Id);
System_linkStop(ipcOutVpssId);
System_linkStop(ipcInVideoId);
System_linkStop(encId);
System_linkStop(ipcBitsOutVideoId);
System_linkStop(ipcBitsInHostId);
System_linkStop(mergeId);
System_linkStop(ipcBitsOutHostId);
System_linkStop(ipcBitsInVideoId);
System_linkStop(decId);
System_linkStop(ipcOutVideoId);
System_linkStop(ipcInVpssId);
for (i=0; i<1; i++) {
System_linkStop(swMsId[i]);
System_linkStop(displayId[i]);
}
}
System_linkDelete(captureId);
System_linkDelete(dup1Id);
System_linkDelete(ipcOutVpssId);
System_linkDelete(ipcInVideoId);
System_linkDelete(encId);
System_linkDelete(ipcBitsOutVideoId);
System_linkDelete(ipcBitsInHostId);
System_linkDelete(mergeId);
System_linkDelete(ipcBitsOutHostId);
System_linkDelete(ipcBitsInVideoId);
System_linkDelete(decId);
System_linkDelete(ipcOutVideoId);
System_linkDelete(ipcInVpssId);
for (i=0; i<1; i++){
System_linkDelete(swMsId[i]);
System_linkDelete(displayId[i]);
}
Chains_displayCtrlDeInit();
}
}
//////////////////////////////////////////////////////////////////////////////
One ch-capture->dup1->(merge||ipcOutVpss)
ipcOutVpss->ipcInVideo->enc->ipcBitsOutVideo->ipcBitsInHost->write to file
read from file->ipcBitsOutHost->ipcBitsInVideo->dec->ipcOutVideo->ipcInVpss->merge->dup2
dup2->(swMs[0] and swMs[1])->display[0](swMs[0]) and diplay[1](swMs[0])
mergePrm.numInQue = 2;
mergePrm.inQueParams[0].prevLinkId = dup1Id;
mergePrm.inQueParams[0].prevLinkQueId = 0;
mergePrm.inQueParams[1].prevLinkId = ipcInVpssId;
mergePrm.inQueParams[1].prevLinkQueId = 0;
mergePrm.outQueParams.nextLink = swMsId[0];
mergePrm.notifyNextLink = TRUE;
Only the capture video from dup1 can display
I change the code as follows
mergePrm.numInQue = 2;
mergePrm.inQueParams[0].prevLinkId = ipcInVpssId;
mergePrm.inQueParams[0].prevLinkQueId = 0;
mergePrm.inQueParams[1].prevLinkId = dup1Id;
mergePrm.inQueParams[1].prevLinkQueId = 0;
mergePrm.outQueParams.nextLink = swMsId[0];
mergePrm.notifyNextLink = TRUE;
the video read from file can display .
I don't kown how to use the merge API