WebRTC由于license及其他的一些原因,默认的视频编解码只有使用vp8跟vp9,没有支持h264的编解码,但是我经过一些对比测试(vp9 vs h264)的测试数据发现,vp9的优势在于1080p以上才开始渐渐追上h264的效率,并且目前大多数的视频设备,还是使用h264的比较多,因此要实现对h264的编解码,就必须重新编译WebRTC添加对h264的支持。
通过研究WebRTC的源码发现,对于视频编解码的部分,移动端的使用有两方面需要考虑:
WebRTC从r5X版本开始,Android/iOS 平台开始支持HW en/decoder, 查看r67版本WebRTC,其中:
Android判断是否支持硬件编解码,是在org.webrtc.HardwareVideoEn/Decoder.java中supportedVP8/VP9/H264HwCodecPrefixes这个字符串数组中定义,可根据需要对手机做机型适配,比如华为的某些手机处理器,CPU本身支持硬件编解码,但是检测不到.
软件使用的基本逻辑为先去判断自身平台是否支持硬件编解码,如果支持则使用,如果不支持则回退到软件编解码,具体使用上层代码HardwareVideoEn/Decoder.java和RTCVideoEn/DecoderH264.mm分别去实现Android和iOS平台的h264硬件编解码.
在native c/c++代码中的调用方式代码片段如下:
#if defined(WEBRTC_ANDROID)
webrtc::jni::MediaCodecVideoEncoderFactory* encoder_factory = new webrtc::jni::MediaCodecVideoEncoderFactory();
video_send_config.rtp.payload_name = "H264";
video_send_config.rtp.payload_type = kWtkPayloadTypeH264;
cricket::VideoCodec codec("H264");
webrtc::VideoEncoder* is_encoder_support = encoder_factory->CreateVideoEncoder(codec);
if(is_encoder_support != nullptr)
{
video_send_config.encoder_settings.encoder = is_encoder_support;
RTC_LOG(LS_INFO) << __FUNCTION__ << " , HW H264 Supported, Use it!";
}
else
{
video_send_config.encoder_settings.encoder = webrtc::H264Encoder::Create(codec).release();
RTC_LOG(LS_INFO) << __FUNCTION__ << " , HW H264 Not Supported, roll back to SW H264!";
}
#elif defined(WEBRTC_IOS)
video_send_config.rtp.payload_name = "H264";
video_send_config.rtp.payload_type = kWtkPayloadTypeH264;
video_send_config.encoder_settings.encoder = webrtc::CreateObjCEncoderFactory()->CreateVideoEncoder(webrtc::SdpVideoFormat("H264")).release();
#endif
具体代码参考我的github下wtkrtc_mediaengine中的代码实现.
可参考我在webrtc-discuss中的maillist,具体方法如下:
在WebRTC的源码src/third_party/下,有openh264及ffmpeg的源码,编译默认只支持的配置为
is_linux和is_fuchsia参数,修改方法如下:
#use_linux_config = is_linux || is_fuchsia改为以下
use_linux_config = is_linux || is_fuchsia || is_android
//以下两个文件
third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavcodec/parser_list.c
third_party/ffmpeg/chromium/config/Chrome/android/arm-neon/libavcodec/codec_list.c
--- a/chromium/config/Chrome/android/arm-neon/libavcodec/parser_list.c
+++ b/chromium/config/Chrome/android/arm-neon/libavcodec/parser_list.c
@@ -4,4 +4,5 @@ static const AVCodecParser * const parser_list[] = {
&ff_mpegaudio_parser,
&ff_opus_parser,
&ff_vorbis_parser,
+ &ff_h264_parser,
NULL };
--- a/chromium/config/Chrome/android/arm-neon/libavcodec/codec_list.c
+++ b/chromium/config/Chrome/android/arm-neon/libavcodec/codec_list.c
@@ -13,4 +13,5 @@ static const AVCodec * const codec_list[] = {
&ff_pcm_s32le_decoder,
&ff_pcm_u8_decoder,
&ff_libopus_decoder,
+ &ff_h264_decoder,
NULL };
$ninja -c out/你的项目名
最近在使用Hybird APP的开发模式,采用H5 + 原生的混合模式开发,这样的好处就是不用频繁升级手机端APP,只需服务器前端调整即可实现更新。
最后选用CrossWalk去实现混合开发WebRTC,也是发现默认不支持h264的编解码,有了上面的经验,修改Chromium之后重新编译CrossWalk,感兴趣的请移步这里。
至此,在WebRTC中添加h264编解码的方式已经完成,本人水平一般,能力有限,欢迎大家指正留言交流!