Java Code Examples for org.apache.mina.core.buffer.IoBuffer#rewind()

The following examples show how to use org.apache.mina.core.buffer.IoBuffer#rewind() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AACAudio.java    From red5-io with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean addData(IoBuffer data) {
    if (data.hasRemaining()) {
        // mark
        int start = data.position();
        // ensure we are at the beginning
        data.rewind();
        byte frameType = data.get();
        log.trace("Frame type: {}", frameType);
        byte header = data.get();
        // if we don't have the AACDecoderConfigurationRecord stored
        if (blockDataAACDCR == null) {
            if ((((frameType & 0xf0) >> 4) == AudioCodec.AAC.getId()) && (header == 0)) {
                // back to the beginning
                data.rewind();
                blockDataAACDCR = new byte[data.remaining()];
                data.get(blockDataAACDCR);
            }
        }
        data.position(start);
    }
    return true;
}
 
Example 2
Source File: MsgUtil.java    From game-server with MIT License 6 votes vote down vote up
/**
 * 转换为游戏客户端发送的iobuff
 * 
 * @note portobuf长度对于服务器多余了,服务器进行了大小端转换
 * @param message
 * @return 【length|msgid|protobuf_length|data】
 */
   public static IoBuffer toGameClientIobuffer(final Message message) {
	int msgID = getMessageID(message);
	byte[] msgData = message.toByteArray();
	int protobufLength = msgData.length;
	IoBuffer buf = IoBuffer.allocate(10 + protobufLength); // 消息长度2字节 mid
															// 4字节
															// protobuf长度4字节

	// 消息长度
	byte[] lengthBytes = IntUtil.short2Bytes((short) (protobufLength + 8), ByteOrder.LITTLE_ENDIAN);
	buf.put(lengthBytes);
	// buf.putInt(protobufLength + 8);
	// 消息ID
	buf.put(IntUtil.writeIntToBytesLittleEnding(msgID));
	// buf.putInt(msgID);
	// protobuf长度
	buf.put(IntUtil.writeIntToBytesLittleEnding(protobufLength));
	// buf.putInt(protobufLength);
	buf.put(msgData); // 真实数据
	buf.rewind();
	return buf;
}
 
Example 3
Source File: ScreenVideo.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public IoBuffer getKeyframe() {
    IoBuffer result = IoBuffer.allocate(1024);
    result.setAutoExpand(true);

    // Header
    result.put((byte) (FLV_FRAME_KEY | VideoCodec.SCREEN_VIDEO.getId()));

    // Frame size
    result.putShort((short) this.widthInfo);
    result.putShort((short) this.heightInfo);

    // Get compressed blocks
    byte[] tmpData = new byte[this.blockDataSize];
    int pos = 0;
    for (int idx = 0; idx < this.blockCount; idx++) {
        int size = this.blockSize[idx];
        if (size == 0) {
            // this should not happen: no data for this block
            return null;
        }

        result.putShort((short) size);
        System.arraycopy(this.blockData, pos, tmpData, 0, size);
        result.put(tmpData, 0, size);
        pos += this.blockDataSize;
    }

    result.rewind();
    return result;
}
 
Example 4
Source File: ScreenVideo2.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public IoBuffer getKeyframe() {
    IoBuffer result = IoBuffer.allocate(blockDataSize + 11);
    result.setAutoExpand(true);
    // Header
    result.put((byte) (FLV_FRAME_KEY | VideoCodec.SCREEN_VIDEO2.getId()));
    // Frame size
    result.putShort((short) widthInfo);
    result.putShort((short) heightInfo);
    // reserved (6) has iframeimage (1) has palleteinfo (1)
    result.put(specInfo1);
    // Get compressed blocks
    byte[] tmpData = new byte[blockDataSize];
    int pos = 0;
    for (int idx = 0; idx < blockCount; idx++) {
        int size = blockSize[idx];
        if (size == 0) {
            // this should not happen: no data for this block
            return null;
        }
        result.putShort((short) (size + 1));
        // IMAGEFORMAT
        // reserved(3) color depth(2) has diff blocks(1)
        // ZlibPrimeCompressCurrent(1) ZlibPrimeCompressPrevious (1)
        result.put(specInfo2);
        System.arraycopy(blockData, pos, tmpData, 0, size);
        result.put(tmpData, 0, size);
        pos += blockDataSize;
    }
    result.rewind();
    return result;
}
 
