/* Get the SDP attributes for the stream config */ char* getSdpPayloadForStreamConfig(int rtspClientVersion, int *length) { PSDP_OPTION attributeList; int offset; char* payload; char urlSafeAddr[URLSAFESTRING_LEN]; addrToUrlSafeString(&RemoteAddr, urlSafeAddr); attributeList = getAttributesList(urlSafeAddr); if (attributeList == NULL) { return NULL; } payload = malloc(MAX_SDP_HEADER_LEN + MAX_SDP_TAIL_LEN + getSerializedAttributeListSize(attributeList)); if (payload == NULL) { freeAttributeList(attributeList); return NULL; } offset = fillSdpHeader(payload, rtspClientVersion, urlSafeAddr); offset += fillSerializedAttributeList(&payload[offset], attributeList); offset += fillSdpTail(&payload[offset]); freeAttributeList(attributeList); *length = offset; return payload; }
/* Get the SDP attributes for the stream config */ char* getSdpPayloadForStreamConfig(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress, int rtspClientVersion, int *length) { PSDP_OPTION attributeList; int offset; char* payload; attributeList = getAttributesList(streamConfig, targetAddress); if (attributeList == NULL) { return NULL; } payload = malloc(MAX_SDP_HEADER_LEN + MAX_SDP_TAIL_LEN + getSerializedAttributeListSize(attributeList)); if (payload == NULL) { freeAttributeList(attributeList); return NULL; } offset = fillSdpHeader(payload, targetAddress, rtspClientVersion); offset += fillSerializedAttributeList(&payload[offset], attributeList); offset += fillSdpTail(&payload[offset]); freeAttributeList(attributeList); *length = offset; return payload; }
static void freeElementListStep(XmlElement *first, XmlElement *element) { freeElementList(element->children); freeAttributeList(element->attributes); if (element->next != first) freeElementListStep(first, element->next); free(element->value); free(element->name); free(element); }
static XmlAttribute * parseAttribute(XmlDoc *doc, const char **xmlText, XmlElement *element) { const char *startval; XmlAttribute *attribute = calloc(1, sizeof(XmlAttribute)); attribute->next = attribute->prev = attribute; attribute->parent = element; attribute->name = readBareWord(xmlText, "="); if (!attribute->name) FAIL(XML_UNNAMEDATTR); if (!**xmlText) FAIL(XML_EOF); skipWs(doc, xmlText); if (**xmlText != '=') FAILC(XML_UNEXPECTED, **xmlText); ++(*xmlText); skipWs(doc, xmlText); if (**xmlText == '"' || **xmlText == '\'') { ++(*xmlText); startval = *xmlText; skipUntil(doc, xmlText, *(*xmlText-1)); if (!**xmlText) FAIL(XML_EOF); if (*xmlText - startval) { attribute->value = calloc(1, (size_t)(*xmlText - startval) + 1); memcpy(attribute->value, startval, (size_t)(*xmlText - startval)); } ++(*xmlText); return attribute; } else { attribute->value = readBareWord(xmlText, "/>"); if (!**xmlText) FAIL(XML_EOF); return attribute; } fail: doc->col = *xmlText - doc->currLine + 1; freeAttributeList(attribute); return 0; }
static PSDP_OPTION getAttributesList(char *urlSafeAddr) { PSDP_OPTION optionHead; char payloadStr[92]; int err; optionHead = NULL; err = 0; sprintf(payloadStr, "%d", StreamConfig.width); err |= addAttributeString(&optionHead, "x-nv-video[0].clientViewportWd", payloadStr); sprintf(payloadStr, "%d", StreamConfig.height); err |= addAttributeString(&optionHead, "x-nv-video[0].clientViewportHt", payloadStr); sprintf(payloadStr, "%d", StreamConfig.fps); err |= addAttributeString(&optionHead, "x-nv-video[0].maxFPS", payloadStr); sprintf(payloadStr, "%d", StreamConfig.packetSize); err |= addAttributeString(&optionHead, "x-nv-video[0].packetSize", payloadStr); err |= addAttributeString(&optionHead, "x-nv-video[0].rateControlMode", "4"); // FIXME: Remote optimizations if (StreamConfig.bitrate <= 13000) { err |= addAttributeString(&optionHead, "x-nv-video[0].averageBitrate", "9"); err |= addAttributeString(&optionHead, "x-nv-video[0].peakBitrate", "9"); } err |= addAttributeString(&optionHead, "x-nv-video[0].timeoutLengthMs", "7000"); err |= addAttributeString(&optionHead, "x-nv-video[0].framesWithInvalidRefThreshold", "0"); // Lock the bitrate since we're not scaling resolution so the picture doesn't get too bad if (StreamConfig.height >= 1080 && StreamConfig.fps >= 60) { if (StreamConfig.bitrate < 10000) { sprintf(payloadStr, "%d", StreamConfig.bitrate); err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", payloadStr); } else { err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", "10000"); } } else if (StreamConfig.height >= 1080 || StreamConfig.fps >= 60) { if (StreamConfig.bitrate < 7000) { sprintf(payloadStr, "%d", StreamConfig.bitrate); err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", payloadStr); } else { err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", "7000"); } } else { if (StreamConfig.bitrate < 3000) { sprintf(payloadStr, "%d", StreamConfig.bitrate); err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", payloadStr); } else { err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.minimumBitrate", "3000"); } } sprintf(payloadStr, "%d", StreamConfig.bitrate); err |= addAttributeString(&optionHead, "x-nv-vqos[0].bw.maximumBitrate", payloadStr); // Using FEC turns padding on which makes us have to take the slow path // in the depacketizer, not to mention exposing some ambiguous cases with // distinguishing padding from valid sequences. Since we can only perform // execute an FEC recovery on a 1 packet frame, we'll just turn it off completely. err |= addAttributeString(&optionHead, "x-nv-vqos[0].fec.enable", "0"); err |= addAttributeString(&optionHead, "x-nv-vqos[0].videoQualityScoreUpdateTime", "5000"); // FIXME: Remote optimizations err |= addAttributeString(&optionHead, "x-nv-vqos[0].qosTrafficType", "5"); err |= addAttributeString(&optionHead, "x-nv-aqos.qosTrafficType", "4"); if (ServerMajorVersion == 3) { err |= addGen3Options(&optionHead, urlSafeAddr); } else { err |= addGen4Options(&optionHead, urlSafeAddr); } if (err == 0) { return optionHead; } freeAttributeList(optionHead); return NULL; }
int32_t GCConfigTest::allocationWalker(pugi::xml_node node) { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 0; AttributeElem *numOfFieldsElem = NULL; AttributeElem *breadthElem = NULL; int32_t depth = 0; OMRGCObjectType objType = INVALID; const char *namePrefixStr = node.attribute("namePrefix").value(); const char *numOfFieldsStr = node.attribute("numOfFields").value(); const char *typeStr = node.attribute("type").value(); const char *breadthStr = node.attribute("breadth").value(); const char *depthStr = node.attribute("depth").value(); if (0 != strcmp(node.name(), "object")) { /* allow non-object node nested inside allocation? */ goto done; } if ((0 == strcmp(namePrefixStr, "")) || (0 == strcmp(typeStr, "")) || (0 == strcmp(numOfFieldsStr, ""))) { rt = 1; omrtty_printf("%s:%d Invalid XML input: please specify namePrefix, type and numOfFields for object %s.\n", __FILE__, __LINE__, namePrefixStr); goto done; } /* set default value for breadth and depth to 1 */ if (0 == strcmp(breadthStr, "")) { breadthStr = "1"; } if (0 == strcmp(depthStr, "")) { depthStr = "1"; } depth = atoi(depthStr); objType = parseObjectType(node); rt = parseAttribute(&numOfFieldsElem, numOfFieldsStr); OMRGCTEST_CHECK_RT(rt) rt = parseAttribute(&breadthElem, breadthStr); OMRGCTEST_CHECK_RT(rt); /* process current xml node, perform allocation for single object or object tree */ rt = processObjNode(node, namePrefixStr, objType, numOfFieldsElem, breadthElem, depth); OMRGCTEST_CHECK_RT(rt); /* only single object can contain nested child object */ if ((0 == strcmp(breadthStr, "1")) && (0 == strcmp(depthStr, "1"))) { for (pugi::xml_node childNode = node.first_child(); childNode; childNode = childNode.next_sibling()) { rt = allocationWalker(childNode); OMRGCTEST_CHECK_RT(rt); } } /* After the entire garbage tree is allocated, remove garbage root object from the root set * or remove garbage top object from the slot of its parent object. */ if (GARBAGE_ROOT == objType) { for (int32_t i = 0; i < breadthElem->value; i++) { char objName[MAX_NAME_LENGTH]; omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefixStr, 0, i); rt = removeObjectFromRootTable(objName); OMRGCTEST_CHECK_RT(rt); } } else if (GARBAGE_TOP == objType) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parentPtr = parentEntry->objPtr; for (int32_t i = 0; i < breadthElem->value; i++) { char objName[MAX_NAME_LENGTH]; omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefixStr, 0, i); rt = removeObjectFromParentSlot(objName, parentPtr); OMRGCTEST_CHECK_RT(rt); } } /* insert garbage per tree */ if ((0 == strcmp(gp.frequency, "perRootStruct")) && (ROOT == objType)){ rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } done: freeAttributeList(breadthElem); freeAttributeList(numOfFieldsElem); return rt; }