首页 > 其他分享 > iMX8MP HDMI图像输出 & V4L2生成MJPEG流

iMX8MP HDMI图像输出 & V4L2生成MJPEG流

时间:2023-08-10 14:55:27浏览次数:58  
标签:MJPEG return HDMI v4l2 VIDIOC fd iMX8MP V4L2

飞凌嵌入式OKMX8MP-C开发板基于NXP i.MX 8M Plus处理器开发设计,该系列处理器专注于机器学习与视觉、高级多媒体以及具有高可靠性的工业自动化。旨在满足智慧城市工业互联网、智能医疗智慧交通等应用的需求。强大的四核或双核Arm® Cortex®-A53处理器,主频高达1.6GHz,带有神经处理单元(NPU),最高运行速率可达2.3TOPS。本文采用的硬件板卡为飞凌嵌入式OKMX8MP-C开发板,系统版本Linux5.4.70+Qt5.15.0,主要介绍iMX8MP HDMI输出编程方法以及V4L2相机生成MJPEG流画面。

 

---------------------------------

 

飞凌嵌入式OKMX8MP-C开发板默认将三种显示接口LVDS/MIPI/HDMI全部打开,要对HDMI输出编程的话需要将MIPI显示关闭,关闭方式是进入uboot菜单的display选项进行操作:

 

iMX8MP 官方手册截图

 

iMX8MP上电之后,在串口终端uboot启动时狂按空格键,即可进入uboot菜单:

 

imx8mp uboot菜单

 

uboot菜单中的Display select选项就是设置iMX8MP输出接口的,可以分别对这三种接口进行设置,默认情况下三个输出接口都打开,而如果要进行FrameBuffer编程的话,经过实际测试,需要将LVDS和HDMI选项都打开,HDMI接口才能正常输出/dev/fb0外设的映射图像:

 

imx8mp Display select选项 1

 

如果将iMX8MP 的 LVDS接口关闭的话,HDMI接口输出不正常,/dev/fb0也不会生成,也就无法对

FrameBuffer进行编程:

 

FrameBuffer进行编程

 

imx8mp

 

 

在飞凌厂商提供的iMX8MP文档中,已经写明了iMX8MP HDMI接口输出的分辨率上限为1280*800*32,这个是由HDMI输出芯片决定的,毕竟IMX8的定位是工业控制而不是多媒体应用,对/dev/fb0外设进行ioctl,输出的分辨率也是1280*800,32位色彩:

 

使用命令

 

x11vnc -rawfb /dev/fb0 -clip 1280*800

 

可搭建x11vnc服务器,将FrameBuffer画面输出至vnc软件客户端,也就可以在不使用HDMI输出设备的FrameBuffer分辨率只有1280*800,意味着,V4L2相机生成的流画面,分辨率高于或等于这个数无法生成显示,甚至在实测中,低于这个数一点点也无法生成(1000*750),会提示段错误终止进程,因此我经过反复调试,最终将V4L2生成的流分辨率设置为900*675,无法对相机物尽其用(相机最大分辨率为1080P),但这是板子的Framebuffer最大支持的输出分辨率,无法再设置更大了。

 

#define  IMAGEWIDTH    900
#define  IMAGEHEIGHT   675

 

这次的V4L2推流,我不采用之前已经熟练掌握的V4L2生成YUYV流,而是直接生成MJPEG流,生成此流有2个好处,一是生成MJPEG流无需经过YUYV转RGB的步骤,帧生成时间更短,相比起之前生成YUYV流的方式,流畅度有非常明显的提升;二是生成MJPEG流可直接保存为JPEG文件,在确保IO读取锁无冲突的前提下,可供外部程序进行访问。要使用V4L2驱动库生成MJPEG流,初始化步骤要写对:

 

    struct v4l2_format fmt;

    fmt.type = V4L2_CAP_VIDEO_CAPTURE;
    fmt.fmt.pix.width = IMAGEWIDTH;
    fmt.fmt.pix.height = IMAGEHEIGHT;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
    IF (ioctl (fd_video, VIDIOC_S_FMT, &fmt) == -1)
    {
        perror("ERROR camera VIDIOC_S_FMT FaiLED.");
        return -1;
    }

 

