使用Webrtc h264支持为Android构建Chromium

时间:2019-11-23 00:57:32

标签: android webrtc chromium

我正在尝试在webrtc中构建具有h264支持的Chromium Android。我的理解是,以下args.gn文件应该可以执行我想要的操作。

target_os = "android"
target_cpu = "arm64"
proprietary_codecs = true
ffmpeg_branding = "Chrome"

但是,当我在Pixel 3上安装APK时,请使用chrome:// inspect从我的桌面上调试并运行new RTCPeerConnection().createOffer({offerToReceiveVideo: true}).then(s => console.log(s.sdp)),我只会看到VP8和VP9编解码器。

还有什么我想念的吗?

1 个答案:

答案 0 :(得分:0)

我最终不得不更改代码以获得所需的行为。

设置这些构建标志会使GPU进程对任何查询https://cs.chromium.org/chromium/src/media/gpu/android/media_codec_video_decoder.cc?q=proprietary_codecs&sq=package:chromium&dr=C&l=154回答“是,我支持H264视频解码”

但是,webrtc支持的编解码器的定义来自此函数,该函数只是轮询编码器支持的格式。 https://webrtc.googlesource.com/src/+/refs/heads/master/media/engine/webrtc_video_engine.cc#142。因此看来,尽管我的Pixel 3支持H264解码,但它不支持编码,因此webrtc认为它是不受支持的格式。有趣的是,在完全相同的设备上运行的Chrome确实支持webrtc H264。

我只希望接收H264视频,因此我编辑了此功能,以便为Chrome支持的每种H264格式添加一个webrtc :: SdpVideoFormat。

+static void AddH264Formats(std::vector<webrtc::SdpVideoFormat>& formats) {
+  webrtc::SdpVideoFormat h264Format(kH264CodecName, {
+    {cricket::kH264FmtpLevelAsymmetryAllowed, "1"}});
+
+  h264Format.parameters[cricket::kH264FmtpProfileLevelId] = "42001f";
+  h264Format.parameters[cricket::kH264FmtpPacketizationMode] = "1";
+  if(std::find(formats.begin(), formats.end(), h264Format) == formats.end()) {
+    formats.push_back(h264Format);
+  }
+  h264Format.parameters[cricket::kH264FmtpPacketizationMode] = "0";
+  if(std::find(formats.begin(), formats.end(), h264Format) == formats.end()) {
+    formats.push_back(h264Format);
+  }
+
+  h264Format.parameters[cricket::kH264FmtpProfileLevelId] = "42e01f";
+  h264Format.parameters[cricket::kH264FmtpPacketizationMode] = "1";
+  if(std::find(formats.begin(), formats.end(), h264Format) == formats.end()) {
+    formats.push_back(h264Format);
+  }
+  h264Format.parameters[cricket::kH264FmtpPacketizationMode] = "0";
+  if(std::find(formats.begin(), formats.end(), h264Format) == formats.end()) {
+    formats.push_back(h264Format);
+  }
+
+  h264Format.parameters[cricket::kH264FmtpProfileLevelId] = "4d0032";
+  h264Format.parameters[cricket::kH264FmtpPacketizationMode] = "1";
+  if(std::find(formats.begin(), formats.end(), h264Format) == formats.end()) {
+    formats.push_back(h264Format);
+  }
+  h264Format.parameters[cricket::kH264FmtpPacketizationMode] = "0";
+  if(std::find(formats.begin(), formats.end(), h264Format) == formats.end()) {
+    formats.push_back(h264Format);
+  }
+}
+
 std::vector<VideoCodec> AssignPayloadTypesAndDefaultCodecs(
     const webrtc::VideoEncoderFactory* encoder_factory) {
-  return encoder_factory ? AssignPayloadTypesAndDefaultCodecs(
-                               encoder_factory->GetSupportedFormats())
-                         : std::vector<VideoCodec>();
+  auto formats = encoder_factory->GetSupportedFormats();
+  AddH264Formats(formats);
+
+  return AssignPayloadTypesAndDefaultCodecs(formats);
 }

我认为我可以编辑GpuVideoAcceleratorFactoriesImpl::GetVideoEncodeAcceleratorSupportedProfiles,而不是编辑webrtc代码。以这种方式编辑GpuVideoAcceleratorFactoriesImpl可能不太正确,但是它使我可以派生Chromium,而不必弄乱第三方存储库。