Amlogic Linux系列(四) 视频解码分析2

打算学习一下Amlogic Linux系统,目前已知的amlogic Linux系统包括

1.官方的buildroot(没有技术资料,只支持A311D/S905D3)

2.khadas ubuntu (开源,只对vim系列开发板技术支持):

KVM1-S905X

KVM2-S912

KVM3-A311D

手上有一块amlogic S912的盒子一直没用,buildroot是没法用了,准备将KVM2的ubuntu系统移植到这块板子上,并移植后相关驱动,并做后续的功能测试

这块板子的基本配置:

S912+LPDDR3+32G带RTC数码管
一、概述

上一章测试了khadas 自带的mpv播放器直接播视频是没有走硬解的,播放视频卡顿。为此研究和对比khadas 的代码,发现khadas是加入了amlogic硬解的,但是应该是上层没法调用。

为了确认这一点,使用了相关测试程序,来验证硬解码驱动。经确认是可以的。

相关打印:

[  350.125624] DI: unreg f
[  350.127619] pts hit 0, pts missed 0, i hit 0, missed 0
[  350.127638] total frame 0, avi_flag 0, rate 3840
[  350.127887] vdec_release instance ffffff800ea2b000, total 1
[  350.128910] the clk_hevc_mux    clock off, ref cnt: -7
[  350.128959] the clk_vdec_mux    clock off, ref cnt: 0
[  350.128979] the vdec            clock off, ref cnt: 0
[  350.128998] the parser_top      clock off, ref cnt: 0
[  350.129015] the demux           clock off, ref cnt: 0
[  350.129407] fb: osd[0] enable: 1 (ttyx)
[  356.096944] fb: osd[0] enable: 0 (ttyx)
[  356.107191] video_global_output_store(1)
[  356.117039] the demux           clock on, ref cnt: 1
[  356.117065] the parser_top      clock on, ref cnt: 1
[  356.117083] the vdec            clock on, ref cnt: 1
[  356.117123] the clk_vdec_mux    clock on, ref cnt: 1
[  356.117149] vdec mux clock is 500000000 Hz
[  356.117265] vdec_create instance ffffff800ea64000, total 1
[  356.117414] no drmmode
[  356.117473] The fw has been loaded.
[  356.121055] Video stbuf alloced at 00000000a3000000, secure = 0, size = 10485760
[  356.121118] vdec_init, dev_name:amvdec_vc1, vdec_type=VDEC_TYPE_SINGLE
[  356.121133] vdec_init set vfm decoder ffffff800ea64000
[  356.126917] vvc1_init, format 11
[  356.126949] decoder_bmmu_box_alloc_box, tvp_flags = 0
[  356.126964] WVC1 dec format
[  356.126984] [LOCAL], the fw (vc1) will be loaded.
[  356.129716] vdec_request_irq ffffff80026340c0, vvc1-irq
[  356.130883] di_receiver_event_fun: vframe provider reg ppmgr
[  356.131033] DI: reg f
[  356.138215] vdec_init, vf_provider_name = 
[  356.138893] video first pts = 0
[  356.138913] vdec_request_irq ffffff8002309f98, parser
[  356.205380] DI: di_receiver_event_fun , is_bypass() 1 trick_mode 0 bypass_all 0
[  356.205398] DI: di_receiver_event_fun: unreg
[  356.205410] DI: provider name:(null)
[  356.205557] DI: di_unreg_process unreg start 1.
[  356.205591] VD1 AFBC 0x0.
[  356.205612] DI: di_unreg_process vf unreg cost 0 ms.
[  356.205624] DI: di_unreg_process unreg stop 1.
[  356.205700] di_unreg_process_irq disable di mirror image.
[  356.205711] DI: di_unreg_process_irq:cma release req time: 56132 ms
[  356.205758] di_cma_release:release 0 buffer use 0 ms(56132~56132)
[  356.208848] DI: unreg f
[  356.211352] pts hit 0, pts missed 0, i hit 0, missed 0
[  356.211374] total frame 0, avi_flag 0, rate 3840
[  356.215434] vdec_release instance ffffff800ea64000, total 1
[  356.216513] the clk_hevc_mux    clock off, ref cnt: -8
[  356.216563] the clk_vdec_mux    clock off, ref cnt: 0
[  356.216585] the vdec            clock off, ref cnt: 0
[  356.216603] the parser_top      clock off, ref cnt: 0
[  356.216620] the demux           clock off, ref cnt: 0
[  356.217039] fb: osd[0] enable: 1 (ttyx)
[  358.672936] fb: osd[0] enable: 0 (ttyx)
[  358.676404] video_global_output_store(1)
[  367.113682] fb: osd[0] enable: 0 (ttyx)
[  367.118266] video_global_output_store(1)
[  371.051434] fb: osd[0] enable: 0 (ttyx)
[  371.055476] video_global_output_store(1)
[  384.099813] fb: osd[0] enable: 0 (ttyx)
[  384.103504] video_global_output_store(1)
[  390.212107] fb: osd[0] enable: 0 (ttyx)
[  390.224701] video_global_output_store(1)
[  390.232051] the demux           clock on, ref cnt: 1
[  390.232077] the parser_top      clock on, ref cnt: 1
[  390.232094] the vdec            clock on, ref cnt: 1
[  390.232135] the clk_vdec_mux    clock on, ref cnt: 1
[  390.232162] vdec mux clock is 500000000 Hz
[  390.232277] vdec_create instance ffffff800ea9d000, total 1
[  390.232390] no drmmode
[  390.232447] The fw has been loaded.
[  390.236408] Video stbuf alloced at 00000000a3000000, secure = 0, size = 10485760
[  390.236465] vdec_init, dev_name:amvdec_h264, vdec_type=VDEC_TYPE_SINGLE
[  390.236479] vdec_init set vfm decoder ffffff800ea9d000
[  390.244415] decoder_bmmu_box_alloc_box, tvp_flags = 0
[  390.244442] H264 sysinfo: 1920x960 duration=3840, pts_outside=1 
[  390.244455] sync_outside=1, use_idr_framerate=0
[  390.247592] 264 ucode swap area: phyaddr 00000000b4a40000, cpu vaddr ffffff800eab4000
[  390.247668] [LOCAL], the fw (h264) will be loaded.
[  390.247944] vdec_request_irq ffffff8002525b68, vh264-irq
[  390.247998] di_receiver_event_fun: vframe provider reg ppmgr
[  390.248140] DI: reg f
[  390.258154] h264_reset_userdata_fifo: bInit: 1, ri: 0, wi: 0
[  390.258261] vdec_init, vf_provider_name = 
[  390.258916] video first pts = 0
[  390.258936] vdec_request_irq ffffff8002309f98, parser
[  390.270525] Enter set parameter cmd1.
[  390.270733] vdec mux clock is 666666666 Hz
[  390.271001] vdec1 video changed to 3840 x 2160 60 fps clk->667MHZ
[  390.271022] actual_dpb_size 11 max_dpb_size 5 max_ref 4
[  390.378059] di: di_init_buf -S
[  390.378101] DI: di_init_buf:cma alloc req time: 90308 ms
[  390.378126] di: di_init_buf -E
[  390.378158] di_patch_post_update_mc_sw:0x0->0x2
[  390.438016] di_cma_alloc:alloc 10 buffer use 60 ms(90308~90368)
[  390.444228] pre_de_buf_config:90372ms 1th source change: 0x0/0/0/0=>0x9000/1920/1080/0
[  390.474445] video first pts = e10
[  390.474595] 
               [amvideo..] saturation_pre:0 hue_pre:0 mab:1000000
