org.red5.server.net.rtmp.message.Header Java Examples

The following examples show how to use org.red5.server.net.rtmp.message.Header. 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: RTMPTClientTest.java    From red5-client with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings("unchecked")
protected void onCommand(RTMPConnection conn, Channel channel, Header header, Notify notify) {
    super.onCommand(conn, channel, header, notify);
    System.out.println("onInvoke, header = " + header.toString());
    System.out.println("onInvoke, notify = " + notify.toString());
    Object obj = notify.getCall().getArguments().length > 0 ? notify.getCall().getArguments()[0] : null;
    if (obj instanceof Map) {
        Map<String, String> map = (Map<String, String>) obj;
        String code = map.get("code");
        if (StatusCodes.NS_PLAY_STOP.equals(code)) {
            synchronized (RTMPTClientTest.class) {
                finished = true;
                RTMPTClientTest.class.notifyAll();
            }
            disconnect();
            System.out.println("Disconnected");
        }
    }

}
 
Example #2
Source File: RTMPTSClientTest.java    From red5-client with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings("unchecked")
protected void onCommand(RTMPConnection conn, Channel channel, Header header, Notify notify) {
    super.onCommand(conn, channel, header, notify);
    System.out.println("onInvoke, header = " + header.toString());
    System.out.println("onInvoke, notify = " + notify.toString());
    Object obj = notify.getCall().getArguments().length > 0 ? notify.getCall().getArguments()[0] : null;
    if (obj instanceof Map) {
        Map<String, String> map = (Map<String, String>) obj;
        String code = map.get("code");
        if (StatusCodes.NS_PLAY_STOP.equals(code)) {
            synchronized (RTMPTSClientTest.class) {
                finished = true;
                RTMPTSClientTest.class.notifyAll();
            }
            disconnect();
            System.out.println("Disconnected");
        }
    }

}
 
Example #3
Source File: BaseRTMPClientHandler.java    From red5-client with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void onSharedObject(RTMPConnection conn, Channel channel, Header source, SharedObjectMessage object) {
    log.trace("onSharedObject");
    ClientSharedObject so = sharedObjects.get(object.getName());
    if (so != null) {
        if (so.isPersistent() == object.isPersistent()) {
            log.debug("Received SO request: {}", object);
            so.dispatchEvent(object);
        } else {
            log.error("Ignoring request for wrong-persistent SO: {}", object);
        }
    } else {
        log.error("Ignoring request for non-existend SO: {}", object);
    }
}
 
Example #4
Source File: Channel.java    From red5-server-common with Apache License 2.0 6 votes vote down vote up
/**
 * Writes packet from event data to RTMP connection and stream id.
 *
 * @param event
 *            Event data
 * @param streamId
 *            Stream id
 */
private void write(IRTMPEvent event, Number streamId) {
    log.trace("write to stream id: {} channel: {}", streamId, id);
    final Header header = new Header();
    final Packet packet = new Packet(header, event);
    // set the channel id
    header.setChannelId(id);
    int ts = event.getTimestamp();
    if (ts != 0) {
        header.setTimer(event.getTimestamp());
    }
    header.setStreamId(streamId);
    header.setDataType(event.getDataType());
    // should use RTMPConnection specific method.. 
    //log.trace("Connection type for write: {}", connection.getClass().getName());
    connection.write(packet);
}
 
Example #5
Source File: RTMPProtocolEncoder.java    From red5-server-common with Apache License 2.0 6 votes vote down vote up
/**
 * Determine type of header to use.
 * 
 * @param header RTMP message header
 * @param lastHeader Previous header
 * @return Header type to use
 */
private byte getHeaderType(final Header header, final Header lastHeader) {
    //int lastFullTs = ((RTMPConnection) Red5.getConnectionLocal()).getState().getLastFullTimestampWritten(header.getChannelId());
    if (lastHeader == null || header.getStreamId() != lastHeader.getStreamId() || header.getTimer() < lastHeader.getTimer()) {
        // new header mark if header for another stream
        return HEADER_NEW;
    } else if (header.getSize() != lastHeader.getSize() || header.getDataType() != lastHeader.getDataType()) {
        // same source header if last header data type or size differ
        return HEADER_SAME_SOURCE;
    } else if (header.getTimer() != lastHeader.getTimer()) {
        // timer change marker if there's time gap between header time stamps
        return HEADER_TIMER_CHANGE;
    }
    // continue encoding
    return HEADER_CONTINUE;
}
 
