Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Table of Contents
maxLevel1

Introduction

This page gives an overview of Xilinx Multi-Scaler driver, which is available as part of the Xilinx Linux distribution.

The driver is part of the V4L2 Memory to Memory framework.

The Multi-Scaler driver generates up to eight scaled output images from a single or multiple (up to eight) external video and/or graphics sources. Video scaling is the process of converting an input color image of dimensions Xin pixels by Yin lines to an output color image of dimensions Xout pixels by Yout lines. This IP also capable of doing color space conversion. Multi-Scaler IP reads the input images from the memory addresses and writes the scaled output images to the destination memory addresses.

The Multi-scaler works in a sequential way, i.e. the input of the first channel scaled first and then the 2nd input gets scaled and so no up to the maximum channels configured in HwReg_num_outs. When all channels (configured) get scaled, IP generates the interrupt and ready for next processing.

Multi-Scaler converts and scales video frames between a great variety of video formats. For more supported formats please visit IP Product guide.

Xilinx-multiscaler creates a device node per channel and can be accessed from user-space via standard V4L2 system calls. Even though the devices created by driver looks like independent nodes but as multi-scaler IP has one scaler inside and works in sequential manner these nodes/devices are not independent. For more details see limitation section. 

HW IP features

  • Memory mapped AXI4 Interface
  • Supports maximum 8 outputs
  • Supports spatial resolutions from 64 × 64 up to 7680 × 4320
  • Supports one, two, or four pixel-width
  • Supports RGB, YUV 444, YUV 422, YUV 420
  • Supports 8-bit and 10-bit per color component on memory interface
  • Supports semi-planar memory formats next to packed memory formats
  • Dynamically configurable source and destination buffer addresses
  • Supports 6, 8, 10, and 12 taps in both H and V domains
  • Supports 64 phases
  • Supports 8K 30 fps depending on the device family

Missing Features / Known Issues / Limitations in Driver

  • Tested 64 × 64 up to 1920 × 1080.
  • 10-bit per color component is not tested.
  • As hardware processes all channels in sequential order, the driver has limitation to add only the next immediate channel. 

Example: Channels 0,1,2,3 are streaming, then the user can stream on immediate next channel 4.

...


Table of Contents
maxLevel1

Introduction

This page gives an overview of Xilinx Multi-Scaler driver, which is available as part of the Xilinx Linux distribution.

The driver is part of the V4L2 Memory to Memory framework.

The Multi-Scaler driver generates up to eight scaled output images from a single or multiple (up to eight) external video and/or graphics sources. Video scaling is the process of converting an input color image of dimensions Xin pixels by Yin lines to an output color image of dimensions Xout pixels by Yout lines. This IP also capable of doing color space conversion. Multi-Scaler IP reads the input images from the memory addresses and writes the scaled output images to the destination memory addresses.

The Multi-scaler works in a sequential way, i.e. the input of the first channel scaled first and then the 2nd input gets scaled and so no up to the maximum channels configured in HwReg_num_outs. When all channels (configured) get scaled, IP generates the interrupt and ready for next processing.

Multi-Scaler converts and scales video frames between a great variety of video formats. For more supported formats please visit IP Product guide.

Xilinx-multiscaler creates a device node per channel and can be accessed from user-space via standard V4L2 system calls. Even though the devices created by driver looks like independent nodes but as multi-scaler IP has one scaler inside and works in sequential manner these nodes/devices are not independent. For more details see limitation section. 

HW IP features

  • Memory mapped AXI4 Interface
  • Supports maximum 8 outputs
  • Supports spatial resolutions from 64 × 64 up to 7680 × 4320
  • Supports one, two, or four pixel-width
  • Supports RGB, YUV 444, YUV 422, YUV 420
  • Supports 8-bit and 10-bit per color component on memory interface
  • Supports semi-planar memory formats next to packed memory formats
  • Dynamically configurable source and destination buffer addresses
  • Supports 6, 8, 10, and 12 taps in both H and V domains
  • Supports 64 phases
  • Supports 8K 30 fps depending on the device family

