localhost

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost  发布于  2016-07-27 18:12:47
采纳率 0%
16个问答
5299

Hi3516A如何实现同源多路编码输出

 
根据HI3516A的demo程序中,原本操作是通过配置多组vi ve参数:
        vi_par vi;
        vi.cap_width = 1920; // 视频输入的大小
        vi.cap_height = 1080;
        vi.interlaced = 0; // 是否是隔行输入, 1080p 这里为0,1080i 这里为1

        venc_par ve;
        ve.bitrate = 2 * 1024;
        ve.rc_mode = HI3516A_RC_VBR;
        ve.codec = PT_H264; // 编码方式是 PT_H265 或者 PT_H264

        vi_par vi_another;
        vi_another.cap_width = 1280;
        vi_another.cap_height = 720;
        vi_another.interlaced = 0;

        venc_par ve_another;
        ve_another.bitrate = 2*1024;
        ve_another.rc_mode = HI3516A_RC_VBR;
        ve_another.codec = PT_H264;

        StartSys();
        StartVi(vi);

        StartVenc(vi, ve,0);

        StartVenc(vi_another, ve_another, 1);

如上配置两组编码通道参数 实现保存1080p与720p的两组视频文件
但是 这种方式感觉与海思官方提供的拓展通道操作有区别
而且 在后续OSD处理时 对于两组不同视频流不是很方便

所以 想请教各位前辈指导一下 该如何正确实现同源多路视频编码输出
我来回答
回答24个
时间排序
认可量排序

ngswfx

1个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-27 19:28:11
认可0
你想不通过VI拓展通道,估计还编不出来2路呢。

////////OSD处理本来就要分成好几种,这样才有针对性,別嫌麻烦。

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 10:08:37
认可0
本帖最后由 localhost 于 2016-7-28 10:13 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=34964&ptid=12102]ngswfx 发表于 2016-7-27 19:28[/url]
你想不通过VI拓展通道,估计还编不出来2路呢。

////////OSD处理本来就要分成好几种,这样才有针对 ...[/quote]

是的 我之前是分开实验 就是先实验将采集的视频 再不处理的情况下分出两路不同分辨率的视频流编码保存
另一个是 将采集的视频经过OSD处理后 编码保存出来 然后 现在我想将这两个整合到一起 但是发现有以下几个疑点:  希望前辈可以指正一下谢谢啦
1、关于通道的问题 手册中有提到vi通道功能图与vpss管道功能图以及vpss组的概念,他们的关联关系是怎样的呢?  
      我是这样理解的,采集的视频从sensor  进入vi通道 --> 进入绑定的vpss某一组(假设group0)的通道中 -->接下来在进入VENC编码通道之前进行CROP、LDC、ROTATE、OSD等处理 --> 处理完成后这时就会涉及到拓展通道extchn和物理通道的分别对视频进行缩放 然后编码并保存呢。

图中标出的两个通道是否是同一个呢?

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-07-28 11:02:04
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=34994&ptid=12102]localhost 发表于 2016-7-28 10:08[/url]
是的 我之前是分开实验 就是先实验将采集的视频 再不处理的情况下分出两路不同分辨率的视频流编码保存
...[/quote]

哪有那么复杂

Vi 直接绑定VPSS

VPSS chn0 绑定大编码器 (1920x1080)
VPSS chn1 绑定小编码器 (1280x720)

就实现两个码流了,这个就是所谓的主码流和子码流

关于OSD叠加,是叠加在VENC上而不是在VI上

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 11:12:49
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35002&ptid=12102]zhuangweiye 发表于 2016-7-28 11:02[/url]
哪有那么复杂

Vi 直接绑定VPSS
[/quote]

