1. 程式人生 > >webrtc (5) 在Webrtc中整合H264 Codec

webrtc (5) 在Webrtc中整合H264 Codec

Webrtc原生支援VP8和VP9,但是並不支援H264,這個在上一篇Webrtc和OpenWebrtc的對比中已經講過。

那麼如果我們想要使用H264怎麼辦呢?

可供選擇的方案有兩種,一種是x264,另一個是OpenH264。

OpenH264是彙編程式碼,在效能上比x264更強,所以我選擇了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要求的格式進行封裝。

這個帖子裡面的程式碼比較古老,很多介面已經跟現在的程式碼對應不上。另外主要的修改在於對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開源協議,但是仍然需要收取授權費用。

具體可參考: