OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.webrtc; | 11 package org.webrtc; |
12 | 12 |
13 import android.graphics.SurfaceTexture; | 13 import android.graphics.SurfaceTexture; |
14 import android.opengl.GLES11Ext; | 14 import android.opengl.GLES11Ext; |
15 import android.opengl.GLES20; | 15 import android.opengl.GLES20; |
16 import android.os.Build; | 16 import android.os.Build; |
17 import android.os.Handler; | 17 import android.os.Handler; |
18 import android.os.HandlerThread; | 18 import android.os.HandlerThread; |
19 import android.os.SystemClock; | 19 import android.os.SystemClock; |
20 import java.nio.ByteBuffer; | 20 import java.nio.ByteBuffer; |
21 import java.nio.FloatBuffer; | 21 import java.nio.FloatBuffer; |
22 import java.util.concurrent.Callable; | 22 import java.util.concurrent.Callable; |
23 import java.util.concurrent.TimeUnit; | 23 import java.util.concurrent.TimeUnit; |
24 import org.webrtc.VideoFrame.I420Buffer; | |
25 import org.webrtc.VideoFrame.TextureBuffer; | |
24 | 26 |
25 /** | 27 /** |
26 * Helper class to create and synchronize access to a SurfaceTexture. The caller will get notified | 28 * Helper class to create and synchronize access to a SurfaceTexture. The caller will get notified |
27 * of new frames in onTextureFrameAvailable(), and should call returnTextureFram e() when done with | 29 * of new frames in onTextureFrameAvailable(), and should call returnTextureFram e() when done with |
28 * the frame. Only one texture frame can be in flight at once, so returnTextureF rame() must be | 30 * the frame. Only one texture frame can be in flight at once, so returnTextureF rame() must be |
29 * called in order to receive a new frame. Call stopListening() to stop receivei ng new frames. Call | 31 * called in order to receive a new frame. Call stopListening() to stop receivei ng new frames. Call |
30 * dispose to release all resources once the texture frame is returned. | 32 * dispose to release all resources once the texture frame is returned. |
31 * Note that there is a C++ counter part of this class that optionally can be us ed. It is used for | 33 * Note that there is a C++ counter part of this class that optionally can be us ed. It is used for |
32 * wrapping texture frames into webrtc::VideoFrames and also handles calling ret urnTextureFrame() | 34 * wrapping texture frames into webrtc::VideoFrames and also handles calling ret urnTextureFrame() |
33 * when the webrtc::VideoFrame is no longer used. | 35 * when the webrtc::VideoFrame is no longer used. |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 throw new IllegalStateException("Unexpected release."); | 272 throw new IllegalStateException("Unexpected release."); |
271 } | 273 } |
272 if (yuvConverter != null) { | 274 if (yuvConverter != null) { |
273 yuvConverter.release(); | 275 yuvConverter.release(); |
274 } | 276 } |
275 GLES20.glDeleteTextures(1, new int[] {oesTextureId}, 0); | 277 GLES20.glDeleteTextures(1, new int[] {oesTextureId}, 0); |
276 surfaceTexture.release(); | 278 surfaceTexture.release(); |
277 eglBase.release(); | 279 eglBase.release(); |
278 handler.getLooper().quit(); | 280 handler.getLooper().quit(); |
279 } | 281 } |
282 | |
283 public TextureBuffer createTextureBuffer(int width, int height, float[] transf ormMatrix) { | |
sakal
2017/07/18 08:53:40
nit: Add JavaDoc for this method.
mellem
2017/07/18 16:50:03
Done.
| |
284 return new OesTextureBuffer(oesTextureId, width, height, transformMatrix, th is); | |
285 } | |
286 | |
287 /** Android OES texture buffer. */ | |
sakal
2017/07/18 08:53:40
nit: Improve the comment to explain that the objec
mellem
2017/07/18 16:50:03
Done.
| |
288 private static class OesTextureBuffer implements TextureBuffer { | |
289 private final int id; | |
290 private final int width; | |
291 private final int height; | |
292 private final float[] transformMatrix; | |
293 private final SurfaceTextureHelper helper; | |
294 private int refCount; | |
295 | |
296 OesTextureBuffer( | |
297 int id, int width, int height, float[] transformMatrix, SurfaceTextureHe lper helper) { | |
298 this.id = id; | |
299 this.width = width; | |
300 this.height = height; | |
301 this.transformMatrix = transformMatrix; | |
302 this.helper = helper; | |
303 this.refCount = 1; // Creator implicitly holds a reference. | |
304 } | |
305 | |
306 @Override | |
307 public TextureBuffer.Type getType() { | |
308 return TextureBuffer.Type.OES; | |
309 } | |
310 | |
311 @Override | |
312 public int getTextureId() { | |
313 return id; | |
314 } | |
315 | |
316 @Override | |
317 public int getWidth() { | |
318 return width; | |
319 } | |
320 | |
321 @Override | |
322 public int getHeight() { | |
323 return height; | |
324 } | |
325 | |
326 @Override | |
327 public I420Buffer toI420() { | |
328 // SurfaceTextureHelper requires a stride that is divisible by 8. Round w idth up. | |
329 // See SurfaceTextureHelper for details on the size and format. | |
330 int stride = ((width + 7) / 8) * 8; | |
331 int uvHeight = (height + 1) / 2; | |
332 // Due to the layout used by SurfaceTextureHelper, vPos + stride * uvHeigh t would overrun the | |
333 // buffer. Add one row at the bottom to compensate for this. There will never be data in the | |
334 // extra row, but now other code does not have to deal with v stride * v h eight exceeding the | |
335 // buffer's capacity. | |
336 int size = stride * (height + uvHeight + 1); | |
337 ByteBuffer buffer = ByteBuffer.allocateDirect(size); | |
338 helper.textureToYUV(buffer, width, height, stride, id, transformMatrix); | |
339 | |
340 int yPos = 0; | |
341 int uPos = yPos + stride * height; | |
342 // Rows of U and V alternate in the buffer, so V data starts after the fir st row of U. | |
343 int vPos = yPos + stride / 2; | |
344 | |
345 // SurfaceTextureHelper uses the same stride for Y, U, and V data. | |
346 return new I420BufferImpl( | |
347 buffer, width, height, yPos, stride, uPos, stride, vPos, stride, null) ; | |
348 } | |
349 | |
350 @Override | |
351 public void retain() { | |
352 ++refCount; | |
353 } | |
354 | |
355 @Override | |
356 public void release() { | |
357 if (--refCount == 0) { | |
358 helper.returnTextureFrame(); | |
359 } | |
360 } | |
361 } | |
280 } | 362 } |
OLD | NEW |