是的 前辈 开始我实现两个码流的 方法是两组参数 然后将vi分别绑定vpss 的chn0 和chn1 代码如下:
[code]        /***video input/venc configure****/       
        //视频输入的大小
        vi_par vi;
        vi.cap_width =  hiConfig.vid_capturewidth;
        vi.cap_height = hiConfig.vid_captureheight;
        vi.interlaced = hiConfig.vid_captureinterlace;
        vi.framerate = hiConfig.vid_captureframerate;

        venc_par ve;
        ve.bitrate = hiConfig.vid_bit_rate/1000;
        ve.width = hiConfig.vid_width;
        ve.height = hiConfig.vid_height;
        if (hiConfig.vbr)
                ve.rc_mode = HI3516A_RC_VBR;
        else
                ve.rc_mode = HI3516A_RC_CBR;
        vi_par vi_another;
        vi_another.cap_width = hiConfig.vid_capturewidth;
        vi_another.cap_height = hiConfig.vid_captureheight;
        vi_another.interlaced = 0;//hiConfig.vid_captureinterlace;//shi pin fen liu shi fou xu yao ge hang shu chu

        venc_par ve_another;
        ve_another.bitrate = hiConfig.vid_sub_bit_rate/1000;
        ve_another.width = hiConfig.vid_sub_width;
        ve_another.height = hiConfig.vid_sub_height;

        ve_another.rc_mode = ve.rc_mode;

        StartVenc(0,vi, ve, ViFormat);
        if (hiConfig.vid_sub_enable)
        {
                StartVenc(1,vi_another, ve_another, ViFormat_another);
        }

/***************分割线 配置函数****************************/
int StartVenc(int Chn,vi_par& vi, venc_par& vp, pt_h264& ViFormat){

  VENC_CHN VencChn = Chn;
  VPSS_GRP VpssGrp = 0;
  VPSS_CHN VpssChn = 0;

  HI_S32 s32Ret = HI_SUCCESS;
  s32Ret = HI3516A_COMM_VENC_Start(VencChn, vi, vp, ViFormat);
  if (HI_SUCCESS != s32Ret)
  {
      HI3516A_PRT("Start Venc failed!\n");
      return HI_FAILURE;
  }

  s32Ret = HI3516A_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);
  if (HI_SUCCESS != s32Ret)
  {
      HI3516A_PRT("Start Venc failed!\n");
      return HI_FAILURE;
  }

        g_VideoEncoderCount++;
        return HI_SUCCESS;
}

[/code]

这样修改以后 实现双流输出 不知道和您的想法一样

然后 我实现osd叠加的方式是在venc的通道上 但是我想实现双流一起叠加 不知道是由于我双流的实现方式有问题还是 osd叠加的位置有问题 希望能指点一下

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-07-28 11:30:27
认可0
VPSS_GRP VpssGrp = 0;
VPSS_CHN VpssChn = 0;

s32Ret = HI3516A_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);
这样的代码, 只能让所有的VENC都绑定到vpss group0 channel0

楼主对VPSS的绑定可能还不是很熟悉

假设 1920x1080的venc channel = 0,那么应该用 s32Ret = HI3516A_COMM_VENC_BindVpss(0, 0, 0);
假设 1920x1080的venc channel = 1,那么应该用 s32Ret = HI3516A_COMM_VENC_BindVpss(1, 0, 1);

关于OSD, 每个VENC都要有自己的RGN分别叠加, 不要想所谓的一起叠加




localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 11:41:12
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35007&ptid=12102]zhuangweiye 发表于 2016-7-28 11:30[/url]
VPSS_GRP VpssGrp = 0;
VPSS_CHN VpssChn = 0;

[/quote]

是的 前辈 看了MPP手册的介绍 和配图对于系统中提到的几个通道的逻辑关系有些迷糊 感觉他们之间有些矛盾说不通 但又好像是对的
特别是 vpss组中的通道和 拓展通道和vi  venc的通道关系

尤其 在osd叠加处理时 根据手册介绍 osd叠加可以有两种方式 分别venc 叠加 和vpss叠加
如果在vpss上叠加的画 那么同组分出的各个通道 按照手册的说法 应该会自动根据不同分辨率结合输出
而如果在venc上处理 那么只会在通过相应venc通道上的视频才会处理叠加

如果我的理解正确的话 这样设计一个问题 就是对于分出的小流视频 想要叠加osd的话 那么是应该在物理通道上处理还是在拓展通道上处理呢 如果在拓展通道上处理的话 那么是不是说 之前我的配置方式就有问题了呢?

(说法不太专业见谅  希望前辈指导一下 谢谢啦)

ngswfx

1个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-28 11:50:18
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35002&ptid=12102]zhuangweiye 发表于 2016-7-28 11:02[/url]
哪有那么复杂

