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

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 and rerun tests 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;
AlexG 2015/08/26 23:27:25 why not to keep final?
magjed_webrtc 2015/08/27 15:52:20 I set it to null in renderFrameDone() to make sure
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() {
(...skipping 10 matching lines...) Expand all
113 if (width != source.width || height != source.height) { 117 if (width != source.width || height != source.height) {
114 throw new RuntimeException("Mismatched dimensions! Source: " + 118 throw new RuntimeException("Mismatched dimensions! Source: " +
115 source.toString() + ", destination: " + toString()); 119 source.toString() + ", destination: " + toString());
116 } 120 }
117 nativeCopyPlane(source.yuvPlanes[0], width, height, 121 nativeCopyPlane(source.yuvPlanes[0], width, height,
118 source.yuvStrides[0], yuvPlanes[0], yuvStrides[0]); 122 source.yuvStrides[0], yuvPlanes[0], yuvStrides[0]);
119 nativeCopyPlane(source.yuvPlanes[1], width / 2, height / 2, 123 nativeCopyPlane(source.yuvPlanes[1], width / 2, height / 2,
120 source.yuvStrides[1], yuvPlanes[1], yuvStrides[1]); 124 source.yuvStrides[1], yuvPlanes[1], yuvStrides[1]);
121 nativeCopyPlane(source.yuvPlanes[2], width / 2, height / 2, 125 nativeCopyPlane(source.yuvPlanes[2], width / 2, height / 2,
122 source.yuvStrides[2], yuvPlanes[2], yuvStrides[2]); 126 source.yuvStrides[2], yuvPlanes[2], yuvStrides[2]);
123 rotationDegree = source.rotationDegree; 127 rotationDegree = source.rotationDegree;
AlexG 2015/08/26 23:27:25 Add a comment why nativeFramePointer is not copied
magjed_webrtc 2015/08/27 15:52:20 Done.
124 return this; 128 return this;
125 } else if (!source.yuvFrame && !yuvFrame) { 129 } else if (!source.yuvFrame && !yuvFrame) {
126 textureObject = source.textureObject; 130 textureObject = source.textureObject;
127 textureId = source.textureId; 131 textureId = source.textureId;
128 rotationDegree = source.rotationDegree; 132 rotationDegree = source.rotationDegree;
129 return this; 133 return this;
130 } else { 134 } else {
131 throw new RuntimeException("Mismatched frame types! Source: " + 135 throw new RuntimeException("Mismatched frame types! Source: " +
132 source.toString() + ", destination: " + toString()); 136 source.toString() + ", destination: " + toString());
133 } 137 }
(...skipping 29 matching lines...) Expand all
163 } 167 }
164 } 168 }
165 169
166 // Helper native function to do a video frame plane copying. 170 // Helper native function to do a video frame plane copying.
167 private static native void nativeCopyPlane(ByteBuffer src, int width, 171 private static native void nativeCopyPlane(ByteBuffer src, int width,
168 int height, int srcStride, ByteBuffer dst, int dstStride); 172 int height, int srcStride, ByteBuffer dst, int dstStride);
169 173
170 /** The real meat of VideoRendererInterface. */ 174 /** The real meat of VideoRendererInterface. */
171 public static interface Callbacks { 175 public static interface Callbacks {
172 // |frame| might have pending rotation and implementation of Callbacks 176 // |frame| might have pending rotation and implementation of Callbacks
173 // should handle that by applying rotation during rendering. 177 // should handle that by applying rotation during rendering. The callee
178 // is responsible for signaling when it is done with |frame| by calling
179 // renderFrameDone(frame).
174 public void renderFrame(I420Frame frame); 180 public void renderFrame(I420Frame frame);
175 } 181 }
176 182
183 /**
184 * This must be called after every renderFrame() to release the frame.
185 */
186 public static void renderFrameDone(I420Frame frame) {
187 frame.yuvPlanes = null;
188 frame.textureObject = null;
189 frame.textureId = 0;
190 if (frame.nativeFramePointer != 0) {
191 releaseNativeFrame(frame.nativeFramePointer);
192 frame.nativeFramePointer = 0;
193 }
194 }
195
177 // |this| either wraps a native (GUI) renderer or a client-supplied Callbacks 196 // |this| either wraps a native (GUI) renderer or a client-supplied Callbacks
178 // (Java) implementation; this is indicated by |isWrappedVideoRenderer|. 197 // (Java) implementation; this is indicated by |isWrappedVideoRenderer|.
179 long nativeVideoRenderer; 198 long nativeVideoRenderer;
180 private final boolean isWrappedVideoRenderer; 199 private final boolean isWrappedVideoRenderer;
181 200
182 public static VideoRenderer createGui(int x, int y) { 201 public static VideoRenderer createGui(int x, int y) {
183 long nativeVideoRenderer = nativeCreateGuiVideoRenderer(x, y); 202 long nativeVideoRenderer = nativeCreateGuiVideoRenderer(x, y);
184 if (nativeVideoRenderer == 0) { 203 if (nativeVideoRenderer == 0) {
185 return null; 204 return null;
186 } 205 }
(...skipping 21 matching lines...) Expand all
208 freeWrappedVideoRenderer(nativeVideoRenderer); 227 freeWrappedVideoRenderer(nativeVideoRenderer);
209 } 228 }
210 nativeVideoRenderer = 0; 229 nativeVideoRenderer = 0;
211 } 230 }
212 231
213 private static native long nativeCreateGuiVideoRenderer(int x, int y); 232 private static native long nativeCreateGuiVideoRenderer(int x, int y);
214 private static native long nativeWrapVideoRenderer(Callbacks callbacks); 233 private static native long nativeWrapVideoRenderer(Callbacks callbacks);
215 234
216 private static native void freeGuiVideoRenderer(long nativeVideoRenderer); 235 private static native void freeGuiVideoRenderer(long nativeVideoRenderer);
217 private static native void freeWrappedVideoRenderer(long nativeVideoRenderer); 236 private static native void freeWrappedVideoRenderer(long nativeVideoRenderer);
237
238 private static native void releaseNativeFrame(long nativeFramePointer);
218 } 239 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698