webrtc android native如何開啓硬件加速

在android平臺中開發webrtc相關項目,可以直接使用webrtc提供的java SDK。當然,也可以選擇native的方式來實現。後者相對前者來說,不容易被反編譯。所以我們選擇的後者的開發方式。

要實現硬件加速,在我腦海中出現了兩種方案:
方案一. 通過ffmpeg來實現硬件加速
方案二. 通過webrtc SDK來實現硬件加速

方案一調研:
如果想要實現硬件加速,理論上來說,直接開啓ffmpeg中的硬件加速,即可實現自己想要的功能。但現實並不是那麼簡單,具體看圖(參考來源):
在這裏插入圖片描述
在這裏插入圖片描述
也就是說,如果想要通過ffmpeg在android平臺中來實現硬件加速,只能通過調用MediaCodec API來實現。但可惜的是,ffmpeg只實現了調用MediaCodec API來實現硬件解碼加速,硬件編譯加速並沒能實現。

所以,通過ffmpeg在android平臺中實現硬件編解碼加速,目前無法實現。方案一行不通。

方案二調研

  1. 在java層創建HardwareVideoEncoderFactory與HardwareVideoDecoderFactory類對象
  2. 把以上兩個實例傳遞到native層,在native層通過JavaToNativeVideoEncoderFactory
    和JavaToNativeVideoDecoderFactory把Java類實例轉換成native層實例
    方案二在調研過程中,確實成功了,因爲我使用的測試機是android 9.0。但在真正開發的時候,使用android 8.0及以下手機時,一直報錯(很詭異的錯誤),最終在尋找了兩天BUG後,我放棄了方案二,開始尋找方案三。

方案三
與方案二類似,但不通過android SDK來創建HardwareVideoEncoderFactory及HardwareVideoDecoderFactory實例,而是直接在native層創建兩者的實例。該方案與webrtc源碼中提供的test代碼思路一致(源碼太多,test代碼找了好久才找到,否則也沒有方案一和方案二的調研了,test代碼src/modules/video_coding/codecs/test/android_codec_factory_helper.cc)源碼如下:

std::unique_ptr<VideoEncoderFactory> CreateAndroidEncoderFactory() {
  JNIEnv* env = AttachCurrentThreadIfNeeded();
  ScopedJavaLocalRef<jclass> factory_class =
      GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
  jmethodID factory_constructor = env->GetMethodID(
      factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
  ScopedJavaLocalRef<jobject> factory_object(
      env, env->NewObject(factory_class.obj(), factory_constructor,
                          nullptr /* shared_context */,
                          false /* enable_intel_vp8_encoder */,
                          true /* enable_h264_high_profile */));
  return JavaToNativeVideoEncoderFactory(env, factory_object.obj());
}

std::unique_ptr<VideoDecoderFactory> CreateAndroidDecoderFactory() {
  JNIEnv* env = AttachCurrentThreadIfNeeded();
  ScopedJavaLocalRef<jclass> factory_class =
      GetClass(env, "org/webrtc/HardwareVideoDecoderFactory");
  jmethodID factory_constructor = env->GetMethodID(
      factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;)V");
  ScopedJavaLocalRef<jobject> factory_object(
      env, env->NewObject(factory_class.obj(), factory_constructor,
                          nullptr /* shared_context */));
  return JavaToNativeVideoDecoderFactory(env, factory_object.obj());
}

柳暗花明,方案三終於實現了在android下的硬件加速了。不過測試結果發現,H.264硬編效果不及軟編。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章