private bool FeedDataVideoFUA(Stream pData, uint dataLength, uint processedLength, uint totalLength, uint absoluteTimestamp) { uint sentAmount = 0; while (sentAmount != dataLength) { var chunkSize = dataLength - sentAmount; chunkSize = chunkSize < _maxRTPPacketSize ? chunkSize : _maxRTPPacketSize; //1. Flags _videoData.Buffers[0][1] = processedLength + sentAmount + chunkSize == totalLength ?(byte)0xe1 : (byte)0x61; //2. counter _videoData.Buffers[0].Write(2, _videoCounter); _videoCounter++; //3. Timestamp _videoData.Buffers[0].Write(4, BaseConnectivity.ToRTPTS(absoluteTimestamp, 90000)); if (chunkSize == totalLength) { //4. No chunking Array.Resize(ref _videoData.Buffers[0], 12); Array.Resize(ref _videoData.Buffers[1], (int)chunkSize); pData.Read(_videoData.Buffers[1], 0, (int)chunkSize); } else { //5. Chunking Array.Resize(ref _videoData.Buffers[0], 14); if (processedLength + sentAmount == 0) { //6. First chunk var firstByte = (byte)pData.ReadByte(); _videoData.Buffers[0][12] = (byte)(firstByte & 0xe0 | (byte)NaluType.NALU_TYPE_FUA); _videoData.Buffers[0][13] = (byte)(firstByte & 0x1f | 0x80); Array.Resize(ref _videoData.Buffers[1], (int)chunkSize - 1); pData.Read(_videoData.Buffers[1], 0, (int)chunkSize - 1); } else { _videoData.Buffers[0][13] &= 0x1f; if (processedLength + sentAmount + chunkSize == totalLength) { //7. Last chunk _videoData.Buffers[0][13] |= 0x40; } Array.Resize(ref _videoData.Buffers[1], (int)chunkSize); pData.Read(_videoData.Buffers[1], 0, (int)chunkSize); } } Connectivity.FeedVideoData(ref _videoData, absoluteTimestamp); sentAmount += chunkSize; } return(true); }
private bool FeedDataAudioMPEG4Generic_aggregate(Stream pData, uint dataLength, uint processedLength, uint totalLength, uint absoluteTimestamp) { //1. We only support frame-by-frame approach if (dataLength != totalLength) { WARN("Chunked mode not yet supported"); return(true); } //2. Test if we need to send what we have so far if (((14 + _audioData.Buffers[1].Length + _audioBuffer.GetAvaliableByteCounts() + 2 + dataLength - 7) > _maxRTPPacketSize) || (_audioData.Buffers[1].Length == 16)) { //3. counter _audioData.Buffers[0].Write(2, AudioCounter); AudioCounter++; //4. Timestamp _audioData.Buffers[0].Write(4, BaseConnectivity.ToRTPTS(absoluteTimestamp, Capabilities.Aac._sampleRate)); //6. put the actual buffer Array.Resize(ref _audioData.Buffers[2], (int)_audioBuffer.GetAvaliableByteCounts()); _audioBuffer.Read(_audioData.Buffers[2], 0, _audioData.Buffers[2].Length); _audioData.Buffers[0].Write(12, (ushort)(_audioData.Buffers[1].Length * 8)); Connectivity.FeedAudioData(ref _audioData, absoluteTimestamp); Array.Resize(ref _audioData.Buffers[1], 0); } //3. AU-Header var auHeader = (dataLength - 7) << 3; auHeader = auHeader | (byte)(_audioData.Buffers[1].Length / 2); Array.Resize(ref _audioData.Buffers[1], _audioData.Buffers[1].Length + 2); _audioData.Buffers[1].Write(_audioData.Buffers[1].Length - 2, (ushort)auHeader); //4. Save the buffer pData.Position += 7; pData.CopyDataTo(_audioBuffer, (int)(dataLength - 7)); pData.Position -= 7; return(true); }