org.red5.io.utils.IOUtils Java Examples

The following examples show how to use org.red5.io.utils.IOUtils. 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: TestRTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 6 votes vote down vote up
@Test
public void testDecodeBuffer() {
    log.debug("\ntestDecodeBuffer");
    RTMPProtocolDecoder dec = new RTMPProtocolDecoder();
    List<Object> objs;
    RTMPConnection conn = new RTMPMinaConnection();
    conn.getState().setState(RTMP.STATE_CONNECTED);
    conn.setHandler(this);
    IoBuffer p00 = IoBuffer.wrap(IOUtils.hexStringToByteArray(
            "8639ae8685ad4e802fb905a7918b480416b013e0632e41773e6ba30a1ee089ddb94df6eff6b59aa6251a2707215a2907dc6b51a749ff6680b37792b6c302d43e80f4780361ab7b3c79de5f917aece673e6192e0d45606a5a56dc23ee8113b3381a5d428074f461db71f8caaefa650517809b63edc8412c1f88b4e4d43584ca491a89dfdbb78df1b00c1cedc8e2139fe831becd70527adf4d17760c1cbfff47a1116aaa8f603d3f5319a0688bbc215c1cae1cfb06b6546abd4b76cc7f32cbc84b4531ba2f539d6ae5c4c081bcc51a73b7c14881f8b6bddb480d8a4430b98577f15d31215480d6ebb9cb56931ad3703c2bf024c943b3c45c18717d467387141cdcc88f389548bc335b10ead0daf8e8c69e67f43099ab1f5f2afcb343c08d4b065ec7ce3a437d9891ec8388155d5bdae8dcfd6b4419df2d9c7ca584511e240cc6b1f04ccc098a74d5037c921e4f5916affa17ff71daed20d621687b12bd3f7fcb8f538360b39eb237ca05ada13dc433dc10c2504c55e5ca2e6528b3279eb49e4629218acfc33fce315c58533076d7e3fff6e49650d4283c8fa4ee766f93fc3d10b10bd10b8c2393e2a1da4e6c53dcc5ddbd6efd7b844b7546b0472346b9229cdb6e8d45f70f1e6d23b96cbb2c41fcd486e25fef021e19568c4617248e58ca195fb7aad5ca34dcf27ac7f03dc71a8b4831d1bbb273f6bba56ed9cdf49eef6c45df5071d19d9e8e23fb33b34a65648141cd61db72f79fa7944e3232cd8e30ba310d566fdac6d51b683a3c27af315ca5dc0f614d62c6672e97c036d181e00d6cf08b41a130d7a24783ad616593dc10753959529657f94aec63fa073ae24afe44b2d7075164ebc25305db954607b92c1c7ded5f88e587227ce411010292b6e392aeaeca456d64dadec73cac5de51ec2d3b530db0cdb9869fbdabe1f0aae10bcc1479dc927178a323ac0b2c1def11a086605ee0a66d5a9f1652b5b5860cdbd3594c8e2511c004d8704ccb2732197f37e687753ce0ed00717f20ca6e7076fd4d06b49ba8c665a2adc41e702753225868ace398baebb6944c29c149b838fb71b1e8c20ed3c9561129867c56bc800be10f8dba659f37bbe2242b0cbdcf342396e5ee61f327e7759500d4647e313937c81809b602af08493812ca199698ed35de9ebeded83e1ef5d8f8ad56c368acd7a6d7a05118541bf9d60bc3e45d64431a7700770c814f48f5dcd1c35270a5288b8cbde9333b5b8c40dfd6f0d31d51bea52e0bc6e6e4f46b1bfe85268a494a83d20668829dcfa492325e5f372f45a74bc19c9be07eda5bb1060376b0563081f541801b7d7ce5f7408e5bb11f63d0638419f7cb8aaaa55afa32dfb1e4f0df11fc355ad6c30405b8824f8fff87feeb3b5390cde76040008bb422200a571cd0c19fda9df620ad6ca881c833728081e7cefecc78b280cc06b4c7de3d1c9cebc04d84e1c43fb9fc8b52cc07e0eb15012872c0739322b1da9d7888b6c0f968863ac571837fd63457f98d574665e3cbe1f3b497fb03d1ab8e481985732de26051919d0aba7f18281d8f512b05a625746e4dd50e0c4be16ab4b59aa3cf24e1648ee9d74e4f3b2a92fc7828a5eb2040a706d52e354fb079df3062d404c46fb78de4931caac381020c5bf6b38fecdc5f7d66c3ea3fb087f4ed8ac98a81a24a42053282c7524c2953a5885c1ff5d736d46c472d318312f2a427dc3526fd513c88dbb8583d607031c0a2825f9e74428b859d8874e0cb013b458b27d549a41e4330682dac90e073b79c458dcb2cba317f816bd2dabdcee96d77ab6466021a23a932d134ba33279956aae938787a3a59216b53d50dc0554fe34b5f51d1e050f84e03a7442b29604684291a2ee79198a3911f8a54a1e47c0bf9ec25114f60dae43d4aa4639e5a5c89010ba3884014c2721cab878795f22ba8136f7d4685c9a5c348bda08b60a1ff1afe6d5578d52f5051eeafa9e3b9501701a272a880aaeb30fbc2db66a5e48d7c811a56c9a809c92567d8a10472c142f3dc38c0123e20ed3feb067a550e0a997b38061e191a3bb5b47a04ef70fdd94e69bfc9be160d8a8cc7dc163e8d595cc987c1d676a7b543f56305be60921c19113be5ea988c864b636e216c1c6d71319e0c96b58eb619ac63016ffb97761b79a3eea0016cfacadc7c10300000100014d1400000000020007636f6e6e656374003ff0000000000000030003617070020003766f640008666c61736856657202000e4c4e582032302c302c302c323836000673776655726c020036687474703a2f2f6c6f63616c686f73743a353038302f766f642f6d696e69706c617965722e7377662f5b5b44594e414d49435d5d2f320005746355c3726c02001972746d703a2f2f6c6f63616c686f73743a313933352f766f640004667061640100000c6361706162696c697469657300406de00000000000000b617564696f436f646563730040abee0000000000000b766964656f436f6465637300406f800000000000000d766964656f46756e6374696f6e003ff00000000000c30000077061676555726c020024687474703a2f2f6c6f63616c686f73743a353038302f766f642f696e6465782e68746d6c000e6f626a656374456e636f64696e67004008000000000000000009"));
    p00.position(1536);
    objs = dec.decodeBuffer(conn, p00);
    log.debug("Objects #00: {}", objs);
    assertNotNull("Objects should not be null", objs);
    assertFalse("Objects should not be empty", objs.isEmpty());
    assertEquals("Method should be 'connect'", "connect", ((Invoke) ((Packet) objs.get(0)).getMessage()).getCall().getServiceMethodName());

    IoBuffer p01 = IoBuffer.wrap(IOUtils.hexStringToByteArray(
            "030000000001431400000000020007636f6e6e656374003ff0000000000000030003617070020003766f640008666c61736856657202000e4c4e582032302c302c302c323836000673776655726c020036687474703a2f2f6c6f63616c686f73743a353038302f766f642f6d696e69706c617965722e7377662f5b5b44594e414d49435d5d2f320005746355c3726c02001972746d703a2f2f6c6f63616c686f73743a313933352f766f640004667061640100000c6361706162696c697469657300406de00000000000000b617564696f436f646563730040abee0000000000000b766964656f436f6465637300406f800000000000000d766964656f46756e6374696f6e003ff00000000000c30000077061676555726c02001a687474703a2f2f6c6f63616c686f73743a353038302f766f642f000e6f626a656374456e636f64696e6700400800000000000000000902fffe410000040500000000009896800300003100001a11000000000002000c63726561746553747265616d00400000000000000005"));
    objs = dec.decodeBuffer(conn, p01);
    log.debug("Objects #01: {}", objs);
}
 
