bool InFileRTMPStream::AVCBuilder::BuildFrame(MediaFile* pFile, MediaFrame& mediaFrame, IOBuffer& buffer) { if (mediaFrame.isBinaryHeader) { buffer.ReadFromBuffer(_videoCodecHeaderInit, sizeof (_videoCodecHeaderInit)); } else { if (mediaFrame.isKeyFrame) { // video key frame buffer.ReadFromBuffer(_videoCodecHeaderKeyFrame, sizeof (_videoCodecHeaderKeyFrame)); } else { //video normal frame buffer.ReadFromBuffer(_videoCodecHeader, sizeof (_videoCodecHeader)); } uint32_t cts = (EHTONL(((uint32_t) mediaFrame.cts) & 0x00ffffff)) >> 8; buffer.ReadFromBuffer((uint8_t *) & cts, 3); } if (!pFile->SeekTo(mediaFrame.start)) { FATAL("Unable to seek to position %"PRIu64, mediaFrame.start); return false; } 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; }
bool InFileRTMPFLVStream::BuildFrame(FileClass *pFile, MediaFrame &mediaFrame, IOBuffer &buffer) { //1. 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; } //2. 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; } //3. Done 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; }
bool InFileRTMPStream::AACBuilder::BuildFrame(MediaFile* pFile, MediaFrame& mediaFrame, IOBuffer& buffer) { //1. add the binary header if (mediaFrame.isBinaryHeader) { buffer.ReadFromBuffer(_audioCodecHeaderInit, sizeof (_audioCodecHeaderInit)); } else { buffer.ReadFromBuffer(_audioCodecHeader, sizeof (_audioCodecHeader)); } //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; }
bool TSDocument::ParseDocument() { if (!DetermineChunkSize()) { FATAL("Unable to determine chunk size"); return false; } if (!_mediaFile.SeekTo(_chunkSizeDetectionCount)) { FATAL("Unable to seek at %"PRIu32, _chunkSizeDetectionCount); return false; } _pParser->SetChunkSize(_chunkSize); IOBuffer buffer; uint32_t defaultBlockSize = ((1024 * 1024 * 4) / _chunkSize) * _chunkSize; while (!_chunkSizeErrors) { uint32_t available = (uint32_t) (_mediaFile.Size() - _mediaFile.Cursor()); if (available < _chunkSize) { break; } if (GETAVAILABLEBYTESCOUNT(buffer) != 0) { WARN("Leftovers detected"); break; } uint32_t blockSize = defaultBlockSize < available ? defaultBlockSize : available; buffer.MoveData(); if (!buffer.ReadFromFs(_mediaFile, blockSize)) { WARN("Unable to read %"PRIu32" bytes from file", blockSize); break; } if (!_pParser->ProcessBuffer(buffer, false)) { WARN("Unable to process block of data"); break; } } return true; }
bool BaseInFileStream::Initialize(int32_t clientSideBufferLength) { //1. Check to see if we have an universal seeking file string seekFilePath = GetName() + "."MEDIA_TYPE_SEEK; if (!fileExists(seekFilePath)) { Variant temp; temp[META_SERVER_FULL_PATH] = GetName(); if (!ResolveCompleteMetadata(temp)) { FATAL("Unable to generate metadata"); return false; } } //2. Open the seek file _pSeekFile = GetFile(seekFilePath, 128 * 1024); if (_pSeekFile == NULL) { FATAL("Unable to open seeking file %s", STR(seekFilePath)); return false; } //3. read stream capabilities uint32_t streamCapabilitiesSize = 0; IOBuffer raw; if (!_pSeekFile->ReadUI32(&streamCapabilitiesSize, false)) { FATAL("Unable to read stream Capabilities Size"); return false; } if (!raw.ReadFromFs(*_pSeekFile, streamCapabilitiesSize)) { FATAL("Unable to read raw stream Capabilities"); return false; } if (!StreamCapabilities::Deserialize(raw, _streamCapabilities)) { FATAL("Unable to deserialize stream Capabilities. Please delete %s and %s files so they can be regenerated", STR(GetName() + "."MEDIA_TYPE_SEEK), STR(GetName() + "."MEDIA_TYPE_META)); return false; } //4. compute offsets _seekBaseOffset = _pSeekFile->Cursor(); _framesBaseOffset = _seekBaseOffset + 4; //5. Compute the optimal window size by reading the biggest frame size //from the seek file. if (!_pSeekFile->SeekTo(_pSeekFile->Size() - 8)) { FATAL("Unable to seek to %"PRIu64" position", _pSeekFile->Cursor() - 8); return false; } uint64_t maxFrameSize = 0; if (!_pSeekFile->ReadUI64(&maxFrameSize, false)) { FATAL("Unable to read max frame size"); return false; } if (!_pSeekFile->SeekBegin()) { FATAL("Unable to seek to beginning of the file"); return false; } //3. Open the media file uint32_t windowSize = (uint32_t) maxFrameSize * 16; windowSize = windowSize < 65536 ? 65536 : windowSize; windowSize = (windowSize > (1024 * 1024)) ? (windowSize / 2) : windowSize; _pFile = GetFile(GetName(), windowSize); if (_pFile == NULL) { FATAL("Unable to initialize file"); return false; } //4. Read the frames count from the file if (!_pSeekFile->SeekTo(_seekBaseOffset)) { FATAL("Unable to seek to _seekBaseOffset: %"PRIu64, _seekBaseOffset); return false; } if (!_pSeekFile->ReadUI32(&_totalFrames, false)) { FATAL("Unable to read the frames count"); return false; } _timeToIndexOffset = _framesBaseOffset + _totalFrames * sizeof (MediaFrame); //5. Set the client side buffer length _clientSideBufferLength = clientSideBufferLength; //6. Create the timer _pTimer = new InFileStreamTimer(this); _pTimer->EnqueueForTimeEvent(_clientSideBufferLength - _clientSideBufferLength / 3); //7. Done return true; }