Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit efc1379

Browse files
jianjunztaste1981
andauthored
External ffmpeg support (#695)
* Do not use internal ffmpeg for client SDK build. By default we should not build ffmpeg for client SDK. If you need to use ffmpeg for d3d11va decoding, you need to specify owt_ffmpeg_header_root gn arg which points to the source root of external ffmpeg, so the build process can find ffmpeg headers there. Your application needs to explicitly link to ffmpeg libraries, which includes but not limited to avutil.lib, avcodec.lib & avformat.lib. * Update scripts for external FFmpeg. * Roll WebRTC revision. * Limit d3d11va_h264_decoder to Windows only. --------- Co-authored-by: Johny Qiu <[email protected]>
1 parent a9272f2 commit efc1379

File tree

8 files changed

+71
-39
lines changed

8 files changed

+71
-39
lines changed

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ deps = {
9898
Var('chromium_git') + '/chromium/src/third_party' + '@' + 'cd30703e732f3436f72f63c13f16ebb19803ddd6',
9999
# WebRTC-only dependencies (not present in Chromium).
100100
'src/third_party/webrtc':
101-
Var('deps_owt_git') + '/owt-deps-webrtc' + '@' + '1f8b8174fdf33ea954ce2afcedd24f73ca0ef759',
101+
Var('deps_owt_git') + '/owt-deps-webrtc' + '@' + '15bb85d7886c653bba004f2b2826bc471d07fd96',
102102
# Gradle 4.3-rc4. Used for testing Android Studio project generation for WebRTC.
103103
'src/third_party/webrtc/examples/androidtests/third_party/gradle': {
104104
'url': Var('chromium_git') + '/external/github.com/gradle/gradle.git' + '@' +

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ target_os = []
6464
Common build options shared by Windows and Linux:
6565
- By default `x86|Debug` library will be created. Specify `--arch x64` if you want to build x64 libraries; Specify `--scheme release` if release version of library is to be built.
6666
- The built binary will be under path specified by `--output_path`. If `--output_path` is not set, the built binary will be under `src/out` directory.
67-
- The optional `--ssl_root` should be set to the root directory of lastest OpenSSL 3.0 series directory. If specified, build tool will search external OpenSSL headers in `ssl_root/include` and OpenSSL binaries in `ssl_root/lib`. But binaries are not included in OWT SDK, so applications still need to link libcrypto and libssl.
6867
- The argument `--sio_root` should be set to the root directory of Socket.IO cpp 3.x SDK, with headers in `include` sub-folder, libsioclient_tls.a in `lib` sub-folder.
68+
- The optional `--ssl_root` should be set to the root directory of lastest OpenSSL 3.0 series directory. If specified, build tool will search external OpenSSL headers in `ssl_root/include` and OpenSSL binaries in `ssl_root/lib`. But binaries are not included in OWT SDK, so applications still need to link libcrypto and libssl.
69+
- The optional `--ffmpeg_root` should be set to the root directory of FFmpeg, with headers in `include` sub-folder, and libs in `lib` sub-folder. Binary libraries are not necessary for building OWT SDK, but it's needed by your application or tests when this argument is specified. If this argument is not specified, FFmpeg will not be used. If neither `--ffmpeg_root` nor `--msdk_root` is specified, and external decoder doesn't support H.264, GN arg `rtc_use_h264` should be set to `false`, otherwise, a runtime error will occur.
6970
- Use `--gn_gen` to generate args.gn during the first build or when you change either `ssl_root`/`msdk_root` options.
7071
- The optional `--tests` will trigger unit tests after build.
7172
- Run `build*.py` with `--help` for argument description.
@@ -79,7 +80,6 @@ Update to latest macOS and Xcode. iOS SDK can only be built on macOS.
7980
#### Android
8081
This branch doesn't support Android build. owt-client-android depends on 5.0.x branch of this repository.
8182

82-
8383
## How to contribute
8484
We warmly welcome community contributions to the owt-client-native repository. If you are willing to contribute your features and ideas to OWT, follow the process below:
8585

scripts/build-win.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
'''Script to build WebRTC libs on Windows.
66
7-
It builds OWT Windows SDK library which includes WebRTC lib, OWT base, p2p and conference
8-
lib.
7+
This script is a shortcut for building OWT Windows SDK library which includes
8+
WebRTC lib, OWT base, p2p and conference lib. It doesn't cover all
9+
configurations. Please update GN args and use ninja build manually if you have
10+
special configurations.
911
1012
Output lib is located in out/owt-debug(release).lib.
1113
'''
@@ -24,20 +26,15 @@
2426
NONPARALLEL_TEST_TARGET_LIST = ['webrtc_nonparallel_tests']
2527

2628
GN_ARGS = [
27-
'rtc_use_h264=true',
28-
'ffmpeg_branding="Chrome"',
29-
'rtc_use_h265=true',
3029
'is_component_build=false',
3130
'use_lld=false',
3231
'enable_libaom=true',
3332
'rtc_build_examples=false',
3433
'treat_warnings_as_errors=false',
35-
# <stdatomic.h> is not yet supported when compiling as C.
36-
'ffmpeg_use_unsafe_atomics=true',
3734
]
3835

3936

40-
def gngen(arch, sio_root, ssl_root, msdk_root, quic_root, scheme, tests, runtime, cloud_gaming):
37+
def gngen(arch, sio_root, ffmpeg_root, ssl_root, msdk_root, quic_root, scheme, tests, runtime, cloud_gaming):
4138
gn_args = list(GN_ARGS)
4239
gn_args.append('target_cpu="%s"' % arch)
4340
using_llvm = False
@@ -89,6 +86,12 @@ def gngen(arch, sio_root, ssl_root, msdk_root, quic_root, scheme, tests, runtime
8986
if sio_root:
9087
# If sio_root is not specified, conference SDK is not able to build.
9188
gn_args.append('owt_sio_header_root="%s"' % (sio_root + r'\include'))
89+
if ffmpeg_root:
90+
gn_args.append('owt_ffmpeg_header_root="%s"'%(ffmpeg_root+r'\include'))
91+
if ffmpeg_root or msdk_root or cloud_gaming:
92+
gn_args.append('rtc_use_h264=true')
93+
if msdk_root or cloud_gaming:
94+
gn_args.append('rtc_use_h265=true')
9295
flattened_args = ' '.join(gn_args)
9396
ret = subprocess.call(['gn.bat', 'gen', getoutputpath(arch, scheme), '--args=%s' % flattened_args],
9497
cwd=HOME_PATH, shell=False)
@@ -173,6 +176,7 @@ def main():
173176
parser.add_argument('--msdk_root', help='Path for MSDK.')
174177
parser.add_argument('--quic_root', help='Path to QUIC library. Not supported yet.')
175178
parser.add_argument('--sio_root', required=False, help='Path to Socket.IO cpp. Headers in include sub-folder, libsioclient_tls.a in lib sub-folder.')
179+
parser.add_argument('--ffmpeg_root', required=False, help='Path to to root directory of FFmpeg, with headers in include sub-folder, and libs in lib sub-folder. Binary libraries are not necessary for building OWT SDK, but it is needed by your application or tests when this argument is specified.')
176180
parser.add_argument('--scheme', default='debug', choices=('debug', 'release'),
177181
help='Schemes for building. Supported value: debug, release')
178182
parser.add_argument('--gn_gen', default=False, action='store_true',
@@ -202,7 +206,7 @@ def main():
202206
print('Invalid quic_root')
203207
return 1
204208
if opts.gn_gen:
205-
if not gngen(opts.arch, opts.sio_root, opts.ssl_root, opts.msdk_root, opts.quic_root,
209+
if not gngen(opts.arch, opts.sio_root, opts.ffmpeg_root, opts.ssl_root, opts.msdk_root, opts.quic_root,
206210
opts.scheme, opts.tests, opts.runtime, opts.cloud_gaming):
207211
return 1
208212
if opts.sdk:

scripts/build_linux.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
'''Script to build WebRTC libs on Linux.
66
7-
It builds OWT Linux SDK library which includes WebRTC lib, OWT base, p2p and conference
8-
lib.
7+
This script is a shortcut for building OWT Linux SDK library which includes
8+
WebRTC lib, OWT base, p2p and conference lib. It doesn't cover all
9+
configurations. Please update GN args and use ninja build manually if you have
10+
special configurations.
911
1012
Output lib is located in out/owt-debug(release).a.
1113
'''
@@ -24,16 +26,9 @@
2426
PARALLEL_TEST_TARGET_LIST = ['rtc_unittests', 'video_engine_tests']
2527

2628
GN_ARGS = [
27-
'rtc_use_h264=true',
28-
'rtc_use_h265=true',
2929
'enable_libaom=true',
3030
'is_component_build=false',
3131
'rtc_build_examples=false',
32-
# When is_clang is false, we're not using sysroot in tree.
33-
'use_sysroot=false',
34-
# For Linux build we expect application built with gcc/g++. Set SDK to use
35-
# the same toolchain.
36-
'is_clang=false',
3732
# Upstream only officially supports clang, so we need to suppress warnings
3833
# to avoid gcc/g++ specific build errors.
3934
'treat_warnings_as_errors=false',
@@ -45,7 +40,7 @@ def gen_lib_path(scheme):
4540
out_lib = OUT_LIB % {'scheme': scheme}
4641
return os.path.join(HOME_PATH + r'/out', out_lib)
4742

48-
def gngen(arch, sio_root, ssl_root, msdk_root, quic_root, scheme, tests, use_gcc, fake_audio, shared, cloud_gaming):
43+
def gngen(arch, sio_root, ffmpeg_root, ssl_root, msdk_root, quic_root, scheme, tests, use_gcc, fake_audio, shared, cloud_gaming):
4944
gn_args = list(GN_ARGS)
5045
gn_args.append('target_cpu="%s"' % arch)
5146
if scheme == 'release':
@@ -68,20 +63,19 @@ def gngen(arch, sio_root, ssl_root, msdk_root, quic_root, scheme, tests, use_gcc
6863
msdk_lib = msdk_root + r'/lib64'
6964
else:
7065
return False
71-
gn_args.append('owt_msdk_header_root="%s"' % (msdk_root + r'/include'))
66+
gn_args.append('owt_msdk_header_root="%s"' % (msdk_root + '/include'))
7267
gn_args.append('owt_msdk_lib_root="%s"' % msdk_lib)
7368
else:
7469
print('msdk_root is not set.')
7570
if quic_root:
76-
gn_args.append('owt_quic_header_root="%s"' % (quic_root + r'\include'))
71+
gn_args.append('owt_quic_header_root="%s"' % (quic_root + '/include'))
7772
if scheme == 'release':
78-
quic_lib = quic_root + r'\bin\release'
73+
quic_lib = quic_root + '/bin/release'
7974
elif scheme == 'debug':
80-
quic_lib = quic_root + r'\bin\debug'
75+
quic_lib = quic_root + '/bin/debug'
8176
else:
8277
return False
8378
gn_args.append('owt_use_quic=true')
84-
8579
if tests:
8680
gn_args.append('rtc_include_tests=true')
8781
gn_args.append('owt_include_tests=true')
@@ -96,11 +90,14 @@ def gngen(arch, sio_root, ssl_root, msdk_root, quic_root, scheme, tests, use_gcc
9690
gn_args.extend(['rtc_enable_protobuf=false', 'is_component_build=true'])
9791
else:
9892
gn_args.extend(['is_component_build=false'])
99-
ffmpeg_branding_name = "Chrome"
10093
if cloud_gaming:
101-
ffmpeg_branding_name = "OWT"
10294
gn_args.extend(['owt_cloud_gaming=true'])
103-
gn_args.append('ffmpeg_branding="%s"' % ffmpeg_branding_name)
95+
if ffmpeg_root:
96+
gn_args.append('owt_ffmpeg_header_root="%s"'%(ffmpeg_root+'/include'))
97+
if ffmpeg_root or msdk_root or cloud_gaming:
98+
gn_args.append('rtc_use_h264=true')
99+
if msdk_root or cloud_gaming:
100+
gn_args.append('rtc_use_h265=true')
104101

105102
flattened_args = ' '.join(gn_args)
106103
out = 'out/%s-%s' % (scheme, arch)
@@ -184,6 +181,7 @@ def main():
184181
help='Target architecture. Supported value: x86, x64')
185182
parser.add_argument('--ssl_root', help='Path for OpenSSL.')
186183
parser.add_argument('--sio_root', required=False, help='Path to Socket.IO cpp. Headers in include sub-folder, libsioclient_tls.a in lib sub-folder.')
184+
parser.add_argument('--ffmpeg_root', required=False, help='Path to to root directory of FFmpeg, with headers in include sub-folder, and libs in lib sub-folder. Binary libraries are not necessary for building OWT SDK, but it is needed by your application or tests when this argument is specified.')
187185
parser.add_argument('--msdk_root', help='Path for MSDK.')
188186
parser.add_argument('--quic_root', help='Path to QUIC library')
189187
parser.add_argument('--scheme', default='debug', choices=('debug', 'release'),
@@ -207,7 +205,7 @@ def main():
207205
print("sio_root is missing.")
208206
return 1
209207
if opts.gn_gen:
210-
if not gngen(opts.arch, opts.sio_root, opts.ssl_root, opts.msdk_root, opts.quic_root, opts.scheme, opts.tests, opts.use_gcc, opts.fake_audio, opts.shared, opts.cloud_gaming):
208+
if not gngen(opts.arch, opts.sio_root, opts.ffmpeg_root, opts.ssl_root, opts.msdk_root, opts.quic_root, opts.scheme, opts.tests, opts.use_gcc, opts.fake_audio, opts.shared, opts.cloud_gaming):
211209
return 1
212210
if opts.sdk:
213211
if not ninjabuild(opts.arch, opts.scheme, opts.shared):

talk/owt/BUILD.gn

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ declare_args() {
1212
owt_msdk_lib_root = ""
1313
owt_msdk_header_root = ""
1414
owt_sio_header_root = ""
15+
owt_ffmpeg_header_root = ""
1516
}
1617

1718
# Introduced for using libvpx config files. We only enable libvpx rate
@@ -234,6 +235,11 @@ static_library("owt_sdk_base") {
234235
if (rtc_include_internal_audio_device) {
235236
defines += [ "WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE" ]
236237
}
238+
239+
if (owt_ffmpeg_header_root != "") {
240+
include_dirs += [ owt_ffmpeg_header_root ]
241+
}
242+
237243
if (rtc_use_x11) {
238244
defines += [ "WEBRTC_USE_X11" ]
239245
}
@@ -347,6 +353,17 @@ static_library("owt_sdk_base") {
347353
"sdk/base/linux/videorenderlinux.h",
348354
]
349355
}
356+
357+
if (owt_ffmpeg_header_root != "") {
358+
if (is_win) {
359+
sources += [
360+
"sdk/base/win/d3d11va_h264_decoder.cc",
361+
"sdk/base/win/d3d11va_h264_decoder.h",
362+
]
363+
}
364+
defines += [ "OWT_USE_FFMPEG" ]
365+
}
366+
350367
if (!is_ios) {
351368
sources += [
352369
"sdk/base/customizedvideodecoderfactory.cc",

talk/owt/sdk/base/win/d3d11va_h264_decoder.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ int32_t H264DXVADecoderImpl::Decode(const webrtc::EncodedImage& input_image,
408408
surface_handle_->cursor_data_size = cursor_data_size;
409409
surface_handle_->decode_start = decode_start_time;
410410
surface_handle_->decode_end = clock_->CurrentTime().ms_or(0);
411-
surface_handle_->start_duration = input_image.bwe_stats_.start_duration_;
411+
surface_handle_->start_duration =
412+
input_image.bwe_stats_.start_duration_;
412413
surface_handle_->last_duration = input_image.bwe_stats_.last_duration_;
413414
surface_handle_->packet_loss = input_image.bwe_stats_.packets_lost_;
414415
surface_handle_->frame_size = input_image.size();

talk/owt/sdk/base/win/d3d11va_h264_decoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class H264DXVADecoderImpl : public webrtc::H264Decoder {
8282
std::vector<uint8_t> current_cursor_data_;
8383
AVBufferRef* hw_device_ctx = nullptr;
8484
AVCodecContext* decoder_ctx = nullptr;
85-
AVCodec* decoder = nullptr;
85+
const AVCodec* decoder = nullptr;
8686
webrtc::Clock* clock_ = nullptr;
8787
};
8888

talk/owt/sdk/base/win/msdkvideodecoderfactory.cc

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ MSDKVideoDecoderFactory::MSDKVideoDecoderFactory(ID3D11Device* d3d11_device_exte
6666

6767
MSDKVideoDecoderFactory::~MSDKVideoDecoderFactory() {}
6868

69-
std::unique_ptr<webrtc::VideoDecoder> MSDKVideoDecoderFactory::CreateVideoDecoder(
69+
std::unique_ptr<webrtc::VideoDecoder>
70+
MSDKVideoDecoderFactory::CreateVideoDecoder(
7071
const webrtc::SdpVideoFormat& format) {
7172
bool vp9_hw = false, vp8_hw = false, av1_hw = false, h264_hw = false;
7273
#ifdef WEBRTC_USE_H265
@@ -92,17 +93,28 @@ std::unique_ptr<webrtc::VideoDecoder> MSDKVideoDecoderFactory::CreateVideoDecode
9293
return webrtc::VP9Decoder::Create();
9394
} else if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName) &&
9495
!vp8_hw) {
95-
RTC_LOG(LS_INFO) << "Not supporting HW VP8 decoder. Requesting SW decoding.";
96+
RTC_LOG(LS_INFO)
97+
<< "Not supporting HW VP8 decoder. Requesting SW decoding.";
9698
return webrtc::VP8Decoder::Create();
97-
} else if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName) && !h264_hw) {
99+
}
100+
#ifdef OWT_USE_FFMPEG
101+
else if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName)) {
102+
return owt::base::H264DXVADecoderImpl::Create(cricket::VideoCodec(format));
103+
}
104+
#else
105+
else if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName) &&
106+
!h264_hw) {
98107
return webrtc::H264Decoder::Create();
99-
} else if (absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName) &&
100-
!av1_hw) {
108+
}
109+
#endif
110+
else if (absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName) &&
111+
!av1_hw) {
101112
return webrtc::CreateDav1dDecoder();
102113
}
103114
#ifdef WEBRTC_USE_H265
104115
// This should not happen. We do not return here but preceed with HW decoder.
105-
else if (absl::EqualsIgnoreCase(format.name, cricket::kH265CodecName) && !h265_hw) {
116+
else if (absl::EqualsIgnoreCase(format.name, cricket::kH265CodecName) &&
117+
!h265_hw) {
106118
RTC_LOG(LS_ERROR) << "Returning null hevc encoder.";
107119
}
108120
#endif

0 commit comments

Comments
 (0)