Example #6
Source File: AxisTest.java    From red5-rtsp-restreamer with Apache License 2.0 5 votes vote down vote up
public IRTMPEvent getAVCDecoderConfig() {
	IoBuffer buffV = IoBuffer.allocate(_pCodecSetup.length);
	buffV.setAutoExpand(true);
	for (int p = 0; p < _pCodecSetup.length; p++)
		buffV.put((byte) _pCodecSetup[p]);
	buffV.flip();
	buffV.position(0);
	IRTMPEvent video = new VideoData(buffV);
	video.setHeader(new Header());
	return video;
}
 
Example #7
Source File: ClientBroadcastStream.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Notifies handler on stream broadcast start
 */
private void notifyBroadcastStart() {
    IStreamAwareScopeHandler handler = getStreamAwareHandler();
    if (handler != null) {
        try {
            handler.streamBroadcastStart(this);
        } catch (Throwable t) {
            log.error("Error in notifyBroadcastStart", t);
        }
    }
    // send metadata for creation and start dates
    IoBuffer buf = IoBuffer.allocate(256);
    buf.setAutoExpand(true);
    Output out = new Output(buf);
    out.writeString("onMetaData");
    Map<Object, Object> params = new HashMap<>();
    Calendar cal = GregorianCalendar.getInstance();
    cal.setTimeInMillis(creationTime);
    params.put("creationdate", ZonedDateTime.ofInstant(cal.toInstant(), ZoneId.of("UTC")).format(DateTimeFormatter.ISO_INSTANT));
    cal.setTimeInMillis(startTime);
    params.put("startdate", ZonedDateTime.ofInstant(cal.toInstant(), ZoneId.of("UTC")).format(DateTimeFormatter.ISO_INSTANT));
    if (log.isDebugEnabled()) {
        log.debug("Params: {}", params);
    }
    out.writeMap(params);
    buf.flip();
    Notify notify = new Notify(buf);
    notify.setAction("onMetaData");
    notify.setHeader(new Header());
    notify.getHeader().setDataType(Notify.TYPE_STREAM_METADATA);
    notify.getHeader().setStreamId(0);
    notify.setTimestamp(0);
    dispatchEvent(notify);
}
 
Example #8
Source File: RTMPHandler.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void onChunkSize(RTMPConnection conn, Channel channel, Header source, ChunkSize chunkSize) {
    int requestedChunkSize = chunkSize.getSize();
    log.debug("Chunk size: {}", requestedChunkSize);
    // set chunk size on the connection
    RTMP state = conn.getState();
    // set only the read chunk size since it came from the client
    state.setReadChunkSize(requestedChunkSize);
    //state.setWriteChunkSize(requestedChunkSize);
    // set on each of the streams
    for (IClientStream stream : conn.getStreams()) {
        if (stream instanceof IClientBroadcastStream) {
            IClientBroadcastStream bs = (IClientBroadcastStream) stream;
            IBroadcastScope scope = bs.getScope().getBroadcastScope(bs.getPublishedName());
            if (scope == null) {
                continue;
            }
            OOBControlMessage setChunkSize = new OOBControlMessage();
            setChunkSize.setTarget("ClientBroadcastStream");
            setChunkSize.setServiceName("chunkSize");
            if (setChunkSize.getServiceParamMap() == null) {
                setChunkSize.setServiceParamMap(new HashMap<String, Object>());
            }
            setChunkSize.getServiceParamMap().put("chunkSize", requestedChunkSize);
            scope.sendOOBControlMessage((IConsumer) null, setChunkSize);
            log.debug("Sending chunksize {} to {}", chunkSize, bs.getProvider());
        }
    }
}
 
Example #9
Source File: RTMPHandler.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void onPing(RTMPConnection conn, Channel channel, Header source, Ping ping) {
    switch (ping.getEventType()) {
        case Ping.CLIENT_BUFFER:
            SetBuffer setBuffer = (SetBuffer) ping;
            // get the stream id
            int streamId = setBuffer.getStreamId();
            // get requested buffer size in milliseconds
            int buffer = setBuffer.getBufferLength();
            log.debug("Client sent a buffer size: {} ms for stream id: {}", buffer, streamId);
            IClientStream stream = null;
            if (streamId != 0) {
                // The client wants to set the buffer time
                stream = conn.getStreamById(streamId);
                if (stream != null) {
                    stream.setClientBufferDuration(buffer);
                    log.trace("Stream type: {}", stream.getClass().getName());
                }
            }
            //catch-all to make sure buffer size is set
            if (stream == null) {
                // Remember buffer time until stream is created
                conn.rememberStreamBufferDuration(streamId, buffer);
                log.debug("Remembering client buffer on stream: {}", buffer);
            }
            break;
        case Ping.PONG_SERVER:
            // This is the response to an IConnection.ping request
            conn.pingReceived(ping);
            break;
        default:
            log.warn("Unhandled ping: {}", ping);
    }
}
 
