mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 985253: Support H.264 RTP mode 1 support in webrtc signaling r=ehugg
This commit is contained in:
parent
41ccb95961
commit
88dd15fc1e
@ -60,31 +60,36 @@ struct VideoCodecConfig
|
||||
* The data-types for these properties mimic the
|
||||
* corresponding webrtc::VideoCodec data-types.
|
||||
*/
|
||||
int mType;
|
||||
int mType; // payload type
|
||||
std::string mName;
|
||||
uint32_t mRtcpFbTypes;
|
||||
unsigned int mMaxFrameSize;
|
||||
unsigned int mMaxFrameRate;
|
||||
LoadManager* mLoadManager;
|
||||
uint8_t mProfile;
|
||||
uint8_t mConstraints;
|
||||
uint8_t mLevel;
|
||||
uint8_t mPacketizationMode;
|
||||
// TODO: add external negotiated SPS/PPS
|
||||
|
||||
VideoCodecConfig(int type,
|
||||
std::string name,
|
||||
int rtcpFbTypes,
|
||||
LoadManager* load_manager = nullptr) :
|
||||
LoadManager* load_manager = nullptr,
|
||||
uint8_t profile = 0x42,
|
||||
uint8_t constraints = 0xC0,
|
||||
uint8_t level = 30,
|
||||
uint8_t packetization = 0) :
|
||||
mType(type),
|
||||
mName(name),
|
||||
mRtcpFbTypes(rtcpFbTypes),
|
||||
mMaxFrameSize(0),
|
||||
mMaxFrameRate(0),
|
||||
mLoadManager(load_manager)
|
||||
{
|
||||
// Replace codec name here because WebRTC.org code has a whitelist of
|
||||
// supported video codec in |webrtc::ViECodecImpl::CodecValid()| and will
|
||||
// reject registration of those not in it.
|
||||
// TODO: bug 995884 to support H.264 in WebRTC.org code.
|
||||
if (mName == "H264_P0")
|
||||
mName = "I420";
|
||||
}
|
||||
mLoadManager(load_manager),
|
||||
mProfile(profile),
|
||||
mConstraints(constraints),
|
||||
mLevel(level),
|
||||
mPacketizationMode(packetization) {}
|
||||
|
||||
VideoCodecConfig(int type,
|
||||
std::string name,
|
||||
@ -97,16 +102,7 @@ struct VideoCodecConfig
|
||||
mRtcpFbTypes(rtcpFbTypes),
|
||||
mMaxFrameSize(max_fs),
|
||||
mMaxFrameRate(max_fr),
|
||||
mLoadManager(load_manager)
|
||||
{
|
||||
// Replace codec name here because WebRTC.org code has a whitelist of
|
||||
// supported video codec in |webrtc::ViECodecImpl::CodecValid()| and will
|
||||
// reject registration of those not in it.
|
||||
// TODO: bug 995884 to support H.264 in WebRTC.org code.
|
||||
if (mName == "H264_P0")
|
||||
mName = "I420";
|
||||
}
|
||||
|
||||
mLoadManager(load_manager) {}
|
||||
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_nack_type_e type) const
|
||||
{
|
||||
@ -122,7 +118,6 @@ struct VideoCodecConfig
|
||||
{
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_ccm_to_bitmap(type);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -279,7 +279,7 @@ public:
|
||||
* @param encoder
|
||||
* @result: on success, we will use the specified encoder
|
||||
*/
|
||||
virtual MediaConduitErrorCode SetExternalSendCodec(int pltype,
|
||||
virtual MediaConduitErrorCode SetExternalSendCodec(VideoCodecConfig* config,
|
||||
VideoEncoder* encoder) = 0;
|
||||
|
||||
/**
|
||||
@ -287,7 +287,7 @@ public:
|
||||
* @param decoder
|
||||
* @result: on success, we will use the specified decoder
|
||||
*/
|
||||
virtual MediaConduitErrorCode SetExternalRecvCodec(int pltype,
|
||||
virtual MediaConduitErrorCode SetExternalRecvCodec(VideoCodecConfig* config,
|
||||
VideoDecoder* decoder) = 0;
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "CSFLog.h"
|
||||
#include "nspr.h"
|
||||
#include "plstr.h"
|
||||
|
||||
// For rtcp-fb constants
|
||||
#include "ccsdp.h"
|
||||
@ -479,7 +480,7 @@ WebrtcVideoConduit::AttachTransport(mozilla::RefPtr<TransportInterface> aTranspo
|
||||
MediaConduitErrorCode
|
||||
WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
{
|
||||
CSFLogDebug(logTag, "%s ", __FUNCTION__);
|
||||
CSFLogDebug(logTag, "%s for %s", __FUNCTION__, codecConfig->mName.c_str());
|
||||
bool codecFound = false;
|
||||
MediaConduitErrorCode condError = kMediaConduitNoError;
|
||||
int error = 0; //webrtc engine errors
|
||||
@ -509,35 +510,52 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
mPtrViEBase->LastError());
|
||||
return kMediaConduitUnknownError;
|
||||
}
|
||||
}
|
||||
|
||||
mEngineTransmitting = false;
|
||||
mEngineTransmitting = false;
|
||||
}
|
||||
|
||||
if (codecConfig->mLoadManager) {
|
||||
mPtrViEBase->RegisterCpuOveruseObserver(mChannel, codecConfig->mLoadManager);
|
||||
mPtrViEBase->SetLoadManager(codecConfig->mLoadManager);
|
||||
}
|
||||
|
||||
// we should be good here to set the new codec.
|
||||
for(int idx=0; idx < mPtrViECodec->NumberOfCodecs(); idx++)
|
||||
{
|
||||
if(0 == mPtrViECodec->GetCodec(idx, video_codec))
|
||||
if (mExternalSendCodec &&
|
||||
codecConfig->mType == mExternalSendCodec->mType) {
|
||||
CSFLogError(logTag, "%s Configuring External H264 Send Codec", __FUNCTION__);
|
||||
|
||||
// width/height will be overridden on the first frame
|
||||
video_codec.width = 320;
|
||||
video_codec.height = 240;
|
||||
video_codec.qpMax = 56;
|
||||
video_codec.numberOfSimulcastStreams = 1;
|
||||
video_codec.mode = webrtc::kRealtimeVideo;
|
||||
|
||||
codecFound = true;
|
||||
} else {
|
||||
// we should be good here to set the new codec.
|
||||
for(int idx=0; idx < mPtrViECodec->NumberOfCodecs(); idx++)
|
||||
{
|
||||
payloadName = video_codec.plName;
|
||||
if(codecConfig->mName.compare(payloadName) == 0)
|
||||
if(0 == mPtrViECodec->GetCodec(idx, video_codec))
|
||||
{
|
||||
CodecConfigToWebRTCCodec(codecConfig, video_codec);
|
||||
codecFound = true;
|
||||
break;
|
||||
payloadName = video_codec.plName;
|
||||
if(codecConfig->mName.compare(payloadName) == 0)
|
||||
{
|
||||
// Note: side-effect of this is that video_codec is filled in
|
||||
// by GetCodec()
|
||||
codecFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}//for
|
||||
}
|
||||
|
||||
if(codecFound == false)
|
||||
{
|
||||
CSFLogError(logTag, "%s Codec Mismatch ", __FUNCTION__);
|
||||
return kMediaConduitInvalidSendCodec;
|
||||
}
|
||||
// Note: only for overriding parameters from GetCodec()!
|
||||
CodecConfigToWebRTCCodec(codecConfig, video_codec);
|
||||
|
||||
if(mPtrViECodec->SetSendCodec(mChannel, video_codec) == -1)
|
||||
{
|
||||
@ -656,35 +674,61 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
|
||||
|
||||
mEngineReceiving = false;
|
||||
memset(&video_codec, 0, sizeof(webrtc::VideoCodec));
|
||||
//Retrieve pre-populated codec structure for our codec.
|
||||
for(int idx=0; idx < mPtrViECodec->NumberOfCodecs(); idx++)
|
||||
{
|
||||
if(mPtrViECodec->GetCodec(idx, video_codec) == 0)
|
||||
|
||||
if (mExternalRecvCodec &&
|
||||
codecConfigList[i]->mType == mExternalRecvCodec->mType) {
|
||||
CSFLogError(logTag, "%s Configuring External H264 Receive Codec", __FUNCTION__);
|
||||
|
||||
// XXX Do we need a separate setting for receive maxbitrate? Is it
|
||||
// different for hardware codecs? For now assume symmetry.
|
||||
CodecConfigToWebRTCCodec(codecConfigList[i], video_codec);
|
||||
|
||||
// values SetReceiveCodec() cares about are name, type, maxbitrate
|
||||
if(mPtrViECodec->SetReceiveCodec(mChannel,video_codec) == -1)
|
||||
{
|
||||
payloadName = video_codec.plName;
|
||||
if(codecConfigList[i]->mName.compare(payloadName) == 0)
|
||||
CSFLogError(logTag, "%s Invalid Receive Codec %d ", __FUNCTION__,
|
||||
mPtrViEBase->LastError());
|
||||
} else {
|
||||
CSFLogError(logTag, "%s Successfully Set the codec %s", __FUNCTION__,
|
||||
codecConfigList[i]->mName.c_str());
|
||||
if(CopyCodecToDB(codecConfigList[i]))
|
||||
{
|
||||
CodecConfigToWebRTCCodec(codecConfigList[i], video_codec);
|
||||
if(mPtrViECodec->SetReceiveCodec(mChannel,video_codec) == -1)
|
||||
{
|
||||
CSFLogError(logTag, "%s Invalid Receive Codec %d ", __FUNCTION__,
|
||||
mPtrViEBase->LastError());
|
||||
} else {
|
||||
CSFLogError(logTag, "%s Successfully Set the codec %s", __FUNCTION__,
|
||||
codecConfigList[i]->mName.c_str());
|
||||
if(CopyCodecToDB(codecConfigList[i]))
|
||||
{
|
||||
success = true;
|
||||
} else {
|
||||
CSFLogError(logTag,"%s Unable to updated Codec Database", __FUNCTION__);
|
||||
return kMediaConduitUnknownError;
|
||||
}
|
||||
}
|
||||
break; //we found a match
|
||||
success = true;
|
||||
} else {
|
||||
CSFLogError(logTag,"%s Unable to update Codec Database", __FUNCTION__);
|
||||
return kMediaConduitUnknownError;
|
||||
}
|
||||
}
|
||||
}//end for codeclist
|
||||
|
||||
} else {
|
||||
//Retrieve pre-populated codec structure for our codec.
|
||||
for(int idx=0; idx < mPtrViECodec->NumberOfCodecs(); idx++)
|
||||
{
|
||||
if(mPtrViECodec->GetCodec(idx, video_codec) == 0)
|
||||
{
|
||||
payloadName = video_codec.plName;
|
||||
if(codecConfigList[i]->mName.compare(payloadName) == 0)
|
||||
{
|
||||
CodecConfigToWebRTCCodec(codecConfigList[i], video_codec);
|
||||
if(mPtrViECodec->SetReceiveCodec(mChannel,video_codec) == -1)
|
||||
{
|
||||
CSFLogError(logTag, "%s Invalid Receive Codec %d ", __FUNCTION__,
|
||||
mPtrViEBase->LastError());
|
||||
} else {
|
||||
CSFLogError(logTag, "%s Successfully Set the codec %s", __FUNCTION__,
|
||||
codecConfigList[i]->mName.c_str());
|
||||
if(CopyCodecToDB(codecConfigList[i]))
|
||||
{
|
||||
success = true;
|
||||
} else {
|
||||
CSFLogError(logTag,"%s Unable to update Codec Database", __FUNCTION__);
|
||||
return kMediaConduitUnknownError;
|
||||
}
|
||||
}
|
||||
break; //we found a match
|
||||
}
|
||||
}
|
||||
}//end for codeclist
|
||||
}
|
||||
}//end for
|
||||
|
||||
if(!success)
|
||||
@ -882,22 +926,28 @@ WebrtcVideoConduit::SelectSendResolution(unsigned short width,
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
WebrtcVideoConduit::SetExternalSendCodec(int pltype,
|
||||
WebrtcVideoConduit::SetExternalSendCodec(VideoCodecConfig* config,
|
||||
VideoEncoder* encoder) {
|
||||
int ret = mPtrExtCodec->RegisterExternalSendCodec(mChannel,
|
||||
pltype,
|
||||
static_cast<WebrtcVideoEncoder*>(encoder),
|
||||
false);
|
||||
return ret ? kMediaConduitInvalidSendCodec : kMediaConduitNoError;
|
||||
if (!mPtrExtCodec->RegisterExternalSendCodec(mChannel,
|
||||
config->mType,
|
||||
static_cast<WebrtcVideoEncoder*>(encoder),
|
||||
false)) {
|
||||
mExternalSendCodec = new VideoCodecConfig(*config);
|
||||
return kMediaConduitNoError;
|
||||
}
|
||||
return kMediaConduitInvalidSendCodec;
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
WebrtcVideoConduit::SetExternalRecvCodec(int pltype,
|
||||
WebrtcVideoConduit::SetExternalRecvCodec(VideoCodecConfig* config,
|
||||
VideoDecoder* decoder) {
|
||||
int ret = mPtrExtCodec->RegisterExternalReceiveCodec(mChannel,
|
||||
pltype,
|
||||
static_cast<WebrtcVideoDecoder*>(decoder));
|
||||
return ret ? kMediaConduitInvalidReceiveCodec : kMediaConduitNoError;
|
||||
if (!mPtrExtCodec->RegisterExternalReceiveCodec(mChannel,
|
||||
config->mType,
|
||||
static_cast<WebrtcVideoDecoder*>(decoder))) {
|
||||
mExternalRecvCodec = new VideoCodecConfig(*config);
|
||||
return kMediaConduitNoError;
|
||||
}
|
||||
return kMediaConduitInvalidReceiveCodec;
|
||||
}
|
||||
|
||||
MediaConduitErrorCode
|
||||
@ -1141,8 +1191,23 @@ void
|
||||
WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
|
||||
webrtc::VideoCodec& cinst)
|
||||
{
|
||||
// Note: this assumes cinst is initialized to a base state either by
|
||||
// hand or from a config fetched with GetConfig(); this modifies the config
|
||||
// to match parameters from VideoCodecConfig
|
||||
cinst.plType = codecInfo->mType;
|
||||
// leave width/height alone; they'll be overridden on the first frame
|
||||
if (codecInfo->mName == "H264_P0" || codecInfo->mName == "H264_P1") {
|
||||
cinst.codecType = webrtc::kVideoCodecH264;
|
||||
PL_strncpyz(cinst.plName, "H264", sizeof(cinst.plName));
|
||||
} else if (codecInfo->mName == "VP8") {
|
||||
cinst.codecType = webrtc::kVideoCodecVP8;
|
||||
PL_strncpyz(cinst.plName, "VP8", sizeof(cinst.plName));
|
||||
} else if (codecInfo->mName == "I420") {
|
||||
cinst.codecType = webrtc::kVideoCodecI420;
|
||||
PL_strncpyz(cinst.plName, "I420", sizeof(cinst.plName));
|
||||
}
|
||||
|
||||
// width/height will be overridden on the first frame; they must be 'sane' for
|
||||
// SetSendCodec()
|
||||
if (codecInfo->mMaxFrameRate > 0)
|
||||
{
|
||||
cinst.maxFramerate = codecInfo->mMaxFrameRate;
|
||||
@ -1150,6 +1215,19 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
|
||||
cinst.minBitrate = mMinBitrate;
|
||||
cinst.startBitrate = mStartBitrate;
|
||||
cinst.maxBitrate = mMaxBitrate;
|
||||
|
||||
if (cinst.codecType == webrtc::kVideoCodecH264)
|
||||
{
|
||||
cinst.codecSpecific.H264.profile = codecInfo->mProfile;
|
||||
cinst.codecSpecific.H264.constraints = codecInfo->mConstraints;
|
||||
cinst.codecSpecific.H264.level = codecInfo->mLevel;
|
||||
cinst.codecSpecific.H264.packetizationMode = codecInfo->mPacketizationMode;
|
||||
// paranoia
|
||||
cinst.codecSpecific.H264.spsData = nullptr;
|
||||
cinst.codecSpecific.H264.spsLen = 0;
|
||||
cinst.codecSpecific.H264.ppsData = nullptr;
|
||||
cinst.codecSpecific.H264.ppsLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Copy the codec passed into Conduit's database
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef VIDEO_SESSION_H_
|
||||
#define VIDEO_SESSION_H_
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "MediaConduitInterface.h"
|
||||
@ -146,14 +147,14 @@ public:
|
||||
* Set an external encoder object |encoder| to the payload type |pltype|
|
||||
* for sender side codec.
|
||||
*/
|
||||
virtual MediaConduitErrorCode SetExternalSendCodec(int pltype,
|
||||
virtual MediaConduitErrorCode SetExternalSendCodec(VideoCodecConfig* config,
|
||||
VideoEncoder* encoder);
|
||||
|
||||
/**
|
||||
* Set an external decoder object |decoder| to the payload type |pltype|
|
||||
* for receiver side codec.
|
||||
*/
|
||||
virtual MediaConduitErrorCode SetExternalRecvCodec(int pltype,
|
||||
virtual MediaConduitErrorCode SetExternalRecvCodec(VideoCodecConfig* config,
|
||||
VideoDecoder* decoder);
|
||||
|
||||
|
||||
@ -338,6 +339,9 @@ private:
|
||||
static const unsigned int sRoundingPadding = 1024;
|
||||
|
||||
mozilla::RefPtr<WebrtcAudioConduit> mSyncedTo;
|
||||
|
||||
nsAutoPtr<VideoCodecConfig> mExternalSendCodec;
|
||||
nsAutoPtr<VideoCodecConfig> mExternalRecvCodec;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
@ -2135,7 +2135,7 @@ static int vcmEnsureExternalCodec(
|
||||
// whitelist internal codecs; I420 will be here once we resolve bug 995884
|
||||
return 0;
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
} else if (config->mName == "I420") {
|
||||
} else if (config->mName == "H264_P0" || config->mName == "H264_P1") {
|
||||
// Here we use "I420" to register H.264 because WebRTC.org code has a
|
||||
// whitelist of supported video codec in |webrtc::ViECodecImpl::CodecValid()|
|
||||
// and will reject registration of those not in it.
|
||||
@ -2145,14 +2145,14 @@ static int vcmEnsureExternalCodec(
|
||||
if (send) {
|
||||
VideoEncoder* encoder = OMXVideoCodec::CreateEncoder(OMXVideoCodec::CodecType::CODEC_H264);
|
||||
if (encoder) {
|
||||
return conduit->SetExternalSendCodec(config->mType, encoder);
|
||||
return conduit->SetExternalSendCodec(config, encoder);
|
||||
} else {
|
||||
return kMediaConduitInvalidSendCodec;
|
||||
}
|
||||
} else {
|
||||
VideoDecoder* decoder = OMXVideoCodec::CreateDecoder(OMXVideoCodec::CodecType::CODEC_H264);
|
||||
if (decoder) {
|
||||
return conduit->SetExternalRecvCodec(config->mType, decoder);
|
||||
return conduit->SetExternalRecvCodec(config, decoder);
|
||||
} else {
|
||||
return kMediaConduitInvalidReceiveCodec;
|
||||
}
|
||||
@ -2740,7 +2740,8 @@ int vcmGetVideoCodecList(int request_type)
|
||||
*/
|
||||
int vcmGetVideoMaxSupportedPacketizationMode()
|
||||
{
|
||||
return 0;
|
||||
// We support mode 1 packetization in webrtc
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3015,7 +3016,9 @@ void vcmPopulateAttribs(void *sdp_p, int level, cc_uint32_t media_type,
|
||||
|
||||
(void) ccsdpAttrSetFmtpPayloadType(sdp_p, level, 0, a_inst, payload_number);
|
||||
|
||||
//(void) sdp_attr_set_fmtp_pack_mode(sdp_p, level, 0, a_inst, 1 /*packetization_mode*/);
|
||||
if (media_type == RTP_H264_P1) {
|
||||
(void) ccsdpAttrSetFmtpPackMode(sdp_p, level, 0, a_inst, 1 /*packetization_mode*/);
|
||||
}
|
||||
//(void) sdp_attr_set_fmtp_parameter_sets(sdp_p, level, 0, a_inst, "J0KAFJWgUH5A,KM4H8n=="); // NAL units 27 42 80 14 95 a0 50 7e 40 28 ce 07 f2
|
||||
|
||||
//profile = 0x42E000 + H264ToSDPLevel( vt_GetClientProfileLevel() );
|
||||
|
@ -604,7 +604,6 @@ sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[],
|
||||
{
|
||||
uint16_t count = 0;
|
||||
int codec_mask;
|
||||
cc_uint32_t major_ver, minor_ver;
|
||||
|
||||
if ( isOffer ) {
|
||||
codec_mask = vcmGetVideoCodecList(VCM_DSP_FULLDUPLEX);
|
||||
@ -615,18 +614,9 @@ sip_config_video_supported_codecs_get (rtp_ptype aSupportedCodecs[],
|
||||
codec_mask = vcmGetVideoCodecList(VCM_DSP_IGNORE);
|
||||
}
|
||||
if ( codec_mask & VCM_CODEC_RESOURCE_H264) {
|
||||
/*
|
||||
* include payload type for packetization mode 1 only if ucm sis version
|
||||
* is equal to or greater than 5.1.0 (AngelFire).
|
||||
*/
|
||||
platGetSISProtocolVer(&major_ver, &minor_ver, NULL, NULL);
|
||||
if ((major_ver > SIS_PROTOCOL_MAJOR_VERSION_ANGELFIRE) ||
|
||||
(major_ver == SIS_PROTOCOL_MAJOR_VERSION_ANGELFIRE &&
|
||||
minor_ver >= SIS_PROTOCOL_MINOR_VERSION_ANGELFIRE)) {
|
||||
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
|
||||
aSupportedCodecs[count] = RTP_H264_P1;
|
||||
count++;
|
||||
}
|
||||
if (vcmGetVideoMaxSupportedPacketizationMode() == 1) {
|
||||
aSupportedCodecs[count] = RTP_H264_P1;
|
||||
count++;
|
||||
}
|
||||
aSupportedCodecs[count] = RTP_H264_P0;
|
||||
count++;
|
||||
|
Loading…
Reference in New Issue
Block a user