webrtc (5) 在Webrtc中集成H264 Codec

Webrtc原生支持VP8和VP9,但是并不支持H264,这个在上一篇Webrtc和OpenWebrtc的对比中已经讲过。


那么如果我们想要使用H264怎么办呢?

可供选择的方案有两种,一种是x264,另一个是OpenH264。

OpenH264是汇编代码,在性能上比x264更强,所以我选择了OpenH264.


OpenH264是思科开源的项目,项目地址:https://github.com/cisco/openh264

这个项目的下载和编译可以说是傻瓜级的了,具体不多介绍,主要讲怎么将OpenH264集成进webrtc和使用起来。


1,集成

事实上集成264到webrtc是一个工作量很大的任务。不过还好,webrtc代码中已经帮我们做了一大部分事情(比如rtp对264的封装),我们只需要关注Codec的接口即可。

ViEEncoder中有一个方法可以注册第三方编码器:

  int32_t RegisterExternalEncoder(VideoEncoder* encoder,
                                  uint8_t pl_type,
                                  bool internal_source);

ViEChannel中也可以注册第三方解码器:

  int32_t RegisterExternalDecoder(const uint8_t pl_type,
                                  VideoDecoder* decoder,
                                  bool buffered_rendering,
                                  int32_t render_delay);

首先,需要创建VideoEncoder和VideoDecoder的支持H264的子类,也就是将OpenH264按照webrtc要求的格式进行封装。

这个代码我主要参考了https://groups.google.com/forum/#!topic/discuss-webrtc/U-y3or-dBOU  这里面的帖子,然后对其中的代码做了部分修改。

这个帖子里面的代码比较古老,很多接口已经跟现在的代码对应不上。另外主要的修改在于对RTPFragmentationHeader的支持。

encoded_complete_callback_->Encoded(encoded_image_, NULL, NULL);
目前第三个参数已经不能为空,必须填入一个RTPFragmentationHeader
encoded_complete_callback_->Encoded(encoded_image_, NULL, &frag_info);



2,使用

要使用的话,首先需要将264编码器和解码器注册进webrtc,代码如下:

    _vieChannel = _vieBase->GetChannel(channel);
    _vieEncoder = _vieBase->GetEncoder(channel);

    webrtc::H264Encoder *h264encoder = webrtc::H264Encoder::Create();
    _vieEncoder->RegisterExternalEncoder(h264encoder, 103, false);
    webrtc::H264Decoder *h264decoder = webrtc::H264Decoder::Create();
    _vieChannel->RegisterExternalDecoder(103, h264decoder, true, 100);

另外,这里面配置H264的pt为103,后续设置Codec也要指定103才会正确的使用H264.

    webrtc::VideoCodec videoCodec;
    int numberOfCodecs = _vieCodec->NumberOfCodecs();
    for (int i = 0; i < numberOfCodecs; i++) {
        if (_vieCodec->GetCodec(i, videoCodec) != -1) {
            if (videoCodec.codecType == webrtc::kVideoCodecH264) {
                break;
            }
        }
    }
    
    videoCodec.targetBitrate = 256;
    videoCodec.minBitrate = 200;
    videoCodec.maxBitrate = 300;
    videoCodec.plType = 103;
    videoCodec.maxFramerate = DEFAULT_VIDEO_CODEC_MAX_FRAMERATE;
    
    _vieCodec->SetSendCodec(channel, videoCodec);
    _vieCodec->SetReceiveCodec(channel, videoCodec);

配置完成之后,264就可以使用了。

经过测试,Open264的性能确实不错,在iPod5上,设置分辨率CiF,码率256k,帧率15以内,CPU开销在60%多,视频也非常流畅。


另外,关于OpenH264的授权费用,虽然OpenH264是遵循BSD开源协议,但是仍然需要收取授权费用。

具体可参考:

http://www.openh264.org/faq.html 

http://stackoverflow.com/questions/21858527/cisco-h264-encoding-series-of-images-to-h264 



你可能感兴趣的:(iOS,OpenH264,Codec,H264,webrtc)