Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Unified Diff: webrtc/media/base/videocapturer.cc

Issue 1740963002: Revert of Removed unused cricket::VideoCapturer methods (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/media/base/videocapturer.h ('k') | webrtc/media/base/videocapturer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/media/base/videocapturer.cc
diff --git a/webrtc/media/base/videocapturer.cc b/webrtc/media/base/videocapturer.cc
index cdaf8ba0c21f1f7f1c10e32af629b61e7b44f75c..2d6a15e544046e3ee768ae7b39e4c8a18251cca0 100644
--- a/webrtc/media/base/videocapturer.cc
+++ b/webrtc/media/base/videocapturer.cc
@@ -19,18 +19,34 @@
#include "webrtc/base/logging.h"
#include "webrtc/base/systeminfo.h"
#include "webrtc/media/base/videoframefactory.h"
+
+#if defined(HAVE_WEBRTC_VIDEO)
#include "webrtc/media/engine/webrtcvideoframe.h"
#include "webrtc/media/engine/webrtcvideoframefactory.h"
+#endif // HAVE_WEBRTC_VIDEO
namespace cricket {
namespace {
+
+// TODO(thorcarpenter): This is a BIG hack to flush the system with black
+// frames. Frontends should coordinate to update the video state of a muted
+// user. When all frontends to this consider removing the black frame business.
+const int kNumBlackFramesOnMute = 30;
+
+// MessageHandler constants.
+enum {
+ MSG_DO_PAUSE = 0,
+ MSG_DO_UNPAUSE,
+ MSG_STATE_CHANGE
+};
static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63);
#ifdef WEBRTC_LINUX
static const int kYU12Penalty = 16; // Needs to be higher than MJPG index.
#endif
static const int kDefaultScreencastFps = 5;
+typedef rtc::TypedMessageData<CaptureState> StateChangeParams;
// Limit stats data collections to ~20 seconds of 30fps data before dropping
// old data in case stats aren't reset for long periods of time.
@@ -65,16 +81,23 @@
// Implementation of class VideoCapturer
/////////////////////////////////////////////////////////////////////
VideoCapturer::VideoCapturer()
- : adapt_frame_drops_data_(kMaxAccumulatorSize),
+ : thread_(rtc::Thread::Current()),
+ adapt_frame_drops_data_(kMaxAccumulatorSize),
frame_time_data_(kMaxAccumulatorSize),
apply_rotation_(true) {
- thread_checker_.DetachFromThread();
Construct();
}
+VideoCapturer::VideoCapturer(rtc::Thread* thread)
+ : thread_(thread),
+ adapt_frame_drops_data_(kMaxAccumulatorSize),
+ frame_time_data_(kMaxAccumulatorSize),
+ apply_rotation_(true) {
+ Construct();
+}
+
void VideoCapturer::Construct() {
- ratio_w_ = 0;
- ratio_h_ = 0;
+ ClearAspectRatio();
enable_camera_list_ = false;
square_pixel_aspect_ratio_ = false;
capture_state_ = CS_STOPPED;
@@ -85,15 +108,19 @@
SignalVideoFrame.connect(this, &VideoCapturer::OnFrame);
scaled_width_ = 0;
scaled_height_ = 0;
+ muted_ = false;
+ black_frame_count_down_ = kNumBlackFramesOnMute;
enable_video_adapter_ = true;
adapt_frame_drops_ = 0;
previous_frame_time_ = 0.0;
+#ifdef HAVE_WEBRTC_VIDEO
// There are lots of video capturers out there that don't call
// set_frame_factory. We can either go change all of them, or we
// can set this default.
// TODO(pthatcher): Remove this hack and require the frame factory
// to be passed in the constructor.
set_frame_factory(new WebRtcVideoFrameFactory());
+#endif
}
const std::vector<VideoFormat>* VideoCapturer::GetSupportedFormats() const {
@@ -101,7 +128,6 @@
}
bool VideoCapturer::StartCapturing(const VideoFormat& capture_format) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
previous_frame_time_ = frame_length_time_reporter_.TimerNow();
CaptureState result = Start(capture_format);
const bool success = (result == CS_RUNNING) || (result == CS_STARTING);
@@ -114,18 +140,104 @@
return true;
}
+void VideoCapturer::UpdateAspectRatio(int ratio_w, int ratio_h) {
+ if (ratio_w == 0 || ratio_h == 0) {
+ LOG(LS_WARNING) << "UpdateAspectRatio ignored invalid ratio: "
+ << ratio_w << "x" << ratio_h;
+ return;
+ }
+ ratio_w_ = ratio_w;
+ ratio_h_ = ratio_h;
+}
+
+void VideoCapturer::ClearAspectRatio() {
+ ratio_w_ = 0;
+ ratio_h_ = 0;
+}
+
+// Override this to have more control of how your device is started/stopped.
+bool VideoCapturer::Pause(bool pause) {
+ if (pause) {
+ if (capture_state() == CS_PAUSED) {
+ return true;
+ }
+ bool is_running = capture_state() == CS_STARTING ||
+ capture_state() == CS_RUNNING;
+ if (!is_running) {
+ LOG(LS_ERROR) << "Cannot pause a stopped camera.";
+ return false;
+ }
+ LOG(LS_INFO) << "Pausing a camera.";
+ rtc::scoped_ptr<VideoFormat> capture_format_when_paused(
+ capture_format_ ? new VideoFormat(*capture_format_) : NULL);
+ Stop();
+ SetCaptureState(CS_PAUSED);
+ // If you override this function be sure to restore the capture format
+ // after calling Stop().
+ SetCaptureFormat(capture_format_when_paused.get());
+ } else { // Unpause.
+ if (capture_state() != CS_PAUSED) {
+ LOG(LS_WARNING) << "Cannot unpause a camera that hasn't been paused.";
+ return false;
+ }
+ if (!capture_format_) {
+ LOG(LS_ERROR) << "Missing capture_format_, cannot unpause a camera.";
+ return false;
+ }
+ if (muted_) {
+ LOG(LS_WARNING) << "Camera cannot be unpaused while muted.";
+ return false;
+ }
+ LOG(LS_INFO) << "Unpausing a camera.";
+ if (!Start(*capture_format_)) {
+ LOG(LS_ERROR) << "Camera failed to start when unpausing.";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool VideoCapturer::Restart(const VideoFormat& capture_format) {
+ if (!IsRunning()) {
+ return StartCapturing(capture_format);
+ }
+
+ if (GetCaptureFormat() != NULL && *GetCaptureFormat() == capture_format) {
+ // The reqested format is the same; nothing to do.
+ return true;
+ }
+
+ Stop();
+ return StartCapturing(capture_format);
+}
+
+bool VideoCapturer::MuteToBlackThenPause(bool muted) {
+ if (muted == IsMuted()) {
+ return true;
+ }
+
+ LOG(LS_INFO) << (muted ? "Muting" : "Unmuting") << " this video capturer.";
+ muted_ = muted; // Do this before calling Pause().
+ if (muted) {
+ // Reset black frame count down.
+ black_frame_count_down_ = kNumBlackFramesOnMute;
+ // Following frames will be overritten with black, then the camera will be
+ // paused.
+ return true;
+ }
+ // Start the camera.
+ thread_->Clear(this, MSG_DO_PAUSE);
+ return Pause(false);
+}
+
void VideoCapturer::SetSupportedFormats(
const std::vector<VideoFormat>& formats) {
- // This method is OK to call during initialization on a separate thread.
- RTC_DCHECK(capture_state_ == CS_STOPPED ||
- thread_checker_.CalledOnValidThread());
supported_formats_ = formats;
UpdateFilteredSupportedFormats();
}
bool VideoCapturer::GetBestCaptureFormat(const VideoFormat& format,
VideoFormat* best_format) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
// TODO(fbarchard): Directly support max_format.
UpdateFilteredSupportedFormats();
const std::vector<VideoFormat>* supported_formats = GetSupportedFormats();
@@ -164,7 +276,6 @@
}
void VideoCapturer::ConstrainSupportedFormats(const VideoFormat& max_format) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
max_format_.reset(new VideoFormat(max_format));
LOG(LS_VERBOSE) << " ConstrainSupportedFormats " << max_format.ToString();
UpdateFilteredSupportedFormats();
@@ -208,20 +319,17 @@
void VideoCapturer::RemoveSink(
rtc::VideoSinkInterface<cricket::VideoFrame>* sink) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
broadcaster_.RemoveSink(sink);
}
void VideoCapturer::AddOrUpdateSink(
rtc::VideoSinkInterface<cricket::VideoFrame>* sink,
const rtc::VideoSinkWants& wants) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
broadcaster_.AddOrUpdateSink(sink, wants);
OnSinkWantsChanged(broadcaster_.wants());
}
void VideoCapturer::OnSinkWantsChanged(const rtc::VideoSinkWants& wants) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
apply_rotation_ = wants.rotation_applied;
if (frame_factory_) {
frame_factory_->SetApplyRotation(apply_rotation_);
@@ -230,28 +338,37 @@
void VideoCapturer::OnFrameCaptured(VideoCapturer*,
const CapturedFrame* captured_frame) {
+ if (muted_) {
+ if (black_frame_count_down_ == 0) {
+ thread_->Post(this, MSG_DO_PAUSE, NULL);
+ } else {
+ --black_frame_count_down_;
+ }
+ }
+
if (!broadcaster_.frame_wanted()) {
return;
}
// Use a temporary buffer to scale
rtc::scoped_ptr<uint8_t[]> scale_buffer;
+
if (IsScreencast()) {
int scaled_width, scaled_height;
- int desired_screencast_fps =
- capture_format_.get()
- ? VideoFormat::IntervalToFps(capture_format_->interval)
- : kDefaultScreencastFps;
+ int desired_screencast_fps = capture_format_.get() ?
+ VideoFormat::IntervalToFps(capture_format_->interval) :
+ kDefaultScreencastFps;
ComputeScale(captured_frame->width, captured_frame->height,
desired_screencast_fps, &scaled_width, &scaled_height);
if (FOURCC_ARGB == captured_frame->fourcc &&
(scaled_width != captured_frame->width ||
- scaled_height != captured_frame->height)) {
+ scaled_height != captured_frame->height)) {
if (scaled_width != scaled_width_ || scaled_height != scaled_height_) {
- LOG(LS_INFO) << "Scaling Screencast from " << captured_frame->width
- << "x" << captured_frame->height << " to " << scaled_width
- << "x" << scaled_height;
+ LOG(LS_INFO) << "Scaling Screencast from "
+ << captured_frame->width << "x"
+ << captured_frame->height << " to "
+ << scaled_width << "x" << scaled_height;
scaled_width_ = scaled_width;
scaled_height_ = scaled_height;
}
@@ -280,6 +397,7 @@
const int kArgbBpp = 4;
// TODO(fbarchard): Make a helper function to adjust pixels to square.
// TODO(fbarchard): Hook up experiment to scaling.
+ // TODO(fbarchard): Avoid scale and convert if muted.
// Temporary buffer is scoped here so it will persist until i420_frame.Init()
// makes a copy of the frame, converting to I420.
rtc::scoped_ptr<uint8_t[]> temp_buffer;
@@ -407,6 +525,10 @@
return;
}
+ if (muted_) {
+ // TODO(pthatcher): Use frame_factory_->CreateBlackFrame() instead.
+ adapted_frame->SetToBlack();
+ }
SignalVideoFrame(this, adapted_frame.get());
UpdateStats(captured_frame);
}
@@ -416,13 +538,35 @@
}
void VideoCapturer::SetCaptureState(CaptureState state) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
if (state == capture_state_) {
// Don't trigger a state changed callback if the state hasn't changed.
return;
}
+ StateChangeParams* state_params = new StateChangeParams(state);
capture_state_ = state;
- SignalStateChange(this, capture_state_);
+ thread_->Post(this, MSG_STATE_CHANGE, state_params);
+}
+
+void VideoCapturer::OnMessage(rtc::Message* message) {
+ switch (message->message_id) {
+ case MSG_STATE_CHANGE: {
+ rtc::scoped_ptr<StateChangeParams> p(
+ static_cast<StateChangeParams*>(message->pdata));
+ SignalStateChange(this, p->data());
+ break;
+ }
+ case MSG_DO_PAUSE: {
+ Pause(true);
+ break;
+ }
+ case MSG_DO_UNPAUSE: {
+ Pause(false);
+ break;
+ }
+ default: {
+ ASSERT(false);
+ }
+ }
}
// Get the distance between the supported and desired formats.
@@ -434,7 +578,6 @@
// otherwise, we use preference.
int64_t VideoCapturer::GetFormatDistance(const VideoFormat& desired,
const VideoFormat& supported) {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
int64_t distance = kMaxDistance;
// Check fourcc.
@@ -545,7 +688,6 @@
}
bool VideoCapturer::ShouldFilterFormat(const VideoFormat& format) const {
- RTC_DCHECK(thread_checker_.CalledOnValidThread());
if (!enable_camera_list_) {
return false;
}
« no previous file with comments | « webrtc/media/base/videocapturer.h ('k') | webrtc/media/base/videocapturer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698