From 2f8ea6094cf3ed91c167896fa75f319472e47d05 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Fri, 22 Jan 2010 15:40:30 +0000 Subject: [PATCH] Enables local video display for the QTKit CaptureDevice on Mac OS X. --- .../neomedia/codec/video/ImageScaler.java | 3 +- .../device/VideoMediaDeviceSession.java | 2 +- .../AbstractPushBufferCaptureDevice.java | 42 ++++++++-------- .../media/protocol/quicktime/DataSource.java | 48 +++++++++++++++---- .../protocol/quicktime/QuickTimeStream.java | 2 +- 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java index b54b91196..88e265c80 100644 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java +++ b/src/net/java/sip/communicator/impl/neomedia/codec/video/ImageScaler.java @@ -161,8 +161,7 @@ public int process(Buffer input, Buffer output) final Dimension outputSize = ((VideoFormat) outputFormat).getSize(); /* rescale by preserving ratio */ final BufferedImage scaled = scalePreserveRatio(image, outputSize.width, outputSize.height); // TODO: is the size exact? what about rounding errors? - -// System.out.println("scaled: " + scaled.getWidth() + "x" + scaled.getHeight()); + final Buffer b = ImageToBuffer.createBuffer(scaled, ((VideoFormat) outputFormat).getFrameRate()); output.setData(b.getData()); output.setLength(b.getLength()); 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 dce1b46c5..f4ad18aad 100644 --- a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java +++ b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java @@ -135,7 +135,7 @@ protected DataSource createCaptureDevice() * FIXME There is no video in calls when using the QuickTime/QTKit * CaptureDevice so the local video support is disabled for it. */ - if (!QuickTimeAuto.LOCATOR_PROTOCOL.equals(protocol)) +// if (!QuickTimeAuto.LOCATOR_PROTOCOL.equals(protocol)) { DataSource cloneableDataSource = Manager.createCloneableDataSource(captureDevice); diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java index fff1a9201..0c630adf4 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/AbstractPushBufferCaptureDevice.java @@ -77,8 +77,12 @@ public abstract class AbstractPushBufferCaptureDevice /** * The PushBufferStreams through which this * PushBufferDataSource gives access to its media data. + *

+ * Warning: Caution is advised when directly using the field and access to + * it is to be synchronized with sync root this. + *

*/ - private AbstractPushBufferStream[] streams; + protected AbstractPushBufferStream[] streams; /** * Initializes a new AbstractPushBufferCaptureDevice instance. @@ -288,24 +292,24 @@ protected synchronized void doConnect() */ protected synchronized void doDisconnect() { - if (streams != null) - try - { - for (AbstractPushBufferStream stream : streams) - stream.close(); - } - finally - { - /* - * While it is not clear whether the streams can be released - * upon disconnect, - * com.imb.media.protocol.SuperCloneableDataSource gets the - * streams of the DataSource it adapts (i.e. this DataSource - * when SourceCloneable support support is to be created for it) - * before #connect(). - */ - // streams = null; - } + /* + * While it is not clear whether the streams can be released upon + * disconnect, com.imb.media.protocol.SuperCloneableDataSource gets the + * streams of the DataSource it adapts (i.e. this DataSource when + * SourceCloneable support is to be created for it) before #connect(). + * Unfortunately, it means that it isn't clear when the streams are to + * be disposed. + */ +// if (streams != null) +// try +// { +// for (AbstractPushBufferStream stream : streams) +// stream.close(); +// } +// finally +// { +// streams = null; +// } } /** diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java index c32e17eda..accb7327b 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/DataSource.java @@ -109,15 +109,16 @@ protected AbstractPushBufferStream createStream( { QuickTimeStream stream = new QuickTimeStream(formatControl); - try - { - captureSession.addOutput(stream.captureOutput); - } - catch (NSErrorException nseex) - { - logger.error("Failed to addOutput to QTCaptureSession", nseex); - throw new UndeclaredThrowableException(nseex); - } + if (captureSession != null) + try + { + captureSession.addOutput(stream.captureOutput); + } + catch (NSErrorException nseex) + { + logger.error("Failed to addOutput to QTCaptureSession", nseex); + throw new UndeclaredThrowableException(nseex); + } return stream; } @@ -167,6 +168,35 @@ protected void doConnect() ioex.initCause(nseex); throw ioex; } + + /* + * Add the QTCaptureOutputs represented by the QuickTimeStreams (if any) + * to the QTCaptureSession. + */ + synchronized (this) + { + if (streams != null) + for (AbstractPushBufferStream stream : streams) + if (stream != null) + try + { + captureSession + .addOutput( + ((QuickTimeStream) stream).captureOutput); + } + catch (NSErrorException nseex) + { + logger + .error( + "Failed to addOutput to QTCaptureSession", + nseex); + + IOException ioex = new IOException(); + + ioex.initCause(nseex); + throw ioex; + } + } } /** diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java index 6a2b99341..5f45a2b86 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java @@ -355,7 +355,7 @@ private void setCaptureOutputFormat(Format format) { VideoFormat videoFormat = (VideoFormat) format; Dimension size = videoFormat.getSize(); -System.err.println(format); + /* * FIXME Mac OS X Leopard does not seem to report the size of the * QTCaptureDevice in its formatDescriptions early in its creation.