吾是3C312

吾是3C312

0个粉丝

3

问答

0

专栏

0

资料

吾是3C312  发布于  2016-03-15 14:07:26
采纳率 0%
3个问答
10713

HI3520D venc 720P获取视频流出错

 
本帖最后由 吾是3C312 于 2016-3-15 14:10 编辑

Sample_venc.c中,之前一直使用的标清视频流704*576,在SAMPLE_COMM_VENC_StartGetStream线程中获取视频流,最近换了图像分辨率,使用SAMPLE_VENC_1HD_H264获取1路720P视频。

从源码中看,720P视频获取时调用的程序流程和8路D1的视频基本一致,只是图像分辨率格式换为720P,
但是在SAMPLE_COMM_VENC_StartGetStream中获取视频流时,报错,get venc stream time out, exit thread
查看源码大概是在sample/common/Sample_comm_venc.c中SAMPLE_COMM_VENC_GetVencStreamProc函数中1179行报错,

标红的两行为出错的位置,初步考虑可能是因为摄像头的分辨率不够,但是这个摄像头是900线的,卖家也说最高支持720P,
但是相同的流程,D1分辨率就没问题,720P就出错,比较奇怪,不知道哪里出错了。
请各位大神指教,
PS:特别谢谢版主,每次有问题都帮我想办法。

