This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

mcfw,帧率过高会解码出错。



我修改了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。

  • 你好,

    请问是jpeg单独解码么?如果你把8个500万像素的jpg拼成一个mjpeg文件,让系统自己去读去文件解码,这样会有同样的问题么?

    不知道你使用的IVAHD的频率是多少,一般来说一个IVAHD至少是1080p60的性能,对于5Mp的图像就是24帧,那间隔是42ms左右,如果IVAHD的频率较高,帧率还可以更高,间隔就会变短。

  • 我找到初步的原因了,是因为我把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。问题是,这两次替换为什么会造成必须下降帧率?有什么解决办法?谢谢。

  • 你好,

    M3就200来兆,上面做memcpy应该会很耗cpu。建议传递指针而不要复制内容。

  • 我刚才也这样猜。然后代码修改如下:

    在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的时候,图像显示在一个马赛克窗口。

  • 是否320是某个队列的长度?此队列元素一直不能释放,到此长度程序就崩溃了。

  • 帧间隔调整到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]

    希望能帮助解决,谢谢。

  • 我现在又回到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;

    但此时速度无任何提高。

  • 我刚刚测了一下这样做的时间消耗:

    UInt32 begin = Utils_getCurTimeInMsec();

    。。。

    UInt32 end = Utils_getCurTimeInMsec();
    Vps_printf("xxxxxxxxxxxxxxxxxxxxxx swms exchange time = %dms xxxxxxxxxxxxxxxxxxxxxxx\n", end-begin);

    结果为0ms,这说明不是两次交换浪费了时间,而是马赛克显示浪费了时间。该怎么解决?

  • 您好 请问demos_vdec_vdis 是如何控制帧率的,我在解码后加了一个DEILINK ,将YUV422转换到YUV420,

    现在帧率完全控制不住,画面显示非常快,不知道什么原因。

    我知道在demos_vdec_vdis里swMsPrm.maxInputQueLen参数好像可以用来控制帧率,

    但是我加了deilink过后 ,这个办法也不行了,主要是deiPrm.enableDeiForceBypass = TRUE;这个参数影响的。。。

    现在不知道怎么调。。 我只想把帧率控制在30左右,谢谢