[  391.290121] vdec mux clock is 285714285 Hz
[  391.290144] vdec1 video changed to 1920 x 1080 25 fps clk->333MHZ
[  393.653897] DI: DI: tasklet schedule cost 12ms.
[  411.253879] DI: DI: tasklet schedule cost 12ms.
[  412.898661] DI: di_receiver_event_fun , is_bypass() 0 trick_mode 0 bypass_all 0
[  412.898678] DI: di_receiver_event_fun: unreg
[  412.898690] DI: provider name:(null)
[  412.914125] DI: di_unreg_process unreg start 1.
[  412.914173] keep exit is skip current
[  412.914190] video first pts = 0
[  412.914198] VD1 AFBC 0x0.
[  412.914219] DI: di_unreg_process vf unreg cost 0 ms.
[  412.914231] DI: di_unreg_process unreg stop 1.
[  412.914316] di_unreg_process_irq disable di mirror image.
[  412.914326] di_patch_post_update_mc_sw:0x2->0x0
[  412.914334] DI: di_unreg_process_irq:cma release req time: 112844 ms
[  412.917500] di_cma_release:release 10 buffer use 0 ms(112844~112844)
[  412.917556] DI: unreg f
[  412.924465] vdec mux clock is 285714285 Hz
[  412.924487] vdec1 video changed to 0 x 0 0 fps clk->333MHZ
[  412.924770] vdec_release instance ffffff800ea9d000, total 1
[  412.926634] the clk_hevc_mux    clock off, ref cnt: -9
[  412.926679] the clk_vdec_mux    clock off, ref cnt: 0
[  412.926702] the vdec            clock off, ref cnt: 0
[  412.926721] the parser_top      clock off, ref cnt: 0
[  412.926738] the demux           clock off, ref cnt: 0
[  412.927138] fb: osd[0] enable: 1 (ttyx)
[  417.312544] fb: osd[0] enable: 0 (ttyx)
[  417.318588] video_global_output_store(1)
[  417.328461] the demux           clock on, ref cnt: 1
[  417.328486] the parser_top      clock on, ref cnt: 1
[  417.328504] the vdec            clock on, ref cnt: 1
[  417.328541] the clk_vdec_mux    clock on, ref cnt: 1
[  417.328618] vdec mux clock is 500000000 Hz
[  417.328733] vdec_create instance ffffff800eae5000, total 1
[  417.328885] no drmmode
[  417.328945] The fw has been loaded.
[  417.332987] Video stbuf alloced at 00000000a3000000, secure = 0, size = 10485760
[  417.333053] vdec_init, dev_name:amvdec_h264, vdec_type=VDEC_TYPE_SINGLE
[  417.333068] vdec_init set vfm decoder ffffff800eae5000
[  417.334886] decoder_bmmu_box_alloc_box, tvp_flags = 0
[  417.334913] H264 sysinfo: 1920x960 duration=3840, pts_outside=1 
[  417.334926] sync_outside=1, use_idr_framerate=0
[  417.335929] 264 ucode swap area: phyaddr 00000000b4a40000, cpu vaddr ffffff800eafc000
[  417.335999] [LOCAL], the fw (h264) will be loaded.
[  417.336273] vdec_request_irq ffffff8002525b68, vh264-irq
[  417.336338] di_receiver_event_fun: vframe provider reg ppmgr
[  417.340248] DI: reg f
[  417.341018] h264_reset_userdata_fifo: bInit: 1, ri: 0, wi: 0
[  417.341098] vdec_init, vf_provider_name = 
[  417.343314] video first pts = 0
[  417.343338] vdec_request_irq ffffff8002309f98, parser
[  417.345718] Enter set parameter cmd1.
[  417.346613] vdec mux clock is 666666666 Hz
[  417.346632] vdec1 video changed to 3840 x 2160 60 fps clk->667MHZ
[  417.346651] actual_dpb_size 11 max_dpb_size 5 max_ref 4
[  417.374029] di: di_init_buf -S
[  417.374074] DI: di_init_buf:cma alloc req time: 117304 ms
[  417.374100] di: di_init_buf -E
[  417.374131] di_patch_post_update_mc_sw:0x0->0x2
[  417.380362] di_cma_alloc:alloc 10 buffer use 4 ms(117304~117308)
[  417.384180] pre_de_buf_config:117312ms 1th source change: 0x0/0/0/0=>0x9000/1920/1080/0
[  417.401444] video first pts = e10
[  418.213933] vdec mux clock is 285714285 Hz
[  418.213954] vdec1 video changed to 1920 x 1080 25 fps clk->333MHZ
[  481.253887] DI: DI: tasklet schedule cost 12ms.
[  531.453872] DI: DI: tasklet schedule cost 12ms