Example 5
Source File: AACAudio.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public IoBuffer getDecoderConfiguration() {
    if (blockDataAACDCR == null) {
        return null;
    }
    IoBuffer result = IoBuffer.allocate(4);
    result.setAutoExpand(true);
    result.put(blockDataAACDCR);
    result.rewind();
    return result;
}
 
Example 6
Source File: AACAudio.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean canHandleData(IoBuffer data) {
    if (data.limit() == 0) {
        // Empty buffer
        return false;
    }
    byte first = data.get();
    boolean result = (((first & 0xf0) >> 4) == AudioCodec.AAC.getId());
    data.rewind();
    return result;
}
 
Example 7
Source File: MP3Audio.java    From red5-io with Apache License 2.0 5 votes vote down vote up
@Override
public boolean canHandleData(IoBuffer data) {
    if (data.limit() == 0) {
        // Empty buffer
        return false;
    }
    byte first = data.get();
    boolean result = (((first & 0xf0) >> 4) == AudioCodec.MP3.getId());
    data.rewind();
    return result;
}
 
Example 8
Source File: ULAWAudio.java    From red5-io with Apache License 2.0 5 votes vote down vote up
@Override
public boolean canHandleData(IoBuffer data) {
    if (data.limit() == 0) {
        // Empty buffer
        return false;
    }
    byte first = data.get();
    boolean result = (((first & 0xf0) >> 4) == AudioCodec.PCM_MULAW.getId());
    data.rewind();
    return result;
}
 
Example 9
Source File: SpeexAudio.java    From red5-io with Apache License 2.0 5 votes vote down vote up
@Override
public boolean canHandleData(IoBuffer data) {
    if (data.limit() == 0) {
        // Empty buffer
        return false;
    }
    byte first = data.get();
    boolean result = (((first & 0xf0) >> 4) == AudioCodec.SPEEX.getId());
    data.rewind();
    return result;
}
 
Example 10
Source File: ScreenVideo2.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean addData(IoBuffer data) {
    if (!this.canHandleData(data)) {
        return false;
    }
    data.get();
    this.updateSize(data);
    int idx = 0;
    int pos = 0;
    byte[] tmpData = new byte[blockDataSize];
    // reserved (6) has iframeimage (1) has palleteinfo (1)
    specInfo1 = data.get();
    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;
        } else {
            // imageformat
            specInfo2 = data.get();
            size--;
        }
        // Store new block data
        blockSize[idx] = size;
        data.get(tmpData, 0, size);
        System.arraycopy(tmpData, 0, blockData, pos, size);
        idx += 1;
        pos += blockDataSize;
    }
    data.rewind();
    return true;
}
 
Example 11
Source File: MsgUtil.java    From game-server with MIT License 5 votes vote down vote up
/**
 * 去掉消息【id|msgid|data】的id部分并转换为【length|msgid|data】
 *
 * @param bytes
 * @param idlength
 * @return 【length|msgid|data】
 */
   public static IoBuffer toIobufferWithoutID(final byte[] bytes, final int idlength) {
	if (bytes.length < idlength || bytes.length < 1) {
		return null;
	}
	byte[] target = Arrays.copyOfRange(bytes, idlength, bytes.length);
	IoBuffer buf = IoBuffer.allocate(target.length + 4);
	buf.putInt(target.length);
	buf.put(target);
	buf.rewind();
	return buf;
}
 
Example 12
Source File: MsgUtil.java    From game-server with MIT License 5 votes vote down vote up
/**
 * 转换为未携带消息长度的iobuff
 *
 * @param message
 * @return 【msgid|data】
 */
   public static IoBuffer toIobufferWithoutLength(final Message message) {
	int msgID = getMessageID(message);
	byte[] msgData = message.toByteArray();
	if (msgData.length < 1) {
		return null;
	}
	IoBuffer buf = IoBuffer.allocate(4 + msgData.length);
	buf.putInt(msgID);
	buf.put(msgData);
	buf.rewind();
	return buf;
}
 
Example 13
Source File: ScreenVideo.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean canHandleData(IoBuffer data) {
    byte first = data.get();
    boolean result = ((first & 0x0f) == VideoCodec.SCREEN_VIDEO.getId());
    data.rewind();
    return result;
}
 
