diff --git a/talk/media/base/videoframe.cc b/talk/media/base/videoframe.cc index 83790d225..990552e72 100644 --- a/talk/media/base/videoframe.cc +++ b/talk/media/base/videoframe.cc @@ -122,6 +122,51 @@ 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(GetWidth()); + int height = static_cast(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(GetVideoRotation())); + if (ret == 0) { + return rotated_frame_.get(); + } + return nullptr; +} + size_t VideoFrame::ConvertToRgbBuffer(uint32 to_fourcc, uint8* buffer, size_t size, diff --git a/talk/media/base/videoframe.h b/talk/media/base/videoframe.h index 371dd9b67..ce3cd284f 100644 --- a/talk/media/base/videoframe.h +++ b/talk/media/base/videoframe.h @@ -29,6 +29,7 @@ #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" @@ -161,9 +162,7 @@ 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 { - return nullptr; - } + virtual const VideoFrame* GetCopyWithRotationApplied() const; // Writes the frame into the given stream and returns the StreamResult. // See webrtc/base/stream.h for a description of StreamResult and error. @@ -229,6 +228,11 @@ 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 rotated_frame_; }; } // namespace cricket diff --git a/talk/media/webrtc/webrtcvideoframe.cc b/talk/media/webrtc/webrtcvideoframe.cc index 8d702c9b7..052e6f29e 100644 --- a/talk/media/webrtc/webrtcvideoframe.cc +++ b/talk/media/webrtc/webrtcvideoframe.cc @@ -288,49 +288,4 @@ 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(GetWidth()); - int height = static_cast(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(GetVideoRotation())); - if (ret == 0) { - return rotated_frame_.get(); - } - return nullptr; -} - } // namespace cricket diff --git a/talk/media/webrtc/webrtcvideoframe.h b/talk/media/webrtc/webrtcvideoframe.h index bdbe11d89..29e5ec8ec 100644 --- a/talk/media/webrtc/webrtcvideoframe.h +++ b/talk/media/webrtc/webrtcvideoframe.h @@ -124,8 +124,6 @@ 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; } @@ -142,10 +140,6 @@ 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 rotated_frame_; }; } // namespace cricket