您的位置:首页 > 其它

使用RTMPdump(libRTMP)直播来自v4l2的摄像头数据

2018-03-28 23:44 465 查看
转载至:https://blog.csdn.net/li_wen01/article/details/71548079
 RTMP是Real Time Messaging Protocol(实时消息传输协议),RTMPdump 封装了RTMP协议的一些接口,使用户使用RTMP协议更加的方便。关于RTMPdump的使用,可以参考博客    linux系统RTMPdump(libRTMP) 通过RTMP 发布H264数据    linux系统RTMPdump(libRTMP) 通过RTMP 发布FLV数据在进行RTMP实验的时候,需要先搭建好RTMP的编译文件和一个RTMP服务器,具体可以参考:    linux 编译安装TRMPdump(libRTMP)    nginx 搭建rtmp流媒体服务器    要实现RTMP直播V4L2摄像头数据,最简单的方案就是使用FFMPEG,它已经实现了所有的功能,用户只要使用一条命令就行了。但是对于有些嵌入式设备,没有足够的硬件资源来运行FFMPEG,对于这种情况,只能是自己来实现所需的所有接口。本文主要介绍在linux系统,用户通过v4l2采集摄像头的数据,然后对摄像头数据进行x264编码,再使用RTMPdump库通过RTMP协议将编码好的H264数据推送到RTMP服务器,最后客户端从RTMP服务器中将数据拉下来,解码,最后显示出来,进而实现实时直播的目的。主要工作流程图如下:


    关于v4l2采集摄像头数据并编码成H264,可以参考:V4L2视频采集与编码——学习目录及总结 主程序代码如下:[objc] view plain copy/*=============================================================================   
 *     FileName: main.cpp 
 *         Desc:   
 *       Author: licaibiao   
 *   LastChange: 2017-05-8    
 * =============================================================================*/    
#include "x264_encoder.h"  
#include "v4l2_device.h"  
#include "librtmp/log.h"  
#include <signal.h>  
#include <error.h>  
  
int runflag=0;  
static void sig_user(int signo){  
    if(signo==SIGINT){  
        runflag=0;  
        printf("received SIGINT\n");  
  }  
}  
  
void rtmp_push_v4l2(){  
    char url[]="rtmp://192.168.0.5:1935/live";  
    int fps     = 30;  
    int rate    = 333;  
    int width   = 640;  
    int height  = 480;  
    int outSize = 1024;  
  
    int index=0;      
    unsigned int tick = 0;  
    unsigned int tick_gap = 1000/fps;  
    uint32_t now=0;  
    uint32_t last_update=0;  
  
    int fd;  
    int len = 0;  
    uint8_t *cam_buf;  
    uint32_t pixelformat;  
  
    cam_buf = (uint8_t*)malloc(1024*1024*3);  
    memset(cam_buf, 0, 1024*1024*3);  
      
    pixelformat = V4L2_PIX_FMT_YUYV;  
      
    if(signal(SIGINT,sig_user)==SIG_ERR){  
        perror("catch SIGINT err");  
    }  
  
    fd =open_camera();  
    init_camera(fd, width, height);  
    start_capture(fd);  
          
    RTMP_CreatePublish(url,outSize,1,RTMP_LOGINFO);  
    printf("connected \n");  
    RTMP_InitVideoParams(width,height,fps, rate, pixelformat,false);  
    printf("inited \n");  
    runflag=1;  
    //runflag=3;  
          
    while(runflag){  
        if(index!=0){  
            RTMP_SendScreenCapture(cam_buf,height,tick, pixelformat, width, height);  
            printf("send frame index -- %d\n",index);  
        }  
        last_update=RTMP_GetTime();  
  
        read_frame(fd, cam_buf,&len);  
  
        tick +=tick_gap;  
        now=RTMP_GetTime();  
          
        //usleep((tick_gap-now+last_update)*1000);  
        usleep(1000);  
        index++;  
    }  
  
    free(cam_buf);  
    stop_capture(fd);  
    close_camera_device(fd);  
    RTMP_DeletePublish();  
}  
  
int main(){  
    rtmp_push_v4l2();  
    return 0;  
}  
    我使用的是一个30万像素的摄像头,也就是输出图像尺寸为640*480,它可以支持输出MJPEG 和YUV422 两种数据格式,因为需要进行x264编码,所以我这里设置的是输出YUV422(YUYV)格式。我自己搭建的RTMP服务器所在的地址为:rtmp://192.168.0.5:1935/live。    有几点需要注意:    1.在发送数据的时候,一定需要设置合适的帧率,因为在有些平台,可能编码花费的时间较多,并达不到初始化设置的帧率,这样在显示的时候就会出现问题。 
    2.需要客户端先向服务端请求数据,然后再向服务器推送h264数据,否则会出现非常明显的图像延时,大约2~3秒。工程目录如下:[objc] view plain copy-bash-4.1# tree  
.  
├── include  
│   ├── librtmp  
│   │   ├── amf.h  
│   │   ├── bytes.h  
│   │   ├── dhgroups.h  
│   │   ├── dh.h  
│   │   ├── handshake.h  
│   │   ├── http.h  
│   │   ├── log.h  
│   │   ├── rtmp.h  
│   │   └── rtmp_sys.h  
│   ├── librtmp_send264.h  
│   ├── sps_decode.h  
│   ├── v4l2_device.h  
│   ├── x264_config.h  
│   ├── x264_encoder.h  
│   └── x264.h  
├── lib  
│   ├── librtmp.a  
│   └── libx264.a  
├── librtmp_send264.cpp  
├── main.cpp  
├── Makefile  
├── v4l2_device.cpp  
└── x264_encoder.cpp  
程序运行如下:[objc] view plain copy-bash-4.1# ./test   
  
camera driver name is : uvcvideo  
camera device name is : UVC Camera (046d:0825)  
camera bus information: usb-0000:00:1a.0-1.1  
  
support device 1.YUV 4:2:2 (YUYV)  
support device 2.MJPEG  
  
n_buffer = 4  
connected   
x264 [warning]: VBV maxrate specified, but no bufsize, ignored  
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX  
x264 [info]: profile High 4:2:2, level 3.0, 4:2:2 8-bit  
inited   
^Creceived SIGINT  
select received SIGINT   
x264 [info]: frame I:1     Avg QP:36.90  size:  3106  
x264 [info]: frame P:55    Avg QP:25.29  size:  1070  
x264 [info]: mb I  I16..4: 25.9% 72.0%  2.1%  
x264 [info]: mb P  I16..4:  3.7%  2.5%  0.0%  P16..4: 20.0%  4.0%  0.6%  0.0%  0.0%    skip:69.1%  
x264 [info]: final ratefactor: 24.32  
x264 [info]: 8x8 transform intra:47.2% inter:32.7%  
x264 [info]: coded y,uvDC,uvAC intra: 18.5% 41.6% 7.7% inter: 2.0% 10.7% 0.0%  
x264 [info]: i16 v,h,dc,p: 27% 51% 12% 11%  
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 13% 45% 30%  2%  1%  1%  3%  1%  4%  
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 54% 12%  2%  2%  2%  4%  1%  4%  
x264 [info]: i8c dc,h,v,p: 61% 19% 17%  2%  
x264 [info]: Weighted P-Frames: Y:0.0% UV:0.0%  
x264 [info]: kb/s:265.47  
客户端直接使用VLC播放器,效果如下:


    需要完整工程下载链接:使用RTMPdump(libRTMP)直播来自v4l2的摄像头数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: