Burn Mac Address(Rockchip Linux)

|

Unlike rockchip android, we don’t limit you how to get mac address. You can write/read it in any places.

Usually, it could be stored in reserved1.
http://opensource.rock-chips.com/wiki_Partitions

Bellow is how to burn mac address to reserved1 and read it.

First, enter maskrom and issue fllowing command to burn mac adress.

printf '\xde\xad\xbe\xef\xef\xee' > mac.bin
build/flash_tool.sh -p reserved1 -c rk3288 -i mac.bin

Then, add ethadder-set fucntion to u-boot board file, it will read mac address from reserved1.

#include <mmc.h>

int rk_board_late_init(void)
{
  u8 ethaddr[1024];

  // 1 for sd-card
  struct mmc *mmc = find_mmc_device(0);
  struct blk_desc *desc = mmc_get_blk_desc(mmc);
  unsigned long blk_start = 8064;
  unsigned long blk_cnt = 1;

  int d = blk_dread(desc, blk_start, blk_cnt, ethaddr);

  eth_setenv_enetaddr("ethaddr", ethaddr);

  return 0;
}

Show Boot Logo(Rockchip Linux)

|

Unlik rockchip android, we don’t have a complete method for boot logo on linux.

It means you can only show logo by generic way, and there are three parts.

U-boot

First, you need enable video driver in u-boot and make it show console in screen. and then, apply below patches.(Don’t forget to remove console in screen)

https://github.com/wzyy2/Scripts/blob/master/tmp/U-Boot-v1-1-2-board-rockchip-common-Add-bmp-logo-support.patch
https://github.com/wzyy2/Scripts/blob/master/tmp/U-Boot-v1-2-2-rockchip-include-Enable-logo-display-for-evb-rk3399.patch

Since rockchip rom code have litmit the uboot size to 1Mb, so you can’t display with big size bmp. If you want to display big size bmp, you might need use gzipped bmp.

https://github.com/rockchip-linux/u-boot/blob/release/cmd/bmp.c#L40

Kernel

http://blog.csdn.net/wang_zheng_kai/article/details/41847687

set logos_freed to false
http://elixir.free-electrons.com/linux/latest/source/drivers/video/logo/logo.c#L32

System

You can use ‘plymouth’ to show logo before desktop launched.

If you are using debian, there are some bug need fix.

  1. Change ExecStartPost in /lib/systemd/system/plymouth-start.service to ExecStartPost=-/usr/bin/udevadm settle –timeout=30 –exit-if-exists=/sys/class/drm/card0/dev ; /usr/bin/udevadm settle –timeout=30 –exit-if-exists=/sys/class/graphics/fb0/dev ;

  2. Add plymouth-quit.service to After in /lib/systemd/system/lightdm.service

Swap video layer(Rockchip Linux)

|

By default, Video layer is on top of GUI layer, which means you can’t put GUI items on top of video.

To allow video work with GUI, there are two ways.

  1. Use Wayland dma-buf api
    If there is something cover the video layer, wayland compositor will use GPU to composite. The advantage is that it’s a standard and the api is clean. The disadvantage is that wayland have many compatibility problem(e.g QT) and the using of GPU will reduce performance.

  2. Change video layer to the bottom
    In this way, we could make the place we want to show video transparent, so the bottom layer would show up. The advantage is that it has the best performance. The disadvantage is that it’s kind of hacky.

In below, i will introduce how to enable the second way on different display server.

First, you need apply the below kernel patches.

The Kernel Patch for swap layer:
kernel patch 1

The Kernel Patch for dsiable double vsync with drm api:
kernel patch 2

QT eglfs

“we could make the place we want to show video transparent”
To make qt background transparent, we need this patches to change the default color format to ARGB.
qt patch 1

Then set the alpha value of the window you want to show video to zero, VOP will skip them when do alpha blending.

display

Before starting application, please set below env value to force qt use kmssink to show video on bottom.

export QT_GSTREAMER_WINDOW_VIDEOSINK=kmssink

qt class

Please use qmlvideo

X11/Wayland

On X11 and Wayland backend, we can’t make GUI layer transparent by alpha becuase of the exists of desktop background. If you set window backgournd color to transparent, it would show background rather than video lyaer, so we can only use color key.

To set color key, it need some changes in kernel driver.

kernel patch 5

kernel patch 6

it will make black color a transparency color key.

display

Before starting application, please set below env value to force qt use rkximagesink to show video on bottom.

export QT_GSTREAMER_WINDOW_VIDEOSINK=rkximagesink

qt class

qmlvideo, qtvideowidget

Others

Somtimes we need a 1080P UI with the video layer in 4K resolution for smooth, then we might need this patch.

The Kernel Patch for 1080P UI + 4K video layer :
kernel patch 3

The Qt patch for 1080 UI:
kernel patch 4

Multimedia User Guide(Rockchip Linux)

|

Overall

这里主要记录一些常见问题, 主要帮助通过gstreamer来在rockchip平台上做multimedia的开发.

首先介绍rockchip平台上视频编解码大概的流程

 vpu_service  -->  mpp --> gstreamer/ffmpeg --> app
  • vpu_service: 驱动
  • mpp: rockchip平台的视频编解码中间件
  • gstreamer/ffmpeg: 对接app的组件

目前rockchip提供的完整solution是基于gstreamer的,使用gstreamer的好处就是可以比较方便的基于pipeline的方式完整播放器, 编码器这些应用。 对gstreamer不了解的话,也可以看看博客里关于gstreamer的文章。

直接用使用底层的api, 比如通过mpp完成解码,也可以。但复杂应用下会很麻烦,因为你需要直接接触很多底层的概念,我们支持也很麻烦。。。 当然如果只是简单的输入码流,输出画面, 是可以的。 不过对编码来说, 使用Mpp会更好点

Note

建议先了解清楚graphic,因为客户很多的问题,其实都是关于graphic,可以搜博客里的另一篇Graphic user guide。 这篇其实在讲的也都是graphic。

另外你要很好的理解这块内容,最好接触下下面的概念: v4l2,dmabuf,gstreamer,drm,opengles,gbm 这块的开发,其实都是很灵活的,如果你足够了解这些基础的东西,很容易利用已有的软件做各种组合,如果你不了解的话,能做的事情就不多了。 主要在rockchip linux平台上,主要的关键还是dmabuf,我们所有的graphic和media,都是基于dmabuf来达到zero-copy,和你过去接触的fbmmap的方式会有很大的不一样。

Gstreamer-1.0

Rockchip have provide two gstreamer plugin packages:

(Note: Please choose debian branch for debian, do not use master or release branch.

这里现在变动了,这样分branch太麻烦,容易有歧义,现在全部使用release tag做基础版本号,做code base,临时的features,bug-fix的东西全部弄成补丁。 现在debian额外的补丁都单独放在这个仓库这里,你可以根据deb的版本号下载相应release tag的代码,然后打上这个目录的补丁。这样会比较清楚。

gstreamer-rockchip includes the following video decoders and encoders:

Elements Type Comments
mppvideodec Video Decoder h264, h265, jpeg, vp8, vp9
mpph264enc Video Encoder h264

gstreamer-rockchip-extra includes the following plugins:
please refer to gstreamer-rockchip-extra README on github for more infos.

Elements Type Comments
rkximagesink Video Render (sink) kmssink + ximagesink
kmssink Video Render (sink) overlay display
rgaconvert Video Converter video colorspace,format,size conversion
rkcamsrc Device Sources rockchip isp camera source

Pipeline Example

如有变动,以这里为准:
https://github.com/rockchip-linux/rk-rootfs-build/tree/master/overlay-debug/usr/local

Decode with uridecodebin/playbin:

gst-launch-1.0 uridecodebin uri=file:///usr/local/test.mp4  ! kmssink

Decode (JPEG):

gst-launch-1.0 -v videotestsrc  ! "video/x-raw,width=1920,height=1080"  ! queue ! jpegenc ! queue ! jpegparse ! queue ! mppvideodec ! kmssink 

Encode:

gst-launch-1.0 videotestsrc num-buffers=512 ! video/x-raw,format=NV12,width=1920,height= 1080,framerate=30/1 \
    ! queue ! mpph264enc ! queue ! h264parse ! mpegtsmux ! filesink location=/home/linaro/2k.ts

RGA Convert:

gst-launch-1.0 -v videotestsrc ! "video/x-raw,format=BGRA, width=1920,height=1080,framerate=30/1" ! \
 rgaconvert hflip=false vflip=false rotation=90 input-crop=0x0x1920x1080 output-crop=0x0x640x360 \
 output-io-mode=dmabuf capture-io-mode=dmabuf ! \
 "video/x-raw,format=NV12, width=640,height=640x360,framerate=30/1" ! kmssink

Usage

使用的gstreamer的时候,如果你的应用只是要发起一个编码或者解码过程,那直接参考gst-lauch,集成到应用皆可。 其工作方式就类似于在应用里每次输入一次命令一样

Player

如果是要做player,最好是使用qtmultimedia来做,qtmultimedia可以直接调用到gstreamer。不过要注意qtmultiemdia还涉及到显示问题, 请参考下面的Playback with QT multiemdia is slow。 或者debian下/usr/local/bin/test_dec-qt.sh脚本。

自己管理Buffer

如果你的应用需要深度化的控制,自己管理buffer,而不是仅仅是在pipeline上开关, 那么可以参考博客里的另一篇gstreamer+opencv。

编译

在板子编译,交叉编译请用docker or 自己研究。

./autogen.sh --disable-rkximage --prefix=/usr/
make
make install

Mpp

直接使用mpp的例子请看代码下的test/mpi_dec_test

mpp和libdrm结合使用的代码。 注意里面用到了RGA,其实没有必要使用, drm可以自己缩放显示。 sdl的东西也不要管,用的还是fb那套,现在sdl2好像也支持gbm和drm了。

更多的文档可以看mpp下readme。

编译

在板子编译,交叉编译请用docker。

本地编译的话:

cmake -DRKPLATFORM=ON -DHAVE_DRM=ON && make

FFMpeg

FFMpeg从3.4以后就合并了mpp支持,直接从官网下打开mpp选项就行。
但是除非你比较了解,不然不推荐使用。不是xxx app使用的ffmpeg,我替换一个可以调的mpp的ffmpeg就可以让硬解码工作了,这里涉及到一个format和zero-copy的问题。另外FFMpeg不属于我们官方支持的东西,如果有bug,我们也只能支持到mpp部分。

FFMpeg配套的测试播放器可以用mpv, 不过要注意mpv也要用最新的才行。

编译

mpv和ffmpeg的代码和编译选项看yocto里的bitbake文件。

自己配置交叉编译比较麻烦,没研究过,建议使用yocto,选中这两个package就可以了。

More

都写在meta-rockchip下的readme里了,就不重复了
https://github.com/rockchip-linux/meta-rockchip/tree/master/recipes-multimedia/ffmpeg
https://github.com/rockchip-linux/meta-rockchip/tree/master/recipes-multimedia/mplayer

Device Driver

VPU

rk的私有驱动, 一般不需要有接触, 使用mpp既可.
驱动的位置在drvier/video/rockchip下面, 有很多vpu_service, mpp_service一类的, 主要对应不同版本的驱动, 不用细究, sdk给出来什么就用什么。

RGA

Source:
https://github.com/rockchip-linux/kernel/tree/release-4.4/drivers/media/platform/rockchip-rga

关键词: v4l2 m2m
Demo: https://github.com/wzyy2/rga-v4l2-demo

rga linux版本的驱动是根据v4l2 m2m的api写出来, 如果需要直接操作v4l2 device, 最好是参考驱动里的rga.c和v4l2 m2m的userspace demo, 目前我们并没有提供任何的wrap lib.

FAQ

I have use mppvideodec/mppvideoenc, however, it is slow.

检查下你是不是用了videoconvert, 如果使用了videoconvert, 如果用了, 那CPU会参与进去转颜色格式, 导致性能下降. 还有检查下你使用的sink, 想xvimagesink这种, 也是CPU直接拷贝的, 速度会很慢的. 可以的话尽量使用glimagesink, wayland(gpu)和kmssink, rkximagesink(drm).其中drm的性能最好.另外要注意使用gpu的话, 在x11上有稍微的性能缺陷.

背景知识: 图像和视频这种的Buffer, 一般为了DMA coherent, 都是uncached, 这种情况下, 如果CPU要操作, 那耗时是很大的.

Playback with QT multiemdia is slow

同上, 需要指定sink, 具体的方法根据display backend不同而不同, 见:
https://github.com/rockchip-linux/meta-rockchip-extra/tree/master/recipes-rk/autostart/autostart

How to build

Debian的使用docker, yocto的话本身就是编译工具. 或者你自己想法办法, 这个不是一个应该问的问题.

怎么playbin软解的时候用ximagesink, 硬解用rkx

可以修改caps https://github.com/wzyy2/gstreamer-rockchip/commit/6c4672a69fe4fc0aa08853825fb39014a26a8746

这样可以让autovideosink强制mppvideodec输出到rkximagesink上,而没mppvideodec就会走ximagesink:
https://github.com/wzyy2/gstreamer-rockchip/commit/6c4672a69fe4fc0aa08853825fb39014a26a8746

如何多路合成

多路合成可以通过rga设置好crop,把所有的影片copy到一个buffer上去,但是这个目前通过gstreamer还没有办法做。
一个可行的办法是用通过3.4以上版本ffmpeg调用mpp解码,或者gstreamer的appsink(参考gstreamer+opencv),得到含有drm_prime的frame,取出dmabuf,通过v4l2的ioctl操作rga,把取出合成到目标buffer上。目标buffer可以通过drm申请,显示也可以通过drm显示。

这个主要的问题是没有写demo,所以需要user根据前面的rga-v4l2-demo和网络上的资料。
也可以看上面那个“mpp和libdrm结合使用的代码”, 里面就使用到了RGA。

UI overlay 视频

这个其实挺hack的。。等以后看看有没有好的办法吧。

https://github.com/rockchip-linux/meta-rockchip-extra/tree/master/demo/meta-player-qt

http://blog.iotwrt.com/tips/2017/06/04/swap-layer/

kmssink/rkxiamgesink双屏输出

因为kmssink和rkxiamgesink都是基于屏幕做overlay输出的,所以如果要支持双屏,必须要指定对应的屏幕,不然只会在默认的屏幕上输出。 指定屏幕可以通过设置connector_id property来完成,connector在drm是什么意思,可以看graphic guide。

获得uncache的buffer

默认VPU和GPU出来都是UnCache的buffer,要处理的话最好是CPU拷贝下到正常的内存再处理。 用RGA拷到正常内存也可以,但是需要改动内核代码,暂时还没试过(V4L2是支持申请uncache的buffer的)。

但是走DRM的话(也就是我们mpp里用的),应该是没办法直接出cache的buffer的。

Bluetooth(Rockchip Linux)

|

Rockchip 蓝牙模块统一使用的HCI驱动,因此调试主要是电源相关的配置。

net/rkkill/rfkill-rk.c下面有一些rk写的rfkill代码,主要用来控制电源睡眠唤醒这些。 在移植到自己板子上的时候,主要是配下面这样的dts。

wireless-bluetooth {
  compatible = "bluetooth-platdata";
  uart_rts_gpios = <&gpio4 19 GPIO_ACTIVE_LOW>;
  pinctrl-names = "default", "rts_gpio";
  pinctrl-0 = <&uart0_rts>;
  pinctrl-1 = <&uart0_gpios>;
  BT,reset_gpio    = <&gpio4 29 GPIO_ACTIVE_HIGH>;
  BT,wake_gpio     = <&gpio4 26 GPIO_ACTIVE_HIGH>;
  BT,wake_host_irq = <&gpio4 31 GPIO_ACTIVE_HIGH>;
  status = "okay";
};

我也不知道linux下的程序,比如blueman,能不能和这个rkkill配合,一般都是先自己手动确认下

root@evb-rk3288:~# rfkill list                                                     
  0: bt_default: bluetooth                                                           
          Soft blocked: yes                                                          
          Hard blocked: no                                                           
  1: phy0: wlan                                                                      
          Soft blocked: no                                                           
          Hard blocked: no                                                           
  2: brcmfmac-wifi: wlan                                                             
          Soft blocked: no                                                           
          Hard blocked: no 
          
  root@evb-rk3288:~# rfkill unblock 0                                                
  [  599.915815] [BT_RFKILL]: ENABLE UART_RTS                                        
  [  600.025465] [BT_RFKILL]: DISABLE UART_RTS                                       
  [  600.029514] [BT_RFKILL]: bt turn on power

确认电源打开了,然后进行hci attach

rtk:

rtk_hciattach -n -s 115200 ttyS0 rtk_h5

brcm:

brcm_patchram_plus -d --enable_hci --no2bytes --use_baudrate_for_download --tosleep 20000 --baudrate 1500000 --patchram /etc/firmware/bcm4339a0.hcd /dev/ttyS0 &

brcm_patchram_plus版本:
https://github.com/rockchip-linux/meta-rockchip/tree/morty/recipes-bsp/brcm-patchram-plus

然后再 hciconfig, 可以看到bt起来

root@mq:~# hciconfig -a
hci0: Type: Primary Bus: UART

DEBUG

参考RK BT文档里的常见问题,一般是没上电阿,uart通信有问题,晶体问题

Function

BT 4.0

A2DP

choppy的话看下cpufreq, 是不是太低, sbc解码比较吃cpu

audio conf, 可以设置force sbc和mpeg https://android.googlesource.com/platform/external/bluetooth/bluez/+/android-4.1.1_r4/audio/audio.conf

BLE

Central

Peripheral

Known issue

要注意不要在CONFIG里打开HCI_SDIO, 发现有时候WIFI SDIO会被认成HCI SDIO,导致一系列出错。