diff options
author | perkj <perkj@webrtc.org> | 2015-11-30 22:15:45 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-01 06:15:53 +0000 |
commit | 14f4144a82558ec4da2d4962ef02b23f44967b6a (patch) | |
tree | ec00a9cea4e74167221d7690b79b00ef24998cf0 /webrtc | |
parent | ee69ed505b6ba4a9dbb47cc927aaf220d661fa06 (diff) | |
download | webrtc-14f4144a82558ec4da2d4962ef02b23f44967b6a.tar.gz |
Add helper KeepRefUntilDone.
The callback keeps a reference to an object until the callback goes out of scope.
Review URL: https://codereview.webrtc.org/1487493002
Cr-Commit-Position: refs/heads/master@{#10847}
Diffstat (limited to 'webrtc')
-rw-r--r-- | webrtc/base/callback_unittest.cc | 59 | ||||
-rw-r--r-- | webrtc/base/keep_ref_until_done.h | 43 | ||||
-rw-r--r-- | webrtc/common_video/video_frame_buffer.cc | 10 | ||||
-rw-r--r-- | webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc | 18 |
4 files changed, 107 insertions, 23 deletions
diff --git a/webrtc/base/callback_unittest.cc b/webrtc/base/callback_unittest.cc index 66c939140e..db294cd96e 100644 --- a/webrtc/base/callback_unittest.cc +++ b/webrtc/base/callback_unittest.cc @@ -11,6 +11,8 @@ #include "webrtc/base/bind.h" #include "webrtc/base/callback.h" #include "webrtc/base/gunit.h" +#include "webrtc/base/keep_ref_until_done.h" +#include "webrtc/base/refcount.h" namespace rtc { @@ -26,6 +28,21 @@ struct BindTester { int b(int x) const { return x * x; } }; +class RefCountedBindTester : public RefCountInterface { + public: + RefCountedBindTester() : count_(0) {} + int AddRef() const override { + return ++count_; + } + int Release() const { + return --count_; + } + int RefCount() const { return count_; } + + private: + mutable int count_; +}; + } // namespace TEST(CallbackTest, VoidReturn) { @@ -78,4 +95,46 @@ TEST(CallbackTest, WithBind) { EXPECT_EQ(25, cb1()); } +TEST(KeepRefUntilDoneTest, simple) { + RefCountedBindTester t; + EXPECT_EQ(0, t.RefCount()); + { + Callback0<void> cb = KeepRefUntilDone(&t); + EXPECT_EQ(1, t.RefCount()); + cb(); + EXPECT_EQ(1, t.RefCount()); + cb(); + EXPECT_EQ(1, t.RefCount()); + } + EXPECT_EQ(0, t.RefCount()); +} + +TEST(KeepRefUntilDoneTest, copy) { + RefCountedBindTester t; + EXPECT_EQ(0, t.RefCount()); + Callback0<void> cb2; + { + Callback0<void> cb = KeepRefUntilDone(&t); + EXPECT_EQ(1, t.RefCount()); + cb2 = cb; + } + EXPECT_EQ(1, t.RefCount()); + cb2 = Callback0<void>(); + EXPECT_EQ(0, t.RefCount()); +} + +TEST(KeepRefUntilDoneTest, scopedref) { + RefCountedBindTester t; + EXPECT_EQ(0, t.RefCount()); + { + scoped_refptr<RefCountedBindTester> t_scoped_ref(&t); + Callback0<void> cb = KeepRefUntilDone(t_scoped_ref); + t_scoped_ref = nullptr; + EXPECT_EQ(1, t.RefCount()); + cb(); + EXPECT_EQ(1, t.RefCount()); + } + EXPECT_EQ(0, t.RefCount()); +} + } // namespace rtc diff --git a/webrtc/base/keep_ref_until_done.h b/webrtc/base/keep_ref_until_done.h new file mode 100644 index 0000000000..269e1c8657 --- /dev/null +++ b/webrtc/base/keep_ref_until_done.h @@ -0,0 +1,43 @@ +/* + * Copyright 2015 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_BASE_KEEP_REF_UNTIL_DONE_H_ +#define WEBRTC_BASE_KEEP_REF_UNTIL_DONE_H_ + +#include "webrtc/base/bind.h" +#include "webrtc/base/callback.h" +#include "webrtc/base/refcount.h" +#include "webrtc/base/scoped_ref_ptr.h" + +namespace rtc { + +namespace impl { +template <class T> +static inline void DoNothing(const scoped_refptr<T>& object) {} +} // namespace impl + +// KeepRefUntilDone keeps a reference to |object| until the returned +// callback goes out of scope. If the returned callback is copied, the +// reference will be released when the last callback goes out of scope. +template <class ObjectT> +static inline Callback0<void> KeepRefUntilDone(ObjectT* object) { + return rtc::Bind(&impl::DoNothing<ObjectT>, scoped_refptr<ObjectT>(object)); +} + +template <class ObjectT> +static inline Callback0<void> KeepRefUntilDone( + const scoped_refptr<ObjectT>& object) { + return rtc::Bind(&impl::DoNothing<ObjectT>, object); +} + +} // namespace rtc + + +#endif // WEBRTC_BASE_KEEP_REF_UNTIL_DONE_H_ diff --git a/webrtc/common_video/video_frame_buffer.cc b/webrtc/common_video/video_frame_buffer.cc index fff90defbd..492bc49587 100644 --- a/webrtc/common_video/video_frame_buffer.cc +++ b/webrtc/common_video/video_frame_buffer.cc @@ -10,19 +10,13 @@ #include "webrtc/common_video/include/video_frame_buffer.h" -#include "webrtc/base/bind.h" #include "webrtc/base/checks.h" +#include "webrtc/base/keep_ref_until_done.h" // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD. static const int kBufferAlignment = 64; namespace webrtc { -namespace { - -// Used in rtc::Bind to keep a buffer alive until destructor is called. -static void NoLongerUsedCallback(rtc::scoped_refptr<VideoFrameBuffer> dummy) {} - -} // anonymous namespace uint8_t* VideoFrameBuffer::MutableData(PlaneType type) { RTC_NOTREACHED(); @@ -238,7 +232,7 @@ rtc::scoped_refptr<VideoFrameBuffer> ShallowCenterCrop( y_plane, buffer->stride(kYPlane), u_plane, buffer->stride(kUPlane), v_plane, buffer->stride(kVPlane), - rtc::Bind(&NoLongerUsedCallback, buffer)); + rtc::KeepRefUntilDone(buffer)); } } // namespace webrtc diff --git a/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc b/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc index eba8dfb6b1..6fdd676ab1 100644 --- a/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -21,8 +21,8 @@ #include "vpx/vp8cx.h" #include "vpx/vp8dx.h" -#include "webrtc/base/bind.h" #include "webrtc/base/checks.h" +#include "webrtc/base/keep_ref_until_done.h" #include "webrtc/base/logging.h" #include "webrtc/base/trace_event.h" #include "webrtc/common.h" @@ -31,16 +31,6 @@ #include "webrtc/modules/video_coding/codecs/vp9/screenshare_layers.h" #include "webrtc/system_wrappers/include/tick_util.h" -namespace { - -// VP9DecoderImpl::ReturnFrame helper function used with WrappedI420Buffer. -static void WrappedI420BufferNoLongerUsedCb( - webrtc::Vp9FrameBufferPool::Vp9FrameBuffer* img_buffer) { - img_buffer->Release(); -} - -} // anonymous namespace - namespace webrtc { // Only positive speeds, range for real-time coding currently is: 5 - 8. @@ -933,12 +923,10 @@ int VP9DecoderImpl::ReturnFrame(const vpx_image_t* img, uint32_t timestamp) { } // This buffer contains all of |img|'s image data, a reference counted - // Vp9FrameBuffer. Performing AddRef/Release ensures it is not released and - // recycled during use (libvpx is done with the buffers after a few + // Vp9FrameBuffer. (libvpx is done with the buffers after a few // vpx_codec_decode calls or vpx_codec_destroy). Vp9FrameBufferPool::Vp9FrameBuffer* img_buffer = static_cast<Vp9FrameBufferPool::Vp9FrameBuffer*>(img->fb_priv); - img_buffer->AddRef(); // The buffer can be used directly by the VideoFrame (without copy) by // using a WrappedI420Buffer. rtc::scoped_refptr<WrappedI420Buffer> img_wrapped_buffer( @@ -950,7 +938,7 @@ int VP9DecoderImpl::ReturnFrame(const vpx_image_t* img, uint32_t timestamp) { // WrappedI420Buffer's mechanism for allowing the release of its frame // buffer is through a callback function. This is where we should // release |img_buffer|. - rtc::Bind(&WrappedI420BufferNoLongerUsedCb, img_buffer))); + rtc::KeepRefUntilDone(img_buffer))); VideoFrame decoded_image; decoded_image.set_video_frame_buffer(img_wrapped_buffer); |