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