Example #10
Source File: RTMPProtocolEncoder.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Calculate number of bytes necessary to encode the header.
 * 
 * @param header
 *            RTMP message header
 * @param lastHeader
 *            Previous header
 * @return Calculated size
 */
private int calculateHeaderSize(final Header header, final Header lastHeader) {
    final byte headerType = getHeaderType(header, lastHeader);
    int channelIdAdd = 0;
    int channelId = header.getChannelId();
    if (channelId > 320) {
        channelIdAdd = 2;
    } else if (channelId > 63) {
        channelIdAdd = 1;
    }
    return RTMPUtils.getHeaderLength(headerType) + channelIdAdd;
}
 
Example #11
Source File: BaseRTMPClientHandler.java    From red5-client with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void onChunkSize(RTMPConnection conn, Channel channel, Header source, ChunkSize chunkSize) {
    log.debug("onChunkSize");
    // set read and write chunk sizes
    RTMP state = conn.getState();
    state.setReadChunkSize(chunkSize.getSize());
    state.setWriteChunkSize(chunkSize.getSize());
    log.info("ChunkSize is not fully implemented: {}", chunkSize);
}
 
Example #12
Source File: ClientTest.java    From red5-client with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
protected void onCommand(RTMPConnection conn, Channel channel, Header header, Notify notify) {
    super.onCommand(conn, channel, header, notify);
    System.out.println("onInvoke - header: " + header.toString() + " notify: " + notify.toString());
    Object obj = notify.getCall().getArguments().length > 0 ? notify.getCall().getArguments()[0] : null;
    if (obj instanceof Map) {
        Map<String, String> map = (Map<String, String>) obj;
        String code = map.get("code");
        if (StatusCodes.NS_PLAY_STOP.equals(code)) {
            finished = true;
            disconnect();
            System.out.println("Disconnected");
        }
    }
}
 
Example #13
Source File: RTMP.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * @return the writeHeader
 */
public Header getWriteHeader() {
    return writeHeader;
}
 
Example #14
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 #15
Source File: RTMPHandler.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void onSharedObject(RTMPConnection conn, Channel channel, Header source, SharedObjectMessage message) {
    if (log.isDebugEnabled()) {
        log.debug("onSharedObject - conn: {} channel: {} so message: {}", new Object[] { conn.getSessionId(), channel.getId(), message });
    }
    final IScope scope = conn.getScope();
    if (scope != null) {
        // so name
        String name = message.getName();
        // whether or not the incoming so is persistent
        boolean persistent = message.isPersistent();
        // shared object service
        ISharedObjectService sharedObjectService = (ISharedObjectService) ScopeUtils.getScopeService(scope, ISharedObjectService.class, SharedObjectService.class, false);
        if (!sharedObjectService.hasSharedObject(scope, name)) {
            log.debug("Shared object service doesnt have requested object, creation will be attempted");
            ISharedObjectSecurityService security = (ISharedObjectSecurityService) ScopeUtils.getScopeService(scope, ISharedObjectSecurityService.class);
            if (security != null) {
                // Check handlers to see if creation is allowed
                for (ISharedObjectSecurity handler : security.getSharedObjectSecurity()) {
                    if (!handler.isCreationAllowed(scope, name, persistent)) {
                        log.debug("Shared object create failed, creation is not allowed");
                        sendSOCreationFailed(conn, message);
                        return;
                    }
                }
            }
            if (!sharedObjectService.createSharedObject(scope, name, persistent)) {
                log.debug("Shared object create failed");
                sendSOCreationFailed(conn, message);
                return;
            }
        }
        ISharedObject so = sharedObjectService.getSharedObject(scope, name);
        if (so != null) {
            if (so.isPersistent() == persistent) {
                log.debug("Dispatch persistent shared object");
                so.dispatchEvent(message);
            } else {
                log.warn("Shared object persistence mismatch - current: {} incoming: {}", so.isPersistent(), persistent);
                // reset the object so we can re-use it
                message.reset();
                // add the error event
                message.addEvent(new SharedObjectEvent(ISharedObjectEvent.Type.CLIENT_STATUS, "error", SO_PERSISTENCE_MISMATCH));
                conn.getChannel(3).write(message);
            }
        } else {
            log.warn("Shared object lookup returned null for {} in {}", name, scope.getName());
            // reset the object so we can re-use it
            message.reset();
            // add the error event
            message.addEvent(new SharedObjectEvent(ISharedObjectEvent.Type.CLIENT_STATUS, "error", NC_CALL_FAILED));
            conn.getChannel(3).write(message);
        }
    } else {
        // The scope already has been deleted
        log.debug("Shared object scope was not found");
        sendSOCreationFailed(conn, message);
    }
}
 
