Add concept of whether video renderer supports rotation.
Rotation is best done when rendered in GPU, added the shader code which rotates the frame. For renderers which don't support rotation, the rotation will be done before sending down the frame to render. By default, assume renderer can't do rotation. BUG=4145 R=glaznev@webrtc.org, pthatcher@webrtc.org Committed: https://code.google.com/p/webrtc/source/detail?r=8660 Review URL: https://webrtc-codereview.appspot.com/43569004 Cr-Commit-Position: refs/heads/master@{#8661} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8661 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
0ad48935fc
commit
31d16467ac
@ -122,51 +122,6 @@ void VideoFrame::CopyToFrame(VideoFrame* dst) const {
|
||||
dst->GetYPitch(), dst->GetUPitch(), dst->GetVPitch());
|
||||
}
|
||||
|
||||
const VideoFrame* VideoFrame::GetCopyWithRotationApplied() const {
|
||||
// If the frame is not rotated, the caller should reuse this frame instead of
|
||||
// making a redundant copy.
|
||||
if (GetVideoRotation() == webrtc::kVideoRotation_0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// If the video frame is backed up by a native handle, it resides in the GPU
|
||||
// memory which we can't rotate here. The assumption is that the renderers
|
||||
// which uses GPU to render should be able to rotate themselves.
|
||||
DCHECK(!GetNativeHandle());
|
||||
|
||||
if (rotated_frame_) {
|
||||
return rotated_frame_.get();
|
||||
}
|
||||
|
||||
int width = static_cast<int>(GetWidth());
|
||||
int height = static_cast<int>(GetHeight());
|
||||
|
||||
int rotated_width = width;
|
||||
int rotated_height = height;
|
||||
if (GetVideoRotation() == webrtc::kVideoRotation_90 ||
|
||||
GetVideoRotation() == webrtc::kVideoRotation_270) {
|
||||
rotated_width = height;
|
||||
rotated_height = width;
|
||||
}
|
||||
|
||||
rotated_frame_.reset(CreateEmptyFrame(rotated_width, rotated_height,
|
||||
GetPixelWidth(), GetPixelHeight(),
|
||||
GetElapsedTime(), GetTimeStamp()));
|
||||
|
||||
// TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from
|
||||
// VideoRotation to libyuv::RotationMode.
|
||||
int ret = libyuv::I420Rotate(
|
||||
GetYPlane(), GetYPitch(), GetUPlane(), GetUPitch(), GetVPlane(),
|
||||
GetVPitch(), rotated_frame_->GetYPlane(), rotated_frame_->GetYPitch(),
|
||||
rotated_frame_->GetUPlane(), rotated_frame_->GetUPitch(),
|
||||
rotated_frame_->GetVPlane(), rotated_frame_->GetVPitch(), width, height,
|
||||
static_cast<libyuv::RotationMode>(GetVideoRotation()));
|
||||
if (ret == 0) {
|
||||
return rotated_frame_.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t VideoFrame::ConvertToRgbBuffer(uint32 to_fourcc,
|
||||
uint8* buffer,
|
||||
size_t size,
|
||||
|
@ -29,7 +29,6 @@
|
||||
#define TALK_MEDIA_BASE_VIDEOFRAME_H_
|
||||
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
#include "webrtc/common_video/rotation.h"
|
||||
|
||||
@ -162,7 +161,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.
|
||||
virtual const VideoFrame* GetCopyWithRotationApplied() const;
|
||||
virtual const VideoFrame* GetCopyWithRotationApplied() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Writes the frame into the given stream and returns the StreamResult.
|
||||
// See webrtc/base/stream.h for a description of StreamResult and error.
|
||||
@ -228,11 +229,6 @@ class VideoFrame {
|
||||
size_t pixel_height,
|
||||
int64_t elapsed_time,
|
||||
int64_t time_stamp) const = 0;
|
||||
|
||||
private:
|
||||
// This is mutable as the calculation is expensive but once calculated, it
|
||||
// remains const.
|
||||
mutable rtc::scoped_ptr<VideoFrame> rotated_frame_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -288,4 +288,49 @@ void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h, size_t pixel_width,
|
||||
rotation_ = webrtc::kVideoRotation_0;
|
||||
}
|
||||
|
||||
const VideoFrame* WebRtcVideoFrame::GetCopyWithRotationApplied() const {
|
||||
// If the frame is not rotated, the caller should reuse this frame instead of
|
||||
// making a redundant copy.
|
||||
if (GetVideoRotation() == webrtc::kVideoRotation_0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// If the video frame is backed up by a native handle, it resides in the GPU
|
||||
// memory which we can't rotate here. The assumption is that the renderers
|
||||
// which uses GPU to render should be able to rotate themselves.
|
||||
DCHECK(!GetNativeHandle());
|
||||
|
||||
if (rotated_frame_) {
|
||||
return rotated_frame_.get();
|
||||
}
|
||||
|
||||
int width = static_cast<int>(GetWidth());
|
||||
int height = static_cast<int>(GetHeight());
|
||||
|
||||
int rotated_width = width;
|
||||
int rotated_height = height;
|
||||
if (GetVideoRotation() == webrtc::kVideoRotation_90 ||
|
||||
GetVideoRotation() == webrtc::kVideoRotation_270) {
|
||||
rotated_width = height;
|
||||
rotated_height = width;
|
||||
}
|
||||
|
||||
rotated_frame_.reset(CreateEmptyFrame(rotated_width, rotated_height,
|
||||
GetPixelWidth(), GetPixelHeight(),
|
||||
GetElapsedTime(), GetTimeStamp()));
|
||||
|
||||
// TODO(guoweis): Add a function in webrtc_libyuv.cc to convert from
|
||||
// VideoRotation to libyuv::RotationMode.
|
||||
int ret = libyuv::I420Rotate(
|
||||
GetYPlane(), GetYPitch(), GetUPlane(), GetUPitch(), GetVPlane(),
|
||||
GetVPitch(), rotated_frame_->GetYPlane(), rotated_frame_->GetYPitch(),
|
||||
rotated_frame_->GetUPlane(), rotated_frame_->GetUPitch(),
|
||||
rotated_frame_->GetVPlane(), rotated_frame_->GetVPitch(), width, height,
|
||||
static_cast<libyuv::RotationMode>(GetVideoRotation()));
|
||||
if (ret == 0) {
|
||||
return rotated_frame_.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -124,6 +124,8 @@ class WebRtcVideoFrame : public VideoFrame {
|
||||
virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, uint8* buffer,
|
||||
size_t size, int stride_rgb) const;
|
||||
|
||||
const VideoFrame* GetCopyWithRotationApplied() const override;
|
||||
|
||||
protected:
|
||||
void SetRotation(webrtc::VideoRotation rotation) { rotation_ = rotation; }
|
||||
|
||||
@ -140,6 +142,10 @@ class WebRtcVideoFrame : public VideoFrame {
|
||||
int64_t elapsed_time_ns_;
|
||||
int64_t time_stamp_ns_;
|
||||
webrtc::VideoRotation rotation_;
|
||||
|
||||
// This is mutable as the calculation is expensive but once calculated, it
|
||||
// remains const.
|
||||
mutable rtc::scoped_ptr<VideoFrame> rotated_frame_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
Loading…
x
Reference in New Issue
Block a user