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

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

2024.11.27

做成配置了,下发配置处理。

Vue.js是一个前端框架,而WebRTC(Web Real-Time Communication)是一种HTML5标准,用于实时通信,包括音频、视频和数据传输。要在Vue应用中使用WebRTC并配置HEVC(H.265)编解码,首先需要确保浏览器支持H.265编码,因为并非所有浏览器都内置了对它的支持。 以下是基本步骤: 1. 安装必要的库:如`adapter.js`,它帮助处理跨浏览器兼容性;`vue-peerjs` 或 `vue-webrtc` 等提供WebRTC功能的Vue组件库。 2. 引入和配置:在Vue组件中引入所需的WebRTC API,并设置正确的编解码参数。例如,在`vue-webrtc`中,你可以通过`setCodecPreferences`方法指定首选的编解码: ```javascript import { RTCPeerConnection } from 'vue-webrtc'; export default { data() { return { peerConnection: null, }; }, mounted() { this.peerConnection = new RTCPeerConnection(); this.peerConnection.setCodecPreferences(['avc1.640028', // H.264 'hev1.6.640028']); // H.265 (HEVC) }, }; ``` 3. 添加媒体时设置视频轨道的编解码: ```javascript // 当收到offer或candidate时,更新媒体描述 this.offerAnswerHandler(sdp) { const videoTracks = sdp.media[0].video_tracks; for (const track of videoTracks) { track.codec = 'hev1.6.640028'; // 设置为H.265 } this.updatePeerConnection(sdp); } ``` 请注意,由于H.265编解码的带宽需求较高,如果网络条件不佳,可能会导致视频质量下降或连接不稳定。同时,不是所有的设备都支持H.265,所以在实际项目中需要做适配处理。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值