RV1126+FFMPEG推流项目(5)VI和VENC模块绑定,并且开启线程收罗 ...

  金牌会员 | 2025-1-16 05:43:44 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 868|帖子 868|积分 2604

        回首一下这个图,前面VI和VENC已经初始化了,现在也已经到了绑定两个模块的时候了。末了才开启线程到通道内里拿数据。 

 
        接下要完成这个两个模块,
rkmedia_assignment_manage.cpp (任务管理模块),管理 RV1126 上的各个任务。重要任务是创建并管理三个线程:


  • 视频编码线程 (camera_venc_thread)。
  • 音频编码线程 (audio_aenc_thread)。
  • 音视频合成推流线程 (push_server_thread)。
 rkmedia_data_process.cpp (数据处置惩罚模块)



  • 实现了三个线程的具体功能:

    • 视频编码线程:处置惩罚视频编码和数据存储。
    • 音频编码线程:处置惩罚音频编码和数据存储。
    • 音视频合成并推流线程:将音视频数据举行合成并推送到服务器。

        今天的任务:    //1.VI和VENC绑定,//2.开启线程收罗视频
  1. int init_rv1126_first_assignment(int protocol_type, char* network_addr)
  2. {
  3.     //1.VI和VENC绑定
  4.     //2.开启线程采集视频
  5. }
复制代码
        第一步:VI和VENC绑定,我们先来认识一个数据结构"MPP_CHN_S"和一个函数“RK_MPI_SYS_Bind()”,这个结构体也是来自rv1126手册的。
 RK_MPI_SYS_Bind() :

        看到这个函数 ,有两个参数,这两个参数就是这两个模块,以是先要界说出来
 
  1.     //绑定vi和venc
  2.     //不绑定venc就无法从vi模块拿到数据进行编码
  3.     ret = RK_MPI_SYS_Bind(&vi_channel, &venc_channel);
  4.     if(ret != 0)
  5.     {
  6.         printf("绑定失败\n");
  7.         return -1;
  8.     }
  9.     //成功
  10.     printf("绑定成功");
复制代码

MPP_CHN_S:

        在rv1126上面,有怎么多的模块,怎么管理的?接纳一个先描述后组织的思想,先描述:MPP_CHN_S这个是在rv1126上面描述一个模块的结构体,后组织:就是用什么把他管理起来,链表还是数组,这里没有用到先不说。                 

  1. int init_rv1126_first_assignment(int protocol_type, char* network_addr)
  2. {
  3.     //1.VI和VENC绑定
  4.     //1.1定义出VI和VENC模块
  5.     MPP_CHN_S vi_channel;
  6.     MPP_CHN_S venc_channel;
  7.     //1.2从VI容器里面获取通道VI_ID
  8.     //这里就体现出来容器的作用了,我只要放在公共的容器里面,就可以从其他文件拿到,很好的解偶
  9.     RV1126_VI_CONTAINER vi_container;
  10.     get_vi_container(0, &vi_container);
  11.     vi_channel.s32ChnId = vi_container.vi_id; //获取id
  12.     vi_channel.enModId = RK_ID_VI; //设定成VI模块,enModId 是一个枚举里面还有很多模块,这里只用到了RK_ID_VI
  13.    
  14.     //1.3从VI容器里面获取通道VENC_ID
  15.     RV1126_VENC_CONTAINER venc_container;
  16.     get_venc_container(0, &venc_container);
  17.     venc_channel.s32ChnId = venc_container.venc_id;//获取id
  18.     venc_channel.enModId = RK_ID_VENC;//设定成VI模块
  19.     //绑定
  20.    
  21.     //2.开启线程采集视频
  22. }
复制代码
开启线程获取摄像头的编码数据:

        先来认识几个参数,是和venc哪里拿数据有关的“RK_MPI_SYS_GetMediaBuffer”这个函数是从指定通道中获取VENC数据。假设获取数据是mb, mb数据有两部门构成,有用数据和数据的大小。

RK_MPI_SYS_GetMediaBuffer: 



“RK_MPI_MB_GetPtr”获取到mb内里的有用数据,RK_MPI_MB_GetSize这个mb数据是多大

 RK_MPI_MB_GetPtr:

 
