Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Unified Diff: webrtc/media/engine/webrtcvideoframefactory.cc

Issue 1960073002: New method CreateScaledFrame in the VideoFrameFactory interface. Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Implement cropping. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/media/engine/webrtcvideoframefactory.cc
diff --git a/webrtc/media/engine/webrtcvideoframefactory.cc b/webrtc/media/engine/webrtcvideoframefactory.cc
index 2c08c63129c6c28303a743d5122bf69d6e0f57d3..b7b4fd9c9bf7ea917910d020552bba71afd31575 100644
--- a/webrtc/media/engine/webrtcvideoframefactory.cc
+++ b/webrtc/media/engine/webrtcvideoframefactory.cc
@@ -10,12 +10,106 @@
#include <memory>
+#include "libyuv/convert.h"
+#include "libyuv/scale.h"
+
#include "webrtc/base/logging.h"
#include "webrtc/media/engine/webrtcvideoframe.h"
#include "webrtc/media/engine/webrtcvideoframefactory.h"
+// TODO(nisse): Needed for the struct CapturedFrame. Move declaration
+// to videoframefactory.h instead?
+#include "webrtc/media/base/videocapturer.h"
+
namespace cricket {
+std::unique_ptr<VideoFrame> WebRtcVideoFrameFactory::CreateScaledFrame(
+ const CapturedFrame* input_frame,
+ int dst_width,
+ int dst_height) const {
+ // Size of the used portion of the input frame, updated for
+ // cropping, but pre-rotation.
+ int crop_width = input_frame->width;
+ int crop_height = input_frame->height;
+
+ // Cropp the input frame, if needed to preserve aspect ratio.
+ long aspect_diff = static_cast<long>(crop_width) * dst_height -
+ static_cast<long>(crop_height) * dst_width;
+ if (aspect_diff > 0) {
magjed_webrtc 2016/05/09 13:44:55 This code will be the same for all implementations
nisse-webrtc 2016/05/10 07:56:22 It used to be a helper function in videocommon. I
+ // Horizontal crop.
+
+ // TODO(nisse): Old code carried a comment saying that MJPG can
+ // only be cropped vertically, and disabled horizontal cropping in
+ // that case. Still needed?
+ crop_width -= aspect_diff / dst_height;
+ RTC_DCHECK(crop_width > 0);
+ } else if (aspect_diff > 0) {
+ // Vertical crop.
+ crop_height -= (-aspect_diff) / dst_width;
+ RTC_DCHECK(crop_height > 0);
+ }
+
+ webrtc::VideoRotation rotation = input_frame->rotation;
+ // The size of the input frame, after cropping and rotation.
+ int src_width = crop_width;
+ int src_height = crop_height;
+ if (apply_rotation_ && (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270)) {
+ std::swap(dst_width, dst_height);
+ std::swap(src_width, src_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(src_width, src_height));
+
+ // Color space conversion, cropping, and rotation.
+ uint32_t format = CanonicalFourCC(input_frame->fourcc);
+ int r = libyuv::ConvertToI420(
+ static_cast<const uint8_t*>(input_frame->data), input_frame->data_size,
+ buffer->MutableDataY(), buffer->StrideY(),
+ buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(),
+ // Cropping coordinates, and width and height, are pre-rotation values.
+ (input_frame->width - crop_width) / 2,
+ (input_frame->height - crop_height) / 2,
+ input_frame->width, input_frame->height,
+ crop_width, crop_height,
+ static_cast<libyuv::RotationMode>(
+ apply_rotation_ ? rotation : webrtc::kVideoRotation_0),
+ format);
+ if (r) {
+ LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format)
+ << " return code : " << r;
+ return nullptr;
+ }
+
+ // Scaling, if needed.
+ if (src_width != dst_width || src_height != dst_height) {
+ rtc::scoped_refptr<webrtc::I420Buffer> scaled(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(dst_width, dst_height));
+
+ if (libyuv::I420Scale(buffer->DataY(), buffer->StrideY(),
+ buffer->DataU(), buffer->StrideU(),
+ buffer->DataV(), buffer->StrideV(),
+ buffer->width(), buffer->height(),
+ scaled->MutableDataY(), scaled->StrideY(),
+ scaled->MutableDataU(), scaled->StrideU(),
+ scaled->MutableDataV(), scaled->StrideV(),
+ scaled->width(), scaled->height(),
+ libyuv::kFilterBox) < 0) {
+ LOG(LS_ERROR) << "I420Scale failed: src size "
+ << buffer->width() << " x " << buffer->height()
+ << ", dst size: "
+ << scaled->width() << " x " << scaled->height();
+ return nullptr;
+ }
+ buffer = scaled;
+ }
+ return std::unique_ptr<VideoFrame>(new WebRtcVideoFrame(
+ buffer, apply_rotation_ ? webrtc::kVideoRotation_0 : rotation,
+ input_frame->time_stamp / rtc::kNumNanosecsPerMicrosec));
+}
+
VideoFrame* WebRtcVideoFrameFactory::CreateAliasedFrame(
const CapturedFrame* aliased_frame, int width, int height) const {
std::unique_ptr<WebRtcVideoFrame> frame(new WebRtcVideoFrame());
« no previous file with comments | « webrtc/media/engine/webrtcvideoframefactory.h ('k') | webrtc/media/engine/webrtcvideoframefactory_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698