HarmonyOS鸿蒙Next中AVCodec H.265 低延迟解码在不同设备上输出回调延迟差异较大,是否为硬解/Surface调度策略差异?

HarmonyOS鸿蒙Next中AVCodec H.265 低延迟解码在不同设备上输出回调延迟差异较大,是否为硬解/Surface调度策略差异? 诸位好,我们尝试基于官方视频解码指南实现一个最小 H.265 解码渲染 demo,用于测试 AVCodec 低延迟解码能力。

测试方式:

  1. 使用 OH_VideoDecoder_CreateByMime(“video/hevc”) 创建解码器。
  2. Configure 阶段设置:
OH_AVFormat_SetIntValue(format.get(), OH_MD_KEY_WIDTH, 2560);
OH_AVFormat_SetIntValue(format.get(), OH_MD_KEY_HEIGHT, 1440);
OH_AVFormat_SetDoubleValue(format.get(), OH_MD_KEY_FRAME_RATE, static_cast<double>(60));
OH_AVFormat_SetIntValue(format.get(), OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_SURFACE_FORMAT);
OH_AVFormat_SetIntValue(format.get(), OH_MD_KEY_VIDEO_ENABLE_LOW_LATENCY, 1);
OH_AVFormat_SetIntValue(format.get(), OH_MD_MAX_INPUT_BUFFER_COUNT, 1);
OH_AVFormat_SetIntValue(format.get(), OH_MD_MAX_OUTPUT_BUFFER_COUNT, 1);
  1. 输入码流为 Annex-B H.265 elementary stream,开头包含 VPS/SPS/PPS/IDR。
  2. 使用 XComponent Surface 渲染。
  3. 统计方式是在 PushInputBuffer 前记录时间戳,在 OnNewOutputBuffer 回调中按 PTS 匹配,计算 PushInputBuffer -> OnNewOutputBuffer 的耗时,并每秒输出 avg/min/max。

现象:

同一份 H.265 码流、同一份 demo、同样启用低延迟解码,在两台设备上测试结果差异明显:

  • 设备 A:Mate80,平均约 16ms
  • 设备 B:畅享 P90 Pro Max,平均约 10ms

问题:

  1. Mate80 理论上整机性能更强,但 AVCodec 输出回调平均耗时反而更高, 为什么会这样? 是实际上畅享的硬件解码能力本身就更胜一筹吗?
  2. 如果要准确评估 H.265 硬解耗时,推荐的统计点应该放在哪里?

附图:


更多关于HarmonyOS鸿蒙Next中AVCodec H.265 低延迟解码在不同设备上输出回调延迟差异较大,是否为硬解/Surface调度策略差异?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

尊敬的开发者,您好,

解码耗时统计无问题,从写入待解码码流,到获取解码数据之间就可以,建议开发者通过接口判断当前解码类型是否为硬件解码,硬件解码效率更高。

bool isHardware = OH_AVCapability_IsHardware(capability);

更多关于HarmonyOS鸿蒙Next中AVCodec H.265 低延迟解码在不同设备上输出回调延迟差异较大,是否为硬解/Surface调度策略差异?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


解码过程还可以监控下CPU使用率,佐证下。或者DevEco Profiler搞下CPU等的活动分析。

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

PushInputBuffer 到 OnNewOutputBuffer 这段时间不等于纯硬解耗时,它还混了输入排队、解码器内部调度、低延迟策略、Surface 输出队列、线程调度甚至功耗状态。高端机平均值更高,不一定代表硬解能力更弱,可能只是驱动策略、帧同步或 Surface 链路更保守。

建议分层打点:1. input buffer 入队前后;2. OnNewOutputBuffer 回调时间;3. 若走 Surface,再统计帧真正到渲染/显示链路的时间;4. 固定分辨率、码率、GOP、刷新率、电量模式和温度,预热后多轮统计 p50/p95。若想尽量接近纯解码耗时,可先用非显示链路或最小 Surface 消费链路对比,避免把渲染调度误算进解码器。

Mate80(9020芯片) 畅享 P90 Pro Max(8000芯片)

主要原因

  • 解码器架构:麒麟9020可能有更复杂的内部缓冲池、多帧并行处理、后处理流水线 麒麟8000解码路径更直接,帧输出更"即时"
  • AVCodec 回调时机:麒麟9020可能包含帧重排序、格式转换、同步等待等额外环节 麒麟8000解码完成即回调,中间环节少
  • 低延迟模式实现:高端芯片的低延迟可能只是"减少缓冲",而非完全直通 中端芯片可能因架构简单反而更接近直通模式

可以在 MediaCodec/AVCodec的输入入队点和 输出生成点 分别打戳:,

AVCodec H.265 低延迟解码回调延迟差异主要源于硬解芯片的编解码器性能、驱动优化水平以及 Surface 合成器的缓冲区调度策略(如队列深度、Vsync 同步机制)不同。设备间硬件加速能力、渲染管线负载及内存带宽差异也会直接影响回调触发时机。,

设备差异的核心在于你的测量方式:你用 Surface 模式,统计的是 Push 到回调的总耗时,这包含了渲染管线等待,而非纯解码耗时。

1. 为何 Mate80 反而慢? 关键在 OH_MD_KEY_PIXEL_FORMAT 设为 SURFACE_FORMATBuffer 数设为 1。低延时模式下,OnNewOutputBuffer 回调返回时,往往要等 Surface 释放前一帧的 buffer。

  • 两台设备 GPU/显示子系统调度节奏不同:一台可能在 V-Sync 前快速释放,另一台可能卡在合成器节奏上。
  • 这 16ms vs 10ms 的差异,很可能只是反映了两台设备 Surface 释放的节拍差异(如一帧 16.7ms 边界),而与硬解单元解码速度无关。解码器本身速度可能没差别。

2. 准确评估硬解延时 要测纯硬解耗时,必须避开 Surface 释放等待。改用 Buffer 模式,直接取原始 YUV 数据:

  • 配置时设置 OH_MD_KEY_PIXEL_FORMATAV_PIXEL_FORMAT_NV12
  • 同线程 内,Push 后记录时间戳,OnNewOutputBuffer 回调中拿到数据后立即记录结束时间。 这样测出来的差值,才能近似代表从送入码流到核心解码完成的时间,可以排除渲染跟 Surface 调度的影响。
回到顶部