static struct ast_format *h263_parse_sdp_fmtp(const struct ast_format *format, const char *attributes) { char *attribs = ast_strdupa(attributes), *attrib; struct ast_format *cloned; struct h263_attr *attr; cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); while ((attrib = strsep(&attribs, ";"))) { unsigned int val, val2 = 0, val3 = 0, val4 = 0; if (sscanf(attrib, "SQCIF=%30u", &val) == 1) { attr->SQCIF = val; } else if (sscanf(attrib, "QCIF=%30u", &val) == 1) { attr->QCIF = val; } else if (sscanf(attrib, "CIF=%30u", &val) == 1) { attr->CIF = val; } else if (sscanf(attrib, "CIF4=%30u", &val) == 1) { attr->CIF4 = val; } else if (sscanf(attrib, "CIF16=%30u", &val) == 1) { attr->CIF16 = val; } else if (sscanf(attrib, "VGA=%30u", &val) == 1) { attr->VGA = val; } else if (sscanf(attrib, "CUSTOM=%30u,%30u,%30u", &val, &val2, &val3) == 3) { attr->CUSTOM_XMAX = val; attr->CUSTOM_YMAX = val2; attr->CUSTOM_MPI = val3; } else if (sscanf(attrib, "F=%30u", &val) == 1) { attr->F = val; } else if (sscanf(attrib, "I=%30u", &val) == 1) { attr->I = val; } else if (sscanf(attrib, "J=%30u", &val) == 1) { attr->J = val; } else if (sscanf(attrib, "T=%30u", &val) == 1) { attr->T = val; } else if (sscanf(attrib, "K=%30u", &val) == 1) { attr->K = val; } else if (sscanf(attrib, "N=%30u", &val) == 1) { attr->N = val; } else if (sscanf(attrib, "PAR=%30u:%30u", &val, &val2) == 2) { attr->PAR_WIDTH = val; attr->PAR_HEIGHT = val2; } else if (sscanf(attrib, "BPP=%30u", &val) == 1) { attr->BPP = val; } else if (sscanf(attrib, "HRD=%30u", &val) == 1) { attr->HRD = val; } else if (sscanf(attrib, "P=%30u,%30u,%30u,%30u", &val, &val2, &val3, &val4) > 0) { attr->P_SUB1 = val; attr->P_SUB2 = val2; attr->P_SUB3 = val3; attr->P_SUB4 = val4; } } return cloned; }
static struct ast_format *h264_parse_sdp_fmtp(const struct ast_format *format, const char *attributes) { char *attribs = ast_strdupa(attributes), *attrib; struct ast_format *cloned; struct h264_attr *attr; cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); attr->REDUNDANT_PIC_CAP = H264_ATTR_KEY_UNSET; attr->PARAMETER_ADD = H264_ATTR_KEY_UNSET; attr->PACKETIZATION_MODE = H264_ATTR_KEY_UNSET; attr->LEVEL_ASYMMETRY_ALLOWED = H264_ATTR_KEY_UNSET; while ((attrib = strsep(&attribs, ";"))) { unsigned int val; unsigned long int val2; if (sscanf(attrib, "profile-level-id=%lx", &val2) == 1) { attr->PROFILE_IDC = ((val2 >> 16) & 0xFF); attr->PROFILE_IOP = ((val2 >> 8) & 0xFF); attr->LEVEL = (val2 & 0xFF); } else if (sscanf(attrib, "sprop-parameter-sets=%" H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT "[^','],%" H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT "s", attr->SPS, attr->PPS) == 2) {
static struct ast_format *ilbc_getjoint(const struct ast_format *format1, const struct ast_format *format2) { struct ast_format *jointformat; struct ilbc_attr *attr1 = ast_format_get_attribute_data(format1); struct ilbc_attr *attr2 = ast_format_get_attribute_data(format2); struct ilbc_attr *attr_res; if (!attr1) { attr1 = &default_ilbc_attr; } if (!attr2) { attr2 = &default_ilbc_attr; } jointformat = ast_format_clone(format1); if (!jointformat) { return NULL; } attr_res = ast_format_get_attribute_data(jointformat); if (attr1->mode != attr2->mode) { attr_res->mode = 30; } return jointformat; }
static struct ast_format *silk_set(const struct ast_format *format, const char *name, const char *value) { struct ast_format *cloned; struct silk_attr *attr; unsigned int val; if (sscanf(value, "%30u", &val) != 1) { ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n", value, name); return NULL; } cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); if (!strcasecmp(name, "max_bitrate")) { attr->maxbitrate = val; } else if (!strcasecmp(name, "dtx")) { attr->dtx = val; } else if (!strcasecmp(name, "fec")) { attr->fec = val; } else if (!strcasecmp(name, "packetloss_percentage")) { attr->packetloss_percentage = val; } else { ast_log(LOG_WARNING, "unknown attribute type %s\n", name); } return cloned; }
static struct ast_format *celt_set(const struct ast_format *format, const char *name, const char *value) { struct ast_format *cloned; struct celt_attr *attr; unsigned int val; cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); if (sscanf(value, "%30u", &val) != 1) { ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n", value, name); ao2_ref(cloned, -1); return NULL; } if (!strcasecmp(name, "sample_rate")) { attr->samplerate = val; } else if (!strcasecmp(name, "max_bitrate")) { attr->maxbitrate = val; } else if (!strcasecmp(name, "frame_size")) { attr->framesize = val; } else { ast_log(LOG_WARNING, "Unknown attribute type '%s'\n", name); ao2_ref(cloned, -1); return NULL; } return cloned; }
static struct ast_format *celt_getjoint(const struct ast_format *format1, const struct ast_format *format2) { struct celt_attr *attr1 = ast_format_get_attribute_data(format1); struct celt_attr *attr2 = ast_format_get_attribute_data(format2); struct ast_format *jointformat; struct celt_attr *jointattr; if (attr1 && attr2 && (attr1->samplerate != attr2->samplerate)) { return NULL; } jointformat = ast_format_clone(format1); if (!jointformat) { return NULL; } jointattr = ast_format_get_attribute_data(jointformat); /* either would work, they are guaranteed the same at this point. */ jointattr->samplerate = attr1->samplerate; /* Take the lowest max bitrate */ jointattr->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate); jointattr->framesize = attr2->framesize; /* TODO figure out what joint framesize means */ return jointformat; }
static struct ast_format *h264_getjoint(const struct ast_format *format1, const struct ast_format *format2) { struct ast_format *cloned; struct h264_attr *attr, *attr1, *attr2; cloned = ast_format_clone(format1); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); attr1 = ast_format_get_attribute_data(format1); attr2 = ast_format_get_attribute_data(format2); DETERMINE_JOINT(attr, attr1, attr2, PROFILE_IDC); DETERMINE_JOINT(attr, attr1, attr2, PROFILE_IOP); DETERMINE_JOINT(attr, attr1, attr2, LEVEL); DETERMINE_JOINT(attr, attr1, attr2, MAX_MBPS); DETERMINE_JOINT(attr, attr1, attr2, MAX_FS); DETERMINE_JOINT(attr, attr1, attr2, MAX_CPB); DETERMINE_JOINT(attr, attr1, attr2, MAX_DPB); DETERMINE_JOINT(attr, attr1, attr2, MAX_BR); DETERMINE_JOINT(attr, attr1, attr2, MAX_SMBPS); DETERMINE_JOINT(attr, attr1, attr2, MAX_FPS); DETERMINE_JOINT(attr, attr1, attr2, REDUNDANT_PIC_CAP); DETERMINE_JOINT(attr, attr1, attr2, PARAMETER_ADD); DETERMINE_JOINT(attr, attr1, attr2, SPROP_INTERLEAVING_DEPTH); DETERMINE_JOINT(attr, attr1, attr2, SPROP_DEINT_BUF_REQ); DETERMINE_JOINT(attr, attr1, attr2, DEINT_BUF_CAP); DETERMINE_JOINT(attr, attr1, attr2, SPROP_INIT_BUF_TIME); DETERMINE_JOINT(attr, attr1, attr2, SPROP_MAX_DON_DIFF); DETERMINE_JOINT(attr, attr1, attr2, MAX_RCMD_NALU_SIZE); DETERMINE_JOINT(attr, attr1, attr2, LEVEL_ASYMMETRY_ALLOWED); DETERMINE_JOINT(attr, attr1, attr2, PACKETIZATION_MODE); if (attr1 && !ast_strlen_zero(attr1->SPS)) { ast_copy_string(attr->SPS, attr1->SPS, sizeof(attr->SPS)); } else if (attr2 && !ast_strlen_zero(attr2->SPS)) { ast_copy_string(attr->SPS, attr2->SPS, sizeof(attr->SPS)); } if (attr1 && !ast_strlen_zero(attr1->PPS)) { ast_copy_string(attr->PPS, attr1->PPS, sizeof(attr->PPS)); } else if (attr2 && !ast_strlen_zero(attr2->PPS)) { ast_copy_string(attr->PPS, attr2->PPS, sizeof(attr->PPS)); } return cloned; }
static struct ast_format *celt_parse_sdp_fmtp(const struct ast_format *format, const char *attributes) { struct ast_format *cloned; struct celt_attr *attr; unsigned int val; cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); if (sscanf(attributes, "framesize=%30u", &val) == 1) { attr->framesize = val; } return cloned; }
static struct ast_format *ilbc_parse_sdp_fmtp(const struct ast_format *format, const char *attributes) { struct ast_format *cloned; struct ilbc_attr *attr; const char *kvp; unsigned int val; cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); if ((kvp = strstr(attributes, "mode")) && sscanf(kvp, "mode=%30u", &val) == 1) { attr->mode = val; } else { attr->mode = 30; /* optional attribute; 30 is default value */ } return cloned; }
static struct ast_format *h263_getjoint(const struct ast_format *format1, const struct ast_format *format2) { struct ast_format *cloned; struct h263_attr *attr, *attr1, *attr2; cloned = ast_format_clone(format1); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); attr1 = ast_format_get_attribute_data(format1); attr2 = ast_format_get_attribute_data(format2); DETERMINE_JOINT(attr, attr1, attr2, SQCIF); DETERMINE_JOINT(attr, attr1, attr2, QCIF); DETERMINE_JOINT(attr, attr1, attr2, CIF); DETERMINE_JOINT(attr, attr1, attr2, CIF4); DETERMINE_JOINT(attr, attr1, attr2, CIF16); DETERMINE_JOINT(attr, attr1, attr2, VGA); DETERMINE_JOINT(attr, attr1, attr2, CUSTOM_XMAX); DETERMINE_JOINT(attr, attr1, attr2, CUSTOM_YMAX); DETERMINE_JOINT(attr, attr1, attr2, CUSTOM_MPI); DETERMINE_JOINT(attr, attr1, attr2, F); DETERMINE_JOINT(attr, attr1, attr2, I); DETERMINE_JOINT(attr, attr1, attr2, J); DETERMINE_JOINT(attr, attr1, attr2, T); DETERMINE_JOINT(attr, attr1, attr2, K); DETERMINE_JOINT(attr, attr1, attr2, N); DETERMINE_JOINT(attr, attr1, attr2, P_SUB1); DETERMINE_JOINT(attr, attr1, attr2, P_SUB2); DETERMINE_JOINT(attr, attr1, attr2, P_SUB3); DETERMINE_JOINT(attr, attr1, attr2, P_SUB4); DETERMINE_JOINT(attr, attr1, attr2, PAR_WIDTH); DETERMINE_JOINT(attr, attr1, attr2, PAR_HEIGHT); DETERMINE_JOINT(attr, attr1, attr2, BPP); DETERMINE_JOINT(attr, attr1, attr2, HRD); return cloned; }
static struct ast_format *silk_getjoint(const struct ast_format *format1, const struct ast_format *format2) { struct silk_attr *attr1 = ast_format_get_attribute_data(format1); struct silk_attr *attr2 = ast_format_get_attribute_data(format2); struct ast_format *jointformat; struct silk_attr *attr_res; if (ast_format_get_sample_rate(format1) != ast_format_get_sample_rate(format2)) { return NULL; } jointformat = ast_format_clone(format1); if (!jointformat) { return NULL; } attr_res = ast_format_get_attribute_data(jointformat); if (!attr1 || !attr2) { attr_init(attr_res); } else { /* Take the lowest max bitrate */ attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate); /* Only do dtx if both sides want it. DTX is a trade off between * computational complexity and bandwidth. */ attr_res->dtx = attr1->dtx && attr2->dtx ? 1 : 0; /* Only do FEC if both sides want it. If a peer specifically requests not * to receive with FEC, it may be a waste of bandwidth. */ attr_res->fec = attr1->fec && attr2->fec ? 1 : 0; /* Use the maximum packetloss percentage between the two attributes. This affects how * much redundancy is used in the FEC. */ attr_res->packetloss_percentage = MAX(attr1->packetloss_percentage, attr2->packetloss_percentage); } return jointformat; }
static struct ast_format *silk_parse_sdp_fmtp(const struct ast_format *format, const char *attributes) { struct ast_format *cloned; struct silk_attr *attr; unsigned int val; cloned = ast_format_clone(format); if (!cloned) { return NULL; } attr = ast_format_get_attribute_data(cloned); if (sscanf(attributes, "maxaveragebitrate=%30u", &val) == 1) { attr->maxbitrate = val; } if (sscanf(attributes, "usedtx=%30u", &val) == 1) { attr->dtx = val; } if (sscanf(attributes, "useinbandfec=%30u", &val) == 1) { attr->fec = val; } return cloned; }