Vi 直接绑定VPSS
[/quote]

呵呵,你终于来了,这种问题,也只有你最明白了,我对这种通道绑定,无能为力,弄了几次,失败告终。

我现在的感觉就是同一个VI,如果不使用扩展通道,估计绑定不到2个VPSS上。


////////////我在3520D上实验,同一个VDEC,想绑定到2个VPSS上,一个用automode,vpss输出绑定到VO。
另外一个vpss使用usermode,仅仅用来抓YUV,然后送去编码VENC,弄一个jpg出来。结果只要绑定第二个vpss,第一个就完蛋了,VO图像停止了。最终还是绑定一个VPSS,通过VO弄得YUV数据去编码,得jpg了。

//不知是不是第二个vpss,没有绑定输出的原因,还是因为vdec模式原因,只能绑定一个vpss.

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-07-28 12:19:10
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35010&ptid=12102]ngswfx 发表于 2016-7-28 11:50[/url]
呵呵,你终于来了,这种问题,也只有你最明白了,我对这种通道绑定,无能为力,弄了几次,失败告终。

...[/quote]

vdec的问题

vdec有所谓的"反压问题", 即后续绑定模块没有把数据"消费"掉,就会导致vdec停止解码
这个问题可以通过设置vdec为preview模式而不是playback模式(缺省)来解决

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-07-28 12:26:03
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35009&ptid=12102]localhost 发表于 2016-7-28 11:41[/url]
是的 前辈 看了MPP手册的介绍 和配图对于系统中提到的几个通道的逻辑关系有些迷糊 感觉他们之间有些矛盾 ...[/quote]

楼主的应用是经典的IPC应用

海思对于这种应用有着极其方便的做法

VI-->VPSS chn0-->VENC1(主)
                chn1-->VENC2(子)

这就是绑定关系, 只要一个vpss group就可以了

关于OSD, 由于主码流和子码流分辨率不同, OSD的字体要适应不同的分辨率, 原理上讲在VPSS上叠加也是可以的,但是同样大小的OSD经过VPSS压缩后在子码流上的显示效果往往很难令人满意,或者说子码流上的OSD满意了,主码流上的就太大了,所以一般都分开叠加,以满足效果上的要求

ngswfx

1个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-28 12:28:49
认可0
本帖最后由 ngswfx 于 2016-7-28 12:42 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=35012&ptid=12102]zhuangweiye 发表于 2016-7-28 12:19[/url]
vdec的问题

vdec有所谓的"反压问题", 即后续绑定模块没有把数据"消费"掉,就会导致vdec停止解码
[/quote]

呵呵,原来是这样,我试试。

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 13:42:57
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35014&ptid=12102]zhuangweiye 发表于 2016-7-28 12:26[/url]
楼主的应用是经典的IPC应用

海思对于这种应用有着极其方便的做法
[/quote]

原来可以这样 谢谢前辈指导 那可否再问一下
将这种思路转换到实际代码 就是说 我需要 在两个venc通道分别处理osd了吧?
那么对于在提取字库文件的时候 多次重复打开字库文件 应该会占用大量内存 b

对于这一点 前辈有什么可以优化的方案嘛 谢谢啦

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-07-28 14:02:57
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35026&ptid=12102]localhost 发表于 2016-7-28 13:42[/url]
原来可以这样 谢谢前辈指导 那可否再问一下
将这种思路转换到实际代码 就是说 我需要 在两个venc通道分 ...[/quote]

为什么要多次重复打开字库文件?

一次打开不就好了, 打开一个文件能用多少内存, 不是很理解楼主关于内存的担忧

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 14:13:46
认可0
本帖最后由 localhost 于 2016-7-28 14:16 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=35027&ptid=12102]zhuangweiye 发表于 2016-7-28 14:02[/url]
为什么要多次重复打开字库文件?

一次打开不就好了, 打开一个文件能用多少内存, 不是很理解楼主关于内 ...[/quote]

ttf的话 在初始化的时候 对于不同字号的文字转化成位图 那个打开字体文件的参数是不一样的

比如目前要求 logo是32号字  时间戳要24号字 这就需要打开两次自己文件提取

