webrtc-m79-msvc compile H264

0 is written in front

The main reference of this article: webrtc 4577 version vs compilation_tusong86’s blog-CSDN blog

4577 is m93. Due to different source code versions, there may be certain discrepancies and can be modified according to the actual situation;

Thanks to the author for his contribution;

1 Compilation parameters

Powershell runs:

// debug requires compilation parameter enable_iterator_debugging=true

gn gen h264-debug-m79 –args=’is_debug=true use_lld=false is_clang=false treat_warnings_as_errors=false use_custom_libcxx=false is_component_build=false use_rtti=true rtc_enable_protobuf=false rtc_build_examples=true enable_iterator_debugging=true rtc_use_h264=true use_openh264=true ffmpeg_branding=”Chrome” proprietary_codecs=true‘ –ide=vs2019

Check whether the parameters are effective:

gn args h264-debug-m79 –list=rtc_use_h264

gn args h264-debug-m79 –list=use_openh264

//release does not require compilation parameters enable_iterator_debugging=true

gn gen h264-release-m79 –args=’is_debug=false use_lld=false is_clang=false treat_warnings_as_errors=false use_custom_libcxx=false is_component_build=false use_rtti=true rtc_enable_protobuf=false rtc_build_examples=true rtc_use_h264=true use_openh264=true ffmpeg_branding=”Chrome” proprietary_codecs=true’ –ide=vs2019

Check whether the parameters are effective:

gn args h264-release-m79 –list=rtc_use_h264

gn args h264-release-m79 –list=use_openh264

In order to avoid the problem in section 2.3 below, the compilation parameters of webrtc need to be modified to MD(d). The specific modifications are as follows:

2 Compilation errors and repairs

2.1 Error 1

solution:

Comment out the code:

See: bugs.webrtc.org/9213#c13

The specific modifications are as follows:

2.2 Error 2

solution:

Comment out the last line of \third_party\ffmpeg\libavcodec\pcm.c, as shown below:

2.3 Mistake Three

2.3.1 Problem description

To solve this problem, you need to use the x64 ffmpeg dynamic library compiled by your own MSVC. How to compile the ffmpeg dynamic library can use the reference link [2]. I encountered some problems during the attempt:

(1) Many problems arise when compiling ffmpeg using MT(d), so MD(d) is still used to compile ffmpeg. However, webrtc compiles by default MT(d), so webrtc needs to be modified to MD. (d), the modification method is detailed above;

(2) When using ffmpeg_deps.sln to generate a library, be sure to choose to compile dynamic library. When using ffmpeg static library, symbol redefinition problems will occur, as follows:

The reason is that the third-party library that webrtc relies on also uses libvp8 (highbd_variance_sse2.obj), and ffmpeg’s static library libavcodec.lib also contains the definition of highbd_variance_sse2.obj, so there is a conflict. The arguments are as follows:

Evidence in webrtc:

2.3.2 Solution steps

Assuming that the dynamic library of ffmpeg has been prepared, the subsequent steps are as follows:

2.3.2.1 Copy files

Copy the file as shown below generated by ffmpeg_deps.sln to the specified directory of webrtc, as follows:

The D:\webrtc-checkout\src\third_party\ffmpeg_smp_release_x64 directory is newly created to distinguish it from the previous ffmpeg;

Copy dynamic library files:

Copy header files:

2.3.2.2 Modify gn file

Modify the D:\webrtc-checkout\src\modules\video_coding\BUILD.gn file

The modifications are listed below:

