--- res/res_format_attr_h263.c (Asterisk 13.38.1) +++ res/res_format_attr_h263.c (working copy) @@ -40,2 +40,5 @@ +/*! \brief Value that indicates an attribute is actually unset */ +#define H263_ATTR_KEY_UNSET UINT8_MAX + struct h263_attr { @@ -50,2 +53,10 @@ struct h263_attr { unsigned int CUSTOM_MPI; /*!< Custom resolution (MPI) */ + unsigned int CPCF; /*!< Custom Picture Clock Frequency */ + unsigned int CPCF_2; + unsigned int CPCF_3; + unsigned int CPCF_4; + unsigned int CPCF_5; + unsigned int CPCF_6; + unsigned int CPCF_7; + unsigned int CPCF_MPI; unsigned int F; /*!< F annex support */ @@ -64,2 +75,3 @@ struct h263_attr { unsigned int HRD; /*!< Hypothetical reference decoder status */ + unsigned int MaxBR; /*!< Vendor Specific: CounterPath Bria (Solo) */ }; @@ -127,2 +139,10 @@ static struct ast_format *h263_getjoint( DETERMINE_JOINT(attr, attr1, attr2, CUSTOM_MPI); + DETERMINE_JOINT(attr, attr1, attr2, CPCF); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_2); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_3); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_4); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_5); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_6); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_7); + DETERMINE_JOINT(attr, attr1, attr2, CPCF_MPI); DETERMINE_JOINT(attr, attr1, attr2, F); @@ -141,2 +161,3 @@ static struct ast_format *h263_getjoint( DETERMINE_JOINT(attr, attr1, attr2, HRD); + DETERMINE_JOINT(attr, attr1, attr2, MaxBR); @@ -157,4 +178,9 @@ static struct ast_format *h263_parse_sdp + attr->BPP = H263_ATTR_KEY_UNSET; + attr->MaxBR = H263_ATTR_KEY_UNSET; + attr->PAR_WIDTH = H263_ATTR_KEY_UNSET; + attr->PAR_HEIGHT = H263_ATTR_KEY_UNSET; + while ((attrib = strsep(&attribs, ";"))) { - unsigned int val, val2 = 0, val3 = 0, val4 = 0; + unsigned int val, val2 = 0, val3 = 0, val4 = 0, val5 = 0, val6 = 0, val7 = 0, val8 = 0; @@ -164,12 +190,24 @@ static struct ast_format *h263_parse_sdp attr->SQCIF = val; + } else if (strcmp(attrib, "SQCIF") == 0) { + attr->SQCIF = 1; } else if (sscanf(attrib, "QCIF=%30u", &val) == 1) { attr->QCIF = val; + } else if (strcmp(attrib, "QCIF") == 0) { + attr->QCIF = 1; } else if (sscanf(attrib, "CIF=%30u", &val) == 1) { attr->CIF = val; + } else if (strcmp(attrib, "CIF") == 0) { + attr->CIF = 1; } else if (sscanf(attrib, "CIF4=%30u", &val) == 1) { attr->CIF4 = val; + } else if (strcmp(attrib, "CIF4") == 0) { + attr->CIF4 = 1; } else if (sscanf(attrib, "CIF16=%30u", &val) == 1) { attr->CIF16 = val; + } else if (strcmp(attrib, "CIF16") == 0) { + attr->CIF16 = 1; } else if (sscanf(attrib, "VGA=%30u", &val) == 1) { attr->VGA = val; + } else if (strcmp(attrib, "VGA") == 0) { + attr->VGA = 1; } else if (sscanf(attrib, "CUSTOM=%30u,%30u,%30u", &val, &val2, &val3) == 3) { @@ -178,2 +216,12 @@ static struct ast_format *h263_parse_sdp attr->CUSTOM_MPI = val3; + } else if (sscanf(attrib, "CPCF=%30u,%30u,%30u,%30u,%30u,%30u,%30u,%30u", + &val, &val2, &val3, &val4, &val5, &val6, &val7, &val8) == 8) { + attr->CPCF = val; + attr->CPCF_2 = val2; + attr->CPCF_3 = val3; + attr->CPCF_4 = val4; + attr->CPCF_5 = val5; + attr->CPCF_6 = val6; + attr->CPCF_7 = val7; + attr->CPCF_MPI = val8; } else if (sscanf(attrib, "F=%30u", &val) == 1) { @@ -202,2 +250,4 @@ static struct ast_format *h263_parse_sdp attr->P_SUB4 = val4; + } else if (sscanf(attrib, "MAXBR=%30u", &val) == 1) { + attr->MaxBR = val; } @@ -208,2 +258,24 @@ static struct ast_format *h263_parse_sdp +#define APPEND_IF_NOT_H263_UNSET(field, str, name) do { \ + if (field != H263_ATTR_KEY_UNSET) { \ + if (added) { \ + ast_str_append(str, 0, ";"); \ + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { \ + added = 1; \ + } \ + ast_str_append(str, 0, "%s=%u", name, field); \ + } \ +} while (0) + +#define APPEND_IF_NONZERO(field, str, name) do { \ + if (field) { \ + if (added) { \ + ast_str_append(str, 0, ";"); \ + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { \ + added = 1; \ + } \ + ast_str_append(str, 0, "%s=%u", name, field); \ + } \ +} while (0) + static void h263_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str) @@ -211,2 +283,3 @@ static void h263_generate_sdp_fmtp(const struct h263_attr *attr = ast_format_get_attribute_data(format); + int added = 0; @@ -216,16 +289,42 @@ static void h263_generate_sdp_fmtp(const - ast_str_append(str, 0, "a=fmtp:%u SQCIF=%u;QCIF=%u;CIF=%u;CIF4=%u;CIF16=%u;VGA=%u;F=%u;I=%u;J=%u;T=%u;K=%u;N=%u;BPP=%u;HRD=%u", - payload, attr->SQCIF, attr->QCIF, attr->CIF, attr->CIF4, attr->CIF16, attr->VGA, attr->F, attr->I, attr->J, - attr->T, attr->K, attr->N, attr->BPP, attr->HRD); + if (attr->CPCF) { + if (added) { + ast_str_append(str, 0, ";"); + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { + added = 1; + } + ast_str_append(str, 0, "CPCF=%u,%u,%u,%u,%u,%u,%u,%u", attr->CPCF, attr->CPCF_2, attr->CPCF_3, + attr->CPCF_4, attr->CPCF_5, attr->CPCF_6, attr->CPCF_7, attr->CPCF_MPI); + } + + APPEND_IF_NONZERO(attr->CIF16, str, "CIF16"); + APPEND_IF_NONZERO(attr->CIF4, str, "CIF4"); + APPEND_IF_NONZERO(attr->VGA, str, "VGA"); + APPEND_IF_NONZERO(attr->CIF, str, "CIF"); + APPEND_IF_NONZERO(attr->QCIF, str, "QCIF"); + APPEND_IF_NONZERO(attr->SQCIF, str, "SQCIF"); if (attr->CUSTOM_XMAX && attr->CUSTOM_YMAX && attr->CUSTOM_MPI) { - ast_str_append(str, 0, ";CUSTOM=%u,%u,%u", attr->CUSTOM_XMAX, attr->CUSTOM_YMAX, attr->CUSTOM_MPI); + if (added) { + ast_str_append(str, 0, ";"); + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { + added = 1; + } + ast_str_append(str, 0, "CUSTOM=%u,%u,%u", attr->CUSTOM_XMAX, attr->CUSTOM_YMAX, attr->CUSTOM_MPI); } - if (attr->PAR_WIDTH && attr->PAR_HEIGHT) { - ast_str_append(str, 0, ";PAR=%u:%u", attr->PAR_WIDTH, attr->PAR_HEIGHT); - } + APPEND_IF_NONZERO(attr->F, str, "F"); + APPEND_IF_NONZERO(attr->I, str, "I"); + APPEND_IF_NONZERO(attr->J, str, "J"); + APPEND_IF_NONZERO(attr->T, str, "T"); + APPEND_IF_NONZERO(attr->K, str, "K"); + APPEND_IF_NONZERO(attr->N, str, "N"); if (attr->P_SUB1) { - ast_str_append(str, 0, ";P=%u", attr->P_SUB1); + if (added) { + ast_str_append(str, 0, ";"); + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { + added = 1; + } + ast_str_append(str, 0, "P=%u", attr->P_SUB1); if (attr->P_SUB2) { @@ -241,2 +340,17 @@ static void h263_generate_sdp_fmtp(const + if (attr->PAR_WIDTH != H263_ATTR_KEY_UNSET && attr->PAR_HEIGHT != H263_ATTR_KEY_UNSET) { + if (added) { + ast_str_append(str, 0, ";"); + } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) { + added = 1; \ + } + ast_str_append(str, 0, "PAR=%u:%u", attr->PAR_WIDTH, attr->PAR_HEIGHT); + } + + APPEND_IF_NOT_H263_UNSET(attr->BPP, str, "BPP"); + + APPEND_IF_NONZERO(attr->HRD, str, "HRD"); + + APPEND_IF_NOT_H263_UNSET(attr->MaxBR, str, "MaxBR"); + ast_str_append(str, 0, "\r\n");