private IoBuffer createRawPacketData(int chunkSize, Header header, IoBuffer buf, int channelId) { Header cHeader = header.clone(); // if(numChunks > 0) { // cHeader.setSize(cHeader.getSize()+numChunks-1); // } byte[] hArr = encoder.encodeHeader(cHeader, null).array(); byte[] bArr = ChunksUtils.splitOnChunks(chunkSize, buf, (byte) channelId); // byte[] tArr = buf.array(); // for(int i=0; i<bArr.length; i++) { // bArr[i] = tArr[i]; // } IoBuffer ioNew = IoBuffer.allocate(hArr.length + bArr.length); ioNew.put(hArr); ioNew.put(bArr); return ioNew; }
public void process() throws IOException { while (true) { IoBuffer totalBuffer = IoBuffer.allocate(0); totalBuffer.setAutoExpand(true); byte headerByte = get(); totalBuffer.put(headerByte); int headerValue; int byteCount; if ((headerByte & 0x3f) == 0) { byte b1 = get(); totalBuffer.put(b1); headerValue = (headerByte & 0xff) << 8 | (b1 & 0xff); byteCount = 2; } else if ((headerByte & 0x3f) == 1) { byte b1 = get(); byte b2 = get(); totalBuffer.put(b1); totalBuffer.put(b2); headerValue = (headerByte & 0xff) << 16 | (b1 & 0xff) << 8 | (b2 & 0xff); byteCount = 3; } else { // Single byte header headerValue = headerByte & 0xff; byteCount = 1; } final int channelId = RTMPUtils.decodeChannelId(headerValue, byteCount); if (channelId < 0) { throw new RuntimeException("Bad channel id: " + channelId); } // Get the header size and length byte headerSize = RTMPUtils.decodeHeaderSize(headerValue, byteCount); int headerLength = RTMPUtils.getHeaderLength(headerSize); Header lastHeader = lastHeaders.get(channelId); headerLength += byteCount - 1; switch (headerSize) { case Constants.HEADER_NEW: case Constants.HEADER_SAME_SOURCE: case Constants.HEADER_TIMER_CHANGE: IoBuffer tempIo = IoBuffer.wrap(get(3)); int timeValue = RTMPUtils.readUnsignedMediumInt(tempIo); if (timeValue == 0xffffff) { headerLength += 4; } totalBuffer.put(tempIo.array()); break; case Constants.HEADER_CONTINUE: if (lastHeader != null && lastHeader.getExtendedTimestamp() != 0) { headerLength += 4; } break; default: throw new RuntimeException("Unexpected header size " + headerSize + " check for error"); } if (totalBuffer.limit() > 1) totalBuffer.put(get(headerLength - totalBuffer.limit())); IoBuffer headerBuf = IoBuffer.wrap(totalBuffer.array(), 0, totalBuffer.limit()); final Header header = decodeHeader(headerBuf, lastHeader); if (header == null) { throw new RuntimeException("Header is null, check for error"); } lastHeaders.put(channelId, header); // check to see if this is a new packets or continue decoding an existing one GeneratedMessage packet = lastPackets.get(channelId); if (packet == null) { packet = new GeneratedMessage(header.clone()); lastPackets.put(channelId, packet); } final IoBuffer buf = packet.getData(); final int readRemaining = header.getSize() - buf.position(); final int chunkSize = connection.getChunkSize().getSize(); final int readAmount = (readRemaining > chunkSize) ? chunkSize : readRemaining; BufferUtils.put(buf, IoBuffer.wrap(get(readAmount)), readAmount); if (buf.position() < header.getSize()) { // state.continueDecoding(); continue; } if (buf.position() > header.getSize()) { System.out.println("Packet size expanded from {} to {} ({})"); } final IoBuffer rawPacketData = createRawPacketData(4096, header.clone(), buf, channelId); executor2.execute( new Runnable() { @Override public void run() { for (MessageRawListener l : rawListeners) { l.onMessage(rawPacketData, header.getDataType()); } } }); /// System.out.println("������������!"); // System.out.println("CHANNEL: " + channelId); // System.out.println("DATA TYPE: " + header.getDataType()); lastPackets.put(channelId, null); try { final IRTMPEvent message = decodeMessage(packet.getHeader(), buf); // message.setHeader(packet.getHeader()); // Unfortunately flash will, especially when resetting a video stream with a new key frame, // sometime // send an earlier time stamp. To avoid dropping it, we just give it the minimal increment // since the // last message. But to avoid relative time stamps being mis-computed, we don't reset the // header we stored. // final Header lastReadHeader = lastHeaders.get(channelId); // lastHeaders.put(channelId, packet.getHeader()); // packet.setMessage(message); // collapse the time stamps on the last packet so that it works right for chunk type 3 later lastHeader = lastHeaders.get(channelId); lastHeader.setTimerBase(header.getTimer()); if (message != null) { switch (header.getDataType()) { case TYPE_PING: Ping ping = (Ping) message; // Ping p = new Ping(Ping.PING_CLIENT); // Header hd = new Header(); // hd.setDataType((byte)TYPE_PING); // writer.write(encoder.encodeEvent(hd, p).array()); System.out.println("PING TYPE: " + ping.getEventType()); if (ping.getEventType() == Ping.PING_CLIENT) { try { Ping pong = new Ping(Ping.PONG_SERVER); pong.setTimestamp((int) (System.currentTimeMillis() & 0xffffffff)); writer.write(encoder.encodeEvent(header, pong).array()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } break; case TYPE_CHUNK_SIZE: ChunkSize chunkSIZE = (ChunkSize) message; if (connection.isAutoMutableChunkSize()) { connection.setChunkSize(chunkSIZE); } break; } } // System.out.println("HEADER SIZE: " + header.getSize()); // System.out.println("DATA TIME: " + header.getDataType()); // System.out.println("CHANNEL ID: " + header.getChannelId()); // System.out.println("TIMESTAMP: " + header.getTimer()); } finally { lastPackets.put(channelId, null); } } }