rtc_static_library(“webrtc_h264”) {
visibility = [ “*” ]
sources = [
“codecs/h264/h264.cc”,
“codecs/h264/h264_color_space.cc”,
“codecs/h264/h264_color_space.h”,
“codecs/h264/h264_decoder_impl.cc”,
“codecs/h264/h264_decoder_impl.h”,
“codecs/h264/h264_encoder_impl.cc”,
“codecs/h264/h264_encoder_impl.h”,
“codecs/h264/include/h264.h”,
]

if (!is_clang) {
#Set header file path
include_dirs = [ “//third_party/ffmpeg_smp_release_x64/include” ]
libs = [
# Set reference library
“//third_party/ffmpeg_smp_release_x64/bin/avcodec.lib”,
“//third_party/ffmpeg_smp_release_x64/bin/avdevice.lib”,
“//third_party/ffmpeg_smp_release_x64/bin/avfilter.lib”,
“//third_party/ffmpeg_smp_release_x64/bin/avformat.lib”,
“//third_party/ffmpeg_smp_release_x64/bin/avutil.lib”,
“//third_party/ffmpeg_smp_release_x64/bin/swresample.lib”,
“//third_party/ffmpeg_smp_release_x64/bin/swscale.lib”,
]
}

defines = []
deps = [
“:video_codec_interface”,
“:video_coding_utility”,
“../../api/video:video_frame”,
“../../api/video:video_frame_i010”,
“../../api/video:video_frame_i420”,
“../../api/video:video_rtp_headers”,
“../../api/video_codecs:video_codecs_api”,
“../../common_video”,
“../../media:rtc_h264_profile_id”,
“../../media:rtc_media_base”,
“../../rtc_base”,
“../../rtc_base:checks”,
“../../rtc_base/system:rtc_export”,
“../../system_wrappers:field_trial”,
“../../system_wrappers:metrics”,
“//third_party/abseil-cpp/absl/strings”,
“//third_party/abseil-cpp/absl/types:optional”,
“//third_party/libyuv”,
]

if (rtc_use_h264) {
deps + = [
#”//third_party/ffmpeg”,
“//third_party/openh264:encoder”,
]
if (!build_with_mozilla) {
deps + = [ “../../media:rtc_media_base” ]
}
}
}

Although it can be compiled successfully so far, there are still other problems. Although it has been replaced with the x64 dynamic library of ffmpeg compiled by myself, the header file referenced in the webrtc code is still the path of the previous ffmpeg. If it is not modified, It will crash when running, so the source code needs to be modified. See section 2.3.2.3 for details;

2.3.2.3 Modify the reference to the ffmpeg header file in the webrtc source code

At this point, all exes can be compiled and passed, but it is not possible to use peerconnection_client.exe to verify the function of H264. SDP needs to be modified to increase the priority of H264;

Notice:

Due to the problem with the ffmpeg version I am using (the version of ffmpeg is too new compared to the code of webrtc-m79), there is also a problem with avcodec_find_decoder, because avcodec_find_decoder now returns const AVCodec*, which is not available in webrtc-m79 Forced type conversion leads to compilation errors, and a simple modification is required:

Will

AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);

change into:

AVCodec* codec = const_cast(avcodec_find_decoder(av_context_->codec_id));

3 Increase H264 priority

The modified code is as follows:

std::vector<SdpVideoFormat> InternalEncoderFactory::GetSupportedFormats()
    const {
  std::vector<SdpVideoFormat> supported_codecs;
  for (const webrtc::SdpVideoFormat & amp; format : webrtc::SupportedH264Codecs())
    supported_codecs.push_back(format);
  supported_codecs.push_back(SdpVideoFormat(cricket::kVp8CodecName));
  for (const webrtc::SdpVideoFormat & amp; format : webrtc::SupportedVP9Codecs())
    supported_codecs.push_back(format);
  return supported_codecs;
}

4 Two peerconnection_clients for verification

Run peerconnection_client.exe, don’t forget to copy the dynamic libraries it depends on:

The test results are as follows:

5 Web terminal and peerconnection_client test

If you use web and peerconnection_client for testing, you need to note that if the web end sends an offer to start the media negotiation process, the transmission at this time is still VP8 encoding, because:

The web-side offer describes that the highest priority it receives is VP8. The peerconnection_client receiving the offer will call SelectSendVideoCodecs in WebRtcVideoChannel::GetChangedSendParameters to compare the encoding it can provide with the encoding expected by the offer, and will give priority to matching the higher priority in the offer. Level VP8 encoding, in the code I modified in InternalEncoderFactory::GetSupportedFormats, I just increased the priority of H264 (((This increase in the priority of H264 can allow the opposite end to match first when this end serves as the offer end. This encoding))), later added support for VP8 and VP9, so when the highest priority VP8 on the offer side can be supported by the opposite end, the VP8 format will be preferred to match the offer side ; It is precisely for this reason that this problem will not occur when using two peerconnection_clients for testing, because both set the receiving H264 to the highest priority;

Of course, if peerconnection_client.exe sends an offer to start the media negotiation process, this problem will not exist, because H264 is the video encoding format it receives with the highest priority.

Reference link

[1] webrtc 4577 version vs compilation_tusong86’s blog-CSDN blog

[2] Create ffmpeg vs2019 project_hclbeloved’s blog-CSDN blog