s5pv210 Linux HDMI TV output

Source: Internet
Author: User

Originally this is unfair open source code of now found also not worth the following published source code support linux3.0 linux2.6 kernel linux3.1 core V4L2 architecture has changed while supporting HDMI output and TV output using the board is the channel icool210

Source code is based on the Android LIBHDMI Library is organized here is based on the linux2.6.35 kernel test success

/* * * * * * * * * * * * * * hclydao<[email protected]> * * hidmitest.c Can redistribute it and/or modify * it under the terms of the GNU general public License version 2 as * published by T He free software Foundation. */#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include < getopt.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/stat.h># Include <sys/types.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/ioctl.h># Include <asm/types.h> #include <linux/videodev2.h> #include <linux/fb.h> #include "videodev2_ Samsung.h "#define HDMI_DEV"/dev/video14 "#define TVOUT_DEV0"/dev/video22 "#define FIMC_DEV"/dev/video2 "#define CLEAR (x) memset (& (x), 0, sizeof (x)) #define ALIGN (x, a) (((x) + (a)-1) & ~ ((a)-1)) static int fd = -1;v4l2_std_i D std_id = 0;static int m_width = 0;static int m_height = 0; #define LCD_dev "/dev/fb0" #define S3CFB_GET_LCD_ADDR _ior (' F ', 311, int) unsigned int phylcdaddr = 0;unsigned int Physya DDR = 0;static int lcd_fd = -1;static int ov_fd = -1;static int fimc_fd = -1;unsigned int mfimcrrvedphysmemaddr;unsigned i NT Hwver;static int out_w = 0;static int out_h = 0;struct Overlay_param {struct V4l2_framebuffer overlay_frame;struct v4l2 _window_s5p_tvout overlay_rect;struct v4l2_rectoverlay_dst;}; typedef unsigned int dma_addr_t;struct fimc_buf {dma_addr_tbase[3]; size_tlength[3];}; int Lcd_open () {lcd_fd = open (lcd_dev,o_rdwr, 0), if (LCD_FD < 0) {printf ("++++++open tvout DEV error\n"); return-1;} return LCD_FD;} int lcd_getaddr () {struct Fb_var_screeninfo info;if (IOCTL (LCD_FD, s3cfb_get_lcd_addr, &phylcdaddr) = =-1) {printf (" %s:ioctl (S3CFB_GET_LCD_ADDR) fail\n ", __func__); return-1;}               if (phylcdaddr = = 0) {printf ("%s::s3cfb_get_lcd_addr fail \ n", __func__); return-1;} if (IOCTL (LCD_FD, fbioget_vscreeninfo, &info) = =-1) {printf ("%s:ioctl (Fbioget_vscreeninfo) fail\n ", __func__);    return-1;    } m_width = Info.xres; M_height = Info.yres;return 0;} int Hdmi_open () {fd = open (Hdmi_dev, O_RDWR), if (FD < 0) {printf ("++++++open tvout DEV error\n"); return FD;} return FD;}    int Tvout_v4l2_querycap (void) {struct v4l2_capability cap;    int ret;    RET = IOCTL (FD, Vidioc_querycap, &cap);    if (Ret < 0) {printf ("Tvout_v4l2_querycap Vidioc_querycap failed%d\n", errno);    return ret;    }//printf ("Tvout_v4l2_querycap DRIVER:%s, CARD:%s, CAP.: 0x%08x\n",//Cap.driver, Cap.card, cap.capabilities); return ret;}    int tvout_v4l2_s_std (void) {int ret;    RET = IOCTL (FD, VIDIOC_S_STD, &std_id);    if (Ret < 0) {printf ("tvout_v4l2_s_std" "Vidioc_s_std failed%d\n", errno);    return ret; } return ret;}    int tvout_v4l2_enum_output (struct v4l2_output *output) {int ret;    RET = IOCTL (FD, vidioc_enumoutput, Output); return ret;} int tvout_v4l2_s_output (int index) {int ret;   RET = IOCTL (FD, Vidioc_s_output, &index);    if (Ret < 0) {printf ("Tvout_v4l2_s_output" "Vidioc_s_output failed%d\n", errno);    return ret; } return ret;} int Overlay_open () {ov_fd = open (Tvout_dev0, O_RDWR), if (OV_FD < 0) {printf ("++++++open TV out 0 dev error\n"); return ov_ FD;} return OV_FD;}    int tvout_ov_s_parm (int fp, int buf_type, void *ptr) {struct v4l2_streamparm parm;    struct V4l2_window_s5p_tvout *vparm = (struct v4l2_window_s5p_tvout*) ptr;    int ret;    Parm.type = (enum v4l2_buf_type) Buf_type;    memcpy (Parm.parm.raw_data, vparm, sizeof (struct v4l2_window_s5p_tvout));    RET = IOCTL (FP, Vidioc_s_parm, &parm);    if (Ret < 0) {printf ("Tvout_v4l2_s_parm" "Vidioc_s_parm failed%d\n", errno);    return ret; } return 0;}    int tvout_v4l2_s_fbuf (int fp, struct v4l2_framebuffer *frame) {int ret;    RET = IOCTL (FP, vidioc_s_fbuf, frame);    if (Ret < 0) {printf ("Tvout_v4l2_s_fbuf" "Vidioc_streamon failed%d\n", errno); return ret;    } return 0;}    int tvout_v4l2_cropcap (int fp, struct v4l2_cropcap *a) {struct V4l2_cropcap *cropcap = A;    int ret;    RET = IOCTL (FP, Vidioc_cropcap, Cropcap);        if (Ret < 0) {printf ("Tvout_v4l2_cropcap" "Vidioc_cropcap failed%d\n", errno);    return ret; } printf ("Tvout_v4l2_cropcap" "Bound width:%d, bound height:%d,\n", Cropcap->bounds.width, Cropcap->bounds    . height); return ret;}    int tvout_ov_s_crop (int fp, unsigned int type, struct v4l2_rect *rect) {struct V4l2_crop crop;    int ret;    Crop.type = (enum v4l2_buf_type) type;    Crop.c.left = rect->left;    Crop.c.top = rect->top;    Crop.c.width = rect->width;    Crop.c.height = rect->height;    RET = IOCTL (FP, Vidioc_s_crop, &crop);    if (Ret < 0) {printf ("Tvout_v4l2_s_crop" "Vidioc_s_crop failed%d\n", errno);    return ret; } return 0;} int tvout_v4l2_set_overlay (int fp) {struct Overlay_param ov_param;struct v4l2_cropcap cropcap;int dst_w,dst_h;dSt_w = Out_w;dst_h = Out_h;    Ov_param.overlay_frame.fmt.pixelformat = V4l2_pix_fmt_rgb32;    Ov_param.overlay_frame.base = (void *) mfimcrrvedphysmemaddr;    ov_param.overlay_rect.flags = 0;    ov_param.overlay_rect.priority = 0x02;    Ov_param.overlay_rect.win.w.left = 0;    ov_param.overlay_rect.win.w.top = 0;    Ov_param.overlay_rect.win.w.width = Dst_w;    Ov_param.overlay_rect.win.w.height = Dst_h;    Ov_param.overlay_rect.win.global_alpha = 0;ov_param.overlay_dst.left = 0;    ov_param.overlay_dst.top = 0;    Ov_param.overlay_dst.width = Dst_w; Ov_param.overlay_dst.height = Dst_h;tvout_v4l2_s_fbuf (FP, & (Ov_param.overlay_frame)); Tvout_ov_s_parm (fp,v4l2_    Buf_type_video_output_overlay, & (Ov_param.overlay_rect));    Cropcap.type = V4l2_buf_type_video_output_overlay;    Tvout_v4l2_cropcap (FP, &cropcap); if (ov_param.overlay_dst.width <= cropcap.bounds.width && Ov_param.overlay_dst.height <= cropcap.bounds.height) {tvout_ov_s_crop (FP, v4l2_buf_type_video_output_overlay,& (OV_PARAM.OVERLAY_DST));                } else {printf ("[%s] Invalid crop size dst.w=%d dst.h=%d bounds.w=%d bounds.h=%d\n", __func__,                Ov_param.overlay_dst.width, Ov_param.overlay_dst.height, Cropcap.bounds.width,    Cropcap.bounds.height);    return-1; }return 0;}    int Tvout_v4l2_streamon (int fp, unsigned int type) {int ret;    RET = IOCTL (FP, Vidioc_streamon, &type);    if (Ret < 0) {printf ("Tvout_v4l2_streamon" "Vidioc_streamon failed%d\n", errno);    return ret; } return 0;}    int tvout_v4l2_start_overlay (int fp) {int ret, start = 1;    RET = IOCTL (FP, Vidioc_overlay, &start);    if (Ret < 0) {printf ("Tvout_v4l2_start_overlay" "Vidioc_overlay failed\n");    return ret; } return ret;} int Fimc_open () {fimc_fd = open (Fimc_dev, O_RDWR), if (FIMC_FD < 0) {printf ("++++++open tvout DEV error\n"); return-1;} return FIMC_FD;}    int fimc_querycap (int fp) {struct v4l2_capability cap;    int ret;    RET = IOCTL (FP, Vidioc_querycap, &cap);    if (Ret < 0) {printf ("%s Vidioc_querycap failed%d\n", __func__, errno);    return ret; } if (! (        Cap.capabilities & v4l2_cap_streaming) {printf ("%s::%s has no streaming support\n", __func__, Fimc_dev);    return-1; } if (! (        Cap.capabilities & V4l2_cap_video_output) {printf ("%s::%s is no VIDEO output\n", __func__, Fimc_dev);    return-1; } return ret;}    int fimc_gfmt (int fp) {struct V4l2_format fmt;int ret;    Fmt.type = V4l2_buf_type_video_output;    RET = IOCTL (FP, VIDIOC_G_FMT, &AMP;FMT);        if (Ret < 0) {printf ("%s:: Error in Video vidioc_g_fmt\n", __func__);    return-1; }return ret;}    int Fimc_gctrl (int fp) {struct V4l2_control vc;int ret;    Vc.id = v4l2_cid_reserved_mem_base_addr;    Vc.value = 0;    RET = IOCTL (FP, Vidioc_g_ctrl, &AMP;VC); if (Ret < 0) {printf ("Error in video vidioc_g_ctrl-v4l2_cid_reserved_mem_baes_addr (%d) \ n", ret);    return-1;    }MFIMCRRVEDPHYSMEMADDR = (unsigned int) vc.value;    Vc.id = v4l2_cid_fimc_version;    Vc.value = 0;    RET = IOCTL (FP, Vidioc_g_ctrl, &AMP;VC); if (Ret < 0) {printf ("Error in video vidioc_g_ctrl-v4l2_cid_fimc_version (%d), Fimc VERSION was set with Defau        Lt\n ", ret);    Vc.value = 0x43;return-1; }hwver = Vc.value;return ret;}    int Fimc_sctrl (int fp) {struct V4l2_control vc;int ret;    Vc.id = V4l2_cid_ovly_mode;    Vc.value = 0x3;    RET = IOCTL (FP, Vidioc_s_ctrl, &AMP;VC);        if (Ret < 0) {printf ("Error in video Vidioc_s_ctrl-v4l2_cid_ovly_mode (%d) \ n", ret);    return-1; }return ret;}                int fimc_v4l2_set_src (int fd, unsigned int hw_ver) {struct v4l2_formatfmt;struct v4l2_cropcrop;intret_val;fmt.type = V4l2_buf_type_video_output;fmt.fmt.pix.width = M_width;fmt.fmt.pix.height = M_height;fmt.fmt.pix.pixel format = V4l2_pix_Fmt_rgb32;fmt.fmt.pix.field = V4l2_field_none;ret_val = IOCTL (FD, VIDIOC_S_FMT, &fmt); if (Ret_val < 0) {Prin TF ("Vidioc_s_fmt failed:ret=%d\n", ret_val); return-1;} Crop.type = v4l2_buf_type_video_output;if (Hw_ver = = 0x50) {crop.c.left = 0;crop.c.top = 0;} else {crop.c.left = 0;crop.c . top = 0;} Crop.c.width = M_width;crop.c.height = M_height;ret_val = IOCTL (FD, Vidioc_s_crop, &crop); if (Ret_val < 0) {printf ("Error in video Vidioc_s_crop (%d) \ n", ret_val); return-1;} return ret_val;}    int fimc_v4l2_req_buf (int fd, int num_bufs, int cacheable_buffers) {struct v4l2_requestbuffers reqbuf;    int ret;    Reqbuf.type = V4l2_buf_type_video_output;    Reqbuf.memory = v4l2_memory_userptr;    Reqbuf.count = Num_bufs;    RET = IOCTL (FD, VIDIOC_REQBUFS, &reqbuf);        if (Ret < 0) {printf ("+++++REQBUF ioctl error");    return ret;        } if (Reqbuf.count > Num_bufs) {printf ("++not enough buffer structs passed to Get_buffers"); Return-enomem; } return 0;} int fimc_v4l2_set_dst (int fd,int rotation, unsigned int addr) {struct V4l2_format sformat;struct v4l2_control vc;s Truct v4l2_framebuffer fbuf;int ret_val;/* * Set rotation configuration */vc.id = V4L2_CID_ROTATION;VC . Value = Rotation;ret_val = IOCTL (FD, Vidioc_s_ctrl, &AMP;VC), if (Ret_val < 0) {printf ("Error in video Vidioc_s_ctrl- Rotation (%d) \ n ", ret_val); return-1;} /* * Set Size, format & address for destination image (Dma-output) */ret_val = IOCTL (FD, VIDIOC_G_FBUF, &fbuf); (Ret_val < 0) {printf ("Error in video vidioc_g_fbuf (%d) \ n", ret_val); return-1;} Fbuf.base = (void *) Addr;fbuf.fmt.width = Out_w;fbuf.fmt.height = Out_h;fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB32;ret_ val = ioctl (FD, VIDIOC_S_FBUF, &fbuf); if (Ret_val < 0) {printf ("Error in video vidioc_s_fbuf (%d) \ n", ret_val); Retu rn-1;} /* * Set destination window */sformat.type = V4l2_buf_type_video_overlay;sformat.fmt.win.w.left = 0;SFORMAT.FMT.WIN.W. top = 0;sformat.fmt.win.w.width = Out_w;sformat.fmt.win.w.height = Out_h;ret_val = IOCTL (FD, VIDIOC_S_FMT, &sFormat if (Ret_val < 0) {printf ("Error in video vidioc_s_fmt (%d) \ n", ret_val); return-1;} return 0;} int fimc_v4l2_queue (int fd, struct fimc_buf *fimc_buf, int index) {struct v4l2_bufferbuf;intret_val;buf.type= v4l2_buf_ type_video_output;buf.memory= v4l2_memory_userptr;buf.m.userptr= (unsigned long) fimc_buf;buf.length= 0;buf.index= Index;ret_val = IOCTL (FD, VIDIOC_QBUF, &buf); if (Ret_val < 0) {printf ("Error in Vidioc_qbuf: (%d) \ n", ret_val); r eturn-1;} return 0;}  int fimc_v4l2_stream_on (int fd, enum V4l2_buf_type type) {if (IOCTL (FD, Vidioc_streamon, &type) < 0) {printf ("Error In vidioc_streamon\n "); return-1;} return 0;} int fimc_v4l2_dequeue (int fd) {struct V4l2_bufferbuf;buf.type = V4l2_buf_type_video_output;buf.memory = V4L2_ME Mory_userptr;if (IOCTL (FD, VIDIOC_DQBUF, &buf) < 0) {printf ("Error in vidioc_dqbuf\n"); return-1;} Return Buf.index;} int main (int argc, char *argv[]) {struct v4l2_output output;unsigned int i=0,ret=0,index;struct fimc_buf fimc_sbuf; unsigned int mode = 0;unsigned int hdmi_mode = 0;unsigned int y_size = 0;if (argc! = 2) {printf ("Usage%s mode\n", Argv[0] );p rintf ("mode is 1080,720,480,tv\n");p rintf ("Example%s 1080\n", argv[0]); return 0;} mode = Strtol (argv[1],null,10); switch (mode) {case 1080:std_id = V4l2_std_1080p_60;hdmi_mode = V4l2_output_type_digital ; out_w = 1920;out_h = 1080;break;case 720:std_id = V4l2_std_720p_60;hdmi_mode = V4l2_output_type_digital;out_w = 1280;out _h = 720;break;case 480:std_id = V4l2_std_480p_60_16_9;hdmi_mode = V4l2_output_type_digital;out_w = 720;out_h = 480;break ;d efault:std_id = V4l2_std_pal_bdghi;hdmi_mode = V4l2_output_type_composite;out_w = 720;out_h = 576;break;} Y_size = ALIGN (ALIGN (out_w,128) * ALIGN (Out_h, +), 8*1024); Lcd_open (); Lcd_getaddr ();p hysyaddr = Phylcdaddr;hdmi_open (    ); Tvout_v4l2_querycap (); tvout_v4l2_s_std ();    do {output.index = i; RET = Tvout_v4l2_enum_output (&output);    if (Output.type = = Hdmi_mode) break;    i++; }while (ret >=0); Tvout_v4l2_s_output (Output.index); Fimc_open (); Fimc_querycap (FIMC_FD); fimc_gfmt (FIMC_FD); FIMC _gctrl (FIMC_FD); Fimc_sctrl (FIMC_FD); fimc_v4l2_set_src (fimc_fd,hwver); FIMC_V4L2_SET_DST (fimc_fd,0, MFIMCRRVEDPHYSMEMADDR); Fimc_v4l2_req_buf (fimc_fd,1,0); fimc_v4l2_stream_on (fimc_fd,v4l2_buf_type_video_output); Fimc_sbuf.base[0] = phylcdaddr;fimc_sbuf.base[1] = phylcdaddr + y_size;fimc_sbuf.base[2] = 0;fimc_v4l2_queue (fimc_fd,& amp;fimc_sbuf,0); Overlay_open (); Tvout_v4l2_set_overlay (OV_FD); Tvout_v4l2_start_overlay (OV_FD); while (1) {index =    Fimc_v4l2_dequeue (FIMC_FD);    Fimc_sbuf.base[0] = phylcdaddr;    FIMC_SBUF.BASE[1] = phylcdaddr + y_size; FIMC_SBUF.BASE[2] = 0;fimc_v4l2_queue (fimc_fd,&fimc_sbuf,0);} return 1;}
Compilation generates binary after execution

Hdmitest 480 is output 480p

Hdmitest 720 Output 720p

Hdmitest 1080 Output 1080p

Hdmitest TV is the TV output which is the default is the TV output

Time is too long the specific principle is not fully understood the general principle is to obtain the FB data through the FIMC conversion and then overlay (hope not to say wrong)

Entire Source: http://download.csdn.net/detail/hclydao/8360065

============================================
Hclydao
Http://blog.csdn.net/hclydao
Copyright not, but reproduced please retain this paragraph statement

============================================


s5pv210 Linux HDMI TV output

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.