Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Update to spring 3.0.6. Applied patches for issues #132 and #153. Als…

…o a bit of clean up on other classes.

git-svn-id: http://red5.googlecode.com/svn/java/server/trunk@4290 1b6495e4-3631-0410-8e05-8f51eee8b9cc
  • Loading branch information...
commit b4557c3ea7eb636c74c78fcd8efe7246ccbdea8a 1 parent 2e039f1
mondain authored
View
172 ivy.xml
@@ -1,82 +1,92 @@
-<ivy-module version="2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
- <info organisation="red5" module="server" />
-
- <configurations defaultconfmapping="default">
- <conf name="default"/>
- <conf name="java6" extends="default" description="Java 6 dependencies"/>
- <conf name="eclipse" description="Special dependencies in Eclipse"/>
- <conf name="utest" extends="eclipse" description="Unit testing dependencies"/>
- </configurations>
-
- <dependencies>
- <dependency org="javax" name="javaee-api" rev="5.1.2" />
-
- <!-- Spring -->
- <dependency org="org.springframework" name="spring-asm" rev="3.0.5.RELEASE"/>
- <dependency org="org.springframework" name="spring-beans" rev="3.0.5.RELEASE" />
- <dependency org="org.springframework" name="spring-context" rev="3.0.5.RELEASE" />
- <dependency org="org.springframework" name="spring-core" rev="3.0.5.RELEASE" />
- <dependency org="org.springframework" name="spring-expression" rev="3.0.5.RELEASE" />
- <dependency org="org.springframework" name="spring-web" rev="3.0.5.RELEASE" />
-
- <!-- Logging -->
- <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="1.6.1" transitive="false" />
- <dependency org="org.slf4j" name="com.springsource.slf4j.bridge" rev="1.6.1" transitive="false" />
-
- <dependency name="jul-to-slf4j" rev="1.6.1" />
- <dependency name="log4j-over-slf4j" rev="1.6.1" />
- <dependency name="jcl-over-slf4j" rev="1.6.1" />
- <dependency name="logback-classic" rev="0.9.28" />
- <dependency name="logback-core" rev="0.9.28" />
-
- <!-- General -->
- <dependency org="commons" name="commons-beanutils" rev="1.8.2" />
- <dependency org="org.apache.commons" name="com.springsource.org.apache.commons.codec" rev="1.4.0" transitive="false" />
- <dependency org="org.apache.commons" name="com.springsource.org.apache.commons.collections" rev="3.2.1" transitive="false" />
-
- <dependency org="commons" name="httpcore" rev="4.1.3" />
- <dependency org="commons" name="httpclient" rev="4.1.2" />
-
- <dependency org="commons" name="commons-lang3" rev="3.0-beta" />
- <dependency org="org.apache.commons" name="com.springsource.org.apache.commons.modeler" rev="2.0.1" transitive="false" />
-
- <dependency org="commons" name="commons-pool" rev="1.5.6" />
- <dependency name="quartz" rev="1.8.5" />
- <dependency name="ehcache" rev="2.2.0" />
-
- <!-- XML -->
- <dependency org="org.apache.xerces" name="com.springsource.org.apache.xerces" rev="2.9.1" transitive="false" />
- <dependency name="xmlrpc" rev="2.0.1" />
-
- <!-- Mina -->
- <dependency org="mina" name="mina-integration-beans" rev="2.0.4" />
- <dependency org="mina" name="mina-integration-jmx" rev="2.0.4" />
- <dependency org="mina" name="mina-core" rev="2.0.4" />
-
- <!-- Scripting -->
- <dependency org="org.objectweb.asm" name="com.springsource.org.objectweb.asm" rev="3.2.0" transitive="false" />
- <dependency org="org.objectweb.asm" name="com.springsource.org.objectweb.asm.commons" rev="3.2.0" transitive="false" />
- <dependency org="org.antlr" name="com.springsource.org.antlr" rev="3.1.3" transitive="false" />
- <dependency org="org.codehaus.groovy" name="com.springsource.org.codehaus.groovy" rev="1.7.0" transitive="false" />
- <dependency name="jruby-complete" rev="1.1.6" />
- <dependency name="jython" rev="2.5" />
- <dependency org="org.mozilla.javascript" name="com.springsource.org.mozilla.javascript" rev="1.7.0.R2" transitive="false" />
- <dependency org="javax.xml.stream" name="com.springsource.javax.xml.stream" rev="1.0.1" transitive="false" />
- <dependency org="org.springframework" name="spring-context-support" rev="3.0.5.RELEASE" />
-
- <!-- Crypto -->
- <dependency name="bcprov-jdk16" rev="145" conf="java6->*" />
-
- <!-- MP3 -->
- <dependency name="jaudiotagger" rev="2.0.4-SNAPSHOT" />
-
- <!-- Testing support -->
- <!-- until Eclipse updates their junit version, we have to use this -->
- <dependency org="org.junit" name="com.springsource.org.junit" rev="4.8.1" conf="eclipse->*" transitive="false" />
- <dependency name="GroboUtils" rev="5-core" conf="eclipse->*" />
- <dependency org="org.springframework" name="org.springframework.test" rev="3.0.5.RELEASE" conf="eclipse->*" transitive="false" />
- <dependency org="org.springframework" name="org.springframework.transaction" rev="3.0.5.RELEASE" conf="eclipse->*" transitive="false" />
- </dependencies>
+<ivy-module version="2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
+ <info organisation="red5" module="server" />
+ <configurations defaultconfmapping="default">
+ <conf name="default" />
+ <conf name="java6" extends="default" description="Java 6 dependencies" />
+ <conf name="eclipse" description="Special dependencies in Eclipse" />
+ <conf name="utest" extends="eclipse" description="Unit testing dependencies" />
+ </configurations>
+ <dependencies>
+ <dependency org="javax" name="javaee-api" rev="5.1.2" />
+ <!-- Spring -->
+ <dependency org="org.springframework" name="spring-asm"
+ rev="3.0.6.RELEASE" />
+ <dependency org="org.springframework" name="spring-beans"
+ rev="3.0.6.RELEASE" />
+ <dependency org="org.springframework" name="spring-context"
+ rev="3.0.6.RELEASE" />
+ <dependency org="org.springframework" name="spring-core"
+ rev="3.0.6.RELEASE" />
+ <dependency org="org.springframework" name="spring-expression"
+ rev="3.0.6.RELEASE" />
+ <dependency org="org.springframework" name="spring-web"
+ rev="3.0.6.RELEASE" />
+ <!-- Logging -->
+ <dependency org="org.slf4j" name="com.springsource.slf4j.api"
+ rev="1.6.1" transitive="false" />
+ <dependency org="org.slf4j" name="com.springsource.slf4j.bridge"
+ rev="1.6.1" transitive="false" />
+ <dependency name="jul-to-slf4j" rev="1.6.1" />
+ <dependency name="log4j-over-slf4j" rev="1.6.1" />
+ <dependency name="jcl-over-slf4j" rev="1.6.1" />
+ <dependency name="logback-classic" rev="0.9.28" />
+ <dependency name="logback-core" rev="0.9.28" />
+ <!-- General -->
+ <dependency org="commons" name="commons-beanutils" rev="1.8.2" />
+ <dependency org="org.apache.commons" name="com.springsource.org.apache.commons.codec"
+ rev="1.4.0" transitive="false" />
+ <dependency org="org.apache.commons"
+ name="com.springsource.org.apache.commons.collections" rev="3.2.1"
+ transitive="false" />
+ <dependency org="commons" name="httpcore" rev="4.1.3" />
+ <dependency org="commons" name="httpclient" rev="4.1.2" />
+ <dependency org="commons" name="commons-lang3" rev="3.0-beta" />
+ <dependency org="org.apache.commons"
+ name="com.springsource.org.apache.commons.modeler" rev="2.0.1"
+ transitive="false" />
+ <dependency org="commons" name="commons-pool" rev="1.5.6" />
+ <dependency name="quartz" rev="1.8.5" />
+ <dependency name="ehcache" rev="2.2.0" />
+ <!-- XML -->
+ <dependency org="org.apache.xerces" name="com.springsource.org.apache.xerces"
+ rev="2.9.1" transitive="false" />
+ <dependency name="xmlrpc" rev="2.0.1" />
+ <!-- Mina -->
+ <dependency org="mina" name="mina-integration-beans" rev="2.0.4" />
+ <dependency org="mina" name="mina-integration-jmx" rev="2.0.4" />
+ <dependency org="mina" name="mina-core" rev="2.0.4" />
+ <!-- Scripting -->
+ <dependency org="org.objectweb.asm" name="com.springsource.org.objectweb.asm"
+ rev="3.2.0" transitive="false" />
+ <dependency org="org.objectweb.asm"
+ name="com.springsource.org.objectweb.asm.commons" rev="3.2.0"
+ transitive="false" />
+ <dependency org="org.antlr" name="com.springsource.org.antlr"
+ rev="3.1.3" transitive="false" />
+ <dependency org="org.codehaus.groovy" name="com.springsource.org.codehaus.groovy"
+ rev="1.7.0" transitive="false" />
+ <dependency name="jruby-complete" rev="1.1.6" />
+ <dependency name="jython" rev="2.5" />
+ <dependency org="org.mozilla.javascript" name="com.springsource.org.mozilla.javascript"
+ rev="1.7.0.R2" transitive="false" />
+ <dependency org="javax.xml.stream" name="com.springsource.javax.xml.stream"
+ rev="1.0.1" transitive="false" />
+ <dependency org="org.springframework" name="spring-context-support"
+ rev="3.0.6.RELEASE" />
+ <!-- Crypto -->
+ <dependency name="bcprov-jdk16" rev="145" conf="java6->*" />
+ <!-- MP3 -->
+ <dependency name="jaudiotagger" rev="2.0.4-SNAPSHOT" />
+ <!-- Testing support -->
+ <!-- until Eclipse updates their junit version, we have to use this -->
+ <dependency org="org.junit" name="com.springsource.org.junit"
+ rev="4.8.1" conf="eclipse->*" transitive="false" />
+ <dependency name="GroboUtils" rev="5-core" conf="eclipse->*" />
+ <dependency org="org.springframework" name="org.springframework.test"
+ rev="3.0.6.RELEASE" conf="eclipse->*" transitive="false" />
+ <dependency org="org.springframework" name="org.springframework.transaction"
+ rev="3.0.6.RELEASE" conf="eclipse->*" transitive="false" />
+ </dependencies>
</ivy-module>
View
5 src/org/red5/io/amf/Input.java
@@ -559,7 +559,10 @@ public Object readObject(Deserializer deserializer, Type target) {
instance = newInstance(className);
if (instance != null) {
result = readBean(deserializer, instance);
- } // else fall through
+ } else {
+ log.debug("Forced to use simple object for class {}", className);
+ result = readSimpleObject(deserializer);
+ }
}
} else {
result = readSimpleObject(deserializer);
View
2  src/org/red5/server/api/Red5.java
@@ -43,7 +43,7 @@
*
* @author The Red5 Project (red5@osflash.org)
* @author Luke Hubbard (luke@codegent.com)
- * @author Paul Gregoire (mondain@gmail.com)
+ * @author Paul Gregoire (mondain@gmail.com)
*/
public final class Red5 {
View
65 src/org/red5/server/api/stream/IVideoStreamCodec.java
@@ -26,14 +26,14 @@
*/
public interface IVideoStreamCodec {
- /**
- * FLV frame marker constant
- */
+ /**
+ * FLV frame marker constant
+ */
static final byte FLV_FRAME_KEY = 0x10;
-
+
/**
* @return the name of the video codec.
- */
+ */
public String getName();
/**
@@ -43,35 +43,66 @@
/**
* Check if the codec supports frame dropping.
- * @return if the codec supports frame dropping.
- */
+ * @return if the codec supports frame dropping.
+ */
public boolean canDropFrames();
/**
* Returns true if the codec knows how to handle the passed
* stream data.
- * @param data some sample data to see if this codec can handle it.
- * @return can this code handle the data.
- */
+ * @param data some sample data to see if this codec can handle it.
+ * @return can this code handle the data.
+ */
public boolean canHandleData(IoBuffer data);
/**
* Update the state of the codec with the passed data.
- * @param data data to tell the codec we're adding
- * @return true for success. false for error.
- */
+ * @param data data to tell the codec we're adding
+ * @return true for success. false for error.
+ */
public boolean addData(IoBuffer data);
/**
* @return the data for a keyframe.
- */
+ */
public IoBuffer getKeyframe();
-
+
/**
* Returns information used to configure the decoder.
*
* @return the data for decoder setup.
- */
+ */
public IoBuffer getDecoderConfiguration();
-
+
+ /**
+ * Holder for video frame data.
+ */
+ public final static class FrameData {
+
+ private IoBuffer frame;
+
+ /**
+ * Makes a copy of the incoming bytes and places them in an IoBuffer. No flip or rewind is performed on the source data.
+ *
+ * @param data
+ */
+ public void setData(IoBuffer data) {
+ if (frame == null) {
+ frame = IoBuffer.allocate(data.limit());
+ } else {
+ frame.clear();
+ frame.free();
+ frame = IoBuffer.allocate(data.limit());
+ }
+ byte[] buf = new byte[frame.limit()];
+ data.get(buf);
+ frame.put(buf).flip();
+ }
+
+ public IoBuffer getFrame() {
+ return frame == null ? null : frame.asReadOnlyBuffer();
+ }
+
+ }
+
}
View
78 src/org/red5/server/net/rtmp/RTMPConnection.java
@@ -29,6 +29,7 @@
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -213,8 +214,8 @@
/**
* Bandwidth limit type / enforcement. (0=hard,1=soft,2=dynamic)
*/
- protected int limitType = 0;
-
+ protected int limitType = 0;
+
protected volatile int clientId;
/**
@@ -267,8 +268,8 @@ public void setBandwidth(int mbits) {
getChannel(2).write(new ServerBW(mbits));
// second param is the limit type (0=hard,1=soft,2=dynamic)
getChannel(2).write(new ClientBW(mbits, (byte) limitType));
- }
-
+ }
+
@Override
public boolean connect(IScope newScope, Object[] params) {
log.debug("Connect scope: {}", newScope);
@@ -1161,42 +1162,57 @@ public boolean equals(Object obj) {
*/
private class KeepAliveJob implements IScheduledJob {
+ private final AtomicBoolean running = new AtomicBoolean(false);
+
private final AtomicLong lastBytesRead = new AtomicLong(0);
private volatile long lastBytesReadTime = 0;
/** {@inheritDoc} */
public void execute(ISchedulingService service) {
- long thisRead = getReadBytes();
- long previousReadBytes = lastBytesRead.get();
- if (thisRead > previousReadBytes) {
- // Client sent data since last check and thus is not dead. No need to ping
- if (lastBytesRead.compareAndSet(previousReadBytes, thisRead)) {
- lastBytesReadTime = System.currentTimeMillis();
- }
- return;
- }
- // Client didn't send response to ping command and didn't sent data for too long, disconnect
- if (lastPongReceived.get() > 0 && (lastPingSent.get() - lastPongReceived.get() > maxInactivity) && !(System.currentTimeMillis() - lastBytesReadTime < maxInactivity)) {
- log.debug("Keep alive job name {}", keepAliveJobName);
- if (log.isDebugEnabled()) {
- log.debug("Scheduled job list");
- for (String jobName : service.getScheduledJobNames()) {
- log.debug("Job: {}", jobName);
+ // ensure the job is not already running
+ if (running.compareAndSet(false, true)) {
+ // get now
+ long now = System.currentTimeMillis();
+ // get the current bytes read count on the connection
+ long currentReadBytes = getReadBytes();
+ // get our last bytes read count
+ long previousReadBytes = lastBytesRead.get();
+ log.debug("Time now: {} current read count: {} last read count: {}", new Object[] { now, currentReadBytes, previousReadBytes });
+ if (currentReadBytes > previousReadBytes) {
+ log.debug("Client is still alive, no ping needed");
+ // client has sent data since last check and thus is not dead. No need to ping
+ if (lastBytesRead.compareAndSet(previousReadBytes, currentReadBytes)) {
+ // update the timestamp to match our update
+ lastBytesReadTime = now;
+ }
+ } else {
+ // client didn't send response to ping command and didn't sent data for too long, disconnect
+ long lastPingTime = lastPingSent.get();
+ long lastPongTime = lastPongReceived.get();
+ if (lastPongTime > 0 && (lastPingTime - lastPongTime > maxInactivity) && !(now - lastBytesReadTime < maxInactivity)) {
+ log.debug("Keep alive job name {}", keepAliveJobName);
+ if (log.isTraceEnabled()) {
+ log.trace("Scheduled job list");
+ for (String jobName : service.getScheduledJobNames()) {
+ log.trace("Job: {}", jobName);
+ }
+ }
+ service.removeScheduledJob(keepAliveJobName);
+ keepAliveJobName = null;
+ log.warn("Closing {}, with id {}, due to too much inactivity ({} ms), last ping sent {} ms ago", new Object[] { RTMPConnection.this, getId(),
+ (lastPingTime - lastPongTime), (now - lastPingTime) });
+ // Add the following line to (hopefully) deal with a very common support request
+ // on the Red5 list
+ log.warn("This often happens if YOUR Red5 application generated an exception on start-up. Check earlier in the log for that exception first!");
+ onInactive();
}
+ // send ping command to client to trigger sending of data
+ ping();
}
- service.removeScheduledJob(keepAliveJobName);
- keepAliveJobName = null;
- log.warn("Closing {}, with id {}, due to too much inactivity ({}ms), last ping sent {}ms ago", new Object[] { RTMPConnection.this, getId(),
- (lastPingSent.get() - lastPongReceived.get()), (System.currentTimeMillis() - lastPingSent.get()) });
- // Add the following line to (hopefully) deal with a very common support request
- // on the Red5 list
- log.warn("This often happens if YOUR Red5 application generated an exception on start-up. Check earlier in the log for that exception first!");
- onInactive();
- return;
+ // reset running flag
+ running.compareAndSet(true, false);
}
- // Send ping command to client to trigger sending of data
- ping();
}
}
View
2  src/org/red5/server/net/rtmp/event/ClientBW.java
@@ -24,7 +24,7 @@
import java.io.ObjectOutput;
/**
- * Client bandwidth event
+ * Client bandwidth event. Also known as a Peer Bandwidth message.
*/
public class ClientBW extends BaseEvent {
View
2  src/org/red5/server/net/rtmp/event/ServerBW.java
@@ -24,7 +24,7 @@
import java.io.ObjectOutput;
/**
- * Server bandwidth event
+ * Server bandwidth event. Also known as a Window Acknowledgement size message.
*/
public class ServerBW extends BaseEvent {
View
5 src/org/red5/server/net/rtmp/message/Constants.java
@@ -70,7 +70,10 @@
*/
public static final byte TYPE_CLIENT_BANDWIDTH = 0x06;
- // Unknown: 0x07
+ /**
+ * Edge / Origin message.
+ */
+ public static final byte TYPE_EDGE_ORIGIN = 0x07;
/**
* Audio data marker
View
35 src/org/red5/server/stream/PlayEngine.java
@@ -954,33 +954,34 @@ private void sendMessage(RTMPMessage messageIn) {
if (log.isTraceEnabled()) {
log.trace("sendMessage: streamStartTS={}, length={}, streamOffset={}, timestamp={}", new Object[] { streamStartTS, currentItem.getLength(), streamOffset, ts });
}
+
+ // don't reset streamStartTS to 0 for live streams
+ if ((streamStartTS == -1 && (ts > 0 || playDecision != 0)) || streamStartTS > ts) {
+ log.debug("sendMessage: resetting streamStartTS");
+ streamStartTS = ts;
+ messageOut.getBody().setTimestamp(0);
+ }
+
//relative timestamp adjustment for live streams
if (playDecision == 0 && streamStartTS > 0) {
//subtract the offset time of when the stream started playing for the client
- int relativeTs = ts - streamStartTS;
- messageOut.getBody().setTimestamp(relativeTs);
- //we changed the timestamp to update var
- ts = relativeTs;
+ ts -= streamStartTS;
+ messageOut.getBody().setTimestamp(ts);
if (log.isTraceEnabled()) {
log.trace("sendMessage (updated): streamStartTS={}, length={}, streamOffset={}, timestamp={}", new Object[] { streamStartTS, currentItem.getLength(), streamOffset,
ts });
}
}
- // don't reset streamStartTS to 0 for live streams
- if (streamStartTS == -1 && (ts > 0 || playDecision != 0)) {
- log.debug("sendMessage: resetting streamStartTS");
- streamStartTS = ts;
- messageOut.getBody().setTimestamp(0);
- } else {
- if (currentItem.getLength() >= 0) {
- int duration = ts - streamStartTS;
- if (duration - streamOffset >= currentItem.getLength()) {
- // Sent enough data to client
- stop();
- return;
- }
+
+ if (streamStartTS > -1 && currentItem.getLength() >= 0) {
+ int duration = ts - streamStartTS;
+ if (duration - streamOffset >= currentItem.getLength()) {
+ // Sent enough data to client
+ stop();
+ return;
}
}
+
doPushMessage(messageOut);
}
View
126 src/org/red5/server/stream/codec/AVCVideo.java
@@ -25,9 +25,7 @@
import org.slf4j.Logger;
/**
- * Red5 video codec for the AVC (h264) video format.
- *
- * Store DecoderConfigurationRecord and last keyframe (for now! we're cooking a very exciting new!)
+ * Red5 video codec for the AVC (h264) video format. Stores DecoderConfigurationRecord and last keyframe.
*
* @author Tiago Jacobs (tiago@imdt.com.br)
* @author Paul Gregoire (mondain@gmail.com)
@@ -41,35 +39,11 @@
*/
static final String CODEC_NAME = "AVC";
- /**
- * Block of data (AVC DecoderConfigurationRecord)
- */
- private byte[] blockDataAVCDCR;
-
- /**
- * Data block size (AVC DecoderConfigurationRecord)
- */
- private int blockSizeAVCDCR;
-
- /**
- * Block of data (Last KeyFrame)
- */
- private byte[] blockDataLKF;
-
- /**
- * Data block size (Last KeyFrame)
- */
- private int blockSizeLKF;
-
- /**
- * Number of data blocks (last key frame)
- */
- private int dataCountLKF;
-
- /**
- * Number of data blocks (Decoder Configuration Record)
- */
- private int dataCountAVCDCR;
+ /** Last keyframe found */
+ private FrameData keyframe;
+
+ /** Video decoder configuration data */
+ private FrameData decoderConfiguration;
/** Constructs a new AVCVideo. */
public AVCVideo() {
@@ -88,12 +62,8 @@ public boolean canDropFrames() {
/** {@inheritDoc} */
public void reset() {
- this.blockDataLKF = null;
- this.blockSizeLKF = 0;
- this.blockSizeAVCDCR = 0;
- this.blockDataAVCDCR = null;
- this.dataCountLKF = 0;
- this.dataCountAVCDCR = 0;
+ keyframe = new FrameData();
+ decoderConfiguration = new FrameData();
}
/** {@inheritDoc} */
@@ -102,7 +72,6 @@ public boolean canHandleData(IoBuffer data) {
// Empty buffer
return false;
}
-
byte first = data.get();
boolean result = ((first & 0x0f) == VideoCodec.AVC.getId());
data.rewind();
@@ -112,83 +81,44 @@ public boolean canHandleData(IoBuffer data) {
/** {@inheritDoc} */
public boolean addData(IoBuffer data) {
if (data.limit() > 0) {
-
//ensure that we can "handle" the data
if (!canHandleData(data)) {
return false;
}
-
+ // get frame type
byte frameType = data.get();
-
- //check for keyframe
+ // check for keyframe
if ((frameType & 0xf0) == FLV_FRAME_KEY) {
log.trace("Key frame found");
- //If we don't have the AVCDecoderConfigurationRecord stored...
- if (blockDataAVCDCR == null) {
- //data.get();//Frame Type - already read above
- data.get();//CODECID
-
- byte AVCPacketType = data.get();
-
- //Sequence Header / here comes a AVCDecoderConfigurationRecord
- log.debug("AVCPacketType: {}", AVCPacketType);
- if (AVCPacketType == 0) {
- log.trace("Decoder configuration found");
- data.rewind();
-
- // Store AVCDecoderConfigurationRecord data
- this.dataCountAVCDCR = data.limit();
-
- if (this.blockSizeAVCDCR < this.dataCountAVCDCR) {
- this.blockSizeAVCDCR = this.dataCountAVCDCR;
- this.blockDataAVCDCR = new byte[this.blockSizeAVCDCR];
- }
-
- data.get(this.blockDataAVCDCR, 0, this.dataCountAVCDCR);
- }
- }
-
- //rewind data prior to reading the keyframe
- data.rewind();
-
- // Store last keyframe
- this.dataCountLKF = data.limit();
- if (this.blockSizeLKF < this.dataCountLKF) {
- this.blockSizeLKF = this.dataCountLKF;
- this.blockDataLKF = new byte[this.blockSizeLKF];
- }
-
- data.get(this.blockDataLKF, 0, this.dataCountLKF);
+ byte AVCPacketType = data.get();
+ // rewind
+ data.rewind();
+ // sequence header / here comes a AVCDecoderConfigurationRecord
+ log.debug("AVCPacketType: {}", AVCPacketType);
+ if (AVCPacketType == 0) {
+ log.trace("Decoder configuration found");
+ // Store AVCDecoderConfigurationRecord data
+ decoderConfiguration.setData(data);
+ // rewind
+ data.rewind();
+ }
+ // store last keyframe
+ keyframe.setData(data);
}
-
- //finished with the data, rewind one last time
+ // finished with the data, rewind one last time
data.rewind();
}
-
return true;
}
/** {@inheritDoc} */
public IoBuffer getKeyframe() {
- if (this.dataCountLKF == 0) {
- return null;
- }
-
- IoBuffer result = IoBuffer.allocate(dataCountLKF);
- result.put(blockDataLKF, 0, dataCountLKF);
- result.flip();
- return result;
+ return keyframe.getFrame();
}
/** {@inheritDoc} */
public IoBuffer getDecoderConfiguration() {
- if (dataCountAVCDCR == 0) {
- return null;
- }
-
- IoBuffer result = IoBuffer.allocate(dataCountAVCDCR);
- result.put(blockDataAVCDCR, 0, dataCountAVCDCR);
- result.flip();
- return result;
+ return decoderConfiguration.getFrame();
}
+
}
Please sign in to comment.
Something went wrong with that request. Please try again.