Example 14
Source File: MsgUtil.java    From game-server with MIT License 5 votes vote down vote up
public static IoBuffer toIobuffer(final MassMessage message) {
	IoBuffer buf = IoBuffer.allocate(8 + message.getLength());
	buf.putInt(message.getLength() + 4); // 总长度
	buf.putInt(message.getBuffLength()); // 内容长度
	buf.put(message.getBuffer());
	for (Long target : message.getTargets()) {
		buf.putLong(target);
	}
	buf.rewind();
	return buf;
}
 
Example 15
Source File: AudioCodecFactory.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Create and return new audio codec applicable for byte buffer data
 * 
 * @param data
 *            Byte buffer data
 * @return audio codec
 */
public static IAudioStreamCodec getAudioCodec(IoBuffer data) {
    IAudioStreamCodec result = null;
    try {
        //get the codec identifying byte
        int codecId = (data.get() & 0xf0) >> 4;
        switch (codecId) {
            case 10: //aac 
                result = (IAudioStreamCodec) Class.forName("org.red5.codec.AACAudio").getDeclaredConstructor().newInstance();
                break;
            case 11:
                result = (IAudioStreamCodec) Class.forName("org.red5.codec.SpeexAudio").getDeclaredConstructor().newInstance();
                break;
            case 2:
            case 14:
                result = (IAudioStreamCodec) Class.forName("org.red5.codec.MP3Audio").getDeclaredConstructor().newInstance();
                break;
        }
        data.rewind();
    } catch (Exception ex) {
        log.error("Error creating codec instance", ex);
    }
    //if codec is not found do the old-style loop
    if (result == null) {
        for (IAudioStreamCodec storedCodec : codecs) {
            IAudioStreamCodec codec;
            // XXX: this is a bit of a hack to create new instances of the
            // configured audio codec for each stream
            try {
                codec = storedCodec.getClass().getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                log.error("Could not create audio codec instance", e);
                continue;
            }
            if (codec.canHandleData(data)) {
                result = codec;
                break;
            }
        }
    }
    return result;
}
 
Example 16
Source File: MinaProtocolDecoder.java    From jforgame with Apache License 2.0 4 votes vote down vote up
@Override
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	// 必须保证每一个数据包的字节缓存都和session绑定在一起,不然就读取不了上一次剩余的数据了
	CodecContext context = SessionManager.INSTANCE.getSessionAttr(session, MinaSessionProperties.CODEC_CONTEXT,
			CodecContext.class);
	if (context == null) {
		context = new CodecContext();
		session.setAttribute(MinaSessionProperties.CODEC_CONTEXT, context);
	}

	IoBuffer ioBuffer = context.getBuffer();
	ioBuffer.put(in);

	IMessageDecoder msgDecoder = SerializerHelper.getInstance().getDecoder();

	// 在循环里迭代,以处理数据粘包
	for (;;) {
		ioBuffer.flip();
		// 消息元信息常量3表示消息body前面的两个字段,一个short表示module,一个byte表示cmd,
		final int metaSize = 3;
		if (ioBuffer.remaining() < metaSize) {
			ioBuffer.compact();
			return;
		}
		// ----------------消息协议格式-------------------------
		// packetLength | moduleId | cmd  | body
		// int            short      byte byte[]
		int length = ioBuffer.getInt();
		// int packLen = length + metaSize;
		// 大于消息body长度,说明至少有一条完整的message消息
		if (ioBuffer.remaining() >= length) {
			short moduleId = ioBuffer.getShort();
			byte cmd = ioBuffer.get();
			int msgbodyLen = length - metaSize;
			byte[] body = new byte[msgbodyLen];
			ioBuffer.get(body);
			Message msg = msgDecoder.readMessage(moduleId, cmd, body);

			if (moduleId > 0) {
				out.write(msg);
			} else { // 属于组合包
				CombineMessage combineMessage = (CombineMessage) msg;
				List<Packet> packets = combineMessage.getPackets();
				for (Packet packet : packets) {
					// 依次拆包反序列化为具体的Message
					out.write(Packet.asMessage(packet));
				}
			}
			if (ioBuffer.remaining() == 0) {
				ioBuffer.clear();
				break;
			}
			ioBuffer.compact();
		} else {
			// 数据包不完整,继续等待数据到达
			ioBuffer.rewind();
			ioBuffer.compact();
			break;
		}
	}
}
 