Missing Features / Known Issues / Limitations in Driver

  • Tested 64 × 64 up to 1920 × 1080.
  • 10-bit per color component is not tested.
  • As hardware processes all channels in sequential order, the driver has limitation to add only the next immediate channel. 

Example: Channels 0,1,2,3 are streaming, then the user can stream on immediate next channel 4.

If user adds stream for channel 6 when channels 0,1,2,3 are running, then driver does not start 6th channel and does not return any error.

...

  • The driver is tested with YUY2, NV16, NV12, RGB, GRAY8, UYVY and BGR Gstreamer formats only.  
  • Please check section below on Stride and height Height align issue. Please check here


Kernel Configuration

The following config options should be enabled in order to build Xilinx Multi-Scaler driver

CONFIG_VIDEO_XILINX

CONFIG_VIDEO_DEV

...

CONFIG_VIDEO_XILINX_MULTISCALER


The driver is available To check if the options are enabled run the following:

Code Block
themeMidnight
petalinux-config -c kernel

When the GUI opens, you can use '/' to search for each config.

Image Added


The driver is available at,
https://github.com/Xilinx/linux-xlnx/blob/master/drivers/media/platform/xilinx/xilinx-multi-scaler.c

Device Tree Binding

The device tree node will be automatically generated, if the core is configured in the HW design, using the Device Tree BSP.

Steps to generate device-tree is documented here,
http://www.wiki.xilinx.com/Build+Device+Tree+Blob

And a sample binding is shown below and the description of DT property is documented here


Code Block
themeMidnight
v_multi_scaler_1: v_multi_scaler@a0000000 {
          clock-names = "ap_clk";
          clocks = <&misc_clk_0>;
          compatible = "xlnx,v-multi-scaler-1.0", "xlnx,v-multi-scaler-v1.0";
          interrupt-names = "interrupt";
          interrupt-parent = <&gic>;
          interrupts = <0 89 4>;
          reg = <0x0 0xa0000000 0x0 0x20000>;
          reset-gpios = <&gpio 78 1>;
          xlnx,dma-addr-width = <0x20>;
          xlnx,max-chan = <8>;
          xlnx,max-height = <2160>;
          xlnx,max-width = <3840>;
          xlnx,num-taps = <12>;
          xlnx,pixels-per-clock = /bits/ 8 <2>;
          xlnx,vid-formats = "xrgb8888", "bgr888", "xbgr8888", "xbgr2101010", "uyvy", "y8", "y10", "vuy888", "xvuy8888", "yuvx2101010", "yuyv", "nv12", "nv16", "xv20", "xv15";
};                                

...

Multi-Scaler is tested with the generic gstreamer v4l2videotransform plugin which maps device node to v4l2videoNconvert elements. Where N is the number of device node. 

Below is the steps to get the proper gstreamer element for the Multi-Scaler.   

Find the Multi-Scaler devices

Gstreamer device name for Multi-Scaler is xm2msc (Xilinx memory to  memory video multi-scaler).

In below example the IP is configured for 8 channels. 

Code Block
languagebash
themeMidnight
# gst-inspect-1.0 -a | grep xm2msc
v4l2video0convert: String. Default: "xm2msc"
v4l2video1convert: String. Default: "xm2msc"
v4l2video2convert: String. Default: "xm2msc"
v4l2video3convert: String. Default: "xm2msc"
v4l2video4convert: String. Default: "xm2msc"
v4l2video5convert: String. Default: "xm2msc"
v4l2video6convert: String. Default: "xm2msc"
v4l2video7convert: String. Default: "xm2msc"

N-N Use Case:

...

N-N Use Case:

Multi-Scaler is tested with the generic gstreamer v4l2videotransform elements which is part of gst-plugins-good. So no extra library required to run N:N use case.