while (HI_TRUE == pstPara->bThreadStart)
    {
        FD_ZERO(&read_fds);
        for (i = 0; i < s32ChnTotal; i++)
        {
            FD_SET(VencFd, &read_fds);
        }

        TimeoutVal.tv_sec  = 2;
        TimeoutVal.tv_usec = 0;
       s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal);
        if (s32Ret < 0)
        {
            SAMPLE_PRT("select failed!\n");
            break;
        }
        else if (s32Ret == 0)
        {
            SAMPLE_PRT("get venc stream time out, exit thread\n");
            continue;
        }
        else
        {
            for (i = 0; i < s32ChnTotal; i++)
            {
                if(i%2==1||i>11)
                continue;
                if (FD_ISSET(VencFd, &read_fds))
                {
                    /*******************************************************
                     step 2.1 : query how many packs in one-frame stream.
                    *******************************************************/
                    memset(&stStream, 0, sizeof(stStream));
                    s32Ret = HI_MPI_VENC_Query(i, &stStat);
                    if (HI_SUCCESS != s32Ret)
                    {
                        SAMPLE_PRT("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);
                        break;
                    }

                    /*******************************************************
                     step 2.2 : malloc corresponding number of pack nodes.
                    *******************************************************/
                    stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);

我来回答
回答20个
时间排序
认可量排序

吾是3C312

0个粉丝

3

问答

0

专栏

0

资料

吾是3C312 2016-03-15 14:22:22
认可0
我的好像不是NVP611,你如果要源码我可以给你。

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-03-15 14:40:05
认可0
SAMPLE_VENC_1HD_H264()

调用SAMPLE_COMM_VI_Start(enViMode, gs_enNorm)来设定AD和Vi, 注意: enViMode = SAMPLE_VI_MODE_1_720P

调用 SAMPLE_COMM_VI_ADStart(enViMode, enNorm)来设定AD,
注意(如果没改代码):
...
        case SAMPLE_VI_MODE_1_720P:
            break;
就是说啥也没干,那么AD没有设定,肯定是不会有东西送到Vi来(除非AD驱动缺省就是720P), vi没东西, vpss自然也不会有,那么venc只能timeout了

所以,只要把AD设对了就可以了,和接不接摄像头没啥关系(接了有图,不接黑图)

吾是3C312

0个粉丝

3

问答

0

专栏

0

资料

吾是3C312 2016-03-15 14:46:45
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26564&ptid=10398]zhuangweiye 发表于 2016-3-15 14:40[/url]
SAMPLE_VENC_1HD_H264()

调用SAMPLE_COMM_VI_Start(enViMode, gs_enNorm)来设定AD和Vi, 注意: enViMode  ...[/quote]

但是我看着这个代码里,这些步骤都是有的,而且现在就是用的例子代码,什么都没有改。
HI_S32 SAMPLE_VENC_1HD_H264(HI_VOID)
{
    SAMPLE_VI_MODE_E enViMode = SAMPLE_VI_MODE_1_720P;

    HI_U32 u32ViChnCnt = 1;
    HI_S32 s32VpssGrpCnt = 1;
    PAYLOAD_TYPE_E enPayLoad[2]= {PT_H264, PT_H264};
    PIC_SIZE_E enSize[2] = {PIC_HD720, PIC_D1};

    VB_CONF_S stVbConf;
    VPSS_GRP VpssGrp;
    VPSS_CHN VpssChn;
    VPSS_GRP_ATTR_S stGrpAttr;
    VENC_GRP VencGrp;
    VENC_CHN VencChn;
    SAMPLE_RC_E enRcMode;

    HI_S32 i;
    HI_S32 s32Ret = HI_SUCCESS;
    HI_U32 u32BlkSize;
    HI_CHAR ch;
    SIZE_S stSize;

    /******************************************
     step  1: init variable
    ******************************************/
    memset(&stVbConf,0,sizeof(VB_CONF_S));

    u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
                PIC_HD720, SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);
    stVbConf.u32MaxPoolCnt = 128;

    /* video buffer*/
    stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;
    stVbConf.astCommPool[0].u32BlkCnt = u32ViChnCnt * 6;
    memset(stVbConf.astCommPool[0].acMmzName,0,
        sizeof(stVbConf.astCommPool[0].acMmzName));

    /* hist buf*/
    stVbConf.astCommPool[1].u32BlkSize = (196*4);
    stVbConf.astCommPool[1].u32BlkCnt = u32ViChnCnt * 4;
    memset(stVbConf.astCommPool[1].acMmzName,0,
        sizeof(stVbConf.astCommPool[1].acMmzName));

    /******************************************
     step 2: mpp system init.
    ******************************************/
    s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("system init failed with %d!\n", s32Ret);
        goto END_VENC_1HD_0;
    }

    /******************************************
     step 3: start vi dev & chn to capture
    ******************************************/
    s32Ret = SAMPLE_COMM_VI_Start(enViMode, gs_enNorm);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("start vi failed!\n");
        goto END_VENC_1HD_0;
    }

    /******************************************
     step 4: start vpss and vi bind vpss
    ******************************************/
    s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, PIC_HD720, &stSize);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n");
        goto END_VENC_1HD_0;
    }

    stGrpAttr.u32MaxW = stSize.u32Width;
    stGrpAttr.u32MaxH = stSize.u32Height;
    stGrpAttr.bDrEn = HI_FALSE;
    stGrpAttr.bDbEn = HI_FALSE;
    stGrpAttr.bIeEn = HI_TRUE;
    stGrpAttr.bNrEn = HI_TRUE;
    stGrpAttr.bHistEn = HI_TRUE;
    stGrpAttr.enDieMode = VPSS_DIE_MODE_NODIE;
    stGrpAttr.enPixFmt = SAMPLE_PIXEL_FORMAT;

    s32Ret = SAMPLE_COMM_VPSS_Start(s32VpssGrpCnt, &stSize, VPSS_MAX_CHN_NUM, &stGrpAttr);

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-03-15 15:05:42
认可0
我的意思是例子程序的过程是:

SAMPLE_VENC_1HD_H264()这个函数
调用SAMPLE_COMM_VI_Start(enViMode, gs_enNorm)来设定AD和Vi
而SAMPLE_COMM_VI_Start(enViMode, gs_enNorm)
调用 SAMPLE_COMM_VI_ADStart(enViMode, enNorm)来设定AD,
SAMPLE_COMM_VI_ADStart()这个函数针对SAMPLE_VI_MODE_1_D1做了
            enWorkMode = VI_WORK_MODE_4Multiplex;
            s32Ret = SAMPLE_AD_CfgV_D1(enNorm, enWorkMode);
