diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java index 9b462d88f..30e4395fe 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DataSource.java @@ -16,6 +16,7 @@ import net.java.sip.communicator.impl.neomedia.codec.*; import net.java.sip.communicator.impl.neomedia.codec.video.*; +import net.java.sip.communicator.impl.neomedia.control.*; import net.java.sip.communicator.impl.neomedia.device.*; import net.java.sip.communicator.impl.neomedia.directshow.*; import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*; @@ -174,6 +175,43 @@ private void setDevice(DSCaptureDevice device) } } + /** + * Creates a new FrameRateControl instance which is to allow the + * getting and setting of the frame rate of this + * AbstractVideoPushBufferCaptureDevice. + * + * @return a new FrameRateControl instance which is to allow the + * getting and setting of the frame rate of this + * AbstractVideoPushBufferCaptureDevice + * @see AbstractPushBufferCaptureDevice#createFrameRateControl() + */ + @Override + protected FrameRateControl createFrameRateControl() + { + return + new FrameRateControlAdapter() + { + /** + * The output frame rate of this + * AbstractVideoPullBufferCaptureDevice. + */ + private float frameRate = -1; + + @Override + public float getFrameRate() + { + return frameRate; + } + + @Override + public float setFrameRate(float frameRate) + { + this.frameRate = frameRate; + return this.frameRate; + } + }; + } + /** * Create a new PushBufferStream which is to be at a specific * zero-based index in the list of streams of this diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java index f475d30f7..ab5f54bbf 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/directshow/DirectShowStream.java @@ -223,15 +223,68 @@ public void close() private void runInTransferDataThread() { boolean transferData = false; + FrameRateControl frameRateControl + = (FrameRateControl) + dataSource.getControl(FrameRateControl.class.getName()); + long transferDataTimeStamp = -1; - while(Thread.currentThread().equals(transferDataThread)) + while (Thread.currentThread().equals(transferDataThread)) { - if(transferData) + if (transferData) { BufferTransferHandler transferHandler = this.transferHandler; - if(transferHandler != null) + if (transferHandler != null) + { + /* + * Respect the frame rate specified through the + * FrameRateControl of the associated DataSource. + */ + if (frameRateControl != null) + { + float frameRate; + long newTransferDataTimeStamp + = System.currentTimeMillis(); + + if ((transferDataTimeStamp != -1) + && ((frameRate + = frameRateControl.getFrameRate()) + > 0)) + { + long minimumVideoFrameInterval + = (long) (1000 / frameRate); + + if (minimumVideoFrameInterval > 0) + { + long t + = newTransferDataTimeStamp + - transferDataTimeStamp; + + if ((t > 0) && (t < minimumVideoFrameInterval)) + { + boolean interrupted = false; + + try + { + Thread.sleep( + minimumVideoFrameInterval - t); + } + catch (InterruptedException ie) + { + interrupted = true; + } + if (interrupted) + Thread.currentThread().interrupt(); + continue; + } + } + } + + transferDataTimeStamp = newTransferDataTimeStamp; + } + transferHandler.transferData(this); + } synchronized (dataSyncRoot) { @@ -249,13 +302,13 @@ private void runInTransferDataThread() synchronized (dataSyncRoot) { - if(data == null) + if (data == null) { data = nextData; dataTimeStamp = nextDataTimeStamp; nextData = null; } - if(data == null) + if (data == null) { boolean interrupted = false; @@ -298,7 +351,6 @@ public void run() runInTransferDataThread(); } }; - transferDataThread.start(); } }