summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsuderman@chromium.org <suderman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-08 01:24:47 +0000
committersuderman@chromium.org <suderman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-08 01:24:47 +0000
commitf78c3e804184183450bd79a538aec01b965338d3 (patch)
tree018535e456e0e78fc33cd2ac1f75cf43c76fbc7f
parent63e18ddaee9078a1925dff1a52693bb4c0808456 (diff)
downloadchromium_src-f78c3e804184183450bd79a538aec01b965338d3.zip
chromium_src-f78c3e804184183450bd79a538aec01b965338d3.tar.gz
chromium_src-f78c3e804184183450bd79a538aec01b965338d3.tar.bz2
Integrated video rotation piping into video layer {impl} and
included the transform for fixing the video orientation. BUG=47554 Review URL: https://codereview.chromium.org/388643002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288194 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/video_layer.cc14
-rw-r--r--cc/layers/video_layer.h8
-rw-r--r--cc/layers/video_layer_impl.cc55
-rw-r--r--cc/layers/video_layer_impl.h12
-rw-r--r--cc/layers/video_layer_impl_unittest.cc149
-rw-r--r--cc/test/layer_test_common.h9
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc8
-rw-r--r--cc/trees/layer_tree_host_unittest.cc3
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc6
-rw-r--r--cc/trees/layer_tree_host_unittest_video.cc10
-rw-r--r--content/browser/media/media_browsertest.cc27
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc3
-rw-r--r--content/renderer/media/webmediaplayer_impl.cc19
-rw-r--r--content/renderer/media/webmediaplayer_ms.cc4
-rw-r--r--media/test/data/player.html4
15 files changed, 294 insertions, 37 deletions
diff --git a/cc/layers/video_layer.cc b/cc/layers/video_layer.cc
index 4ddfdae..995668b 100644
--- a/cc/layers/video_layer.cc
+++ b/cc/layers/video_layer.cc
@@ -8,18 +8,24 @@
namespace cc {
-scoped_refptr<VideoLayer> VideoLayer::Create(VideoFrameProvider* provider) {
- return make_scoped_refptr(new VideoLayer(provider));
+scoped_refptr<VideoLayer> VideoLayer::Create(
+ VideoFrameProvider* provider,
+ media::VideoRotation video_rotation) {
+ return make_scoped_refptr(new VideoLayer(provider, video_rotation));
}
-VideoLayer::VideoLayer(VideoFrameProvider* provider) : provider_(provider) {
+VideoLayer::VideoLayer(VideoFrameProvider* provider,
+ media::VideoRotation video_rotation)
+ : provider_(provider), video_rotation_(video_rotation) {
DCHECK(provider_);
}
VideoLayer::~VideoLayer() {}
scoped_ptr<LayerImpl> VideoLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
- return VideoLayerImpl::Create(tree_impl, id(), provider_).PassAs<LayerImpl>();
+ scoped_ptr<VideoLayerImpl> impl =
+ VideoLayerImpl::Create(tree_impl, id(), provider_, video_rotation_);
+ return impl.PassAs<LayerImpl>();
}
bool VideoLayer::Update(ResourceUpdateQueue* queue,
diff --git a/cc/layers/video_layer.h b/cc/layers/video_layer.h
index dd2c4e1..361007d 100644
--- a/cc/layers/video_layer.h
+++ b/cc/layers/video_layer.h
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "cc/base/cc_export.h"
#include "cc/layers/layer.h"
+#include "media/base/video_rotation.h"
namespace media { class VideoFrame; }
@@ -19,7 +20,8 @@ class VideoLayerImpl;
// A Layer that contains a Video element.
class CC_EXPORT VideoLayer : public Layer {
public:
- static scoped_refptr<VideoLayer> Create(VideoFrameProvider* provider);
+ static scoped_refptr<VideoLayer> Create(VideoFrameProvider* provider,
+ media::VideoRotation video_rotation);
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
OVERRIDE;
@@ -28,13 +30,15 @@ class CC_EXPORT VideoLayer : public Layer {
const OcclusionTracker<Layer>* occlusion) OVERRIDE;
private:
- explicit VideoLayer(VideoFrameProvider* provider);
+ VideoLayer(VideoFrameProvider* provider, media::VideoRotation video_rotation);
virtual ~VideoLayer();
// This pointer is only for passing to VideoLayerImpl's constructor. It should
// never be dereferenced by this class.
VideoFrameProvider* provider_;
+ media::VideoRotation video_rotation_;
+
DISALLOW_COPY_AND_ASSIGN(VideoLayer);
};
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index 7b4234c..fc04a26 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -28,17 +28,21 @@ namespace cc {
scoped_ptr<VideoLayerImpl> VideoLayerImpl::Create(
LayerTreeImpl* tree_impl,
int id,
- VideoFrameProvider* provider) {
- scoped_ptr<VideoLayerImpl> layer(new VideoLayerImpl(tree_impl, id));
+ VideoFrameProvider* provider,
+ media::VideoRotation video_rotation) {
+ scoped_ptr<VideoLayerImpl> layer(
+ new VideoLayerImpl(tree_impl, id, video_rotation));
layer->SetProviderClientImpl(VideoFrameProviderClientImpl::Create(provider));
DCHECK(tree_impl->proxy()->IsImplThread());
DCHECK(tree_impl->proxy()->IsMainThreadBlocked());
return layer.Pass();
}
-VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* tree_impl, int id)
- : LayerImpl(tree_impl, id),
- frame_(NULL) {}
+VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* tree_impl,
+ int id,
+ media::VideoRotation video_rotation)
+ : LayerImpl(tree_impl, id), frame_(NULL), video_rotation_(video_rotation) {
+}
VideoLayerImpl::~VideoLayerImpl() {
if (!provider_client_impl_->Stopped()) {
@@ -55,7 +59,8 @@ VideoLayerImpl::~VideoLayerImpl() {
scoped_ptr<LayerImpl> VideoLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return scoped_ptr<LayerImpl>(new VideoLayerImpl(tree_impl, id()));
+ VideoLayerImpl* impl = new VideoLayerImpl(tree_impl, id(), video_rotation_);
+ return scoped_ptr<LayerImpl>(impl);
}
void VideoLayerImpl::PushPropertiesTo(LayerImpl* layer) {
@@ -130,20 +135,48 @@ void VideoLayerImpl::AppendQuads(
AppendQuadsData* append_quads_data) {
DCHECK(frame_.get());
+ gfx::Transform transform = draw_transform();
+ gfx::Size rotated_size = content_bounds();
+
+ switch (video_rotation_) {
+ case media::VIDEO_ROTATION_90:
+ rotated_size = gfx::Size(rotated_size.height(), rotated_size.width());
+ transform.Rotate(90.0);
+ transform.Translate(0.0, -rotated_size.height());
+ break;
+ case media::VIDEO_ROTATION_180:
+ transform.Rotate(180.0);
+ transform.Translate(-rotated_size.width(), -rotated_size.height());
+ break;
+ case media::VIDEO_ROTATION_270:
+ rotated_size = gfx::Size(rotated_size.height(), rotated_size.width());
+ transform.Rotate(270.0);
+ transform.Translate(-rotated_size.width(), 0);
+ case media::VIDEO_ROTATION_0:
+ break;
+ }
+
SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
- PopulateSharedQuadState(shared_quad_state);
+ shared_quad_state->SetAll(transform,
+ rotated_size,
+ visible_content_rect(),
+ clip_rect(),
+ is_clipped(),
+ draw_opacity(),
+ blend_mode(),
+ sorting_context_id());
AppendDebugBorderQuad(
- render_pass, content_bounds(), shared_quad_state, append_quads_data);
+ render_pass, rotated_size, shared_quad_state, append_quads_data);
- gfx::Rect quad_rect(content_bounds());
+ gfx::Rect quad_rect(rotated_size);
gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
gfx::Rect visible_rect = frame_->visible_rect();
gfx::Size coded_size = frame_->coded_size();
- gfx::Rect visible_quad_rect = occlusion_tracker.UnoccludedContentRect(
- quad_rect, draw_properties().target_space_transform);
+ gfx::Rect visible_quad_rect =
+ occlusion_tracker.UnoccludedContentRect(quad_rect, transform);
if (visible_quad_rect.IsEmpty())
return;
diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h
index dd09589..d2e0fe3 100644
--- a/cc/layers/video_layer_impl.h
+++ b/cc/layers/video_layer_impl.h
@@ -11,6 +11,7 @@
#include "cc/layers/layer_impl.h"
#include "cc/resources/release_callback.h"
#include "cc/resources/video_resource_updater.h"
+#include "media/base/video_rotation.h"
namespace media {
class VideoFrame;
@@ -24,7 +25,8 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
public:
static scoped_ptr<VideoLayerImpl> Create(LayerTreeImpl* tree_impl,
int id,
- VideoFrameProvider* provider);
+ VideoFrameProvider* provider,
+ media::VideoRotation video_rotation);
virtual ~VideoLayerImpl();
// LayerImpl implementation.
@@ -45,8 +47,12 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
void SetProviderClientImpl(
scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl);
+ media::VideoRotation video_rotation() const { return video_rotation_; }
+
private:
- VideoLayerImpl(LayerTreeImpl* tree_impl, int id);
+ VideoLayerImpl(LayerTreeImpl* tree_impl,
+ int id,
+ media::VideoRotation video_rotation);
virtual const char* LayerTypeAsString() const OVERRIDE;
@@ -54,6 +60,8 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl {
scoped_refptr<media::VideoFrame> frame_;
+ media::VideoRotation video_rotation_;
+
scoped_ptr<VideoResourceUpdater> updater_;
VideoFrameExternalResources::ResourceType frame_resource_type_;
std::vector<ResourceProvider::ResourceId> frame_resources_;
diff --git a/cc/layers/video_layer_impl_unittest.cc b/cc/layers/video_layer_impl_unittest.cc
index 7a17eef..03fafc0 100644
--- a/cc/layers/video_layer_impl_unittest.cc
+++ b/cc/layers/video_layer_impl_unittest.cc
@@ -7,6 +7,7 @@
#include "cc/layers/video_frame_provider_client_impl.h"
#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
+#include "cc/quads/draw_quad.h"
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/layer_test_common.h"
#include "cc/trees/single_thread_proxy.h"
@@ -33,7 +34,7 @@ TEST(VideoLayerImplTest, Occlusion) {
provider.set_frame(video_frame);
VideoLayerImpl* video_layer_impl =
- impl.AddChildToRoot<VideoLayerImpl>(&provider);
+ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
video_layer_impl->SetBounds(layer_size);
video_layer_impl->SetContentBounds(layer_size);
video_layer_impl->SetDrawsContent(true);
@@ -82,7 +83,7 @@ TEST(VideoLayerImplTest, DidBecomeActiveShouldSetActiveVideoLayer) {
FakeVideoFrameProvider provider;
VideoLayerImpl* video_layer_impl =
- impl.AddChildToRoot<VideoLayerImpl>(&provider);
+ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
VideoFrameProviderClientImpl* client =
static_cast<VideoFrameProviderClientImpl*>(provider.client());
@@ -93,5 +94,149 @@ TEST(VideoLayerImplTest, DidBecomeActiveShouldSetActiveVideoLayer) {
EXPECT_EQ(video_layer_impl, client->active_video_layer());
}
+TEST(VideoLayerImplTest, Rotated0) {
+ gfx::Size layer_size(100, 50);
+ gfx::Size viewport_size(1000, 500);
+
+ LayerTestCommon::LayerImplTest impl;
+ DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
+
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
+ gfx::Size(20, 10),
+ gfx::Rect(20, 10),
+ gfx::Size(20, 10),
+ base::TimeDelta());
+ FakeVideoFrameProvider provider;
+ provider.set_frame(video_frame);
+
+ VideoLayerImpl* video_layer_impl =
+ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
+ video_layer_impl->SetBounds(layer_size);
+ video_layer_impl->SetContentBounds(layer_size);
+ video_layer_impl->SetDrawsContent(true);
+
+ impl.CalcDrawProps(viewport_size);
+ gfx::Rect occluded;
+ impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
+
+ EXPECT_EQ(1u, impl.quad_list().size());
+
+ gfx::Point3F p1(0, impl.quad_list()[0]->rect.height(), 0);
+ gfx::Point3F p2(impl.quad_list()[0]->rect.width(), 0, 0);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p1);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p2);
+ EXPECT_EQ(gfx::Point3F(0, 50, 0), p1);
+ EXPECT_EQ(gfx::Point3F(100, 0, 0), p2);
+}
+
+TEST(VideoLayerImplTest, Rotated90) {
+ gfx::Size layer_size(100, 50);
+ gfx::Size viewport_size(1000, 500);
+
+ LayerTestCommon::LayerImplTest impl;
+ DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
+
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
+ gfx::Size(20, 10),
+ gfx::Rect(20, 10),
+ gfx::Size(20, 10),
+ base::TimeDelta());
+ FakeVideoFrameProvider provider;
+ provider.set_frame(video_frame);
+
+ VideoLayerImpl* video_layer_impl =
+ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_90);
+ video_layer_impl->SetBounds(layer_size);
+ video_layer_impl->SetContentBounds(layer_size);
+ video_layer_impl->SetDrawsContent(true);
+
+ impl.CalcDrawProps(viewport_size);
+ gfx::Rect occluded;
+ impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
+
+ EXPECT_EQ(1u, impl.quad_list().size());
+
+ gfx::Point3F p1(0, impl.quad_list()[0]->rect.height(), 0);
+ gfx::Point3F p2(impl.quad_list()[0]->rect.width(), 0, 0);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p1);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p2);
+ EXPECT_EQ(gfx::Point3F(0, 0, 0), p1);
+ EXPECT_EQ(gfx::Point3F(100, 50, 0), p2);
+}
+
+TEST(VideoLayerImplTest, Rotated180) {
+ gfx::Size layer_size(100, 50);
+ gfx::Size viewport_size(1000, 500);
+
+ LayerTestCommon::LayerImplTest impl;
+ DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
+
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
+ gfx::Size(20, 10),
+ gfx::Rect(20, 10),
+ gfx::Size(20, 10),
+ base::TimeDelta());
+ FakeVideoFrameProvider provider;
+ provider.set_frame(video_frame);
+
+ VideoLayerImpl* video_layer_impl =
+ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_180);
+ video_layer_impl->SetBounds(layer_size);
+ video_layer_impl->SetContentBounds(layer_size);
+ video_layer_impl->SetDrawsContent(true);
+
+ impl.CalcDrawProps(viewport_size);
+ gfx::Rect occluded;
+ impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
+
+ EXPECT_EQ(1u, impl.quad_list().size());
+
+ gfx::Point3F p1(0, impl.quad_list()[0]->rect.height(), 0);
+ gfx::Point3F p2(impl.quad_list()[0]->rect.width(), 0, 0);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p1);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p2);
+ EXPECT_EQ(gfx::Point3F(100, 0, 0), p1);
+ EXPECT_EQ(gfx::Point3F(0, 50, 0), p2);
+}
+
+TEST(VideoLayerImplTest, Rotated270) {
+ gfx::Size layer_size(100, 50);
+ gfx::Size viewport_size(1000, 500);
+
+ LayerTestCommon::LayerImplTest impl;
+ DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
+
+ scoped_refptr<media::VideoFrame> video_frame =
+ media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
+ gfx::Size(20, 10),
+ gfx::Rect(20, 10),
+ gfx::Size(20, 10),
+ base::TimeDelta());
+ FakeVideoFrameProvider provider;
+ provider.set_frame(video_frame);
+
+ VideoLayerImpl* video_layer_impl =
+ impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_270);
+ video_layer_impl->SetBounds(layer_size);
+ video_layer_impl->SetContentBounds(layer_size);
+ video_layer_impl->SetDrawsContent(true);
+
+ impl.CalcDrawProps(viewport_size);
+ gfx::Rect occluded;
+ impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
+
+ EXPECT_EQ(1u, impl.quad_list().size());
+
+ gfx::Point3F p1(0, impl.quad_list()[0]->rect.height(), 0);
+ gfx::Point3F p2(impl.quad_list()[0]->rect.width(), 0, 0);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p1);
+ impl.quad_list()[0]->quadTransform().TransformPoint(&p2);
+ EXPECT_EQ(gfx::Point3F(100, 50, 0), p1);
+ EXPECT_EQ(gfx::Point3F(0, 0, 0), p2);
+}
+
} // namespace
} // namespace cc
diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h
index 3b967ec..e74ea6d 100644
--- a/cc/test/layer_test_common.h
+++ b/cc/test/layer_test_common.h
@@ -69,6 +69,15 @@ class LayerTestCommon {
return ptr;
}
+ template <typename T, typename A, typename B>
+ T* AddChildToRoot(const A& a, const B& b) {
+ scoped_ptr<T> layer =
+ T::Create(host_->host_impl()->active_tree(), 2, a, b);
+ T* ptr = layer.get();
+ root_layer_impl_->AddChild(layer.template PassAs<LayerImpl>());
+ return ptr;
+ }
+
template <typename T, typename A, typename B, typename C, typename D>
T* AddChildToRoot(const A& a, const B& b, const C& c, const D& d) {
scoped_ptr<T> layer =
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index a940e34..5d45d53 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -4577,8 +4577,8 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
FakeVideoFrameProvider provider;
provider.set_frame(softwareFrame);
- scoped_ptr<VideoLayerImpl> video_layer =
- VideoLayerImpl::Create(host_impl_->active_tree(), 4, &provider);
+ scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
+ host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0);
video_layer->SetBounds(gfx::Size(10, 10));
video_layer->SetContentBounds(gfx::Size(10, 10));
video_layer->SetDrawsContent(true);
@@ -5622,8 +5622,8 @@ TEST_F(LayerTreeHostImplTest,
// VideoLayerImpl will not be drawn.
FakeVideoFrameProvider provider;
- scoped_ptr<VideoLayerImpl> video_layer =
- VideoLayerImpl::Create(host_impl_->active_tree(), 2, &provider);
+ scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
+ host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0);
video_layer->SetBounds(gfx::Size(10, 10));
video_layer->SetContentBounds(gfx::Size(10, 10));
video_layer->SetDrawsContent(true);
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 5c69225..ea806aa 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3998,7 +3998,8 @@ class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
public:
virtual void SetupTree() OVERRIDE {
LayerTreeHostTest::SetupTree();
- scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
+ scoped_refptr<VideoLayer> video_layer =
+ VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0);
video_layer->SetBounds(gfx::Size(10, 10));
video_layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(video_layer);
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 879e534..80898d2 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -761,19 +761,19 @@ class LayerTreeHostContextTestDontUseLostResources
root->AddChild(content_with_mask);
scoped_refptr<VideoLayer> video_color =
- VideoLayer::Create(&color_frame_provider_);
+ VideoLayer::Create(&color_frame_provider_, media::VIDEO_ROTATION_0);
video_color->SetBounds(gfx::Size(10, 10));
video_color->SetIsDrawable(true);
root->AddChild(video_color);
scoped_refptr<VideoLayer> video_hw =
- VideoLayer::Create(&hw_frame_provider_);
+ VideoLayer::Create(&hw_frame_provider_, media::VIDEO_ROTATION_0);
video_hw->SetBounds(gfx::Size(10, 10));
video_hw->SetIsDrawable(true);
root->AddChild(video_hw);
scoped_refptr<VideoLayer> video_scaled_hw =
- VideoLayer::Create(&scaled_hw_frame_provider_);
+ VideoLayer::Create(&scaled_hw_frame_provider_, media::VIDEO_ROTATION_0);
video_scaled_hw->SetBounds(gfx::Size(10, 10));
video_scaled_hw->SetIsDrawable(true);
root->AddChild(video_scaled_hw);
diff --git a/cc/trees/layer_tree_host_unittest_video.cc b/cc/trees/layer_tree_host_unittest_video.cc
index 5484e4c..7d0bb41 100644
--- a/cc/trees/layer_tree_host_unittest_video.cc
+++ b/cc/trees/layer_tree_host_unittest_video.cc
@@ -27,10 +27,10 @@ class LayerTreeHostVideoTestSetNeedsDisplay
root->SetBounds(gfx::Size(10, 10));
root->SetIsDrawable(true);
- scoped_refptr<VideoLayer> video = VideoLayer::Create(
- &video_frame_provider_);
+ scoped_refptr<VideoLayer> video =
+ VideoLayer::Create(&video_frame_provider_, media::VIDEO_ROTATION_90);
video->SetPosition(gfx::PointF(3.f, 3.f));
- video->SetBounds(gfx::Size(4, 4));
+ video->SetBounds(gfx::Size(4, 5));
video->SetIsDrawable(true);
root->AddChild(video);
@@ -60,7 +60,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay
break;
case 1:
// Second frame the video layer is damaged.
- EXPECT_EQ(gfx::RectF(6.f, 6.f, 8.f, 8.f).ToString(),
+ EXPECT_EQ(gfx::RectF(6.f, 6.f, 8.f, 10.f).ToString(),
damage_rect.ToString());
EndTest();
break;
@@ -74,6 +74,8 @@ class LayerTreeHostVideoTestSetNeedsDisplay
VideoLayerImpl* video = static_cast<VideoLayerImpl*>(
host_impl->active_tree()->root_layer()->children()[0]);
+ EXPECT_EQ(media::VIDEO_ROTATION_90, video->video_rotation());
+
if (num_draws_ == 0)
video->SetNeedsRedraw();
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc
index 0ca34d1..0ffc029 100644
--- a/content/browser/media/media_browsertest.cc
+++ b/content/browser/media/media_browsertest.cc
@@ -4,6 +4,7 @@
#include "content/browser/media/media_browsertest.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
@@ -97,6 +98,16 @@ class MediaTest : public testing::WithParamInterface<bool>,
query_params.push_back(std::make_pair(tag, media_file));
RunMediaTestPage("player.html", query_params, kEnded, http);
}
+
+ void RunVideoSizeTest(const char* media_file, int width, int height) {
+ std::string expected;
+ expected += base::IntToString(width);
+ expected += " ";
+ expected += base::IntToString(height);
+ media::QueryParams query_params;
+ query_params.push_back(std::make_pair("video", media_file));
+ RunMediaTestPage("player.html", query_params, expected, false);
+ }
};
IN_PROC_BROWSER_TEST_P(MediaTest, VideoBearTheora) {
@@ -142,6 +153,22 @@ IN_PROC_BROWSER_TEST_P(MediaTest, VideoBearMovPcmS16be) {
IN_PROC_BROWSER_TEST_P(MediaTest, VideoBearMovPcmS24be) {
PlayVideo("bear_pcm_s24be.mov", GetParam());
}
+
+IN_PROC_BROWSER_TEST_F(MediaTest, VideoBearRotated0) {
+ RunVideoSizeTest("bear_rotate_0.mp4", 1280, 720);
+}
+
+IN_PROC_BROWSER_TEST_F(MediaTest, VideoBearRotated90) {
+ RunVideoSizeTest("bear_rotate_90.mp4", 720, 1280);
+}
+
+IN_PROC_BROWSER_TEST_F(MediaTest, VideoBearRotated180) {
+ RunVideoSizeTest("bear_rotate_180.mp4", 1280, 720);
+}
+
+IN_PROC_BROWSER_TEST_F(MediaTest, VideoBearRotated270) {
+ RunVideoSizeTest("bear_rotate_270.mp4", 720, 1280);
+}
#endif // defined(USE_PROPRIETARY_CODECS)
#if defined(OS_CHROMEOS)
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 2a050c5..43886fc 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -786,7 +786,8 @@ void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
// Lazily allocate compositing layer.
if (!video_weblayer_) {
- video_weblayer_.reset(new WebLayerImpl(cc::VideoLayer::Create(this)));
+ video_weblayer_.reset(new WebLayerImpl(
+ cc::VideoLayer::Create(this, media::VIDEO_ROTATION_0)));
client_->setWebLayer(video_weblayer_.get());
}
diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc
index 35af6cd..7aad83b 100644
--- a/content/renderer/media/webmediaplayer_impl.cc
+++ b/content/renderer/media/webmediaplayer_impl.cc
@@ -546,6 +546,13 @@ void WebMediaPlayerImpl::paint(WebCanvas* canvas,
GetCurrentFrameFromCompositor();
gfx::Rect gfx_rect(rect);
+
+ if (pipeline_metadata_.video_rotation == media::VIDEO_ROTATION_90 ||
+ pipeline_metadata_.video_rotation == media::VIDEO_ROTATION_270) {
+ gfx_rect.set_size(gfx::Size(gfx_rect.size().height(),
+ gfx_rect.size().width()));
+ }
+
skcanvas_video_renderer_.Paint(video_frame.get(), canvas, gfx_rect, alpha);
}
@@ -945,8 +952,16 @@ void WebMediaPlayerImpl::OnPipelineMetadata(
if (hasVideo()) {
DCHECK(!video_weblayer_);
- video_weblayer_.reset(
- new WebLayerImpl(cc::VideoLayer::Create(compositor_)));
+ scoped_refptr<cc::VideoLayer> layer =
+ cc::VideoLayer::Create(compositor_, pipeline_metadata_.video_rotation);
+
+ if (pipeline_metadata_.video_rotation == media::VIDEO_ROTATION_90 ||
+ pipeline_metadata_.video_rotation == media::VIDEO_ROTATION_270) {
+ gfx::Size size = pipeline_metadata_.natural_size;
+ pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width());
+ }
+
+ video_weblayer_.reset(new WebLayerImpl(layer));
video_weblayer_->setOpaque(opaque_);
client_->setWebLayer(video_weblayer_.get());
}
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc
index 45bcc7b..f433231 100644
--- a/content/renderer/media/webmediaplayer_ms.cc
+++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -21,6 +21,7 @@
#include "content/renderer/render_frame_impl.h"
#include "media/base/media_log.h"
#include "media/base/video_frame.h"
+#include "media/base/video_rotation.h"
#include "media/base/video_util.h"
#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
#include "third_party/WebKit/public/platform/WebRect.h"
@@ -416,7 +417,8 @@ void WebMediaPlayerMS::OnFrameAvailable(
GetClient()->sizeChanged();
if (video_frame_provider_) {
- video_weblayer_.reset(new WebLayerImpl(cc::VideoLayer::Create(this)));
+ video_weblayer_.reset(new WebLayerImpl(
+ cc::VideoLayer::Create(this, media::VIDEO_ROTATION_0)));
video_weblayer_->setOpaque(true);
GetClient()->setWebLayer(video_weblayer_.get());
}
diff --git a/media/test/data/player.html b/media/test/data/player.html
index e954cf8..fa50d73 100644
--- a/media/test/data/player.html
+++ b/media/test/data/player.html
@@ -61,6 +61,10 @@ function RunTest() {
player.controls = true;
document.getElementById('player_container').appendChild(player);
+ player.addEventListener('loadedmetadata', function(e) {
+ document.title = '' + player.videoWidth + ' ' + player.videoHeight;
+ });
+
// Transition to the seek test after X seconds of playback or when the ended
// event occurs, whichever happens first.
player.addEventListener('ended', SeekTestStep, false);