OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 EGLContext sharedContext) { | 352 EGLContext sharedContext) { |
353 Logging.d(TAG, "VideoCapturerAndroid"); | 353 Logging.d(TAG, "VideoCapturerAndroid"); |
354 this.id = cameraId; | 354 this.id = cameraId; |
355 this.eventsHandler = eventsHandler; | 355 this.eventsHandler = eventsHandler; |
356 cameraThread = new HandlerThread(TAG); | 356 cameraThread = new HandlerThread(TAG); |
357 cameraThread.start(); | 357 cameraThread.start(); |
358 cameraThreadHandler = new Handler(cameraThread.getLooper()); | 358 cameraThreadHandler = new Handler(cameraThread.getLooper()); |
359 videoBuffers = new FramePool(cameraThread); | 359 videoBuffers = new FramePool(cameraThread); |
360 isCapturingToTexture = (sharedContext != null); | 360 isCapturingToTexture = (sharedContext != null); |
361 cameraStatistics = | 361 cameraStatistics = |
362 new CameraStatistics(isCapturingToTexture ? 1 : videoBuffers.numCaptureB
uffers); | 362 new CameraStatistics(isCapturingToTexture ? 1 : FramePool.NUMBER_OF_CAPT
URE_BUFFERS); |
363 surfaceHelper = SurfaceTextureHelper.create( | 363 surfaceHelper = SurfaceTextureHelper.create( |
364 isCapturingToTexture ? sharedContext : EGL10.EGL_NO_CONTEXT, cameraThrea
dHandler); | 364 isCapturingToTexture ? sharedContext : EGL10.EGL_NO_CONTEXT, cameraThrea
dHandler); |
365 if (isCapturingToTexture) { | 365 if (isCapturingToTexture) { |
366 surfaceHelper.setListener(this); | 366 surfaceHelper.setListener(this); |
367 } | 367 } |
368 } | 368 } |
369 | 369 |
370 private void checkIsOnCameraThread() { | 370 private void checkIsOnCameraThread() { |
371 if (Thread.currentThread() != cameraThread) { | 371 if (Thread.currentThread() != cameraThread) { |
372 throw new IllegalStateException("Wrong thread"); | 372 throw new IllegalStateException("Wrong thread"); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 final int[] range = CameraEnumerationAndroid.getFramerateRange(parameters, f
ramerate * 1000); | 529 final int[] range = CameraEnumerationAndroid.getFramerateRange(parameters, f
ramerate * 1000); |
530 final android.hardware.Camera.Size previewSize = | 530 final android.hardware.Camera.Size previewSize = |
531 CameraEnumerationAndroid.getClosestSupportedSize( | 531 CameraEnumerationAndroid.getClosestSupportedSize( |
532 parameters.getSupportedPreviewSizes(), width, height); | 532 parameters.getSupportedPreviewSizes(), width, height); |
533 final CaptureFormat captureFormat = new CaptureFormat( | 533 final CaptureFormat captureFormat = new CaptureFormat( |
534 previewSize.width, previewSize.height, | 534 previewSize.width, previewSize.height, |
535 range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX], | 535 range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX], |
536 range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); | 536 range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); |
537 | 537 |
538 // Check if we are already using this capture format, then we don't need to
do anything. | 538 // Check if we are already using this capture format, then we don't need to
do anything. |
539 if (captureFormat.equals(this.captureFormat)) { | 539 if (captureFormat.isSameFormat(this.captureFormat)) { |
540 return; | 540 return; |
541 } | 541 } |
542 | 542 |
543 // Update camera parameters. | 543 // Update camera parameters. |
544 Logging.d(TAG, "isVideoStabilizationSupported: " + | 544 Logging.d(TAG, "isVideoStabilizationSupported: " + |
545 parameters.isVideoStabilizationSupported()); | 545 parameters.isVideoStabilizationSupported()); |
546 if (parameters.isVideoStabilizationSupported()) { | 546 if (parameters.isVideoStabilizationSupported()) { |
547 parameters.setVideoStabilization(true); | 547 parameters.setVideoStabilization(true); |
548 } | 548 } |
549 // Note: setRecordingHint(true) actually decrease frame rate on N5. | 549 // Note: setRecordingHint(true) actually decrease frame rate on N5. |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 | 771 |
772 // Class used for allocating and bookkeeping video frames. All buffers are | 772 // Class used for allocating and bookkeeping video frames. All buffers are |
773 // direct allocated so that they can be directly used from native code. This c
lass is | 773 // direct allocated so that they can be directly used from native code. This c
lass is |
774 // not thread-safe, and enforces single thread use. | 774 // not thread-safe, and enforces single thread use. |
775 private static class FramePool { | 775 private static class FramePool { |
776 // Thread that all calls should be made on. | 776 // Thread that all calls should be made on. |
777 private final Thread thread; | 777 private final Thread thread; |
778 // Arbitrary queue depth. Higher number means more memory allocated & held, | 778 // Arbitrary queue depth. Higher number means more memory allocated & held, |
779 // lower number means more sensitivity to processing time in the client (and | 779 // lower number means more sensitivity to processing time in the client (and |
780 // potentially stalling the capturer if it runs out of buffers to write to). | 780 // potentially stalling the capturer if it runs out of buffers to write to). |
781 public static final int numCaptureBuffers = 3; | 781 public static final int NUMBER_OF_CAPTURE_BUFFERS = 3; |
782 // This container tracks the buffers added as camera callback buffers. It is
needed for finding | 782 // This container tracks the buffers added as camera callback buffers. It is
needed for finding |
783 // the corresponding ByteBuffer given a byte[]. | 783 // the corresponding ByteBuffer given a byte[]. |
784 private final Map<byte[], ByteBuffer> queuedBuffers = new IdentityHashMap<by
te[], ByteBuffer>(); | 784 private final Map<byte[], ByteBuffer> queuedBuffers = new IdentityHashMap<by
te[], ByteBuffer>(); |
785 // This container tracks the frames that have been sent but not returned. It
is needed for | 785 // This container tracks the frames that have been sent but not returned. It
is needed for |
786 // keeping the buffers alive and for finding the corresponding ByteBuffer gi
ven a timestamp. | 786 // keeping the buffers alive and for finding the corresponding ByteBuffer gi
ven a timestamp. |
787 private final Map<Long, ByteBuffer> pendingBuffers = new HashMap<Long, ByteB
uffer>(); | 787 private final Map<Long, ByteBuffer> pendingBuffers = new HashMap<Long, ByteB
uffer>(); |
788 private int frameSize = 0; | 788 private int frameSize = 0; |
789 private android.hardware.Camera camera; | 789 private android.hardware.Camera camera; |
790 | 790 |
791 public FramePool(Thread thread) { | 791 public FramePool(Thread thread) { |
792 this.thread = thread; | 792 this.thread = thread; |
793 } | 793 } |
794 | 794 |
795 private void checkIsOnValidThread() { | 795 private void checkIsOnValidThread() { |
796 if (Thread.currentThread() != thread) { | 796 if (Thread.currentThread() != thread) { |
797 throw new IllegalStateException("Wrong thread"); | 797 throw new IllegalStateException("Wrong thread"); |
798 } | 798 } |
799 } | 799 } |
800 | 800 |
801 // Discards previous queued buffers and adds new callback buffers to camera. | 801 // Discards previous queued buffers and adds new callback buffers to camera. |
802 public void queueCameraBuffers(int frameSize, android.hardware.Camera camera
) { | 802 public void queueCameraBuffers(int frameSize, android.hardware.Camera camera
) { |
803 checkIsOnValidThread(); | 803 checkIsOnValidThread(); |
804 this.camera = camera; | 804 this.camera = camera; |
805 this.frameSize = frameSize; | 805 this.frameSize = frameSize; |
806 | 806 |
807 queuedBuffers.clear(); | 807 queuedBuffers.clear(); |
808 for (int i = 0; i < numCaptureBuffers; ++i) { | 808 for (int i = 0; i < NUMBER_OF_CAPTURE_BUFFERS; ++i) { |
809 final ByteBuffer buffer = ByteBuffer.allocateDirect(frameSize); | 809 final ByteBuffer buffer = ByteBuffer.allocateDirect(frameSize); |
810 camera.addCallbackBuffer(buffer.array()); | 810 camera.addCallbackBuffer(buffer.array()); |
811 queuedBuffers.put(buffer.array(), buffer); | 811 queuedBuffers.put(buffer.array(), buffer); |
812 } | 812 } |
813 Logging.d(TAG, "queueCameraBuffers enqueued " + numCaptureBuffers | 813 Logging.d(TAG, "queueCameraBuffers enqueued " + NUMBER_OF_CAPTURE_BUFFERS |
814 + " buffers of size " + frameSize + "."); | 814 + " buffers of size " + frameSize + "."); |
815 } | 815 } |
816 | 816 |
817 public void stopReturnBuffersToCamera() { | 817 public void stopReturnBuffersToCamera() { |
818 checkIsOnValidThread(); | 818 checkIsOnValidThread(); |
819 this.camera = null; | 819 this.camera = null; |
820 queuedBuffers.clear(); | 820 queuedBuffers.clear(); |
821 // Frames in |pendingBuffers| need to be kept alive until they are returne
d. | 821 // Frames in |pendingBuffers| need to be kept alive until they are returne
d. |
822 } | 822 } |
823 | 823 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 private native void nativeOnByteBufferFrameCaptured(long nativeCapturer, | 938 private native void nativeOnByteBufferFrameCaptured(long nativeCapturer, |
939 byte[] data, int length, int width, int height, int rotation, long timeS
tamp); | 939 byte[] data, int length, int width, int height, int rotation, long timeS
tamp); |
940 private native void nativeOnTextureFrameCaptured(long nativeCapturer, int wi
dth, int height, | 940 private native void nativeOnTextureFrameCaptured(long nativeCapturer, int wi
dth, int height, |
941 int oesTextureId, float[] transformMatrix, long timestamp); | 941 int oesTextureId, float[] transformMatrix, long timestamp); |
942 private native void nativeOnOutputFormatRequest(long nativeCapturer, | 942 private native void nativeOnOutputFormatRequest(long nativeCapturer, |
943 int width, int height, int framerate); | 943 int width, int height, int framerate); |
944 } | 944 } |
945 | 945 |
946 private static native long nativeCreateVideoCapturer(VideoCapturerAndroid vide
oCapturer); | 946 private static native long nativeCreateVideoCapturer(VideoCapturerAndroid vide
oCapturer); |
947 } | 947 } |
OLD | NEW |