cat vfm/map 打印

khadas@Khadas:/sys/class$ 
khadas@Khadas:/sys/class$ 
khadas@Khadas:/sys/class$ cat vfm/map 
[00]  default { decoder(1) ppmgr(1) deinterlace(1) amvideo}
[01]  default_amlvideo2 { vdin1(0) amlvideo2.1}
[02]  dvblpath { dvbldec(0) amvideo}
[03]  dvelpath { dveldec(0) dvel}
[04]  dvhdmiin { dv_vdin(0) amvideo}

provider list:
   decoder.h264
   ppmgr
   deinterlace

receiver list:
   vfm_grabber
   amvideo
   videopip
   deinterlace
   amlvideo
   amlvideo2.0
   amlvideo2.1
   ppmgr
   ionvideo
   videosync.0
khadas@Khadas:/sys/class$ 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Amlogic将其硬件解码器的实现封装在了一个名为“amvdec”的库中,通过调用该库中的接口来实现MP4文件的硬解码。 以下是一个简单的示例代码,演示如何使用amvdec库来解码MP4文件: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include "amvdec.h" int main(int argc, char **argv) { int fd, ret; struct amvdec_ctx *ctx; struct amvdec_input *input; struct amvdec_output *output; if (argc != 2) { printf("Usage: %s input.mp4\n", argv[0]); return 0; } // 打开MP4文件 fd = open(argv[1], O_RDONLY); if (fd < 0) { printf("Failed to open input file\n"); return -1; } // 初始化解码器上下文 ctx = amvdec_init(); if (!ctx) { printf("Failed to initialize decoder context\n"); close(fd); return -1; } // 分配输入数据结构 input = amvdec_alloc_input(); if (!input) { printf("Failed to allocate input buffer\n"); amvdec_release(ctx); close(fd); return -1; } // 分配输出数据结构 output = amvdec_alloc_output(); if (!output) { printf("Failed to allocate output buffer\n"); amvdec_release(ctx); amvdec_free_input(input); close(fd); return -1; } // 解码循环,直到文件结束 while (1) { // 从文件中读取数据 input->addr = mmap(NULL, input->size, PROT_READ, MAP_PRIVATE, fd, 0); if (input->addr == MAP_FAILED) { printf("Failed to read input data\n"); break; } // 设置输入数据长度 input->length = lseek(fd, 0, SEEK_END) - input->offset; lseek(fd, input->offset, SEEK_SET); // 解码输入数据 ret = amvdec_decode(ctx, input, output); if (ret < 0) { printf("Failed to decode input data\n"); break; } // 输出解码后的数据(可以保存到文件中) printf("Decoded %d bytes\n", output->length); // 释放输入数据内存 munmap(input->addr, input->size); // 如果解码完毕,则退出循环 if (output->flags & AMVDEC_FLAG_EOS) { break; } } // 释放资源 amvdec_free_output(output); amvdec_free_input(input); amvdec_release(ctx); close(fd); return 0; } ``` 需要注意的是,该示例代码并没有处理解码后的数据,而是直接将其输出到屏幕上。如果需要保存解码后的数据到文件中,可以将输出数据写入到文件中。另外,该示例代码只是一个简单的演示,实际应用中还需要进行错误处理和资源释放等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值