svn commit: r7044 - trunk: lib/native/freebsd lib/native/freebsd-64 lib/native/linux lib/native/linux-64 lib/native/mac lib/native/windows lib/nati...

s_vincent at dev.java.net s_vincent at dev.java.net
Tue Apr 27 09:11:18 CEST 2010


Author: s_vincent
Date: 2010-04-27 07:11:16+0000
New Revision: 7044

Added:
   trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java
Modified:
   trunk/lib/native/freebsd-64/libscreencapture.so
   trunk/lib/native/freebsd/libscreencapture.so
   trunk/lib/native/linux-64/libscreencapture.so
   trunk/lib/native/linux/libscreencapture.so
   trunk/lib/native/mac/libscreencapture.jnilib
   trunk/lib/native/windows-64/screencapture.dll
   trunk/lib/native/windows/screencapture.dll
   trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c
   trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h
   trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java
   trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java
   trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java
   trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java
   trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java
   trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java
   trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java

Log:
Passes desktop captured images to scaler/colorspace converter as native memory.

Modified: trunk/lib/native/freebsd-64/libscreencapture.so
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/freebsd-64/libscreencapture.so?view=diff&rev=7044&p1=trunk/lib/native/freebsd-64/libscreencapture.so&p2=trunk/lib/native/freebsd-64/libscreencapture.so&r1=7043&r2=7044
==============================================================================
Binary files. No diff available.

Modified: trunk/lib/native/freebsd/libscreencapture.so
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/freebsd/libscreencapture.so?view=diff&rev=7044&p1=trunk/lib/native/freebsd/libscreencapture.so&p2=trunk/lib/native/freebsd/libscreencapture.so&r1=7043&r2=7044
==============================================================================
Binary files. No diff available.

Modified: trunk/lib/native/linux-64/libscreencapture.so
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/linux-64/libscreencapture.so?view=diff&rev=7044&p1=trunk/lib/native/linux-64/libscreencapture.so&p2=trunk/lib/native/linux-64/libscreencapture.so&r1=7043&r2=7044
==============================================================================
Binary files trunk/lib/native/linux-64/libscreencapture.so	(original) and trunk/lib/native/linux-64/libscreencapture.so	2010-04-27 07:11:16+0000 differ

Modified: trunk/lib/native/linux/libscreencapture.so
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/linux/libscreencapture.so?view=diff&rev=7044&p1=trunk/lib/native/linux/libscreencapture.so&p2=trunk/lib/native/linux/libscreencapture.so&r1=7043&r2=7044
==============================================================================
Binary files trunk/lib/native/linux/libscreencapture.so	(original) and trunk/lib/native/linux/libscreencapture.so	2010-04-27 07:11:16+0000 differ

Modified: trunk/lib/native/mac/libscreencapture.jnilib
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/mac/libscreencapture.jnilib?view=diff&rev=7044&p1=trunk/lib/native/mac/libscreencapture.jnilib&p2=trunk/lib/native/mac/libscreencapture.jnilib&r1=7043&r2=7044
==============================================================================
Binary files. No diff available.

Modified: trunk/lib/native/windows-64/screencapture.dll
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/windows-64/screencapture.dll?view=diff&rev=7044&p1=trunk/lib/native/windows-64/screencapture.dll&p2=trunk/lib/native/windows-64/screencapture.dll&r1=7043&r2=7044
==============================================================================
Binary files. No diff available.

Modified: trunk/lib/native/windows/screencapture.dll
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/lib/native/windows/screencapture.dll?view=diff&rev=7044&p1=trunk/lib/native/windows/screencapture.dll&p2=trunk/lib/native/windows/screencapture.dll&r1=7043&r2=7044
==============================================================================
Binary files. No diff available.

Modified: trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c?view=diff&rev=7044&p1=trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c&p2=trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c&r1=7043&r2=7044
==============================================================================
--- trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c	(original)
+++ trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.c	2010-04-27 07:11:16+0000
@@ -462,7 +462,7 @@
 /**
  * \brief JNI native method to grab desktop screen and retrieve ARGB pixels.
  * \param env JVM environment
- * \param obj NativeScreenCapture Java class
+ * \param clazz NativeScreenCapture Java class
  * \param x x position to start capture
  * \param y y position to start capture
  * \param width capture width
@@ -470,13 +470,13 @@
  * \param output output buffer, screen bytes will be stored in
  * \return true if success, false otherwise
  */
-JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen
-  (JNIEnv* env, jclass obj, jint x, jint y, jint width, jint height, jbyteArray output)
+JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIII_3B
+  (JNIEnv* env, jclass clazz, jint x, jint y, jint width, jint height, jbyteArray output)
 {
   jint size = width * height * 4;
   jbyte* data = NULL;
 
-  obj = obj; /* not used */
+  clazz = clazz; /* not used */
 
   if(!output || (*env)->GetArrayLength(env, output) < size)
   {
@@ -506,3 +506,43 @@
   return JNI_TRUE;
 }
 
+/**
+ * \brief JNI native method to grab desktop screen and retrieve ARGB pixels.
+ * \param env JVM environment
+ * \param clazz NativeScreenCapture Java class
+ * \param x x position to start capture
+ * \param y y position to start capture
+ * \param width capture width
+ * \param height capture height
+ * \param output native output buffer
+ * \return true if success, false otherwise
+ */
+JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIIIJI
+  (JNIEnv* env, jclass clazz, jint x, jint y, jint width, jint height, jlong output, jint outputLength)
+{
+  jint size = width * height * 4;
+  jbyte* data = (jbyte*)output;
+
+  /* not used */
+  clazz = clazz;
+  env = env;
+
+  if(!data || outputLength < size)
+  {
+    return JNI_FALSE;
+  }
+
+#if defined (_WIN32) || defined(_WIN64)
+  if(windows_grab_screen(data, x, y, width, height) == -1)
+#elif defined(__APPLE__)
+    if(quartz_grab_screen(data, x, y, width, height) == -1)
+#else /* Unix */
+  if(x11_grab_screen(NULL, data, x, y, width, height) == -1)
+#endif
+  {
+    return JNI_FALSE;
+  }
+
+  return JNI_TRUE;
+}
+  

Modified: trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h?view=diff&rev=7044&p1=trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h&p2=trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h&r1=7043&r2=7044
==============================================================================
--- trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h	(original)
+++ trunk/src/native/screencapture/net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture.h	2010-04-27 07:11:16+0000
@@ -12,9 +12,17 @@
  * Method:    grabScreen
  * Signature: (IIII[B)Z
  */
-JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen
+JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIII_3B
   (JNIEnv *, jclass, jint, jint, jint, jint, jbyteArray);
 
+/*
+ * Class:     net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture
+ * Method:    grabScreen
+ * Signature: (IIIIJI)Z
+ */
+JNIEXPORT jboolean JNICALL Java_net_java_sip_communicator_impl_neomedia_imgstreaming_NativeScreenCapture_grabScreen__IIIIJI
+  (JNIEnv *, jclass, jint, jint, jint, jint, jlong, jint);
+
 #ifdef __cplusplus
 }
 #endif

Added: trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java?view=auto&rev=7044
==============================================================================
--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/ByteBuffer.java	2010-04-27 07:11:16+0000
@@ -0,0 +1,116 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.neomedia.codec.video;
+
+/**
+ * Represents a buffer of native memory with a specific size/capacity which
+ * either contains a specific number of bytes of valid data or is free for
+ * consumption.
+ *
+ * @author Lubomir Marinov
+ */
+public class ByteBuffer
+{
+
+    /**
+     * The maximum number of bytes which can be written into the native
+     * memory represented by this instance.
+     */
+    public final int capacity;
+
+    /**
+     * The indicator which determines whether this instance is free to be
+     * written bytes into.
+     */
+    private boolean free;
+
+    /**
+     * The number of bytes of valid data that the native memory represented
+     * by this instance contains.
+     */
+    private int length;
+
+    /**
+     * The pointer to the native memory represented by this instance.
+     */
+    public final long ptr;
+
+    /**
+     * Initializes a new <tt>ByteBuffer</tt> instance with a specific
+     * <tt>capacity</tt>.
+     *
+     * @param capacity the maximum number of bytes which can be written into
+     * the native memory represented by the new instance
+     */
+    public ByteBuffer(int capacity)
+    {
+        this.capacity = capacity;
+        this.ptr = FFmpeg.av_malloc(this.capacity);
+
+        this.free = true;
+        this.length = 0;
+
+        if (this.ptr == 0)
+        {
+            throw
+                new OutOfMemoryError(
+                        getClass().getSimpleName()
+                            + " with capacity "
+                            + this.capacity);
+        }
+    }
+
+    /**
+     * Gets the number of bytes of valid data that the native memory
+     * represented by this instance contains.
+     *
+     * @return the number of bytes of valid data that the native memory
+     * represented by this instance contains
+     */
+    public int getLength()
+    {
+        return length;
+    }
+
+    /**
+     * Determines whether this instance is free to be written bytes into.
+     *
+     * @return <tt>true</tt> if this instance is free to be written bytes
+     * into or <tt>false</tt> is the native memory represented by this
+     * instance is already is use
+     */
+    public boolean isFree()
+    {
+        return free;
+    }
+
+    /**
+     * Sets the indicator which determines whether this instance is free to
+     * be written bytes into.
+     *
+     * @param free <tt>true</tt> if this instance is to be made available
+     * for writing bytes into; otherwise, <tt>false</tt>
+     */
+    public void setFree(boolean free)
+    {
+        this.free = free;
+        if (this.free)
+            setLength(0);
+    }
+
+    /**
+     * Sets the number of bytes of valid data that the native memory
+     * represented by this instance contains.
+     *
+     * @param length the number of bytes of valid data that the native
+     * memory represented by this instance contains
+     */
+    public void setLength(int length)
+    {
+        this.length = length;
+    }
+}
\ No newline at end of file

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/codec/video/SwScaler.java	2010-04-27 07:11:16+0000
@@ -58,6 +58,9 @@
         new RGBFormat(null, -1, Format.shortArray, -1.0f, 24, -1, -1, -1),
     };
 