Example 17
Source File: RTMPProtocolEncoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Encode packet.
 *
 * @param packet
 *            RTMP packet
 * @return Encoded data
 */
public IoBuffer encodePacket(Packet packet) {
    IoBuffer out = null;
    Header header = packet.getHeader();
    int channelId = header.getChannelId();
    //log.trace("Channel id: {}", channelId);
    IRTMPEvent message = packet.getMessage();
    if (message instanceof ChunkSize) {
        ChunkSize chunkSizeMsg = (ChunkSize) message;
        ((RTMPConnection) Red5.getConnectionLocal()).getState().setWriteChunkSize(chunkSizeMsg.getSize());
    }
    // normally the message is expected not to be dropped
    if (!dropMessage(channelId, message)) {
        //log.trace("Header time: {} message timestamp: {}", header.getTimer(), message.getTimestamp());
        IoBuffer data = encodeMessage(header, message);
        if (data != null) {
            RTMP rtmp = ((RTMPConnection) Red5.getConnectionLocal()).getState();
            // set last write packet
            rtmp.setLastWritePacket(channelId, packet);
            // ensure we're at the beginning
            if (data.position() != 0) {
                data.flip();
            } else {
                data.rewind();
            }
            // length of the data to be chunked
            int dataLen = data.limit();
            header.setSize(dataLen);
            //if (log.isTraceEnabled()) {
            //log.trace("Message: {}", data);
            //}
            // chunk size for writing
            int chunkSize = rtmp.getWriteChunkSize();
            // number of chunks to write
            int numChunks = (int) Math.ceil(dataLen / (float) chunkSize);
            // get last header
            Header lastHeader = rtmp.getLastWriteHeader(channelId);
            if (log.isTraceEnabled()) {
                log.trace("Channel id: {} chunkSize: {}", channelId, chunkSize);
            }
            // attempt to properly guess the size of the buffer we'll need
            int bufSize = dataLen + 18 + (numChunks * 2);
            //log.trace("Allocated buffer size: {}", bufSize);
            out = IoBuffer.allocate(bufSize, false);
            out.setAutoExpand(true);
            do {
                // encode the header
                encodeHeader(header, lastHeader, out);
                // write a chunk
                byte[] buf = new byte[Math.min(chunkSize, data.remaining())];
                data.get(buf);
                //log.trace("Buffer: {}", Hex.encodeHexString(buf));
                out.put(buf);
                // move header over to last header
                lastHeader = header.clone();
            } while (data.hasRemaining());
            // collapse the time stamps on the last header after decode is complete
            lastHeader.setTimerBase(lastHeader.getTimer());
            // clear the delta
            lastHeader.setTimerDelta(0);
            // set last write header
            rtmp.setLastWriteHeader(channelId, lastHeader);
            data.free();
            out.flip();
            data = null;
        }
    }
    message.release();
    return out;
}
 
Example 18
Source File: AVCVideo.java    From red5-io with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean addData(IoBuffer data, int timestamp) {
    //log.trace("addData timestamp: {} remaining: {}", timestamp, data.remaining());
    if (data.hasRemaining()) {
        // mark
        int start = data.position();
        // get frame type
        byte frameType = data.get();
        byte avcType = data.get();
        if ((frameType & 0x0f) == VideoCodec.AVC.getId()) {
            // check for keyframe
            if ((frameType & 0xf0) == FLV_FRAME_KEY) {
                //log.trace("Key frame");
                if (log.isDebugEnabled()) {
                    log.debug("Keyframe - AVC type: {}", avcType);
                }
                // rewind
                data.rewind();
                switch (avcType) {
                    case 1: // keyframe
                        //log.trace("Keyframe - keyframeTimestamp: {} {}", keyframeTimestamp, timestamp);
                        // get the time stamp and compare with the current value
                        if (timestamp != keyframeTimestamp) {
                            //log.trace("New keyframe");
                            // new keyframe
                            keyframeTimestamp = timestamp;
                            // if its a new keyframe, clear keyframe and interframe collections
                            softReset();
                        }
                        // store keyframe
                        keyframes.add(new FrameData(data));
                        break;
                    case 0: // configuration
                        //log.trace("Decoder configuration");
                        // Store AVCDecoderConfigurationRecord data
                        decoderConfiguration.setData(data);
                        softReset();
                        break;
                }
                //log.trace("Keyframes: {}", keyframes.size());
            } else if (bufferInterframes) {
                //log.trace("Interframe");
                if (log.isDebugEnabled()) {
                    log.debug("Interframe - AVC type: {}", avcType);
                }
                // rewind
                data.rewind();
                try {
                    int lastInterframe = numInterframes.getAndIncrement();
                    //log.trace("Buffering interframe #{}", lastInterframe);
                    if (lastInterframe < interframes.size()) {
                        interframes.get(lastInterframe).setData(data);
                    } else {
                        interframes.add(new FrameData(data));
                    }
                } catch (Throwable e) {
                    log.error("Failed to buffer interframe", e);
                }
                //log.trace("Interframes: {}", interframes.size());
            }
        } else {
            // not AVC data
            log.debug("Non-AVC data, rejecting");
            // go back to where we started
            data.position(start);
            return false;
        }
        // go back to where we started
        data.position(start);
    }
    return true;
}
 
