public bool AddData(ByteBuffer data) { if (data.Limit == 0) return true; if (!CanHandleData(data)) return false; data.Rewind(); byte frameType = data.Get(); data.Rewind(); if ((frameType & 0xf0) != VideoCodec.FLV_FRAME_KEY) return true;// Not a keyframe //If we don't have the AVCDecoderConfigurationRecord stored... if (_blockDataAVCDCR == null) { data.Get();//FT data.Get();//CODECID byte AVCPacketType = data.Get(); //Sequence Header / here comes a AVCDecoderConfigurationRecord if (log.IsDebugEnabled) log.Debug(string.Format("AVCPacketType: {0}", AVCPacketType)); if (AVCPacketType == 0) { data.Rewind(); // Store AVCDecoderConfigurationRecord data _dataCountAVCDCR = data.Limit; if (_blockSizeAVCDCR < _dataCountAVCDCR) { _blockSizeAVCDCR = _dataCountAVCDCR; _blockDataAVCDCR = new byte[_blockSizeAVCDCR]; } data.Read(_blockDataAVCDCR, 0, _dataCountAVCDCR); } } data.Rewind(); // Store last keyframe _dataCountLKF = data.Limit; if (_blockSizeLKF < _dataCountLKF) { _blockSizeLKF = _dataCountLKF; _blockDataLKF = new byte[_blockSizeLKF]; } data.Read(_blockDataLKF, 0, _dataCountLKF); data.Rewind(); return true; }
public bool AddData(ByteBuffer data) { if (data.Limit == 0) return false;// Empty buffer if (!CanHandleData(data)) return false; data.Get(); UpdateSize(data); int idx = 0; int pos = 0; byte[] tmpData = new byte[_blockDataSize]; int countBlocks = _blockCount; while (data.Remaining > 0 && countBlocks > 0) { short size = data.GetShort(); countBlocks--; if (size == 0) { // Block has not been modified idx += 1; pos += _blockDataSize; continue; } // Store new block data _blockSize[idx] = size; data.Read(tmpData, 0, size); Array.Copy(tmpData, 0, _blockData, pos, size); idx += 1; pos += _blockDataSize; } data.Rewind(); return true; }
public static byte[] GetHandshakeResponse(ByteBuffer input) { int position = (int)input.Position; if (input[position + 4] == 0) { //Using old style handshake byte[] output = new byte[2 * RtmpProtocolDecoder.HandshakeSize + 1]; output[0] = 0x03; int tick = System.Environment.TickCount; output[1] = (byte)((tick >> 24) & 0xff); output[2] = (byte)((tick >> 16) & 0xff); output[3] = (byte)((tick >> 8) & 0xff); output[4] = (byte)(tick & 0xff); HandshakePadBytes.CopyTo(output, 5); input.Read(output, RtmpProtocolDecoder.HandshakeSize + 1, RtmpProtocolDecoder.HandshakeSize); return output; } else { //This method is broken by FP 10.0.32.18 //int index = (input[8] + input[9] + input[10] + input[11]) % 728 + 12; int index = 0; if (input[position + 5] == 0 && input[position + 6] == 3 && input[position + 7] == 2) index = ((input[position + 772] & 0x0ff) + (input[position + 773] & 0x0ff) + (input[position + 774] & 0x0ff) + (input[position + 775] & 0x0ff)) % 728 + 776; else index = ((input[position + 8] & 0x0ff) + (input[position + 9] & 0x0ff) + (input[position + 10] & 0x0ff) + (input[position + 11] & 0x0ff)) % 728 + 12; byte[] part = new byte[32]; for (int i = 0; i < 32; ++i) { part[i] = input[position + index + i]; } HMACSHA256 hmacsha256 = new HMACSHA256(); hmacsha256.Key = SecretKey; byte[] newKey = hmacsha256.ComputeHash(part); byte[] randBytes = new byte[RtmpProtocolDecoder.HandshakeSize - 32]; Random random = new Random(); random.NextBytes(randBytes); hmacsha256.Key = newKey; byte[] hashedBytes = hmacsha256.ComputeHash(randBytes); byte[] output = new byte[2 * RtmpProtocolDecoder.HandshakeSize + 1]; output[0] = 0x03; HandshakeServerBytes.CopyTo(output, 1); //randBytes.CopyTo(output, RtmpProtocolDecoder.HandshakeSize + 1); randBytes.CopyTo(output, 1 + HandshakeServerBytes.Length); //hashedBytes.CopyTo(output, RtmpProtocolDecoder.HandshakeSize + 1 + randBytes.Length); hashedBytes.CopyTo(output, 1 + HandshakeServerBytes.Length + randBytes.Length); input.Skip(RtmpProtocolDecoder.HandshakeSize); return output; } }