Example #2
Source File: TestRTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 6 votes vote down vote up
@Test
public void testDecodeBufferChunks() {
    log.debug("\n testDecodeBufferChunks");
    RTMPProtocolDecoder dec = new RTMPProtocolDecoder();
    List<Object> objs;
    RTMPConnection conn = new RTMPMinaConnection();
    conn.getState().setState(RTMP.STATE_CONNECTED);
    conn.setHandler(this);
    IoBuffer p00 = IoBuffer.wrap(IOUtils.hexStringToByteArray(
            "030000000001531400000000020007636f6e6e656374003ff0000000000000030003617070020000000e6f626a656374456e636f64696e6700000000000000000000046670616401000008666c61736856657202001057494e2031312c322c3230322c3233350005746355726c02001b72746d703a2f2f36372e3136372e3136382e3138323a313933352f00c30b617564696f436f646563730040abee000000000000077061676555726c05000b636c7573746572506173730200086368616e67656d65000f70726976617465496e7374616e6365010000087075626c6963497002000d35342e3230392e32342e323138000a7075626c6963506f727400409e3c0000000000000d766964656fc346756e6374696f6e003ff0000000000000000470617468020000000c6361706162696c697469657300402e000000000000000673776655726c05000b766964656f436f64656373000000000000000000000009"));
    objs = dec.decodeBuffer(conn, p00);
    log.debug("Objects #00: {}", objs);
    assertNotNull("Objects should not be null", objs);
    assertFalse("Objects should not be empty", objs.isEmpty());
    assertEquals("Method should be 'connect'", "connect", ((Invoke) ((Packet) objs.get(0)).getMessage()).getCall().getServiceMethodName());
}
 
Example #3
Source File: AMFIOTest.java    From red5-io with Apache License 2.0 6 votes vote down vote up
@Test
public void testAMF0Connect() {
    log.debug("\ntestAMF0Connect");
    IoBuffer data = IoBuffer.wrap(IOUtils.hexStringToByteArray(
            "020007636f6e6e656374003ff00000000000000300036170700200086f666c6144656d6f0008666c61736856657202000e4c4e582032302c302c302c323836000673776655726c020029687474703a2f2f6c6f63616c686f73743a353038302f64656d6f732f6f666c615f64656d6f2e7377660005746355726c02001972746d703a2f2f6c6f63616c686f73742f6f666c6144656d6f0004667061640100000c6361706162696c697469657300406de00000000000000b617564696f436f646563730040abee0000000000000b766964656f436f6465637300406f800000000000000d766964656f46756e6374696f6e003ff000000000000000077061676555726c02002a687474703a2f2f6c6f63616c686f73743a353038302f64656d6f732f6f666c615f64656d6f2e68746d6c000009"));
    Input in0 = new Input(data);
    // action string
    Assert.assertEquals(DataTypes.CORE_STRING, in0.readDataType());
    String action = in0.readString();
    Assert.assertEquals("connect", action);
    // invoke trasaction id
    log.trace("Before reading number type: {}", data.position());
    byte type = in0.readDataType();
    log.trace("After reading number type({}): {}", type, data.position());
    Assert.assertEquals(DataTypes.CORE_NUMBER, type);
    Number transactionId = in0.readNumber();
    System.out.printf("Number - i: %d d: %f%n", transactionId.intValue(), transactionId.doubleValue());
    Map<String, Object> obj1 = Deserializer.deserialize(in0, Map.class);
    assertNotNull("Connection parameters should be valid", obj1);
    log.debug("Parameters: {}", obj1.toString());
    assertEquals("Application does not match", "oflaDemo", obj1.get("app"));
}
 
