分类: 嵌入式
2011-04-25 21:09:06
Display Driver
Contents []
|
Display Sub-System hardware integrates one graphics pipeline, two video pipelines, and two overlay managers (one for digital and one for analog interface). Digital interface is used for LCD and DVI output and analog interface is used for TV out.
The primary functionality of the display driver is to provide
interfaces to user level applications and management of Display
Sub-System hardware.
This section defines and describes the usage of user level interfaces of Video Display Driver.
NOTE: Please note that the AM3517 and AM/DM37x Display Sub-System module is same as OMAP3x, so terms have been used inter-changeably and referred as OMAP3x in this document.
Acronym | Definition |
---|---|
V4L2 | Video for Linux Two |
DSS | Display SubSystem |
NTSC | National Television System Committee |
PAL | Phase Alternating Line |
LCD | Liquid Crystal Display |
DVI | Digital Visual Interface |
The display subsystem provides the logic to display a video frame from the memory frame buffer (either SDRAM or SRAM) on a liquid-crystal display (LCD) panel or a TV set. The display subsystem integrates the following elements
The Display driver supports the following features:
This chapter describes the Driver Architecture and Design concepts
Driver ArchitectureOMAP3x display hardware integrates one graphics pipeline, two video pipelines, and two overlay managers (one for digital and one for analog interface). Digital interface is used for LCD and DVI output and analog interface is used for TV out.
The primary functionality of the display driver is to provide interfaces to
user level applications and management to OMAP3x display hardware.
This includes, but is not limited to:
Above figure (OMAP3x Display Subsystem Architecture) shows the major components that makes up the DSS software sub-system
This is a HAL/functional layer controlling the bulk of DSS hardware.
It exposes the number of APIs controlling the overlay managers, clock,
and pipelines to the user interface drivers like V4L2 and FBDEV. It also
exposes the functions for registering and de-registering of the various
display devices like LCD and DVI to the DSS overlay managers.
The SYSFS interfaces are mostly used as the control path for
configuring the DSS parameters which are common between FBDEV and V4L2
like the alpha blending, color keying, etc. It is also used for
switching the output of the pipeline to either LCD or
Digital overlay manager. In future sysfs entries might also be used to
switch the modes like NTSC, PAL on TV and 480P, 720P on DVI outputs.
This driver is registered with the FBDEV subsystem, and is
responsible for managing the graphics layer frame buffer. Driver creates
/dev/fb0 as the device node. Application can open this device node to
open the driver and negotiate parameters with the driver through frame
buffer ioctls. Application maps driver allocated buffers in the
application memory space and fills them for the driver to display.
Video applications (camera, camcorder, image viewer, etc.) use the
standard V4L2 APIs to render static images and video to the video
layers, or capture/preview camera images.
This driver is responsible for managing the video layers frame-buffers.
It is a V4L2 compliant driver with some additions to implement special
software requirements that target OMAP3x hardware features . This driver
conforms to the Linux driver model. For using the driver, application
should create the device nodes /dev/video1 and /dev/video2 device nodes
for two video layers. Application can open the driver by opening these
device nodes and negotiate the parameters by V4L2 ioctls. Initially
application can request the driver to allocate number of buffers and
MMAPs these buffers. Then the application can fill up these buffers and
pass them to driver for display by using the standard V4L2 streaming
ioctls.
The device can be opened using open call from the application, with the device name and mode of operation as parameters. Application can open the driver only in blocking mode. Non-blocking mode of open is not supported.
The driver will expose two software channels (/dev/video1 and /dev/video2), one for each video pipeline. Both of these channels supports only blocking mode of operations. These channels can only be opened once.
The driver will expose one software channels (/dev/fb0) for the graphics pipeline. The driver cannot be opened multiple times. Driver can be opened only once.
V4L2 driver supports set of command line argument for, default number of buffers, their buffer size, enable/disable VRFB buffer allocation and debug option for both the video pipelines.
V4L2 driver uses the VRFB buffers for rotation. Because of the
limitation of the VRFB engine these buffers are quite big in size.
Please refer to the Buffer Management section for required and allocated
size of the VRFB buffers. VRFB buffers are allocated by driver during
vidioc_reqbufs ioctl if the rotation is enabled and freed during
vidioc_streamoff. But under heavy system load, memory fragmentation may
occur and VFRB buffer allocation may fail. To address this issue V4L2
driver provides command line argument to allocate the VRFB buffers at
driver init time and buffers will be freed when driver is unloaded.
Below is the list of arguments which V4L2 driver supports -
Argument | Description |
---|---|
video1_numbuffers | Number of buffers to be allocated at init time for Video1 device |
video2_numbuffers | Number of buffers to be allocated at init time for Video2 device |
video1_bufsize | Size of the buffer to be allocated for video1 device |
video2_bufsize | Size of the buffer to be allocated for video2 device |
vid1_static_vrfb_alloc | Static allocation of the VRFB buffer for video1 device |
vid2_static_vrfb_alloc | Static allocation of the VRFB buffer for video2 device |
debug | Enable debug messaging |
For dynamic build of the driver, these argument are specified at the
time of inserting the driver. For static build of the driver, these
argument can be specified along with boot time arguments. Following
example shows how to specify command line argument for static and
dynamic build.
Insert the dynamically built module with following parameters:
Below is the sample example of bootargs for statically compiled driver from bootloader:
# setenv bootargs 'console=ttyS0,115200n8 mem=128M root=/dev/nfs noinitrd nfsroot=nfs-server/home,nolock ip=dhcp omap_vout.video1_numbuffers=3 omap_vout.video2_numbuffers=3 omap_vout.video1_bufsize=64400 omap_vout.video2_bufsize=64400 omap_vout.vid1_static_vrfb_alloc=y omap_vout.vid2_static_vrfb_alloc=y'
FBDEV driver supports set of command line argument for enabling/setting rotation angle, enable/disable VRFB rotation, default mode, size of vram and debug option. These command line arguments can only be used with boot time arguments as FBDEV driver only supports static build.
Below is the list of arguments which Fbdev driver supports -
Argument | Description |
---|---|
mode | Default video mode for specified displays |
vram | VRAM allocated memory for a framebuffer, user can individually configure VRAM buffers for each plane/device node |
vrfb | Use VRFB rotation for framebuffer |
rotate | Default rotation applied to framebuffer |
test | Draw test pattern to framebuffer whenever framebuffer settings change |
debug | Enable debug messaging |
Following example shows how to specify 90 degree rotation in boot time argument:
Following example shows how to specify size of framebuffer in boot time argument:
setenv bootargs console=ttyS0,115200n8 mem=128M noinitrd root=/dev/nfs nfsroot=nfs-server/home,nolock ip=dhcp vram=20M omapfb.vram=0:20M
Following example shows how to specify mode for framebuffer in boot time argument:
# setenv bootargs console=ttyS0,115200n8 mem=128M noinitrd root=/dev/nfs nfsroot=nfs-server/home,nolock ip=dhcp omapfb.mode=dvi:720x480@60
There are few arguments which allows control over core DSS functionality.
Argument | Description |
---|---|
def_disp | Name of default display, to which all overlays will be connected |
debug | Enable debug messages |
Following example shows how to specify default display to particular output in boot time argument:
Driver | Without Rotation | With Rotation |
---|---|---|
Fbdev Driver | A single buffer of size 480*640*2 bytes, can be changed through bootargs | A single buffer of size 2048*640*2 bytes, can be changed through bootargs |
V4L2 Driver | Single buffer of 1280*720*4 bytes and Number of buffers is configurable using VIDIOC_REQBUFS ioctl and command line argument | Same requirement as without rotation. Additionally allocates one buffer of size 3686400 bytes for each context. Number of context are same as the number of buffers allocated using REQBUFS, which is not more than four. |
Memory Mapped buffer mode and User pointer buffer mode are the two memory allocation modes supported by driver. In Memory map buffer mode, application can request memory from the driver by calling VIDIOC_REQBUFS ioctl. In this mode, maximum number of buffers is limited to VIDEO_MAX_FRAME (defined in driver header files) and is limited by the available memory in the kernel. If driver is not able to allocate the requested number of buffer, it will return the number of buffer it is able to allocate.
The main steps that the application must perform for buffer allocation are:
Ioctl: VIDIOC_REQBUFS
This is a necessary ioctl for streaming IO. It has to be called for both drivers buffer mode and user buffer mode. Using this ioctl, driver will identify whether driver buffer mode or user buffer mode will be used.
It takes a pointer to instance of the v4l2_requestbuffers structure as an argument.
User can specify the buffer type (V4L2_BUF_TYPE_VIDEO_OUTPUT), number of buffers, and memory type (V4L2_MEMORY_MMAP, V4L2_MEMORY_USERPTR)at the time of buffer allocation. In case of driver buffer mode, this ioctl also returns the actual number of buffers allocated in count member of v4l2_requestbuffer structure.
It can be called with zero number of buffers to free up all the buffers already allocated. It also frees allocated buffers when application changes buffer exchange mechanism. Driver always allocates buffers of maximum image size supported. If application wants to change buffer size, it can be done through video1_buffsize and video2_buffsize command line arguments.
When rotation is enabled, driver also allocates buffer for the VRFB virtual memory space along with the mmap or user buffer. It allocates same number of buffers as the mmap or user buffers. Maximum number of buffers, which can be allocated, is 4 when rotation is enabled.
Ioctl: VIDIOC_QUERYBUF
This ioctl is used to query buffer information like buffer size and buffer physical address. This physical address is used in m-mapping the buffers. This ioctl is necessary for driver buffer mode as it provides the physical address of buffers, which are used to mmap system call the buffers.
It takes a pointer to instance of v4l2_buffer structure as an argument. User has to specify the buffer type (V4L2_BUF_TYPE_VIDEO_OUTPUT), buffer index, and memory type (V4L2_MEMORY_MMAP)at the time of querying.
Mapping the kernel buffer to the user space can be done via mmap. User can pass buffer size and physical address of buffer for getting the user space address
FBDEV driver supports only memory mapped buffers. Driver allocates one physically contiguous buffers, which can support 480X640 resolution for 16 bpp format.
Following steps are required to map buffers in application memory space.
FBIOGET_FSCREENINFO ioctl is used to get the not-changing screen information like physical address of the buffer, size of the buffer, line length.
FBIOGET_VSCREENINFO ioctl is used to get the variable screen information like resolution, bits per pixel etc...
Mapping the kernel buffer to the user space can be done via mmap system call.
Rotation is implemented with use of Rotation Engine module in Virtual Rotation Frame Buffer module in OMAP3x. Rotation engine supports rotation of an image with degree 0, 90, 180 and 270. There are 12 contexts available for rotating an image and there are four virtual memory space associated with each context. To rotate an image, image is written to 0 degree virtual memory for a context and rotated image can read back from the virtual memory for that angle of the same context.
For using Rotation Engine, User has to allocate physical memory and provide address of the memory to the rotation engine. The buffer size for this physical buffer should be large enough to store the image to be rotated. When program writes to the virtual address of the context, rotation engine write to this memory space and when program reads image from virtual address, rotation engine reads image from this buffer with rotation angle.
V4L2 driver supports rotation by using rotation engine in the VRFB module. Driver allocates physical buffers, required for the rotation engine, when application calls VIDIOC_REQBUFS ioctl. Therefore, when this ioctl is called driver allocates buffers for storing image and allocates buffers for the rotation engine. It also programs VRFB rotation engine when this ioctl is called. At the time of enqueing memory mapped buffer, driver copies entire image from mmaped buffer to buffer for the rotation engine using DMA. DSS is programmed to take image from VRFB memory space when rotation is enabled. So DSS always gets rotated image. Maximum four buffers can be allocated using REQBUFS ioctl when rotation is enabled.
Driver provides ioctl interface for enabling/disabling and changing the rotation angle. These ioctls are VIDIOC_S_CTRL/VIDIOC_G_CTRL as drive allocates buffer for VRFB during REQBUFS ioctl, application has to enable/set the rotation angle before calling REQBUFS ioctl. After enabling rotation, application can change the rotation angle. Rotation angle cannot be changed while streaming is on.
Following code shows how to set rotation angle to 90 degree:
NOTE: Rotation value must be set using VIDIOC_S_CTRL before setting any format using VIDIOC_S_FMT as VIDIOC_S_FMT uses rotation value for calculating buffer formats. Also VIDIOC_S_FMT ioctl must be called after changing the rotation angle to change parameters as per the new rotation angle.
FBDEV driver supports rotation by using rotation engine in the VRFB module. For using this feature of the driver, rotation has to be enabled. Application can enable rotation by enabling/setting rotation angle in boot time argument of the kernel for FBDEV driver. Applications can thus use the FBIOPUT_VSCREENINFO ioctl to set the rotation angle. Applications have to set the 'rotate' field in the fb_var_screeninfo structure equal to the angle of rotation (0, 90, 180 or 270) and call this ioctl. Frame buffer driver also supports the rotation through sysfs entry. Any one of the two method can be used to configure rotation.
Constraint: While doing rotation x-resolution virtual should be equal to x-resolution. y-resolution virtual should be greater than or equal to yresolution. Please note that VRFB rotation engine requires alignment of 32 bytes in horizontal size and 32 lines in vertical size. So while doing rotation x-resolution should be 32 byte aligned and y resolution and y resolution virtual should be 32 lines aligned. For example for 360X360 required resolution with 16bpp no of bytes per line comes to 360*2=720. Which is not 32 byte aligned. While no of lines comes to 360 which is also ot 32 lines aligned. So actual resolution should be set to 368X368. But if same resolution is required for 32bpp then no of bytes per line comes to 360*4 that is 1440. Which is 32 byte aligned so actual resolution should be set to 360X368. Also the maximum y-res virtual possible is 2048 because of VRFB limitation when rotation enabled.
var.rotate variable should not be modified when rotation is not selected through command line arguments else behaviour is unexpected
NOTE: By default frame buffer driver allocates the buffer for single VGA (480x640) frame considering 0 degree rotation. Please refer to the section
Following code listings demos how to set the rotation in frame buffer driver using ioctl and sysfs entry:
Setting the rotation through sysfs where 0 - 0 degree, 1 - 90 degree, 2 - 180 degree and 3 - 270 degree respectively:
# echo 1 > /sys/class/graphics/fb0/rotate
There are two types of transparent color keys: Video source transparency and graphics destination transparency key. The encoded pixel color value is compared to the transparency color key. For CLUT bitmaps, the palette index is compared to the transparency color key and not to the palette value pointed out by the palette index.
Constraint: The video source transparency color key and graphics destination transparency color key cannot be active at the same time.
User can Color Keying either through V4L2 Driver IOCTL interface or SYSFS interface.
Video source transparency color key value allows defining a color that
the matching pixels with that color in the video pipelines are replaced
by the pixels in graphics pipeline. It is limited to RGB formats only
and non-scaling cases.
The Graphics destination color key allows defining a color that the nonmatching pixels in the graphics pipelines prevent video overlay. The destination transparency color key is applicable only in the graphics region when graphics and video overlap. Otherwise, the destination transparency color key is ignored.
Both the keying mechanism cannot be used simultaneously. All color key related IOCTLs are not pipeline oriented. Following example shows how to use source and destination color key using both the interfaces -
Enable Source Color Keying:
struct v4l2_framebuffer framebuffer; ret = ioctl (fd, VIDIOC_G_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_G_FBUF"); close(fd); exit(1); } /* Set SRC_COLOR_KEYING if device supports that */ if(framebuffer.capability & V4L2_FBUF_CAP_SRC_CHROMAKEY) { framebuffer.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; framebuffer.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; ret = ioctl (fd, VIDIOC_S_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_S_FBUF"); close(fd); exit(1); } }Disabling the Source Color Keying:
struct v4l2_framebuffer framebuffer; ret = ioctl (fd, VIDIOC_G_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_G_FBUF"); close(fd); exit(1); } if(framebuffer.capability & V4L2_FBUF_CAP_SRC_CHROMAKEY) { framebuffer.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; ret = ioctl (fd, VIDIOC_S_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_S_FBUF"); close(fd); exit(1); } }Enableing destination color keying:
struct v4l2_framebuffer framebuffer; ret = ioctl (fd, VIDIOC_G_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_G_FBUF"); close(fd); exit(1); } /* Set SRC_COLOR_KEYING if device supports that */ if(framebuffer.capability & V4L2_FBUF_CAP_CHROMAKEY) { framebuffer.flags |= V4L2_FBUF_FLAG_CHROMAKEY; framebuffer.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; ret = ioctl (fd, VIDIOC_S_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_S_FBUF"); close(fd); exit(1); } }Disabling destination color keying:
struct v4l2_framebuffer framebuffer; ret = ioctl (fd, VIDIOC_G_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_G_FBUF"); close(fd); exit(1); } if(framebuffer.capability & V4L2_FBUF_CAP_CHROMAKEY) { framebuffer.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; ret = ioctl (fd, VIDIOC_S_FBUF, &framebuffer); if (ret < 0) { perror ("VIDIOC_S_FBUF"); close(fd); exit(1); } }
Below program listing shows how to set the chromakey value. Please note
that chroma key value should be set before enabling the chroma keying.
Overlay manager should not be changed between the setting up
of chroma key and enabling the chroma keying.
The code snippet below illustrates how to get the chromakey value.
struct v4l2_format fmt; fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ret = ioctl(fd, VIDIOC_G_FMT, &fmt); if (ret < 0) { perror("VIDIOC_G_FMT\n"); close(fd); exit(0); } printf("Croma value read is %d\n", fmt.fmt.win.chromakey);
Alpha blending is a process of blending a foreground color with a background color and producing a new blended color. New blended color depends on the transparency factor referred to as alpha factor of the foreground color. If the alpha factor is 100% then blended image will have only foreground color. If the alpha factor is 0% blended image will have only back ground color. Any value between 0 to 100% will blend the foreground and background color to produce new blended color depending upon the alpha factor.
Overlay manager of DSS is capable of supporting the alpha blending. This
is done by displaying more than one layer (video and graphics) to the
same output device, TV or LCD. Overlay manager supports normal mode and
alpha mode of operation.
In normal mode graphics plane is at bottom on top of it is video1 and video2 is on top of video1. While in alpha mode video1 plane is at bottom, video2 is on top of video1, and graphics plane is above video2. Alpha mode is selectable on any of the output device TV or LCD.
Video2 and graphics layer of the DSS is capable of supporting alpha
blending. Two types of alpha blending is supported global and pixel
alpha blending. ARGB and RGBA formats of the video2 and graphics
pipeline
supports pixel based alpha blending. In which A represent the alpha
value for each pixel. Thus, each pixel can have different alpha value.
While global alpha is the constant alpha factor for the pipeline for all
the pixels. Both can be used in conjunction.
Both V4L2 and Frame buffer driver supports alpha blending based on pixel format for video2 and graphics pipeline respectively. Global alpha blending is also supported through V4L2 and SYSFS interface. Before using any of the alpha blending methods alpha blending needs to be enabled on the selected output device either through V4L2 ioctl or SYSFS interface. Alpha blending will be enabled on the output device to which video pipeline is connected
Following program listing will enable alpha blending through V4L2 driver ioctl -
Following program listing will disable alpha blending through V4L2 driver ioctl -
Following program listing will enable/disable alpha blending through SYSFS entry -
User can configure global alpha value either through V4L2 IOCTL (V4L2_BUF_TYPE_VIDEO_OVERLAY ) or SYSFS interfac.
Below programlisting shows how to set the global alpha value for video2 pipeline.
V4L2 Driver
V4l2 driver supports alpha blending through ARGB pixel format as well as global alpha value.
To set the pixel alpha value set ARGB format by setting format type to V4L2_PIX_FMT_RGB32. Call VIDIOC_S_FMT ioctl of the driver to set it to ARGB format.
Note: RGBA format is not supported.
FBDEV Driver
Pixel alpha value is supported through 32 bpp. Setting the offsets correctly will set the pixel format as ARGB or RGBA.
Below program listing shows how to set ARGB pixel format.
User can set the global alpha value for graphics pipeline using sysfs entry, as shown below -
NOTE: Before using the global alpha or pixel based alpha Alpha
blending needs to be enabled using either sysfs or V4L2 ioctl interface.
Buffer format describes the pixel format in the image. It also describes the memory organization of each color component within the pixel format. In all buffer formats, blue value is always stored in least significant bits, then green value and then red value.
V4L2 Driver
Video layer supports following buffer format: YUYV, UYVY, RGB565, RGB24 (packed and unpacked). The corresponding v4l2 defines for pixel format are V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_RGB24 (packed), V4L2_PIX_FMT_RGB32. (For video1 and video2 V4L2_PIX_FMT_RGB32 corresponds to RGB24 unpacked).
Buffer format can be changed using VIDIOC_S_FMT ioctl with type as V4L2_BUF_TYPE_VIDEO_OUTPUT and appropriate pixel format type.
Following example shows how to change pixel format to RGB565
FBDEV Driver
Graphics layer supports following buffer format: RGB24(un-packed) ARGB, RGBA and RGB565. Buffer format can be changed in FBDEV driver by using bpp, red, green, and blue fields of fb_vscreeninfo structure and ioctl FBIOPUT_VSCREENINFO. Application needs to specify bits per pixel and length and offset of red, green and blue component. Bits-per-pixel and color depth in the pixel aren't quite the same thing. The display controller supports color depths of 1, 2, 4, 8, 12, 16, 24 and 32 bits. Color depth and bits-per-pixel are the same for depths of 1, 2, 4, 8, and 16 bits, but for a color depth of 12 bits the pixel data is padded to 16 bits-per-pixel, and for a color depth of 24 bits the pixel data is padded to 32 bits-per-pixel. So application has to specify bits per pixel 16 and 32 for the color depth 12 and 24. To specify exact color depth, red, green and blue member of the fb_varscreeninfo can be used.
Following example shows how to set 12 and 24 bits per pixels.
struct fb_varscreeninfo var; var.bpp = 16; var.red.length = var.green.length = var.blue.length = 4; var.red.offset = 8; var.green.offset = 4; var.blue.offset = 0; ret = ioctl(fd, FBIOPUT_VSCREENINFO, &var); if (ret < 0) { perror("FBIOPUT_VSCREENINFO\n"); close(fd); exit(0); }
Buffer Formats
The video pipelines can be connected to either an DVI output LCD output or a TV output either through boot time parameter or through SYSFS interface. Although the display Driver computes a default display window whenever the image size or cropping is changed, an application should position the display window via the VIDIOC_S_FMT I/O control with the V4L2_BUF_TYPE_VIDEO_OVERLAY buffer type. When a switch from LCD to TV or from TV to LCD happens, an application is expected to adjust the display window. V4L2 driver only supports change of display window.
Following example shows how to change display window size.
struct v4l2_format fmt; Fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; fmt.fmt.win.w.left = 0; fmt.fmt.win.w.top = 0; fmt.fmt.win.w.width = 200; fmt.fmt.win.w.height = 200; ret = ioctl(fd, VIDIOC_S_FMT, &fmt); if (ret < 0) { perror("VIDIOC_S_FMT\n"); close(fd); exit(0); } /* Display window size and position is changed now */
The V4L2 Driver allows an application to define a rectangular portion of the image to be rendered via the VIDIOC_S_CROP Ioctl with the V4L2_BUF_TYPE_VIDEO_OUTPUT buffer type. When application calls VIDIOC_S_FMT ioctl, driver sets default cropping rectangle that is the largest rectangle no larger than the image size and display windows size. The default cropping rectangle is centered in the image. All cropping dimensions are rounded down to even numbers. Changing the size of the cropping rectangle will in general also result in a new default display window. As stated above, an application must adjust the display window accordingly.
Following example shows how to change crop size.
struct v4l2_crop crop; crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; crop.c.left = 0; crop.c.top = 0; crop.c.width = 320; crop.c.height = 320; ret = ioctl(fd, VIDIOC_S_CROP, &crop); if (ret < 0) { perror("VIDIOC_S_CROP\n"); close(fd); exit(0); } /* Image cropping rectangle is now changed */
Video pipe line contains scaling unit which is used when transferring pixels from the system memory to the LCD panel or the TV set. The scaling unit consists of two scaling blocks: The vertical scaling block followed by the horizontal scaling block. The two scaling units are independent: Neither of them, only one, or both can be used simultaneously.
As scaling unit is on video pipeline, scaling is only supported in V4L2 driver. Scaling is not explicitly exposed at the API level. Instead, the horizontal and vertical scaling factors are based on the display window and the image cropping rectangle. The horizontal scaling factor is computed by dividing the width of the display window by the width of the cropping rectangle. Similarly, the vertical scaling factor is computed by dividing the height of the display window by the height of the cropping rectangle.
Down-scaling is limited upto factor 0.5 and the up-scaling factor to 8 in the software, while hardware supports from 0.25x to 8x both horizontally and vertically . The display Driver makes sure the limits are never exceeded.
The code snippet below illustrates how to scale image by factor of 2.
struct v4l2_format fmt; struct v4l2_crop crop; /* Changing display window size to 200x200 */ fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; fmt.fmt.win.w.left = 0; fmt.fmt.win.w.top = 0; fmt.fmt.win.w.width = 200; fmt.fmt.win.w.height = 200; ret = ioctl(fd, VIDIOC_S_FMT, &fmt); if (ret < 0) { perror("VIDIOC_S_FMT\n"); close(fd); exit(0); } /* Changing crop window size to 400x400 */ crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; crop.c.left = 0; crop.c.top = 0; crop.c.width = 400; crop.c.height = 400; ret = ioctl(fd, VIDIOC_S_CROP, &crop); if (ret < 0) { perror("VIDIOC_S_CROP\n"); close(fd); exit(0); } /* Image should be now scaled by factor 2 */
The graphics pipeline supports the color look up table. The CLUT mode uses the encoded pixel values from the input image as pointers to index the 24-bit-wide CLUT value: 1-BPP pixels address 2 entries, 2-BPP pixels address 4 entries, 4-BPP pixels address 16 entries, and 8-BPP pixels address 256 entries.
Driver supports 1, 2, 4 and 8 bits per pixel image format using color lookup table. FBIOPUTCMAP and FBIOGETCMAP can be used to set and get the color map table. When CLUT is set, the driver makes the hardware to reload the CLUT.
Following example shows how to change CLUT.
struct fb_cmap cmap; unsigned short r[4]={0xFF,0x00, 0x00, 0xFF}; unsigned short g[4]={0x00, 0xFF, 0x00, 0xFF}; unsigned short b[4]={0x00, 0x00, 0xFF, 0x00}; cmap.len = 4; cmap.red = r; cmap.green = g; cmap.blue = b; if (ioctl(fd, FBIOPUTCMAP, &cmap)) { perror("FBIOPUTCMAP\n"); close(fd); exit(3); }
V4L2 driver supports the streaming of the buffer. To do streaming minimum of three buffers should be requested by the application by using VIDIOC_REQBUFS ioctl. Once driver allocates the requested buffers application should call VIDIOC_QUERYBUF and mmap to get the physical address of the buffers and map the kernel memory to user space as explained earlier. Following are the steps to enable streaming.
Following example shows how to do streaming with V4l2 driver
open ()
To open a framebuffer device
close ()
To close a framebuffer device
ioctl ()
To send ioctl commands to the framebuffer driver.
mmap ()
To obtain the framebuffer region as mmap'ed area in user space.
FBIOGET_VSCREENINFO, FBIOPUT_VSCREENINFO
These I/O controls are used to query and set the so-called variable
screen info. This allows an application to query or change the display
mode, including the color depth, resolution, timing etc. These I/O
controls accept a pointer to a struct fb_var_screeninfo structure. The
video mode data supplied in the fb_var_screeninfo struct is translated
to values loaded into the display controller registers.
FBIOGET_FSCREENINFO
This I/O control can be used by applications to get the fixed properties
of the display, e.g. the start address of the framebuffer memory. This
I/O control accepts a pointer to a struct fb_fix_screeninfo.
FBIOGETCMAP, FBIOPUTCMAP
These I/O controls are used to get and set the color-map for the
framebuffer. These I/O controls accept a pointer to a struct fb_cmap
structure.
FBIO_BLANK
This I/O control is used to blank or unblank the framebuffer console.
OMAPFB_WAITFORVSYNC
This ioctl can be used to put an application to sleep until next vertical
sync interval of the display.
OMAPFB_GET_VRAM_INFO
Ioctl returns the configured/allocated vram information.
OMAPFB_QUERY_MEM
Returns the size and type of the frame buffer.
Data Structure:
Usage:
struct omapfb_mem_info mi; if (ioctl(fb, OMAPFB_QUERY_MEM, &mi)) { perror("Error: OMAPFB_QUERY_MEM.\n"); exit(1); } printf("size - %d\n", mi.size); printf("type - %d\n", mi.type);
OMAPFB_SETUP_MEM
Allows user to setup the frame buffer memory, like size and type.
Data Structure:
#define OMAPFB_MEMTYPE_SDRAM 0 #define OMAPFB_MEMTYPE_SRAM 1 #define OMAPFB_MEMTYPE_MAX 1 struct omapfb_mem_info { __u32 size; __u8 type; __u8 reserved[3]; };Usage:
struct omapfb_mem_info mi; mi.size =
OMAPFB_QUERY_PLANE
Query the plane (gfx) and returns the omapfb_plane_info information -
Data Structure:
struct omapfb_plane_info { __u32 pos_x; __u32 pos_y; __u8 enabled; __u8 channel_out; __u8 mirror; __u8 reserved1; __u32 out_width; __u32 out_height; __u32 reserved2[12]; };Usage:
struct omapfb_plane_info pi; if (ioctl(fb, OMAPFB_QUERY_PLANE, &pi)) { perror("Error: OMAPFB_QUERY_PLANE.\n"); exit(1); }
OMAPFB_SETUP_PLANE
TBD.
fb_var_screeninfo
This structure is used to query and set the so-called variable screen
information. This allows an application to query or change the display
mode, including the color depth, resolution, timing etc.
fb_fix_screeninfo
This structure is used by applications to get the fixed properties of
the display, e.g. the start address of the framebuffer memory,
framebuffer length etc.
fb_cmap
This structure is used to get/set the color-map for the framebuffer.
open()
To open a video device
close()
To close a video device
ioctl()
To send ioctl commands to the display driver.
mmap()
To memory map a driver allocated buffer to user space
This section describes the standard V4L2 IOCTLs supported by the Display Driver.
NOTE: Standard IOCTLs that are not listed here are not supported.
The Display Driver handles the unsupported ones by returning
EINVALerror code.
VIDIOC_QUERYCAP
This is used to query the driver's capability. The video driver fills a
v4l2_capability struct indicating the driver is capable of output and
streaming.
VIDIOC_ENUM_FMT
This is used to enumerate the image formats that are supported by the driver. The driver fills a v4l2_fmtdesc struct.
VIDIOC_G_FMT
This is used to get the current image format or display window depending
on the buffer type. The driver fills the information to a v4l2_format struct.
VIDIOC_TRY_FMT
This is used to validate a new image format or a new display window
depending on the buffer type. The driver may change the passed values if
they are not supported. Application should check what is granted.
VIDIOC_S_FMT
This is used to set a new image format or a new display window depending
on the buffer type. The driver may change the passed values if they are
not supported. Application should check what is granted if VIDIOC_TRY_FMT is not used first.
VIDIOC_CROPCAP
This is used to get the default cropping rectangle based on the current
image size and the current display panel size. The driver fills a v4l2_cropcap struct.
VIDIOC_G_CROP
This is used to get the current cropping rectangle. The driver fills a v4l2_crop struct.
VIDIOC_S_CROP
This is used to set a new cropping rectangle. The driver fills a v4l2_crop struct. Application should check what is granted.
VIDIOC_REQBUFS
This is used to request a number of buffers that can later be memory mapped. The driver fills a v4l2_request buffers struct. Application should check how many buffers are granted.
VIDIOC_QUERYBUF
This is used to get a buffer's information so mmap can be called for that buffer. The driver fills a v4l2_buffer struct.
VIDIOC_QBUF
This is used to queue a buffer by passing a v4l2_buffer struct associated to that buffer.
VIDIOC_DQBUF
This is used to dequeue a buffer by passing a v4l2_buffer struct associated to that buffer.
VIDIOC_STREAMON
This is used to turn on streaming. After that, any VIDIOC_QBUF results in an image being rendered.
VIDIOC_S_CTRL, VIDIOC_G_CTRL, VIDIOC_QUERYCTRL
These ioctls are used to set/get and query various V4L2 controls like
rotation, mirror and background color. Currently only rotation is
supported.
VIDIOC_STREAMOFF
This is used to turn off streaming.
User can control all dynamic configuration of DSS core and Fbdev functionality thorugh SYSFS interface.
Frame-buffer Driver sysfs attributesFollowing attributes are available for user control -
# # ls -1 /sys/class/graphics/fb0/ bits_per_pixel blank console cursor dev device mirror mode modes name overlays overlays_rotate pan phys_addr power rotate rotate_type size state stride subsystem uevent virt_addr virtual_size #
Acronym | Definition |
---|---|
bits_per_pixel | Allows user to control bits per pixel configuration, currently the supported values are 16, 24 and 32. # echo 16/24/32 > /sys/class/graphics/fb0/ bits_per_pixel |
blank | Allows user to control lcd display blanking configuration independently. # echo 0/4 > /sys/class/graphics/fb0/blank Values only 0(FB_BLANK_UNBLANK) and 4(FB_BLANK_POWERDOWN) is supported |
rotate | Allows user to control rotation through this entry, # echo 0/1/2/3 > /sys/class/graphics/fb0/rotate 0 - 0 degree, 1 - 90 degree, 2 - 180 degree and 3 - 270 degree respectively. |
rotate_type | Allows user to control rotation type through this entry, # echo 0/1 > /sys/class/graphics/fb0/rotate_type 0 - DMA based rotation, 1 - VRFB based rotation. Currently only VRFB based rotation is supported. |
virtual_size | Allows user to configure xres_virtual and yres_virtual parameters of frame-buffer, # cat /sys/class/graphics/fb0/virtual_size 480,640 |
virt_addr | Readonly entry, displays virtual address of the frame-buffer memory. |
phys_addr | Readonly entry, displays physical address of the frame-buffer memory. |
DSS library provides/exports following attributes, which explained in detail below -
# # ls -1 /sys/devices/platform/omapdss/ bus display0 display1 display2 driver manager0 manager1 microamps_requested_vdda_dac modalias overlay0 overlay1 overlay2 power subsystem uevent #
In all total 3 output displays are supported on EVM,
# # ls -1 /sys/devices/platform/omapdss/display0/ bus driver enabled microamps_requested_vdvi mirror name power rotate subsystem tear_elim timings uevent update_mode wss #Acronym | Definition |
---|---|
enabled | User can enable/disable the display through this entry |
timings | Displays the timing configuration for specific display panel |
name | Shows name of the display panel/output |
In all total 2 managers are supported on EVM,
# # ls -1 /sys/devices/platform/omapdss/manager0/ alpha_blending_enabled default_color display name trans_key_enabled trans_key_type trans_key_value #Acronym | Definition |
---|---|
alpha_blending_enabled | User can enable/disable Alpha-blending through this entry. |
display | Allows user to control the output display, user can set the output to any of the display |
trans_key_enabled | User can enable/disable Transparency key keying through this entry |
trans_key_type | User can control the Transparency key type here. |
trans_key_value | User can configure Transparency color keying value through this entry. |
In all total 3 Overlays/Planes/Pipelines are supported on EVM,
# # ls -1 /sys/devices/platform/omapdss/overlay0/ enabled global_alpha input_size manager name output_size position screen_width #Acronym | Definition |
---|---|
enabled | User can enable/disable overlay through this entry. |
global_alpha | User can configure global alpha value through this entry. |
manager | Allows control over manager <-> overlay interface, user can configure any overlay to any of the manager |
Please refer for examples of using sysfs interface to change display settings.
Miscellaneous ConfigurationsThe default setup/configuration is -
User can control/configure the various interfaces like, overlay <=> manager <=> display. This section demonstrate/explains the dynamic switching of output using above interfaces.
Follow the steps below to switch output from LCD to DVI interface:
NOTE: Similar steps must be followed for switching from DVI to LCD.
NOTE: Please note that the user can read the panel configuration
through sysfs entry
"/sys/devices/platform/omapdss/display
Follow below steps to switch output from LCD to TV interface -
NOTE: Similar steps must follow for other (Video 1 & 2) overlays.
Follow below steps to clone GFX overlay output to both LCD and TV -
To V4L2 video driver start the Linux Kernel Configuration tool.
$ make menuconfig ARCH=arm
The default TV out interface is S-Video. Other option available is Composite.
NOTE: On OMAP3EVM-1 (< Rev-E) SW1.6 is used to select between S-Video and Composite outputs. ON :- S-Video, OFF :- Composite
NOTE: Please note that by default DSI clock is enabled as a source clock for DSS/DISPC.
NOTE: If this value is set as 1, the graphics pipeline of the
DSS is controlled by the FBDEV interface and both video pipelines by the
V4L2 interface.
If this value is set as 2, the graphics pipeline and one video pipeline
is controlled by the FBDEV interface and one video pipeline by the V4L2
interface.
If this value is set as 3, all 3 pipelines are controlled by the FBDEV interface.
This chapter describes the application flow using the V4l2 and FBDEV drivers.
V4L2-Display Application Flow