Example #16
Source File: AxisTest.java    From red5-rtsp-restreamer with Apache License 2.0 4 votes vote down vote up
private void sendAVCDecoderConfig(int timecode) {

		IoBuffer buffV = IoBuffer.allocate(_pCodecSetup.length);
		buffV.setAutoExpand(true);
		for (int p = 0; p < _pCodecSetup.length; p++)
			buffV.put((byte) _pCodecSetup[p]);
		buffV.flip();

		buffV.position(0);

		IRTMPEvent video = new VideoData(buffV);

		video.setTimestamp(timecode);

		video.setHeader(new Header());

		if (output != null)
			output.dispatchEvent(video);

	}
 
Example #17
Source File: BaseRTMPClientHandler.java    From red5-client with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void onPing(RTMPConnection conn, Channel channel, Header source, Ping ping) {
    log.trace("onPing");
    switch (ping.getEventType()) {
        case Ping.PING_CLIENT:
        case Ping.STREAM_BEGIN:
        case Ping.RECORDED_STREAM:
        case Ping.STREAM_PLAYBUFFER_CLEAR:
            // the server wants to measure the RTT
            Ping pong = new Ping();
            pong.setEventType(Ping.PONG_SERVER);
            pong.setValue2((int) (System.currentTimeMillis() & 0xffffffff));
            conn.ping(pong);
            break;
        case Ping.STREAM_DRY:
            log.debug("Stream indicates there is no data available");
            break;
        case Ping.CLIENT_BUFFER:
            // set the client buffer
            IClientStream stream = null;
            // get the stream id
            Number streamId = ping.getValue2();
            // get requested buffer size in milliseconds
            int buffer = ping.getValue3();
            log.debug("Client sent a buffer size: {} ms for stream id: {}", buffer, streamId);
            // the client wants to set the buffer time
            stream = conn.getStreamById(streamId);
            if (stream != null) {
                stream.setClientBufferDuration(buffer);
                log.info("Setting client buffer on stream: {}", buffer);
            }
            // catch-all to make sure buffer size is set
            if (stream == null) {
                // remember buffer time until stream is created
                conn.rememberStreamBufferDuration(streamId.intValue(), buffer);
                log.info("Remembering client buffer on stream: {}", buffer);
            }
            break;
        case Ping.PING_SWF_VERIFY:
            log.debug("SWF verification ping");
            // TODO get the swf verification bytes from the handshake
            SWFResponse swfPong = new SWFResponse(new byte[42]);
            conn.ping(swfPong);
            break;
        case Ping.BUFFER_EMPTY:
            log.debug("Buffer empty ping");

            break;
        case Ping.BUFFER_FULL:
            log.debug("Buffer full ping");

            break;
        default:
            log.warn("Unhandled ping: {}", ping);
    }
}
 