Example #4
Source File: RTMPClientProtocolDecoderTest.java    From red5-client with Apache License 2.0 6 votes vote down vote up
@Test
public void testDecodeBufferExTS() {
    //log.debug("\testDecodeBufferExTS");
    RTMPProtocolDecoder dec = new RTMPProtocolDecoder();
    RTMPConnection conn = new RTMPMinaConnection();
    Red5.setConnectionLocal(conn);
    RTMP rtmp = conn.getState();
    rtmp.setState(RTMP.STATE_CONNECTED);
    // lastHeader: Header [streamId=1, channelId=4, dataType=18, timerBase=0, timerDelta=0, size=309, extended=false]
    // get the local decode state
    RTMPDecodeState state = conn.getDecoderState();
    // meta and audio 4x chunks
    IoBuffer in = IoBuffer.wrap(IOUtils.hexStringToByteArray(
            "04000000000135120100000002000d40736574446174614672616d6502000a6f6e4d65746144617461080000000d00086475726174696f6e0040d518000000000000057769647468004064000000000000000668656967687400405e000000000000000d766964656f64617461726174650040686a000000000000096672616d657261746500403900000000c40000000c766964656f636f6465636964004000000000000000000d617564696f6461746172617465000000000000000000000f617564696f73616d706c65726174650040d5888000000000000f617564696f73616d706c6573697a65004030000000000000000673746572656f0100000c617564696f636f6465636964004000c40000000000000007656e636f64657202000d4c61766635362e31352e313032000866696c6573697a650000000000000000000000090400000000006908010000002afff340c400104002e62d4110009080200830107ea04cfa810710e0987f820ec130fc401897c1c0c70ff502008020eea04c1f0fe7fcb9fc10ff90d107c1f82008021feb07c1c04010041c20f89c1fff6b6edad93d99d8da6cd42a08e459095589d4b5fb9a4e679a1f4400001a00006a082afff342c41a19c91f225d89300055a47640c62cee7ccc85c08c42cadb6b56daebe65989f78c3ef3cfbd694ac0c34aa855ee0598a031f0a0686212d43631a4c59a926383c2d5201c5e9b7377"));
    Packet packet = null;
    do {
        packet = dec.decodePacket(conn, state, in);
    } while (packet == null);
    assertNotNull(packet);
    assertTrue(packet.getMessage() instanceof Notify);
    do {
        packet = dec.decodePacket(conn, state, in);
    } while (packet == null);
    assertNotNull(packet);
    assertTrue(packet.getMessage() instanceof AudioData);
}
 
Example #5
Source File: RTMPHandshakeTest.java    From red5-client with Apache License 2.0 6 votes vote down vote up
@Test
public void testValidateFromYouTube() {
    log.info("\ntestValidateFromYouTube");
    // client side handshake handler
    OutboundHandshake out = new OutboundHandshake();
    // server response
    IoBuffer y = IoBuffer.allocate(0);
    y.setAutoExpand(true);
    y.put(IOUtils.hexStringToByteArray(youtubeS1));
    y.flip();
    log.debug("Validate youtube: {}", y);
    @SuppressWarnings("unused")
    boolean youtube = out.validate(y.array());
    //boolean decoded = out.decodeServerResponse1(y);

    //Assert.assertTrue(youtube && decoded);
}
 
Example #6
Source File: TestRTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unused")
private void fillBufferFromStringData(IoBuffer buf, String byteDumpFile) throws Exception {
    File f = new File(String.format("%s/target/test-classes/%s", System.getProperty("user.dir"), byteDumpFile));
    BufferedReader in = new BufferedReader(new FileReader(f));
    try {
        String line = null;
        while ((line = in.readLine()) != null) {
            buf.put(IOUtils.hexStringToByteArray(line));
        }
        buf.flip();
        log.debug("Filled buffer: {}", buf);
    } finally {
        in.close();
    }
}
 
Example #7
Source File: FLVReader.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/**
 * Read only header part of a tag.
 *
 * @return Tag header
 * @throws UnsupportedDataTypeException
 */
