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;
}
Example #2
0
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;
}