+    /**
+     * Libswscale context pointer.
+     */
     private long swsContext = 0;
 
     /**

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteract.java	2010-04-27 07:11:16+0000
@@ -11,7 +11,7 @@
 /**
  * Interface to interact with the desktop such as taking
  * screen capture or to generate mouse/keyboard event.
- * 
+ *
  * @author Sebastien Vincent
  */
 public interface DesktopInteract
@@ -23,7 +23,8 @@
      * and not <tt>BufferedImage</tt>. It is done in order to limit
      * slow operation such as converting ARGB images (uint32_t) to bytes
      * especially for big big screen. For example a 1920x1200 desktop consumes
-     * 9 MB of memory for grabbing and another 9 MB array for convertion operation.
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
      *
      * @param output output buffer to store bytes in.
      * Be sure that output length is sufficient
@@ -32,13 +33,31 @@
     public boolean captureScreen(byte output[]);
 
     /**
+     * Capture the full desktop screen using native grabber.
+     *
+     * Contrary to other captureScreen method, it only returns raw bytes
+     * and not <tt>BufferedImage</tt>. It is done in order to limit
+     * slow operation such as converting ARGB images (uint32_t) to bytes
+     * especially for big big screen. For example a 1920x1200 desktop consumes
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
+     *
+     * @param buffer native output buffer to store bytes in.
+     * Be sure that output length is sufficient
+     * @param bufferLength length of native buffer
+     * @return true if success, false if JNI error or output length too short
+     */
+    public boolean captureScreen(long buffer, int bufferLength);
+
+    /**
      * Capture a part of the desktop screen using native grabber.
      *
      * Contrary to other captureScreen method, it only returns raw bytes
      * and not <tt>BufferedImage</tt>. It is done in order to limit
      * slow operation such as converting ARGB images (uint32_t) to bytes
      * especially for big big screen. For example a 1920x1200 desktop consumes
-     * 9 MB of memory for grabbing and another 9 MB array for convertion operation.
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
      *
      * @param x x position to start capture
      * @param y y position to start capture
@@ -48,7 +67,30 @@
      * Be sure that output length is sufficient
      * @return true if success, false if JNI error or output length too short
      */