设定了AD, 所以D1时vi能正确得到数据
而SAMPLE_COMM_VI_ADStart()这个函数针对SAMPLE_VI_MODE_1_720P没有做任何事情,所以vi不会有东西,所以会timeout


所以要想不timeout, 你要自己写相关设置AD的代码

吾是3C312

0个粉丝

3

问答

0

专栏

0

资料

吾是3C312 2016-03-16 09:16:28
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26566&ptid=10398]zhuangweiye 发表于 2016-3-15 15:05[/url]
我的意思是例子程序的过程是:

SAMPLE_VENC_1HD_H264()这个函数
[/quote]

好的,我大概了解你的意思了,我参照着文档调整一下这些函数的参数试试,遇到问题再请教你。
非常感谢!

吾是3C312

0个粉丝

3

问答

0

专栏

0

资料

吾是3C312 2016-03-16 11:56:19
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26566&ptid=10398]zhuangweiye 发表于 2016-3-15 15:05[/url]
我的意思是例子程序的过程是:

SAMPLE_VENC_1HD_H264()这个函数
[/quote]

我今天看了一下8路D1的配置,写的意思大致是往配置文件中把AD的配置信息写进去,但是720P的配置如何写呢?从来没设置过这个。
文档中我只找到了掩码的设置,这个作用是什么呢?

2路720p(INTERLEAVED)场景
2路720p场景下,设置VI设备属性时,可根据表3-9配置掩码。
表3-12 2路720p场景下的掩码配置
设备号  掩码0  掩码1
0 0xFF000000 0x0
1 0x00FF0000 0x0

8路D1的配置源码,应该在这个基础上如何修改成4路720P的呢?

HI_S32 SAMPLE_CX26828_CfgV(VIDEO_NORM_E enVideoMode, int resolution_ratio,
                                      VI_WORK_MODE_E enWorkMode)
{
    int fd, i;
    int video_mode;
    int chip_cnt = 1;
    cx26828_video_norm stVideoMode;
    cx26828_work_mode work_mode;
    cx26828_Multiplex_mode multiplex_mode;

    fd = open(CX26828_FILE, O_RDWR);
    if (fd < 0)
    {
        printf("open %s fail\n", CX26828_FILE);
        return -1;
    }

    video_mode = (VIDEO_ENCODING_MODE_PAL == enVideoMode) ? CX26828_MODE_PAL : CX26828_MODE_NTSC;
    for (i=0; i     {
        stVideoMode.chip    = i;
        stVideoMode.mode    = video_mode;
        if (ioctl(fd, CX26828_SET_VIDEO_NORM, &stVideoMode))
        {
            printf("set cx26828(%d) video mode fail\n", i);
            close(fd);
            return -1;
        }
    }

    for (i=0; i     {
        work_mode.chip = i;
        if (0 == resolution_ratio)
        {
            work_mode.mode = CX26828_16D1;
        }
        else if (1 == resolution_ratio)
        {
            work_mode.mode = CX26828_16E1;
        }
        else
        {
            printf("work mode not support.\n");
            return -1;
        }
        ioctl(fd, CX26828_SET_WORK_MODE, &work_mode);
    }

    for (i=0; i     {
        multiplex_mode.chip = i;
        if (VI_WORK_MODE_4Multiplex== enWorkMode)
        {
            multiplex_mode.mode = CX26828_4D1_MODE;
        }
        else if (VI_WORK_MODE_2Multiplex== enWorkMode)
        {
            multiplex_mode.mode = CX26828_2D1_MODE;
        }
        else if (VI_WORK_MODE_1Multiplex== enWorkMode)
        {
            multiplex_mode.mode = CX26828_1D1_MODE;
        }
        else
        {
            printf("multiplex mode not support\n");
            return -1;
        }
        ioctl(fd, CX26828_SET_Multiplex_MODE, &multiplex_mode);
    }

    close(fd);

    return 0;
}

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-03-16 12:28:05
认可0
从CX26828驱动代码和sample上看,好像都不支持720P的设置

看来前端AD不支持, 海思表示很无奈

吾是3C312

0个粉丝

3

问答

0

专栏

0

资料

吾是3C312 2016-03-16 12:32:28
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26650&ptid=10398]zhuangweiye 发表于 2016-3-16 12:28[/url]
从CX26828驱动代码和sample上看,好像都不支持720P的设置

看来前端AD不支持, 海思表示很无奈[/quote]

如果支持的话,是不是在sample代码里就应该就相应的例子?
但是文档里写的是4路720,1路1080. 这个好郁闷。还有别的方法吗
或者有没有其他什么板子支持4路以上720P的?

drafour

1个粉丝

7

问答

0

专栏

1

资料

drafour 2016-03-16 14:25:36
认可0
3520d不支持720p。

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-03-16 14:36:16
认可0
也不能一棍子打死

3520D分V100, V200, V300
好像只有V100不支持

knaffe

0个粉丝

3

问答

0

专栏

0

资料

knaffe 2016-10-13 08:22:27
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26658&ptid=10398]zhuangweiye 发表于 2016-3-16 14:36[/url]
也不能一棍子打死

3520D分V100, V200, V300
[/quote]

您好,请问3520D怎么保存视频到本地硬盘中?可以参考哪些资料?

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-10-13 08:41:12
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=39302&ptid=10398]knaffe 发表于 2016-10-13 08:22[/url]
您好,请问3520D怎么保存视频到本地硬盘中?可以参考哪些资料?[/quote]