In below image, it is represented a basic test scenario where multiple v4l2videoNconvert elements are launched as different process opening different node of Multi-Scale. The input for the v4l2videoNconvert is frames of different format and different resolutions and the output is given to filesink which stores the scaled and converted frames in a file.    


Image Added


Commands to test

Below command is an example using Gstreamer. You can open Multiple channels by running v4l2videoNconvert process in parallel.
**Note Gstreamer plugins may change, please refer to Gstreamer documentation for the latest information on using Gstreamer plugins

Code Block
languagebash
themeMidnight
gst-launch-1.0 videotestsrc num-buffers=10 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, width=640, height=480, format=RGB ! filesink location=tmp0.rgb


1 to N Use Case:

Multi-Scaler's 1 to N use case  is tested with the xlnxabrscaler plugin. 

In below image, it is represented a basic test scenario where multiple v4l2videoNconvert elements are launched as different process opening single input given to xlnxabrscaler elements which opens different node of Multi-ScaleScaler. The input for the v4l2videoNconvert is frames of different format and different resolutions and the output is given to filesink which stores the scaled and converted frames in a filefiles.       

Image RemovedImage Added


Commands to test

Below command is used to test Multi-Scaler with Gstreamer. You can open Multiple channels by running v4l2videoNconvert process in parallel.

Code Block
languagebash
themeMidnight
gst-launch-1.0 videotestsrc num-buffers=10 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video0convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, width=640, height=480, format=RGB ! filesink location=tmp0.rgb

1 to N Use Case:

Multi-Scaler's 1 to N use case  is tested with the xlnxabrscaler plugin. 

In below image, it is represented a basic test scenario where single input given to xlnxabrscaler elements which opens different node of Multi-Scaler. The output is given to filesink which stores the scaled and converted frames in files.    

Image Removed

Commands to test

For 1 to N Use Case, run commands mention in debugging section.

Mapping table between Gstreamer string and Xilinx Multi-Scaler Supported Formats

Replace the format string in above command with below Gstreamer strings, to test different supported formats 

...

Multi-Scaler

Video Format

Prefix with XILINX_M2MSC_FMT_

...

Device-tree

strings

...

V4L2

Format

Prefix with

V4L2_PIX_FMT_

...

Gstreamer

String

...

YUV Player

Format

...

RGBX8

...

Debugging

Enable Dynamic Debugging in kernel.

Run below commands to enable logs on console

Code Block
languagebash
themeMidnight
echo 1 > /sys/module/v4l2_mem2mem/parameters/debug
echo 8 > /sys/module/videobuf2_core/parameters/debug
echo 8 > /sys/module/videobuf2_v4l2/parameters/debug
echo 8 > /proc/sys/kernel/printk

Use Cases

...

For 1 to N Use Case, run commands mention in debugging section.

Mapping table between Gstreamer string and Xilinx Multi-Scaler Supported Formats

Replace the format string in above command with below Gstreamer strings, to test different supported formats 


ID

Multi-Scaler

Video Format

Prefix with XILINX_M2MSC_FMT_

Device-tree

strings

V4L2

Format

Prefix with

V4L2_PIX_FMT_

Gstreamer

String

YUV Player

Format

10

RGBX8

xbgr8888BGRX32

11YUVX8xvuy8888XVUY32

12YUYV8yuyvYUYVYUY2YUYV
15RGBX10xbgr2101010XBGR30

16YUVX10yuvx2101010XVUY10

18Y_UV8nv16NV16MNV16NV16
19Y_UV8_420nv12NV12MNV12NV12
20RGB8bgr888RGB24RGBRGB24
21YUV8vuy888VUY24

22Y_UV10xv20XV20M
XV20
23Y_UV10_420xv15XV15M
XV15
24Y8y8GREYGRAY8Y
25Y10y10Y10
Y10
27BGRX8xrgb8888XBGR32BGRxBGR32
28UYVY8uyvyUYVYUYVYUYVY
29BGR8rgb888BGR24BGRBGR24