RK_MPI_MB_GetSize: 

   

     rkmedia_assignment_manage.cpp :
  1. int init_rv1126_first_assignment(int protocol_type, char* network_addr){    int ret;    //1.VI和VENC绑定    //1.1界说出VI和VENC模块    MPP_CHN_S vi_channel;    MPP_CHN_S venc_channel;    //1.2从VI容器内里获取通道VI_ID    //这里就表现出来容器的作用了,我只要放在公共的容器内里,就可以从其他文件拿到,很好的解偶    RV1126_VI_CONTAINER vi_container;    get_vi_container(0, &vi_container);    vi_channel.s32ChnId = vi_container.vi_id; //获取id    vi_channel.enModId = RK_ID_VI; //设定成VI模块,enModId 是一个枚举内里还有很多模块,这里只用到了RK_ID_VI        //1.3从VI容器内里获取通道VENC_ID    RV1126_VENC_CONTAINER venc_container;    get_venc_container(0, &venc_container);    venc_channel.s32ChnId = venc_container.venc_id;//获取id    venc_channel.enModId = RK_ID_VENC;//设定成VI模块    //绑定vi和venc
  2.     //不绑定venc就无法从vi模块拿到数据进行编码
  3.     ret = RK_MPI_SYS_Bind(&vi_channel, &venc_channel);
  4.     if(ret != 0)
  5.     {
  6.         printf("绑定失败\n");
  7.         return -1;
  8.     }
  9.     //成功
  10.     printf("绑定成功");    //2.创建VENC线程,获取摄像头编码数据    //VENC线程的参数    VENC_PROC_PARAM* venc_arg_params = ( VENC_PROC_PARAM*)malloc(sizeof( VENC_PROC_PARAM));    venc_arg_params->vencId = vi_channel.s32DevId; //保存这个通道号,内里要通过这个id号获取    pthread_t pid;    ret = pthread_create(&pid, NULL, camera_venc_thread, (void*)venc_arg_params);}
复制代码
rkmedia_data_process.cpp: 
  1. //视频编码线程,并把数据放到队列里面去
  2. void * camera_venc_thread(void *args)
  3. {
  4.     int ret;
  5.     pthread_detach(pthread_self());//线程分离,主线程不用等待回收了,自动释放资源
  6.     MEDIA_BUFFER mb = NULL;         //定义一个媒体缓存区,用于接受编码器的输出数据
  7.    
  8.     VENC_PROC_PARAM *venc_arg = static_cast< VENC_PROC_PARAM *>(args);//可以直接强转,但是最高根安全一点
  9.     free(args); //参数解析到了,释放传入的内存
  10.     printf("线程启动成功");
  11.     while(1) //开始获取和处理venc数据
  12.     {
  13.         //从指定RK_ID_VENC模块的venc_arg->vencId通道里面拿数据, -1就是非阻塞
  14.         mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC,  venc_arg->vencId, -1);
  15.         if(!mb)
  16.         {
  17.             printf("获取数据失败了\n");
  18.             break;
  19.         }
  20.         //把取出的数据存储到一个一个的视频包里面,分配数据结构
  21.         video_data_packet_t *video_data_packet = (video_data_packet_t* )malloc(sizeof(video_data_packet_t));
  22.         //把数据拷贝进去视频包里面,mb数据由两部分组成,有效数据和数据的大小
  23.         memcpy(video_data_packet->buffer, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb) );
  24.         //把venc视频数据缓冲区数据的大小传到video_frame_size
  25.         video_data_packet->video_frame_size = RK_MPI_MB_GetSize(mb);
  26.         //把视频包入到队列里面
  27.         video_queue->putVideoPacketQueue(video_data_packet);//todo......
  28.         
  29.         //释放mb,重新获取下一个包
  30.         RK_MPI_MB_ReleaseBuffer(mb);
  31.     }
  32.     //到这里就是没数据了,就要把资源释放
  33.     //解绑定
  34.     MPP_CHN_S vi_channel;
  35.     MPP_CHN_S venc_channel;
  36.     vi_channel.s32ChnId = 0; //摄像头通道是0,也可以把vi通道号的参数一起传进来
  37.     vi_channel.enModId = RK_ID_VI;
  38.    
  39.     venc_channel.s32ChnId = venc_arg->vencId; //venc通道函数
  40.     venc_channel.enModId = RK_ID_VENC;
  41.    
  42.     ret = RK_MPI_SYS_UnBind(&vi_channel, &venc_channel);
  43.     if(ret != 0)
  44.     {
  45.         printf("VI和VENC解绑失败\n");
  46.     }
  47.     else
  48.     {
  49.         printf("VI和VENC解绑成功\n");
  50.     }
  51.     //释放venc
  52.     ret = RK_MPI_VENC_DestroyChn(venc_arg->vencId);
  53.     if(ret)
  54.     {
  55.         printf("venc释放失败");
  56.         return 0;
  57.     }
  58.     //释放vi
  59.     ret = RK_MPI_VI_DisableChn(0,0);
  60.     if(ret)
  61.     {
  62.         printf("vI释放失败");
  63.         return 0;
  64.     }
  65.     return NULL;
  66. }
复制代码
 
        具体的源码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表