标准的文件读写就可以

关键问题不是读写, 而是存储方式的设计, 要能使硬盘读写效率更高, 搜索更快, 经过多次循环覆盖后硬盘不会碎片化. 满足DVR的各种需求, 比如给指定的通道配置指定的容量等的功能

knaffe

0个粉丝

3

问答

0

专栏

0

资料

knaffe 2016-10-13 22:06:31
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=39303&ptid=10398]zhuangweiye 发表于 2016-10-13 08:41[/url]
标准的文件读写就可以

关键问题不是读写, 而是存储方式的设计, 要能使硬盘读写效率更高, 搜索更快, 经 ...[/quote]

谢谢回答。
我还是没明白如何保存文件。我看到sample/venc中的例子,选择1D1 MJPEG encode才会保存视频。我也看了这个程序,也大概知道它如何保存视频。但是我想更简洁的代码(示例中可能包含其他功能)。我目前就是想按照一定周期保存视频到本地中。因为我的主程序要做一些运动物体检测的东西。程序里是获取这个视频流,然后一个循环将这个视频流写入到文件中(调用SAMPLE_COMM_VENC_SaveMJpeg函数)。我目前不知道如何获取这个流(在我的应用中,运动物体检测可以获取视频流,or frame),不知道我可不可以我每次检测我的运动体检的stream写到文件里,保存的是不是就跟venc程序里保存的MJP文件一样。另外,如何对MJP文件进行处理,有其他的保存文件格式吗?我想对保存的视频文件进行切割

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-10-14 08:25:48
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=39405&ptid=10398]knaffe 发表于 2016-10-13 22:06[/url]
谢谢回答。
我还是没明白如何保存文件。我看到sample/venc中的例子,选择1D1 MJPEG encode才会保存视频 ...[/quote]

好吧, 从头来过, 一步一步来

首先看sample/venc, 关注文件是 sample/venc/sample_venc.c和sample/common/sample_common_venc.c
(如果楼主对海思初始化, VI/VPSS/VENC初始化.绑定等不熟悉的话, 那建议先看代码和文档, 然后再继续后面的部分)
假定上述问题楼主都清楚了, 那么来关注如何取码流, 关注sample/common/sample_common_venc.c中的函数
SAMPLE_COMM_VENC_GetVencStreamProc()

