diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java
index 6bd2ee3e5..9c547bae6 100644
--- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java
+++ b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/DePacketizer.java
@@ -515,6 +515,21 @@ private void padOutput(byte[] out, int outOffset)
Arrays.fill(out, outOffset, outOffset + outputPaddingSize, (byte) 0);
}
+ /**
+ * Requests a key frame from the remote peer associated with this
+ * DePacketizer using the logic of DePacketizer.
+ *
+ * @return true if a key frame was indeed requested in response to
+ * the call; otherwise, false
+ * @deprecated The method and its callers are part of a quick workaround to
+ * expose the logic of DePacketizer to JNIDecoder.
+ */
+ public boolean requestKeyFrame()
+ {
+ setRequestKeyFrame(true);
+ return true;
+ }
+
/**
* Resets the states of this DePacketizer and a specific output
* Buffer so that they are ready to have this DePacketizer
diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java
index 2d37b2409..ea00a908a 100644
--- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java
+++ b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIDecoder.java
@@ -13,6 +13,7 @@
import net.java.sip.communicator.impl.neomedia.codec.*;
import net.java.sip.communicator.impl.neomedia.codec.video.*;
+import net.java.sip.communicator.service.neomedia.control.*;
import net.sf.fmj.media.*;
/**
@@ -58,6 +59,12 @@ public class JNIDecoder
*/
private int height;
+ /**
+ * The KeyFrameControl used by this JNIDecoder to
+ * control its key frame-related logic.
+ */
+ private KeyFrameControl keyFrameControl;
+
/**
* Array of output VideoFormats.
*/
@@ -281,6 +288,12 @@ public synchronized int process(Buffer inBuffer, Buffer outBuffer)
if (!got_picture[0])
{
+ if ((inBuffer.getFlags() & Buffer.FLAG_RTP_MARKER) != 0)
+ {
+ if (keyFrameControl != null)
+ keyFrameControl.requestKeyFrame();
+ }
+
outBuffer.setDiscard(true);
return BUFFER_PROCESSED_OK;
}
@@ -354,4 +367,18 @@ public Format setInputFormat(Format format)
reset();
return setFormat;
}
+
+ /**
+ * Sets the KeyFrameControl to be used by this
+ * DePacketizer as a means of control over its key frame-related
+ * logic.
+ *
+ * @param keyFrameControl the KeyFrameControl to be used by this
+ * DePacketizer as a means of control over its key frame-related
+ * logic
+ */
+ public void setKeyFrameControl(KeyFrameControl keyFrameControl)
+ {
+ this.keyFrameControl = keyFrameControl;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java
index 8d459a1bc..f8f1a6e97 100644
--- a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java
+++ b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java
@@ -23,6 +23,7 @@
import net.java.sip.communicator.impl.neomedia.format.*;
import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.service.neomedia.*;
+import net.java.sip.communicator.service.neomedia.control.*;
import net.java.sip.communicator.service.neomedia.control.KeyFrameControl; // disambiguation
import net.java.sip.communicator.service.neomedia.event.*;
import net.java.sip.communicator.service.neomedia.format.*;
@@ -828,13 +829,31 @@ protected void playerConfigureComplete(final Processor player)
if ("h264/rtp".equalsIgnoreCase(
getFormat().getJMFEncoding()))
{
- DePacketizer depacketizer = new DePacketizer();
+ final DePacketizer depacketizer = new DePacketizer();
+ JNIDecoder decoder = new JNIDecoder();
if (keyFrameControl != null)
+ {
depacketizer.setKeyFrameControl(keyFrameControl);
+ decoder.setKeyFrameControl(
+ new KeyFrameControlAdapter()
+ {
+ @Override
+ public boolean requestKeyFrame()
+ {
+ return
+ depacketizer.requestKeyFrame();
+ }
+ });
+ }
trackControl.setCodecChain(
- new Codec[] { depacketizer, playerScaler });
+ new Codec[]
+ {
+ depacketizer,
+ decoder,
+ playerScaler
+ });
}
else
{
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
index 8cf375458..aae8ec349 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
@@ -355,7 +355,6 @@ boolean processPictureFastUpdate(
Request request)
throws OperationFailedException
{
- System.err.println("processPictureFastUpdate Request");
CallPeerMediaHandlerSipImpl mediaHandler = getMediaHandler();
boolean requested
= (mediaHandler == null)
diff --git a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java b/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java
index 65554e812..499a37e54 100644
--- a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java
+++ b/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControl.java
@@ -100,6 +100,16 @@ public void addKeyFrameRequester(
*/
public boolean removeKeyFrameRequester(KeyFrameRequester keyFrameRequester);
+ /**
+ * Requests a key frame from the remote peer of the associated
+ * VideoMediaStream.
+ *
+ * @return true if a key frame was indeed requested from the remote
+ * peer of the associated VideoMediaStream in response to the call;
+ * otherwise, false
+ */
+ public boolean requestKeyFrame();
+
/**
* Represents a way for the remote peer of a VideoMediaStream to
* request a key frame from its local peer.
diff --git a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java b/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java
index 50449aadf..1517389bf 100644
--- a/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java
+++ b/src/net/java/sip/communicator/service/neomedia/control/KeyFrameControlAdapter.java
@@ -248,4 +248,29 @@ public boolean removeKeyFrameRequester(KeyFrameRequester keyFrameRequester)
return false;
}
}
+
+ /**
+ * Implements {@link KeyFrameControl#requestKeyFrame()}.
+ *
+ * {@inheritDoc}
+ */
+ public boolean requestKeyFrame()
+ {
+ for (KeyFrameRequester keyFrameRequester : getKeyFrameRequesters())
+ {
+ try
+ {
+ if (keyFrameRequester.requestKeyFrame())
+ return true;
+ }
+ catch (Exception e)
+ {
+ /*
+ * A KeyFrameRequestee has malfunctioned, do not let it
+ * interfere with the others.
+ */
+ }
+ }
+ return false;
+ }
}