private ITag readTagHeader() throws UnsupportedDataTypeException {
    // previous tag size (4 bytes) + flv tag header size (11 bytes)
    fillBuffer(15);
    // previous tag's size
    int previousTagSize = in.getInt();
    // start of the flv tag
    byte dataType = in.get();
    if (log.isTraceEnabled()) {
        log.trace("Bits: {}", Integer.toBinaryString(dataType));
    }
    dataType = (byte) (dataType & 31);
    byte filter = (byte) ((dataType & 63) >> 5);
    byte reserved = (byte) ((dataType & 127) >> 6);
    log.debug("Reserved: {}, Filter: {}, Datatype: {}", reserved, filter, dataType);
    switch (dataType) {
        case 8: // audio
            log.debug("Found audio");
            break;
        case 9: // video
            log.debug("Found video");
            break;
        case 15: // special fms undocumented type?
        case 18: // meta / script data
            log.debug("Found meta/script data");
            break;
        default:
            log.debug("Invalid data type detected ({}), reading ahead\n current position: {} limit: {}", dataType, in.position(), in.limit());
            throw new UnsupportedDataTypeException("Invalid data type detected (" + dataType + ")");
    }
    int bodySize = IOUtils.readUnsignedMediumInt(in);
    int timestamp = IOUtils.readExtendedMediumInt(in);
    int streamId = IOUtils.readUnsignedMediumInt(in);
    if (log.isDebugEnabled()) {
        log.debug("Data type: {} timestamp: {} stream id: {} body size: {} previous tag size: {}", new Object[] { dataType, timestamp, streamId, bodySize, previousTagSize });
    }
    return new Tag(dataType, timestamp, bodySize, null, previousTagSize);
}
 
Example #8
Source File: AMFIOTest.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/**
 * Sample data from https://en.wikipedia.org/wiki/Action_Message_Format
 */
@Test
public void testAMF0Wiki() {
    log.debug("\ntestAMF0Wiki");
    IoBuffer data = IoBuffer.wrap(IOUtils.hexStringToByteArray("03 00 04 6e 61 6d 65 02 00 04 4d 69 6b 65 00 03 61 67 65 00 40 3e 00 00 00 00 00 00 00 05 61 6c 69 61 73 02 00 04 4d 69 6b 65 00 00 09"));
    Input in0 = new Input(data);
    // object
    assertEquals(DataTypes.CORE_OBJECT, in0.readDataType());
    @SuppressWarnings("rawtypes")
    ObjectMap person = (ObjectMap) in0.readObject();
    assertEquals(person.get("name"), "Mike");
    assertEquals(person.get("alias"), "Mike");
    assertEquals(person.get("age"), 30d);
}
 
Example #9
Source File: InputTest.java    From red5-io with Apache License 2.0 5 votes vote down vote up
@Test
public void testOnStreamSendMap() {
    // 02 = string
    // 08 = mixed array (map) max number = 0

    IoBuffer data = IoBuffer.wrap(IOUtils.hexStringToByteArray("02 00 0c 6f 6e 53 74 72 65 61 6d 53 65 6e 64 08 00000000 00 05 76 616c7565 02 00 01 31 00 00 09"));
    Input in0 = new Input(data);
    assertEquals(DataTypes.CORE_STRING, in0.readDataType());
    String method = in0.readString();
    assertEquals("onStreamSend", method);
    assertEquals(DataTypes.CORE_MAP, in0.readDataType());
    @SuppressWarnings("rawtypes")
    ObjectMap map = (ObjectMap) in0.readMap();
    assertEquals(map.get("value"), "1");
}
 
Example #10
Source File: RTMPClientProtocolDecoderTest.java    From red5-client with Apache License 2.0 5 votes vote down vote up
@Test
public void testDecodeBufferYugeTimestamp2() {
    // this test data is from a flash forum
    byte[] buf = IOUtils.hexStringToByteArray(
            "06FFFFFF00BC48090100000001643DD012 00 00 84 02 80 9E FE 25 2A 2E F8 30 3F 99 FC 4C AB 6E B7 2F CB CB E2 DE 62 A7 86 9E BC 3E 04 05 73 C3 D1 F0 FB 70 45 12 80 32 CE 4C B3 44 6E 76 37 66 62 C7 A5 84 A0 60 12 C1 80 51 55 E9 41 80 D5 06 01 69 55 53 EB 70 18 06 10 60 1A FC C2 BF 4C B0 03 65 1D E5 FA 6B 57 AE 91 80 C0 25 03 00 A9 E2 EB F0 60 36 01 80 61 B6 65 1D 83 00 D0 0C 03 82 B1 16 C0 52 89 35 7A D3 18 C2 88 F6 CD C601 64 3D D000 FE 03 02 F7 28 19 50 AF F8 55 7D 8C 35 1A 33 0E 3D EE DC F2 75 3B 10 E4 CC 21 7B CF C1 80 11 06 00 64 BF 41 0C 18 00 F0 0C F9 7F F2 DA AC 18 01 10 40 56 3B C5 17 3F 4B BE AD AC B6 E5 DC C1 DC 91 EF 60 C0 4F 03 00 3E 5F B6 83 00 36 0C 00 99 7C A0 C1 88 80 62 A5 3C C0 60 9E 81 80 10 CD 9B 59 83 BE B0 E8 F5 40 C0 22 03 00 A9 00 D8 30 0C 00 C0 36 97 F2 D0 60 5E 02 1D 08 39 F1 EE 03C6 01 64 3D D0 04 F2 07 FB 67 07 6D F6 5B B6 9F 8E A0 C0 20 83 00 B3 E5 14 18 0F 00 84 AF 6A AD A2 58 30 02 A0 C0 0C 04 39 F8 A6 A9 D0 60 3E 41 80 10 2F 6B 16 98 C0 8A E6 AF 2A 12 44 75 73 CA F6 62 90 3F FA 58 08 52 6C 63 AB 64 E1 D8 70 43 FC 9C 2F 2F F5 9B 66 5A 0A AD FB 48 0C 3D E8 18 0A 60 60 09 2D 55 FF 03 00 3A 0C 00 CA 8B C5 70 4B 06 00 60 18 00 F2 FA 8F EA 84 88 5D F9 19 6B E0 59 EF 5E 06");
    RTMPConnection conn = RTMPConnManager.getInstance().createConnection(RTMPMinaConnection.class);
    conn.setStateCode(RTMP.STATE_CONNECTED);

    RTMPClientProtocolDecoder decoder = new RTMPClientProtocolDecoder();
    decoder.decodeBuffer(conn, IoBuffer.wrap(buf));
}
 
