1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file. 4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "media/video/capture/android/video_capture_device_factory_android.h" 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/android/jni_string.h" 8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/android/scoped_java_ref.h" 9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/strings/string_number_conversions.h" 10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/strings/stringprintf.h" 11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "jni/VideoCaptureFactory_jni.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "media/video/capture/android/video_capture_device_android.h" 13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing base::android::AttachCurrentThread; 15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing base::android::ScopedJavaLocalRef; 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace media { 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// static 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool VideoCaptureDeviceFactoryAndroid::RegisterVideoCaptureDeviceFactory( 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) JNIEnv* env) { 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RegisterNativesImpl(env); 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//static 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ScopedJavaLocalRef<jobject> 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)VideoCaptureDeviceFactoryAndroid::createVideoCaptureAndroid( 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int id, 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) jlong nativeVideoCaptureDeviceAndroid) { 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (Java_VideoCaptureFactory_createVideoCapture( 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AttachCurrentThread(), 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::android::GetApplicationContext(), 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) id, 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) nativeVideoCaptureDeviceAndroid)); 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryAndroid::Create( 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const VideoCaptureDevice::Name& device_name) { 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int id; 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!base::StringToInt(device_name.id(), &id)) 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<VideoCaptureDevice>(); 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VideoCaptureDeviceAndroid* video_capture_device( 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new VideoCaptureDeviceAndroid(device_name)); 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (video_capture_device->Init()) 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<VideoCaptureDevice>(video_capture_device); 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DLOG(ERROR) << "Error creating Video Capture Device."; 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<VideoCaptureDevice>(); 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid VideoCaptureDeviceFactoryAndroid::GetDeviceNames( 55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VideoCaptureDevice::Names* device_names) { 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch device_names->clear(); 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch JNIEnv* env = AttachCurrentThread(); 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int num_cameras = Java_ChromiumCameraInfo_getNumberOfCameras( 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) env, base::android::GetApplicationContext()); 63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DVLOG(1) << "VideoCaptureDevice::GetDeviceNames: num_cameras=" << num_cameras; 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (num_cameras <= 0) 65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (int camera_id = num_cameras - 1; camera_id >= 0; --camera_id) { 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ScopedJavaLocalRef<jobject> ci = 69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Java_ChromiumCameraInfo_getAt(env, camera_id); 70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VideoCaptureDevice::Name name( 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::android::ConvertJavaStringToUTF8( 73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Java_ChromiumCameraInfo_getDeviceName(env, ci.obj())), 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::StringPrintf("%d", Java_ChromiumCameraInfo_getId(env, ci.obj()))); 75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch device_names->push_back(name); 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DVLOG(1) << "VideoCaptureDeviceFactoryAndroid::GetDeviceNames: camera" 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << "device_name=" << name.name() << ", unique_id=" << name.id() 79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << ", orientation " 80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << Java_ChromiumCameraInfo_getOrientation(env, ci.obj()); 81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid VideoCaptureDeviceFactoryAndroid::GetDeviceSupportedFormats( 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const VideoCaptureDevice::Name& device, 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VideoCaptureFormats* capture_formats) { 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch int id; 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!base::StringToInt(device.id(), &id)) 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch JNIEnv* env = AttachCurrentThread(); 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::android::ScopedJavaLocalRef<jobjectArray> collected_formats = 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Java_VideoCaptureFactory_getDeviceSupportedFormats(env, id); 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (collected_formats.is_null()) 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch jsize num_formats = env->GetArrayLength(collected_formats.obj()); 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (int i = 0; i < num_formats; ++i) { 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::android::ScopedJavaLocalRef<jobject> format( 100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch env, env->GetObjectArrayElement(collected_formats.obj(), i)); 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VideoPixelFormat pixel_format = media::PIXEL_FORMAT_UNKNOWN; 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch switch (media::Java_VideoCaptureFactory_getCaptureFormatPixelFormat( 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch env, format.obj())) { 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch case ANDROID_IMAGEFORMAT_YV12: 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch pixel_format = media::PIXEL_FORMAT_YV12; 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch break; 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch case ANDROID_IMAGEFORMAT_NV21: 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch pixel_format = media::PIXEL_FORMAT_NV21; 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch break; 111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch default: 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch break; 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VideoCaptureFormat capture_format( 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gfx::Size(media::Java_VideoCaptureFactory_getCaptureFormatWidth(env, 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch format.obj()), 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch media::Java_VideoCaptureFactory_getCaptureFormatHeight(env, 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch format.obj())), 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch media::Java_VideoCaptureFactory_getCaptureFormatFramerate(env, 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch format.obj()), 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch pixel_format); 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch capture_formats->push_back(capture_format); 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << device.name() << " " << capture_format.ToString(); 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace media 128