Debugging

Enable Dynamic Debugging in kernel.

Run below commands to enable logs on console

Code Block
languagebash
themeMidnight
echo 1 > /sys/module/v4l2_mem2mem/parameters/debug
echo 8 > /sys/module/videobuf2_core/parameters/debug
echo 8 > /sys/module/videobuf2_v4l2/parameters/debug
echo 8 > /proc/sys/kernel/printk

Use Cases

1-1 Scaler

Code Block
languagebash
themeMidnight
gst-launch-1.0 videotestsrc num-buffers=10 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, width=640, height=480, format=RGB ! filesink location=640X480.rgb

N-N Scaler

Code Block
languagebash
themeMidnight
#!/bin/bash
gst-launch-1.0 videotestsrc num-buffers=103 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video0convertv4l2video1convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, width=640, height=480, format=RGB ! filesink location=640X480.rgb

N-N Scaler

Code Block
languagebash
themeMidnight
#!/bin/bashtmp1.rgb &

sleep 3

gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video1convertv4l2video2convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, width=640, height=480, format=RGB ! filesink location=tmp1tmp2.rgb &

sleep 3

gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video2convertv4l2video3convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, 
width=640, height=480, format=RGB ! filesink location=tmp2tmp3.rgb &

sleep 3

gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video3convertv4l2video4convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, 
width=640, height=480, format=RGB ! filesink location=tmp3tmp4.rgb &

sleep 3

gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video4convertv4l2video5convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, 
width=640, height=480, format=RGB ! filesink location=tmp4tmp5.rgb &

sleep 3

gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video5convertv4l2video6convert capture-io-mode=4 output-io-mode=4 ! video/x-raw,  width=640, height=480, format=RGB ! filesink location=tmp5tmp6.rgb &

sleep 3

gst-launch-1.0 videotestsrc num-buffers=3 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video6convertv4l2video7convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, 
width=640, height=480, format=RGB ! filesink location=tmp6tmp7.rgb &

sleep 3

gst-launch-1.0  videotestsrc num-buffers=310 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video7convertv4l2convert capture-io-mode=4 output-io-mode=4 ! video/x-raw,  width=640, height=480, format=RGB ! filesink location=tmp7tmp0.rgb &

sleep 3


1-N Scaler

Code Block
languagebash
themeMidnight
#Create input file for abrscaler
gst-launch-1.0 videotestsrc videotestsrc
num-buffers=10 ! video/x-raw, width=1280, height=720, format=RGB ! v4l2video0convert
v4l2convert capture-io-mode=4 output-io-mode=4 ! video/x-raw, 
width=6401920, height=4801080, format=RGB ! filesink 
location=tmp0.rgb

1-N Scaler

Code Block
languagebash
themeMidnight
#Create input file for abrscaler
testsrc_rgb_time_10frames.rgb