Example #18
Source File: BaseRTMPHandler.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public void messageReceived(RTMPConnection conn, Packet packet) throws Exception {
    log.trace("messageReceived connection: {}", conn.getSessionId());
    if (conn != null) {
        IRTMPEvent message = null;
        try {
            message = packet.getMessage();
            final Header header = packet.getHeader();
            final Number streamId = header.getStreamId();
            final Channel channel = conn.getChannel(header.getChannelId());
            final IClientStream stream = conn.getStreamById(streamId);
            if (log.isTraceEnabled()) {
                log.trace("Message received - header: {}", header);
            }
            // set stream id on the connection
            conn.setStreamId(streamId);
            // increase number of received messages
            conn.messageReceived();
            // set the source of the message
            message.setSource(conn);
            // process based on data type
            final byte headerDataType = header.getDataType();
            if (log.isTraceEnabled()) {
                log.trace("Header / message data type: {}", headerDataType);
            }
            switch (headerDataType) {
                case TYPE_AGGREGATE:
                    log.debug("Aggregate type data - header timer: {} size: {}", header.getTimer(), header.getSize());
                case TYPE_AUDIO_DATA:
                case TYPE_VIDEO_DATA:
                    // mark the event as from a live source
                    // log.trace("Marking message as originating from a Live source");
                    message.setSourceType(Constants.SOURCE_TYPE_LIVE);
                    // NOTE: If we respond to "publish" with "NetStream.Publish.BadName",
                    // the client sends a few stream packets before stopping. We need to ignore them
                    if (stream != null) {
                        ((IEventDispatcher) stream).dispatchEvent(message);
                    }
                    break;
                case TYPE_FLEX_SHARED_OBJECT:
                case TYPE_SHARED_OBJECT:
                    onSharedObject(conn, channel, header, (SharedObjectMessage) message);
                    break;
                case TYPE_INVOKE:
                case TYPE_FLEX_MESSAGE:
                    onCommand(conn, channel, header, (Invoke) message);
                    IPendingServiceCall call = ((Invoke) message).getCall();
                    if (message.getHeader().getStreamId().intValue() != 0 && call.getServiceName() == null && StreamAction.PUBLISH.equals(call.getServiceMethodName())) {
                        if (stream != null) {
                            // Only dispatch if stream really was created
                            ((IEventDispatcher) stream).dispatchEvent(message);
                        }
                    }
                    break;
                case TYPE_NOTIFY:
                    // like an invoke, but does not return anything and has a invoke / transaction id of 0
                case TYPE_FLEX_STREAM_SEND:
                    if (((Notify) message).getData() != null && stream != null) {
                        // Stream metadata
                        ((IEventDispatcher) stream).dispatchEvent(message);
                    } else {
                        onCommand(conn, channel, header, (Notify) message);
                    }
                    break;
                case TYPE_PING:
                    onPing(conn, channel, header, (Ping) message);
                    break;
                case TYPE_BYTES_READ:
                    onStreamBytesRead(conn, channel, header, (BytesRead) message);
                    break;
                case TYPE_CHUNK_SIZE:
                    onChunkSize(conn, channel, header, (ChunkSize) message);
                    break;
                case Constants.TYPE_CLIENT_BANDWIDTH: // onBWDone / peer bw
                    log.debug("Client bandwidth: {}", message);
                    onClientBandwidth(conn, channel, (ClientBW) message);
                    break;
                case Constants.TYPE_SERVER_BANDWIDTH: // window ack size
                    log.debug("Server bandwidth: {}", message);
                    onServerBandwidth(conn, channel, (ServerBW) message);
                    break;
                default:
                    log.debug("Unknown type: {}", header.getDataType());
            }
            if (message instanceof Unknown) {
                log.info("Message type unknown: {}", message);
            }
        } catch (Throwable t) {
            log.error("Exception", t);
        }
        // XXX this may be causing 'missing' data if previous methods are not making copies before buffering etc..
        if (message != null) {
            message.release();
        }
    }
}
 
Example #19
Source File: RTMP.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * @return the readPacketHeader
 */
public Header getReadPacketHeader() {
    return readPacketHeader;
}
 
Example #20
Source File: RTMP.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * @return the readHeader
 */
public Header getReadHeader() {
    return readHeader;
}
 
Example #21
Source File: RTMPConnection.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
private String getMessageType(Packet packet) {
    final Header header = packet.getHeader();
    final byte headerDataType = header.getDataType();
    return messageTypeToName(headerDataType);
}
 
Example #22
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 #23
Source File: BaseEvent.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public Header getHeader() {
    return header;
}
 
Example #24
Source File: BaseEvent.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public void setHeader(Header header) {
    this.header = header;
}
 
Example #25
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 #26
Source File: RTMPProtocolEncoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Encode RTMP header into given IoBuffer.
 *
 * @param header RTMP message header
 * @param lastHeader Previous header
 * @param buf Buffer for writing encoded header into
 */
