欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

webrtc 海思芯片解码出错的解决办法

程序员文章站 2022-07-01 15:29:48
...

webrtc-android h264只支持 OMX.ExynosOMX.IntelOMX.NvidiaOMX.qcom 这几个的硬解。不支持软解.
支持软解我做了,记录在这篇博客中。
支持海思芯片的硬解,只要改下 HardwareVideoEncoderFactory::isHardwareSupportedInCurrentSdkH264 修改下白名单即可(增加OMX.hisi )。

这篇文章是增加了开关之后兼容性测试出现了问题的解决办法。

是什么问题呢?

用户观察上表现为卡顿,能收到数据,没有丢包,但是十几帧解一帧。

关键日志有几行(有删节):

I VDEC    : [set_parameter] : [5184] set_parameter:OMX_IndexParamPortDefinition
E VDEC    : [check_port_param] : [5001] set_parameter: invalid buffer count 15, should not be bigger than max count 14
E OMXNodeInstance: setParameter(0xe73aa220:hisi.decoder.avc, ParamPortDefinition(0x2000001)) ERROR: Undefined(0x80001001)
W ACodec  : [OMX.hisi.video.decoder.avc] setting nBufferCountActual to 15 failed: -2147483648

W video_decoder_wrapper.cc: (line 172): Java decoder produced an unexpected frame: -1000
I VDEC    : [empty_this_buffer] : [6698] [ETB] TimeStamp: 47264352000

解决问题的思路有几个

  1. webrtc的mediacodec的设置不对,数据源不对。

    系统软解和软解都可以正常播放

  2. hisi芯片不是完整的支持avc/hevc的解码

    用自己写的demo,发现可以正常播放出来。

  3. 我们的数据流不对

    自己推流,方法见这篇博客:https://blog.csdn.net/yeshennet/article/details/96993036
    可以正常播放。考虑是数据流有问题,请求推流的同学支援了。

  4. webrtc代码中的某个判断逻辑错了

    找了一下,修改方法是这样的:videodecoderwrapper.cc

void VideoDecoderWrapper::OnDecodedFrame(JNIEnv* jni,
                                         jobject jframe,
                                         jobject jdecode_time_ms,
                                         jobject jqp) {
  const jlong capture_time_ns =
      jni->CallLongMethod(jframe, video_frame_get_timestamp_ns_method_);
  FrameExtraInfo frame_extra_info;
  do {
    if (frame_extra_infos_.empty()) {
      LOG(LS_WARNING) << "Java decoder produced an unexpected frame.";
      // --- Modify by Yeshen ... for omx.hisi.video.decoder.avc
      break;
      //return;
      // --- End modify ...
    }

    frame_extra_info = frame_extra_infos_.front();
    frame_extra_infos_.pop_front();
    // If the decoder might drop frames so iterate through the queue until we
    // find a matching timestamp.
  } while (frame_extra_info.capture_time_ns != capture_time_ns);

本质上是什么问题呢?

https://developer.android.com/reference/android/media/MediaCodec.BufferInfo
The presentation timestamp in microseconds for the buffer. This is derived from the presentation timestamp passed in with the corresponding input buffer. This should be ignored for a 0-sized buffer.

我们的数据流过来,通过hisi的解码器,MediaCodec.BufferInfo 中的 presentationTimeUs 丢失了。

但是看描述是必须的,但是P、B帧缺失了这个数据。

至于我们的数据流为啥解析出来会缺少这个字段。
可能是海思有自己的算法;
可能是数据流的编码方式有问题。

相关标签: webrtc