зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1022008: Hook up SDP negotiation for H.264 GMP codecs r=ehugg
This commit is contained in:
Родитель
39e8e6e97c
Коммит
cf095091a1
|
@ -45,12 +45,31 @@ struct AudioCodecConfig
|
|||
};
|
||||
|
||||
/*
|
||||
* Minimalisitc video codec configuration
|
||||
* Minimalistic video codec configuration
|
||||
* More to be added later depending on the use-case
|
||||
*/
|
||||
|
||||
struct VideoCodecConfig
|
||||
#define MAX_SPROP_LEN 128
|
||||
|
||||
// used for holding SDP negotiation results
|
||||
struct VideoCodecConfigH264
|
||||
{
|
||||
char sprop_parameter_sets[MAX_SPROP_LEN];
|
||||
int packetization_mode;
|
||||
int profile_level_id;
|
||||
int max_mbps;
|
||||
int max_fs;
|
||||
int max_cpb;
|
||||
int max_dpb;
|
||||
int max_br;
|
||||
int tias_bw;
|
||||
};
|
||||
|
||||
|
||||
// class so the std::strings can get freed more easily/reliably
|
||||
class VideoCodecConfig
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* The data-types for these properties mimic the
|
||||
* corresponding webrtc::VideoCodec data-types.
|
||||
|
@ -60,6 +79,10 @@ struct VideoCodecConfig
|
|||
uint32_t mRtcpFbTypes;
|
||||
unsigned int mMaxFrameSize;
|
||||
unsigned int mMaxFrameRate;
|
||||
unsigned int mMaxMBPS; // in macroblocks-per-second
|
||||
unsigned int mMaxBitrate;
|
||||
// max_cpb & max_dpb would be streaming/mode-2 only
|
||||
std::string mSpropParameterSets;
|
||||
uint8_t mProfile;
|
||||
uint8_t mConstraints;
|
||||
uint8_t mLevel;
|
||||
|
@ -69,30 +92,34 @@ struct VideoCodecConfig
|
|||
VideoCodecConfig(int type,
|
||||
std::string name,
|
||||
int rtcpFbTypes,
|
||||
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),
|
||||
mProfile(profile),
|
||||
mConstraints(constraints),
|
||||
mLevel(level),
|
||||
mPacketizationMode(packetization) {}
|
||||
|
||||
VideoCodecConfig(int type,
|
||||
std::string name,
|
||||
int rtcpFbTypes,
|
||||
unsigned int max_fs,
|
||||
unsigned int max_fr) :
|
||||
mType(type),
|
||||
mName(name),
|
||||
mRtcpFbTypes(rtcpFbTypes),
|
||||
mMaxFrameSize(max_fs),
|
||||
mMaxFrameRate(max_fr) {}
|
||||
unsigned int max_fs = 0,
|
||||
unsigned int max_fr = 0,
|
||||
const struct VideoCodecConfigH264 *h264 = nullptr) :
|
||||
mType(type),
|
||||
mName(name),
|
||||
mRtcpFbTypes(rtcpFbTypes),
|
||||
mMaxFrameSize(max_fs), // may be overridden
|
||||
mMaxFrameRate(max_fr),
|
||||
mMaxMBPS(0),
|
||||
mMaxBitrate(0),
|
||||
mProfile(0x42),
|
||||
mConstraints(0xE0),
|
||||
mLevel(0x0C),
|
||||
mPacketizationMode(1)
|
||||
{
|
||||
if (h264) {
|
||||
if (max_fs == 0 || (h264->max_fs != 0 && (unsigned int) h264->max_fs < max_fs)) {
|
||||
mMaxFrameSize = h264->max_fs;
|
||||
}
|
||||
mMaxMBPS = h264->max_mbps;
|
||||
mMaxBitrate = h264->max_br;
|
||||
mProfile = (h264->profile_level_id & 0x00FF0000) >> 16;
|
||||
mConstraints = (h264->profile_level_id & 0x0000FF00) >> 8;
|
||||
mLevel = (h264->profile_level_id & 0x000000FF);
|
||||
mPacketizationMode = h264->packetization_mode;
|
||||
mSpropParameterSets = h264->sprop_parameter_sets;
|
||||
}
|
||||
}
|
||||
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_nack_type_e type) const
|
||||
{
|
||||
|
|
|
@ -1309,6 +1309,14 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
|
|||
cinst.codecSpecific.H264.constraints = codecInfo->mConstraints;
|
||||
cinst.codecSpecific.H264.level = codecInfo->mLevel;
|
||||
cinst.codecSpecific.H264.packetizationMode = codecInfo->mPacketizationMode;
|
||||
if (codecInfo->mMaxBitrate > 0 && codecInfo->mMaxBitrate < cinst.maxBitrate) {
|
||||
cinst.maxBitrate = codecInfo->mMaxBitrate;
|
||||
}
|
||||
if (codecInfo->mMaxMBPS > 0) {
|
||||
// Not supported yet!
|
||||
CSFLogError(logTag, "%s H.264 max_mbps not supported yet ", __FUNCTION__);
|
||||
}
|
||||
// XXX parse the encoded SPS/PPS data
|
||||
// paranoia
|
||||
cinst.codecSpecific.H264.spsData = nullptr;
|
||||
cinst.codecSpecific.H264.spsLen = 0;
|
||||
|
|
|
@ -385,23 +385,8 @@ extern "C" {
|
|||
#define CREATE_MT_MAP(a,b) ((a << 16) | b)
|
||||
#define DYNAMIC_PAYLOAD_TYPE(x) ((x >> 16) & 0xFFFF)
|
||||
|
||||
#define MAX_SPROP_LEN 32
|
||||
|
||||
#define VCM_ERROR -1
|
||||
|
||||
struct h264_video
|
||||
{
|
||||
char sprop_parameter_set[MAX_SPROP_LEN];
|
||||
int packetization_mode;
|
||||
int profile_level_id;
|
||||
int max_mbps;
|
||||
int max_fs;
|
||||
int max_cpb;
|
||||
int max_dpb;
|
||||
int max_br;
|
||||
int tias_bw;
|
||||
};
|
||||
|
||||
/**
|
||||
* start/stop ringing
|
||||
*
|
||||
|
@ -2394,15 +2379,24 @@ static int vcmTxCreateAudioConduit(int level,
|
|||
static int vcmTxCreateVideoConduit(int level,
|
||||
const vcm_payload_info_t *payload,
|
||||
sipcc::PeerConnectionWrapper &pc,
|
||||
const vcm_mediaAttrs_t *attrs,
|
||||
mozilla::RefPtr<mozilla::MediaSessionConduit> &conduit)
|
||||
{
|
||||
mozilla::VideoCodecConfig *config_raw;
|
||||
struct VideoCodecConfigH264 *negotiated = nullptr;
|
||||
|
||||
if (attrs->video.opaque &&
|
||||
(payload->codec_type == RTP_H264_P0 || payload->codec_type == RTP_H264_P1)) {
|
||||
negotiated = static_cast<struct VideoCodecConfigH264 *>(attrs->video.opaque);
|
||||
}
|
||||
|
||||
config_raw = new mozilla::VideoCodecConfig(
|
||||
payload->remote_rtp_pt,
|
||||
ccsdpCodecName(payload->codec_type),
|
||||
payload->video.rtcp_fb_types,
|
||||
payload->video.max_fs,
|
||||
payload->video.max_fr);
|
||||
payload->video.max_fr,
|
||||
negotiated);
|
||||
|
||||
// Take possession of this pointer
|
||||
mozilla::ScopedDeletePtr<mozilla::VideoCodecConfig> config(config_raw);
|
||||
|
@ -2508,7 +2502,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
|||
err = vcmTxCreateAudioConduit(level, payload, pc, attrs, conduit);
|
||||
} else if (CC_IS_VIDEO(mcap_id)) {
|
||||
mediaType = "video";
|
||||
err = vcmTxCreateVideoConduit(level, payload, pc, conduit);
|
||||
err = vcmTxCreateVideoConduit(level, payload, pc, attrs, conduit);
|
||||
} else {
|
||||
CSFLogError(logTag, "%s: mcap_id unrecognized", __FUNCTION__);
|
||||
}
|
||||
|
@ -2957,17 +2951,23 @@ void vcmFreeMediaPtr(void *ptr)
|
|||
* @return cc_boolean - true if attributes are accepted false otherwise
|
||||
*/
|
||||
|
||||
cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level, void **rcapptr)
|
||||
cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level,
|
||||
int remote_pt, void **rcapptr)
|
||||
{
|
||||
CSFLogDebug( logTag, "vcmCheckAttribs(): media=%d", media_type);
|
||||
|
||||
cc_uint16_t temp;
|
||||
const char *ptr;
|
||||
uint32_t t_uint;
|
||||
struct h264_video *rcap;
|
||||
struct VideoCodecConfigH264 *rcap;
|
||||
|
||||
*rcapptr = nullptr;
|
||||
|
||||
int fmtp_inst = ccsdpAttrGetFmtpInst(sdp_p, level, remote_pt);
|
||||
if (fmtp_inst < 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (media_type)
|
||||
{
|
||||
case RTP_VP8:
|
||||
|
@ -2976,26 +2976,26 @@ cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level, void
|
|||
case RTP_H264_P0:
|
||||
case RTP_H264_P1:
|
||||
|
||||
rcap = (struct h264_video *) cpr_malloc( sizeof(struct h264_video) );
|
||||
rcap = (struct VideoCodecConfigH264 *) cpr_malloc( sizeof(struct VideoCodecConfigH264) );
|
||||
if ( rcap == nullptr )
|
||||
{
|
||||
CSFLogDebug( logTag, "vcmCheckAttribs(): Malloc Failed for rcap");
|
||||
return FALSE;
|
||||
}
|
||||
memset( rcap, 0, sizeof(struct h264_video) );
|
||||
memset( rcap, 0, sizeof(struct VideoCodecConfigH264) );
|
||||
|
||||
if ( (ptr = ccsdpAttrGetFmtpParamSets(sdp_p, level, 0, 1)) != nullptr )
|
||||
if ( (ptr = ccsdpAttrGetFmtpParamSets(sdp_p, level, 0, fmtp_inst)) != nullptr )
|
||||
{
|
||||
memset(rcap->sprop_parameter_set, 0, csf_countof(rcap->sprop_parameter_set));
|
||||
sstrncpy(rcap->sprop_parameter_set, ptr, csf_countof(rcap->sprop_parameter_set));
|
||||
memset(rcap->sprop_parameter_sets, 0, csf_countof(rcap->sprop_parameter_sets));
|
||||
sstrncpy(rcap->sprop_parameter_sets, ptr, csf_countof(rcap->sprop_parameter_sets));
|
||||
}
|
||||
|
||||
if ( ccsdpAttrGetFmtpPackMode(sdp_p, level, 0, 1, &temp) == SDP_SUCCESS )
|
||||
if ( ccsdpAttrGetFmtpPackMode(sdp_p, level, 0, fmtp_inst, &temp) == SDP_SUCCESS )
|
||||
{
|
||||
rcap->packetization_mode = temp;
|
||||
}
|
||||
|
||||
if ( (ptr = ccsdpAttrGetFmtpProfileLevelId(sdp_p, level, 0, 1)) != nullptr )
|
||||
if ( (ptr = ccsdpAttrGetFmtpProfileLevelId(sdp_p, level, 0, fmtp_inst)) != nullptr )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
sscanf_s(ptr, "%x", &rcap->profile_level_id, sizeof(int*));
|
||||
|
@ -3004,32 +3004,32 @@ cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level, void
|
|||
#endif
|
||||
}
|
||||
|
||||
if ( ccsdpAttrGetFmtpMaxMbps(sdp_p, level, 0, 1, &t_uint) == SDP_SUCCESS )
|
||||
if ( ccsdpAttrGetFmtpMaxMbps(sdp_p, level, 0, fmtp_inst, &t_uint) == SDP_SUCCESS )
|
||||
{
|
||||
rcap->max_mbps = t_uint;
|
||||
}
|
||||
|
||||
if ( ccsdpAttrGetFmtpMaxFs(sdp_p, level, 0, 1, &t_uint) == SDP_SUCCESS )
|
||||
if ( ccsdpAttrGetFmtpMaxFs(sdp_p, level, 0, fmtp_inst, &t_uint) == SDP_SUCCESS )
|
||||
{
|
||||
rcap->max_fs = t_uint;
|
||||
}
|
||||
|
||||
if ( ccsdpAttrGetFmtpMaxCpb(sdp_p, level, 0, 1, &t_uint) == SDP_SUCCESS )
|
||||
if ( ccsdpAttrGetFmtpMaxCpb(sdp_p, level, 0, fmtp_inst, &t_uint) == SDP_SUCCESS )
|
||||
{
|
||||
rcap->max_cpb = t_uint;
|
||||
}
|
||||
|
||||
if ( ccsdpAttrGetFmtpMaxCpb(sdp_p, level, 0, 1, &t_uint) == SDP_SUCCESS )
|
||||
if ( ccsdpAttrGetFmtpMaxCpb(sdp_p, level, 0, fmtp_inst, &t_uint) == SDP_SUCCESS )
|
||||
{
|
||||
rcap->max_dpb = t_uint;
|
||||
}
|
||||
|
||||
if ( ccsdpAttrGetFmtpMaxCpb(sdp_p, level, 0, 1, &t_uint) == SDP_SUCCESS )
|
||||
if ( ccsdpAttrGetFmtpMaxCpb(sdp_p, level, 0, fmtp_inst, &t_uint) == SDP_SUCCESS )
|
||||
{
|
||||
rcap->max_br = t_uint;
|
||||
}
|
||||
|
||||
rcap->tias_bw = ccsdpGetBandwidthValue(sdp_p, level, 1);
|
||||
rcap->tias_bw = ccsdpGetBandwidthValue(sdp_p, level, fmtp_inst);
|
||||
if ( rcap->tias_bw == 0 )
|
||||
{
|
||||
// received bandwidth of 0 reject this
|
||||
|
@ -3043,7 +3043,7 @@ cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level, void
|
|||
}
|
||||
|
||||
CSFLogDebug( logTag, "vcmCheckAttribs(): Negotiated media attrs\nsprop=%s\npack_mode=%d\nprofile_level_id=%X\nmbps=%d\nmax_fs=%d\nmax_cpb=%d\nmax_dpb=%d\nbr=%d bw=%d\n",
|
||||
rcap->sprop_parameter_set,
|
||||
rcap->sprop_parameter_sets,
|
||||
rcap->packetization_mode,
|
||||
rcap->profile_level_id,
|
||||
rcap->max_mbps,
|
||||
|
|
|
@ -3501,12 +3501,12 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
|
|||
|
||||
|
||||
} else if (media->type == SDP_MEDIA_VIDEO) {
|
||||
if ( media-> video != NULL ) {
|
||||
if ( media->video != NULL ) {
|
||||
vcmFreeMediaPtr(media->video);
|
||||
media->video = NULL;
|
||||
}
|
||||
|
||||
if (!vcmCheckAttribs(codec, sdp_p, level,
|
||||
if (!vcmCheckAttribs(codec, sdp_p, level, remote_pt,
|
||||
&media->video)) {
|
||||
GSM_DEBUG(DEB_L_C_F_PREFIX"codec= %d ignored - "
|
||||
"attribs not accepted\n",
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
#include "sdp.h"
|
||||
#include "ccapi.h"
|
||||
|
||||
int ccsdpAttrGetFmtpInst(void *sdp_ptr, u16 level, u16 payload_num)
|
||||
{
|
||||
cc_sdp_t *sdpp = sdp_ptr;
|
||||
if ( sdpp->dest_sdp == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
return sdp_find_fmtp_inst(sdpp->dest_sdp, level, payload_num);
|
||||
}
|
||||
|
||||
const char* ccsdpAttrGetFmtpParamSets(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num)
|
||||
|
|
|
@ -1225,6 +1225,7 @@ extern sdp_result_e sdp_add_media_profile_payload_type(void *sdp_ptr,
|
|||
sdp_payload_ind_e indicator);
|
||||
|
||||
/* sdp_attr_access.c */
|
||||
extern int sdp_find_fmtp_inst(sdp_t *sdp_ptr, u16 level, u16 payload_num);
|
||||
extern sdp_result_e sdp_add_new_attr(void *sdp_ptr, u16 level, u8 cap_num,
|
||||
sdp_attr_e attr_type, u16 *inst_num);
|
||||
extern sdp_result_e sdp_copy_attr (void *src_sdp_ptr, void *dst_sdp_ptr,
|
||||
|
|
|
@ -1736,6 +1736,33 @@ sdp_result_e sdp_find_attr_list (sdp_t *sdp_p, u16 level, u8 cap_num,
|
|||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
/* Find fmtp inst_num with correct payload value or -1 for failure */
|
||||
int sdp_find_fmtp_inst (sdp_t *sdp_p, u16 level, u16 payload_num)
|
||||
{
|
||||
u16 attr_count=0;
|
||||
sdp_mca_t *mca_p;
|
||||
sdp_mca_t *cap_p;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
/* Attr is at a media level */
|
||||
mca_p = sdp_find_media_level(sdp_p, level);
|
||||
if (mca_p == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
for (attr_p = mca_p->media_attrs_p; attr_p != NULL;
|
||||
attr_p = attr_p->next_p) {
|
||||
if (attr_p->type == SDP_ATTR_FMTP) {
|
||||
attr_count++;
|
||||
if (attr_p->attr.fmtp.payload_num == payload_num) {
|
||||
return (attr_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (-1);
|
||||
|
||||
}
|
||||
|
||||
/* Function: sdp_find_attr
|
||||
* Description: Find the specified attribute in an SDP structure.
|
||||
* Note: This is not an API for the application but an internal
|
||||
|
@ -12628,4 +12655,3 @@ sdp_attr_set_extmap(void *sdp_ptr, u16 level, u16 id, const char* uri, u16 inst)
|
|||
sstrncpy(attr_p->attr.extmap.uri, uri, SDP_MAX_STRING_LEN+1);
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -263,6 +263,17 @@ typedef enum {
|
|||
SDP_SETUP_UNKNOWN
|
||||
} sdp_setup_type_e;
|
||||
|
||||
/**
|
||||
* Returns the inst_num value for the specified FTMP attr
|
||||
*
|
||||
* @param[in] sdp_handle The SDP handle
|
||||
* @param[in] level The level to check for the attribute.
|
||||
*
|
||||
* @return inst_num The attribute instance number to check, or -1 for failure
|
||||
*/
|
||||
|
||||
int ccsdpAttrGetFmtpInst(void *sdp_handle, uint16_t level, uint16_t payload_num);
|
||||
|
||||
/**
|
||||
* Gets the value of the fmtp attribute- parameter-sets parameter for H.264 codec
|
||||
*
|
||||
|
|
|
@ -1009,12 +1009,14 @@ void vcmSetRtcpDscp(cc_groupid_t group_id, int dscp);
|
|||
* @param [in] media_type - codec for which we are negotiating
|
||||
* @param [in] sdp_p - opaque SDP pointer to be used via SDP helper APIs
|
||||
* @param [in] level - Parameter to be used with SDP helper APIs
|
||||
* @param [in] remote_pt - payload type remote is using for this codec
|
||||
* @param [out] rcapptr - variable to return the allocated attrib structure
|
||||
*
|
||||
* @return cc_boolean - true if attributes are accepted false otherwise
|
||||
*/
|
||||
|
||||
cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level, void **rcapptr);
|
||||
cc_boolean vcmCheckAttribs(cc_uint32_t media_type, void *sdp_p, int level,
|
||||
int remote_pt, void **rcapptr);
|
||||
|
||||
/**
|
||||
* Add Video attributes in the offer/answer SDP
|
||||
|
|
Загрузка…
Ссылка в новой задаче