Index: media/base/video_util.cc |
diff --git a/media/base/video_util.cc b/media/base/video_util.cc |
index d9954f8f8e7b4b902d33bd6c63aebd42d619801c..da392c3dd617909094ff044ce1a11aa21f545d96 100644 |
--- a/media/base/video_util.cc |
+++ b/media/base/video_util.cc |
@@ -11,6 +11,7 @@ |
#include "base/numerics/safe_math.h" |
#include "media/base/video_frame.h" |
#include "media/base/yuv_convert.h" |
+#include "third_party/libyuv/include/libyuv.h" |
namespace media { |
@@ -19,6 +20,34 @@ namespace { |
// Empty method used for keeping a reference to the original media::VideoFrame. |
void ReleaseOriginalFrame(const scoped_refptr<media::VideoFrame>& frame) {} |
+// Helper to apply padding to the region outside visible rect with the repeated |
+// last column / row of the visible rect. |
+void FillRegionOutsideVisibleRect(uint8_t* frame, |
+ const gfx::Size& frame_size, |
+ const gfx::Size& visible_size) { |
+ if (visible_size.IsEmpty()) { |
+ if (!frame_size.IsEmpty()) |
+ memset(frame, 0, frame_size.GetArea()); |
+ return; |
+ } |
+ |
+ const int stride = frame_size.width(); |
+ if (visible_size.width() < stride) { |
+ const int pad_length = stride - visible_size.width(); |
+ uint8_t* dst = frame + visible_size.width(); |
+ for (int i = 0; i < visible_size.height(); ++i, dst += stride) |
+ std::memset(dst, *(dst - 1), pad_length); |
+ } |
+ |
+ if (visible_size.height() < frame_size.height()) { |
+ uint8_t* dst = frame + visible_size.height() * stride; |
+ uint8_t* src = dst - stride; |
+ for (int i = visible_size.height(); i < frame_size.height(); |
+ ++i, dst += stride) |
+ std::memcpy(dst, src, stride); |
+ } |
+} |
+ |
} // namespace |
gfx::Size GetNaturalSize(const gfx::Size& visible_size, |
@@ -339,4 +368,49 @@ scoped_refptr<VideoFrame> WrapAsI420VideoFrame( |
return wrapped_frame; |
} |
+bool I420CopyWithPadding(const VideoFrame& src_frame, VideoFrame* dst_frame) { |
+ if (!dst_frame || !dst_frame->IsMappable()) |
+ return false; |
+ |
+ DCHECK_GE(dst_frame->coded_size().width(), src_frame.visible_rect().width()); |
+ DCHECK_GE(dst_frame->coded_size().height(), |
+ src_frame.visible_rect().height()); |
+ DCHECK(dst_frame->visible_rect().origin().IsOrigin()); |
xhwang
2016/05/04 21:08:29
All these conditions should be documented in the h
xjz
2016/05/05 01:15:56
Done.
|
+ |
+ if (libyuv::I420Copy(src_frame.visible_data(media::VideoFrame::kYPlane), |
xhwang
2016/05/04 21:08:29
Drop media:: since you are already in media namesp
xjz
2016/05/05 01:15:56
Done.
|
+ src_frame.stride(media::VideoFrame::kYPlane), |
+ src_frame.visible_data(media::VideoFrame::kUPlane), |
+ src_frame.stride(media::VideoFrame::kUPlane), |
+ src_frame.visible_data(media::VideoFrame::kVPlane), |
+ src_frame.stride(media::VideoFrame::kVPlane), |
+ dst_frame->data(media::VideoFrame::kYPlane), |
+ dst_frame->stride(media::VideoFrame::kYPlane), |
+ dst_frame->data(media::VideoFrame::kUPlane), |
+ dst_frame->stride(media::VideoFrame::kUPlane), |
+ dst_frame->data(media::VideoFrame::kVPlane), |
+ dst_frame->stride(media::VideoFrame::kVPlane), |
+ src_frame.visible_rect().width(), |
+ src_frame.visible_rect().height())) |
+ return false; |
+ |
+ // Padding the region outside the visible rect with the repeated last |
+ // column / row of the visible rect. This can improve the coding efficiency. |
+ FillRegionOutsideVisibleRect(dst_frame->data(media::VideoFrame::kYPlane), |
+ dst_frame->coded_size(), |
+ src_frame.visible_rect().size()); |
+ FillRegionOutsideVisibleRect( |
+ dst_frame->data(media::VideoFrame::kUPlane), |
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, media::VideoFrame::kUPlane, |
+ dst_frame->coded_size()), |
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, media::VideoFrame::kUPlane, |
+ src_frame.visible_rect().size())); |
+ FillRegionOutsideVisibleRect( |
+ dst_frame->data(media::VideoFrame::kVPlane), |
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, media::VideoFrame::kVPlane, |
+ dst_frame->coded_size()), |
+ VideoFrame::PlaneSize(PIXEL_FORMAT_I420, media::VideoFrame::kVPlane, |
+ src_frame.visible_rect().size())); |
+ return true; |
+} |
+ |
} // namespace media |