public void encodeHeader(Header header, Header lastHeader, IoBuffer buf) {
    byte headerType = getHeaderType(header, lastHeader);
    RTMPUtils.encodeHeaderByte(buf, headerType, header.getChannelId());
    if (log.isTraceEnabled()) {
        log.trace("{} lastHeader: {}", Header.HeaderType.values()[headerType], lastHeader);
    }
    /*
     * Timestamps in RTMP are given as an integer number of milliseconds relative to an unspecified epoch. Typically, each stream will start with a timestamp of 0, but this is not
     * required, as long as the two endpoints agree on the epoch. Note that this means that any synchronization across multiple streams (especially from separate hosts) requires some
     * additional mechanism outside of RTMP. Because timestamps are 32 bits long, they roll over every 49 days, 17 hours, 2 minutes and 47.296 seconds. Because streams are allowed to
     * run continuously, potentially for years on end, an RTMP application SHOULD use serial number arithmetic [RFC1982] when processing timestamps, and SHOULD be capable of handling
     * wraparound. For example, an application assumes that all adjacent timestamps are within 2^31 - 1 milliseconds of each other, so 10000 comes after 4000000000, and 3000000000
     * comes before 4000000000. Timestamp deltas are also specified as an unsigned integer number of milliseconds, relative to the previous timestamp. Timestamp deltas may be either 24
     * or 32 bits long.
     */
    int timeBase = 0, timeDelta = 0;
    int headerSize = header.getSize();
    // encode the message header section
    switch (headerType) {
        case HEADER_NEW: // type 0 - 11 bytes
            timeBase = header.getTimerBase();
            // absolute time - unsigned 24-bit (3 bytes) (chop at max 24bit time) 
            RTMPUtils.writeMediumInt(buf, Math.min(timeBase, MEDIUM_INT_MAX));
            // header size 24-bit (3 bytes)
            RTMPUtils.writeMediumInt(buf, headerSize);
            // 1 byte
            buf.put(header.getDataType());
            // little endian 4 bytes
            RTMPUtils.writeReverseInt(buf, header.getStreamId().intValue());
            header.setTimerDelta(timeDelta);
            // write the extended timestamp if we are indicated to do so
            if (timeBase >= MEDIUM_INT_MAX) {
                buf.putInt(timeBase);
                header.setExtended(true);
            }
            RTMPConnection conn = (RTMPConnection) Red5.getConnectionLocal();
            if (conn != null) {
                conn.getState().setLastFullTimestampWritten(header.getChannelId(), timeBase);
            }
            break;
        case HEADER_SAME_SOURCE: // type 1 - 7 bytes
            // delta type
            timeDelta = (int) RTMPUtils.diffTimestamps(header.getTimer(), lastHeader.getTimer());
            header.setTimerDelta(timeDelta);
            // write the time delta 24-bit 3 bytes
            RTMPUtils.writeMediumInt(buf, Math.min(timeDelta, MEDIUM_INT_MAX));
            // write header size
            RTMPUtils.writeMediumInt(buf, headerSize);
            buf.put(header.getDataType());
            // write the extended timestamp if we are indicated to do so
            if (timeDelta >= MEDIUM_INT_MAX) {
                buf.putInt(timeDelta);
                header.setExtended(true);
            }
            // time base is from last header minus delta
            timeBase = header.getTimerBase() - timeDelta;
            header.setTimerBase(timeBase);
            break;
        case HEADER_TIMER_CHANGE: // type 2 - 3 bytes
            // delta type
            timeDelta = (int) RTMPUtils.diffTimestamps(header.getTimer(), lastHeader.getTimer());
            header.setTimerDelta(timeDelta);
            // write the time delta 24-bit 3 bytes
            RTMPUtils.writeMediumInt(buf, Math.min(timeDelta, MEDIUM_INT_MAX));
            // write the extended timestamp if we are indicated to do so
            if (timeDelta >= MEDIUM_INT_MAX) {
                buf.putInt(timeDelta);
                header.setExtended(true);
            }
            // time base is from last header minus delta
            timeBase = header.getTimerBase() - timeDelta;
            header.setTimerBase(timeBase);
            break;
        case HEADER_CONTINUE: // type 3 - 0 bytes
            // time base from the most recent header
            timeBase = header.getTimerBase() - timeDelta;
            // write the extended timestamp if we are indicated to do so
            if (lastHeader.isExtended()) {
                buf.putInt(timeBase);
            }
            break;
        default:
            break;
    }
    log.trace("Encoded chunk {} {}", Header.HeaderType.values()[headerType], header);
}
 
Example #27
Source File: RTMPProtocolEncoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Encode message.
 *
 * @param header
 *            RTMP message header
 * @param message
 *            RTMP message (event)
 * @return Encoded message data
 */