这是在一个venc通道中实现  如果在另一个venc通道进行osd叠加 需要不同的字号 那么就会再次重复以不同的字号打开字库文件了

我之前最开始没有注意到字号的问题 后来 根据不同内容 打开字库 发现内存上升非常高 以为重复打开 没有关闭 而且 如果使用一次关闭一次的话会导致
多次的字体 都是按照最后一次的字号大小叠加

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-07-28 14:20:16
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35029&ptid=12102]localhost 发表于 2016-7-28 14:13[/url]
ttf的话 在初始化的时候 对于不同字号的文字转化成位图 那个打开字体文件的参数是不一样的

比如目前要 ...[/quote]

按理文件使用只要打开一次就好了

至于使用的字体的大小也是有限的

时间OSD就那几个字符是固定的,一次把0-9以及相应的几个字符取出来,等做时间OSD时再拼接就好了
用不着每次都去打开文件

另外:如果只会用人家的接口当我没说

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 15:44:43
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35030&ptid=12102]zhuangweiye 发表于 2016-7-28 14:20[/url]
按理文件使用只要打开一次就好了

至于使用的字体的大小也是有限的
[/quote]

是这样的 因为不光是时间戳 此外 还有不同的文字logo 也要这样叠加
所以文字是不固定的
而且 需求想做到字符任意变换  所以不太好直接确定到底会用到几个字符
因此还是要打开字体文件
同时 我试利用SDL的方式 进行字体处理叠加 我做的方法如下:

[code]int sdk_comm_video_loadosdbmp(const char *ptxt, int handle, RegionInfo *word)
{
        if(WordTTFSize != WordTTFInfo[handle])
        {
                if(TTF_Init() < 0)
                {
                        printf("Couldn`t initialize TTF: %s\n",SDL_GetError());
                        SDL_Quit();
                        return -1;
                }
                stFont[handle] = TTF_OpenFont("simhei.ttf", WordTTFSize);
                if(stFont[handle] ==NULL)
                {
                        printf("ttf err\n");
                        return -1;
                }
                WordTTFInfo[handle] = WordTTFSize;
                printf("WordTTFInfo[%d]:%d \n", handle, WordTTFInfo[handle]);
        }
       
        SDL_Surface *sdl_txtsurface = NULL;
        SDL_Surface *sdl_tmpsurface = NULL;
        BITMAP_S stBitmap;
        int s32Ret;
[/code]

不知道 前辈有其他的初始化方式可以避免重复打开嘛

ngswfx

1个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-28 15:53:26
认可0
本帖最后由 ngswfx 于 2016-7-28 16:13 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=35046&ptid=12102]localhost 发表于 2016-7-28 15:44[/url]
是这样的 因为不光是时间戳 此外 还有不同的文字logo 也要这样叠加
所以文字是不固定的
而且 需求想 ...[/quote]

你流程思路没对!这东西不能动态产生,而是先产生可能用的bitmap,放到内存里面,固定下来。用的时候,再组合。

////我要是弄这个东西,就这么干:

//首先监控用的OSD都是固定的,不会随便变的。只有用户配置修改OSD时,才变化一下。即便时间在走,再怎么变,也是0-9,你只要把这9个字符的buff弄固定即可,弄成全局buff变量即可。

//////程序启动,加载各种需要的字库,产生数字,中文,logo等的bmp格式的buff,这个buff是全局的,考虑到时间在变,数字部分的buff有很多个,0-9应该够用了。

//一旦产生某个buff,中间过程的东西,能释放就释放掉了,没必要占用住内存。

///////由于全局buff的存在,主要由于OSD时间部分在不停变,为此总体叠加的OSD,你可以分成基本版块,其他的部分基本不变,只有时间OSD需要不停组合,不停刷,你就留着这10个buff一直用就可以了。

//这么用起来,除了程序启动加载计算bitmap费点内存,实际工作中,有个几十K量级的内存占用,就满足所有OSD的数据了。(OSD时间,OSD通道名中文,OSD地理位置多行中文)

你就多弄几个bitmap buff即可。计算文字部分,和实际贴图部分没关系。异步的。