Example #11
Source File: Aggregate.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Breaks-up the aggregate into its individual parts and returns them as a list. The parts are returned based on the ordering of the aggregate itself.
 * 
 * @return list of IRTMPEvent objects
 */
public LinkedList<IRTMPEvent> getParts() {
    LinkedList<IRTMPEvent> parts = new LinkedList<IRTMPEvent>();
    log.trace("Aggregate data length: {}", data.limit());
    int position = data.position();
    do {
        try {
            // read the header
            //log.trace("Hex: {}", data.getHexDump());
            byte subType = data.get();
            // when we run into subtype 0 break out of here
            if (subType == 0) {
                log.debug("Subtype 0 encountered within this aggregate, processing with exit");
                break;
            }
            int size = IOUtils.readUnsignedMediumInt(data);
            log.debug("Data subtype: {} size: {}", subType, size);
            // TODO ensure the data contains all the bytes to support the specified size
            int timestamp = IOUtils.readExtendedMediumInt(data);
            /* timestamp = ntohap((GETIBPOINTER(buffer) + 4)); 0x12345678 == 34 56 78 12 */
            int streamId = IOUtils.readUnsignedMediumInt(data);
            log.debug("Data timestamp: {} stream id: {}", timestamp, streamId);
            Header partHeader = new Header();
            partHeader.setChannelId(header.getChannelId());
            partHeader.setDataType(subType);
            partHeader.setSize(size);
            // use the stream id from the aggregate's header
            partHeader.setStreamId(header.getStreamId());
            partHeader.setTimer(timestamp);
            // timer delta == time stamp - timer base
            // the back pointer may be used to verify the size of the individual part
            // it will be equal to the data size + header size
            int backPointer = 0;
            switch (subType) {
                case TYPE_AUDIO_DATA:
                    AudioData audio = new AudioData(data.getSlice(size));
                    audio.setTimestamp(timestamp);
                    audio.setHeader(partHeader);
                    log.debug("Audio header: {}", audio.getHeader());
                    parts.add(audio);
                    //log.trace("Hex: {}", data.getHexDump());
                    // ensure 4 bytes left to read an int
                    if (data.position() < data.limit() - 4) {
                        backPointer = data.getInt();
                        //log.trace("Back pointer: {}", backPointer);
                        if (backPointer != (size + 11)) {
                            log.debug("Data size ({}) and back pointer ({}) did not match", size, backPointer);
                        }
                    }
                    break;
                case TYPE_VIDEO_DATA:
                    VideoData video = new VideoData(data.getSlice(size));
                    video.setTimestamp(timestamp);
                    video.setHeader(partHeader);
                    log.debug("Video header: {}", video.getHeader());
                    parts.add(video);
                    //log.trace("Hex: {}", data.getHexDump());
                    // ensure 4 bytes left to read an int
                    if (data.position() < data.limit() - 4) {
                        backPointer = data.getInt();
                        //log.trace("Back pointer: {}", backPointer);
                        if (backPointer != (size + 11)) {
                            log.debug("Data size ({}) and back pointer ({}) did not match", size, backPointer);
                        }
                    }
                    break;
                default:
                    log.debug("Non-A/V subtype: {}", subType);
                    Unknown unk = new Unknown(subType, data.getSlice(size));
                    unk.setTimestamp(timestamp);
                    unk.setHeader(partHeader);
                    parts.add(unk);
                    // ensure 4 bytes left to read an int
                    if (data.position() < data.limit() - 4) {
                        backPointer = data.getInt();
                    }
            }
            position = data.position();
        } catch (Exception e) {
            log.error("Exception decoding aggregate parts", e);
            break;
        }
        log.trace("Data position: {}", position);
    } while (position < data.limit());
    log.trace("Aggregate processing complete, {} parts extracted", parts.size());
    return parts;
}
 
