Index: media/video/capture/fake_video_capture_device.cc |
diff --git a/media/video/capture/fake_video_capture_device.cc b/media/video/capture/fake_video_capture_device.cc |
index 34f8f20d701d8b3e2accd3b433db342a2b5b8ebe..82735df0680df919e8c857e91768ee86c04b5521 100644 |
--- a/media/video/capture/fake_video_capture_device.cc |
+++ b/media/video/capture/fake_video_capture_device.cc |
@@ -10,31 +10,41 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/strings/stringprintf.h" |
#include "media/audio/fake_audio_input_stream.h" |
+#include "media/base/encoded_bitstream_buffer.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
#include "third_party/skia/include/core/SkPaint.h" |
namespace media { |
-static const int kFakeCaptureTimeoutMs = 50; |
-static const int kFakeCaptureBeepCycle = 20; // Visual beep every 1s. |
+namespace { |
Ami GONE FROM CHROMIUM
2013/06/18 18:35:55
not adding value
sheu
2013/08/22 22:40:31
Fine :-P
|
+ |
+const int kFakeCaptureTimeoutMs = 50; |
+const int kFakeCaptureBeepCycle = 20; // Visual beep every 1s. |
enum { kNumberOfFakeDevices = 2 }; |
+} // anonymous namespace |
+ |
bool FakeVideoCaptureDevice::fail_next_create_ = false; |
-void FakeVideoCaptureDevice::GetDeviceNames(Names* const device_names) { |
+void FakeVideoCaptureDevice::GetDeviceNames(Names* const device_names, |
+ bool encoded_capture) { |
// Empty the name list. |
device_names->erase(device_names->begin(), device_names->end()); |
for (int n = 0; n < kNumberOfFakeDevices; n++) { |
Name name; |
name.unique_id = base::StringPrintf("/dev/video%d", n); |
- name.device_name = base::StringPrintf("fake_device_%d", n); |
+ name.device_name = base::StringPrintf( |
+ "fake_%sdevice_%d", |
+ (encoded_capture ? "encoded_" : ""), |
+ n); |
device_names->push_back(name); |
} |
} |
-VideoCaptureDevice* FakeVideoCaptureDevice::Create(const Name& device_name) { |
+VideoCaptureDevice* FakeVideoCaptureDevice::Create(const Name& device_name, |
+ bool encoded_capture) { |
if (fail_next_create_) { |
fail_next_create_ = false; |
return NULL; |
@@ -42,7 +52,7 @@ VideoCaptureDevice* FakeVideoCaptureDevice::Create(const Name& device_name) { |
for (int n = 0; n < kNumberOfFakeDevices; ++n) { |
std::string possible_id = base::StringPrintf("/dev/video%d", n); |
if (device_name.unique_id.compare(possible_id) == 0) { |
- return new FakeVideoCaptureDevice(device_name); |
+ return new FakeVideoCaptureDevice(device_name, encoded_capture); |
} |
} |
return NULL; |
@@ -52,8 +62,10 @@ void FakeVideoCaptureDevice::SetFailNextCreate() { |
fail_next_create_ = true; |
} |
-FakeVideoCaptureDevice::FakeVideoCaptureDevice(const Name& device_name) |
+FakeVideoCaptureDevice::FakeVideoCaptureDevice(const Name& device_name, |
+ bool encoded_capture) |
: device_name_(device_name), |
+ encoded_capture_(encoded_capture), |
observer_(NULL), |
state_(kIdle), |
capture_thread_("CaptureThread"), |
@@ -69,39 +81,71 @@ FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { |
DCHECK(!capture_thread_.IsRunning()); |
} |
+VideoEncodingCapabilities FakeVideoCaptureDevice::GetEncodingCapabilities() { |
+ media::VideoEncodingCapabilities capabilities; |
+ if (encoded_capture_) { |
+ media::VideoEncodingConfig config; |
+ config.codec_type = kCodecVP8; |
+ config.codec_name = "VP8"; |
+ config.max_resolution.SetSize(640, 480); |
+ config.max_frames_per_second = 30; |
+ config.max_bitrate = 1024 * 1024; |
+ capabilities.push_back(config); |
+ } |
+ return capabilities; |
+} |
+ |
+void FakeVideoCaptureDevice::TryConfigureEncodedBitstream( |
+ const RuntimeVideoEncodingParameters& params) { |
+ DCHECK(encoded_capture_); |
+ DCHECK(observer_); |
+ observer_->OnBitstreamConfigChanged(params); |
+} |
+ |
void FakeVideoCaptureDevice::Allocate(int width, |
- int height, |
- int frame_rate, |
- EventHandler* observer) { |
+ int height, |
+ int frame_rate, |
+ EventHandler* observer) { |
if (state_ != kIdle) { |
return; // Wrong state. |
} |
+ DCHECK(!observer_); |
observer_ = observer; |
- VideoCaptureCapability current_settings; |
- current_settings.color = VideoCaptureCapability::kI420; |
- current_settings.expected_capture_delay = 0; |
- current_settings.interlaced = false; |
- if (width > 320) { // VGA |
- current_settings.width = 640; |
- current_settings.height = 480; |
- current_settings.frame_rate = 30; |
- } else { // QVGA |
- current_settings.width = 320; |
- current_settings.height = 240; |
- current_settings.frame_rate = 30; |
- } |
+ state_ = kAllocated; |
- size_t fake_frame_size = |
- current_settings.width * current_settings.height * 3 / 2; |
- fake_frame_.reset(new uint8[fake_frame_size]); |
- memset(fake_frame_.get(), 0, fake_frame_size); |
- frame_size_ = fake_frame_size; |
- frame_width_ = current_settings.width; |
- frame_height_ = current_settings.height; |
+ if (encoded_capture_) { |
+ media::VideoEncodingParameters params; |
+ params.codec_name = std::string("VP8"); |
+ params.resolution.SetSize(640, 480); |
+ params.runtime_params.target_bitrate = 512; |
+ params.runtime_params.max_bitrate = 1024; |
+ params.runtime_params.frames_per_second = 30; |
+ observer_->OnEncodedFrameInfo(params); |
+ } else { |
+ VideoCaptureCapability current_settings; |
+ current_settings.color = VideoCaptureCapability::kI420; |
+ current_settings.expected_capture_delay = 0; |
+ current_settings.interlaced = false; |
+ if (width > 320) { // VGA |
+ current_settings.width = 640; |
+ current_settings.height = 480; |
+ current_settings.frame_rate = 30; |
+ } else { // QVGA |
+ current_settings.width = 320; |
+ current_settings.height = 240; |
+ current_settings.frame_rate = 30; |
+ } |
- state_ = kAllocated; |
- observer_->OnFrameInfo(current_settings); |
+ size_t fake_frame_size = |
+ current_settings.width * current_settings.height * 3 / 2; |
+ fake_frame_.reset(new uint8[fake_frame_size]); |
+ memset(fake_frame_.get(), 0, fake_frame_size); |
+ frame_size_ = fake_frame_size; |
+ frame_width_ = current_settings.width; |
+ frame_height_ = current_settings.height; |
+ observer_->OnFrameInfo(current_settings); |
+ } |
} |
void FakeVideoCaptureDevice::Start() { |
@@ -130,6 +174,7 @@ void FakeVideoCaptureDevice::DeAllocate() { |
} |
capture_thread_.Stop(); |
state_ = kIdle; |
+ observer_ = NULL; |
} |
const VideoCaptureDevice::Name& FakeVideoCaptureDevice::device_name() { |
@@ -143,57 +188,70 @@ void FakeVideoCaptureDevice::OnCaptureTask() { |
memset(fake_frame_.get(), 0, frame_size_); |
Ami GONE FROM CHROMIUM
2013/06/18 18:35:55
only used in the not-encoding case
sheu
2013/08/22 22:40:31
Also used for encoding. Changed up a bit here.
|
- SkBitmap bitmap; |
- bitmap.setConfig(SkBitmap::kA8_Config, frame_width_, frame_height_, |
- frame_width_); |
- bitmap.setPixels(fake_frame_.get()); |
- |
- SkCanvas canvas(bitmap); |
- |
- // Draw a sweeping circle to show an animation. |
- int radius = std::min(frame_width_, frame_height_) / 4; |
- SkRect rect = SkRect::MakeXYWH( |
- frame_width_ / 2 - radius, frame_height_ / 2 - radius, |
- 2 * radius, 2 * radius); |
- |
- SkPaint paint; |
- paint.setStyle(SkPaint::kFill_Style); |
- |
- // Only Y plane is being drawn and this gives 50% grey on the Y |
- // plane. The result is a light green color in RGB space. |
- paint.setAlpha(128); |
- |
- int end_angle = (frame_count_ % kFakeCaptureBeepCycle * 360) / |
- kFakeCaptureBeepCycle; |
- if (!end_angle) |
- end_angle = 360; |
- canvas.drawArc(rect, 0, end_angle, true, paint); |
- |
- // Draw current time. |
- int elapsed_ms = kFakeCaptureTimeoutMs * frame_count_; |
- int milliseconds = elapsed_ms % 1000; |
- int seconds = (elapsed_ms / 1000) % 60; |
- int minutes = (elapsed_ms / 1000 / 60) % 60; |
- int hours = (elapsed_ms / 1000 / 60 / 60) % 60; |
- |
- std::string time_string = |
- base::StringPrintf("%d:%02d:%02d:%03d %d", hours, minutes, |
- seconds, milliseconds, frame_count_); |
- canvas.scale(3, 3); |
- canvas.drawText(time_string.data(), time_string.length(), 30, 20, |
- paint); |
- |
- if (frame_count_ % kFakeCaptureBeepCycle == 0) { |
- // Generate a synchronized beep sound if there is one audio input |
- // stream created. |
- FakeAudioInputStream::BeepOnce(); |
- } |
- |
- frame_count_++; |
- |
- // Give the captured frame to the observer. |
- observer_->OnIncomingCapturedFrame( |
- fake_frame_.get(), frame_size_, base::Time::Now(), 0, false, false); |
+ if (encoded_capture_) { |
+ // Just return empty frames. |
+ scoped_refptr<media::EncodedBitstreamBuffer> buffer = |
+ observer_->ReserveOutputEncodedBitstreamBuffer(); |
+ if (buffer) { |
+ observer_->OnIncomingCapturedEncodedBitstreamBuffer( |
+ buffer, |
+ 0, |
+ base::Time::Now()); |
+ } |
+ } else { |
+ SkBitmap bitmap; |
+ bitmap.setConfig(SkBitmap::kA8_Config, frame_width_, frame_height_, |
+ frame_width_); |
+ bitmap.setPixels(fake_frame_.get()); |
+ |
+ SkCanvas canvas(bitmap); |
+ |
+ // Draw a sweeping circle to show an animation. |
+ int radius = std::min(frame_width_, frame_height_) / 4; |
+ SkRect rect = SkRect::MakeXYWH( |
+ frame_width_ / 2 - radius, frame_height_ / 2 - radius, |
+ 2 * radius, 2 * radius); |
+ |
+ SkPaint paint; |
+ paint.setStyle(SkPaint::kFill_Style); |
+ |
+ // Only Y plane is being drawn and this gives 50% grey on the Y |
+ // plane. The result is a light green color in RGB space. |
+ paint.setAlpha(128); |
+ |
+ int end_angle = (frame_count_ % kFakeCaptureBeepCycle * 360) / |
+ kFakeCaptureBeepCycle; |
+ if (!end_angle) |
+ end_angle = 360; |
+ canvas.drawArc(rect, 0, end_angle, true, paint); |
+ |
+ // Draw current time. |
+ int elapsed_ms = kFakeCaptureTimeoutMs * frame_count_; |
+ int milliseconds = elapsed_ms % 1000; |
+ int seconds = (elapsed_ms / 1000) % 60; |
+ int minutes = (elapsed_ms / 1000 / 60) % 60; |
+ int hours = (elapsed_ms / 1000 / 60 / 60) % 60; |
+ |
+ std::string time_string = |
+ base::StringPrintf("%d:%02d:%02d:%03d %d", hours, minutes, |
+ seconds, milliseconds, frame_count_); |
+ canvas.scale(3, 3); |
+ canvas.drawText(time_string.data(), time_string.length(), 30, 20, |
+ paint); |
+ |
+ if (frame_count_ % kFakeCaptureBeepCycle == 0) { |
+ // Generate a synchronized beep sound if there is one audio input |
+ // stream created. |
+ FakeAudioInputStream::BeepOnce(); |
+ } |
+ |
+ frame_count_++; |
+ |
+ // Give the captured frame to the observer. |
+ observer_->OnIncomingCapturedFrame( |
+ fake_frame_.get(), frame_size_, base::Time::Now(), 0, false, false); |
+ } |
+ |
// Reschedule next CaptureTask. |
capture_thread_.message_loop()->PostDelayedTask( |
FROM_HERE, |