Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java

Issue 24072012: Hold video frame in Bitmap instead of keeping a ByteBuffer reference. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Allow FrameConsumer to operate directly on Bitmap pixels Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting.jni; 5 package org.chromium.chromoting.jni;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.app.AlertDialog; 8 import android.app.AlertDialog;
9 import android.app.ProgressDialog; 9 import android.app.ProgressDialog;
10 import android.content.Context; 10 import android.content.Context;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 103
104 /** Severs the connection and cleans up. */ 104 /** Severs the connection and cleans up. */
105 public static void disconnectFromHost() { 105 public static void disconnectFromHost() {
106 synchronized(JniInterface.class) { 106 synchronized(JniInterface.class) {
107 if (!sLoaded || !sConnected) return; 107 if (!sLoaded || !sConnected) return;
108 108
109 if (sProgressIndicator != null) { 109 if (sProgressIndicator != null) {
110 sProgressIndicator.dismiss(); 110 sProgressIndicator.dismiss();
111 sProgressIndicator = null; 111 sProgressIndicator = null;
112 } 112 }
113
114 // Drop the reference to free the Bitmap for GC.
115 sFrameBitmap = null;
113 } 116 }
114 117
115 disconnectNative(); 118 disconnectNative();
116 sSuccessCallback = null; 119 sSuccessCallback = null;
117 sConnected = false; 120 sConnected = false;
118 } 121 }
119 122
120 /** Performs the native portion of the connection. */ 123 /** Performs the native portion of the connection. */
121 private static native void connectNative(String username, String authToken, String hostJid, 124 private static native void connectNative(String username, String authToken, String hostJid,
122 String hostId, String hostPubkey, String pairId, String pairSecret); 125 String hostId, String hostPubkey, String pairId, String pairSecret);
123 126
124 /** Performs the native portion of the cleanup. */ 127 /** Performs the native portion of the cleanup. */
125 private static native void disconnectNative(); 128 private static native void disconnectNative();
126 129
127 /** Position of cursor hotspot within cursor image. */ 130 /** Position of cursor hotspot within cursor image. */
128 public static Point getCursorHotspot() { return sCursorHotspot; } 131 public static Point getCursorHotspot() { return sCursorHotspot; }
129 132
130 /** Returns the current cursor shape. */ 133 /** Returns the current cursor shape. */
131 public static Bitmap getCursorBitmap() { return sCursorBitmap; } 134 public static Bitmap getCursorBitmap() { return sCursorBitmap; }
132 135
133 /* 136 /*
134 * Entry points *from* the native code. 137 * Entry points *from* the native code.
135 */ 138 */
136 /** Callback to signal whenever we need to redraw. */ 139 /** Callback to signal whenever we need to redraw. */
137 private static Runnable sRedrawCallback = null; 140 private static Runnable sRedrawCallback = null;
138 141
139 /** Screen width of the video feed. */ 142 /** Bitmap holding a copy of the latest video frame. */
140 private static int sWidth = 0; 143 private static Bitmap sFrameBitmap = null;
141
142 /** Screen height of the video feed. */
143 private static int sHeight = 0;
144
145 /** Bitmap holding the latest screen image. */
146 private static Bitmap sBitmap = null;
147
148 /** Buffer holding the video feed. */
149 private static ByteBuffer sBuffer = null;
150 144
151 /** Position of cursor hot-spot. */ 145 /** Position of cursor hot-spot. */
152 private static Point sCursorHotspot = new Point(); 146 private static Point sCursorHotspot = new Point();
153 147
154 /** Bitmap holding the cursor shape. */ 148 /** Bitmap holding the cursor shape. */
155 private static Bitmap sCursorBitmap = null; 149 private static Bitmap sCursorBitmap = null;
156 150
157 /** Reports whenever the connection status changes. */ 151 /** Reports whenever the connection status changes. */
158 private static void reportConnectionStatus(int state, int error) { 152 private static void reportConnectionStatus(int state, int error) {
159 if (state < SUCCESSFUL_CONNECTION && error == 0) { 153 if (state < SUCCESSFUL_CONNECTION && error == 0) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 return true; 288 return true;
295 } 289 }
296 290
297 /** Performs the redrawing callback. This is a no-op if the window isn't vis ible. */ 291 /** Performs the redrawing callback. This is a no-op if the window isn't vis ible. */
298 private static void redrawGraphicsInternal() { 292 private static void redrawGraphicsInternal() {
299 if (sRedrawCallback != null) 293 if (sRedrawCallback != null)
300 sRedrawCallback.run(); 294 sRedrawCallback.run();
301 } 295 }
302 296
303 /** 297 /**
304 * Obtains the image buffer. 298 * Returns a bitmap of the latest video frame. Called on the native graphics thread when
305 * This should not be called from the UI thread. (We prefer the native graph ics thread.) 299 * DesktopView is repainted.
306 */ 300 */
307 public static Bitmap retrieveVideoFrame() { 301 public static Bitmap getVideoFrame() {
308 if (Looper.myLooper() == Looper.getMainLooper()) { 302 if (Looper.myLooper() == Looper.getMainLooper()) {
309 Log.w("jniiface", "Canvas being redrawn on UI thread"); 303 Log.w("jniiface", "Canvas being redrawn on UI thread");
310 } 304 }
311 305
312 if (!sConnected) { 306 if (!sConnected) {
313 return null; 307 return null;
314 } 308 }
315 309
316 // This is synchronized only to silence a findbugs warning about incorre ct initialization of 310 return sFrameBitmap;
317 // |sBitmap|.
318 // TODO(lambroslambrou): Annotate this class as @NotThreadSafe to preven t similar warnings
319 // in future.
320 synchronized (JniInterface.class) {
321 if (sBitmap == null || sBitmap.getWidth() != sWidth || sBitmap.getHe ight() != sHeight) {
322 sBitmap = Bitmap.createBitmap(sWidth, sHeight, Bitmap.Config.ARG B_8888);
323 }
324 }
325
326 sBuffer.rewind();
327 sBitmap.copyPixelsFromBuffer(sBuffer);
328 return sBitmap;
329 } 311 }
330 312
331 /** 313 /**
314 * Sets a new video frame. Called from native code on the native graphics th read when a new
315 * frame is allocated.
316 */
317 private static void setVideoFrame(Bitmap bitmap) {
318 if (Looper.myLooper() == Looper.getMainLooper()) {
319 Log.w("jniiface", "Video frame updated on UI thread");
320 }
321
322 synchronized (JniInterface.class) {
Yaron 2013/10/09 06:42:30 I believe this will trigger a findbugs error. We d
Lambros 2013/10/10 01:35:58 There are already lots of these in this file. I've
323 sFrameBitmap = bitmap;
324 }
325 }
326
327 /**
328 * Creates a new Bitmap to hold video frame pixels. Called by native code wh ich stores a global
329 * reference to the Bitmap and writes the decoded frame pixels to it.
330 */
331 private static Bitmap newBitmap(int width, int height) {
332 return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
333 }
334
335 /**
332 * Updates the cursor shape. This is called from native code on the graphics thread when 336 * Updates the cursor shape. This is called from native code on the graphics thread when
333 * receiving a new cursor shape from the host. 337 * receiving a new cursor shape from the host.
334 */ 338 */
335 public static void updateCursorShape(int width, int height, int hotspotX, in t hotspotY, 339 public static void updateCursorShape(int width, int height, int hotspotX, in t hotspotY,
336 ByteBuffer buffer) { 340 ByteBuffer buffer) {
337 sCursorHotspot = new Point(hotspotX, hotspotY); 341 sCursorHotspot = new Point(hotspotX, hotspotY);
338 342
339 int[] data = new int[width * height]; 343 int[] data = new int[width * height];
340 buffer.order(ByteOrder.LITTLE_ENDIAN); 344 buffer.order(ByteOrder.LITTLE_ENDIAN);
341 buffer.asIntBuffer().get(data, 0, data.length); 345 buffer.asIntBuffer().get(data, 0, data.length);
(...skipping 23 matching lines...) Expand all
365 369
366 /** Schedules a redraw on the native graphics thread. */ 370 /** Schedules a redraw on the native graphics thread. */
367 private static native void scheduleRedrawNative(); 371 private static native void scheduleRedrawNative();
368 372
369 /** Passes mouse information to the native handling code. */ 373 /** Passes mouse information to the native handling code. */
370 private static native void mouseActionNative(int x, int y, int whichButton, boolean buttonDown); 374 private static native void mouseActionNative(int x, int y, int whichButton, boolean buttonDown);
371 375
372 /** Passes key press information to the native handling code. */ 376 /** Passes key press information to the native handling code. */
373 private static native void keyboardActionNative(int keyCode, boolean keyDown ); 377 private static native void keyboardActionNative(int keyCode, boolean keyDown );
374 } 378 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698