检查写入参数是否正确:

 

    if (ioctl (fd_video, VIDIOC_G_FMT, &fmt) == -1)
    {
        perror("ERROR camera VIDIOC_G_FMT Failed.");
        return -1;
    }

 

使用mmap()进行物理内存地址到用户内存地址的映射,即使用一个用户定义缓存来读取物理内存中的摄像头缓存数据:

 

    struct v4l2_buffer v4l2_buf;
    v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    v4l2_buf.memory = V4L2_MEMORY_MMAP;
    for(i = 0; i < 4; i++)
    {
        v4l2_buf.index = i;
        if(ioctl(fd_video, VIDIOC_QUERYBUF, &v4l2_buf) < 0)
        {
            perror("Unable to query buffer.");
            return -1;
        }

        pic.tmpbuffer[i] = (unsigned char*)mmap(NULL, v4l2_buf.length, PROT_READ, MAP_SHARED, fd_video, v4l2_buf.m.offset);
        if(pic.tmpbuffer[i] == MAP_FAILED)
        {
             perror("Unable to map buffer.");
             return -1;
        }
        if(ioctl(fd_video, VIDIOC_QBUF, &v4l2_buf) < 0)
        {
            perror("Unable to queue buffer.");
            return -1;
        }
    }

 

开启捕捉:

 

    int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if(ioctl(fd_video , VIDIOC_STREAMON , &type) < 0)
    {
        perror("Unable to start capture.");
        return -1;
    }

 

捕捉并生成JPEG文件,循环执行的函数:


<div><div><span>int</span><span> </span><span>V4l2_Grab_Mjpeg</span><span>(</span><span>char</span><span> </span><span>*</span><span> </span><span>filename</span><span>)</span>
</div></div>{
    struct v4l2_buffer buff;
    buff.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buff.memory = V4L2_MEMORY_MMAP;
    if(ioctl(fd_video , VIDIOC_DQBUF, &buff) < 0)
    {
        printf("camera VIDIOC_DQBUF Failed.\n");
        usleep(1000*1000);
        return -1;
    }

    pic.tmpbytesused[buff.index] = buff.bytesused;
    printf("size : %d\n",pic.tmpbytesused[buff.index]);

    int jpg_fd = open("1.jpeg" , O_RDWR | O_CREAT , 00700);
    if(jpg_fd == -1)
    {
        printf("open ipg Failed!\n ");
        return -1;
    }
    int writesize = write(jpg_fd , pic.tmpbuffer[buff.index] , pic.tmpbytesused[buff.index]);
    printf("Write successfully size : %d\n" , writesize);
    close(jpg_fd);

    //10、Queue the buffers.
    if(ioctl(fd_video , VIDIOC_QBUF, &buff) < 0)
    {
        printf("camera VIDIOC_QBUF Failed.");
        usleep(1000*1000);
        return -1;
    }
    return 0;
}

 

主循环运行:

 

    while(1)
    {
        V4l2_Grab_Mjpeg(MJPEG_FILE_NAME);
        LCD_RGB888_Show_JPG_File(FB_DEV, 0 , 0 , MJPEG_FILE_NAME);
    }

 

运行效果:

 

imx8mp 运行结果

标签:MJPEG,return,HDMI,v4l2,VIDIOC,fd,iMX8MP,V4L2
From: https://www.cnblogs.com/kn-zheng/p/17620326.html

