New static I420Buffer::Rotate method, to replace GetCopyWithRotationApplied.
GetCopyWithRotationApplied is not yet deleted; downstream projects must be updated first. BUG=webrtc:5682 Review-Url: https://codereview.webrtc.org/2285693002 Cr-Commit-Position: refs/heads/master@{#13973}
This commit is contained in:
parent
c31446f49e
commit
d50747269e
@ -18,6 +18,7 @@
|
||||
#include "webrtc/base/callback.h"
|
||||
#include "webrtc/base/refcount.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
#include "webrtc/common_video/rotation.h"
|
||||
#include "webrtc/system_wrappers/include/aligned_malloc.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -130,6 +131,13 @@ class I420Buffer : public VideoFrameBuffer {
|
||||
static rtc::scoped_refptr<I420Buffer> CopyKeepStride(
|
||||
const rtc::scoped_refptr<VideoFrameBuffer>& buffer);
|
||||
|
||||
// Returns a rotated versions of |src|. Native buffers are not
|
||||
// supported. The reason this function doesn't return an I420Buffer,
|
||||
// is that it returns |src| unchanged in case |rotation| is zero.
|
||||
static rtc::scoped_refptr<VideoFrameBuffer> Rotate(
|
||||
const rtc::scoped_refptr<VideoFrameBuffer>& src,
|
||||
VideoRotation rotation);
|
||||
|
||||
protected:
|
||||
~I420Buffer() override;
|
||||
|
||||
|
||||
@ -216,6 +216,7 @@ void I420Buffer::ScaleFrom(const rtc::scoped_refptr<VideoFrameBuffer>& src) {
|
||||
CropAndScaleFrom(src, 0, 0, src->width(), src->height());
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<I420Buffer> I420Buffer::CopyKeepStride(
|
||||
const rtc::scoped_refptr<VideoFrameBuffer>& source) {
|
||||
int width = source->width();
|
||||
@ -236,6 +237,41 @@ rtc::scoped_refptr<I420Buffer> I420Buffer::CopyKeepStride(
|
||||
return target;
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<VideoFrameBuffer> I420Buffer::Rotate(
|
||||
const rtc::scoped_refptr<VideoFrameBuffer>& src,
|
||||
VideoRotation rotation) {
|
||||
RTC_DCHECK(src->DataY());
|
||||
RTC_DCHECK(src->DataU());
|
||||
RTC_DCHECK(src->DataV());
|
||||
|
||||
if (rotation == webrtc::kVideoRotation_0) {
|
||||
return src;
|
||||
}
|
||||
|
||||
int rotated_width = src->width();
|
||||
int rotated_height = src->height();
|
||||
if (rotation == webrtc::kVideoRotation_90 ||
|
||||
rotation == webrtc::kVideoRotation_270) {
|
||||
std::swap(rotated_width, rotated_height);
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::I420Buffer> buffer =
|
||||
I420Buffer::Create(rotated_width, rotated_height);
|
||||
|
||||
int res = libyuv::I420Rotate(
|
||||
src->DataY(), src->StrideY(),
|
||||
src->DataU(), src->StrideU(),
|
||||
src->DataV(), src->StrideV(),
|
||||
buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataU(),
|
||||
buffer->StrideU(), buffer->MutableDataV(), buffer->StrideV(),
|
||||
src->width(), src->height(),
|
||||
static_cast<libyuv::RotationMode>(rotation));
|
||||
RTC_DCHECK_EQ(res, 0);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
NativeHandleBuffer::NativeHandleBuffer(void* native_handle,
|
||||
int width,
|
||||
int height)
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/stringutils.h"
|
||||
#include "webrtc/media/engine/webrtcvideoframe.h"
|
||||
|
||||
using rtc::sprintfn;
|
||||
|
||||
@ -484,16 +485,19 @@ void GtkMainWnd::VideoRenderer::OnFrame(
|
||||
const cricket::VideoFrame& video_frame) {
|
||||
gdk_threads_enter();
|
||||
|
||||
const cricket::VideoFrame* frame = video_frame.GetCopyWithRotationApplied();
|
||||
const cricket::WebRtcVideoFrame frame(
|
||||
webrtc::I420Buffer::Rotate(video_frame.video_frame_buffer(),
|
||||
video_frame.rotation()),
|
||||
webrtc::kVideoRotation_0, video_frame.timestamp_us());
|
||||
|
||||
SetSize(frame->width(), frame->height());
|
||||
SetSize(frame.width(), frame.height());
|
||||
|
||||
int size = width_ * height_ * 4;
|
||||
// TODO(henrike): Convert directly to RGBA
|
||||
frame->ConvertToRgbBuffer(cricket::FOURCC_ARGB,
|
||||
image_.get(),
|
||||
size,
|
||||
width_ * 4);
|
||||
frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
|
||||
image_.get(),
|
||||
size,
|
||||
width_ * 4);
|
||||
// Convert the B,G,R,A frame to R,G,B,A, which is accepted by GTK.
|
||||
// The 'A' is just padding for GTK, so we can use it as temp.
|
||||
uint8_t* pix = image_.get();
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "webrtc/base/arraysize.h"
|
||||
#include "webrtc/base/common.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/media/engine/webrtcvideoframe.h"
|
||||
|
||||
ATOM MainWnd::wnd_class_ = 0;
|
||||
const wchar_t MainWnd::kClassName[] = L"WebRTC_MainWnd";
|
||||
@ -604,17 +605,19 @@ void MainWnd::VideoRenderer::OnFrame(
|
||||
{
|
||||
AutoLock<VideoRenderer> lock(this);
|
||||
|
||||
const cricket::VideoFrame* frame =
|
||||
video_frame.GetCopyWithRotationApplied();
|
||||
const cricket::WebRtcVideoFrame frame(
|
||||
webrtc::I420Buffer::Rotate(video_frame.video_frame_buffer(),
|
||||
video_frame.rotation()),
|
||||
webrtc::kVideoRotation_0, video_frame.timestamp_us());
|
||||
|
||||
SetSize(frame->width(), frame->height());
|
||||
SetSize(frame.width(), frame.height());
|
||||
|
||||
ASSERT(image_.get() != NULL);
|
||||
frame->ConvertToRgbBuffer(cricket::FOURCC_ARGB,
|
||||
image_.get(),
|
||||
bmi_.bmiHeader.biSizeImage,
|
||||
bmi_.bmiHeader.biWidth *
|
||||
bmi_.bmiHeader.biBitCount / 8);
|
||||
frame.ConvertToRgbBuffer(cricket::FOURCC_ARGB,
|
||||
image_.get(),
|
||||
bmi_.bmiHeader.biSizeImage,
|
||||
bmi_.bmiHeader.biWidth *
|
||||
bmi_.bmiHeader.biBitCount / 8);
|
||||
}
|
||||
InvalidateRect(wnd_, NULL, TRUE);
|
||||
}
|
||||
|
||||
@ -58,9 +58,9 @@ class VideoFrame {
|
||||
// Return a copy of frame which has its pending rotation applied. The
|
||||
// ownership of the returned frame is held by this frame.
|
||||
|
||||
// TODO(nisse): Deprecated. Should be moved or deleted in the
|
||||
// cricket::VideoFrame and webrtc::VideoFrame merge, possibly with a helper
|
||||
// method on VideoFrameBuffer.
|
||||
// TODO(nisse): Deprecated, no longer used within webrtc. Should be
|
||||
// deleted as soon as downstream applications are updated. Use
|
||||
// webrtc::I420Buffer::Rotate instead.
|
||||
virtual const VideoFrame* GetCopyWithRotationApplied() const = 0;
|
||||
|
||||
// Converts the I420 data to RGB of a certain type such as ARGB and ABGR.
|
||||
|
||||
@ -106,19 +106,22 @@ bool CarbonVideoRenderer::SetSize(int width, int height) {
|
||||
|
||||
void CarbonVideoRenderer::OnFrame(const VideoFrame& video_frame) {
|
||||
{
|
||||
const VideoFrame* frame = video_frame->GetCopyWithRotationApplied();
|
||||
const cricket::WebRtcVideoFrame frame(
|
||||
webrtc::I420Buffer::Rotate(video_frame.video_frame_buffer(),
|
||||
video_frame.rotation()),
|
||||
webrtc::kVideoRotation_0, video_frame.timestamp_us());
|
||||
|
||||
if (!SetSize(frame->width(), frame->height())) {
|
||||
if (!SetSize(frame.width(), frame.height())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grab the image lock so we are not trashing up the image being drawn.
|
||||
rtc::CritScope cs(&image_crit_);
|
||||
frame->ConvertToRgbBuffer(cricket::FOURCC_ABGR,
|
||||
image_.get(),
|
||||
static_cast<size_t>(frame->width()) *
|
||||
frame->height() * 4,
|
||||
frame->width() * 4);
|
||||
frame.ConvertToRgbBuffer(cricket::FOURCC_ABGR,
|
||||
image_.get(),
|
||||
static_cast<size_t>(frame.width()) *
|
||||
frame.height() * 4,
|
||||
frame.width() * 4);
|
||||
}
|
||||
|
||||
// Trigger a repaint event for the whole window.
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/base/win32window.h"
|
||||
#include "webrtc/media/base/videocommon.h"
|
||||
#include "webrtc/media/base/videoframe.h"
|
||||
#include "webrtc/media/engine/webrtcvideoframe.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
@ -135,10 +135,13 @@ void GdiVideoRenderer::VideoWindow::OnFrame(const VideoFrame& video_frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
const VideoFrame* frame = video_frame.GetCopyWithRotationApplied();
|
||||
const cricket::WebRtcVideoFrame frame(
|
||||
webrtc::I420Buffer::Rotate(video_frame.video_frame_buffer(),
|
||||
video_frame.rotation()),
|
||||
webrtc::kVideoRotation_0, video_frame.timestamp_us());
|
||||
|
||||
if (SetSize(frame->width(), frame->height())) {
|
||||
SendMessage(handle(), kRenderFrameMsg, reinterpret_cast<WPARAM>(frame), 0);
|
||||
if (SetSize(frame.width(), frame.height())) {
|
||||
SendMessage(handle(), kRenderFrameMsg, reinterpret_cast<WPARAM>(&frame), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "webrtc/media/base/videocommon.h"
|
||||
#include "webrtc/media/base/videoframe.h"
|
||||
#include "webrtc/media/engine/webrtcvideoframe.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
@ -81,19 +81,22 @@ bool GtkVideoRenderer::SetSize(int width, int height) {
|
||||
}
|
||||
|
||||
void GtkVideoRenderer::OnFrame(const VideoFrame& video_frame) {
|
||||
const VideoFrame* frame = video_frame.GetCopyWithRotationApplied();
|
||||
const cricket::WebRtcVideoFrame frame(
|
||||
webrtc::I420Buffer::Rotate(video_frame.video_frame_buffer(),
|
||||
video_frame.rotation()),
|
||||
webrtc::kVideoRotation_0, video_frame.timestamp_us());
|
||||
|
||||
// Need to set size as the frame might be rotated.
|
||||
if (!SetSize(frame->width(), frame->height())) {
|
||||
if (!SetSize(frame.width(), frame.height())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// convert I420 frame to ABGR format, which is accepted by GTK
|
||||
frame->ConvertToRgbBuffer(cricket::FOURCC_ABGR,
|
||||
image_.get(),
|
||||
static_cast<size_t>(frame->width()) *
|
||||
frame->height() * 4,
|
||||
frame->width() * 4);
|
||||
frame.ConvertToRgbBuffer(cricket::FOURCC_ABGR,
|
||||
image_.get(),
|
||||
static_cast<size_t>(frame.width()) *
|
||||
frame.height() * 4,
|
||||
frame.width() * 4);
|
||||
|
||||
ScopedGdkLock lock;
|
||||
|
||||
@ -106,11 +109,11 @@ void GtkVideoRenderer::OnFrame(const VideoFrame& video_frame) {
|
||||
draw_area_->style->fg_gc[GTK_STATE_NORMAL],
|
||||
0,
|
||||
0,
|
||||
frame->width(),
|
||||
frame->height(),
|
||||
frame.width(),
|
||||
frame.height(),
|
||||
GDK_RGB_DITHER_MAX,
|
||||
image_.get(),
|
||||
frame->width() * 4);
|
||||
frame.width() * 4);
|
||||
|
||||
// Run the Gtk main loop to refresh the window.
|
||||
Pump();
|
||||
|
||||
@ -275,22 +275,26 @@ TEST_F(WebRtcVideoFrameTest, ApplyRotationToFrame) {
|
||||
|
||||
// Claim that this frame needs to be rotated for 90 degree.
|
||||
SetFrameRotation(&applied0, webrtc::kVideoRotation_90);
|
||||
EXPECT_EQ(applied0.rotation(), webrtc::kVideoRotation_90);
|
||||
|
||||
// Apply rotation on frame 1. Output should be different from frame 1.
|
||||
WebRtcVideoFrame* applied90 =
|
||||
const_cast<WebRtcVideoFrame*>(static_cast<const WebRtcVideoFrame*>(
|
||||
applied0.GetCopyWithRotationApplied()));
|
||||
EXPECT_TRUE(applied90);
|
||||
EXPECT_EQ(applied90->rotation(), webrtc::kVideoRotation_0);
|
||||
EXPECT_FALSE(IsEqual(applied0, *applied90, 0));
|
||||
WebRtcVideoFrame applied90(
|
||||
webrtc::I420Buffer::Rotate(applied0.video_frame_buffer(),
|
||||
applied0.rotation()),
|
||||
webrtc::kVideoRotation_0, applied0.timestamp_us());
|
||||
|
||||
EXPECT_EQ(applied90.rotation(), webrtc::kVideoRotation_0);
|
||||
EXPECT_FALSE(IsEqual(applied0, applied90, 0));
|
||||
|
||||
// Claim the frame 2 needs to be rotated for another 270 degree. The output
|
||||
// from frame 2 rotation should be the same as frame 1.
|
||||
SetFrameRotation(applied90, webrtc::kVideoRotation_270);
|
||||
const VideoFrame* applied360 = applied90->GetCopyWithRotationApplied();
|
||||
EXPECT_TRUE(applied360);
|
||||
EXPECT_EQ(applied360->rotation(), webrtc::kVideoRotation_0);
|
||||
EXPECT_TRUE(IsEqual(applied0, *applied360, 0));
|
||||
SetFrameRotation(&applied90, webrtc::kVideoRotation_270);
|
||||
WebRtcVideoFrame applied360(
|
||||
webrtc::I420Buffer::Rotate(applied90.video_frame_buffer(),
|
||||
applied90.rotation()),
|
||||
webrtc::kVideoRotation_0, applied90.timestamp_us());
|
||||
EXPECT_EQ(applied360.rotation(), webrtc::kVideoRotation_0);
|
||||
EXPECT_TRUE(IsEqual(applied0, applied360, 0));
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user