////////////////如果用户修改了中文OSD,例如地名,位置等信息,这时候再通过相关库函数(SDL TTF等),重新产生需要的文字的OSD的bitmap,至于时间等OSD的bitmap,还是不用管它。千万别动态调取字库,以及时间,每次都去算bitmap,CPU受不了,内存也受不了。


//////////////////////当然,上述这些前提是你在做一个IPC的OSD,你要是弄类似电视电影字幕,那就没办法,只能频繁调用产生了。

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-07-28 16:52:06
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35048&ptid=12102]ngswfx 发表于 2016-7-28 15:53[/url]
你流程思路没对!这东西不能动态产生,而是先产生可能用的bitmap,放到内存里面,固定下来。用的时候, ...[/quote]

感谢前辈指导 确实是我之前一直考虑会出现 文字频繁改变而做的

现在看来 是应该换一下思路 我去更改一下

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-08-01 14:52:44
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35030&ptid=12102]zhuangweiye 发表于 2016-7-28 14:20[/url]
按理文件使用只要打开一次就好了

至于使用的字体的大小也是有限的
[/quote]

前辈 我有一个想法 不知道是否符合标准 我下面说一下 希望您给指导一下:

先说一下目的需求:同源视频 分成多路不同分辨率并 经过OSD处理后 编码输出

我的想法是 将vi输入的视频流 送到同一组vpss group通道中 然后 将视频源码 在venc通道编码前进行osd处理 然后送入不同venc通道 进行分辨率调整编码

如果可行,那么在这里有两个疑问:
1、对于osd处理 是应该按照vpss模式进行 还是在venc上进行;
2、对于通道绑定关系是否应该是 vi0--->vpssGrp0---->vpssChn0----->vencChn0;
                                             vi0--->vpssGrp0---->vpssChn0----->vencChn1;

localhost

0个粉丝

16

问答

0

专栏

4

资料

localhost 2016-08-01 14:56:24
认可0
本帖最后由 localhost 于 2016-8-1 15:38 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=35014&ptid=12102]zhuangweiye 发表于 2016-7-28 12:26[/url]
楼主的应用是经典的IPC应用

海思对于这种应用有着极其方便的做法
[/quote]

前辈 对于 这里的通道绑定关系 我试验了一下绑定方式
一下是我利用demo基础上修改实验
[code]int StartVenc(vi_par& vi, venc_par& vp){

        VENC_CHN VencChn = 0;
    VPSS_GRP VpssGrp = 0;
    VPSS_CHN VpssChn = 0;

        HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = HI3516A_COMM_VENC_Start(VencChn, vi, vp);
    if (HI_SUCCESS != s32Ret)
    {
        HI3516A_PRT("Start Venc failed!\n");
        return HI_FAILURE;
    }

    s32Ret = HI3516A_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);
    if (HI_SUCCESS != s32Ret)
    {
        HI3516A_PRT("Start Venc failed!\n");
        return HI_FAILURE;
    }
        return HI_SUCCESS;
}[/code]

[code]int StartVenc_another(vi_par& vi, venc_par& vp){

        VENC_CHN VencChn = 1;
    VPSS_GRP VpssGrp = 0;
    VPSS_CHN VpssChn = 1;//这里 如果为1 那么编译后应用 在运行过程中 小流文件 内容为空 而如果是0的话 那么小流文件 即为 缩小分辨率的视频 并且可播放

        HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = HI3516A_COMM_VENC_Start(VencChn, vi, vp);
    if (HI_SUCCESS != s32Ret)
    {
        HI3516A_PRT("Start Venc failed!\n");
        return HI_FAILURE;
    }

    s32Ret = HI3516A_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);
    if (HI_SUCCESS != s32Ret)
    {
        HI3516A_PRT("Start Venc failed!\n");
        return HI_FAILURE;
    }

        return HI_SUCCESS;
}[/code]

可能是我关于通道的理解有误 希望前辈指导纠正一下
附图 是两种情况的文件

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-08-01 16:03:32
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=35207&ptid=12102]localhost 发表于 2016-8-1 14:56[/url]
前辈 对于 这里的通道绑定关系 我试验了一下绑定方式
一下是我利用demo基础上修改实验

[/quote]

给个运行时的 /proc/umap/vpss 以及 /proc/umap/sys的log
加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

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

Markdown 语法

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

举报类型

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

详细说明

易百纳技术社区