org.red5.server.net.rtmp.event.IRTMPEvent Java Examples

The following examples show how to use org.red5.server.net.rtmp.event.IRTMPEvent. 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: 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 #2
Source File: Application.java    From red5-rtsp-restreamer with Apache License 2.0 6 votes vote down vote up
@Override
public void packetReceived(IBroadcastStream stream, IStreamPacket packet) {

	RTMPMessage m = RTMPMessage.build((IRTMPEvent) packet, packet.getTimestamp());

	try {

		limiter--;
		if (limiter > 1) {
			streamer.pushMessage(null, m);
		} else {
			if (streamer != null) {
				stream.removeStreamListener(this);
				streamer.stop();
				streamer = null;
			}
		}

	} catch (IOException e) {

		e.printStackTrace();
	}

}
 
Example #3
Source File: PlayEngine.java    From red5-server-common with Apache License 2.0 6 votes vote down vote up
/**
 * Send message to output stream and handle exceptions.
 * 
 * @param message
 *            The message to send.
 */
private void doPushMessage(AbstractMessage message) {
    if (log.isTraceEnabled()) {
        String msgType = message.getMessageType();
        log.trace("doPushMessage: {}", msgType);
    }
    IMessageOutput out = msgOutReference.get();
    if (out != null) {
        try {
            out.pushMessage(message);
            if (message instanceof RTMPMessage) {
                IRTMPEvent body = ((RTMPMessage) message).getBody();
                // update the last message sent's timestamp
                lastMessageTs = body.getTimestamp();
                IoBuffer streamData = null;
                if (body instanceof IStreamData && (streamData = ((IStreamData<?>) body).getData()) != null) {
                    bytesSent.addAndGet(streamData.limit());
                }
            }
        } catch (IOException err) {
            log.warn("Error while pushing message", err);
        }
    } else {
        log.warn("Push message failed due to null output pipe");
    }
}
 
Example #4
Source File: StreamRelay.java    From red5-client with Apache License 2.0 5 votes vote down vote up
@Override
public void dispatchEvent(IEvent event) {
    System.out.println("ClientStream.dispachEvent()" + event.toString());
    try {
        proxy.pushMessage(null, RTMPMessage.build((IRTMPEvent) event));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
 
Example #5
Source File: Channel.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Writes packet from event data to RTMP connection.
 *
 * @param event
 *            Event data
 */
public void write(IRTMPEvent event) {
    if (!connection.isClosed()) {
        final IClientStream stream = connection.getStreamByChannelId(id);
        if (id > 3 && stream == null) {
            log.warn("Non-existant stream for channel id: {}, session: {} discarding: {}", id, connection.getSessionId(), event);
        }
        // if the stream is non-existant, the event will go out with stream id == 0
        final Number streamId = (stream == null) ? 0 : stream.getStreamId();
        write(event, streamId);
    } else {
        log.debug("Connection {} is closed, cannot write to channel: {}", connection.getSessionId(), id);
    }
}
 
Example #6
Source File: Channel.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Discard an event routed to this channel.
 * 
 * @param event
 */
@SuppressWarnings("unused")
private void discard(IRTMPEvent event) {
    if (event instanceof IStreamData<?>) {
        log.debug("Discarding: {}", ((IStreamData<?>) event).toString());
        IoBuffer data = ((IStreamData<?>) event).getData();
        if (data != null) {
            log.trace("Freeing discarded event data");
            data.free();
            data = null;
        }
    }
    event.setHeader(null);
}
 
Example #7
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 #8
Source File: PlayEngine.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Releases pending message body, nullifies pending message object
 */
private void releasePendingMessage() {
    if (pendingMessage != null) {
        IRTMPEvent body = pendingMessage.getBody();
        if (body instanceof IStreamData && ((IStreamData<?>) body).getData() != null) {
            ((IStreamData<?>) body).getData().free();
        }
        pendingMessage = null;
    }
}
 
Example #9
Source File: PlayEngine.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Check if it's okay to send the client more data. This takes the configured bandwidth as well as the requested client buffer into
 * account.
 * 
 * @param message
 * @return true if it is ok to send more, false otherwise
 */
private boolean okayToSendMessage(IRTMPEvent message) {
    if (message instanceof IStreamData) {
        final long now = System.currentTimeMillis();
        // check client buffer size
        if (isClientBufferFull(now)) {
            return false;
        }
        // get pending message count
        long pending = pendingMessages();
        if (bufferCheckInterval > 0 && now >= nextCheckBufferUnderrun) {
            if (pending > underrunTrigger) {
                // client is playing behind speed, notify him
                sendInsufficientBandwidthStatus(currentItem.get());
            }
            nextCheckBufferUnderrun = now + bufferCheckInterval;
        }
        // check for under run
        if (pending > underrunTrigger) {
            // too many messages already queued on the connection
            return false;
        }
        return true;
    } else {
        String itemName = "Undefined";
        // if current item exists get the name to help debug this issue
        if (currentItem.get() != null) {
            itemName = currentItem.get().getName();
        }
        Object[] errorItems = new Object[] { message.getClass(), message.getDataType(), itemName };
        throw new RuntimeException(String.format("Expected IStreamData but got %s (type %s) for %s", errorItems));
    }
}
 
Example #10
Source File: PlayEngine.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Performs the processes needed for VOD / pre-recorded streams.
 * 
 * @param withReset
 *            whether or not to perform reset on the stream
 * @param itemLength
 *            length of the item to be played
 * @return message for the consumer
 * @throws IOException
 */
private final IMessage playVOD(boolean withReset, long itemLength) throws IOException {
    IMessage msg = null;
    // change state
    subscriberStream.setState(StreamState.PLAYING);
    if (withReset) {
        releasePendingMessage();
    }
    sendVODInitCM(currentItem.get());
    // Don't use pullAndPush to detect IOExceptions prior to sending NetStream.Play.Start
    int start = (int) currentItem.get().getStart();
    if (start > 0) {
        streamOffset = sendVODSeekCM(start);
        // We seeked to the nearest keyframe so use real timestamp now
        if (streamOffset == -1) {
            streamOffset = start;
        }
    }
    IMessageInput in = msgInReference.get();
    msg = in.pullMessage();
    if (msg instanceof RTMPMessage) {
        // Only send first video frame
        IRTMPEvent body = ((RTMPMessage) msg).getBody();
        if (itemLength == 0) {
            while (body != null && !(body instanceof VideoData)) {
                msg = in.pullMessage();
                if (msg != null && msg instanceof RTMPMessage) {
                    body = ((RTMPMessage) msg).getBody();
                } else {
                    break;
                }
            }
        }
        if (body != null) {
            // Adjust timestamp when playing lists
            body.setTimestamp(body.getTimestamp() + timestampOffset);
        }
    }
    return msg;
}
 
Example #11
Source File: SlicedFileConsumer.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Sets a audio decoder configuration; some codecs require this, such as AAC.
 * 
 * @param decoderConfig
 *            audio codec configuration
 */
public void setAudioDecoderConfiguration(IRTMPEvent decoderConfig) {
    if (decoderConfig instanceof IStreamData) {
        IoBuffer data = ((IStreamData<?>) decoderConfig).getData().asReadOnlyBuffer();
        audioConfigurationTag = ImmutableTag.build(decoderConfig.getDataType(), 0, data, 0);
    }
}
 
Example #12
Source File: SlicedFileConsumer.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Sets a video decoder configuration; some codecs require this, such as AVC.
 * 
 * @param decoderConfig
 *            video codec configuration
 */
public void setVideoDecoderConfiguration(IRTMPEvent decoderConfig) {
    if (decoderConfig instanceof IStreamData) {
        IoBuffer data = ((IStreamData<?>) decoderConfig).getData().asReadOnlyBuffer();
        videoConfigurationTag = ImmutableTag.build(decoderConfig.getDataType(), 0, data, 0);
    }
}
 
Example #13
Source File: AxisTest.java    From red5-rtsp-restreamer with Apache License 2.0 4 votes vote down vote up
public synchronized List<IRTMPEvent> getLastSlices() {
	return slices;
}
 
Example #14
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 #15
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
public IRTMPEvent decodeAbort(IoBuffer in) {
    return new Abort(in.getInt());
}
 
Example #16
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 #17
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 #18
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 #19
Source File: Packet.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    header = (Header) in.readObject();
    message = (IRTMPEvent) in.readObject();
    message.setHeader(header);
    message.setTimestamp(header.getTimer());
}
 
Example #20
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 #21
Source File: VideoFrameDropper.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public boolean canSendPacket(RTMPMessage message, long pending) {
    IRTMPEvent packet = message.getBody();
    boolean result = true;
    // We currently only drop video packets.
    if (packet instanceof VideoData) {
        VideoData video = (VideoData) packet;
        FrameType type = video.getFrameType();
        switch (state) {
            case SEND_ALL:
                // All packets will be sent
                break;
            case SEND_INTERFRAMES:
                // Only keyframes and interframes will be sent.
                if (type == FrameType.KEYFRAME) {
                    if (pending == 0) {
                        // Send all frames from now on.
                        state = SEND_ALL;
                    }
                } else if (type == FrameType.INTERFRAME) {
                }
                break;
            case SEND_KEYFRAMES:
                // Only keyframes will be sent.
                result = (type == FrameType.KEYFRAME);
                if (result && pending == 0) {
                    // Maybe switch back to SEND_INTERFRAMES after the next keyframe
                    state = SEND_KEYFRAMES_CHECK;
                }
                break;
            case SEND_KEYFRAMES_CHECK:
                // Only keyframes will be sent.
                result = (type == FrameType.KEYFRAME);
                if (result && pending == 0) {
                    // Continue with sending interframes as well
                    state = SEND_INTERFRAMES;
                }
                break;
            default:
        }
    }
    return result;
}
 
Example #22
Source File: AxisTest.java    From red5-rtsp-restreamer with Apache License 2.0 4 votes vote down vote up
public synchronized IRTMPEvent getLastKey() {
	return lastKey;
}
 
Example #23
Source File: SlicedFileConsumer.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Push message through pipe
 * 
 * @param pipe
 *            Pipe
 * @param message
 *            Message to push
 * @throws IOException
 *             if message could not be written
 */
@SuppressWarnings("rawtypes")
public void pushMessage(IPipe pipe, IMessage message) throws IOException {
    if (message instanceof RTMPMessage) {
        final IRTMPEvent msg = ((RTMPMessage) message).getBody();
        // get the type
        byte dataType = msg.getDataType();
        // get the timestamp
        int timestamp = msg.getTimestamp();
        log.trace("Data type: {} timestamp: {}", dataType, timestamp);
        // if writes are delayed, queue the data and sort it by time
        if (queue == null) {
            // if we plan to use a queue, create one
            queue = new PriorityQueue<QueuedMediaData>(queueThreshold <= 0 ? 11 : queueThreshold);
        }
        QueuedMediaData queued = null;
        if (msg instanceof IStreamData) {
            if (log.isTraceEnabled()) {
                log.trace("Stream data, body saved. Data type: {} class type: {}", dataType, msg.getClass().getName());
            }
            // ensure that our first video frame written is a key frame
            if (msg instanceof VideoData) {
                log.debug("pushMessage video - waitForVideoKeyframe: {} gotVideoKeyframe: {}", waitForVideoKeyframe, gotVideoKeyframe);
                if (!gotVideoKeyframe) {
                    VideoData video = (VideoData) msg;
                    if (video.getFrameType() == FrameType.KEYFRAME) {
                        log.debug("Got our first keyframe");
                        gotVideoKeyframe = true;
                    }
                    if (waitForVideoKeyframe && !gotVideoKeyframe) {
                        // skip this frame bail out
                        log.debug("Skipping video data since keyframe has not been written yet");
                        return;
                    }
                }
            }
            queued = new QueuedMediaData(timestamp, dataType, (IStreamData) msg);
        } else {
            // XXX what type of message are we saving that has no body data??
            if (log.isTraceEnabled()) {
                log.trace("Non-stream data, body not saved. Data type: {} class type: {}", dataType, msg.getClass().getName());
            }
            queued = new QueuedMediaData(timestamp, dataType);
        }
        if (queued != null) {
            writeLock.lock();
            try {
                // add to the queue
                queue.add(queued);
            } finally {
                writeLock.unlock();
            }
        }
        int queueSize = 0;
        readLock.lock();
        try {
            queueSize = queue.size();
        } finally {
            readLock.unlock();
        }
        // initialize a writer
        if (writer == null) {
            init();
            if (msg instanceof VideoData) {
                writeQueuedDataSlice(createTimestampLimitedSlice(msg.getTimestamp()));
            } else if (queueThreshold >= 0 && queueSize >= queueThreshold) {
                writeQueuedDataSlice(createFixedLengthSlice(queueThreshold / (100 / percentage)));
            }
        }
    } else if (message instanceof ResetMessage) {
        startTimestamp = -1;
    } else if (log.isDebugEnabled()) {
        log.debug("Ignoring pushed message: {}", message);
    }
}
 
Example #24
Source File: FileConsumer.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
public void setAudioDecoderConfiguration(IRTMPEvent audioConfig) {
    // no-op
}
 
Example #25
Source File: FileConsumer.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
public void setVideoDecoderConfiguration(IRTMPEvent videoConfig) {
    // no-op
}
 
Example #26
Source File: VideoFrameDropper.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public void dropPacket(RTMPMessage message) {
    IRTMPEvent packet = message.getBody();
    // Only check video packets.
    if (packet instanceof VideoData) {
        VideoData video = (VideoData) packet;
        FrameType type = video.getFrameType();
        switch (state) {
            case SEND_ALL:
                if (type == FrameType.DISPOSABLE_INTERFRAME) {
                    // Remain in state, packet is safe to drop.
                    return;
                } else if (type == FrameType.INTERFRAME) {
                    // Drop all frames until the next keyframe.
                    state = SEND_KEYFRAMES;
                    return;
                } else if (type == FrameType.KEYFRAME) {
                    // Drop all frames until the next keyframe.
                    state = SEND_KEYFRAMES;
                    return;
                }
                break;
            case SEND_INTERFRAMES:
                if (type == FrameType.INTERFRAME) {
                    // Drop all frames until the next keyframe.
                    state = SEND_KEYFRAMES_CHECK;
                    return;
                } else if (type == FrameType.KEYFRAME) {
                    // Drop all frames until the next keyframe.
                    state = SEND_KEYFRAMES;
                    return;
                }
                break;
            case SEND_KEYFRAMES:
                // Remain in state.
                break;
            case SEND_KEYFRAMES_CHECK:
                if (type == FrameType.KEYFRAME) {
                    // Switch back to sending keyframes, but don't move to
                    // SEND_INTERFRAMES afterwards.
                    state = SEND_KEYFRAMES;
                    return;
                }
                break;
            default:
        }
    }
}
 
Example #27
Source File: RTMPMessage.java    From red5-server-common with Apache License 2.0 3 votes vote down vote up
/**
 * Creates a new rtmp message.
 * 
 * @param body
 *            value to set for property 'body'
 * @param eventTime
 *            updated timestamp
 */
private RTMPMessage(IRTMPEvent body, int eventTime) {
    this.body = body;
    this.body.setTimestamp(eventTime);
    this.body.setSourceType(body.getSourceType());
    this.setMessageType(RTMPType.valueOf(body.getDataType()));
}
 
Example #28
Source File: Packet.java    From red5-server-common with Apache License 2.0 3 votes vote down vote up
/**
 * Create packet with given header and event context.
 * 
 * @param header
 *            RTMP header
 * @param event
 *            RTMP message
 */
public Packet(Header header, IRTMPEvent event) {
    if (log.isTraceEnabled()) {
        log.trace("Header: {} event: {}", header, event);
    }
    this.header = header;
    this.message = event;
}
 
Example #29
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 2 votes vote down vote up
/**
 * Decodes client bandwidth.
 * 
 * @param in
 *            Byte buffer
 * @return RTMP event
 */
private IRTMPEvent decodeClientBW(IoBuffer in) {
    return new ClientBW(in.getInt(), in.get());
}
 
Example #30
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 2 votes vote down vote up
/**
 * Decodes server bandwidth.
 * 
 * @param in
 *            IoBuffer
 * @return RTMP event
 */
private IRTMPEvent decodeServerBW(IoBuffer in) {
    return new ServerBW(in.getInt());
}