-    public boolean captureScreen(int x, int y, int width, int height, byte output[]);
+    public boolean captureScreen(int x, int y, int width, int height,
+            byte output[]);
+
+    /**
+     * Capture a part of the desktop screen using native grabber.
+     *
+     * Contrary to other captureScreen method, it only returns raw bytes
+     * and not <tt>BufferedImage</tt>. It is done in order to limit
+     * slow operation such as converting ARGB images (uint32_t) to bytes
+     * especially for big big screen. For example a 1920x1200 desktop consumes
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
+     *
+     * @param x x position to start capture
+     * @param y y position to start capture
+     * @param width capture width
+     * @param height capture height
+     * @param buffer native output buffer to store bytes in.
+     * Be sure that output length is sufficient
+     * @param bufferLength length of native buffer
+     * @return true if success, false if JNI error or output length too short
+     */
+    public boolean captureScreen(int x, int y, int width, int height,
+            long buffer, int bufferLength);
 
     /**
      * Capture the full desktop screen.

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/DesktopInteractImpl.java	2010-04-27 07:11:16+0000
@@ -12,19 +12,20 @@
 import net.java.sip.communicator.util.*;
 
 /**
- * This singleton class provide screen capture and key/mouse 
+ * This singleton class provide screen capture and key/mouse
  * events generation by wrapping partial or all <tt>java.awt.Robot</tt>
  * methods to interact with desktop.
  *
  * @see java.awt.Robot
  * @author Sebastien Vincent
  */
-public class DesktopInteractImpl implements DesktopInteract 
+public class DesktopInteractImpl implements DesktopInteract
 {
     /**
      * The <tt>Logger</tt>.
      */
-    private static final Logger logger = Logger.getLogger(DesktopInteractImpl.class);
+    private static final Logger logger =
+        Logger.getLogger(DesktopInteractImpl.class);
 
     /**
      * Screen capture robot.
@@ -33,11 +34,12 @@
 
     /**
      * Constructor.
-     * 
-     * @throws AWTException if platform configuration does not allow low-level input control
+     *
+     * @throws AWTException if platform configuration does not allow low-level
+     * input control
      * @throws SecurityException if Robot creation is not permitted
      */
-    public DesktopInteractImpl() throws AWTException, SecurityException 
+    public DesktopInteractImpl() throws AWTException, SecurityException
     {
         robot = new Robot();
     }
@@ -49,7 +51,8 @@
      * and not <tt>BufferedImage</tt>. It is done in order to limit
      * slow operation such as converting ARGB images (uint32_t) to bytes
      * especially for big big screen. For example a 1920x1200 desktop consumes
-     * 9 MB of memory for grabbing and another 9 MB array for convertion operation.
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
      *
      * @param output output buffer to store bytes in.
      * Be sure that output length is sufficient
@@ -59,7 +62,29 @@
     {
         Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
 
-        return captureScreen(0, 0, (int)dim.getWidth(), (int)dim.getHeight(), output);
+        return captureScreen(0, 0, dim.width, dim.height,
+                output);
+    }
+
+    /**
+     * Capture the full desktop screen using native grabber.
+     *
+     * Contrary to other captureScreen method, it only returns raw bytes
+     * and not <tt>BufferedImage</tt>. It is done in order to limit
+     * slow operation such as converting ARGB images (uint32_t) to bytes
+     * especially for big big screen. For example a 1920x1200 desktop consumes
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
+     *
+     * @param buffer native output buffer to store bytes in.
+     * Be sure that output length is sufficient
+     * @param bufferLength length of native buffer
+     * @return true if success, false if JNI error or output length too short
+     */
+    public boolean captureScreen(long buffer, int bufferLength)
+    {
+        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
+        return captureScreen(0, 0, dim.width, dim.height, buffer, bufferLength);
     }
 
     /**
@@ -67,9 +92,10 @@
      *
      * Contrary to other captureScreen method, it only returns raw bytes
      * and not <tt>BufferedImage</tt>. It is done in order to limit
-     * slow operation such as converting ARGB images (uint32_t) to bytes 
+     * slow operation such as converting ARGB images (uint32_t) to bytes
      * especially for big big screen. For example a 1920x1200 desktop consumes
-     * 9 MB of memory for grabbing and another 9 MB array for convertion operation.
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
      *
      * @param x x position to start capture
      * @param y y position to start capture
@@ -79,7 +105,8 @@
      * Be sure that output length is sufficient
      * @return true if success, false if JNI error or output length too short
      */
-    public boolean captureScreen(int x, int y, int width, int height, byte output[])
+    public boolean captureScreen(int x, int y, int width, int height,
+            byte output[])
     {
         if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS
                 || OSUtils.IS_MAC)
@@ -92,6 +119,38 @@
     }
 
     /**
+     * Capture a part of the desktop screen using native grabber.
+     *
+     * Contrary to other captureScreen method, it only returns raw bytes
+     * and not <tt>BufferedImage</tt>. It is done in order to limit
+     * slow operation such as converting ARGB images (uint32_t) to bytes
+     * especially for big big screen. For example a 1920x1200 desktop consumes
+     * 9 MB of memory for grabbing and another 9 MB array for conversion
+     * operation.
+     *
+     * @param x x position to start capture
+     * @param y y position to start capture
+     * @param width capture width
+     * @param height capture height
+     * @param buffer native output buffer to store bytes in.
+     * Be sure that output length is sufficient
+     * @param bufferLength length of native buffer
+     * @return true if success, false if JNI error or output length too short
+     */
+    public boolean captureScreen(int x, int y, int width, int height,
+            long buffer, int bufferLength)
+    {
+        if(OSUtils.IS_LINUX || OSUtils.IS_FREEBSD || OSUtils.IS_WINDOWS
+                || OSUtils.IS_MAC)
+        {
+            return NativeScreenCapture.grabScreen(
+                        x, y, width, height, buffer, bufferLength);
+        }
+
+        return false;
+    }
+
+    /**
      * Capture the full desktop screen using <tt>java.awt.Robot</tt>.
      *
      * @return <tt>BufferedImage</tt> of the desktop screen
@@ -100,7 +159,7 @@
     {
         Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
 
-        return captureScreen(0, 0, (int)dim.getWidth(), (int)dim.getHeight());
+        return captureScreen(0, 0, dim.width, dim.height);
     }
 
     /**
@@ -117,7 +176,7 @@
     {
         BufferedImage img = null;
         Rectangle rect = null;
-           
+
         if(robot == null)
         {
             /* Robot has not been created so abort */
