196e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org/*
296e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * libjingle
396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * Copyright 2015 Google Inc.
496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *
596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * Redistribution and use in source and binary forms, with or without
696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * modification, are permitted provided that the following conditions are met:
796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *
896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *     this list of conditions and the following disclaimer.
1096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
1196e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *     this list of conditions and the following disclaimer in the documentation
1296e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *     and/or other materials provided with the distribution.
1396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *  3. The name of the author may not be used to endorse or promote products
1496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *     derived from this software without specific prior written permission.
1596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *
1696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
1796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
1996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2196e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2296e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org *
2796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org */
2896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
2996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org#include "talk/app/webrtc/java/jni/androidvideocapturer_jni.h"
3096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org#include "talk/app/webrtc/java/jni/classreferenceholder.h"
31ac30642461c4f94916741106e3ba3f3b7b670a47perkj#include "talk/app/webrtc/java/jni/native_handle_impl.h"
3288518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj#include "talk/app/webrtc/java/jni/surfacetexturehelper_jni.h"
3388518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj#include "third_party/libyuv/include/libyuv/convert.h"
343db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org#include "webrtc/base/bind.h"
3596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
3696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.orgnamespace webrtc_jni {
3796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
3896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.orgjobject AndroidVideoCapturerJni::application_context_ = nullptr;
3996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
4096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org// static
4196e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.orgint AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni,
4296e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org                                               jobject appliction_context) {
4396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  if (application_context_) {
4496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org    jni->DeleteGlobalRef(application_context_);
4596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  }
4696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  application_context_ = NewGlobalRef(jni, appliction_context);
4796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
4896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  return 0;
4996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org}
5096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
51c490e01bd1bd4a0d754ed5f746b95ac03136346fnisseAndroidVideoCapturerJni::AndroidVideoCapturerJni(
52c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse    JNIEnv* jni,
53c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse    jobject j_video_capturer,
54c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse    jobject j_surface_texture_helper)
55c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse    : j_video_capturer_(jni, j_video_capturer),
5696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org      j_video_capturer_class_(
5796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org          jni, FindClass(jni, "org/webrtc/VideoCapturerAndroid")),
583db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org      j_observer_class_(
5996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org          jni,
6096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org          FindClass(jni,
613db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org                    "org/webrtc/VideoCapturerAndroid$NativeObserver")),
6288518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      surface_texture_helper_(new rtc::RefCountedObject<SurfaceTextureHelper>(
6388518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj          jni, j_surface_texture_helper)),
64c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert      capturer_(nullptr) {
658c054154daa17676ad32ca6554025b7a09670410Alex Glaznev  LOG(LS_INFO) << "AndroidVideoCapturerJni ctor";
663db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org  thread_checker_.DetachFromThread();
673db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org}
683db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org
693db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.orgAndroidVideoCapturerJni::~AndroidVideoCapturerJni() {
70c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  LOG(LS_INFO) << "AndroidVideoCapturerJni dtor";
71f706c8ae914da976f16205ff13d15b1a28ead8fdMagnus Jedvert  jni()->CallVoidMethod(
72c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse      *j_video_capturer_,
73f706c8ae914da976f16205ff13d15b1a28ead8fdMagnus Jedvert      GetMethodID(jni(), *j_video_capturer_class_, "release", "()V"));
74f706c8ae914da976f16205ff13d15b1a28ead8fdMagnus Jedvert  CHECK_EXCEPTION(jni()) << "error during VideoCapturerAndroid.release()";
753db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org}
7696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
7796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.orgvoid AndroidVideoCapturerJni::Start(int width, int height, int framerate,
7896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org                                    webrtc::AndroidVideoCapturer* capturer) {
798c054154daa17676ad32ca6554025b7a09670410Alex Glaznev  LOG(LS_INFO) << "AndroidVideoCapturerJni start";
8091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(thread_checker_.CalledOnValidThread());
81c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  {
82c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    rtc::CritScope cs(&capturer_lock_);
8391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_CHECK(capturer_ == nullptr);
8491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg    RTC_CHECK(invoker_.get() == nullptr);
85c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    capturer_ = capturer;
86c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    invoker_.reset(new rtc::GuardedAsyncInvoker());
87c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  }
88c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  jobject j_frame_observer =
893db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org      jni()->NewObject(*j_observer_class_,
90c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                       GetMethodID(jni(), *j_observer_class_, "<init>", "(J)V"),
91c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                       jlongFromPointer(this));
9296e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  CHECK_EXCEPTION(jni()) << "error during NewObject";
9396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
9496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  jmethodID m = GetMethodID(
9596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org      jni(), *j_video_capturer_class_, "startCapture",
9696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org      "(IIILandroid/content/Context;"
9796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org      "Lorg/webrtc/VideoCapturerAndroid$CapturerObserver;)V");
98c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse  jni()->CallVoidMethod(*j_video_capturer_,
9996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org                        m, width, height,
10096e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org                        framerate,
10196e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org                        application_context_,
102c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                        j_frame_observer);
10396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  CHECK_EXCEPTION(jni()) << "error during VideoCapturerAndroid.startCapture";
10496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org}
10596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
1063db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.orgvoid AndroidVideoCapturerJni::Stop() {
1078c054154daa17676ad32ca6554025b7a09670410Alex Glaznev  LOG(LS_INFO) << "AndroidVideoCapturerJni stop";
10891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK(thread_checker_.CalledOnValidThread());
109c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  {
110c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    rtc::CritScope cs(&capturer_lock_);
111c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    // Destroying |invoker_| will cancel all pending calls to |capturer_|.
112c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    invoker_ = nullptr;
113c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    capturer_ = nullptr;
114c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  }
11596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  jmethodID m = GetMethodID(jni(), *j_video_capturer_class_,
1163db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.org                            "stopCapture", "()V");
117c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse  jni()->CallVoidMethod(*j_video_capturer_, m);
11896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  CHECK_EXCEPTION(jni()) << "error during VideoCapturerAndroid.stopCapture";
1198c054154daa17676ad32ca6554025b7a09670410Alex Glaznev  LOG(LS_INFO) << "AndroidVideoCapturerJni stop done";
120112f127170193bf022565b112b03827c025168b6perkj@webrtc.org}
121112f127170193bf022565b112b03827c025168b6perkj@webrtc.org
122c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedverttemplate <typename... Args>
123c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvertvoid AndroidVideoCapturerJni::AsyncCapturerInvoke(
124c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    const char* method_name,
125c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    void (webrtc::AndroidVideoCapturer::*method)(Args...),
12630a5b5e9fb574016ced1a45ae43921c1a01860a0olka    typename Identity<Args>::type... args) {
127c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  rtc::CritScope cs(&capturer_lock_);
128c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  if (!invoker_) {
129c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert    LOG(LS_WARNING) << method_name << "() called for closed capturer.";
130c4905fb72a01d5fe5788cc33d847c31b039468e3Alex Glaznev    return;
131c4905fb72a01d5fe5788cc33d847c31b039468e3Alex Glaznev  }
132c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  invoker_->AsyncInvoke<void>(rtc::Bind(method, capturer_, args...));
133c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert}
134c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert
13596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.orgstd::string AndroidVideoCapturerJni::GetSupportedFormats() {
13696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  jmethodID m =
13796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org      GetMethodID(jni(), *j_video_capturer_class_,
13896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org                  "getSupportedFormatsAsJson", "()Ljava/lang/String;");
13996e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  jstring j_json_caps =
140c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse      (jstring) jni()->CallObjectMethod(*j_video_capturer_, m);
14196e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  CHECK_EXCEPTION(jni()) << "error during supportedFormatsAsJson";
14296e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org  return JavaToStdString(jni(), j_json_caps);
14396e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org}
14496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
145112f127170193bf022565b112b03827c025168b6perkj@webrtc.orgvoid AndroidVideoCapturerJni::OnCapturerStarted(bool success) {
146c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  LOG(LS_INFO) << "AndroidVideoCapturerJni capture started: " << success;
147c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  AsyncCapturerInvoke("OnCapturerStarted",
148c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                      &webrtc::AndroidVideoCapturer::OnCapturerStarted,
149c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                      success);
150112f127170193bf022565b112b03827c025168b6perkj@webrtc.org}
151112f127170193bf022565b112b03827c025168b6perkj@webrtc.org
152ac30642461c4f94916741106e3ba3f3b7b670a47perkjvoid AndroidVideoCapturerJni::OnMemoryBufferFrame(void* video_frame,
153ac30642461c4f94916741106e3ba3f3b7b670a47perkj                                                  int length,
154ac30642461c4f94916741106e3ba3f3b7b670a47perkj                                                  int width,
155ac30642461c4f94916741106e3ba3f3b7b670a47perkj                                                  int height,
156ac30642461c4f94916741106e3ba3f3b7b670a47perkj                                                  int rotation,
157ac30642461c4f94916741106e3ba3f3b7b670a47perkj                                                  int64_t timestamp_ns) {
158b5815c801362c98d99668924a8d3ba763ec36a04magjed  const uint8_t* y_plane = static_cast<uint8_t*>(video_frame);
15988518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj  const uint8_t* vu_plane = y_plane + width * height;
16088518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj
16188518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj  rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
16288518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      buffer_pool_.CreateBuffer(width, height);
16388518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj  libyuv::NV21ToI420(
16488518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      y_plane, width,
16588518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      vu_plane, width,
16688518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      buffer->MutableData(webrtc::kYPlane), buffer->stride(webrtc::kYPlane),
16788518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      buffer->MutableData(webrtc::kUPlane), buffer->stride(webrtc::kUPlane),
16888518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      buffer->MutableData(webrtc::kVPlane), buffer->stride(webrtc::kVPlane),
16988518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      width, height);
170c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  AsyncCapturerInvoke("OnIncomingFrame",
171c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                      &webrtc::AndroidVideoCapturer::OnIncomingFrame,
172ac30642461c4f94916741106e3ba3f3b7b670a47perkj                      buffer, rotation, timestamp_ns);
173ac30642461c4f94916741106e3ba3f3b7b670a47perkj}
174ac30642461c4f94916741106e3ba3f3b7b670a47perkj
175488e75f11b840dfbe636a9ea9bbc18252e7c59f0Pervoid AndroidVideoCapturerJni::OnTextureFrame(int width,
176488e75f11b840dfbe636a9ea9bbc18252e7c59f0Per                                             int height,
17771f5a9a37750d6ccea110028e3154ee90334ba6dPer                                             int rotation,
178488e75f11b840dfbe636a9ea9bbc18252e7c59f0Per                                             int64_t timestamp_ns,
179488e75f11b840dfbe636a9ea9bbc18252e7c59f0Per                                             const NativeHandleImpl& handle) {
180ac30642461c4f94916741106e3ba3f3b7b670a47perkj  rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
18188518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj      surface_texture_helper_->CreateTextureFrame(width, height, handle));
18288518a22c62ccb7989a0e10d43bea1a63cdfcd09perkj
183ac30642461c4f94916741106e3ba3f3b7b670a47perkj  AsyncCapturerInvoke("OnIncomingFrame",
184ac30642461c4f94916741106e3ba3f3b7b670a47perkj                      &webrtc::AndroidVideoCapturer::OnIncomingFrame,
18571f5a9a37750d6ccea110028e3154ee90334ba6dPer                      buffer, rotation, timestamp_ns);
186112f127170193bf022565b112b03827c025168b6perkj@webrtc.org}
187112f127170193bf022565b112b03827c025168b6perkj@webrtc.org
1882b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Perssonvoid AndroidVideoCapturerJni::OnOutputFormatRequest(int width,
1892b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson                                                    int height,
1902b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson                                                    int fps) {
191c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  AsyncCapturerInvoke("OnOutputFormatRequest",
192c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                      &webrtc::AndroidVideoCapturer::OnOutputFormatRequest,
193c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert                      width, height, fps);
1942b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson}
1952b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson
19696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.orgJNIEnv* AndroidVideoCapturerJni::jni() { return AttachCurrentThreadIfNeeded(); }
19796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
1983d06eca5e3310ea068625a9c95d492a16854f421perkjJOW(void,
1993d06eca5e3310ea068625a9c95d492a16854f421perkj    VideoCapturerAndroid_00024NativeObserver_nativeOnByteBufferFrameCaptured)
200b5815c801362c98d99668924a8d3ba763ec36a04magjed    (JNIEnv* jni, jclass, jlong j_capturer, jbyteArray j_frame, jint length,
201ac30642461c4f94916741106e3ba3f3b7b670a47perkj        jint width, jint height, jint rotation, jlong timestamp) {
202b5815c801362c98d99668924a8d3ba763ec36a04magjed  jboolean is_copy = true;
203b5815c801362c98d99668924a8d3ba763ec36a04magjed  jbyte* bytes = jni->GetByteArrayElements(j_frame, &is_copy);
204c464f504dcb40ad40b5258875493f12783bd5fdaMagnus Jedvert  reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)
205ac30642461c4f94916741106e3ba3f3b7b670a47perkj      ->OnMemoryBufferFrame(bytes, length, width, height, rotation, timestamp);
206b5815c801362c98d99668924a8d3ba763ec36a04magjed  jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT);
20796e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org}
20896e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
209ac30642461c4f94916741106e3ba3f3b7b670a47perkjJOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnTextureFrameCaptured)
210ac30642461c4f94916741106e3ba3f3b7b670a47perkj    (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height,
211ac30642461c4f94916741106e3ba3f3b7b670a47perkj        jint j_oes_texture_id, jfloatArray j_transform_matrix,
21271f5a9a37750d6ccea110028e3154ee90334ba6dPer        jint j_rotation, jlong j_timestamp) {
213ac30642461c4f94916741106e3ba3f3b7b670a47perkj   reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)
21471f5a9a37750d6ccea110028e3154ee90334ba6dPer         ->OnTextureFrame(j_width, j_height, j_rotation, j_timestamp,
215488e75f11b840dfbe636a9ea9bbc18252e7c59f0Per                          NativeHandleImpl(jni, j_oes_texture_id,
216488e75f11b840dfbe636a9ea9bbc18252e7c59f0Per                                           j_transform_matrix));
217ac30642461c4f94916741106e3ba3f3b7b670a47perkj}
218ac30642461c4f94916741106e3ba3f3b7b670a47perkj
2193db042e2f09f1df7d8b5d40f30766f780848ecd9perkj@webrtc.orgJOW(void, VideoCapturerAndroid_00024NativeObserver_nativeCapturerStarted)
220112f127170193bf022565b112b03827c025168b6perkj@webrtc.org    (JNIEnv* jni, jclass, jlong j_capturer, jboolean j_success) {
2218c054154daa17676ad32ca6554025b7a09670410Alex Glaznev  LOG(LS_INFO) << "NativeObserver_nativeCapturerStarted";
222112f127170193bf022565b112b03827c025168b6perkj@webrtc.org  reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)->OnCapturerStarted(
223112f127170193bf022565b112b03827c025168b6perkj@webrtc.org      j_success);
22496e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org}
22596e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org
2262b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa PerssonJOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnOutputFormatRequest)
2272b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson    (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height,
2282b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson        jint j_fps) {
2292b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson  LOG(LS_INFO) << "NativeObserver_nativeOnOutputFormatRequest";
2302b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson  reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)->OnOutputFormatRequest(
2312b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson      j_width, j_height, j_fps);
2322b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson}
2332b679250fbd50b3c8d9ac266a42fbc8a1bd84167Åsa Persson
234e0bce240652bcf4031ae61985938e968469d3f53perkjJOW(jlong, VideoCapturerAndroid_nativeCreateVideoCapturer)
235c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse    (JNIEnv* jni, jclass,
236c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse     jobject j_video_capturer, jobject j_surface_texture_helper) {
237e0bce240652bcf4031ae61985938e968469d3f53perkj  rtc::scoped_refptr<webrtc::AndroidVideoCapturerDelegate> delegate =
238c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse      new rtc::RefCountedObject<AndroidVideoCapturerJni>(
239c490e01bd1bd4a0d754ed5f746b95ac03136346fnisse          jni, j_video_capturer, j_surface_texture_helper);
240e0bce240652bcf4031ae61985938e968469d3f53perkj  rtc::scoped_ptr<cricket::VideoCapturer> capturer(
241e0bce240652bcf4031ae61985938e968469d3f53perkj      new webrtc::AndroidVideoCapturer(delegate));
242e0bce240652bcf4031ae61985938e968469d3f53perkj  // Caller takes ownership of the cricket::VideoCapturer* pointer.
243e0bce240652bcf4031ae61985938e968469d3f53perkj  return jlongFromPointer(capturer.release());
244e0bce240652bcf4031ae61985938e968469d3f53perkj}
245e0bce240652bcf4031ae61985938e968469d3f53perkj
24696e4db9bea49cf096044c89c94778bff525362baperkj@webrtc.org}  // namespace webrtc_jni
247