Example #12
Source File: TestRTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
@Test
public void testDecodeBufferCreateDelete() {
    log.debug("\ntestDecodeBufferCreateDelete");
    RTMPProtocolDecoder dec = new RTMPProtocolDecoder();
    List<Object> objs;
    RTMPConnection conn = new RTMPMinaConnection();
    conn.getState().setState(RTMP.STATE_CONNECTED);
    conn.setHandler(this);
    for (int i = 0; i < 13; ++i) {
        conn.getState().setLastReadHeader(i, new Header()); //TODO hardcoded, so test will not fail
    }
    int idx = 0;
    for (IoBuffer p : new IoBuffer[] {
            // packet #0 // connect // 320
            IoBuffer.wrap(IOUtils.hexStringToByteArray("030000000001321400000000020007636f6e6e656374003ff00000000000000300036170700200086f666c614" + "4656d6f0008666c61736856657202000e4c4e582032302c302c302c333036000673776655726c020029687474703a2f2f6c6f63616c686f73743a35303" + "8302f64656d6f732f6f666c615f64656d6f2e7377660005746355726c02001972746dc3703a2f2f6c6f63616c686f73742f6f666c6144656d6f0004667"
                    + "061640100000c6361706162696c697469657300406de00000000000000b617564696f436f646563730040abee0000000000000b766964656f436f64656" + "37300406f800000000000000d766964656f46756e6374696f6e003ff000000000000000077061676555c3726c02002a687474703a2f2f6c6f63616c686" + "f73743a353038302f64656d6f732f6f666c615f64656d6f2e68746d6c000009"))
            // packet #1 // 16
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("02db5565000004050000000000989680"))
            // packet #2 // 59
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("0300017c00002f140000000002002264656d6f536572766963652e6765744c6973744f66417661696c61626" + "c65464c567300400000000000000005"))
            // packet #3  // 14
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("42000000000006040007ce4c5f73"))
            // packet #4 // 7
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("c20007ce4c6743"))
            // packet #5 // 7
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("c20007ce4c6f13"))
            // packet #6 // 33
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("43001e610000191402000c63726561746553747265616d00400800000000000005"))
            // packet #7 // 18
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("4200000000000a0400030000000000001388"))
            // packet #8 // 52
            , IoBuffer.wrap(IOUtils.hexStringToByteArray("08001fdd00001d1401000000020004706c61790000000000000000000502000973706565782e666c76c200030000000100001388"))
            // packet #9 // huge connect from OpenMeetings
            ,
            IoBuffer.wrap(IOUtils.hexStringToByteArray("030000000001b71400000000020007636f6e6e656374003ff000000000000003000361707002000e6f70656" + "e6d656574696e67732f350008666c61736856657202000e4c4e582032302c302c302c323836000673776655726c020082687474703a2f2f6c6f63616c6" + "86f73743a353038302f6f70656e6d656574696e67732f7075626c69632f6d61696e6465c36275672e73776631312e7377663f7769636b65747369643d3"
                    + "563333562613330396634393030346139303366323264623663323564393330266c616e67756167653d31267769636b6574726f6f6d69643d350005746" + "355726c02002472746d703a2f2f6c6f63616c686f73743a313933352f6f70656e6d656574696e67732f35c30004667061640100000c6361706162696c6" + "97469657300406de00000000000000b617564696f436f646563730040abee0000000000000b766964656f436f6465637300406f800000000000000d766"
                    + "964656f46756e6374696f6e003ff000000000000000077061676555726c02002a687474703a2f2f6c6f63616c686f73743ac3353038302f6f70656e6d6" + "56574696e67732f23726f6f6d2f35000e6f626a656374456e636f64696e670040080000000000000000090100")),
            IoBuffer.wrap(IOUtils.hexStringToByteArray("4300120c0000191402000c63726561746553747265616d00400800000000000005")), IoBuffer.wrap(IOUtils.hexStringToByteArray("4200000000000a0400030000000000001388830014d302000c63726561746553747265616d0040100000000" + "0000005430000000000221402000c64656c65746553747265616d00000000000000000005003ff0000000000000")),
            IoBuffer.wrap(IOUtils.hexStringToByteArray("04007dc400010108010000006a42a5b3b597d08decc518618c31c688880821841022226eaaaaaaaaaafeff" + "ffffffffffffffffffe17384c5790bb1ae48f4812ff082e31ce7381ccecffdfdff7f16a61525c7586c145624279c6d15b8ca145c5b11a396dc1ea405aa" + "eb584a82022a4aab5c0d3ccf732381d8568f05399f98b47eb22b1a714aa116482deab090420000000000040100000101c4e3d6aed29dc420b24cd22897"
                    + "948f0d68c12e16b640bc736918d278b5956c2d44e358010e8ff699b91bd73716ecd70b891b3791263b9d380554dccec61646ad51dd5e9ed429a3a4a2b0" + "51066394111179fbe53f6562f3f461cd49fb1b6b662e79535391f32d29668e3494a211ff442e2de649475ba8e480f6de4ef5b73dff6d3356")),
            IoBuffer.wrap(IOUtils.hexStringToByteArray("8400002e6a5f2bd5e6b81389f5bcd79c93cf8dc82fcde9abd1af033d756343a53488344bd53c15f9202ac59" + "299268794caa179534a2132b68a1da926f5da1ad3566d43223d99437a65ba4f829395c95c94f11838650cb6169785929758aded8b6da3ac86ba422805e" + "cf6ebfc0ecfa8d37a2fde5f7feaa919b154c9136251a8a4aa09753616608175d6aa9b6995a1b89a8472118833d8a6eab81572fdde05ed5f21364cd97a6"
                    + "a7abc24c6fcef545e2d2553b3152384afd567957b749125404821853a388400a2597955cb538137a5b79eab101599c9e71ad7c5d6db1039a1274771d2c" + "eb2cd95eb8ac9befed41d2a79c34b630afc146979b549eaf9d50d952895f63b56ba504600008e0005010932000084074202becac8c293f8c2c3b658622" + "5827a0342932209024ad6308162a489b0c0336fe9de14fe139c3630dcd66b622a6e0892b6c9673ce3a23ce9f3e7db683bcd42b304e2bc951c296bad8b8"
                    + "2f8d0e8abc3d8d271005414b939d278939dd98396c2906fffc41e6cede4d1138362cc1708f4247c30771f80acc29423a3214f3e478350dd11a6353fd95" + "ae16f4157ed26c0f412c29e347a7e9f6ba6a6a994b262cd7535d3cf13e7f4f4cea6ce4e276c1878257c4ae1567630569ee959f17be28cf26064404905e" + "a16a9db4a4c1633da1cb4d1fa03443cf1d3a9c1b8810a784e74ed3d189363379ec459a1cd27059851e8065a48359a23fd911974c8902087c674e893e90"
                    + "b24977641c286330b314b360d50b3a7c559d70af3a18359d17b413b79d17c7857f80ad25141621a9d3ac946706625e367789865cd02dd9abda5ad36c0b" + "02bed04e90e56d4d5c456f72f43f49c870f05f8094f17f4e8859e40889d7c056030ffc9de4024ca472461a14af4621d3408e702b6b3307214f6215d102" + "b35b38784f982b063a06bb5334c201c8ac5e0ddbf89fc6868d831e02f59a8b23de824852e4b9185d74d0838c9cdde42ce360c740e191a853d9180373fe"
                    + "a5905ca943bd662110c561b31c0c0e0ab380da7fc2a6c262d18a104def5a489af528a9e14f60380c3d9fe48a00adbc48a25db7122e4689071098101861" + "0a318649d6bbb4089c64214068e853d1da031095162e115e167286848c5229a0529675108471b5de14f2b71c3ac92fa0eee340c740b29ab460982b74f0" + "d81907fc3209224c42c3220712ad9594ed3a08b5bd1b96f5a17085be34229640bb4a5c046b69aeaec8124a3510b0e148e61e01c0b890a732a6ade87c78"
                    + "4fa30f1721063ffc5d8573a9f1b1c8984d84b296365952241988f045702b8d226c43582a6f943867bd5d869a7254fc8902e0a7f74f66a509f172ae9684" + "a0c83f9b85291b88915150ac29e1c62288cd0e34725a889f288488d0369ff91a0fec4fbc5ae74682e0a17cc4408c186874d82446f596b66b170118e233" + "614f1069ec2160d9625312cdda23a602790a22152f301c64fa45ccc60c27c04d1ba240543511d2b6df077dc85a88640dd80850fa2c0a18dcd6c0cacd4d"
                    + "88fcd3da04c15fc19b61a0238d443c98a04314c0dc06b2878dacd2c23cea36c02042c15c35480c940f4eb189c3cc4dc1a27ac254fd69a2db187853f899" + "3afca21a7321e09c15a59a95938de276b4840b21e831d02c994e81195f48c29edf4ca764190ff328aae09c21f6825318ce242b061608ff160636046414" + "bb02fb8ce836effd2b1c60ce6d5ef53b1c56d830c05c27c9d606414f0b0ac119e1787220d25b3195dbd68a38d778b1e1d6b5ab022854142db0685f9822"
                    + "6b68da2663538884a300a7a146b1c6162af268051846e8c2b06280832d6be1c8653476048c618582fde872329ee8d029f352ea4e44a1422292a6342ff2" + "b641840306960cffd32c3da0436394c9ad0d8300a796a6ab0b574c6160ddda03c49ff015490d9d0a7f3bbc01fcc304d46e31ffba0c27ea86e8191beac9" + "8dc16053ce26b418e7f150a744602650ea227ab7b15b6052d1760bc29e8da4637c4b0f60dd191e8343050186fe0699fae01dc480d2c27563014f27659e"
                    + "b5630154ad06e19286dff5fa22034c052f18d3214f593616c467b06c2d95a44fc11c088bc14f962903b9d6fb0a1819e1442bc220a7b1437780d061c085" + "b01488dde8dd4ea0b55fbd89076673ba16853fa38601907f7a20f4f45c1a3fe06b7f96a9623efbdd44f06360948c4")) }) {
        objs = dec.decodeBuffer(conn, p);
        log.debug("Objects #02: {}", objs);
        assertFalse("Objects should not be empty", objs.isEmpty());
        assertEquals("Buffer should be empty [idx = " + idx++ + "]", p.capacity(), p.remaining());
    }
}
 
