Let WEBRTC support H264 codec

Source: Internet
Author: User

Recently experiment how to let WEBRTC support H264 code, record, for people who need reference.

To illustrate, I was compiling the WebRTC under Ubuntu Server 14.04, using the native (c + +) API to develop WebRTC applications. So my adjustments are based on the native code.

The end result is that the browser can send a video with H264 or receive H264 video.

Note that WebRTC uses OpenH264 to do encoder (see h264_encoder_impl.cc), using FFmpeg to do decoder (see h264_decoder_impl.cc).

Code version

This article corresponds to the code is February 8, 2017, you can use gclient revinfo -a to view the specific version, as follows:

Compilation option Adjustment

WEBRTC can support H264, but it is not turned on by default when compiling under Linux.

rtc_use_h264, this switch controls whether to use H264 (the macro webrtc_use_h264 in the corresponding C + + code), defined in the Webrtc/webrtc.gni file:

rtc_use_h264 = proprietary_codecs && !is_android && !is_ios

Proprietary_codecs is defined in Build/config/features.gni:

proprietary_codecs = is_chrome_branded || is_chromecast

I compile under Linux, branded default is Chromium, so, proprietary_codecs default is False.

Want to go, had to pass GN Gen when passed into the args to adjust the more convenient, use the following command to generate the Ninja build file:

gn gen out/h264Debug --args="proprietary_codecs=true"

Once executed, you can use the following command to verify:

gn args out/h264Debug --list=proprietary_codecsgn args out/h264Debug --list=rtc_use_h264

Seeing that current Value is true indicates that this option is already in effect.

Open rtc_use_h264, OpenH264 encoding support will be enabled.

WEBRTC internal will use FFmpeg to decode H264 (see h264_decoder_impl.cc), ffmpeg associated with an option--rtc_initialize_ffmpeg, this also must be true, otherwise ffmpeg av The codec will not initialize and cannot be used.

The RTC_INITIALIZE_FFMPEG definition is defined in Webrtc/webrtc.gni:

rtc_initialize_ffmpeg = !build_with_crhome

Because we compile for native development, build_with_chrome defaults to False, so rtc_initialize_ffmpeg defaults to true without adjustment.

The rtc_initialize_ffmpeg switch corresponds to a macro webrtc_initialize_ffmpeg in a C + + code.

To use FFmpeg's H264 decoder feature, you also need to modify a macro: Ffmpeg_h264_decoder. In the Config.h file, the path is third_party/chromium/config/chromium/linux/x64 . The original definition is as follows:

#define CONFIG_H264_DECODER 0

Change to 1. This avcodec_register_all() way the H264 decoder is registered in the system.

Wait, there is actually a part of the very important work to be done. Because Linux compiles WEBRTC, the default generated ninja build file, there is no ffmpeg h264 decoder corresponding source code, so even if you open the Ffmpeg_h264_decoder does not work, you have to modify third_party/f Fmpeg/ffmpeg_generated.gni file, find the conditions that contain the H264 and open it.

Note: Because I did not open H264 support at the beginning of the compilation, after the Ffmpeg_generated.gni file was modified, a new directory was specified with the GN Gen Generation Ninja build file, and then the FFmpeg related Ninja file (three) was copied to The original build directory, and then use the Ninja ffmpeg command to compile the so file.

Order Adjustment of Codec

When a Web page uses WebRTC to send an SDP, the default codec order is:

    1. VP8
    2. VP9
    3. H264

In C + + code, the first one to match is selected by default (from PeerConnection::CreateAnswer/SetRemoteDescription two methods, you can see). So, we're going to modify the C + + code to change this selection logic.

WebRtcVideoChannel2 (webrtcvideoengine2.cc) used by codec, from The Internalencoderfactory Class (internalencoderfactory.cc), either as the sender or receiver, is encoded in this form.

In the Internalencoderfactory constructor, you can adjust the order of the codec, the default code is as follows:

supported_codecs_.push_back(cricket::VideoCodec(kVp8CodecName));if (webrtc::VP9Encoder::IsSupported())  supported_codecs_.push_back(cricket::VideoCodec(kVp9CodecName));if (webrtc::H264Encoder::IsSupported()) {  cricket::VideoCodec codec(kH264CodecName);  // TODO(magjed): Move setting these parameters into webrtc::H264Encoder  // instead.  codec.SetParam(kH264FmtpProfileLevelId,                 kH264ProfileLevelConstrainedBaseline);  codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");  supported_codecs_.push_back(std::move(codec));}supported_codecs_.push_back(cricket::VideoCodec(kRedCodecName));supported_codecs_.push_back(cricket::VideoCodec(kUlpfecCodecName));....

Just adjust the H264 codec to the front.

Made this adjustment, Native app as one end of the sending video, in the SDP negotiation, H264 support will be placed in front, the other end if support H264 decoding, will prefer H264 format, on both sides can be H264 to interactive video stream.

When the browser acts as one end of the sending video, the order in which it sends the video format is VP8, VP9, h264,native C + + code that adjusts the order of the local codec in this order, and the code is in mediasession.cc:

Template <class c>static void negotiatecodecs (const std::vector<c>& Local_codecs,  Const std::vector<c>& Offered_codecs, std::vector<c>* negotiated_codecs) {    for (const c& ours:local_codecs) {C theirs; Note that we intentionally only find one matching codec for each of our//local codecs, in case the remote offer CO    Ntains duplicate codecs.      if (Findmatchingcodec (Local_codecs, Offered_codecs, Ours, &theirs)) {C negotiated = ours; Negotiated.      Intersectfeedbackparams (theirs);        if (Isrtxcodec (negotiated)) {Const Auto Apt_it = Theirs.params.find (Kcodecparamassociatedpayloadtype);        Findmatchingcodec shouldn ' t return something with no apt value.        Rtc_dcheck (Apt_it! = Theirs.params.end ()); Negotiated.      SetParam (Kcodecparamassociatedpayloadtype, Apt_it->second);  } if (Codecnameseq (Ours.name.c_str (), kh264codecname)) {      Webrtc::h264::generateprofilelevelidforanswer (Ours.params, Theirs.params, &negotiated.params);      } negotiated.id = Theirs.id;      Negotiated.name = Theirs.name;    Negotiated_codecs->push_back (Std::move (negotiated)); }}//Rfc3264:although the Answerer list the formats in their desired//order of preference, it is RECOMMENDED t Hat unless there is a//specific reason, the Answerer list formats in the same relative order//They were present in T  He offer.  Std::unordered_map<int, int> payload_type_preferences;  int preference = static_cast<int> (Offered_codecs.size () + 1);  for (const c& codec:offered_codecs) {payload_type_preferences[codec.id] = preference--; } std::sort (Negotiated_codecs->begin (), Negotiated_codecs->end (), [&payload_type_preferences] (const c& A, const c& b) {return payload_type_preferences[a.id] > Payload_type_prefe  Rences[b.id];          });} 

The final sort call, which adjusts the order of the decoding formats we support, is based on the codec order of the sending side. So, we also need to modify this here, to remove the sorted parts, or to H264 to remove.

Re-compiling

You can compile a specific module by using the following command:

ninja pc (针对 mediasession.cc )ninja media (针对 internalencoderfactory.cc 和 webrtcvideoengine2.cc )ninja ffmpeg (针对 ffmpeg )

Then compile your own native app.

Related reading:

    • WEBRTC Study Material Daquan
    • Ubuntu 14.04 under compilation WebRTC
    • How to use Turnserver in WEBRTC source code
    • Open the WebRTC log (native API)

Let WEBRTC support H264 codec

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.