Revert "Convert native handles to buffers before encoding."
This reverts commit a831dc3a7d10a1fbaa258ee6b1ca6cfc7e91c5ca to unblock rolling into Chromium. BUG=4081 TBR=magjed@webrtc.org Review URL: https://webrtc-codereview.appspot.com/55549004 Cr-Commit-Position: refs/heads/master@{#9354}
This commit is contained in:
parent
14771ac6bf
commit
308d163c71
@ -654,9 +654,9 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs(
|
|||||||
int32_t callback_status = WEBRTC_VIDEO_CODEC_OK;
|
int32_t callback_status = WEBRTC_VIDEO_CODEC_OK;
|
||||||
if (use_surface_) {
|
if (use_surface_) {
|
||||||
native_handle_.SetTextureObject(surface_texture_, texture_id);
|
native_handle_.SetTextureObject(surface_texture_, texture_id);
|
||||||
VideoFrame texture_image(new rtc::RefCountedObject<JniNativeHandleBuffer>(
|
VideoFrame texture_image(&native_handle_, width, height, output_timestamp_,
|
||||||
&native_handle_, width, height),
|
0, webrtc::kVideoRotation_0,
|
||||||
output_timestamp_, 0, webrtc::kVideoRotation_0);
|
rtc::Callback0<void>());
|
||||||
texture_image.set_ntp_time_ms(output_ntp_time_ms_);
|
texture_image.set_ntp_time_ms(output_ntp_time_ms_);
|
||||||
callback_status = callback_->Decoded(texture_image);
|
callback_status = callback_->Decoded(texture_image);
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,9 +29,6 @@
|
|||||||
#ifndef TALK_APP_WEBRTC_JAVA_JNI_NATIVE_HANDLE_IMPL_H_
|
#ifndef TALK_APP_WEBRTC_JAVA_JNI_NATIVE_HANDLE_IMPL_H_
|
||||||
#define TALK_APP_WEBRTC_JAVA_JNI_NATIVE_HANDLE_IMPL_H_
|
#define TALK_APP_WEBRTC_JAVA_JNI_NATIVE_HANDLE_IMPL_H_
|
||||||
|
|
||||||
#include "webrtc/base/checks.h"
|
|
||||||
#include "webrtc/common_video/interface/video_frame_buffer.h"
|
|
||||||
|
|
||||||
namespace webrtc_jni {
|
namespace webrtc_jni {
|
||||||
|
|
||||||
// Wrapper for texture object.
|
// Wrapper for texture object.
|
||||||
@ -55,23 +52,6 @@ class NativeHandleImpl {
|
|||||||
int32_t texture_id_;
|
int32_t texture_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JniNativeHandleBuffer : public webrtc::NativeHandleBuffer {
|
|
||||||
public:
|
|
||||||
JniNativeHandleBuffer(void* native_handle, int width, int height)
|
|
||||||
: NativeHandleBuffer(native_handle, width, height) {}
|
|
||||||
|
|
||||||
// TODO(pbos): Override destructor to release native handle, at the moment the
|
|
||||||
// native handle is not released based on refcount.
|
|
||||||
|
|
||||||
private:
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override {
|
|
||||||
// TODO(pbos): Implement before using this in the encoder pipeline (or
|
|
||||||
// remove the CHECK() in VideoCapture).
|
|
||||||
RTC_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace webrtc_jni
|
} // namespace webrtc_jni
|
||||||
|
|
||||||
#endif // TALK_APP_WEBRTC_JAVA_JNI_NATIVE_HANDLE_IMPL_H_
|
#endif // TALK_APP_WEBRTC_JAVA_JNI_NATIVE_HANDLE_IMPL_H_
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "talk/media/base/videoframe_unittest.h"
|
#include "talk/media/base/videoframe_unittest.h"
|
||||||
#include "talk/media/webrtc/webrtcvideoframe.h"
|
#include "talk/media/webrtc/webrtcvideoframe.h"
|
||||||
#include "webrtc/test/fake_texture_frame.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -298,11 +297,10 @@ TEST_F(WebRtcVideoFrameTest, InitRotated90DontApplyRotation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WebRtcVideoFrameTest, TextureInitialValues) {
|
TEST_F(WebRtcVideoFrameTest, TextureInitialValues) {
|
||||||
webrtc::test::FakeNativeHandle* dummy_handle =
|
void* dummy_handle = reinterpret_cast<void*>(0x1);
|
||||||
new webrtc::test::FakeNativeHandle();
|
webrtc::TextureBuffer* buffer =
|
||||||
webrtc::NativeHandleBuffer* buffer =
|
new rtc::RefCountedObject<webrtc::TextureBuffer>(dummy_handle, 640, 480,
|
||||||
new rtc::RefCountedObject<webrtc::test::FakeNativeHandleBuffer>(
|
rtc::Callback0<void>());
|
||||||
dummy_handle, 640, 480);
|
|
||||||
cricket::WebRtcVideoFrame frame(buffer, 100, 200, webrtc::kVideoRotation_0);
|
cricket::WebRtcVideoFrame frame(buffer, 100, 200, webrtc::kVideoRotation_0);
|
||||||
EXPECT_EQ(dummy_handle, frame.GetNativeHandle());
|
EXPECT_EQ(dummy_handle, frame.GetNativeHandle());
|
||||||
EXPECT_EQ(640u, frame.GetWidth());
|
EXPECT_EQ(640u, frame.GetWidth());
|
||||||
@ -316,11 +314,10 @@ TEST_F(WebRtcVideoFrameTest, TextureInitialValues) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WebRtcVideoFrameTest, CopyTextureFrame) {
|
TEST_F(WebRtcVideoFrameTest, CopyTextureFrame) {
|
||||||
webrtc::test::FakeNativeHandle* dummy_handle =
|
void* dummy_handle = reinterpret_cast<void*>(0x1);
|
||||||
new webrtc::test::FakeNativeHandle();
|
webrtc::TextureBuffer* buffer =
|
||||||
webrtc::NativeHandleBuffer* buffer =
|
new rtc::RefCountedObject<webrtc::TextureBuffer>(dummy_handle, 640, 480,
|
||||||
new rtc::RefCountedObject<webrtc::test::FakeNativeHandleBuffer>(
|
rtc::Callback0<void>());
|
||||||
dummy_handle, 640, 480);
|
|
||||||
cricket::WebRtcVideoFrame frame1(buffer, 100, 200, webrtc::kVideoRotation_0);
|
cricket::WebRtcVideoFrame frame1(buffer, 100, 200, webrtc::kVideoRotation_0);
|
||||||
cricket::VideoFrame* frame2 = frame1.Copy();
|
cricket::VideoFrame* frame2 = frame1.Copy();
|
||||||
EXPECT_EQ(frame1.GetNativeHandle(), frame2->GetNativeHandle());
|
EXPECT_EQ(frame1.GetNativeHandle(), frame2->GetNativeHandle());
|
||||||
|
@ -40,11 +40,6 @@ class PooledI420Buffer : public webrtc::VideoFrameBuffer {
|
|||||||
}
|
}
|
||||||
void* native_handle() const override { return nullptr; }
|
void* native_handle() const override { return nullptr; }
|
||||||
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override {
|
|
||||||
RTC_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class rtc::RefCountedObject<PooledI420Buffer>;
|
friend class rtc::RefCountedObject<PooledI420Buffer>;
|
||||||
rtc::scoped_refptr<webrtc::I420Buffer> buffer_;
|
rtc::scoped_refptr<webrtc::I420Buffer> buffer_;
|
||||||
};
|
};
|
||||||
|
@ -16,16 +16,27 @@
|
|||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
#include "webrtc/base/bind.h"
|
#include "webrtc/base/bind.h"
|
||||||
#include "webrtc/base/scoped_ptr.h"
|
#include "webrtc/base/scoped_ptr.h"
|
||||||
#include "webrtc/test/fake_texture_frame.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
|
class NativeHandleImpl {
|
||||||
|
public:
|
||||||
|
NativeHandleImpl() : no_longer_needed_(false) {}
|
||||||
|
virtual ~NativeHandleImpl() {}
|
||||||
|
bool no_longer_needed() const { return no_longer_needed_; }
|
||||||
|
void SetNoLongerNeeded() { no_longer_needed_ = true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool no_longer_needed_;
|
||||||
|
};
|
||||||
|
|
||||||
bool EqualPlane(const uint8_t* data1,
|
bool EqualPlane(const uint8_t* data1,
|
||||||
const uint8_t* data2,
|
const uint8_t* data2,
|
||||||
int stride,
|
int stride,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
bool EqualFrames(const VideoFrame& frame1, const VideoFrame& frame2);
|
bool EqualFrames(const VideoFrame& frame1, const VideoFrame& frame2);
|
||||||
|
bool EqualTextureFrames(const VideoFrame& frame1, const VideoFrame& frame2);
|
||||||
int ExpectedSize(int plane_stride, int image_height, PlaneType type);
|
int ExpectedSize(int plane_stride, int image_height, PlaneType type);
|
||||||
|
|
||||||
TEST(TestVideoFrame, InitialValues) {
|
TEST(TestVideoFrame, InitialValues) {
|
||||||
@ -243,14 +254,14 @@ TEST(TestVideoFrame, FailToReuseAllocation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestVideoFrame, TextureInitialValues) {
|
TEST(TestVideoFrame, TextureInitialValues) {
|
||||||
test::FakeNativeHandle* handle = new test::FakeNativeHandle();
|
NativeHandleImpl handle;
|
||||||
VideoFrame frame = test::CreateFakeNativeHandleFrame(
|
VideoFrame frame(&handle, 640, 480, 100, 10, webrtc::kVideoRotation_0,
|
||||||
handle, 640, 480, 100, 10, webrtc::kVideoRotation_0);
|
rtc::Callback0<void>());
|
||||||
EXPECT_EQ(640, frame.width());
|
EXPECT_EQ(640, frame.width());
|
||||||
EXPECT_EQ(480, frame.height());
|
EXPECT_EQ(480, frame.height());
|
||||||
EXPECT_EQ(100u, frame.timestamp());
|
EXPECT_EQ(100u, frame.timestamp());
|
||||||
EXPECT_EQ(10, frame.render_time_ms());
|
EXPECT_EQ(10, frame.render_time_ms());
|
||||||
EXPECT_EQ(handle, frame.native_handle());
|
EXPECT_EQ(&handle, frame.native_handle());
|
||||||
|
|
||||||
frame.set_timestamp(200);
|
frame.set_timestamp(200);
|
||||||
EXPECT_EQ(200u, frame.timestamp());
|
EXPECT_EQ(200u, frame.timestamp());
|
||||||
@ -258,6 +269,17 @@ TEST(TestVideoFrame, TextureInitialValues) {
|
|||||||
EXPECT_EQ(20, frame.render_time_ms());
|
EXPECT_EQ(20, frame.render_time_ms());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestVideoFrame, NoLongerNeeded) {
|
||||||
|
NativeHandleImpl handle;
|
||||||
|
ASSERT_FALSE(handle.no_longer_needed());
|
||||||
|
VideoFrame* frame =
|
||||||
|
new VideoFrame(&handle, 640, 480, 100, 200, webrtc::kVideoRotation_0,
|
||||||
|
rtc::Bind(&NativeHandleImpl::SetNoLongerNeeded, &handle));
|
||||||
|
EXPECT_FALSE(handle.no_longer_needed());
|
||||||
|
delete frame;
|
||||||
|
EXPECT_TRUE(handle.no_longer_needed());
|
||||||
|
}
|
||||||
|
|
||||||
bool EqualPlane(const uint8_t* data1,
|
bool EqualPlane(const uint8_t* data1,
|
||||||
const uint8_t* data2,
|
const uint8_t* data2,
|
||||||
int stride,
|
int stride,
|
||||||
@ -293,6 +315,14 @@ bool EqualFrames(const VideoFrame& frame1, const VideoFrame& frame2) {
|
|||||||
frame1.stride(kVPlane), half_width, half_height);
|
frame1.stride(kVPlane), half_width, half_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EqualTextureFrames(const VideoFrame& frame1, const VideoFrame& frame2) {
|
||||||
|
return ((frame1.native_handle() == frame2.native_handle()) &&
|
||||||
|
(frame1.width() == frame2.width()) &&
|
||||||
|
(frame1.height() == frame2.height()) &&
|
||||||
|
(frame1.timestamp() == frame2.timestamp()) &&
|
||||||
|
(frame1.render_time_ms() == frame2.render_time_ms()));
|
||||||
|
}
|
||||||
|
|
||||||
int ExpectedSize(int plane_stride, int image_height, PlaneType type) {
|
int ExpectedSize(int plane_stride, int image_height, PlaneType type) {
|
||||||
if (type == kYPlane) {
|
if (type == kYPlane) {
|
||||||
return (plane_stride * image_height);
|
return (plane_stride * image_height);
|
||||||
|
@ -52,10 +52,6 @@ class VideoFrameBuffer : public rtc::RefCountInterface {
|
|||||||
// frame is backed by a texture.
|
// frame is backed by a texture.
|
||||||
virtual void* native_handle() const = 0;
|
virtual void* native_handle() const = 0;
|
||||||
|
|
||||||
// Returns a new memory-backed frame buffer converted from this buffer's
|
|
||||||
// native handle.
|
|
||||||
virtual rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~VideoFrameBuffer();
|
virtual ~VideoFrameBuffer();
|
||||||
};
|
};
|
||||||
@ -72,7 +68,6 @@ class I420Buffer : public VideoFrameBuffer {
|
|||||||
uint8_t* data(PlaneType type) override;
|
uint8_t* data(PlaneType type) override;
|
||||||
int stride(PlaneType type) const override;
|
int stride(PlaneType type) const override;
|
||||||
void* native_handle() const override;
|
void* native_handle() const override;
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~I420Buffer() override;
|
~I420Buffer() override;
|
||||||
@ -86,14 +81,15 @@ class I420Buffer : public VideoFrameBuffer {
|
|||||||
const rtc::scoped_ptr<uint8_t, AlignedFreeDeleter> data_;
|
const rtc::scoped_ptr<uint8_t, AlignedFreeDeleter> data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for native-handle buffer is a wrapper around a |native_handle|.
|
// Texture buffer is a VideoFrameBuffer wrapper around a |native_handle|.
|
||||||
// This is used for convenience as most native-handle implementations can share
|
// |native_handle| must be valid for the lifetime of an instance of this object.
|
||||||
// many VideoFrame implementations, but need to implement a few others (such
|
// |no_longer_used| can be used to manage the lifetime of |native_handle|.
|
||||||
// as their own destructors or conversion methods back to software I420).
|
class TextureBuffer : public VideoFrameBuffer {
|
||||||
class NativeHandleBuffer : public VideoFrameBuffer {
|
|
||||||
public:
|
public:
|
||||||
NativeHandleBuffer(void* native_handle, int width, int height);
|
TextureBuffer(void* native_handle,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
const rtc::Callback0<void>& no_longer_used);
|
||||||
int width() const override;
|
int width() const override;
|
||||||
int height() const override;
|
int height() const override;
|
||||||
const uint8_t* data(PlaneType type) const override;
|
const uint8_t* data(PlaneType type) const override;
|
||||||
@ -101,10 +97,15 @@ class NativeHandleBuffer : public VideoFrameBuffer {
|
|||||||
int stride(PlaneType type) const override;
|
int stride(PlaneType type) const override;
|
||||||
void* native_handle() const override;
|
void* native_handle() const override;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
friend class rtc::RefCountedObject<TextureBuffer>;
|
||||||
|
~TextureBuffer() override;
|
||||||
|
|
||||||
|
// |native_handle_| is a raw pointer and not owned by TextureBuffer.
|
||||||
void* native_handle_;
|
void* native_handle_;
|
||||||
const int width_;
|
const int width_;
|
||||||
const int height_;
|
const int height_;
|
||||||
|
rtc::Callback0<void> no_longer_used_cb_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WrappedI420Buffer : public webrtc::VideoFrameBuffer {
|
class WrappedI420Buffer : public webrtc::VideoFrameBuffer {
|
||||||
@ -129,8 +130,6 @@ class WrappedI420Buffer : public webrtc::VideoFrameBuffer {
|
|||||||
int stride(PlaneType type) const override;
|
int stride(PlaneType type) const override;
|
||||||
void* native_handle() const override;
|
void* native_handle() const override;
|
||||||
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class rtc::RefCountedObject<WrappedI420Buffer>;
|
friend class rtc::RefCountedObject<WrappedI420Buffer>;
|
||||||
~WrappedI420Buffer() override;
|
~WrappedI420Buffer() override;
|
||||||
|
@ -36,6 +36,22 @@ VideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
|
|||||||
rotation_(rotation) {
|
rotation_(rotation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoFrame::VideoFrame(void* native_handle,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
uint32_t timestamp,
|
||||||
|
int64_t render_time_ms,
|
||||||
|
VideoRotation rotation,
|
||||||
|
const rtc::Callback0<void>& no_longer_used)
|
||||||
|
: VideoFrame(new rtc::RefCountedObject<TextureBuffer>(native_handle,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
no_longer_used),
|
||||||
|
timestamp,
|
||||||
|
render_time_ms,
|
||||||
|
rotation) {
|
||||||
|
}
|
||||||
|
|
||||||
int VideoFrame::CreateEmptyFrame(int width,
|
int VideoFrame::CreateEmptyFrame(int width,
|
||||||
int height,
|
int height,
|
||||||
int stride_y,
|
int stride_y,
|
||||||
@ -195,12 +211,4 @@ void VideoFrame::set_video_frame_buffer(
|
|||||||
video_frame_buffer_ = buffer;
|
video_frame_buffer_ = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoFrame VideoFrame::ConvertNativeToI420Frame() const {
|
|
||||||
DCHECK(native_handle());
|
|
||||||
VideoFrame frame;
|
|
||||||
frame.ShallowCopy(*this);
|
|
||||||
frame.set_video_frame_buffer(video_frame_buffer_->NativeToI420Buffer());
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -94,47 +94,51 @@ void* I420Buffer::native_handle() const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::NativeToI420Buffer() {
|
TextureBuffer::TextureBuffer(void* native_handle,
|
||||||
RTC_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
|
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height,
|
||||||
: native_handle_(native_handle), width_(width), height_(height) {
|
const rtc::Callback0<void>& no_longer_used)
|
||||||
|
: native_handle_(native_handle),
|
||||||
|
width_(width),
|
||||||
|
height_(height),
|
||||||
|
no_longer_used_cb_(no_longer_used) {
|
||||||
DCHECK(native_handle != nullptr);
|
DCHECK(native_handle != nullptr);
|
||||||
DCHECK_GT(width, 0);
|
DCHECK_GT(width, 0);
|
||||||
DCHECK_GT(height, 0);
|
DCHECK_GT(height, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NativeHandleBuffer::width() const {
|
TextureBuffer::~TextureBuffer() {
|
||||||
|
no_longer_used_cb_();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextureBuffer::width() const {
|
||||||
return width_;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NativeHandleBuffer::height() const {
|
int TextureBuffer::height() const {
|
||||||
return height_;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* NativeHandleBuffer::data(PlaneType type) const {
|
const uint8_t* TextureBuffer::data(PlaneType type) const {
|
||||||
RTC_NOTREACHED(); // Should not be called.
|
RTC_NOTREACHED(); // Should not be called.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* NativeHandleBuffer::data(PlaneType type) {
|
uint8_t* TextureBuffer::data(PlaneType type) {
|
||||||
RTC_NOTREACHED(); // Should not be called.
|
RTC_NOTREACHED(); // Should not be called.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NativeHandleBuffer::stride(PlaneType type) const {
|
int TextureBuffer::stride(PlaneType type) const {
|
||||||
RTC_NOTREACHED(); // Should not be called.
|
RTC_NOTREACHED(); // Should not be called.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* NativeHandleBuffer::native_handle() const {
|
void* TextureBuffer::native_handle() const {
|
||||||
return native_handle_;
|
return native_handle_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WrappedI420Buffer::WrappedI420Buffer(int desired_width,
|
WrappedI420Buffer::WrappedI420Buffer(int desired_width,
|
||||||
int desired_height,
|
int desired_height,
|
||||||
int width,
|
int width,
|
||||||
@ -216,9 +220,4 @@ void* WrappedI420Buffer::native_handle() const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> WrappedI420Buffer::NativeToI420Buffer() {
|
|
||||||
RTC_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -200,10 +200,6 @@ void VCMGenericEncoder::OnDroppedFrame() {
|
|||||||
encoder_->OnDroppedFrame();
|
encoder_->OnDroppedFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCMGenericEncoder::SupportsNativeHandle() const {
|
|
||||||
return encoder_->SupportsNativeHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
* Callback Implementation
|
* Callback Implementation
|
||||||
***************************/
|
***************************/
|
||||||
|
@ -138,8 +138,6 @@ public:
|
|||||||
|
|
||||||
void OnDroppedFrame();
|
void OnDroppedFrame();
|
||||||
|
|
||||||
bool SupportsNativeHandle() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VideoEncoder* const encoder_;
|
VideoEncoder* const encoder_;
|
||||||
VideoEncoderRateObserver* const rate_observer_;
|
VideoEncoderRateObserver* const rate_observer_;
|
||||||
|
@ -321,16 +321,8 @@ int32_t VideoSender::AddVideoFrame(const VideoFrame& videoFrame,
|
|||||||
LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping.";
|
LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping.";
|
||||||
return VCM_PARAMETER_ERROR;
|
return VCM_PARAMETER_ERROR;
|
||||||
}
|
}
|
||||||
VideoFrame converted_frame = videoFrame;
|
|
||||||
if (converted_frame.native_handle() && !_encoder->SupportsNativeHandle()) {
|
|
||||||
// This module only supports software encoding.
|
|
||||||
// TODO(pbos): Offload conversion from the encoder thread.
|
|
||||||
converted_frame = converted_frame.ConvertNativeToI420Frame();
|
|
||||||
CHECK(!converted_frame.IsZeroSize())
|
|
||||||
<< "Frame conversion failed, won't be able to encode frame.";
|
|
||||||
}
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
_encoder->Encode(converted_frame, codecSpecificInfo, _nextFrameTypes);
|
_encoder->Encode(videoFrame, codecSpecificInfo, _nextFrameTypes);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG(LS_ERROR) << "Failed to encode frame. Error code: " << ret;
|
LOG(LS_ERROR) << "Failed to encode frame. Error code: " << ret;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 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_TEST_FAKE_TEXTURE_FRAME_H_
|
|
||||||
#define WEBRTC_TEST_FAKE_TEXTURE_FRAME_H_
|
|
||||||
|
|
||||||
#include "webrtc/base/checks.h"
|
|
||||||
#include "webrtc/common_video/interface/video_frame_buffer.h"
|
|
||||||
#include "webrtc/video_frame.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
class FakeNativeHandle {};
|
|
||||||
|
|
||||||
class FakeNativeHandleBuffer : public NativeHandleBuffer {
|
|
||||||
public:
|
|
||||||
FakeNativeHandleBuffer(void* native_handle, int width, int height)
|
|
||||||
: NativeHandleBuffer(native_handle, width, height) {}
|
|
||||||
|
|
||||||
~FakeNativeHandleBuffer() {
|
|
||||||
delete reinterpret_cast<FakeNativeHandle*>(native_handle_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> NativeToI420Buffer() override {
|
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> buffer(
|
|
||||||
new rtc::RefCountedObject<I420Buffer>(width_, height_));
|
|
||||||
int half_height = (height_ + 1) / 2;
|
|
||||||
int half_width = (width_ + 1) / 2;
|
|
||||||
memset(buffer->data(kYPlane), 0, height_ * width_);
|
|
||||||
memset(buffer->data(kUPlane), 0, half_height * half_width);
|
|
||||||
memset(buffer->data(kVPlane), 0, half_height * half_width);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static VideoFrame CreateFakeNativeHandleFrame(FakeNativeHandle* native_handle,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
uint32_t timestamp,
|
|
||||||
int64_t render_time_ms,
|
|
||||||
VideoRotation rotation) {
|
|
||||||
return VideoFrame(new rtc::RefCountedObject<FakeNativeHandleBuffer>(
|
|
||||||
native_handle, width, height),
|
|
||||||
timestamp, render_time_ms, rotation);
|
|
||||||
}
|
|
||||||
} // namespace test
|
|
||||||
} // namespace webrtc
|
|
||||||
#endif // WEBRTC_TEST_FAKE_TEXTURE_FRAME_H_
|
|
@ -122,10 +122,4 @@ void VideoEncoderSoftwareFallbackWrapper::OnDroppedFrame() {
|
|||||||
return encoder_->OnDroppedFrame();
|
return encoder_->OnDroppedFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoEncoderSoftwareFallbackWrapper::SupportsNativeHandle() const {
|
|
||||||
if (fallback_encoder_)
|
|
||||||
return fallback_encoder_->SupportsNativeHandle();
|
|
||||||
return encoder_->SupportsNativeHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -60,11 +60,6 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
|||||||
|
|
||||||
void OnDroppedFrame() override { ++on_dropped_frame_count_; }
|
void OnDroppedFrame() override { ++on_dropped_frame_count_; }
|
||||||
|
|
||||||
bool SupportsNativeHandle() const override {
|
|
||||||
++supports_native_handle_count_;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_encode_count_ = 0;
|
int init_encode_count_ = 0;
|
||||||
int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
||||||
int encode_count_ = 0;
|
int encode_count_ = 0;
|
||||||
@ -73,7 +68,6 @@ class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
|||||||
int set_channel_parameters_count_ = 0;
|
int set_channel_parameters_count_ = 0;
|
||||||
int set_rates_count_ = 0;
|
int set_rates_count_ = 0;
|
||||||
int on_dropped_frame_count_ = 0;
|
int on_dropped_frame_count_ = 0;
|
||||||
mutable int supports_native_handle_count_ = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FakeEncodedImageCallback : public EncodedImageCallback {
|
class FakeEncodedImageCallback : public EncodedImageCallback {
|
||||||
@ -203,18 +197,4 @@ TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
||||||
SupportsNativeHandleForwardedWithoutFallback) {
|
|
||||||
fallback_wrapper_.SupportsNativeHandle();
|
|
||||||
EXPECT_EQ(1, fake_encoder_.supports_native_handle_count_);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
|
|
||||||
SupportsNativeHandleNotForwardedDuringFallback) {
|
|
||||||
UtilizeFallbackEncoder();
|
|
||||||
fallback_wrapper_.SupportsNativeHandle();
|
|
||||||
EXPECT_EQ(0, fake_encoder_.supports_native_handle_count_);
|
|
||||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_.Release());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
#include "webrtc/test/call_test.h"
|
#include "webrtc/test/call_test.h"
|
||||||
#include "webrtc/test/configurable_frame_size_encoder.h"
|
#include "webrtc/test/configurable_frame_size_encoder.h"
|
||||||
#include "webrtc/test/fake_texture_frame.h"
|
|
||||||
#include "webrtc/test/null_transport.h"
|
#include "webrtc/test/null_transport.h"
|
||||||
#include "webrtc/test/testsupport/perf_test.h"
|
#include "webrtc/test/testsupport/perf_test.h"
|
||||||
#include "webrtc/video/send_statistics_proxy.h"
|
#include "webrtc/video/send_statistics_proxy.h"
|
||||||
@ -51,6 +50,16 @@ void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
|
|||||||
const std::vector<VideoFrame>& frames2);
|
const std::vector<VideoFrame>& frames2);
|
||||||
VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
|
VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
|
||||||
|
|
||||||
|
class FakeNativeHandle {
|
||||||
|
public:
|
||||||
|
FakeNativeHandle() {}
|
||||||
|
~FakeNativeHandle() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void DeleteNativeHandle(FakeNativeHandle* handle) {
|
||||||
|
delete handle;
|
||||||
|
}
|
||||||
|
|
||||||
class VideoSendStreamTest : public test::CallTest {
|
class VideoSendStreamTest : public test::CallTest {
|
||||||
protected:
|
protected:
|
||||||
void TestNackRetransmission(uint32_t retransmit_ssrc,
|
void TestNackRetransmission(uint32_t retransmit_ssrc,
|
||||||
@ -1075,17 +1084,20 @@ TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
|
|||||||
std::vector<VideoFrame> input_frames;
|
std::vector<VideoFrame> input_frames;
|
||||||
int width = static_cast<int>(encoder_config_.streams[0].width);
|
int width = static_cast<int>(encoder_config_.streams[0].width);
|
||||||
int height = static_cast<int>(encoder_config_.streams[0].height);
|
int height = static_cast<int>(encoder_config_.streams[0].height);
|
||||||
test::FakeNativeHandle* handle1 = new test::FakeNativeHandle();
|
FakeNativeHandle* handle1 = new FakeNativeHandle();
|
||||||
test::FakeNativeHandle* handle2 = new test::FakeNativeHandle();
|
FakeNativeHandle* handle2 = new FakeNativeHandle();
|
||||||
test::FakeNativeHandle* handle3 = new test::FakeNativeHandle();
|
FakeNativeHandle* handle3 = new FakeNativeHandle();
|
||||||
input_frames.push_back(test::CreateFakeNativeHandleFrame(
|
input_frames.push_back(VideoFrame(handle1, width, height, 1, 1,
|
||||||
handle1, width, height, 1, 1, kVideoRotation_0));
|
kVideoRotation_0,
|
||||||
input_frames.push_back(test::CreateFakeNativeHandleFrame(
|
rtc::Bind(&DeleteNativeHandle, handle1)));
|
||||||
handle2, width, height, 2, 2, kVideoRotation_0));
|
input_frames.push_back(VideoFrame(handle2, width, height, 2, 2,
|
||||||
|
kVideoRotation_0,
|
||||||
|
rtc::Bind(&DeleteNativeHandle, handle2)));
|
||||||
input_frames.push_back(CreateVideoFrame(width, height, 3));
|
input_frames.push_back(CreateVideoFrame(width, height, 3));
|
||||||
input_frames.push_back(CreateVideoFrame(width, height, 4));
|
input_frames.push_back(CreateVideoFrame(width, height, 4));
|
||||||
input_frames.push_back(test::CreateFakeNativeHandleFrame(
|
input_frames.push_back(VideoFrame(handle3, width, height, 5, 5,
|
||||||
handle3, width, height, 5, 5, kVideoRotation_0));
|
kVideoRotation_0,
|
||||||
|
rtc::Bind(&DeleteNativeHandle, handle3)));
|
||||||
|
|
||||||
send_stream_->Start();
|
send_stream_->Start();
|
||||||
for (size_t i = 0; i < input_frames.size(); i++) {
|
for (size_t i = 0; i < input_frames.size(); i++) {
|
||||||
|
@ -123,8 +123,7 @@ class VideoEncoder {
|
|||||||
virtual int32_t CodecConfigParameters(uint8_t* /*buffer*/, int32_t /*size*/) {
|
virtual int32_t CodecConfigParameters(uint8_t* /*buffer*/, int32_t /*size*/) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
virtual void OnDroppedFrame() {}
|
virtual void OnDroppedFrame() {};
|
||||||
virtual bool SupportsNativeHandle() const { return false; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Class used to wrap external VideoEncoders to provide a fallback option on
|
// Class used to wrap external VideoEncoders to provide a fallback option on
|
||||||
@ -150,7 +149,6 @@ class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder {
|
|||||||
|
|
||||||
int32_t SetRates(uint32_t bitrate, uint32_t framerate) override;
|
int32_t SetRates(uint32_t bitrate, uint32_t framerate) override;
|
||||||
void OnDroppedFrame() override;
|
void OnDroppedFrame() override;
|
||||||
bool SupportsNativeHandle() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const EncoderType encoder_type_;
|
const EncoderType encoder_type_;
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/ref_count.h"
|
#include "webrtc/system_wrappers/interface/ref_count.h"
|
||||||
#include "webrtc/system_wrappers/interface/scoped_vector.h"
|
#include "webrtc/system_wrappers/interface/scoped_vector.h"
|
||||||
#include "webrtc/test/fake_texture_frame.h"
|
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::Invoke;
|
using ::testing::Invoke;
|
||||||
@ -160,10 +159,11 @@ TEST_F(ViECapturerTest, TestRtpTimeStampSet) {
|
|||||||
TEST_F(ViECapturerTest, TestTextureFrames) {
|
TEST_F(ViECapturerTest, TestTextureFrames) {
|
||||||
const int kNumFrame = 3;
|
const int kNumFrame = 3;
|
||||||
for (int i = 0 ; i < kNumFrame; ++i) {
|
for (int i = 0 ; i < kNumFrame; ++i) {
|
||||||
test::FakeNativeHandle* dummy_handle = new test::FakeNativeHandle();
|
void* dummy_handle = reinterpret_cast<void*>(i+1);
|
||||||
// Add one to |i| so that width/height > 0.
|
// Add one to |i| so that width/height > 0.
|
||||||
input_frames_.push_back(new VideoFrame(test::CreateFakeNativeHandleFrame(
|
input_frames_.push_back(new VideoFrame(dummy_handle, i + 1, i + 1, i + 1,
|
||||||
dummy_handle, i + 1, i + 1, i + 1, i + 1, webrtc::kVideoRotation_0)));
|
i + 1, webrtc::kVideoRotation_0,
|
||||||
|
rtc::Callback0<void>()));
|
||||||
AddInputFrame(input_frames_[i]);
|
AddInputFrame(input_frames_[i]);
|
||||||
WaitOutputFrame();
|
WaitOutputFrame();
|
||||||
EXPECT_EQ(dummy_handle, output_frames_[i]->native_handle());
|
EXPECT_EQ(dummy_handle, output_frames_[i]->native_handle());
|
||||||
@ -190,9 +190,10 @@ TEST_F(ViECapturerTest, TestI420Frames) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ViECapturerTest, TestI420FrameAfterTextureFrame) {
|
TEST_F(ViECapturerTest, TestI420FrameAfterTextureFrame) {
|
||||||
test::FakeNativeHandle* dummy_handle = new test::FakeNativeHandle();
|
void* dummy_handle = &input_frames_;
|
||||||
input_frames_.push_back(new VideoFrame(test::CreateFakeNativeHandleFrame(
|
input_frames_.push_back(new VideoFrame(dummy_handle, 1, 1, 1, 1,
|
||||||
dummy_handle, 1, 1, 1, 1, webrtc::kVideoRotation_0)));
|
webrtc::kVideoRotation_0,
|
||||||
|
rtc::Callback0<void>()));
|
||||||
AddInputFrame(input_frames_[0]);
|
AddInputFrame(input_frames_[0]);
|
||||||
WaitOutputFrame();
|
WaitOutputFrame();
|
||||||
EXPECT_EQ(dummy_handle, output_frames_[0]->native_handle());
|
EXPECT_EQ(dummy_handle, output_frames_[0]->native_handle());
|
||||||
@ -209,9 +210,10 @@ TEST_F(ViECapturerTest, TestTextureFrameAfterI420Frame) {
|
|||||||
AddInputFrame(input_frames_[0]);
|
AddInputFrame(input_frames_[0]);
|
||||||
WaitOutputFrame();
|
WaitOutputFrame();
|
||||||
|
|
||||||
test::FakeNativeHandle* dummy_handle = new test::FakeNativeHandle();
|
void* dummy_handle = &input_frames_;
|
||||||
input_frames_.push_back(new VideoFrame(test::CreateFakeNativeHandleFrame(
|
input_frames_.push_back(new VideoFrame(dummy_handle, 1, 1, 2, 2,
|
||||||
dummy_handle, 1, 1, 2, 2, webrtc::kVideoRotation_0)));
|
webrtc::kVideoRotation_0,
|
||||||
|
rtc::Callback0<void>()));
|
||||||
AddInputFrame(input_frames_[1]);
|
AddInputFrame(input_frames_[1]);
|
||||||
WaitOutputFrame();
|
WaitOutputFrame();
|
||||||
|
|
||||||
|
@ -543,6 +543,11 @@ void ViEEncoder::DeliverFrame(VideoFrame video_frame) {
|
|||||||
const VideoFrame* output_frame =
|
const VideoFrame* output_frame =
|
||||||
(decimated_frame != NULL) ? decimated_frame : &video_frame;
|
(decimated_frame != NULL) ? decimated_frame : &video_frame;
|
||||||
|
|
||||||
|
if (video_frame.native_handle() != NULL) {
|
||||||
|
// TODO(wuchengli): add texture support. http://crbug.com/362437
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef VIDEOCODEC_VP8
|
#ifdef VIDEOCODEC_VP8
|
||||||
if (vcm_->SendCodec() == webrtc::kVideoCodecVP8) {
|
if (vcm_->SendCodec() == webrtc::kVideoCodecVP8) {
|
||||||
webrtc::CodecSpecificInfo codec_specific_info;
|
webrtc::CodecSpecificInfo codec_specific_info;
|
||||||
|
@ -25,6 +25,13 @@ class VideoFrame {
|
|||||||
uint32_t timestamp,
|
uint32_t timestamp,
|
||||||
int64_t render_time_ms,
|
int64_t render_time_ms,
|
||||||
VideoRotation rotation);
|
VideoRotation rotation);
|
||||||
|
VideoFrame(void* native_handle,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
uint32_t timestamp,
|
||||||
|
int64_t render_time_ms,
|
||||||
|
VideoRotation rotation,
|
||||||
|
const rtc::Callback0<void>& no_longer_used);
|
||||||
|
|
||||||
// TODO(pbos): Make all create/copy functions void, they should not be able to
|
// TODO(pbos): Make all create/copy functions void, they should not be able to
|
||||||
// fail (which should be DCHECK/CHECKed instead).
|
// fail (which should be DCHECK/CHECKed instead).
|
||||||
@ -153,10 +160,6 @@ class VideoFrame {
|
|||||||
void set_video_frame_buffer(
|
void set_video_frame_buffer(
|
||||||
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer);
|
const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer);
|
||||||
|
|
||||||
// Convert native-handle frame to memory-backed I420 frame. Should not be
|
|
||||||
// called on a non-native-handle frame.
|
|
||||||
VideoFrame ConvertNativeToI420Frame() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// An opaque reference counted handle that stores the pixel data.
|
// An opaque reference counted handle that stores the pixel data.
|
||||||
rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
|
rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user