首先该函数是取码流线程的主函数, 也就是说初始化海思的一系列动作后, 会创建一个线程, 该线程就是跑这个函数
其次该函数分两部分, 1. 初始化, 2. 循环读码流
第一部分比价简单, 是打开要存的文件, 以及得到各个通道VENC的文件句柄
第二部分注释写得非常清楚, 三部曲 得码流+存码流+释放码流

一般自己封装代码是不需要在这个线程里面去打开文件的, 去掉这部分剩下流程可以封装起来, 只要自己重写一下SAMPLE_COMM_VENC_SaveStream()就可以了, 也可以做成回调的形式

至于文件格式, 如果是私有的,那么楼主想咋写就咋写,没人管, 如果是标准格式, 那么就按标准来就是了

另外, 这个取码流函数对海思的所有编码格式都是一样的

knaffe

0个粉丝

3

问答

0

专栏

0

资料

knaffe 2016-10-16 10:45:19
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=39409&ptid=10398]zhuangweiye 发表于 2016-10-14 08:25[/url]
好吧, 从头来过, 一步一步来

首先看sample/venc, 关注文件是 sample/venc/sample_venc.c和sample/co ...[/quote]

视频保存的问题解决了。我还有一个疑问想请教的。
板子的RTC驱动没装,因此无法使用。
我想获取网络时间来更新系统本地时间,请问有什么方法?
我写了一个python的脚本获取网络时间,不过hilinux上没有装python(您有在hilinux上装过python吗?)
我觉得用c++写一个是可以的,不过找不到合适的代码...

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-10-17 07:53:06
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=39562&ptid=10398]knaffe 发表于 2016-10-16 10:45[/url]
视频保存的问题解决了。我还有一个疑问想请教的。
板子的RTC驱动没装,因此无法使用。
我想获取网络时 ...[/quote]

海思SDK中有RTC的源代码, 自己看一下,编一个就好了

用网络时间? NTP校时就行, 可以问问度娘

至于用什么语言, 一般来说海思的芯片 C/C++ 比较普遍吧

zjx94

0个粉丝

7

问答

0

专栏

0

资料

zjx94 2016-12-20 11:15:57
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26650&ptid=10398]zhuangweiye 发表于 2016-3-16 12:28[/url]
从CX26828驱动代码和sample上看,好像都不支持720P的设置

看来前端AD不支持, 海思表示很无奈[/quote]

你好,我的SAMPLE_COMM_VI_ADStart里switch里面我加了函数,照搬之前case里的SAMPLE_TW2865_CfgV(),应该没什么问题吧,我的函数基本都没改过。我也是出现超时,然后./vi_dump 出现HI_MPI_VI_SetFrameDepth err, vi chn 0  ,这样应该是没有输入吧,这种该怎么解决呢

zxf_meian

0个粉丝

3

问答

0

专栏

0

资料

zxf_meian 2017-11-13 16:33:44
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=26564&ptid=10398]zhuangweiye 发表于 2016-3-15 14:40[/url]
SAMPLE_VENC_1HD_H264()

调用SAMPLE_COMM_VI_Start(enViMode, gs_enNorm)来设定AD和Vi, 注意: enViMode  ...[/quote]

例程里面的SAMPLE_COMM_VI_ADStart函数根本就没有使用过,他应该放在哪个位置?这样做之后程序前后需要改动哪些部分?

jcbsuresh

0个粉丝

5

问答

0

专栏

0

资料

jcbsuresh 2016-03-15 14:18:19
认可0
尊敬的楼主,  我需要NVP611示例代码,请帮忙

hero

0个粉丝

1

问答

0

专栏

0

资料

hero 2017-11-13 19:46:56
认可0
:):):):):):):):):):):)
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区