FskErr latmPacketParserCanHandle(SDPMediaDescription mediaDescription, const char *encodingName) { Boolean canHandle = false; // We handle MP4A-LATM encoding if (0 != FskStrCompareCaseInsensitive("MP4A-LATM", encodingName)) goto bail; if (NULL != mediaDescription) { SDPAttribute attribute; attribute = SDPFindMediaAttribute(mediaDescription, "fmtp"); if (NULL != attribute) { char *attr; // The config string must be present in the SDP (i.e. out of band) if (NULL != copyAttributeValue(attribute->value, "cpresent", &attr)) { canHandle = (0 == FskStrToNum(attr)); FskMemPtrDispose(attr); } // Validate the configuration if (canHandle) { if (NULL != copyAttributeValue(attribute->value, "config", &attr)) { canHandle = validateConfig(attr, NULL, NULL, NULL, NULL, NULL); FskMemPtrDispose(attr); } else canHandle = false; } } } bail: return canHandle ? 0 : kFskErrRTSPPacketParserUnsupportedFormat; }
void XmlUniformiser::copyElementAttributes() { do { bool hadSpace = isSpace(); skipSpaces(); if ( startsWith( ">" ) ) break; if ( hadSpace ) m_stripped += ' '; copyAttributeName(); skipSpaces(); if ( startsWith( "=" ) ) { copyNext(); copyAttributeValue(); } else // attribute should always be valued, ne ? m_stripped += ' '; } while ( isValidIndex() ); copyNext(); }
FskErr latmPacketParserNew(RTPPacketParser parser) { FskErr err; LATMPacketParser latmPacketParser; SDPMediaDescription mediaDescription; err = FskMemPtrNewClear(sizeof(LATMPacketParserRecord), &latmPacketParser); BAIL_IF_ERR(err); parser->handlerRefCon = latmPacketParser; parser->mediaFormat = kRTPAudioFormatAAC; latmPacketParser->bitsPerSample = 16; latmPacketParser->mediaFormat = kRTPAudioFormatAAC; mediaDescription = parser->mediaDescription; if (NULL != mediaDescription) { SDPAttribute attribute; // Grab what we need from the "fmtp" attribute attribute = SDPFindMediaAttribute(mediaDescription, "fmtp"); if (NULL != attribute) { char *value, *attr; value = FskStrDoCopy(attribute->value); if (NULL != copyAttributeValue(value, "config", &attr)) { latmPacketParser->config = FskStrDoCopy(attr); FskMemPtrDispose(attr); } FskMemPtrDispose(value); } } // Build an ESDS compatible with Kinoma Player / FhG decoder if (!validateConfig(latmPacketParser->config, &latmPacketParser->nChannels, &latmPacketParser->sampleRate, &latmPacketParser->nSubFrames, latmPacketParser->esds, &latmPacketParser->esdsSize)) { err = kFskErrRTSPPacketParserUnsupportedFormat; } bail: return err; }
FskErr h263PacketParserNew(RTPPacketParser parser) { FskErr err; H263PacketParser h263PacketParser; SDPMediaDescription mediaDescription; SDPAttribute attribute; err = FskMemPtrNew(sizeof(H263PacketParserRecord), &h263PacketParser); if (0 != err) goto bail; parser->handlerRefCon = h263PacketParser; h263PacketParser->frames = NULL; h263PacketParser->mediaFormat = kRTPVideoFormatH263; h263PacketParser->width = 0; h263PacketParser->height = 0; h263PacketParser->lastTimeStamp = 0; // look for the "a=framesize" attribute in the SDP for width and height // referenced in 3GPP TS 26.234 version 6.3.0 Release 6 if (0 == h263PacketParser->width) { char *tmp = NULL, *p[3] = {0}; UInt16 nParts; attribute = SDPFindMediaAttribute(parser->mediaDescription, "framesize"); if (attribute) { SDPMediaFormat mediaFormat = parser->mediaDescription->formatList->head; tmp = FskStrDoCopy(attribute->value); splitToken(tmp, &nParts, ' ', &p[0]); if ((UInt32)FskStrToNum(p[0]) == mediaFormat->payloadType) { splitToken(p[1], &nParts, '-', &p[0]); h263PacketParser->width = FskStrToNum(p[0]); h263PacketParser->height = FskStrToNum(p[1]); } FskMemPtrDispose(tmp); } } // look for the "a=Width" and "a=Height" attributes (TMI server) // a=Width:integer;176 // a=Height:integer;144 if (0 == h263PacketParser->width) { char *p[3] = {0}; UInt16 nParts; attribute = SDPFindMediaAttribute(parser->mediaDescription, "Width"); if (attribute) { char *value; value = FskStrDoCopy(attribute->value); splitToken(value, &nParts, ';', &p[0]); h263PacketParser->width = FskStrToNum(p[1]); FskMemPtrDispose(value); } } if (0 == h263PacketParser->height) { char *p[3] = {0}; UInt16 nParts; attribute = SDPFindMediaAttribute(parser->mediaDescription, "Height"); if (attribute) { char *value; value = FskStrDoCopy(attribute->value); splitToken(value, &nParts, ';', &p[0]); h263PacketParser->height = FskStrToNum(p[1]); FskMemPtrDispose(value); } } // Next try the cliprect attribute if (0 == h263PacketParser->width) { attribute = SDPFindMediaAttribute(parser->mediaDescription, "cliprect"); if (NULL != attribute) { char *value, *parts[5]; UInt16 nParts; value = FskStrDoCopy(attribute->value); splitToken(value, &nParts, ',', &parts[0]); if (4 == nParts) { h263PacketParser->width = FskStrToNum(parts[3]); h263PacketParser->height = FskStrToNum(parts[2]); } FskMemPtrDispose(value); } } // Next try the framesize in the fmtp attribute if (0 == h263PacketParser->width) { attribute = SDPFindMediaAttribute(parser->mediaDescription, "fmtp"); if (NULL != attribute) { char *attr; if (NULL != copyAttributeValue(attribute->value, "framesize", &attr)) { char *value, *parts[5]; UInt16 nParts; value = FskStrDoCopy(attr); splitToken(value, &nParts, '-', &parts[0]); if (2 == nParts) { h263PacketParser->width = FskStrToNum(parts[0]); h263PacketParser->height = FskStrToNum(parts[1]); } FskMemPtrDispose(attr); FskMemPtrDispose(value); } } } // Grab the timescale - should always be 90000 h263PacketParser->timeScale = 90000; mediaDescription = parser->mediaDescription; if (NULL != mediaDescription) { SDPAttribute attribute; attribute = SDPFindMediaAttribute(mediaDescription, "rtpmap"); if (NULL != attribute) { char *value, *parts[4]; UInt16 nParts = 2; value = FskStrDoCopy(attribute->value); splitToken(value, &nParts, '/', &parts[0]); h263PacketParser->timeScale = FskStrToNum(parts[1]); FskMemPtrDispose(value); } } bail: return err; }