@@ -128,7 +187,7 @@
         rect = new Rectangle(x, y, width, height);
         img = robot.createScreenCapture(rect);
         logger.info("End capture: " + System.nanoTime());
-        
+
         return img;
     }
 

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/imgstreaming/NativeScreenCapture.java	2010-04-27 07:11:16+0000
@@ -6,12 +6,10 @@
  */
 package net.java.sip.communicator.impl.neomedia.imgstreaming;
 
-import java.awt.image.*;
-
 /**
  * This class uses native code to capture desktop screen.
- * 
- * It should work for Windows, Mac OS X and X11-based Unix such as Linux 
+ *
+ * It should work for Windows, Mac OS X and X11-based Unix such as Linux
  * and FreeBSD.
  *
  * @author Sebastien Vincent
@@ -25,7 +23,7 @@
 
     /**
      * Grab desktop screen and get raw bytes.
-     * 
+     *
      * @param x x position to start capture
      * @param y y position to start capture
      * @param width capture width
@@ -33,5 +31,20 @@
      * @param output output buffer to store screen bytes
      * @return true if grab success, false otherwise
      */
-    public static native boolean grabScreen(int x, int y, int width, int height, byte output[]);
+    public static native boolean grabScreen(int x, int y, int width, int height,
+            byte output[]);
+
+    /**
+     * Grab desktop screen and get raw bytes.
+     *
+     * @param x x position to start capture
+     * @param y y position to start capture
+     * @param width capture width
+     * @param height capture height
+     * @param output native output buffer to store screen bytes
+     * @param outputLength native output length
+     * @return true if grab success, false otherwise
+     */
+    public static native boolean grabScreen(int x, int y, int width, int height,
+            long output, int outputLength);
 }

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java	2010-04-27 07:11:16+0000
@@ -12,10 +12,11 @@
 import javax.media.control.*;
 import javax.media.format.*;
 
