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}
This commit is contained in:
parent
ee69ed505b
commit
14f4144a82
@ -28,17 +28,13 @@
|
||||
#include "talk/app/webrtc/java/jni/native_handle_impl.h"
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/bind.h"
|
||||
#include "webrtc/base/keep_ref_until_done.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
|
||||
using rtc::scoped_refptr;
|
||||
using webrtc::NativeHandleBuffer;
|
||||
|
||||
namespace webrtc_jni {
|
||||
|
||||
namespace {
|
||||
void ScaledFrameNotInUse(scoped_refptr<NativeHandleBuffer> original) {}
|
||||
} // anonymous namespace
|
||||
|
||||
NativeHandleImpl::NativeHandleImpl(JNIEnv* jni,
|
||||
jint j_oes_texture_id,
|
||||
jfloatArray j_transform_matrix)
|
||||
@ -87,7 +83,7 @@ rtc::scoped_refptr<AndroidTextureBuffer> AndroidTextureBuffer::CropAndScale(
|
||||
// will be decreased by one.
|
||||
return new rtc::RefCountedObject<AndroidTextureBuffer>(
|
||||
dst_widht, dst_height, native_handle_,
|
||||
rtc::Bind(&ScaledFrameNotInUse, this));
|
||||
rtc::KeepRefUntilDone(this));
|
||||
}
|
||||
|
||||
} // namespace webrtc_jni
|
||||
|
||||
@ -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
|
||||
|
||||
43
webrtc/base/keep_ref_until_done.h
Normal file
43
webrtc/base/keep_ref_until_done.h
Normal file
@ -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_
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user