public IoBuffer encodeMessage(Header header, IRTMPEvent message) {
    IServiceCall call = null;
    switch (header.getDataType()) {
        case TYPE_CHUNK_SIZE:
            return encodeChunkSize((ChunkSize) message);
        case TYPE_INVOKE:
            log.trace("Invoke {}", message);
            call = ((Invoke) message).getCall();
            if (call != null) {
                log.debug("{}", call.toString());
                Object[] args = call.getArguments();
                if (args != null && args.length > 0) {
                    Object a0 = args[0];
                    if (a0 instanceof Status) {
                        Status status = (Status) a0;
                        //code: NetStream.Seek.Notify
                        if (StatusCodes.NS_SEEK_NOTIFY.equals(status.getCode())) {
                            //desc: Seeking 25000 (stream ID: 1).
                            int seekTime = Integer.valueOf(status.getDescription().split(" ")[1]);
                            log.trace("Seek to time: {}", seekTime);
                            // TODO make sure this works on stream ids > 1
                            //audio and video channels
                            int[] channels = new int[] { 5, 6 };
                            //if its a seek notification, reset the "mapping" for audio (5) and video (6)
                            RTMP rtmp = ((RTMPConnection) Red5.getConnectionLocal()).getState();
                            for (int channelId : channels) {
                                LiveTimestampMapping mapping = rtmp.getLastTimestampMapping(channelId);
                                if (mapping != null) {
                                    long timestamp = mapping.getClockStartTime() + (seekTime & 0xFFFFFFFFL);
                                    log.trace("Setting last stream time to: {}", timestamp);
                                    mapping.setLastStreamTime(timestamp);
                                } else {
                                    log.trace("No ts mapping for channel id: {}", channelId);
                                }
                            }
                        }
                    }
                }
            }
            return encodeInvoke((Invoke) message);
        case TYPE_NOTIFY:
            log.trace("Notify {}", message);
            call = ((Notify) message).getCall();
            if (call == null) {
                return encodeStreamMetadata((Notify) message);
            } else {
                return encodeNotify((Notify) message);
            }
        case TYPE_PING:
            if (message instanceof SetBuffer) {
                return encodePing((SetBuffer) message);
            } else if (message instanceof SWFResponse) {
                return encodePing((SWFResponse) message);
            } else {
                return encodePing((Ping) message);
            }
        case TYPE_BYTES_READ:
            return encodeBytesRead((BytesRead) message);
        case TYPE_AGGREGATE:
            log.trace("Encode aggregate message");
            return encodeAggregate((Aggregate) message);
        case TYPE_AUDIO_DATA:
            log.trace("Encode audio message");
            return encodeAudioData((AudioData) message);
        case TYPE_VIDEO_DATA:
            log.trace("Encode video message");
            return encodeVideoData((VideoData) message);
        case TYPE_FLEX_SHARED_OBJECT:
            return encodeFlexSharedObject((ISharedObjectMessage) message);
        case TYPE_SHARED_OBJECT:
            return encodeSharedObject((ISharedObjectMessage) message);
        case TYPE_SERVER_BANDWIDTH:
            return encodeServerBW((ServerBW) message);
        case TYPE_CLIENT_BANDWIDTH:
            return encodeClientBW((ClientBW) message);
        case TYPE_FLEX_MESSAGE:
            return encodeFlexMessage((FlexMessage) message);
        case TYPE_FLEX_STREAM_SEND:
            return encodeFlexStreamSend((FlexStreamSend) message);
        default:
            log.warn("Unknown object type: {}", header.getDataType());
    }
    return null;
}
 
Example #28
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Decodes RTMP message event.
 * 
 * @param conn
 *            RTMP connection
 * @param header
 *            RTMP header
 * @param in
 *            Input IoBuffer
 * @return RTMP event
 */