+import net.java.sip.communicator.impl.neomedia.codec.video.*;
 import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*;
 
 /**
- * DataSource for our image streaming (which is used for 
+ * DataSource for our image streaming (which is used for
  * Desktop streaming).
  *
  * @author Sebastien Vincent
@@ -32,7 +33,11 @@
     private static final Format[] formats
         = new Format[]
                 {
-                    new RGBFormat(
+                    new AVFrameFormat(
+                            Toolkit.getDefaultToolkit().getScreenSize(),
+                            Format.NOT_SPECIFIED,
+                            FFmpeg.PIX_FMT_ARGB),
+                     new RGBFormat(
                             Toolkit.getDefaultToolkit().getScreenSize(), // size
                             Format.NOT_SPECIFIED, // maxDataLength
                             Format.byteArray, // dataType

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java	2010-04-27 07:11:16+0000
@@ -14,14 +14,13 @@
 import javax.media.control.*;
 import javax.media.format.*;
 
+import net.java.sip.communicator.impl.neomedia.codec.video.*;
 import net.java.sip.communicator.impl.neomedia.imgstreaming.*;
 import net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.*;
 import net.java.sip.communicator.util.*;
 
 /**
  * The stream used by JMF for our image streaming.
- * 
- * This class launches a thread to handle desktop capture interactions.
  *
  * @author Sebastien Vincent
  * @author Lubomir Marinov
@@ -46,6 +45,11 @@
     private DesktopInteract desktopInteract = null;
 
     /**
+     * Native buffer pointer.
+     */
+    ByteBuffer data = null;
+
+    /**
      * Initializes a new <tt>ImageStream</tt> instance which is to have a
      * specific <tt>FormatControl</tt>
      *
@@ -67,41 +71,80 @@
         throws IOException
     {
         //System.out.println(System.currentTimeMillis());
-        byte data[] = (byte[])buffer.getData();
-        int dataLength = (data != null) ? data.length : 0;
         long begin = System.currentTimeMillis();
         /* maximum time allowed for a capture to respect frame rate */
-        long maxTime = 1000 / 10; 
+        long maxTime = 1000 / 10;
         int wait = 0;
 
-        if((data != null) || (dataLength != 0))
+        if(buffer.getFormat() instanceof AVFrameFormat)
         {
-            byte buf[] = readScreen(data);
+            /* native transfert: we keep data in native memory rather
+             * than Java Heap until we reach SwScaler
+             */
+            Object dataAv = buffer.getData();
+            AVFrame bufferFrame = null;
+            long bufferFramePtr = 0;
 
-            if(buf != data)
+            if (dataAv instanceof AVFrame)
             {
-                /* readScreen returns us a different buffer than JMF ones,
-                 * it means that JMF's initial buffer was too short.
-                 */
-                //System.out.println("use our own buffer");
-                buffer.setData(buf);
+                bufferFrame = (AVFrame)dataAv;
+                bufferFramePtr = bufferFrame.getPtr();
+            }
+            else
+            {
+                bufferFrame = new FinalizableAVFrame();
+                bufferFramePtr = bufferFrame.getPtr();
             }
 
-            buffer.setOffset(0);
-            buffer.setLength(buf.length);
-            buffer.setFormat(getFormat());
-            buffer.setHeader(null);
-            buffer.setTimeStamp(System.nanoTime());
-            buffer.setSequenceNumber(seqNo);
-            buffer.setFlags(Buffer.FLAG_SYSTEM_TIME | Buffer.FLAG_LIVE_DATA);
-            seqNo++;
+            AVFrameFormat bufferFrameFormat = (AVFrameFormat)buffer.getFormat();
+            Dimension bufferFrameSize = bufferFrameFormat.getSize();
+
+            if(readScreenNative(bufferFrameSize))
+            {
+                FFmpeg.avpicture_fill(
+                        bufferFramePtr,
+                        data.ptr,
+                        bufferFrameFormat.getPixFmt(),
+                        bufferFrameSize.width, bufferFrameSize.height);
+            }
+
+            buffer.setData(bufferFrame);
+        }
+        else
+        {
+            byte dataByte[] = (byte[])buffer.getData();
+            int dataLength = (dataByte != null) ? dataByte.length : 0;
+
+            if((dataByte != null) || (dataLength != 0))
+            {
+                byte buf[] = readScreen(dataByte);
+
+                if(buf != dataByte)
+                {
+                    /* readScreen returns us a different buffer than JMF ones,
+                     * it means that JMF's initial buffer was too short.
+                     */
+                    //System.out.println("use our own buffer");
+                    buffer.setData(buf);
+                }
+
+                buffer.setOffset(0);
+                buffer.setLength(buf.length);
+            }
         }
