Attempts to fix the QTKit CaptureDevice on Mac OS X Leopard which does not seem to report the size of the video it is going to output.

cusax-fix
Lyubomir Marinov 16 years ago
parent 9878ff0b4f
commit 0adae885e5

@ -15,6 +15,22 @@ extern "C" {
JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer_getBytes
(JNIEnv *, jclass, jlong);
/*
* Class: net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer
* Method: getHeight
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer_getHeight
(JNIEnv *, jclass, jlong);
/*
* Class: net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer
* Method: getWidth
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer_getWidth
(JNIEnv *, jclass, jlong);
#ifdef __cplusplus
}
#endif

@ -29,3 +29,17 @@ Java_net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer_getBytes
}
return bytes;
}
JNIEXPORT jint JNICALL
Java_net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer_getHeight
(JNIEnv *jniEnv, jclass clazz, jlong ptr)
{
return (jint) CVPixelBufferGetHeight((CVPixelBufferRef) ptr);
}
JNIEXPORT jint JNICALL
Java_net_java_sip_communicator_impl_neomedia_quicktime_CVPixelBuffer_getWidth
(JNIEnv *jniEnv, jclass clazz, jlong ptr)
{
return (jint) CVPixelBufferGetWidth((CVPixelBufferRef) ptr);
}

@ -37,6 +37,13 @@ public class QuickTimeStream
*/
private byte[] data;
/**
* The <tt>Format</tt> of {@link #data} if known. If possible, determined by
* the <tt>CVPixelBuffer</tt> video frame from which <tt>data</tt> is
* acquired.
*/
private Format dataFormat;
/**
* The <tt>Object</tt> which synchronizes the access to the
* {@link #data}-related fields of this instance.
@ -121,13 +128,17 @@ private void captureOutputDidOutputVideoFrameWithSampleBuffer(
CVImageBuffer videoFrame,
QTSampleBuffer sampleBuffer)
{
CVPixelBuffer pixelBuffer = (CVPixelBuffer) videoFrame;
boolean transferData;
synchronized (dataSyncRoot)
{
data = ((CVPixelBuffer) videoFrame).getBytes();
data = pixelBuffer.getBytes();
dataTimeStamp = System.nanoTime();
transferData = (data != null);
if (dataFormat == null)
dataFormat = getVideoFrameFormat(pixelBuffer);
}
if (transferData)
@ -167,9 +178,34 @@ public void close()
@Override
protected Format doGetFormat()
{
if (format == null)
Format format;
if (this.format == null)
{
format = getCaptureOutputFormat();
return (format == null) ? super.doGetFormat() : format;
if (format == null)
format = super.doGetFormat();
else
{
VideoFormat videoFormat = (VideoFormat) format;
if (videoFormat.getSize() != null)
this.format = format;
else
format
= videoFormat
.intersects(
new VideoFormat(
null,
new Dimension(640, 480),
Format.NOT_SPECIFIED,
Format.byteArray,
Format.NOT_SPECIFIED));
}
}
else
format = this.format;
return format;
}
/**
@ -202,7 +238,9 @@ private Format getCaptureOutputFormat()
return
new RGBFormat(
new Dimension(width, height),
((width == 0) && (height == 0)
? null
: new Dimension(width, height)),
Format.NOT_SPECIFIED,
Format.byteArray,
Format.NOT_SPECIFIED,
@ -214,6 +252,38 @@ private Format getCaptureOutputFormat()
return null;
}
/**
* Gets the <tt>Format</tt> of the media data made available by this
* <tt>PushBufferStream</tt> as indicated by a specific
* <tt>CVPixelBuffer</tt>.
*
* @param videoFrame the <tt>CVPixelBuffer</tt> which provides details about
* the <tt>Format</tt> of the media data made available by this
* <tt>PushBufferStream</tt>
* @return the <tt>Format</tt> of the media data made available by this
* <tt>PushBufferStream</tt> as indicated by the specified
* <tt>CVPixelBuffer</tt>
*/
private Format getVideoFrameFormat(CVPixelBuffer videoFrame)
{
Format format = getFormat();
Dimension size = ((VideoFormat) format).getSize();
if ((size == null) || ((size.width == 0) && (size.height == 0)))
format
= format
.intersects(
new VideoFormat(
null,
new Dimension(
videoFrame.getWidth(),
videoFrame.getHeight()),
Format.NOT_SPECIFIED,
Format.byteArray,
Format.NOT_SPECIFIED));
return format;
}
/**
* Reads media data from this <tt>PushBufferStream</tt> into a specific
* <tt>Buffer</tt> without blocking.
@ -235,6 +305,8 @@ public void read(Buffer buffer)
buffer.setData(data);
buffer
.setFlags(Buffer.FLAG_LIVE_DATA | Buffer.FLAG_SYSTEM_TIME);
if (dataFormat != null)
buffer.setFormat(dataFormat);
buffer.setLength(data.length);
buffer.setOffset(0);
buffer.setTimeStamp(dataTimeStamp);
@ -255,6 +327,15 @@ private void setCaptureOutputFormat(Format format)
{
VideoFormat videoFormat = (VideoFormat) format;
Dimension size = videoFormat.getSize();
/*
* FIXME Mac OS X Leopard does not seem to report the size of the
* QTCaptureDevice in its formatDescriptions early in its creation.
* The workaround presented here is to just force a specific size.
*/
if (size == null)
size = new Dimension(640, 480);
NSMutableDictionary pixelBufferAttributes = null;
if (size != null)
@ -300,6 +381,7 @@ public void stop()
synchronized (dataSyncRoot)
{
data = null;
dataFormat = null;
}
}
}

@ -48,4 +48,46 @@ public byte[] getBytes()
* specified CoreVideo <tt>CVPixelBufferRef</tt>
*/
private static native byte[] getBytes(long ptr);
/**
* Gets the height in pixels of this <tt>CVPixelBuffer</tt>.
*
* @return the height in pixels of this <tt>CVPixelBuffer</tt>
*/
public int getHeight()
{
return getHeight(getPtr());
}
/**
* Gets the height in pixels of a specific CoreVideo
* <tt>CVPixelBufferRef</tt>.
*
* @param ptr the CoreVideo <tt>CVPixelBufferRef</tt> to get the height in
* pixels of
* @return the height in pixels of the specified CoreVideo
* <tt>CVPixelBufferRef</tt>
*/
private static native int getHeight(long ptr);
/**
* Gets the width in pixels of this <tt>CVPixelBuffer</tt>.
*
* @return the width in pixels of this <tt>CVPixelBuffer</tt>
*/
public int getWidth()
{
return getWidth(getPtr());
}
/**
* Gets the width in pixels of a specific CoreVideo
* <tt>CVPixelBufferRef</tt>.
*
* @param ptr the CoreVideo <tt>CVPixelBufferRef</tt> to get the width in
* pixels of
* @return the width in pixels of the specified CoreVideo
* <tt>CVPixelBufferRef</tt>
*/
private static native int getWidth(long ptr);
}

Loading…
Cancel
Save