bool StreamCapabilities::Deserialize(string seekFilePath, StreamCapabilities &capabilities) { File file; if (!file.Initialize(seekFilePath, FILE_OPEN_MODE_READ)) { FATAL("Unable to open seek file %s", STR(seekFilePath)); return false; } uint32_t length = 0; if (!file.ReadUI32(&length, false)) { FATAL("Unable to read stream capabilities length from file %s", STR(seekFilePath)); return false; } if (length > 1024 * 1024) { FATAL("Invalid stream capabilities length in file %s: %"PRIu32, STR(seekFilePath), length); return false; } IOBuffer buffer; buffer.ReadFromRepeat(0, length); if (!file.ReadBuffer(GETIBPOINTER(buffer), length)) { FATAL("Unable to read stream capabilities payload from file %s", STR(seekFilePath)); return false; } file.Close(); if (!Deserialize(buffer, capabilities)) { FATAL("Unable to deserialize stream capabilities from file %s", STR(seekFilePath)); return false; } return true; }
bool AMF0Serializer::WriteDouble(IOBuffer &buffer, double value, bool writeType) { if (writeType) buffer.ReadFromRepeat(AMF0_NUMBER, 1); uint64_t temp = 0; EHTOND(value, temp); buffer.ReadFromBuffer((uint8_t *) & temp, 8); return true; }
bool AMF0Serializer::WriteShortString(IOBuffer &buffer, string &value, bool writeType) { if (writeType) buffer.ReadFromRepeat(AMF0_SHORT_STRING, 1); uint16_t length = EHTONS((uint16_t) value.length()); //----MARKED-SHORT---- buffer.ReadFromBuffer((uint8_t *) & length, 2); buffer.ReadFromString(value); return true; }
bool AMF0Serializer::WriteLongString(IOBuffer &buffer, string &value, bool writeType) { if (writeType) buffer.ReadFromRepeat(AMF0_LONG_STRING, 1); uint32_t length = EHTONL((uint32_t) value.length()); buffer.ReadFromBuffer((uint8_t *) & length, 4); buffer.ReadFromString(value); return true; }
bool InFileRTMPStream::MP3Builder::BuildFrame(MediaFile *pFile, MediaFrame &mediaFrame, IOBuffer &buffer) { buffer.ReadFromRepeat(0x2f, 1); //2. Seek into the data file at the correct position if (!pFile->SeekTo(mediaFrame.start)) { FATAL("Unable to seek to position %"PRIu64, mediaFrame.start); return false; } //3. Read the data if (!buffer.ReadFromFs(*pFile, (uint32_t) mediaFrame.length)) { FATAL("Unable to read %"PRIu64" bytes from offset %"PRIu64, mediaFrame.length, mediaFrame.start); return false; } return true; }
void AtomMVHD::SerializeToBuffer(IOBuffer& data, uint32_t maxFrames) { uint32_t start=GETAVAILABLEBYTESCOUNT(data); VersionedAtom::SerializeToBuffer(data, maxFrames); data.ReadFromDataType<uint32_t>(endianSwap32(_creationTime)); data.ReadFromDataType<uint32_t>(endianSwap32(_modificationTime)); data.ReadFromDataType<uint32_t>(endianSwap32(_timeScale)); _offset=GETAVAILABLEBYTESCOUNT(data); data.ReadFromDataType<uint32_t>(endianSwap32(_duration)); data.ReadFromDataType<uint32_t>(endianSwap32(_preferredRate)); data.ReadFromDataType<uint16_t>(endianSwap16(_preferredVolume)); data.ReadFromBuffer(_reserved, sizeof(_reserved)); for (uint32_t i=0; i<9; i++) data.ReadFromDataType<uint32_t>(endianSwap32(_matrixStructure[i])); for (uint32_t i=0; i<6; i++) { data.ReadFromRepeat(0x00, 4); } data.ReadFromDataType<uint32_t>(endianSwap32(_nextTrakId)); _size=GETAVAILABLEBYTESCOUNT(data)-start; *(uint32_t*)(GETIBPOINTER(data)+start) = endianSwap32(_size); }
bool AMF0Serializer::WriteObject(IOBuffer &buffer, Variant &variant, bool writeType) { if (writeType) buffer.ReadFromRepeat(AMF0_OBJECT, 1); Variant temp = variant; FOR_VECTOR_ITERATOR(string, _keysOrder, i) { if (temp.HasKey(VECTOR_VAL(i))) { if (!WriteShortString(buffer, VECTOR_VAL(i), false)) { FATAL("Unable to serialize key"); return false; } if (!Write(buffer, temp[VECTOR_VAL(i)])) { FATAL("Unable to serialize value"); return false; } temp.RemoveKey(VECTOR_VAL(i)); } } FOR_MAP(temp, string, Variant, i) { string key = MAP_KEY(i); if (key.find(VAR_INDEX_VALUE) == 0) { key = key.substr(VAR_INDEX_VALUE_LEN); } if (!WriteShortString(buffer, key, false)) { FATAL("Unable to serialize key"); return false; } if (!Write(buffer, MAP_VAL(i))) { FATAL("Unable to serialize value"); return false; } }
bool AMF0Serializer::WriteObject(IOBuffer &buffer, Variant &variant, bool writeType) { if (writeType) buffer.ReadFromRepeat(AMF0_OBJECT, 1); Variant temp = variant; FOR_VECTOR_ITERATOR(string, _keysOrder, i) { if (temp.HasKey(VECTOR_VAL(i))) { if (!WriteShortString(buffer, VECTOR_VAL(i), false)) { FATAL("Unable to serialize key"); return false; } if (!Write(buffer, temp[VECTOR_VAL(i)])) { FATAL("Unable to serialize value"); return false; } temp.RemoveKey(VECTOR_VAL(i)); } } FOR_MAP(temp, string, Variant, i) { string key = MAP_KEY(i); if ((key.length() == 10) && (key[0] == '0') && (key[1] == 'x')) { key = format("%"PRIu32, (uint32_t) strtol(key.c_str(), NULL, 16)); } if (!WriteShortString(buffer, key, false)) { FATAL("Unable to serialize key"); return false; } if (!Write(buffer, MAP_VAL(i))) { FATAL("Unable to serialize value"); return false; } }
bool OutNetRTMP4TSStream::FeedAudioData(uint8_t *pData, uint32_t dataLength, double absoluteTimestamp) { if (!_videoCodecSent) return true; //the payload here respects this format: //6.2 Audio Data Transport Stream, ADTS //iso13818-7 page 26/206 //1. Send the audio codec setup if necessary if (!_audioCodecSent) { StreamCapabilities *pCapabilities = GetCapabilities(); if ((pCapabilities != NULL) && (pCapabilities->audioCodecId == CODEC_AUDIO_AAC)) { IOBuffer codecSetup; codecSetup.ReadFromRepeat(0xaf, 1); codecSetup.ReadFromRepeat(0x00, 1); codecSetup.ReadFromBuffer(pCapabilities->aac._pAAC, pCapabilities->aac._aacLength); if (!BaseOutNetRTMPStream::FeedData( GETIBPOINTER(codecSetup), //pData GETAVAILABLEBYTESCOUNT(codecSetup), //dataLength 0, //processedLength GETAVAILABLEBYTESCOUNT(codecSetup), //totalLength absoluteTimestamp, //absoluteTimestamp true //isAudio )) { FATAL("Unable to send audio codec setup"); return false; } } _audioCodecSent = true; } if (_inboundStreamIsRTP) { pData[0] = 0xaf; pData[1] = 0x01; return BaseOutNetRTMPStream::FeedData( pData, //pData dataLength, //dataLength 0, //processedLength dataLength, //totalLength absoluteTimestamp, //absoluteTimestamp true //isAudio ); } else { //2. Skip the ADTS headers and re-position the buffer uint32_t totalADTSHeaderLength = 0; if (((pData[1])&0x01) == 0) totalADTSHeaderLength = 9; else totalADTSHeaderLength = 7; pData += totalADTSHeaderLength - 2; //3. Setup the RTMP header pData[0] = 0xaf; pData[1] = 0x01; //4. Feed return BaseOutNetRTMPStream::FeedData( pData, //pData dataLength - totalADTSHeaderLength + 2, //dataLength 0, //processedLength dataLength - totalADTSHeaderLength + 2, //totalLength absoluteTimestamp, //absoluteTimestamp true //isAudio ); } }