public IRTMPEvent decodeMessage(RTMPConnection conn, Header header, IoBuffer in) {
    IRTMPEvent message;
    byte dataType = header.getDataType();
    switch (dataType) {
        case TYPE_AUDIO_DATA:
            message = decodeAudioData(in);
            message.setSourceType(Constants.SOURCE_TYPE_LIVE);
            break;
        case TYPE_VIDEO_DATA:
            message = decodeVideoData(in);
            message.setSourceType(Constants.SOURCE_TYPE_LIVE);
            break;
        case TYPE_AGGREGATE:
            message = decodeAggregate(in);
            break;
        case TYPE_FLEX_SHARED_OBJECT: // represents an SO in an AMF3 container
            message = decodeFlexSharedObject(in);
            break;
        case TYPE_SHARED_OBJECT:
            message = decodeSharedObject(in);
            break;
        case TYPE_FLEX_MESSAGE:
            message = decodeFlexMessage(in);
            break;
        case TYPE_INVOKE:
            message = decodeAction(conn.getEncoding(), in, header);
            break;
        case TYPE_FLEX_STREAM_SEND:
            if (log.isTraceEnabled()) {
                log.trace("Decoding flex stream send on stream id: {}", header.getStreamId());
            }
            // skip first byte
            in.get();
            // decode stream data; slice from the current position
            message = decodeStreamData(in.slice());
            break;
        case TYPE_NOTIFY:
            if (log.isTraceEnabled()) {
                log.trace("Decoding notify on stream id: {}", header.getStreamId());
            }
            if (header.getStreamId().doubleValue() != 0.0d) {
                message = decodeStreamData(in);
            } else {
                message = decodeAction(conn.getEncoding(), in, header);
            }
            break;
        case TYPE_PING:
            message = decodePing(in);
            break;
        case TYPE_BYTES_READ:
            message = decodeBytesRead(in);
            break;
        case TYPE_CHUNK_SIZE:
            message = decodeChunkSize(in);
            break;
        case TYPE_SERVER_BANDWIDTH:
            message = decodeServerBW(in);
            break;
        case TYPE_CLIENT_BANDWIDTH:
            message = decodeClientBW(in);
            break;
        case TYPE_ABORT:
            message = decodeAbort(in);
            break;
        default:
            log.warn("Unknown object type: {}", dataType);
            message = decodeUnknown(dataType, in);
            break;
    }
    // add the header to the message
    message.setHeader(header);
    return message;
}
 
Example #29
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Decode the 'action' for a supplied an Invoke.
 * 
 * @param encoding
 *            AMF encoding
 * @param in
 *            buffer
 * @param header
 *            data header
 * @return notify
 */
private Invoke decodeAction(Encoding encoding, IoBuffer in, Header header) {
    // for response, the action string and invokeId is always encoded as AMF0 we use the first byte to decide which encoding to use
    in.mark();
    byte tmp = in.get();
    in.reset();
    Input input;
    if (encoding == Encoding.AMF3 && tmp == AMF.TYPE_AMF3_OBJECT) {
        input = new org.red5.io.amf3.Input(in);
        ((org.red5.io.amf3.Input) input).enforceAMF3();
    } else {
        input = new org.red5.io.amf.Input(in);
    }
    // get the action
    String action = Deserializer.deserialize(input, String.class);
    if (action == null) {
        throw new RuntimeException("Action was null");
    }
    if (log.isTraceEnabled()) {
        log.trace("Action: {}", action);
    }
    // instance the invoke
    Invoke invoke = new Invoke();
    // set the transaction id
    invoke.setTransactionId(readTransactionId(input));
    // reset and decode parameters
    input.reset();
    // get / set the parameters if there any
    Object[] params = in.hasRemaining() ? handleParameters(in, invoke, input) : new Object[0];
    // determine service information
    final int dotIndex = action.lastIndexOf('.');
    String serviceName = (dotIndex == -1) ? null : action.substring(0, dotIndex);
    // pull off the prefixes since java doesn't allow this on a method name
    if (serviceName != null && (serviceName.startsWith("@") || serviceName.startsWith("|"))) {
        serviceName = serviceName.substring(1);
    }
    String serviceMethod = (dotIndex == -1) ? action : action.substring(dotIndex + 1, action.length());
    // pull off the prefixes since java doesnt allow this on a method name
    if (serviceMethod.startsWith("@") || serviceMethod.startsWith("|")) {
        serviceMethod = serviceMethod.substring(1);
    }
    // create the pending call for invoke
    PendingCall call = new PendingCall(serviceName, serviceMethod, params);
    invoke.setCall(call);
    return invoke;
}
 
Example #30
Source File: RTMP.java    From red5-server-common with Apache License 2.0 2 votes vote down vote up
/**
 * Setter for last read header.
 *
 * @param channelId
 *            Channel id
 * @param header
 *            Header
 */
public void setLastReadHeader(int channelId, Header header) {
    getChannelInfo(channelId).setReadHeader(header);
}