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

Unified Diff: talk/app/webrtc/androidvideocapturer.cc

Issue 1307973002: AndroidVideoCapturerJni: Fix threading issues (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressing tommi@s comments Created 5 years, 4 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 | « talk/app/webrtc/androidvideocapturer.h ('k') | talk/app/webrtc/java/jni/androidvideocapturer_jni.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/app/webrtc/androidvideocapturer.cc
diff --git a/talk/app/webrtc/androidvideocapturer.cc b/talk/app/webrtc/androidvideocapturer.cc
index 8901188492166fd66a6e7f5b5dab721802a4bba1..e2270228227750027ab5e59e3438a63af786c795 100644
--- a/talk/app/webrtc/androidvideocapturer.cc
+++ b/talk/app/webrtc/androidvideocapturer.cc
@@ -27,69 +27,50 @@
#include "talk/app/webrtc/androidvideocapturer.h"
#include "talk/media/webrtc/webrtcvideoframe.h"
-#include "webrtc/base/bind.h"
-#include "webrtc/base/callback.h"
#include "webrtc/base/common.h"
#include "webrtc/base/json.h"
#include "webrtc/base/timeutils.h"
-#include "webrtc/base/thread.h"
-#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
namespace webrtc {
-using cricket::WebRtcVideoFrame;
-using rtc::scoped_ptr;
-using rtc::scoped_refptr;
-
-// An implementation of cricket::VideoFrameFactory for frames that are not
-// guaranteed to outlive the created cricket::VideoFrame.
-// A frame is injected using UpdateCapturedFrame, and converted into a
-// cricket::VideoFrame with
-// CreateAliasedFrame. UpdateCapturedFrame should be called before
-// CreateAliasedFrame for every frame.
+// A hack for avoiding deep frame copies in
+// cricket::VideoCapturer.SignalFrameCaptured() using a custom FrameFactory.
+// A frame is injected using UpdateCapturedFrame(), and converted into a
+// cricket::VideoFrame with CreateAliasedFrame(). UpdateCapturedFrame() should
+// be called before CreateAliasedFrame() for every frame.
+// TODO(magjed): Add an interface cricket::VideoCapturer::OnFrameCaptured()
+// for ref counted I420 frames instead of this hack.
class AndroidVideoCapturer::FrameFactory : public cricket::VideoFrameFactory {
public:
- FrameFactory(int width,
- int height,
- const scoped_refptr<AndroidVideoCapturerDelegate>& delegate)
- : start_time_(rtc::TimeNanos()), delegate_(delegate) {
+ FrameFactory(const rtc::scoped_refptr<AndroidVideoCapturerDelegate>& delegate)
+ : start_time_(rtc::TimeNanos()), delegate_(delegate) {
// Create a CapturedFrame that only contains header information, not the
// actual pixel data.
- captured_frame_.width = width;
- captured_frame_.height = height;
captured_frame_.pixel_height = 1;
captured_frame_.pixel_width = 1;
- captured_frame_.rotation = 0;
- captured_frame_.data = NULL;
+ captured_frame_.data = nullptr;
captured_frame_.data_size = cricket::CapturedFrame::kUnknownDataSize;
captured_frame_.fourcc = static_cast<uint32>(cricket::FOURCC_ANY);
}
- void UpdateCapturedFrame(void* frame_data,
- int length,
- int width,
- int height,
- int rotation,
- int64 time_stamp_in_ns) {
- // Make sure we don't overwrite the previous frame.
- CHECK(captured_frame_.data == nullptr);
- captured_frame_.fourcc = static_cast<uint32>(cricket::FOURCC_YV12);
- captured_frame_.data = frame_data;
- captured_frame_.width = width;
- captured_frame_.height = height;
+ void UpdateCapturedFrame(
+ const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
+ int rotation,
+ int64 time_stamp_in_ns) {
+ buffer_ = buffer;
+ captured_frame_.width = buffer->width();
+ captured_frame_.height = buffer->height();
captured_frame_.elapsed_time = rtc::TimeNanos() - start_time_;
captured_frame_.time_stamp = time_stamp_in_ns;
captured_frame_.rotation = rotation;
- captured_frame_.data_size = length;
}
- void ClearCapturedFrame() const {
- captured_frame_.data = nullptr;
+ void ClearCapturedFrame() {
+ buffer_ = nullptr;
captured_frame_.width = 0;
captured_frame_.height = 0;
captured_frame_.elapsed_time = 0;
captured_frame_.time_stamp = 0;
- captured_frame_.data_size = 0;
}
const cricket::CapturedFrame* GetCapturedFrame() const {
@@ -100,64 +81,23 @@ class AndroidVideoCapturer::FrameFactory : public cricket::VideoFrameFactory {
const cricket::CapturedFrame* captured_frame,
int dst_width,
int dst_height) const override {
- // This override of CreateAliasedFrame creates a copy of the frame since
- // |captured_frame_.data| is only guaranteed to be valid during the scope
- // of |AndroidVideoCapturer::OnIncomingFrame_w|.
// Check that captured_frame is actually our frame.
CHECK(captured_frame == &captured_frame_);
- CHECK(captured_frame->data != nullptr);
-
- if (!apply_rotation_ || captured_frame->rotation == kVideoRotation_0) {
- CHECK(captured_frame->fourcc == cricket::FOURCC_YV12);
- const uint8_t* y_plane = static_cast<uint8_t*>(captured_frame_.data);
-
- // Android guarantees that the stride is a multiple of 16.
- // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFormat%28int%29
- int y_stride;
- int uv_stride;
- webrtc::Calc16ByteAlignedStride(captured_frame->width, &y_stride,
- &uv_stride);
- const uint8_t* v_plane = y_plane + y_stride * captured_frame->height;
- const uint8_t* u_plane =
- v_plane + uv_stride * webrtc::AlignInt(captured_frame->height, 2) / 2;
-
- // Create a WrappedI420Buffer and bind the |no_longer_used| callback
- // to the static method ReturnFrame. The |delegate_| is bound as an
- // argument which means that the callback will hold a reference to
- // |delegate_|.
- rtc::scoped_refptr<WrappedI420Buffer> buffer(
- new rtc::RefCountedObject<webrtc::WrappedI420Buffer>(
- dst_width, dst_height, captured_frame->width,
- captured_frame->height, y_plane, y_stride, u_plane, uv_stride,
- v_plane, uv_stride,
- rtc::Bind(&AndroidVideoCapturer::FrameFactory::ReturnFrame,
- delegate_,
- captured_frame->time_stamp)));
- cricket::VideoFrame* cricket_frame = new WebRtcVideoFrame(
- buffer, captured_frame->elapsed_time,
- captured_frame->time_stamp, captured_frame->GetRotation());
- // |cricket_frame| is now responsible for returning the frame. Clear
- // |captured_frame_| so the frame isn't returned twice.
- ClearCapturedFrame();
- return cricket_frame;
- }
-
- scoped_ptr<WebRtcVideoFrame> frame(new WebRtcVideoFrame());
- frame->Init(captured_frame, dst_width, dst_height, apply_rotation_);
- return frame.release();
- }
-
- static void ReturnFrame(scoped_refptr<AndroidVideoCapturerDelegate> delegate,
- int64 time_stamp) {
- delegate->ReturnBuffer(time_stamp);
+ rtc::scoped_ptr<cricket::VideoFrame> frame(new cricket::WebRtcVideoFrame(
+ ShallowCenterCrop(buffer_, dst_width, dst_height),
+ captured_frame->elapsed_time, captured_frame->time_stamp,
+ captured_frame->GetRotation()));
+ // Caller takes ownership.
+ // TODO(magjed): Change CreateAliasedFrame() to return a rtc::scoped_ptr.
+ return apply_rotation_ ? frame->GetCopyWithRotationApplied()->Copy()
+ : frame.release();
}
private:
uint64 start_time_;
- // |captured_frame_| is mutable as a hacky way to modify it inside
- // CreateAliasedframe().
- mutable cricket::CapturedFrame captured_frame_;
- scoped_refptr<AndroidVideoCapturerDelegate> delegate_;
+ rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer_;
+ cricket::CapturedFrame captured_frame_;
+ rtc::scoped_refptr<AndroidVideoCapturerDelegate> delegate_;
};
AndroidVideoCapturer::AndroidVideoCapturer(
@@ -202,8 +142,7 @@ cricket::CaptureState AndroidVideoCapturer::Start(
CHECK(thread_checker_.CalledOnValidThread());
CHECK(!running_);
- frame_factory_ = new AndroidVideoCapturer::FrameFactory(
- capture_format.width, capture_format.height, delegate_.get());
+ frame_factory_ = new AndroidVideoCapturer::FrameFactory(delegate_.get());
set_frame_factory(frame_factory_);
running_ = true;
@@ -252,24 +191,14 @@ void AndroidVideoCapturer::OnCapturerStarted(bool success) {
SignalStateChange(this, new_state);
}
-void AndroidVideoCapturer::OnIncomingFrame(void* frame_data,
- int length,
- int width,
- int height,
- int rotation,
- int64 time_stamp) {
+void AndroidVideoCapturer::OnIncomingFrame(
+ rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer,
+ int rotation,
+ int64 time_stamp) {
CHECK(thread_checker_.CalledOnValidThread());
- frame_factory_->UpdateCapturedFrame(frame_data, length, width, height,
- rotation, time_stamp);
+ frame_factory_->UpdateCapturedFrame(buffer, rotation, time_stamp);
SignalFrameCaptured(this, frame_factory_->GetCapturedFrame());
- if (frame_factory_->GetCapturedFrame()->data == nullptr) {
- // Ownership has been passed to a WrappedI420Buffer. Do nothing.
- } else {
- // |captured_frame_| has either been copied or dropped, return it
- // immediately.
- delegate_->ReturnBuffer(time_stamp);
- frame_factory_->ClearCapturedFrame();
- }
+ frame_factory_->ClearCapturedFrame();
}
void AndroidVideoCapturer::OnOutputFormatRequest(
« no previous file with comments | « talk/app/webrtc/androidvideocapturer.h ('k') | talk/app/webrtc/java/jni/androidvideocapturer_jni.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698