| Index: webrtc/media/base/videocapturer.cc
|
| diff --git a/webrtc/media/base/videocapturer.cc b/webrtc/media/base/videocapturer.cc
|
| index 1d81d49eb8ac23cf3c7df727d7d2a2b954b2bf97..c3407604681c604fbf944e94ad376f2b8ffaa358 100644
|
| --- a/webrtc/media/base/videocapturer.cc
|
| +++ b/webrtc/media/base/videocapturer.cc
|
| @@ -18,7 +18,9 @@
|
| #include "webrtc/base/common.h"
|
| #include "webrtc/base/logging.h"
|
| #include "webrtc/base/systeminfo.h"
|
| +#include "webrtc/media/base/videoframefactory.h"
|
| #include "webrtc/media/engine/webrtcvideoframe.h"
|
| +#include "webrtc/media/engine/webrtcvideoframefactory.h"
|
|
|
| namespace cricket {
|
|
|
| @@ -30,6 +32,29 @@
|
| #endif
|
|
|
| } // namespace
|
| +
|
| +/////////////////////////////////////////////////////////////////////
|
| +// Implementation of struct CapturedFrame
|
| +/////////////////////////////////////////////////////////////////////
|
| +CapturedFrame::CapturedFrame()
|
| + : width(0),
|
| + height(0),
|
| + fourcc(0),
|
| + pixel_width(0),
|
| + pixel_height(0),
|
| + time_stamp(0),
|
| + data_size(0),
|
| + rotation(webrtc::kVideoRotation_0),
|
| + data(NULL) {}
|
| +
|
| +// TODO(fbarchard): Remove this function once lmimediaengine stops using it.
|
| +bool CapturedFrame::GetDataSize(uint32_t* size) const {
|
| + if (!size || data_size == CapturedFrame::kUnknownDataSize) {
|
| + return false;
|
| + }
|
| + *size = data_size;
|
| + return true;
|
| +}
|
|
|
| /////////////////////////////////////////////////////////////////////
|
| // Implementation of class VideoCapturer
|
| @@ -42,9 +67,16 @@
|
| void VideoCapturer::Construct() {
|
| enable_camera_list_ = false;
|
| capture_state_ = CS_STOPPED;
|
| + SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured);
|
| scaled_width_ = 0;
|
| scaled_height_ = 0;
|
| enable_video_adapter_ = true;
|
| + // 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());
|
| }
|
|
|
| const std::vector<VideoFormat>* VideoCapturer::GetSupportedFormats() const {
|
| @@ -120,6 +152,29 @@
|
| UpdateFilteredSupportedFormats();
|
| }
|
|
|
| +std::string VideoCapturer::ToString(const CapturedFrame* captured_frame) const {
|
| + std::string fourcc_name = GetFourccName(captured_frame->fourcc) + " ";
|
| + for (std::string::const_iterator i = fourcc_name.begin();
|
| + i < fourcc_name.end(); ++i) {
|
| + // Test character is printable; Avoid isprint() which asserts on negatives.
|
| + if (*i < 32 || *i >= 127) {
|
| + fourcc_name = "";
|
| + break;
|
| + }
|
| + }
|
| +
|
| + std::ostringstream ss;
|
| + ss << fourcc_name << captured_frame->width << "x" << captured_frame->height;
|
| + return ss.str();
|
| +}
|
| +
|
| +void VideoCapturer::set_frame_factory(VideoFrameFactory* frame_factory) {
|
| + frame_factory_.reset(frame_factory);
|
| + if (frame_factory) {
|
| + frame_factory->SetApplyRotation(apply_rotation_);
|
| + }
|
| +}
|
| +
|
| bool VideoCapturer::GetInputSize(int* width, int* height) {
|
| rtc::CritScope cs(&frame_stats_crit_);
|
| if (!input_size_valid_) {
|
| @@ -149,6 +204,9 @@
|
| 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_);
|
| + }
|
|
|
| if (video_adapter()) {
|
| video_adapter()->OnResolutionRequest(wants.max_pixel_count,
|
| @@ -196,31 +254,54 @@
|
| return true;
|
| }
|
|
|
| +void VideoCapturer::OnFrameCaptured(VideoCapturer*,
|
| + const CapturedFrame* captured_frame) {
|
| + int out_width;
|
| + int out_height;
|
| + int crop_width;
|
| + int crop_height;
|
| + int crop_x;
|
| + int crop_y;
|
| +
|
| + // TODO(nisse): We don't do timestamp translation on this input
|
| + // path. It seems straight-forward to enable translation, but that
|
| + // breaks the WebRtcVideoEngine2Test.PropagatesInputFrameTimestamp
|
| + // test. Probably not worth the effort to fix, instead, try to
|
| + // delete or refactor all code using VideoFrameFactory and
|
| + // SignalCapturedFrame.
|
| + if (!AdaptFrame(captured_frame->width, captured_frame->height,
|
| + captured_frame->time_stamp / rtc::kNumNanosecsPerMicrosec,
|
| + 0,
|
| + &out_width, &out_height,
|
| + &crop_width, &crop_height, &crop_x, &crop_y, nullptr)) {
|
| + return;
|
| + }
|
| +
|
| + if (!frame_factory_) {
|
| + LOG(LS_ERROR) << "No video frame factory.";
|
| + return;
|
| + }
|
| +
|
| + // TODO(nisse): Reorganize frame factory methods. crop_x and crop_y
|
| + // are ignored for now.
|
| + std::unique_ptr<VideoFrame> adapted_frame(frame_factory_->CreateAliasedFrame(
|
| + captured_frame, crop_width, crop_height, out_width, out_height));
|
| +
|
| + if (!adapted_frame) {
|
| + // TODO(fbarchard): LOG more information about captured frame attributes.
|
| + LOG(LS_ERROR) << "Couldn't convert to I420! "
|
| + << "From " << ToString(captured_frame) << " To "
|
| + << out_width << " x " << out_height;
|
| + return;
|
| + }
|
| +
|
| + OnFrame(*adapted_frame, captured_frame->width, captured_frame->height);
|
| +}
|
| +
|
| void VideoCapturer::OnFrame(const VideoFrame& frame,
|
| int orig_width,
|
| int orig_height) {
|
| - // For a child class which implements rotation itself, we should
|
| - // always have apply_rotation_ == false or frame.rotation() == 0.
|
| - // Except possibly during races where apply_rotation_ is changed
|
| - // mid-stream.
|
| - if (apply_rotation_ && frame.rotation() != webrtc::kVideoRotation_0) {
|
| - rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
|
| - frame.video_frame_buffer());
|
| - if (buffer->native_handle()) {
|
| - // Sources producing native frames must handle apply_rotation
|
| - // themselves. But even if they do, we may occasionally end up
|
| - // in this case, for frames in flight at the time
|
| - // applied_rotation is set to true. In that case, we just drop
|
| - // the frame.
|
| - LOG(LS_WARNING) << "Native frame requiring rotation. Discarding.";
|
| - return;
|
| - }
|
| - broadcaster_.OnFrame(WebRtcVideoFrame(
|
| - webrtc::I420Buffer::Rotate(buffer, frame.rotation()),
|
| - webrtc::kVideoRotation_0, frame.timestamp_us()));
|
| - } else {
|
| - broadcaster_.OnFrame(frame);
|
| - }
|
| + broadcaster_.OnFrame(frame);
|
| UpdateInputSize(orig_width, orig_height);
|
| }
|
|
|
|
|