#Run ABR Test
gst-launch-1.0 videotestsrc filesrc location=testsrc_rgb_time_10frames.rgb num-buffers=10 blocksize=6220800 do-timestamp=true ! "video/x-raw, width=12801920, height=7201080, format=RGB ! 
v4l2video0convert capture-io, framerate=30/1, interlace-mode=4 output-io-mode=4 ! progressive, colorimetry=sRGB" ! xlnxabrscaler device="/dev/video0" name=sc \
sc.src_0 ! "video/x-raw,  width=19201600, height=1080900, format=RGB" ! queue ! filesink 
location=testsrc1600x900_rgb_time_10frames50frames.rgb \
sc.src_1 #Run ABR Test
gst-launch-1.0 filesrc location=testsrc_rgb_time_10frames.rgb num-buffers=10 blocksize=6220800 do-timestamp=true ! "video/x-raw, width=1280, height=720, format=RGB" ! queue ! filesink location=1280x720_rgb_50frames.rgb \
sc.src_2 ! "video/x-raw, width=1920800, height=1080600, format=RGB, framerate=30/1, interlace-mode=progressive, colorimetry=sRGB" ! xlnxabrscaler device="/dev/video0" name=sc " ! queue ! filesink location=800x600_rgb_50frames.rgb \
sc.src_03 ! "video/x-raw, width=1600832, height=900480, format=RGB" ! queue ! filesink location=1600x900832x480_rgb_50frames.rgb \
sc.src_14 ! "video/x-raw, width=1280640, height=720480, format=RGB" ! queue ! filesink location=1280x720640x480_rgb_50frames.rgb \
sc.src_25 ! "video/x-raw, width=800480, height=600320, format=RGB" ! queue ! filesink location=800x600480x320_rgb_50frames.rgb \
sc.src_36 ! "video/x-raw, width=832320, height=480240, format=RGB" ! queue ! filesink location=832x480320x240_rgb_50frames.rgb \
sc.src_47 ! "video/x-raw, width=640176, height=480144, format=RGB" ! queue ! filesink location=640x480176x144_rgb_50frames.rgb \
sc.src_5 ! "video/x-raw, width=480, height=320, format=RGB" ! queue ! filesink location=480x320_rgb_50frames.rgb \
sc.src_6 ! "video/x-raw, width=320, height=240, format=RGB" ! queue ! filesink location=320x240_rgb_50frames.rgb \
sc.src_7 ! "video/x-raw, width=176, height=144, format=RGB" ! queue ! filesink location=176x144_rgb_50frames.rgb

Stride and Height Alignment

Multiple IPs required aligned stride and height to work properly, but till now there is no way to share this information with Multi-Scaler plugin and driver.

Multi-Scaler driver has implemented a mechanism to  provide stride and height align values per channel for both output and capture pads, at run-time. This is temporary fix. Once the stride and height alignment support added to plugin, this change will be reverted.

...


Stride and Height Alignment

Multiple IPs required aligned stride and height to work properly, but till now there is no way to share this information with Multi-Scaler plugin and driver.

Multi-Scaler driver has implemented a mechanism to  provide stride and height align values per channel for both output and capture pads, at run-time. This is temporary fix. Once the stride and height alignment support added to plugin, this change will be reverted.


Example 1:

Filesrc -> Decoder -> Multi-Scaler -> filesink


As decoder require 256 align byteperline and 64 align lines  per frame, so the setting before running gstreamer pipe are :

Code Block
languagebash
themeMidnight
echo 256 > /sys/modules/xilinx-multi-scaler/parameters/output_stride_align
echo 64 > /sys/modules/xilinx-multi-scaler/parameters/output_height_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/capture_stride_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/capture_height_align


And then run :

Code Block
languagebash
themeMidnight
gst-launch-1.0  filesrc location=./1080p_h264.mp4 ! qtdemux ! h264parse ! omxh264dec ! v4l2video1convert capture-io-mode=4 output-io-mode=5 ! video/x-raw, width=1280, height=720, format=BGR ! filesink


Example 2:

Filesrc -> Decoder -> Multi-Scaler -> filesink

As decoder require 256 align byteperline and 64 align lines  per frame, so the setting before running gstreamer pipe are :

...

DP kmssink

Code Block
languagebash
themeMidnight
echo 256 > /sys/modules/xilinx-multi-scaler/parameters/output_stride_align
echo 64 > /sys/modules/xilinx-multi-scaler/parameters/output_height_align
echo 1256 > /sys/modules/xilinx-multi-scaler/parameters/capture_stride_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/capture_height_align


And then the run:

Code Block
languagebash
themeMidnight
gst-launch-1.0  filesrc location=./1080p_h264.mp4 ! qtdemux ! h264parse ! omxh264dec ! v4l2video1convert capture-io-mode=4 output-io-mode=5 ! video/x-raw, width=1280, height=720, format=BGR ! queue max-size-bytes=0 ! filesink
Example 2:

...

 kmssink bus-id="fd4a0000.zynqmp-display" fullscreen-overlay=1 sync=false


Example 3:

videotestsrc  -> Multi-Scaler -> DP kmssinkfilesink

Code Block
languagebash
themeMidnight
echo 2561 > /sys/modules/xilinx-multi-scaler/parameters/output_stride_align
echo 641 > /sys/modules/xilinx-multi-scaler/parameters/output_height_align
echo 2561 > /sys/modules/xilinx-multi-scaler/parameters/capture_stride_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/capture_height_align

...


Example 4:

videotestsrc  -> Multi-Scaler0 -> filesink

Filesrc -> Decoder -> Multi-Scaler1 -> DP kmssink

Code Block
languagebash
themeMidnight
gst-launch-1.0  filesrc location=./1080p_h264.mp4 ! qtdemux ! h264parse ! omxh264dec ! v4l2video1convert capture-io-mode=4 output-io-mode=5 ! video/x-raw, width=1280, height=720, format=BGR ! queue max-size-bytes=0 ! kmssink bus-id="fd4a0000.zynqmp-display" fullscreen-overlay=1 sync=false
Example 3:

videotestsrc  -> Multi-Scaler -> filesink

Code Block
languagebash
themeMidnight
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/output_stride_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/output_height_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/capture_stride_align
echo 1 > /sys/modules/xilinx-multi-scaler/parameters/capture_height_align
Example 4:

videotestsrc  -> Multi-Scaler0 -> filesink

Filesrc -> Decoder -> Multi-Scaler1 -> DP kmssink

Code Block
languagebash
themeMidnight
echo 1,256 > /sys/modules/xilinx-multi-scaler/parameters/output_stride_align
echo 1,64 > /sys/modules/xilinx-multi-scaler/parameters/output_height_align
echo 1,256 > /sys/modules/xilinx-multi-scaler/parameters/capture_stride_align
echo 1,1 > /sys/modules/xilinx-multi-scaler/parameters/capture_height_align

Notes

  1. Gstreamer plugins enumerate all the channel/video devices for each of gst command. So, there might be chances that starting all channels with different gst process at same time do not allow the actual process to open the device and the process dedicated for the device does not start. For example, if all channels are opened immediately in a script, all the gst process open and close all the devices for all the channels and if somehow gst process 1 opens channel 2 and at same time if process 2 open channel 2, the 2nd process do not get the channel 2 and returns, despite the process 1 do not require the channel 2 and close the channel 2 afterwards.  Adding sleep after every enumeration is required to make all applications work properly.   

...

echo 1,256 > /sys/modules/xilinx-multi-scaler/parameters/output_stride_align
echo 1,64 > /sys/modules/xilinx-multi-scaler/parameters/output_height_align
echo 1,256 > /sys/modules/xilinx-multi-scaler/parameters/capture_stride_align
echo 1,1 > /sys/modules/xilinx-multi-scaler/parameters/capture_height_align

Notes

  1. Gstreamer plugins enumerate all the channel/video devices for each of gst command. So, there might be chances that starting all channels with different gst process at same time do not allow the actual process to open the device and the process dedicated for the device does not start. For example, if all channels are opened immediately in a script, all the gst process open and close all the devices for all the channels and if somehow gst process 1 opens channel 2 and at same time if process 2 open channel 2, the 2nd process do not get the channel 2 and returns, despite the process 1 do not require the channel 2 and close the channel 2 afterwards.  Adding sleep after every enumeration is required to make all applications work properly.   

  2. The gstreamer plugins mentioned on this page are developed for Proof of Concept and testing some limited featured only. This plugins are not tested for all possible resolutions, video formats etc. Customers may need to develop their own plugins by using these plugins as example.

...

2018.3

  • Summary:
    • Add first version of driver.
  • Commits:
    • 484cdb2 platform: xilinx: Add mem to mem Multi-Scaler driver (XM2MSC)


Related Links