diff options
author | suderman@chromium.org <suderman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 01:24:47 +0000 |
---|---|---|
committer | suderman@chromium.org <suderman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 01:24:47 +0000 |
commit | f78c3e804184183450bd79a538aec01b965338d3 (patch) | |
tree | 018535e456e0e78fc33cd2ac1f75cf43c76fbc7f | |
parent | 63e18ddaee9078a1925dff1a52693bb4c0808456 (diff) | |
download | chromium_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.cc | 14 | ||||
-rw-r--r-- | cc/layers/video_layer.h | 8 | ||||
-rw-r--r-- | cc/layers/video_layer_impl.cc | 55 | ||||
-rw-r--r-- | cc/layers/video_layer_impl.h | 12 | ||||
-rw-r--r-- | cc/layers/video_layer_impl_unittest.cc | 149 | ||||
-rw-r--r-- | cc/test/layer_test_common.h | 9 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 8 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 3 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_context.cc | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_video.cc | 10 | ||||
-rw-r--r-- | content/browser/media/media_browsertest.cc | 27 | ||||
-rw-r--r-- | content/renderer/media/android/webmediaplayer_android.cc | 3 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_impl.cc | 19 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_ms.cc | 4 | ||||
-rw-r--r-- | media/test/data/player.html | 4 |
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); |