Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / video_engine / test / auto_test / source / vie_autotest_capture.cc
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "gflags/gflags.h"
12 #include "webrtc/common_types.h"
13 #include "webrtc/engine_configurations.h"
14 #include "webrtc/modules/video_capture/include/video_capture_factory.h"
15 #include "webrtc/system_wrappers/interface/tick_util.h"
16 #include "webrtc/video_engine/include/vie_base.h"
17 #include "webrtc/video_engine/include/vie_capture.h"
18 #include "webrtc/video_engine/include/vie_codec.h"
19 #include "webrtc/video_engine/include/vie_network.h"
20 #include "webrtc/video_engine/include/vie_render.h"
21 #include "webrtc/video_engine/include/vie_rtp_rtcp.h"
22 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
23 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
24 #include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
25 #include "webrtc/video_engine/test/libvietest/include/tb_video_channel.h"
26 #include "webrtc/voice_engine/include/voe_base.h"
27
28 DEFINE_bool(capture_test_ensure_resolution_alignment_in_capture_device, true,
29             "If true, we will give resolutions slightly below a reasonable "
30             "value to test the camera's ability to choose a good resolution. "
31             "If false, we will provide reasonable resolutions instead.");
32
33 class CaptureObserver : public webrtc::ViECaptureObserver {
34  public:
35   CaptureObserver()
36       : brightness_(webrtc::Normal),
37         alarm_(webrtc::AlarmCleared),
38         frame_rate_(0) {}
39
40   virtual void BrightnessAlarm(const int capture_id,
41                                const webrtc::Brightness brightness) {
42     brightness_ = brightness;
43     switch (brightness) {
44       case webrtc::Normal:
45         ViETest::Log("  BrightnessAlarm Normal");
46         break;
47       case webrtc::Bright:
48         ViETest::Log("  BrightnessAlarm Bright");
49         break;
50       case webrtc::Dark:
51         ViETest::Log("  BrightnessAlarm Dark");
52         break;
53     }
54   }
55
56   virtual void CapturedFrameRate(const int capture_id,
57                                  const unsigned char frame_rate) {
58     ViETest::Log("  CapturedFrameRate %u", frame_rate);
59     frame_rate_ = frame_rate;
60   }
61
62   virtual void NoPictureAlarm(const int capture_id,
63                               const webrtc::CaptureAlarm alarm) {
64     alarm_ = alarm;
65     if (alarm == webrtc::AlarmRaised) {
66       ViETest::Log("NoPictureAlarm CARaised.");
67     } else {
68       ViETest::Log("NoPictureAlarm CACleared.");
69     }
70   }
71
72   webrtc::Brightness brightness_;
73   webrtc::CaptureAlarm alarm_;
74   unsigned char frame_rate_;
75 };
76
77 class CaptureEffectFilter : public webrtc::ViEEffectFilter {
78  public:
79   CaptureEffectFilter(unsigned int expected_width, unsigned int expected_height)
80       : number_of_captured_frames_(0),
81         expected_width_(expected_width),
82         expected_height_(expected_height) {
83   }
84
85   // Implements video_engineEffectFilter.
86   virtual int Transform(int size,
87                         unsigned char* frame_buffer,
88                         int64_t ntp_time_ms,
89                         unsigned int timestamp,
90                         unsigned int width,
91                         unsigned int height) {
92     EXPECT_TRUE(frame_buffer != NULL);
93     EXPECT_EQ(expected_width_, width);
94     EXPECT_EQ(expected_height_, height);
95     ++number_of_captured_frames_;
96     return 0;
97   }
98
99   int number_of_captured_frames_;
100
101  protected:
102   unsigned int expected_width_;
103   unsigned int expected_height_;
104 };
105
106 void ViEAutoTest::ViECaptureStandardTest() {
107   /// **************************************************************
108   //  Begin create/initialize WebRTC Video Engine for testing
109   /// **************************************************************
110
111   /// **************************************************************
112   //  Engine ready. Begin testing class
113   /// **************************************************************
114
115   TbInterfaces video_engine("video_engineCaptureStandardTest");
116
117   webrtc::VideoCaptureModule::DeviceInfo* dev_info =
118       webrtc::VideoCaptureFactory::CreateDeviceInfo(0);
119   ASSERT_TRUE(dev_info != NULL);
120
121   int number_of_capture_devices = dev_info->NumberOfDevices();
122   ViETest::Log("Number of capture devices %d",
123                         number_of_capture_devices);
124   ASSERT_GT(number_of_capture_devices, 0)
125       << "This test requires a capture device (i.e. a webcam)";
126
127 #if !defined(WEBRTC_MAC)
128   int capture_device_id[10] = {0};
129   webrtc::VideoCaptureModule* vcpms[10] = {0};
130 #endif
131
132   // Check capabilities
133   for (int device_index = 0; device_index < number_of_capture_devices;
134        ++device_index) {
135     char device_name[128];
136     char device_unique_name[512];
137
138     EXPECT_EQ(0, dev_info->GetDeviceName(device_index,
139                                          device_name,
140                                          sizeof(device_name),
141                                          device_unique_name,
142                                          sizeof(device_unique_name)));
143     ViETest::Log("Found capture device %s\nUnique name %s",
144                           device_name, device_unique_name);
145
146 #if !defined(WEBRTC_MAC)  // these functions will return -1
147     int number_of_capabilities =
148         dev_info->NumberOfCapabilities(device_unique_name);
149     EXPECT_GT(number_of_capabilities, 0);
150
151     for (int cap_index = 0; cap_index < number_of_capabilities; ++cap_index) {
152       webrtc::VideoCaptureCapability capability;
153       EXPECT_EQ(0, dev_info->GetCapability(device_unique_name, cap_index,
154                                            capability));
155       ViETest::Log("Capture capability %d (of %u)", cap_index + 1,
156                    number_of_capabilities);
157       ViETest::Log("width %d, height %d, frame rate %d",
158                    capability.width, capability.height, capability.maxFPS);
159       ViETest::Log("expected delay %d, color type %d, encoding %d",
160                    capability.expectedCaptureDelay, capability.rawType,
161                    capability.codecType);
162       EXPECT_GT(capability.width, 0);
163       EXPECT_GT(capability.height, 0);
164       EXPECT_GT(capability.maxFPS, -1);  // >= 0
165       EXPECT_GT(capability.expectedCaptureDelay, 0);
166     }
167 #endif
168   }
169   // Capture Capability Functions are not supported on WEBRTC_MAC.
170 #if !defined(WEBRTC_MAC)
171
172   // Check allocation. Try to allocate them all after each other.
173   for (int device_index = 0; device_index < number_of_capture_devices;
174        ++device_index) {
175     char device_name[128];
176     char device_unique_name[512];
177     EXPECT_EQ(0, dev_info->GetDeviceName(device_index,
178                                          device_name,
179                                          sizeof(device_name),
180                                          device_unique_name,
181                                          sizeof(device_unique_name)));
182     webrtc::VideoCaptureModule* vcpm =
183         webrtc::VideoCaptureFactory::Create(device_index, device_unique_name);
184     EXPECT_TRUE(vcpm != NULL);
185     if (!vcpm)
186       continue;
187
188     vcpm->AddRef();
189     vcpms[device_index] = vcpm;
190
191     EXPECT_EQ(0, video_engine.capture->AllocateCaptureDevice(
192         *vcpm, capture_device_id[device_index]));
193
194     webrtc::VideoCaptureCapability capability;
195     EXPECT_EQ(0, dev_info->GetCapability(device_unique_name, 0, capability));
196
197     // Test that the camera select the closest capability to the selected
198     // width and height.
199     CaptureEffectFilter filter(capability.width, capability.height);
200     EXPECT_EQ(0, video_engine.image_process->RegisterCaptureEffectFilter(
201         capture_device_id[device_index], filter));
202
203     ViETest::Log("Testing Device %s capability width %d  height %d",
204                  device_unique_name, capability.width, capability.height);
205
206     if (FLAGS_capture_test_ensure_resolution_alignment_in_capture_device) {
207       // This tests that the capture device properly aligns to a
208       // multiple of 16 (or at least 8).
209       capability.height = capability.height - 2;
210       capability.width  = capability.width  - 2;
211     }
212
213     webrtc::CaptureCapability vie_capability;
214     vie_capability.width = capability.width;
215     vie_capability.height = capability.height;
216     vie_capability.codecType = capability.codecType;
217     vie_capability.maxFPS = capability.maxFPS;
218     vie_capability.rawType = capability.rawType;
219
220     EXPECT_EQ(0, video_engine.capture->StartCapture(
221         capture_device_id[device_index], vie_capability));
222     webrtc::TickTime start_time = webrtc::TickTime::Now();
223
224     while (filter.number_of_captured_frames_ < 10 &&
225            (webrtc::TickTime::Now() - start_time).Milliseconds() < 10000) {
226       AutoTestSleep(100);
227     }
228
229     EXPECT_GT(filter.number_of_captured_frames_, 9)
230         << "Should capture at least some frames";
231
232     EXPECT_EQ(0, video_engine.image_process->DeregisterCaptureEffectFilter(
233         capture_device_id[device_index]));
234
235 #ifdef WEBRTC_ANDROID  // Can only allocate one camera at the time on Android.
236     EXPECT_EQ(0, video_engine.capture->StopCapture(
237         capture_device_id[device_index]));
238     EXPECT_EQ(0, video_engine.capture->ReleaseCaptureDevice(
239         capture_device_id[device_index]));
240 #endif
241   }
242
243   /// **************************************************************
244   //  Testing finished. Tear down Video Engine
245   /// **************************************************************
246   delete dev_info;
247
248   // Stop all started capture devices.
249   for (int device_index = 0; device_index < number_of_capture_devices;
250        ++device_index) {
251 #if !defined(WEBRTC_ANDROID)
252     // Don't stop on Android since we can only allocate one camera.
253     EXPECT_EQ(0, video_engine.capture->StopCapture(
254         capture_device_id[device_index]));
255     EXPECT_EQ(0, video_engine.capture->ReleaseCaptureDevice(
256         capture_device_id[device_index]));
257 #endif  // !WEBRTC_ANDROID
258     if (vcpms[device_index])
259       vcpms[device_index]->Release();
260   }
261 #endif  // !WEBRTC_MAC
262 }
263
264 void ViEAutoTest::ViECaptureExtendedTest() {
265   ViECaptureExternalCaptureTest();
266 }
267
268 void ViEAutoTest::ViECaptureAPITest() {
269   /// **************************************************************
270   //  Begin create/initialize WebRTC Video Engine for testing
271   /// **************************************************************
272
273   /// **************************************************************
274   //  Engine ready. Begin testing class
275   /// **************************************************************
276   TbInterfaces video_engine("video_engineCaptureAPITest");
277
278   video_engine.capture->NumberOfCaptureDevices();
279
280   char device_name[128];
281   char device_unique_name[512];
282   int capture_id = 0;
283
284   webrtc::VideoCaptureModule::DeviceInfo* dev_info =
285       webrtc::VideoCaptureFactory::CreateDeviceInfo(0);
286   ASSERT_TRUE(dev_info != NULL);
287   ASSERT_GT(dev_info->NumberOfDevices(), 0u)
288       << "This test requires a capture device (i.e. a webcam)";
289
290   // Get the first capture device
291   EXPECT_EQ(0, dev_info->GetDeviceName(0, device_name,
292                                        sizeof(device_name),
293                                        device_unique_name,
294                                        sizeof(device_unique_name)));
295
296   webrtc::VideoCaptureModule* vcpm =
297       webrtc::VideoCaptureFactory::Create(0, device_unique_name);
298   vcpm->AddRef();
299   EXPECT_TRUE(vcpm != NULL);
300
301   // Allocate capture device.
302   EXPECT_EQ(0, video_engine.capture->AllocateCaptureDevice(*vcpm, capture_id));
303
304   // Start the capture device.
305   EXPECT_EQ(0, video_engine.capture->StartCapture(capture_id));
306
307   // Start again. Should fail.
308   EXPECT_NE(0, video_engine.capture->StartCapture(capture_id));
309   EXPECT_EQ(kViECaptureDeviceAlreadyStarted, video_engine.LastError());
310
311   // Start invalid capture device.
312   EXPECT_NE(0, video_engine.capture->StartCapture(capture_id + 1));
313   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
314
315   // Stop invalid capture device.
316   EXPECT_NE(0, video_engine.capture->StopCapture(capture_id + 1));
317   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
318
319   // Stop the capture device.
320   EXPECT_EQ(0, video_engine.capture->StopCapture(capture_id));
321
322   // Stop the capture device again.
323   EXPECT_NE(0, video_engine.capture->StopCapture(capture_id));
324   EXPECT_EQ(kViECaptureDeviceNotStarted, video_engine.LastError());
325
326   // Connect to invalid channel.
327   EXPECT_NE(0, video_engine.capture->ConnectCaptureDevice(capture_id, 0));
328   EXPECT_EQ(kViECaptureDeviceInvalidChannelId,
329             video_engine.LastError());
330
331   TbVideoChannel channel(video_engine);
332
333   // Connect invalid capture_id.
334   EXPECT_NE(0, video_engine.capture->ConnectCaptureDevice(capture_id + 1,
335                                                  channel.videoChannel));
336   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
337
338   // Connect the capture device to the channel.
339   EXPECT_EQ(0, video_engine.capture->ConnectCaptureDevice(capture_id,
340                                                  channel.videoChannel));
341
342   // Connect the channel again.
343   EXPECT_NE(0, video_engine.capture->ConnectCaptureDevice(capture_id,
344                                                  channel.videoChannel));
345   EXPECT_EQ(kViECaptureDeviceAlreadyConnected,
346             video_engine.LastError());
347
348   // Start the capture device.
349   EXPECT_EQ(0, video_engine.capture->StartCapture(capture_id));
350
351   // Release invalid capture device.
352   EXPECT_NE(0, video_engine.capture->ReleaseCaptureDevice(capture_id + 1));
353   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
354
355   // Release the capture device.
356   EXPECT_EQ(0, video_engine.capture->ReleaseCaptureDevice(capture_id));
357
358   // Release the capture device again.
359   EXPECT_NE(0, video_engine.capture->ReleaseCaptureDevice(capture_id));
360   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
361
362   // Test GetOrientation.
363   webrtc::VideoCaptureRotation orientation;
364   char dummy_name[5];
365   EXPECT_NE(0, dev_info->GetOrientation(dummy_name, orientation));
366
367   // Test SetRotation.
368   EXPECT_NE(0, video_engine.capture->SetRotateCapturedFrames(
369       capture_id, webrtc::RotateCapturedFrame_90));
370   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
371
372   // Allocate capture device.
373   EXPECT_EQ(0, video_engine.capture->AllocateCaptureDevice(*vcpm, capture_id));
374
375   EXPECT_EQ(0, video_engine.capture->SetRotateCapturedFrames(
376       capture_id, webrtc::RotateCapturedFrame_0));
377   EXPECT_EQ(0, video_engine.capture->SetRotateCapturedFrames(
378       capture_id, webrtc::RotateCapturedFrame_90));
379   EXPECT_EQ(0, video_engine.capture->SetRotateCapturedFrames(
380       capture_id, webrtc::RotateCapturedFrame_180));
381   EXPECT_EQ(0, video_engine.capture->SetRotateCapturedFrames(
382       capture_id, webrtc::RotateCapturedFrame_270));
383
384   // Release the capture device
385   EXPECT_EQ(0, video_engine.capture->ReleaseCaptureDevice(capture_id));
386
387   /// **************************************************************
388   //  Testing finished. Tear down Video Engine
389   /// **************************************************************
390   delete dev_info;
391   vcpm->Release();
392 }
393
394 void ViEAutoTest::ViECaptureExternalCaptureTest() {
395   /// **************************************************************
396   //  Begin create/initialize WebRTC Video Engine for testing
397   /// **************************************************************
398
399   TbInterfaces video_engine("video_engineCaptureExternalCaptureTest");
400   TbVideoChannel channel(video_engine);
401   channel.StartReceive();
402   channel.StartSend();
403
404   webrtc::VideoCaptureExternal* external_capture = NULL;
405   int capture_id = 0;
406
407   // Allocate the external capture device.
408   webrtc::VideoCaptureModule* vcpm =
409       webrtc::VideoCaptureFactory::Create(0, external_capture);
410   EXPECT_TRUE(vcpm != NULL);
411   EXPECT_TRUE(external_capture != NULL);
412   vcpm->AddRef();
413
414   EXPECT_EQ(0, video_engine.capture->AllocateCaptureDevice(*vcpm, capture_id));
415
416   // Connect the capture device to the channel.
417   EXPECT_EQ(0, video_engine.capture->ConnectCaptureDevice(capture_id,
418                                                  channel.videoChannel));
419
420   // Render the local capture.
421   EXPECT_EQ(0, video_engine.render->AddRenderer(capture_id, _window1, 1, 0.0,
422                                                 0.0, 1.0, 1.0));
423
424   // Render the remote capture.
425   EXPECT_EQ(0, video_engine.render->AddRenderer(channel.videoChannel, _window2,
426                                                 1, 0.0, 0.0, 1.0, 1.0));
427   EXPECT_EQ(0, video_engine.render->StartRender(capture_id));
428   EXPECT_EQ(0, video_engine.render->StartRender(channel.videoChannel));
429
430   // Register observer.
431   CaptureObserver observer;
432   EXPECT_EQ(0, video_engine.capture->RegisterObserver(capture_id, observer));
433
434   // Enable brightness alarm.
435   EXPECT_EQ(0, video_engine.capture->EnableBrightnessAlarm(capture_id, true));
436
437   CaptureEffectFilter effect_filter(176, 144);
438   EXPECT_EQ(0, video_engine.image_process->RegisterCaptureEffectFilter(
439       capture_id, effect_filter));
440
441   // Call started.
442   ViETest::Log("You should see local preview from external capture\n"
443                "in window 1 and the remote video in window 2.\n");
444
445   /// **************************************************************
446   //  Engine ready. Begin testing class
447   /// **************************************************************
448   const unsigned int video_frame_length = (176 * 144 * 3) / 2;
449   unsigned char* video_frame = new unsigned char[video_frame_length];
450   memset(video_frame, 128, 176 * 144);
451
452   int frame_count = 0;
453   webrtc::VideoCaptureCapability capability;
454   capability.width = 176;
455   capability.height = 144;
456   capability.rawType = webrtc::kVideoI420;
457
458   ViETest::Log("Testing external capturing and frame rate callbacks.");
459   // TODO(mflodman) Change when using a real file!
460   // while (fread(video_frame, video_frame_length, 1, foreman) == 1)
461   while (frame_count < 120) {
462     external_capture->IncomingFrame(
463         video_frame, video_frame_length, capability,
464         webrtc::TickTime::MillisecondTimestamp());
465     AutoTestSleep(33);
466
467     if (effect_filter.number_of_captured_frames_ > 2) {
468       EXPECT_EQ(webrtc::Normal, observer.brightness_) <<
469           "Brightness or picture alarm should not have been called yet.";
470       EXPECT_EQ(webrtc::AlarmCleared, observer.alarm_) <<
471           "Brightness or picture alarm should not have been called yet.";
472     }
473     frame_count++;
474   }
475
476   // Test brightness alarm.
477   // Test bright image.
478   for (int i = 0; i < 176 * 144; ++i) {
479     if (video_frame[i] <= 155)
480       video_frame[i] = video_frame[i] + 100;
481     else
482       video_frame[i] = 255;
483   }
484   ViETest::Log("Testing Brighness alarm");
485   for (int frame = 0; frame < 30; ++frame) {
486     external_capture->IncomingFrame(
487         video_frame, video_frame_length, capability,
488         webrtc::TickTime::MillisecondTimestamp());
489     AutoTestSleep(33);
490   }
491   EXPECT_EQ(webrtc::Bright, observer.brightness_) <<
492       "Should be bright at this point since we are using a bright image.";
493
494   // Test Dark image
495   for (int i = 0; i < 176 * 144; ++i) {
496     video_frame[i] = video_frame[i] > 200 ? video_frame[i] - 200 : 0;
497   }
498   for (int frame = 0; frame < 30; ++frame) {
499     external_capture->IncomingFrame(
500         video_frame, video_frame_length, capability,
501         webrtc::TickTime::MillisecondTimestamp());
502     AutoTestSleep(33);
503   }
504   EXPECT_EQ(webrtc::Dark, observer.brightness_) <<
505       "Should be dark at this point since we are using a dark image.";
506   EXPECT_GT(effect_filter.number_of_captured_frames_, 150) <<
507       "Frames should have been played.";
508
509   EXPECT_GE(observer.frame_rate_, 29) <<
510       "Frame rate callback should be approximately correct.";
511   EXPECT_LE(observer.frame_rate_, 30) <<
512       "Frame rate callback should be approximately correct.";
513
514   // Test no picture alarm
515   ViETest::Log("Testing NoPictureAlarm.");
516   AutoTestSleep(1050);
517
518   EXPECT_EQ(webrtc::AlarmRaised, observer.alarm_) <<
519       "No picture alarm should be raised.";
520   for (int frame = 0; frame < 10; ++frame) {
521     external_capture->IncomingFrame(
522         video_frame, video_frame_length, capability,
523         webrtc::TickTime::MillisecondTimestamp());
524     AutoTestSleep(33);
525   }
526   EXPECT_EQ(webrtc::AlarmCleared, observer.alarm_) <<
527   "Alarm should be cleared since ge just got some data.";
528
529   delete video_frame;
530
531   // Release the capture device
532   EXPECT_EQ(0, video_engine.capture->ReleaseCaptureDevice(capture_id));
533
534   // Release the capture device again
535   EXPECT_NE(0, video_engine.capture->ReleaseCaptureDevice(capture_id));
536   EXPECT_EQ(kViECaptureDeviceDoesNotExist, video_engine.LastError());
537   vcpm->Release();
538
539   /// **************************************************************
540   //  Testing finished. Tear down Video Engine
541   /// **************************************************************
542 }