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
This commit is contained in:
cc
layers
test
trees
content
browser
media
renderer
media/test/data
@ -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,
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user