相关文章

  • 汉源高科1路单向非压缩HDMI视频(带环出)+1路双向立体声音频+1路232数据高清视频光端机
    1路单向非压缩HDMI视频(发射端带本地环出)+1路双向立体声音频+1路RS232数据HDMI高清视频光端机HY-HDMI-1V(Z)1D1A(S)是汉源高科(北京)科技有限公司自主研发产品的一款产品,HDMI光端机是由HDMI发射端和HDMI接收端组成,通过一芯单模光纤传输HDMI高清音视频+RS232数据信号。在多媒体应用系统......
  • 汉源高科1路单向非压缩HDMI视频+1路双向音频+1路RS232数据高清视频光端机
    1路单向非压缩HDMI视频+1路双向音频+1路RS232数据HDMI高清视频光端机HY-HDMI-1V(Z)1D1A(S)是汉源高科(北京)科技有限公司自主研发产品的一款产品,HDMI光端机是由HDMI发射端和HDMI接收端组成,通过一芯单模光纤传输HDMI高清音视频+RS232数据信号。在多媒体应用系统中,往往需要把HDMI数字视......
  • 汉源高科1路单向非压缩HDMI视频+1路单向音频HDMI高清视频光端机
    1路单向非压缩HDMI视频+1路单向音频HDMI高清视频光端机HY-HDMI-1V(Z)1A(Z)是汉源高科(北京)科技有限公司自主研发产品的一款产品,HDMI光端机是由HDMI发射端和HDMI接收端组成,通过一芯单模光纤传输HDMI高清音视频信号。在多媒体应用系统中,往往需要把HDMI数字视频信号进行远距离、无失真......
  • 汉源高科1路单向非压缩HDMI高清视频光端机
    1路单向非压缩HDMI高清视频光端机HY-HDMI-1V(Z)是汉源高科(北京)科技有限公司自主研发产品的一款产品,HDMI光端机是由HDMI发射端和HDMI接收端组成,通过一芯单模光纤传输HDMI高清视频信号。在多媒体应用系统中,往往需要把HDMI数字视频信号进行远距离、无失真的并行传输。但使用普通的电缆......
  • Rockchip RK3399 - HDMI音频
    ----------------------------------------------------------------------------------------------------------------------------开发板:NanoPC-T4开发板eMMC:16GBLPDDR3:4GB显示屏:15.6英寸HDMI接口显示屏u-boot:2023.04linux  :6.3--------------------------......
  • 熊猫B7PRO主板3865U3965U输出HDMI音频及视频解码能力
    之前有人咨询过,最近又有一些人咨询,经常发嘛太麻烦,找了个以前截的图。如图采用的USBHDMI采集卡,名称为HDMITOUSB,如果是普通显示器或者电视机,会显示正常的显示器名称之类的。有一些人连接了之后,并没有这个设备,就是因为没有BIOS启用功能。BIOS的设置https://blog.51cto.com/infrado/......
  • msm8909_MIPI转HDMI调试记录
    项目中需要把开发板的MIPI输出信号转换为HDMI和LVDS输出,使用龙迅的LT8912B进行转换。龙迅的FAE提供的资料相对来说还是比较少的。先简单的看一下吧:厂商资料寄存器配置该文件提供了对LT8912B初始化的寄存器配置。对于我们来说需要做的就是,写一个驱动,在开机的时候调用相关的函数,......
  • CS5801国产HDMI转DP/edp(4k60)转换器方案芯片 可替代LT6711
    CS5801是HDMI2.0b到DP1.4a转换器方案IC。CS5801有一个HDMI2.0b.输入,带宽高达18Gbps.它支持辨别率是4k@60Hz。对于DP1.4输出,由4条数据通道组成,支持1.62Gbps、2.7Gbps、5.4Gbps链路速率。内置可选SSC功能可降低EMI影响。嵌入式MCU基于32位RISC-V内核,带有内部串行闪存。CS5801参数......
  • HDMI图像传输(等宽十色彩条)
    第41章、HDMI(等宽十色彩条)41.1DVI(数字视频接口)VGA接口之后,首先推出的的是DVI接口(数字视频接口),DVI是基于TMDS(TransitionMinimizedDifferentialSignaling,最小化传输差分信号)技术来传输数字信号。TMDS运用先进的编码算法把8bit数据(R、G、B中的每路基色信号)通过......
  • CS5213 国产HDMI转VGA带音频方案芯片|CS5213规格书|CS5213原理图
    集睿致远/ASL推出的CS5213芯片是一个国产HDMI(高清多媒体接口)到VGA桥接芯片。它将HDMI信号转换为标准VGA信号它可以在适配器、智能电缆等设备中设计CS5213特征将HDMI信号转换为VGA输出支持数字信号到模似信号的转换支持HDCP1.0/1.1/1.2操作简单,无需设置支持热插拔.HDMI视频输入格......