v3s解h264,720p25帧的电影,只能。0.8左右的播放速度,正常否
离线
最简单的方法,看 CPU 占用,如果硬解的话,基本不占 CPU。另外还可以用 lsof 看进程是否打开了硬解相关的设备文件,比如全志驱动的 /dev/cedar_dev 和 /dev/ion,主线驱动的 /dev/video0 和 /dev/media0。
还有一点,如果放视频的话,除了硬解,还要"硬渲染"配合,因为全志硬解输出的是 NV21 格式,如果用 framebuffer 放的话,要从 YUV 转 RGB,即使使用 NEON 也慢的要命。全志驱动的 /dev/disp 或者主线驱动的 /dev/dri/card0 就是干这个的。
离线
明白,谢谢
离线
/dev/cedar_dev
/dev/ion
/dev/disp
均发现已有
使用哪个软件可以硬解压视频文件
mplayer 播放的时候CPU 还是占用100%
估计是NV21转BGRA的问题
离线
top显示每个线程的cpu占用率,如果线程没有名字,改源代码,给每个线程加个名字。
离线
全志的显示模块 DE 分多个通道,其中通道0和通道1为视频通道,可接受 YUV 和 RGB 格式,通道之间可以透明叠加。一个通道分多个层(一般4层),层之间可叠加。同一个通道只接受一种像素格式,默认情况下 /dev/fb0 配置在通道1的第0层上,那么放视频就要放在通道0上了。在放视频的时候可看一下当前的 DE 状态 /sys/class/disp/disp/attr/sys
比如我这个
# cat /sys/class/disp/disp/attr/sys
screen 0:
de_rate 297000000 hz, ref_fps:58
mgr0: 1024x600 fmt[rgb] cs[0x0] range[limit] unblank direct_show[false]
lcd output backlight( 50) fps:58.5 1024x 600
err:0 skip:1 irq:154729 vsync:0 vsync_skip:0
BUF enable ch[0] lyr[0] z[1] prem[N] a[globl 255] fmt[ 77] fb[1280, 736;1280, 736;1280, 736] crop[ 0, 0,1280, 720] frame[ 85, 0, 853, 480] addr[5b400000,5b4e6000, 0] flags[0x 0] trd[0,0]
BUF enable ch[1] lyr[0] z[0] prem[N] a[pixel 255] fmt[ 0] fb[1024, 600;1024, 600;1024, 600] crop[ 0, 600,1024, 600] frame[ 0, 0,1024, 600] addr[58100000, 0, 0] flags[0x 0] trd[0,0]
ch0 lry0 是 fmt77 格式,也就是NV21格式,就是我显示视频的层了。ch1 lyr0 是 fmt0 格式,是 ARGB 格式,就是/dev/fb0,是我显示UI的层。如果当前只有一个 fmt0 的层,那么铁定不是"硬渲染"的。
我不知道有没有现成的软件,我这个播放器是自己写的,但是是公司的项目,不好开源出来。
离线
哦对了,tina 里 libcedarx 下有 xplayerdemo,可以硬解和"硬渲染",可以尝试一下。
离线
非非非非常感谢
我研究一下相关知识点
非常非常感谢
离线
@benlypan
/dev/disp
能在主线 LINUX 5.2中开启否
使用的是这个版本
git clone -b zero-5.2.y --depth 1 https://github.com/Lichee-Pi/linux.git
参考
https://github.com/aodzip/cedar
https://github.com/aodzip/libcedarc
后
/dev/cedar_dev
/dev/ion
能出现
/dev/disp 无法实现
离线
/dev/disp 是全志的显示模块驱动的设备文件,主线中功能与之对应的是 drm,故主线中不会有 /dev/disp,除非将全志的显示驱动移植过来。尚不清除用全志的解码驱动与主线的 drm 能不能合作。
主线也有对应的解码驱动,叫 cedrus( https://linux-sunxi.org/Sunxi-Cedrus ),他能很好的与 drm 合作。只是 v3s 的还没合并到主线,这是开发中的代码 https://github.com/mcerveny/linux/commits/v3s_videocodec_v4 ,我没试过,但有计划去尝试。主线的解码接口叫 v4l2-request,可以参考这个工程如何调用解码以及如何调用 drm 进行渲染
https://github.com/bootlin/v4l2-request-test ,关于主线的渲染的流程可参考这个文档FOSDEM_Presentation_2018___Lukas_Rusak.pdf
最近编辑记录 benlypan (2022-04-25 09:33:16)
离线
5.2内核中,DRM驱动有问题,不知道后面有没有改进,前面做一个热成像与普通摄像头图像混合时发这个问题,但在我对DRM的各种偿试,把DRM的寄存器与功能摸彻底后,驱动就更正了,但由于是保密项目,就没patch到主线
离线
哦对了,tina 里 libcedarx 下有 xplayerdemo,可以硬解和"硬渲染",可以尝试一下。
tina是不是只有全志的代理商才有
我找了整 个网络没有找到TINA
我在GITHUB上找到了 xplayerdemo 但是无法编译,对方提供的是只适合他的本机环境的一个组件包
以上的内容在哪里可以下载到
离线
https://github.com/lindenis-org/lindenis-v536-package
这就是 tina,全志的硬解软件分3个部分:
1. 内核驱动模块,就是 /dev/cedar_dev,你现在已经有了
2. cedarc, 操作内核模块,各种格式的解码模块(闭源),导出解码接口,这是接口文档http://files.lindeni.org/lindenis-v536/ … %d1%9e.pdf
3. cedarx, 集成了数据流解析,解码(调用 cedarc),渲染等功能,也就是完整的播放器了,xplayerdemo 就在里面(allwinner/tina_multimedia/libcedarx/demo/xplayerdemo)
离线
@benlypan
非常感谢
离线
5.2内核中,DRM驱动有问题,不知道后面有没有改进,前面做一个热成像与普通摄像头图像混合时发这个问题,但在我对DRM的各种偿试,把DRM的寄存器与功能摸彻底后,驱动就更正了,但由于是保密项目,就没patch到主线
我今天在研究 V3s 的 DRM,内核版本就是 5.2,发现一个问题,输入图像格式是 NV21,然后调用 drmModeSetPlane 时如果 SRC_W 超过 1024 图像就显示就不正常,1024以下完全没问题。请问我碰到的这个问题跟您解决的BUG是否相关?
离线
老哥硬件解码成功了没,我也看贴子设置了,但是就是解不了分辨率高的,高就卡
离线
我今天在研究 V3s 的 DRM,内核版本就是 5.2,发现一个问题,输入图像格式是 NV21,然后调用 drmModeSetPlane 时如果 SRC_W 超过 1024 图像就显示就不正常,1024以下完全没问题。请问我碰到的这个问题跟您解决的BUG是否相关?
研究了将近两天时间,终于把这个问题给搞定。DE 里有个叫 scanline 的东西,V3s 里的值是 1024,输入宽度要是超过 scanline,需要进行"coarse scaling",然后主线里将 V3s 的这个值配置成 2048 了,所以图像显示不正常。
全志 Linux 的相关代码 https://github.com/Tina-Linux/tina-v3s-linux-4.9/blob/master/drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_sun8iw8/de_rtmx.c#L1212 https://github.com/Tina-Linux/tina-v3s-linux-4.9/blob/master/drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_sun8iw8/de_feat.c#L57
主线 Linux 的相关代码 https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/sun4i/sun8i_vi_layer.c#L192 https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/sun4i/sun8i_mixer.c#L583
一开就猜测是驱动的 bug,然后有了以下排查流程:
1. 换最新版本的主线内核,问题依旧
2. 因为我用的是 AIC502,虽然跟 V3s 一样,但就担心硬件有差异,换 V3s,一样有问题
3. 换 A64 用主线内核,不存在问题,他们都属于 DE2,用的是同一份驱动,难道是某些条件下对 V3s 设置错寄存器值了?于是用同样的内核版本,同样的测试数据,把 DE 的相关寄存器值都 dump 下来,比对发现几乎一模一样,泪崩。
4. 换全志的 Linux Kernel,不存在问题,此时确定了肯定是驱动问题,不是硬件问题。再把这个系统下的寄存器值 dump 下来,与主线的一个个寄存器比对过去,发现了一个输入宽度相关的寄存器数值不一样,全志的内核是 1024,主线是我图像的宽度 1280,进一步确定了 1024 是一个 magic number
5. 打开调试日志+printk大法,很快定位到是这个 scanline 引起的。虽然具体的计算原理没看懂,但问题解决了。
离线
@benlypan
牛,请问最后怎么解决的呢?
离线
@benlypan
牛,请问最后怎么解决的呢?
把 2048 改成 1024 就行了。V3s 里 YUV 和 RGB 的 scanline 都是 1024,所以可以直接把 https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/sun4i/sun8i_vi_layer.c#L192 这行改成 scanline = 2048 就行了。
然而我的情况比较特殊,我要在别的产品里二次开发,不能换内核,所以就写了个内核模块,启动时 insmod 来动态更改这个配置,这样只能对 YUV 生效,不过反正我也不用 RGB,分享下这个内核模块的代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include "../linux/drivers/gpu/drm/sun4i/sun8i_mixer.h"
static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
.vi_num = 2,
.ui_num = 1,
.scaler_mask = 0x3,
.scanline_yuv = 1024,
.ccsc = 0,
.mod_rate = 150000000,
};
static struct sun8i_mixer* mixer;
static const struct sun8i_mixer_cfg* old_mixer_cfg;
static int find_device_match(struct device* dev, void* data) {
return 1;
}
static int __init fixdrm_init(void) {
struct device_driver* drv;
struct device* dev;
drv = driver_find("sun8i-mixer", &platform_bus_type);
if (!drv) {
pr_err("driver not found");
return -ENODEV;
}
dev = driver_find_device(drv, NULL, NULL, find_device_match);
if (!dev) {
pr_err("device not found");
return -ENODEV;
}
mixer = dev_get_drvdata(dev);
if (!mixer) {
pr_err("mixer not found");
return -ENODEV;
}
old_mixer_cfg = mixer->cfg;
pr_info("scanline_yuv: %d\n", old_mixer_cfg->scanline_yuv);
mixer->cfg = &sun8i_v3s_mixer_cfg;
return 0;
}
static __exit void fixdrm_exit(void) {
if (mixer && old_mixer_cfg) {
mixer->cfg = old_mixer_cfg;
}
pr_info("exit\n");
}
module_init(fixdrm_init);
module_exit(fixdrm_exit);
MODULE_LICENSE("GPL");
最近编辑记录 benlypan (2022-05-01 20:15:56)
离线
@benlypan
请教 printk 要怎么打开?谢谢!
离线
5.2内核中,DRM驱动有问题,不知道后面有没有改进,前面做一个热成像与普通摄像头图像混合时发这个问题,但在我对DRM的各种偿试,把DRM的寄存器与功能摸彻底后,驱动就更正了,但由于是保密项目,就没patch到主线
是有2个plane不能正确显示吗?我也碰到这个问题了,不知道从哪里解决
离线
我也想实现硬解码啊,哪个大神可以指点指点啊。
离线