WebRTC supports the use of its own codec (limited to native development), audio, video can be. Here the video coding as an example to analyze the corresponding source code in the WebRTC.
createpeerconnectionfactory
In Webrtc/api/peerconnectioninterface.h there is a method Createpeerconnectionfactory, the prototype is as follows:
Inline rtc::scoped_refptr<peerconnectionfactoryinterface>
createpeerconnectionfactory (
RTC:: thread* Worker_and_network_thread,
rtc::thread* signaling_thread,
audiodevicemodule* default_adm,
RTC ::scoped_refptr<audioencoderfactory> audio_encoder_factory,
rtc::scoped_refptr<audiodecoderfactory > audio_decoder_factory,
cricket::webrtcvideoencoderfactory* video_encoder_factory,
Cricket:: webrtcvideodecoderfactory* video_decoder_factory);
As you can see, the last four parameters of Createpeerconnectionfactory allow us to provide our own codec factory. This allows us to implement our own factory, create our own encoder (decoder) in factory, and use our WebRTC (encoder) inside decoder.
The code snippet resembles the following:
RTC::SCOPED_REFPTR<WEBRTC::P eerconnectionfactoryinterface> factory = Webrtc::createpeerconnectionfactory (
Current_thread, Current_thread,
your_adm,
your_audio_encoder_factory,
your_audio_decoder_ Factory,
Your_video_encoder_factory,
your_video_decoder_factory);
rtc::scoped_refptr<peerconnectioninterface> peer_connection = factory->createpeerconnection (
config, constraints, NULL, NULL, your_observer);
webrtcvideoencoderfactory
This interface is defined in Webrtcvideoencoderfactory.h (webrtc/media/engine):
class WebRtcVideoEncoderFactory {
public:
// This VideoCodec class is deprecated. Use cricket::VideoCodec directly
// instead and the corresponding factory function. See
// http://crbug/webrtc/6402 for more info.
struct VideoCodec {
webrtc::VideoCodecType type;
std::string name;
VideoCodec(webrtc::VideoCodecType t, const std::string& nm)
: type(t), name(nm) {}
VideoCodec(webrtc::VideoCodecType t,
const std::string& nm,
int w,
int h,
int fr)
: type(t), name(nm) {}
};
virtual ~WebRtcVideoEncoderFactory() {}
// TODO(magjed): Make these functions pure virtual when every external client
// implements it. See http://crbug/webrtc/6402 for more info.
// Caller takes the ownership of the returned object and it should be released
// by calling DestroyVideoEncoder().
virtual webrtc::VideoEncoder* CreateVideoEncoder(
const cricket::VideoCodec& codec);
// Returns a list of supported codecs in order of preference.
virtual const std::vector<cricket::VideoCodec>& supported_codecs() const;
// Caller takes the ownership of the returned object and it should be released
// by calling DestroyVideoEncoder().
// Deprecated: Use cricket::VideoCodec as argument instead. See
// http://crbug/webrtc/6402 for more info.
virtual webrtc::VideoEncoder* CreateVideoEncoder(webrtc::VideoCodecType type);
// Returns a list of supported codecs in order of preference.
// Deprecated: Return cricket::VideoCodecs instead. See
// http://crbug/webrtc/6402 for more info.
virtual const std::vector<VideoCodec>& codecs() const;
// Returns true if encoders created by this factory of the given codec type
// will use internal camera sources, meaning that they don't require/expect
// frames to be delivered via webrtc::VideoEncoder::Encode. This flag is used
// as the internal_source parameter to
// webrtc::ViEExternalCodec::RegisterExternalSendCodec.
virtual bool EncoderTypeHasInternalSource(webrtc::VideoCodecType type) const {
return false;
}
virtual void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) = 0;
private:
// TODO(magjed): Remove these. They are necessary in order to return a const
// reference to a std::vector in the default implementations of codecs() and
// supported_codecs(). See http://crbug/webrtc/6402 for more info.
mutable std::vector<VideoCodec> encoder_codecs_;
mutable std::vector<cricket::VideoCodec> codecs_;
};
Implement Webrtcvideoencoderfactory interface, pass to Createpeerconnectionfactory can. You can refer to Internalencoderfactory.h and internalencoderfactory.cpp under the Webrtc/media/engine directory.
external codecs and internal relationships
In the case of video coding, there is a segment code in webrtc/media/engine/webrtcvideoengine2.cc that illustrates the relationship between an external video encoder and an internal video encoder:
WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder
WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder(
const VideoCodec& codec) {
RTC_DCHECK_RUN_ON(&thread_checker_);
// Do not re-create encoders of the same type.
if (codec == allocated_encoder_.codec &&
allocated_encoder_.encoder != nullptr) {
return allocated_encoder_;
}
// Try creating external encoder.
if (external_encoder_factory_ != nullptr &&
FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) {
webrtc::VideoEncoder* encoder =
external_encoder_factory_->CreateVideoEncoder(codec);
if (encoder != nullptr)
return AllocatedEncoder(encoder, codec, true /* is_external */);
}
// Try creating internal encoder.
if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) {
if (parameters_.encoder_config.content_type ==
webrtc::VideoEncoderConfig::ContentType::kScreen &&
parameters_.conference_mode && UseSimulcastScreenshare()) {
// TODO(sprang): Remove this adapter once libvpx supports simulcast with
// same-resolution substreams.
WebRtcSimulcastEncoderFactory adapter_factory(
internal_encoder_factory_.get());
return AllocatedEncoder(adapter_factory.CreateVideoEncoder(codec), codec,
false /* is_external */);
}
return AllocatedEncoder(
internal_encoder_factory_->CreateVideoEncoder(codec), codec,
false /* is_external */);
}
// This shouldn't happen, we should not be trying to create something we don't
// support.
RTC_NOTREACHED();
return AllocatedEncoder(NULL, cricket::VideoCodec(), false);
}
As you can see, this will first attempt to call External_encoder_factory_ to create an external encoder, if created successfully, with external, if failed, then look inside.
The external_encoder_factory_ here is the Encoder factory instance that we passed in when we called Createpeerconnectionfactory.
Related reading: WebRTC learning material Daquan Ubuntu 14.04 under the compilation WebRTC WebRTC source Turnserver use method open WebRTC log (native API) let WebRTC support H264 codec GN and Ninja WebRTC compiler system of the WebRTC compiler system, and how to enable trace_event in WebRTC codes