Example 19
Source File: ClientProtocolEncoder.java    From game-server with MIT License 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public void encode(IoSession session, Object obj, ProtocolEncoderOutput out) throws Exception {
	if (getOverScheduledWriteBytesHandler() != null
			&& session.getScheduledWriteMessages() > getMaxScheduledWriteMessages()
			&& getOverScheduledWriteBytesHandler().test(session)) {
		LOGGER.warn("{}消息{}大于最大累积{}",MsgUtil.getIp(session), session.getScheduledWriteMessages(),getMaxScheduledWriteMessages());
		return;
	}

	IoBuffer buf = null;
	if (obj instanceof Message) {
		buf = MsgUtil.toGameClientIobuffer((Message) obj);
	} else if (obj instanceof byte[]) {
		byte[] data = (byte[]) obj; // 消息ID(4字节)+protobuf
		buf = IoBuffer.allocate(data.length + 6);
		// 消息长度
		byte[] lengthBytes = IntUtil.short2Bytes((short) (data.length + 4), ByteOrder.LITTLE_ENDIAN);
		buf.put(lengthBytes);

		// 消息ID ,将顺序改变为前端客户端顺序
		byte[] idBytes = new byte[4];
		idBytes[0] = data[3];
		idBytes[1] = data[2];
		idBytes[2] = data[1];
		idBytes[3] = data[0];
		buf.put(idBytes);
		// protobuf长度
		int protobufLength = data.length - 4; // 移除消息ID长度
		buf.put(IntUtil.writeIntToBytesLittleEnding(protobufLength));
		// 数据
		buf.put(data, 4, protobufLength);

	}

	if (buf != null && session.isConnected()) {
		buf.rewind();
		out.write(buf);
		out.flush();
	}
}
 
Example 20
Source File: SorensonVideo.java    From red5-io with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean addData(IoBuffer data) {
    if (data.limit() == 0) {
        return true;
    }
    if (!this.canHandleData(data)) {
        return false;
    }
    byte first = data.get();
    //log.trace("First byte: {}", HexDump.toHexString(first));
    data.rewind();
    // get frame type
    int frameType = (first & MASK_VIDEO_FRAMETYPE) >> 4;
    if (frameType != FLAG_FRAMETYPE_KEYFRAME) {
        // Not a keyframe
        try {
            int lastInterframe = numInterframes.getAndIncrement();
            if (frameType != FLAG_FRAMETYPE_DISPOSABLE) {
                log.trace("Buffering interframe #{}", lastInterframe);
                if (lastInterframe < interframes.size()) {
                    interframes.get(lastInterframe).setData(data);
                } else {
                    interframes.add(new FrameData(data));
                }
            } else {
                numInterframes.set(lastInterframe);
            }
        } catch (Throwable e) {
            log.error("Failed to buffer interframe", e);
        }
        data.rewind();
        return true;
    }
    numInterframes.set(0);
    interframes.clear();
    // Store last keyframe
    dataCount = data.limit();
    if (blockSize < dataCount) {
        blockSize = dataCount;
        blockData = new byte[blockSize];
    }
    data.get(blockData, 0, dataCount);
    data.rewind();
    return true;
}