-        
+
+        buffer.setFormat(buffer.getFormat());
+        buffer.setHeader(null);
+        buffer.setTimeStamp(System.nanoTime());
+        buffer.setSequenceNumber(seqNo);
+        buffer.setFlags(Buffer.FLAG_SYSTEM_TIME | Buffer.FLAG_LIVE_DATA);
+        seqNo++;
+
         wait = (int)(maxTime - (System.currentTimeMillis() - begin));
 
         try
         {
-            /* sleep to respect as much as possible the 
+            /* sleep to respect as much as possible the
              * frame rate
              */
             if(wait > 0)
@@ -110,7 +153,7 @@
             }
             else
             {
-                /* yield a little bit to not use all the 
+                /* yield a little bit to not use all the
                  * CPU
                  */
                 Thread.yield();
@@ -151,14 +194,54 @@
     public void stop()
     {
         logger.info("Stop stream");
+
+        /* native pointer is freed in FinalizableAVFrame */
+        data = null;
+    }
+
+    /**
+     * Read screen and store result in native buffer.
+     *
+     * @param dim dimension of the video
+     * @return true if success, false otherwise
+     */
+    private boolean readScreenNative(Dimension dim)
+    {
+        int size = dim.width * dim.height * 4;
+
+        /* pad the buffer */
+        size += FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE;
+
+        /* allocate native array */
+        if(data == null)
+        {
+            data = new ByteBuffer(size);
+            data.setLength(size);
+        }
+
+        /* reallocate native array if capacity is not enough */
+        if(data.getLength() < size)
+        {
+            data.setFree(true);
+            FFmpeg.av_free(data.ptr);
+            data = new ByteBuffer(size);
+            data.setLength(size);
+        }
+
+        /* get desktop screen via native grabber */
+        if(desktopInteract.captureScreen(data.ptr, data.getLength()))
+        {
+            return true;
+        }
+        return false;
     }
 
     /**
      * Read screen.
-     * 
+     *
      * @param output output buffer for screen bytes
-     * @return raw bytes, it could be equal to output or not. Take care in the caller 
-     * to check if output is the returned value.
+     * @return raw bytes, it could be equal to output or not. Take care in the
+     * caller to check if output is the returned value.
      */
     public byte[] readScreen(byte output[])
     {
@@ -194,8 +277,8 @@
          * Note that it is very memory consuming since memory are allocated
          * to capture screen (via Robot) and then for converting to raw bytes
          *
-         * Normally not of our supported platform (Windows (x86, x64), 
-         * Linux (x86, x86-64), Mac OS X (i386, x86-64, ppc) and 
+         * Normally not of our supported platform (Windows (x86, x64),
+         * Linux (x86, x86-64), Mac OS X (i386, x86-64, ppc) and
          * FreeBSD (x86, x86-64) should go here.
          */
         screen = desktopInteract.captureScreen();
@@ -203,7 +286,7 @@
         if(screen != null)
         {
             /* convert to ARGB BufferedImage */
-            scaledScreen 
+            scaledScreen
                 = ImageStreamingUtils
                     .getScaledImage(
                         screen,
@@ -219,4 +302,61 @@
         scaledScreen = null;
         return data;
     }
+
+    /**
+     * Represents an <tt>AVFrame</tt> used by this instance to provide captured
+     * media data in native format without representing the very frame data in
+     * the Java heap. Since this instance cannot know when the <tt>AVFrame</tt>
+     * instances are really safe for deallocation, <tt>FinalizableAVFrame</tt>
+     * relies on the Java finalization mechanism to reclaim the represented
+     * native memory.
+     */
+    public class FinalizableAVFrame
+        extends AVFrame
+    {
+
+        /**
+         * The indicator which determines whether the native memory represented
+         * by this instance has already been freed/deallocated.
+         */
+        private boolean freed = false;
+
+        /**
+         * Initializes a new <tt>FinalizableAVFrame</tt> instance which is to
+         * allocate a new native FFmpeg <tt>AVFrame</tt> and represent it.
+         */
+        public FinalizableAVFrame()
+        {
+            super(FFmpeg.avcodec_alloc_frame());
+        }
+
+        /**
+         * Deallocates the native memory represented by this instance.
+         *
+         * @see Object#finalize()
+         */
+        @Override
+        protected void finalize()
+            throws Throwable
+        {
+            try
+            {
+                if (!freed)
+                {
+                    long ptr = getPtr();
+                    long bufferPtr = FFmpeg.avpicture_get_data0(ptr);
+
+                    if(bufferPtr != 0)
+                        FFmpeg.av_free(bufferPtr);
+
+                    FFmpeg.av_free(ptr);
+                    freed = true;
+                }
+            }
+            finally
+            {
+                super.finalize();
+            }
+        }
+    }
 }

Modified: trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java?view=diff&rev=7044&p1=trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java&p2=trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java&r1=7043&r2=7044
==============================================================================
--- trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java	(original)
+++ trunk/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/quicktime/QuickTimeStream.java	2010-04-27 07:11:16+0000
@@ -694,7 +694,7 @@
                     nextData = null;
                 }
             }
-            
+
             synchronized (dataSyncRoot)
             {
                 if (data == null)
@@ -880,118 +880,11 @@
     }
 
     /**
-     * Represents a buffer of native memory with a specific size/capacity which
-     * either contains a specific number of bytes of valid data or is free for
-     * consumption.
-     */
-    private static class ByteBuffer
-    {
-
-        /**
-         * The maximum number of bytes which can be written into the native
-         * memory represented by this instance.
-         */
-        public final int capacity;
-
-        /**
-         * The indicator which determines whether this instance is free to be
-         * written bytes into.
-         */
-        private boolean free;
-
-        /**
-         * The number of bytes of valid data that the native memory represented
-         * by this instance contains.
-         */
-        private int length;
-
-        /**
-         * The pointer to the native memory represented by this instance.
-         */
-        public final long ptr;
-
-        /**
-         * Initializes a new <tt>ByteBuffer</tt> instance with a specific
-         * <tt>capacity</tt>.
-         *
-         * @param capacity the maximum number of bytes which can be written into
-         * the native memory represented by the new instance
-         */
-        public ByteBuffer(int capacity)
-        {
-            this.capacity = capacity;
-            this.ptr = FFmpeg.av_malloc(this.capacity);
-
-            this.free = true;
-            this.length = 0;
-
-            if (this.ptr == 0)
-            {
-                throw
-                    new OutOfMemoryError(
-                            getClass().getSimpleName()
-                                + " with capacity "
-                                + this.capacity);
-            }
-        }
-
-        /**
-         * Gets the number of bytes of valid data that the native memory
-         * represented by this instance contains.
-         *
-         * @return the number of bytes of valid data that the native memory
-         * represented by this instance contains
-         */
-        public int getLength()
-        {
-            return length;
-        }
-
-        /**
-         * Determines whether this instance is free to be written bytes into.
-         *
-         * @return <tt>true</tt> if this instance is free to be written bytes
-         * into or <tt>false</tt> is the native memory represented by this
-         * instance is already is use
-         */
-        public boolean isFree()
-        {
-            return free;
-        }
-
-        /**
-         * Sets the indicator which determines whether this instance is free to
-         * be written bytes into.
-         *
-         * @param free <tt>true</tt> if this instance is to be made available
-         * for writing bytes into; otherwise, <tt>false</tt>
-         */
-        public void setFree(boolean free)
-        {
-            this.free = free;
-            if (this.free)
-                setLength(0);
-        }
-
-        /**
-         * Sets the number of bytes of valid data that the native memory
-         * represented by this instance contains.
-         *
-         * @param length the number of bytes of valid data that the native
-         * memory represented by this instance contains
-         */
-        public void setLength(int length)
-        {
-            this.length = length;
-        }
-    }
-
-    /**
      * Represents an <tt>AVFrame</tt> used by this instance to provide captured
      * media data in native format without representing the very frame data in
      * the Java heap. Since this instance cannot know when the <tt>AVFrame</tt>
      * instances are really safe for deallocation, <tt>FinalizableAVFrame</tt>
-     * relies on the Java finialization mechanism to reclaim the represented
+     * relies on the Java finalization mechanism to reclaim the represented
      * native memory.
      */
     private class FinalizableAVFrame

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe at sip-communicator.dev.java.net
For additional commands, e-mail: commits-help at sip-communicator.dev.java.net





More information about the commits mailing list