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

The following examples show how to use org.red5.server.net.rtmp.event.VideoData. 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: QueuedMediaData.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("rawtypes")
public QueuedMediaData(int timestamp, byte dataType, IStreamData streamData) {
    this.tag = ImmutableTag.build(dataType, timestamp, streamData.getData());
    if (streamData instanceof VideoData) {
        video = true;
        config = ((VideoData) streamData).isConfig();
        codecId = ((VideoData) streamData).getCodecId();
        frameType = ((VideoData) streamData).getFrameType();
    } else if (streamData instanceof AudioData) {
        audio = true;
        config = ((AudioData) streamData).isConfig();
    }
}
 
Example #2
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 #3
Source File: RTMPConnection.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Mark message as being written.
 * 
 * @param message
 *            Message to mark
 */
protected void writingMessage(Packet message) {
    if (message.getMessage() instanceof VideoData) {
        Number streamId = message.getHeader().getStreamId();
        final AtomicInteger value = new AtomicInteger();
        AtomicInteger old = pendingVideos.putIfAbsent(streamId.doubleValue(), value);
        if (old == null) {
            old = value;
        }
        old.incrementAndGet();
    }
}
 
Example #4
Source File: RTMPConnection.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Mark message as sent.
 * 
 * @param message
 *            Message to mark
 */
public void messageSent(Packet message) {
    if (message.getMessage() instanceof VideoData) {
        Number streamId = message.getHeader().getStreamId();
        AtomicInteger pending = pendingVideos.get(streamId.doubleValue());
        if (log.isTraceEnabled()) {
            log.trace("Stream id: {} pending: {} total pending videos: {}", streamId, pending, pendingVideos.size());
        }
        if (pending != null) {
            pending.decrementAndGet();
        }
    }
    writtenMessages.incrementAndGet();
}
 
Example #5
Source File: TestConnectionConsumer.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
@Test
public void testNegativeTimestampsAreRolledOver() {
    log.debug("\n testNegativeTimestampsAreRolledOver");
    VideoData videoData1 = new VideoData();
    videoData1.setTimestamp(-1);
    underTest.pushMessage(null, RTMPMessage.build(videoData1));

    assertEquals(Integer.MAX_VALUE, videoData1.getTimestamp());

    VideoData videoData2 = new VideoData();
    videoData2.setTimestamp(Integer.MIN_VALUE);
    underTest.pushMessage(null, RTMPMessage.build(videoData2));

    assertEquals(0, videoData2.getTimestamp());
}
 
Example #6
Source File: TestConnectionConsumer.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
@Test
public void testPositiveTimestampsAreUnaffected() {
    log.debug("\n testPositiveTimestampsAreUnaffected");
    VideoData videoData1 = new VideoData();
    videoData1.setTimestamp(0);
    underTest.pushMessage(null, RTMPMessage.build(videoData1));

    assertEquals(0, videoData1.getTimestamp());

    VideoData videoData2 = new VideoData();
    videoData2.setTimestamp(Integer.MAX_VALUE);
    underTest.pushMessage(null, RTMPMessage.build(videoData2));

    assertEquals(Integer.MAX_VALUE, videoData2.getTimestamp());
}
 
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: 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 #9
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 #10
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 #11
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 #12
Source File: RTMPProtocolEncoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public IoBuffer encodeVideoData(VideoData videoData) {
    final IoBuffer result = videoData.getData();
    return result;
}
 
Example #13
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public VideoData decodeVideoData(IoBuffer in) {
    return new VideoData(in.asReadOnlyBuffer());
}
 
Example #14
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 #15
Source File: IEventDecoder.java    From red5-server-common with Apache License 2.0 2 votes vote down vote up
/**
 * Decodes video data event.
 * 
 * @param in
 *            Byte buffer to decode
 * @return VideoData event
 */
public abstract VideoData decodeVideoData(IoBuffer in);
 
Example #16
Source File: IEventEncoder.java    From red5-server-common with Apache License 2.0 2 votes vote down vote up
/**
 * Encodes VideoData event to byte buffer.
 *
 * @param videoData
 *            VideoData event
 * @return Byte buffer
 */
public abstract IoBuffer encodeVideoData(VideoData videoData);