Example #1
0
  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;
  }
Example #2
0
  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);
      }
    }
  }