Example #13
Source File: FLVWriter.java    From red5-io with Apache License 2.0 4 votes vote down vote up
private Map<String, ?> getMetaData(Path path, int maxTags) throws IOException {
    Map<String, ?> meta = null;
    // attempt to read the metadata
    SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);
    long size = channel.size();
    log.debug("Channel open: {} size: {} position: {}", channel.isOpen(), size, channel.position());
    if (size > 0L) {
        // skip flv signature 4b, flags 1b, data offset 4b (9b), prev tag size (4b)
        channel.position(appendOffset);
        // flv tag header size 11b
        ByteBuffer dst = ByteBuffer.allocate(11);
        do {
            int read = channel.read(dst);
            if (read > 0) {
                dst.flip();
                byte tagType = (byte) (dst.get() & 31); // 1
                int bodySize = IOUtils.readUnsignedMediumInt(dst); // 3
                int timestamp = IOUtils.readExtendedMediumInt(dst); // 4
                int streamId = IOUtils.readUnsignedMediumInt(dst); // 3
                log.debug("Data type: {} timestamp: {} stream id: {} body size: {}", new Object[] { tagType, timestamp, streamId, bodySize });
                if (tagType == ITag.TYPE_METADATA) {
                    ByteBuffer buf = ByteBuffer.allocate(bodySize);
                    read = channel.read(buf);
                    if (read > 0) {
                        buf.flip();
                        // construct the meta
                        IoBuffer ioBuf = IoBuffer.wrap(buf);
                        Input input = new Input(ioBuf);
                        String metaType = Deserializer.deserialize(input, String.class);
                        log.debug("Metadata type: {}", metaType);
                        meta = Deserializer.deserialize(input, Map.class);
                        input = null;
                        ioBuf.clear();
                        ioBuf.free();
                        if (meta.containsKey("duration")) {
                            appendOffset = channel.position() + 4L;
                            break;
                        }
                    }
                    buf.compact();
                }
                // advance beyond prev tag size
                channel.position(channel.position() + 4L);
                //int prevTagSize = dst.getInt(); // 4
                //log.debug("Previous tag size: {} {}", prevTagSize, (bodySize - 11));
                dst.compact();
            }
        } while (--maxTags > 0); // read up-to "max" tags looking for duration
        channel.close();
    }
    return meta;
}
 
