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

Side by Side Diff: talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java

Issue 1313563002: Java VideoRenderer.Callbacks: Make renderFrame() interface asynchronous (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase Created 5 years, 3 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 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2013 Google Inc. 3 * Copyright 2013 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 24 matching lines...) Expand all
35 * class also provides a createGui() method for creating a GUI-rendering window 35 * class also provides a createGui() method for creating a GUI-rendering window
36 * on various platforms. 36 * on various platforms.
37 */ 37 */
38 public class VideoRenderer { 38 public class VideoRenderer {
39 39
40 /** Java version of cricket::VideoFrame. */ 40 /** Java version of cricket::VideoFrame. */
41 public static class I420Frame { 41 public static class I420Frame {
42 public final int width; 42 public final int width;
43 public final int height; 43 public final int height;
44 public final int[] yuvStrides; 44 public final int[] yuvStrides;
45 public final ByteBuffer[] yuvPlanes; 45 public ByteBuffer[] yuvPlanes;
46 public final boolean yuvFrame; 46 public final boolean yuvFrame;
47 public Object textureObject; 47 public Object textureObject;
48 public int textureId; 48 public int textureId;
49 // If |nativeFramePointer| is non-zero, the memory is allocated on the C++ s ide.
50 private long nativeFramePointer;
49 51
50 // rotationDegree is the degree that the frame must be rotated clockwisely 52 // rotationDegree is the degree that the frame must be rotated clockwisely
51 // to be rendered correctly. 53 // to be rendered correctly.
52 public int rotationDegree; 54 public int rotationDegree;
53 55
54 /** 56 /**
55 * Construct a frame of the given dimensions with the specified planar 57 * Construct a frame of the given dimensions with the specified planar
56 * data. If |yuvPlanes| is null, new planes of the appropriate sizes are 58 * data. If |yuvPlanes| is null, new planes of the appropriate sizes are
57 * allocated. 59 * allocated.
58 */ 60 */
59 public I420Frame( 61 public I420Frame(
60 int width, int height, int rotationDegree, 62 int width, int height, int rotationDegree,
61 int[] yuvStrides, ByteBuffer[] yuvPlanes) { 63 int[] yuvStrides, ByteBuffer[] yuvPlanes, long nativeFramePointer) {
62 this.width = width; 64 this.width = width;
63 this.height = height; 65 this.height = height;
64 this.yuvStrides = yuvStrides; 66 this.yuvStrides = yuvStrides;
65 if (yuvPlanes == null) { 67 if (yuvPlanes == null) {
66 yuvPlanes = new ByteBuffer[3]; 68 yuvPlanes = new ByteBuffer[3];
67 yuvPlanes[0] = ByteBuffer.allocateDirect(yuvStrides[0] * height); 69 yuvPlanes[0] = ByteBuffer.allocateDirect(yuvStrides[0] * height);
68 yuvPlanes[1] = ByteBuffer.allocateDirect(yuvStrides[1] * height / 2); 70 yuvPlanes[1] = ByteBuffer.allocateDirect(yuvStrides[1] * height / 2);
69 yuvPlanes[2] = ByteBuffer.allocateDirect(yuvStrides[2] * height / 2); 71 yuvPlanes[2] = ByteBuffer.allocateDirect(yuvStrides[2] * height / 2);
70 } 72 }
71 this.yuvPlanes = yuvPlanes; 73 this.yuvPlanes = yuvPlanes;
72 this.yuvFrame = true; 74 this.yuvFrame = true;
73 this.rotationDegree = rotationDegree; 75 this.rotationDegree = rotationDegree;
76 this.nativeFramePointer = nativeFramePointer;
74 if (rotationDegree % 90 != 0) { 77 if (rotationDegree % 90 != 0) {
75 throw new IllegalArgumentException("Rotation degree not multiple of 90: " + rotationDegree); 78 throw new IllegalArgumentException("Rotation degree not multiple of 90: " + rotationDegree);
76 } 79 }
77 } 80 }
78 81
79 /** 82 /**
80 * Construct a texture frame of the given dimensions with data in SurfaceTex ture 83 * Construct a texture frame of the given dimensions with data in SurfaceTex ture
81 */ 84 */
82 public I420Frame( 85 public I420Frame(
83 int width, int height, int rotationDegree, 86 int width, int height, int rotationDegree,
84 Object textureObject, int textureId) { 87 Object textureObject, int textureId, long nativeFramePointer) {
85 this.width = width; 88 this.width = width;
86 this.height = height; 89 this.height = height;
87 this.yuvStrides = null; 90 this.yuvStrides = null;
88 this.yuvPlanes = null; 91 this.yuvPlanes = null;
89 this.textureObject = textureObject; 92 this.textureObject = textureObject;
90 this.textureId = textureId; 93 this.textureId = textureId;
91 this.yuvFrame = false; 94 this.yuvFrame = false;
92 this.rotationDegree = rotationDegree; 95 this.rotationDegree = rotationDegree;
96 this.nativeFramePointer = nativeFramePointer;
93 if (rotationDegree % 90 != 0) { 97 if (rotationDegree % 90 != 0) {
94 throw new IllegalArgumentException("Rotation degree not multiple of 90: " + rotationDegree); 98 throw new IllegalArgumentException("Rotation degree not multiple of 90: " + rotationDegree);
95 } 99 }
96 } 100 }
97 101
98 public int rotatedWidth() { 102 public int rotatedWidth() {
99 return (rotationDegree % 180 == 0) ? width : height; 103 return (rotationDegree % 180 == 0) ? width : height;
100 } 104 }
101 105
102 public int rotatedHeight() { 106 public int rotatedHeight() {
103 return (rotationDegree % 180 == 0) ? height : width; 107 return (rotationDegree % 180 == 0) ? height : width;
104 } 108 }
105 109
106 /** 110 /**
107 * Copy the planes out of |source| into |this| and return |this|. Calling 111 * Copy the planes out of |source| into |this| and return |this|. Calling
108 * this with mismatched frame dimensions or frame type is a programming 112 * this with mismatched frame dimensions or frame type is a programming
109 * error and will likely crash. 113 * error and will likely crash.
110 */ 114 */
111 public I420Frame copyFrom(I420Frame source) { 115 public I420Frame copyFrom(I420Frame source) {
116 // |nativeFramePointer| is not copied from |source|, because resources in this object are
117 // still allocated in Java. After copyFrom() is done, this object should n ot hold any
118 // references to |source|. This is violated for texture frames however, be cause |textureId|
119 // is copied without making a deep copy.
120 if (this.nativeFramePointer != 0) {
121 throw new RuntimeException("Trying to overwrite a frame allocated in C++ ");
122 }
112 if (source.yuvFrame && yuvFrame) { 123 if (source.yuvFrame && yuvFrame) {
113 if (width != source.width || height != source.height) { 124 if (width != source.width || height != source.height) {
114 throw new RuntimeException("Mismatched dimensions! Source: " + 125 throw new RuntimeException("Mismatched dimensions! Source: " +
115 source.toString() + ", destination: " + toString()); 126 source.toString() + ", destination: " + toString());
116 } 127 }
117 nativeCopyPlane(source.yuvPlanes[0], width, height, 128 nativeCopyPlane(source.yuvPlanes[0], width, height,
118 source.yuvStrides[0], yuvPlanes[0], yuvStrides[0]); 129 source.yuvStrides[0], yuvPlanes[0], yuvStrides[0]);
119 nativeCopyPlane(source.yuvPlanes[1], width / 2, height / 2, 130 nativeCopyPlane(source.yuvPlanes[1], width / 2, height / 2,
120 source.yuvStrides[1], yuvPlanes[1], yuvStrides[1]); 131 source.yuvStrides[1], yuvPlanes[1], yuvStrides[1]);
121 nativeCopyPlane(source.yuvPlanes[2], width / 2, height / 2, 132 nativeCopyPlane(source.yuvPlanes[2], width / 2, height / 2,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 174 }
164 } 175 }
165 176
166 // Helper native function to do a video frame plane copying. 177 // Helper native function to do a video frame plane copying.
167 private static native void nativeCopyPlane(ByteBuffer src, int width, 178 private static native void nativeCopyPlane(ByteBuffer src, int width,
168 int height, int srcStride, ByteBuffer dst, int dstStride); 179 int height, int srcStride, ByteBuffer dst, int dstStride);
169 180
170 /** The real meat of VideoRendererInterface. */ 181 /** The real meat of VideoRendererInterface. */
171 public static interface Callbacks { 182 public static interface Callbacks {
172 // |frame| might have pending rotation and implementation of Callbacks 183 // |frame| might have pending rotation and implementation of Callbacks
173 // should handle that by applying rotation during rendering. 184 // should handle that by applying rotation during rendering. The callee
185 // is responsible for signaling when it is done with |frame| by calling
186 // renderFrameDone(frame).
174 public void renderFrame(I420Frame frame); 187 public void renderFrame(I420Frame frame);
175 } 188 }
176 189
190 /**
191 * This must be called after every renderFrame() to release the frame.
192 */
193 public static void renderFrameDone(I420Frame frame) {
194 frame.yuvPlanes = null;
195 frame.textureObject = null;
196 frame.textureId = 0;
197 if (frame.nativeFramePointer != 0) {
198 releaseNativeFrame(frame.nativeFramePointer);
199 frame.nativeFramePointer = 0;
200 }
201 }
202
177 // |this| either wraps a native (GUI) renderer or a client-supplied Callbacks 203 // |this| either wraps a native (GUI) renderer or a client-supplied Callbacks
178 // (Java) implementation; this is indicated by |isWrappedVideoRenderer|. 204 // (Java) implementation; this is indicated by |isWrappedVideoRenderer|.
179 long nativeVideoRenderer; 205 long nativeVideoRenderer;
180 private final boolean isWrappedVideoRenderer; 206 private final boolean isWrappedVideoRenderer;
181 207
182 public static VideoRenderer createGui(int x, int y) { 208 public static VideoRenderer createGui(int x, int y) {
183 long nativeVideoRenderer = nativeCreateGuiVideoRenderer(x, y); 209 long nativeVideoRenderer = nativeCreateGuiVideoRenderer(x, y);
184 if (nativeVideoRenderer == 0) { 210 if (nativeVideoRenderer == 0) {
185 return null; 211 return null;
186 } 212 }
(...skipping 21 matching lines...) Expand all
208 freeWrappedVideoRenderer(nativeVideoRenderer); 234 freeWrappedVideoRenderer(nativeVideoRenderer);
209 } 235 }
210 nativeVideoRenderer = 0; 236 nativeVideoRenderer = 0;
211 } 237 }
212 238
213 private static native long nativeCreateGuiVideoRenderer(int x, int y); 239 private static native long nativeCreateGuiVideoRenderer(int x, int y);
214 private static native long nativeWrapVideoRenderer(Callbacks callbacks); 240 private static native long nativeWrapVideoRenderer(Callbacks callbacks);
215 241
216 private static native void freeGuiVideoRenderer(long nativeVideoRenderer); 242 private static native void freeGuiVideoRenderer(long nativeVideoRenderer);
217 private static native void freeWrappedVideoRenderer(long nativeVideoRenderer); 243 private static native void freeWrappedVideoRenderer(long nativeVideoRenderer);
244
245 private static native void releaseNativeFrame(long nativeFramePointer);
218 } 246 }
OLDNEW
« no previous file with comments | « talk/app/webrtc/java/jni/peerconnection_jni.cc ('k') | talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698