跳到主要内容

媒体传输 · 解码

1. 模块概述

  • 主要功能:视频解码模块,将 H.264/H.265/JPEG 压缩码流还原为原始 YUV/RGB 视频帧,用于显示或后续图像处理
  • 规格或特性:
    • 支持解码格式:H.264 (AVC)、H.265 (HEVC)、MJPEG
    • 支持分辨率:最高 4K (3840x2160)
    • 支持帧率:最高 60fps(4K)
    • 硬件加速:使用硬件解码器,低功耗高性能
    • 输出格式:YUV420、NV12、NV21 等
  • 相关目录结构:基于 MPP 框架,参考 多媒体 · MPP

2. 环境准备

前置条件

  • 依赖与外部资源:MPP 库、硬件解码器驱动
  • 环境变量与初始化:同 MPP
  • 硬件与连接:SPACEMIT K3 芯片或兼容平台
  • 工具与权限:访问解码器设备节点需相应权限

构建编译

  • 获取代码:

    SDK 源码获取和基础编译环境配置参考2.3-构建编译。完成 SDK 初始化后,回到本文继续执行

    后续命令默认在 spacemit_robot SDK 根目录执行。

  • 本模块编译:参考 多媒体 · MPP

3. 示例使用(从 0 跑通)

3.1 命令行解码测试(文件到文件)

使用 MPP 自带的 test_vdec_file 工具,将压缩码流解码为 YUV 原始帧,快速验证解码功能。

前置:已编译 MPP,开发板已开机并通过 SSH 登录

步骤 1:SSH 登录开发板

ssh root@<开发板IP>
# 密码:root

步骤 2:进入到SDK构建目录,拷贝相关测试文件,然后进入测试程序目录

cd spacemit_robot
cp components/multimedia/mpp/test/assets/1920x1080.jpg output/build/cmake/pkgs/components_multimedia_mpp/test/
cd output/build/cmake/pkgs/components_multimedia_mpp/test

步骤 3:运行 MJPEG 解码

./test_vdec_file ./1920x1080.jpg 1920 1080 ./dec_out_nv12.yuv mjpeg

参数说明:

参数含义
./1920x1080.jpg输入码流文件路径
1920图像宽度
1080图像高度
./dec_out_nv12.yuv输出 YUV 文件路径
mjpeg解码格式(支持 h264h265mjpeg

预期现象:

[INFO] VDEC file test: ./1920x1080.jpg -> ./dec_out_nv12.yuv, codec=mjpeg, size=105692
[INFO] decoded frame: 1920x1080 planes=2 stride=1920 pts=0

解码完成后在当前目录生成 dec_out_nv12.yuv 文件。

步骤 4:验证输出 YUV

dec_out_nv12.yuv 拷贝到 PC 上,使用 ffplay 播放验证:

ffplay -f rawvideo -pix_fmt nv12 -s 1920x1080 dec_out_nv12.yuv

提示:也可以先用编码示例(见 编码)生成 H.264 码流,再用 test_vdec_file 解码验证编解码闭环。

3.2 H.264 解码 API 调用示例

以下为使用 MPP API 进行解码的代码示例,展示核心调用流程。

步骤 1:创建解码器上下文

#include "vdec.h"

MppVdecCtx *ctx = vdec_ctx_create();
vdec_ctx_init(ctx);

步骤 2:设置解码参数

ctx.eCodecType = MPP_CODEC_H264;
vdec_ctx_set_param(&ctx);

步骤 3:送入码流并解码

MppData input_stream;
// 填充 input_stream 码流数据
vdec_ctx_decode(ctx, &input_stream);

步骤 4:获取解码后的视频帧

MppData output_frame;
vdec_ctx_get_output_frame(ctx, &output_frame);
// 处理 output_frame(显示或保存)
vdec_ctx_return_output_frame(ctx, &output_frame);

预期现象:输出 YUV 视频帧,可保存为文件或送显示

4. 应用开发

  • 对外 API 或接口形态

    • 头文件:include/vdec.h
    • 库名:libmpp_vdec.so
    • 主要 API:
      • vdec_ctx_create() - 创建解码器上下文
      • vdec_ctx_init() - 初始化解码器
      • vdec_ctx_set_param() - 设置解码参数
      • vdec_ctx_decode() - 解码码流
      • vdec_ctx_get_output_frame() - 获取输出帧
      • vdec_ctx_destroy() - 销毁解码器
  • 调用方式与注意点

    • 初始化顺序:create → init → set_param → decode
    • 线程安全:单个上下文不支持多线程并发
    • 内存管理:输出帧需及时释放,避免内存泄漏
    • 帧释放:获取帧后必须调用 return_output_frame() 释放
    • 码流格式:确保输入码流格式正确,包含完整的 SPS/PPS
  • 参考 demo 或示例路径mpp/test/test_vdec_file.cmpp/mpi/vdec/vdec.cmpp/sample/sample_uvc_vdec.c

5. 调试指南

  • 帧数据验证:将输出 YUV 保存为文件,用 ffplay 播放验证
  • 性能分析:统计解码耗时,计算实际帧率
  • 错误处理:检查返回值,处理解码失败情况

6. 常见问题

现象可能原因处理
解码初始化失败硬件解码器插件未加载检查 libv4l2_linlonv5v7_codec2.so是否存在
解码花屏码流格式错误或损坏确认码流格式,检查 SPS/PPS
解码帧率低码流码率过高或分辨率过大降低码流码率或分辨率
内存泄漏未释放输出帧确保调用 return_output_frame()

附录:性能与测试数据

指标数值测试条件
H.264 解码性能4K@60fps硬件解码
H.265 解码性能4K@30fps硬件解码
解码延迟<30ms1080p 单帧

测试方法:使用 MPP 测试程序,SPACEMIT K3 平台,Linux 内核 5.10。测试命令:

cd spacemit_robot
cp components/multimedia/mpp/test/assets/1920x1080.jpg output/build/cmake/pkgs/components_multimedia_mpp/test/
cd output/build/cmake/pkgs/components_multimedia_mpp/test
./test_vdec_file ./1920x1080.jpg 1920 1080 ./dec_out_nv12.yuv mjpeg