Example #14
Source File: FLVWriter.java    From red5-io with Apache License 2.0 4 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public boolean writeTag(byte dataType, IoBuffer data) throws IOException {
    if (timeOffset == 0) {
        timeOffset = (int) System.currentTimeMillis();
    }
    try {
        lock.acquire();
        /*
         * Tag header = 11 bytes |-|---|----|---| 0 = type 1-3 = data size 4-7 = timestamp 8-10 = stream id (always 0) Tag data = variable bytes Previous tag = 4 bytes (tag header size +
         * tag data size)
         */
        if (log.isTraceEnabled()) {
            log.trace("writeTag - type: {} data: {}", dataType, data);
        }
        long prevBytesWritten = bytesWritten;
        log.trace("Previous bytes written: {}", prevBytesWritten);
        // skip tags with no data
        int bodySize = data.limit();
        log.debug("Tag body size: {}", bodySize);
        // ensure that the channel is still open
        if (dataChannel != null) {
            log.debug("Current file position: {}", dataChannel.position());
            // set a var holding the entire tag size including the previous tag length
            int totalTagSize = TAG_HEADER_LENGTH + bodySize + 4;
            // create a buffer for this tag
            ByteBuffer tagBuffer = ByteBuffer.allocate(totalTagSize);
            // Data Type
            IOUtils.writeUnsignedByte(tagBuffer, dataType); //1
            // Body Size - Length of the message. Number of bytes after StreamID to end of tag 
            // (Equal to length of the tag - 11) 
            IOUtils.writeMediumInt(tagBuffer, bodySize); //3
            // Timestamp
            int timestamp = (int) (System.currentTimeMillis() - timeOffset);
            IOUtils.writeExtendedMediumInt(tagBuffer, timestamp); //4
            // Stream id
            tagBuffer.put(DEFAULT_STREAM_ID); //3
            log.trace("Tag buffer (after tag header) limit: {} remaining: {}", tagBuffer.limit(), tagBuffer.remaining());
            // get the body if we have one
            if (data.hasArray()) {
                tagBuffer.put(data.array());
                log.trace("Tag buffer (after body) limit: {} remaining: {}", tagBuffer.limit(), tagBuffer.remaining());
            }
            // store new previous tag size
            lastTagSize = TAG_HEADER_LENGTH + bodySize;
            // we add the tag size
            tagBuffer.putInt(lastTagSize);
            log.trace("Tag buffer (after prev tag size) limit: {} remaining: {}", tagBuffer.limit(), tagBuffer.remaining());
            // flip so we can process from the beginning
            tagBuffer.flip();
            if (log.isDebugEnabled()) {
                //StringBuilder sb = new StringBuilder();
                //HexDump.dumpHex(sb, tagBuffer.array());
                //log.debug("\n{}", sb);
            }
            // write the tag
            dataChannel.write(tagBuffer);
            bytesWritten = dataChannel.position();
            if (log.isTraceEnabled()) {
                log.trace("Tag written, check value: {} (should be 0)", (bytesWritten - prevBytesWritten) - totalTagSize);
            }
            tagBuffer.clear();
            // update the duration
            duration = Math.max(duration, timestamp);
            log.debug("Writer duration: {}", duration);
            // validate written amount
            if ((bytesWritten - prevBytesWritten) != totalTagSize) {
                log.debug("Not all of the bytes appear to have been written, prev-current: {}", (bytesWritten - prevBytesWritten));
            }
            return true;
        } else {
            // throw an exception and let them know the cause
            throw new IOException("FLV write channel has been closed", new ClosedChannelException());
        }
    } catch (InterruptedException e) {
        log.warn("Exception acquiring lock", e);
    } finally {
        // update the file information
        updateInfoFile();
        // release lock
        lock.release();
    }
    return false;
}