我修改了demos_vdec_vdis例子,把8个500万像素的jpg图片拷入内存,在一个通道中轮流解码显示。我发现当帧间隔小于80ms时,就会出错。错误如下。
4054:!!!SLAVE CORE DOWN!!!.EXCEPTION INFO DUMP
!!HW EXCEPTION ACTIVE (0/1): [0]
!!EXCEPTION CORE NAME : [VIDEO-M3]
!!EXCEPTION TASK NAME : [DEC0 ]
!!EXCEPTION LOCATION : [links_m3video/iva_dec/decLink_common.c:795]
!!EXCEPTION INFO : [(pFrameInfo != NULL) && UTILS_ARRAYISVALIDENTRY(pFrameInfo, pObj->outObj.outChObj[chId].frameInfo)]
!!EXCEPTION CCS CRASH DUMP FORMAT FILE STORED @ ./CCS_CRASH_DUMP_VIDEO-M3.txt
SystemLink_handleSlaveCoreException:154
但我们的系统希望帧间隔为25ms。
Chris Meng:
你好,
请问是jpeg单独解码么?如果你把8个500万像素的jpg拼成一个mjpeg文件,让系统自己去读去文件解码,这样会有同样的问题么?
不知道你使用的IVAHD的频率是多少,一般来说一个IVAHD至少是1080p60的性能,对于5Mp的图像就是24帧,那间隔是42ms左右,如果IVAHD的频率较高,帧率还可以更高,间隔就会变短。
gaohao wang:
回复 Chris Meng:
我找到初步的原因了,是因为我把500万像素的原图缩小成cif图,然后把原图和cif图送至dsp核作分析,再将叠加了分析结果的500万像素原图送到马赛克link做显示。如果不需要显示500万像素原图,只显示cif图,那帧率为30。
大体流程为:
jpgBuffer
|
V
videoM3解码成500万像素原图
|
V
sclrLink缩小成cif
|
V
ipcFramesOut–>processLink送到dsp做分析
|
V
dupLink–>马赛克做显示
|
V
ipcOutVpss送到video做编码
为此,我在指向cif图的FVID2_Frame里面加入了一个adjointFrame字段,指向500万像素原图的FVID2_Frame。然后在马赛克link里面将此两者替换,以显示500万像素原图。然后在dupLink里面再将其再次替换。代码如下。
FVID2_Frame temp, *adjointFrame; adjointFrame = frame->adjointFrame; memcpy(&temp, frame, sizeof(FVID2_Frame)); memcpy(frame, adjointFrame, sizeof(FVID2_Frame)); frame->adjointFrame = adjointFrame; memcpy(frame->adjointFrame, &temp, sizeof(FVID2_Frame));
如果我不做这两次替换,那么帧率可达30。问题是,这两次替换为什么会造成必须下降帧率?有什么解决办法?谢谢。
Chris Meng:
回复 gaohao wang:
你好,
M3就200来兆,上面做memcpy应该会很耗cpu。建议传递指针而不要复制内容。
gaohao wang:
回复 Chris Meng:
我刚才也这样猜。然后代码修改如下:
在SwMsLink_drvQueueInputFrames()函数里面,把3次memcpy替换成
FVID2_Frame *temp = (FVID2_Frame *)(frame->adjointFrame); temp->adjointFrame = (Ptr)frame; frame = temp;
在DupLink_putEmptyFrames()函数里面,把另外3次memcpy替换成
pFrame = pFrame->adjointFrame;
但是情况也没有改善。当设置帧间隔为33ms时,跑到320处出错,打印出两种错误,且马赛克有两个窗口在显示,而不是一个。
[m3video] 31109:DECLINK::links_m3video/iva_dec/decLink_jpeg.c:[201]::INTERNAL ERROR:-1 [m3video] ALGPROCESS FAILED:STATUS [m3video] 31109:WARN [m3video] DECLINK:ERROR in Declink_jpegDecodeFrameBatch.Status[-1]
以及
16501:!!!SLAVE CORE DOWN!!!.EXCEPTION INFO DUMP
!!HW EXCEPTION ACTIVE (0/1): [0]
!!EXCEPTION CORE NAME : [VPSS-M3]
!!EXCEPTION TASK NAME : [SWMS0]
!!EXCEPTION LOCATION : [links_m3vpss/swMs/swMsLink_drv.c:2970]
!!EXCEPTION INFO : [status == FVID2_SOK]
在我的代码里,2970处为
status = FVID2_processFrames(pDrvObj[i]->fvidHandle, &pDrvObj[i]->processList); UTILS_assert(status == FVID2_SOK);
如果把帧间隔设为50ms和80ms,结果还是一样,在320帧处出错,打印同样的错误。不同的是,帧间隔为50ms的时候,图像显示在两个马赛克窗口,这是错误的。帧间隔为80ms的时候,图像显示在一个马赛克窗口。
gaohao wang:
回复 gaohao wang:
是否320是某个队列的长度?此队列元素一直不能释放,到此长度程序就崩溃了。
gaohao wang:
回复 gaohao wang:
帧间隔调整到200ms,还是在320帧出错,还是同样的错误:
68357:!!!SLAVE CORE DOWN!!!.EXCEPTION INFO DUMP
!!HW EXCEPTION ACTIVE (0/1): [0]
!!EXCEPTION CORE NAME : [VPSS-M3]
!!EXCEPTION TASK NAME : [SWMS0]
!!EXCEPTION LOCATION : [links_m3vpss/swMs/swMsLink_drv.c:2970]
!!EXCEPTION INFO : [status == FVID2_SOK]
[m3video] 111744:DECLINK::links_m3video/iva_dec/decLink_jpeg.c:[201]::INTERNAL ERROR:-1 [m3video] ALGPROCESS FAILED:STATUS [m3video] 111744:WARN [m3video] DECLINK:ERROR in Declink_jpegDecodeFrameBatch.Status[-1]
希望能帮助解决,谢谢。
gaohao wang:
回复 gaohao wang:
我现在又回到memcpy的思路。
但是是自己拷贝,而不用memcpy。代码如下。
FVID2_Frame *adjointFrame;UInt32 i,FVID2_FrameSize;UInt64 temp64;FVID2_FrameSize = sizeof(FVID2_Frame)>>3; adjointFrame = pFrame->adjointFrame;
for(i=0; i<FVID2_FrameSize; i++) { temp64 = *((UInt64 *)pFrame+i); *((UInt64 *)pFrame+i) = *((UInt64 *)adjointFrame+i); *((UInt64 *)adjointFrame+i) = temp64; }
pFrame->adjointFrame = adjointFrame;
速度稍有提高。帧间隔从80ms提高到70ms。
考虑到这两个frame的很多字段是一样的,所以无需交换,代码简化成如下方式:
FVID2_Frame *adjointFrame;UInt32 temp32; UInt64 temp64;adjointFrame = pFrame->adjointFrame;
temp64 = *((UInt64 *)pFrame); //交换图像的地址
*((UInt64 *)pFrame) = *((UInt64 *)adjointFrame);
*((UInt64 *)adjointFrame) = temp64;
temp32 = *(((UInt32 *)pFrame)+9); //交换appData *(((UInt32 *)pFrame)+9) = *(((UInt32 *)adjointFrame)+9); *(((UInt32 *)adjointFrame)+9) = temp32;
temp32 = *(((UInt32 *)pFrame)+15); //交换附加图像结构体 *(((UInt32 *)pFrame)+15) = *(((UInt32 *)adjointFrame)+15); *(((UInt32 *)adjointFrame)+15) = temp32; pFrame->adjointFrame = adjointFrame;
但此时速度无任何提高。
gaohao wang:
回复 gaohao wang:
我刚刚测了一下这样做的时间消耗:
UInt32 begin = Utils_getCurTimeInMsec();
。。。
UInt32 end = Utils_getCurTimeInMsec();Vps_printf("xxxxxxxxxxxxxxxxxxxxxx swms exchange time = %dms xxxxxxxxxxxxxxxxxxxxxxx\n", end-begin);
结果为0ms,这说明不是两次交换浪费了时间,而是马赛克显示浪费了时间。该怎么解决?
bo fan:
回复 Chris Meng:
您好 请问demos_vdec_vdis 是如何控制帧率的,我在解码后加了一个DEILINK ,将YUV422转换到YUV420,
现在帧率完全控制不住,画面显示非常快,不知道什么原因。
我知道在demos_vdec_vdis里swMsPrm.maxInputQueLen参数好像可以用来控制帧率,
但是我加了deilink过后 ,这个办法也不行了,主要是deiPrm.enableDeiForceBypass = TRUE;这个参数影响的。。。
现在不知道怎么调。。 我只想把帧率控制在30左右,谢谢