Linux Encoder 开发指南
前言
文档简介
本文档重点阐述 Allwinner 平台视频编码的驱动开发方法、使用规范与调试技巧。目的是为了视频编码系统开发与支持等相关技术人员,能对 Allwinner 平台视频编码器的 驱动体系有更深入的理解,并通过实际应用指导快速开展高效开发、定位问题与解决问题。文档详细介绍了编码器的接口设计、数据结构、配置方法及最佳实践,为开发者提供全面的技术参考。
目标读者
视频编码系统开发人员、视频编码系统技术支持人员
符号约定
本文档中会使用不同符号区分信息类型,具体释义如下:
备注
用于呈现技术核心信息(如功能原理、核心参数定义)、流程补充内容(如步骤细节说明)等。
:::
提示
用于分享技术操作中的高效方法(如命令行快捷指令、配置项优化窍门)与实践技巧。
:::
注意
用于突出技术操作中易出错的环节(如参数配置边界、操作顺序要求)的提示。
:::
适用平台
| 平台 | 内核版本 |
|---|---|
| V861 | Linux 5.10及以上内核版本 |
相关术语
| 术语 | 解释 |
|---|---|
| CABAC | Context-based Adaptive Binary Arithmetic Coding,基于上下文的自适应二进制算术编码 |
| CAVLC | Context-based Adaptive Variable Length Coding,基于上下文的自适应可变长度编码 |
| Encoder | 视频编码器,将原始视频数据压缩编码为特定格式(如H.264、JPEG等)的硬件或软件模块 |
| H.264 | 一种高效的视频压缩编码标准,也称为MPEG-4 AVC |
| I帧 | Intra-frame,帧内编码帧,可独立编码的完整图像帧 |
| JPEG | 联合图像专家小组制定的静态图像压缩标准 |
| P帧 | Predicted-frame,预测帧,基于前面的I帧或P帧进行预测编码 |
| QP | Quantization Parameter,量化参数,影响编码质量和码率 |
| ROI | Region of Interest,感兴趣区域,可对视频中特定区域进行特殊处理 |
| SVC | Scalable Video Coding,可伸缩视频编码,支持时域、空域等多种可伸缩性 |
| VBV | Video Buffer Verifier,视频缓冲验证器,用于控制码率输出 |
概述
本章节主要介绍Allwinner平台V861芯片的视频编码技术规格及编码特性。
Encoder功能概述
Allwinner平台Encoder模块支持JPEG、H.264、H265格式编码,本节将详细介绍其主要特性,包括支持的编码格式、分辨率范围、编码模式等关键参数,帮助开发者充分了解编码器的能力边界和优化空间。
H.264编码特性
H.264编码是Encoder模块的核心功能之一,具有以下特性:
- Profile支持:支持Baseline Profile、Main Profile、High Profile 5.1
- 编码模式:支持I帧、P帧编码
- 熵编码方式:支持CABAC和CAVLC
- 码率控制:支持CBR(恒定码率)、VBR(可变码率)、AVBR(适配式可变码率控制方式)等多种码率控制方式
- 特殊功能:支持ROI编码、循环帧内刷新、时域SVC等高级特性
- 最大性能:4k@30fps
H.265编码特性
H.264编码是Encoder模块的核心功能之一,具有以下特性:
- Profile支持:支持Main Profile 5.0
- 编码模式:支持I帧、P帧编码
- 熵编码方式:支持CABAC
- 码率控制:支持CBR (恒定码率)、VBR(可变码率)、AVBR(适配式可变码率控制方式)等多种码率控制方式
- 特殊功能:支持ROI编码、循环帧内刷新、时域SVC等高级特性
- 最大性能:4k@35fps
JPEG编码特性
JPEG编码主要用于静态图像压缩,具有以下特性:
- 质量控制:支持0-100级的质量参数调整
- EXIF支持:支持嵌入图像元数据信息
- 编码模式:支持单帧JPEG编码和MJPEG序列编码
- 最大性能:4k@30fps
模块驱动开发
本章节介绍Allwinner平台视频编码的结构设计、核心模块功能及API接口规范,帮助开发者理解编码系统的整体架构和模块间的交互关系。
视频编码的模块架构简介
视频编码库采用模块化架构设计,主要由四个核心模块组成,分别为帧缓冲输入管理模块、视频编码设备、码流输出管理模块、编码控制模块,各模块职责明确,协同工作完成视频编码功能,如下图所示:
| 模块名称 | 英文全称 | 主要职责 |
|---|---|---|
| 帧缓冲输入管理模块 | Frame Buffer Manager | 管理编码输入图像帧,支持外部内存管理和内部内存分配两种模式,提供高效的帧数据存取接口 |
| 视频编码设备 | Video Encoder Device | 负责将输入图像帧编码为压缩码流,提供硬件编码能力接口,支持H.264、H.265、JPEG等编码格式 |
| 码流输出管理模块 | Bitstream Manager | 管理编码输出码流,维护码流缓冲区,记录帧结构信息,支持循环缓冲区管理 |
| 编码控制模块 | vencoder | 协调各模块工作,控制整体编码流程,对外提供统一的编码库接口函数,实现功能封装 |
源码清单
编码器驱动源码主要包含头文件、实现文件和配置文件,整体组织结构清晰。
代码工程结构概述
驱动的主要源码文件及说明如下:
.
├── base/ # Core utility modules: logging, message queue, INI parser, ION memory utils, etc.
│ ├── cdcIniparser/ # Custom INI configuration file parser implementation
│ ├── filesink/ # Output sink modules for bitstream and picture data dumping or MD5 checksum
│ └── include/ # Public headers for base utilities (log, memory list, platform config, etc.)
├── conf/ # System and hardware configuration files (e.g., video engine parameters)
├── demo/ # Example applications demonstrating SDK usage
│ ├── jpegdemo/ # JPEG decoding demo
│ ├── vdecoderDemo/ # Raw video stream decoding demo
│ └── vencoderDemo/ # Video encoding demo (v2 architecture)
├── include/ # Global public headers for video codec APIs (decoder/encoder interfaces, types, adapters)
├── install/ # Staging directory for final system installation (e.g., /etc, /usr/lib)
├── InstallDev/ # Development package layout (headers and libs for SDK integration)
├── library/ # Pre-built static and shared libraries
│ ├── glibc/ # Libraries compiled against glibc C runtime
│ ├── musl/ # Libraries compiled against musl C runtime (for lightweight systems)
│ └── out/ # Intermediate static libraries generated during build
├── memory/ # Memory management abstraction layer
│ ├── ionMemory/ # ION-based memory allocator for Linux kernel (Allwinner SoC)
│ └── secureMemory/ # Secure memory allocation for protected content (e.g., DRM)
└── vencoder/ # Video encoder implementation
├── base/ # Encoder core components: bitstream/frame buffer managers
└── libcodec/v2/ # V2 architecture of the video encoding codec backend
视频编码库使用
本章详细介绍Allwinner视频编码库的使用方法,包括编码流程、接口调用顺序、参数配置以及常见问题处理,帮助开发者快速掌握编码功能的实现。
必备条件
在开始使用视频编码库前,请确保满足以下条件:
- 了解基本的视频编码概念(I帧、P帧、码率、像素格式等)
- 熟悉C/C++编程语言和Linux/Android开发环境
- 准备好待编码的原始视频帧数据(支持YUV420P、NV12等像素格式)
- 确保系统有足够的内存资源分配给编码器
编码控制模块使用流程
Allwinner视频编码库提供了一套完整的接口流程,用户需按照规范的步骤进行操作。具体的使用流程可参考下图所示:

该图展示了视频编码的整体流程,包括初始化、编码循环和资源释放三个主要阶段,接下来会对这三部分进行说明:
- 创建编码器实例并初始化
在开始编码前,必须调用以下函数进行初始化:
// 初始化编码器参数
encode_param_t encode_param;
memset(&encode_param, 0, sizeof(encode_param));
encode_param.src_width = 1280;
encode_param.src_height = 736;
encode_param.dst_width = 1280;
encode_param.dst_height = 736;
encode_param.bit_rate = 2*1024*1024;
encode_param.frame_rate = 30;
encode_param.maxKeyFrame = 30;
encode_param.encode_format = VENC_CODEC_H264;
...
// 创建视频编码器实例
VENC_HANDLE pVideoEnc = VencCreate(encode_param.encode_format);
// 初始化编码器
int ret = VencInit(pVideoEnc, &baseConfig);
if (ret != 0) {
printf("初始化编码器失败!\n");
VideoEncDestroy(pVideoEnc);
return -1;
}
- 执行编码处理
初始化完成后,执行核心编码流程。该流程需在每次处理一帧数据时重复执行,分为输入帧处理和输出码流获取两个子流程:
a. 输入帧处理流程
// 从编码器获取一个已分配的输入缓冲区
pInputBufInfo = dequeueInputBuf(&pEncContext->mInputBufMgr.valid_quene);
memcpy(&mCurInputBuf, &pInputBufInfo->inputbuffer, sizeof(VencInputBuffer));
if(pInputBufInfo == NULL)
{
logv(" get input buffer failed");
USLEEP(10*1000);
return 1;
}
// 读取YUV数据到缓冲区(假设已打开输入文件in_file)
// Y分量
fread(mCurInputBuf.pAddrVirY, 1, bufferParam->nSizeY, in_file);
// UV分量
fread(mCurInputBuf.pAddrVirY, 1, bufferParam->nSizeY, in_file);
// 添加缓冲区并执行编码
enqueueInputBuf(&pEncContext->mInputBufMgr.empty_quene, pInputBufInfo);
VencQueueInputBuf(pEncContext->pVideoEnc, &mCurInputBuf);
VencStart(pVideoEnc);
if (ret != 0) {
printf("编码一帧失败!\n");
return -1;
}
b. 输出码流获取流程
// 获取编码后的码流帧
result = VencDequeueOutputBuf(pVideoEnc, &outputBuffer);
if(result == VENC_RESULT_BITSTREAM_IS_EMPTY)
{
logv("bitstream is empty ,continue");
break;
}
FWRITE(outputBuffer.pData0, 1, outputBuffer.nSize0, out_file);
//归还outputBuffer
VencQueueOutputBuf(pVideoEnc, &outputBuffer);
备注
输入和输出流程可以并行处理,但需注意线程安全。
:::
- 销毁编码器
当所有视频帧处理完毕后,应按以下步骤释放编码器资源:
// 销毁编码器实例
VencDestroy(pVideoEnc);
pVideoEnc = NULL; // 避免悬空指针
注意
确保在程序退出前释放所有编码资源。
:::
编码demo程序使用说明
由于编码demo程序的迭代速度较快,且会针对不同产品做出特性功能开发,故以下说明仅供参考,具体情况请以实际情况为准。
- demo路径
编码demo在Android的sdk中的具体路径为:android/frameworks/av/media/libcedarc/demo/vencoderDemo;
若开发环境为linux,则位于platform/Allwinner/multimedia/libcedarc/demo/vencoderDemo文件夹下。
- 基本参数介绍
在运行编码器demo时,即demoVencoder(以下简称demo),通过输入不同参数来实现不同的编码功能,目前demo中主流的参数配置如下所示:(以下所属环境为linux5.15系统)
在无法确定当前所使用编码器支持哪些参数输入时,则可以运行demo加上参数-h,即
./demoVencoder -h
将当前demo所支持的输入参数打印出来,可以根据该提示进行使用。
-i --input Input file path
-n --encode_frame_num After encoder n frames, encoder stop
-f --encode_format 0:h264 encoder, 1:jpeg_encoder, 3:h265 encoder
-o --output output file path
-s --srcsize src_size,can be 1920x1080 or 2160,1080,720,480,288
-d --dstsize dst_size,can be 1920x1080 or 2160,1080,720,480,288
-c --compare compare file:reference file path
-q --frequency frequency: the frequency of video engine
-b --bitrate bitRate:kbps
-sr --src_framerate src_framerate:fps
-dr --dst_framerate dst_framerate:fps
-v --vbv_size vbv_size:byte
-gs --gop_size Gop Size:
-kp --key_frm_period Key Frame Period
-gm --gop_mode Gop Mode
-rm --rc_mode RC Mode
-pm --product_mode ProductMode
-in --is_night Is Night
-st --sensor_type Sensor Type
-mt --moving_th Moving Th
-qua --quality Quality
-t --test_cycle Cycle num of testing
-l --logfile Log file path
-overlay --overlay add the overlay function
-overlay_in --overlay_int overlay intput data file
-lbc --lbc 1: no lossy lbc, 2: lossy_2x, 3: lossy_2.5x
-afbc --afbc 1: test afbc input data format
-limit_sp --limit speed 1: limit encoder speed by framerate
-i_qp_min --i qp min set the i_qp_min value
-i_qp_max --i qp max set the i_qp_max value
-p_qp_min --p qp min set the p_qp_min value
-p_qp_max --p qp max set the p_qp_max value
-qp_init --qp init set the qp_init value
-enc_num --encoder num create multi encoder
-pformat --pixel formatt set pixel format
-profile --profile set profile
-level --level set level
-ext_flag --ext_flag --ext_flag
-roi_wb --roi_wb test roi wbyuv.
-rotate --rotate test rotate, 0, 90, 180, 270
-hflip --hflip test hflip
-wb --wb test YUV WB
-wb_ratio --wb_ratio test YUV WB scaler ratio 1: 1/8; 2: 1/2; 3: 1/4
-gdc --gdc test gdc function
-gdc_mode --gdc_mode set gdc mode. 8: Warp_User
-ispbe --ispbe test ispbe function
-crop --crop test sw(1) hw(2) crop
-virz --vir_zoom test virtual zoom
-ir --intra_refresh test intra refresh
-vcu_on --vcu_on vcu: 0-vcu disable, 1-vcu enable
-vcu_auto --vcu auto mode vcu: 1-auto mode, 0-triger mode
-share_num --share buf num --share buf num
-share_bk --share buf bk --share buf bk
-enc_ch0 --enc channle0 --enc channle0
-enc_ch1 --enc channle1 --enc channle1
-enc_ch2 --enc channle2 --enc channle2
-enc_ch3 --enc channle3 --enc channle3
-enc_ch4 --enc channle4 --enc channle4
-enc_ch5 --enc channle5 --enc channle4
-enc_ch6 --enc channle6 --enc channle4
-enc_ch7 --enc channle7 --enc channle4
-enc_ch8 --enc channle8 --enc channle4
-s_1 --srcsize1 src_size2,can be 1920x1080 or 2160,1080,720,480,288
-d_1 --dstsize1 dst_size1,can be 1920x1080 or 2160,1080,720,480,288
-bb --bb test bounding box.
-gray --gray test gray.
-rec_lbc_mode --rec_lbc_mode --0: disable, 1:1.5x , 2: 2.0x, 3: 2.5x, 4: no_lossy
-sei --sei_num -----------
- 实例分析
本节提供编码器的详细使用示例,包括不同参数配置场景、日志分析方法以及结果验证步骤,帮助开发者快速上手并解决常见问题。
a. 基础参数配置
Ⅰ. 标准H.264编码示例
使用标准YUV420P视频源进行H.264编码测试:
./demoVencoder -f 0 -n 50 -pformat 2 -i 720p.yuv -o output.h264 -s 1280x720 -d 1280x720 -vcu_on 1 -vcu_auto 1
| 参数 | 说明 | 取值范围 | 示例值 |
|---|---|---|---|
| -i | 输入YUV文件路径 | 有效文件路径7 | 720p.yuv |
| -o | 输出码流文件路径 | 可写文件路径 | output.h264 |
| -s | 视频源尺寸 | W×H格式,支持多种分辨率 | 1280x720 |
| -d | 输出码流尺寸 | W×H格式,与源尺寸一致或缩放 | 1280x720 |
| -f | 编码器类型 | 0:H264, 1:JPEG | 0 |
| -pformat | 视频源像素格式 | 0:YUYV, 1:NV12, 2:YUV420P | 2 |
| -n | 编码总帧数 | >0 | 100 |
| -vcu_on | 开启VCU模式 | 0-1 | 1 |
| -vcu_auto | 开启vcu_auto模式 | 0-1 | 1 |
注意
视频源分辨率和输出码流的尺寸必须严格按照 W×H(宽×高)的格式进行配置。
vcu_on 和vcu_auto在V861上必须开启
:::
Ⅱ. 不同编码场景示例
运动编码场景:
./demoVencoder -f 0 -n 50 -pformat 2 -i 720p.yuv -o output.h264 -s 1280x720 -d 1280x720 -vcu_on 1 -vcu_auto 1 -i_qp_min 5 -i_qp_max 15
高画质编码场景:
./demoVencoder -f 0 -n 50 -pformat 2 -i 720p.yuv -o output.h264 -s 1280x720 -d 1280x720 -vcu_on 1 -vcu_auto 1 -b 5242880
JPEG编码示例:
./demoVencoder -f 1 -n 1 -pformat 2 -i 720p.yuv -o output.jpeg -s 1280x720 -d 1280x720 -vcu_on 1 -vcu_auto 1
b. 日志分析详解
运行日志包含丰富的编码信息,以下是关键日志解析:
***************************************************************
*******test begin time[13318s] *******
***************************************************************
*************[0] cycle demo start time[13318s]**************
******************************
encode_format:3 0:h264,1:jpeg,3:h265
encode:50 frames
test lbc: 0
pixel_format: 2
get input file: ./720P.yuv
get output file: 1280x720
get src_size: 1280x720
get dst_size: 1280x720
vbv size: 8388608byte
share_buf_num: 2
extend_flag: 0
hflip: 0
rotate_value: 0
bEnCrop: 0, l320t120w640h480
gdc_en: 0
gdc_mode: 0
test overlay flag: 0
get overlay file: /tmp/01_argb_464x32_time.dat
ispbe_en: 0
wb_yuv: 0
******************************
[13318.239] DEBUG : cdc <ChannelThread:3794>: tmpOutput_path = 1280x720_0.h265
[13318.240] DEBUG : cdc <ChannelThread:3808>: open log_file fail
[13318.240] DEBUG : cdc <veEnvInit:182>: VeContext 0x84af9820, encoder 0, decodec 1
[13318.240] INFO : cdc <veEnvInit:211>: open /dev/cedar_dev fd = 5
[13318.240] DEBUG : cdc <veEnvInit:220>: get ve_reg_addr = 0x84a3a000
[13318.240] DEBUG : cdc <getIcVersion:43>: ** address_macc 0x84a3a000 ve_top_offset = 0x800
[13318.240] DEBUG : cdc <getIcVersion:94>: *** ic_version = 0x1001000021410
[13318.241] DEBUG : cdc <checkFeatureSupport:1525>: bEnableVcuFuncFlag = 0, nEncoderFlag = 0
[13318.241] DEBUG : cdc <VeInitialize:1798>: address_macc = 0x84a3a000, address_vetop = 0x84a3a800
[13318.241] DEBUG : cdc <getSocInfo:1316>: not exist SocInfo plugin, use SocInfo node
[13318.241] DEBUG : cdc <VeInitialize:1801>: *** ic_version = 0x1001000021410
[13318.241] DEBUG : cdc <VeInitialize:1858>: *** nPhyOffset = 0x0
[13318.241] DEBUG : cdc <CdcIonOpen:320>: open /dev/dma_heap/size_pool
[13318.241] DEBUG : cdc <ChannelThread:3878>: baseConfig.eInputFormat = 2
[13318.241] DEBUG : cdc <ChannelThread:3985>: encode_param.encode_format:3
[13318.242] DEBUG : cdc <CdcIniParserInit:38>: load conf file /etc/cedarc.conf ok!
[13318.242] DEBUG : cdc <VencCreate:717>: now cedarc log level:5
[13318.243] WARNING: cdc <setEncParamBeforeInit:2578>: sei_num:0, nType:0, nLength:12, pBuffer(0):(null)
[13318.244] WARNING: cdc <H265SetFbm:7705>: not implement now
[13318.267] WARNING: cdc <offlineGroupNum_init:318>: ** bEnableDynamicConfig = 1
[13318.269] WARNING: cdc <h265regConfig_getDdrBufSize:848>: size info: mE3dFilter:3680, mDblk:10240, mMapInput:14720, mQpMadSseOut:22080
[13318.269] WARNING: cdc <h265regConfig_getDdrBufSize:852>: size info: mRefRecInfo:16384, mRefRecData:955392, mRefRecColMv:14720, mRefRecSubImg:61440, mRgnMv:16512, mColorBBox:1840
**had encoder frame num = 20
[13319.018] WARNING: cdc <ChannelThread:4385>: ch 0 encode stream fps 32
**had encoder frame num = 40
output file is saved:1280x720
*******[0]cycle demo end time[13319s] cur_cycle_time[1s]*******
***************************************************************
*******test end time[13319s] test_total_time[1s]*******
***************************************************************
c. 结果验证与分析
编码完成后,需要进行以下验证以确保编码质量和正确性:
Ⅰ. 文件存在性检查:
ls -lh 1280x720.h265
Ⅱ. 码流格式验证:
使用ffmpeg工具验证码流格式:
ffprobe -v quiet -print_format json -show_format -show_streams 1280x720.h265
预期输出应包含编码格式、分辨率、帧率等信息,确认与输入参数一致。
Ⅲ. 视频播放测试:
ffplay 1280x720.h265
调试方法
编译编码库
编码库编译是视频编码功能开发的基础环节,通过正确的编译配置可以生成适用于不同平台的编码器库文件。本小节介绍在Linux环境下编译libcedarc编码库的具体步骤,帮助开发者快速搭建编码开发环境。
必备条件
- 已获取完整的SDK源码包
- 配置好交叉编译工具链
- 具备基本的Linux命令行操作能力
- 足够的磁盘空间(建议至少100MB)
确认代码路径
根据开发平台定位编码库源码位置:
| 平台 | 源码路径 | 说明 |
|---|---|---|
| Tina | platform/Allwinner/multimedia/libcedarc | Tina Linux系统路径 |
注意:由于SDK结构可能更新,请以实际源码路径为准,必要时联系技术支持确认。
Linux环境编译配置
- 在SDK根目录设置编译工具链环境
source buile/envsetup.sh
lunch
- 跳转至编码库目录
clibcedarc_p
- 编译
mm -b
配置编码日志系统
简介
libcedarc编码器提供完整的日志记录系统,通过配置cedarc.conf文件可灵活控制日志输出级别和内容。合理配置日志系统有助于跟踪编码过程、快速定位问题并优化编码性能。本任务将指导您完成日志系统的配置,实现对编码过程的精准监控。
必备条件
- 已获取目标平台的cedarc.conf配置文件访问权限
- 了解基本的日志级别概念(ERROR/WARN/INFO/DEBUG)
- 确认编码器已正确部署并可运行
- 具备文件编辑权限
了解日志级别配置
日志系统提供五个级别,根据不同的调试场景选择合适的级别:
| 级别 | 数值 | 说明 | 使用场景 |
|---|---|---|---|
| VERBOSE | 2 | 详细信息 | 深度调试,开发阶段使用 |
| DEBUG | 3 | 调试信息 | 功能调试,问题排查 |
| INFO | 4 | 一般信息 | 正常流程状态、关键操作记录 |
| WARNING | 5 | 警告信息 | 非致命异常、性能瓶颈等 |
| ERROR | 6 | 错误信息 | 编码失败、参数错误等严重问题 |