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

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帧缺失了这个数据。

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

2019.8.30

编码端做了修改,客户端无需绕过。验证修改有效。

你可能感兴趣的:(Android,webrtc)