简体   繁体   中英

Building Chromium for Android with Webrtc h264 support

I'm trying to build Chromium Android with h264 support in webrtc. My understanding is that the following args.gn file should do what I want.

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

However, when I install the APK on my Pixel 3, use chrome://inspect to debug from my desktop and run new RTCPeerConnection().createOffer({offerToReceiveVideo: true}).then(s => console.log(s.sdp)) I only see VP8 and VP9 codecs.

Is there anything else I'm missing?

I ended up having to change the code to get the behavior I wanted.

Setting these build flags causes the GPU process to answer, "Yes, I support H264 video decoding" to any queries https://cs.chromium.org/chromium/src/media/gpu/android/media_codec_video_decoder.cc?q=proprietary_codecs&sq=package:chromium&dr=C&l=154

However, webrtc's definition of supported codecs comes from this function which is simply polling the formats supported by the encoder. https://webrtc.googlesource.com/src/+/refs/heads/master/media/engine/webrtc_video_engine.cc#142 . So it appears that although my Pixel 3 supports H264 decoding it doesn't support encoding and so webrtc considers it an unsupported format. Interestingly, Chrome running on the exact same device does support webrtc H264.

I'm only looking to receive H264 video so I edited this function to add a webrtc::SdpVideoFormat for each H264 format that Chrome supports.

+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);
 }

Instead of editing the webrtc code I think I may edit GpuVideoAcceleratorFactoriesImpl::GetVideoEncodeAcceleratorSupportedProfiles . Editing the GpuVideoAcceleratorFactoriesImpl this way may be less correct but it would allow me to fork Chromium without having to mess with third_party repositories.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM