Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / filters / skcanvas_video_renderer_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/base/video_frame.h"
6 #include "media/base/video_util.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/skia/include/core/SkCanvas.h"
9 #include "media/filters/skcanvas_video_renderer.h"
10
11 using media::VideoFrame;
12
13 namespace media {
14
15 static const int kWidth = 320;
16 static const int kHeight = 240;
17 static const gfx::Rect kNaturalRect(0, 0, kWidth, kHeight);
18
19 // Helper for filling a |canvas| with a solid |color|.
20 void FillCanvas(SkCanvas* canvas, SkColor color) {
21   canvas->clear(color);
22 }
23
24 // Helper for returning the color of a solid |canvas|.
25 SkColor GetColorAt(SkCanvas* canvas, int x, int y) {
26   SkBitmap bitmap;
27   if (!bitmap.allocN32Pixels(1, 1))
28     return 0;
29   if (!canvas->readPixels(&bitmap, x, y))
30     return 0;
31   return bitmap.getColor(0, 0);
32 }
33
34 SkColor GetColor(SkCanvas* canvas) {
35   return GetColorAt(canvas, 0, 0);
36 }
37
38 class SkCanvasVideoRendererTest : public testing::Test {
39  public:
40   enum Color {
41     kNone,
42     kRed,
43     kGreen,
44     kBlue,
45   };
46
47   SkCanvasVideoRendererTest();
48   virtual ~SkCanvasVideoRendererTest();
49
50   // Paints to |canvas| using |renderer_| without any frame data.
51   void PaintWithoutFrame(SkCanvas* canvas);
52
53   // Paints the |video_frame| to the |canvas| using |renderer_|, setting the
54   // color of |video_frame| to |color| first.
55   void Paint(VideoFrame* video_frame, SkCanvas* canvas, Color color);
56
57   // Getters for various frame sizes.
58   VideoFrame* natural_frame() { return natural_frame_.get(); }
59   VideoFrame* larger_frame() { return larger_frame_.get(); }
60   VideoFrame* smaller_frame() { return smaller_frame_.get(); }
61   VideoFrame* cropped_frame() { return cropped_frame_.get(); }
62
63   // Getters for canvases that trigger the various painting paths.
64   SkCanvas* fast_path_canvas() { return &fast_path_canvas_; }
65   SkCanvas* slow_path_canvas() { return &slow_path_canvas_; }
66
67  private:
68   SkCanvasVideoRenderer renderer_;
69
70   scoped_refptr<VideoFrame> natural_frame_;
71   scoped_refptr<VideoFrame> larger_frame_;
72   scoped_refptr<VideoFrame> smaller_frame_;
73   scoped_refptr<VideoFrame> cropped_frame_;
74
75   SkCanvas fast_path_canvas_;
76   SkCanvas slow_path_canvas_;
77
78   DISALLOW_COPY_AND_ASSIGN(SkCanvasVideoRendererTest);
79 };
80
81 static SkBitmap AllocBitmap(int width, int height, bool isOpaque) {
82   SkAlphaType alpha_type = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
83   SkBitmap bitmap;
84
85   bitmap.allocPixels(SkImageInfo::MakeN32(width, height, alpha_type));
86   if (!isOpaque)
87     bitmap.eraseColor(0);
88   return bitmap;
89 }
90
91 SkCanvasVideoRendererTest::SkCanvasVideoRendererTest()
92     : natural_frame_(VideoFrame::CreateBlackFrame(gfx::Size(kWidth, kHeight))),
93       larger_frame_(VideoFrame::CreateBlackFrame(
94           gfx::Size(kWidth * 2, kHeight * 2))),
95       smaller_frame_(VideoFrame::CreateBlackFrame(
96           gfx::Size(kWidth / 2, kHeight / 2))),
97       cropped_frame_(VideoFrame::CreateFrame(
98           VideoFrame::YV12,
99           gfx::Size(16, 16),
100           gfx::Rect(6, 6, 8, 6),
101           gfx::Size(8, 6),
102           base::TimeDelta::FromMilliseconds(4))),
103       fast_path_canvas_(AllocBitmap(kWidth, kHeight, true)),
104       slow_path_canvas_(AllocBitmap(kWidth, kHeight, false)) {
105   // Give each frame a unique timestamp.
106   natural_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(1));
107   larger_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(2));
108   smaller_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(3));
109
110   // Make sure the cropped video frame's aspect ratio matches the output device.
111   // Update cropped_frame_'s crop dimensions if this is not the case.
112   EXPECT_EQ(cropped_frame()->visible_rect().width() * kHeight,
113             cropped_frame()->visible_rect().height() * kWidth);
114
115   // Fill in the cropped frame's entire data with colors:
116   //
117   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
118   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
119   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
120   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
121   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
122   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
123   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
124   //   Bl Bl Bl Bl Bl Bl Bl Bl R  R  R  R  R  R  R  R
125   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
126   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
127   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
128   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
129   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
130   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
131   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
132   //   G  G  G  G  G  G  G  G  B  B  B  B  B  B  B  B
133   //
134   // The visible crop of the frame (as set by its visible_rect_) has contents:
135   //
136   //   Bl Bl R  R  R  R  R  R
137   //   Bl Bl R  R  R  R  R  R
138   //   G  G  B  B  B  B  B  B
139   //   G  G  B  B  B  B  B  B
140   //   G  G  B  B  B  B  B  B
141   //   G  G  B  B  B  B  B  B
142   //
143   // Each color region in the cropped frame is on a 2x2 block granularity, to
144   // avoid sharing UV samples between regions.
145
146   static const uint8 cropped_y_plane[] = {
147       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
148       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
149       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
150       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
151       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
152       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
153       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
154       0,   0,   0,   0,   0,   0,   0,   0, 76, 76, 76, 76, 76, 76, 76, 76,
155     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
156     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
157     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
158     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
159     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
160     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
161     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
162     149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
163   };
164
165   static const uint8 cropped_u_plane[] = {
166     128, 128, 128, 128,  84,  84,  84,  84,
167     128, 128, 128, 128,  84,  84,  84,  84,
168     128, 128, 128, 128,  84,  84,  84,  84,
169     128, 128, 128, 128,  84,  84,  84,  84,
170      43,  43,  43,  43, 255, 255, 255, 255,
171      43,  43,  43,  43, 255, 255, 255, 255,
172      43,  43,  43,  43, 255, 255, 255, 255,
173      43,  43,  43,  43, 255, 255, 255, 255,
174   };
175   static const uint8 cropped_v_plane[] = {
176     128, 128, 128, 128, 255, 255, 255, 255,
177     128, 128, 128, 128, 255, 255, 255, 255,
178     128, 128, 128, 128, 255, 255, 255, 255,
179     128, 128, 128, 128, 255, 255, 255, 255,
180      21,  21,  21,  21, 107, 107, 107, 107,
181      21,  21,  21,  21, 107, 107, 107, 107,
182      21,  21,  21,  21, 107, 107, 107, 107,
183      21,  21,  21,  21, 107, 107, 107, 107,
184   };
185
186   media::CopyYPlane(cropped_y_plane, 16, 16, cropped_frame());
187   media::CopyUPlane(cropped_u_plane, 8, 8, cropped_frame());
188   media::CopyVPlane(cropped_v_plane, 8, 8, cropped_frame());
189 }
190
191 SkCanvasVideoRendererTest::~SkCanvasVideoRendererTest() {}
192
193 void SkCanvasVideoRendererTest::PaintWithoutFrame(SkCanvas* canvas) {
194   renderer_.Paint(NULL, canvas, kNaturalRect, 0xFF);
195 }
196
197 void SkCanvasVideoRendererTest::Paint(VideoFrame* video_frame,
198                                       SkCanvas* canvas,
199                                       Color color) {
200   switch (color) {
201     case kNone:
202       break;
203     case kRed:
204       media::FillYUV(video_frame, 76, 84, 255);
205       break;
206     case kGreen:
207       media::FillYUV(video_frame, 149, 43, 21);
208       break;
209     case kBlue:
210       media::FillYUV(video_frame, 29, 255, 107);
211       break;
212   }
213   renderer_.Paint(video_frame, canvas, kNaturalRect, 0xFF);
214 }
215
216 TEST_F(SkCanvasVideoRendererTest, FastPaint_NoFrame) {
217   // Test that black gets painted over canvas.
218   FillCanvas(fast_path_canvas(), SK_ColorRED);
219   PaintWithoutFrame(fast_path_canvas());
220   EXPECT_EQ(SK_ColorBLACK, GetColor(fast_path_canvas()));
221 }
222
223 TEST_F(SkCanvasVideoRendererTest, SlowPaint_NoFrame) {
224   // Test that black gets painted over canvas.
225   FillCanvas(slow_path_canvas(), SK_ColorRED);
226   PaintWithoutFrame(slow_path_canvas());
227   EXPECT_EQ(SK_ColorBLACK, GetColor(slow_path_canvas()));
228 }
229
230 TEST_F(SkCanvasVideoRendererTest, FastPaint_Natural) {
231   Paint(natural_frame(), fast_path_canvas(), kRed);
232   EXPECT_EQ(SK_ColorRED, GetColor(fast_path_canvas()));
233 }
234
235 TEST_F(SkCanvasVideoRendererTest, SlowPaint_Natural) {
236   Paint(natural_frame(), slow_path_canvas(), kRed);
237   EXPECT_EQ(SK_ColorRED, GetColor(slow_path_canvas()));
238 }
239
240 TEST_F(SkCanvasVideoRendererTest, FastPaint_Larger) {
241   Paint(natural_frame(), fast_path_canvas(), kRed);
242   EXPECT_EQ(SK_ColorRED, GetColor(fast_path_canvas()));
243
244   Paint(larger_frame(), fast_path_canvas(), kBlue);
245   EXPECT_EQ(SK_ColorBLUE, GetColor(fast_path_canvas()));
246 }
247
248 TEST_F(SkCanvasVideoRendererTest, SlowPaint_Larger) {
249   Paint(natural_frame(), slow_path_canvas(), kRed);
250   EXPECT_EQ(SK_ColorRED, GetColor(slow_path_canvas()));
251
252   Paint(larger_frame(), slow_path_canvas(), kBlue);
253   EXPECT_EQ(SK_ColorBLUE, GetColor(slow_path_canvas()));
254 }
255
256 TEST_F(SkCanvasVideoRendererTest, FastPaint_Smaller) {
257   Paint(natural_frame(), fast_path_canvas(), kRed);
258   EXPECT_EQ(SK_ColorRED, GetColor(fast_path_canvas()));
259
260   Paint(smaller_frame(), fast_path_canvas(), kBlue);
261   EXPECT_EQ(SK_ColorBLUE, GetColor(fast_path_canvas()));
262 }
263
264 TEST_F(SkCanvasVideoRendererTest, SlowPaint_Smaller) {
265   Paint(natural_frame(), slow_path_canvas(), kRed);
266   EXPECT_EQ(SK_ColorRED, GetColor(slow_path_canvas()));
267
268   Paint(smaller_frame(), slow_path_canvas(), kBlue);
269   EXPECT_EQ(SK_ColorBLUE, GetColor(slow_path_canvas()));
270 }
271
272 TEST_F(SkCanvasVideoRendererTest, FastPaint_NoTimestamp) {
273   VideoFrame* video_frame = natural_frame();
274   video_frame->set_timestamp(media::kNoTimestamp());
275   Paint(video_frame, fast_path_canvas(), kRed);
276   EXPECT_EQ(SK_ColorRED, GetColor(fast_path_canvas()));
277 }
278
279 TEST_F(SkCanvasVideoRendererTest, SlowPaint_NoTimestamp) {
280   VideoFrame* video_frame = natural_frame();
281   video_frame->set_timestamp(media::kNoTimestamp());
282   Paint(video_frame, slow_path_canvas(), kRed);
283   EXPECT_EQ(SK_ColorRED, GetColor(slow_path_canvas()));
284 }
285
286 TEST_F(SkCanvasVideoRendererTest, FastPaint_SameVideoFrame) {
287   Paint(natural_frame(), fast_path_canvas(), kRed);
288   EXPECT_EQ(SK_ColorRED, GetColor(fast_path_canvas()));
289
290   // Fast paints always get painted to the canvas.
291   Paint(natural_frame(), fast_path_canvas(), kBlue);
292   EXPECT_EQ(SK_ColorBLUE, GetColor(fast_path_canvas()));
293 }
294
295 TEST_F(SkCanvasVideoRendererTest, SlowPaint_SameVideoFrame) {
296   Paint(natural_frame(), slow_path_canvas(), kRed);
297   EXPECT_EQ(SK_ColorRED, GetColor(slow_path_canvas()));
298
299   // Slow paints can get cached, expect the old color value.
300   Paint(natural_frame(), slow_path_canvas(), kBlue);
301   EXPECT_EQ(SK_ColorRED, GetColor(slow_path_canvas()));
302 }
303
304 TEST_F(SkCanvasVideoRendererTest, FastPaint_CroppedFrame) {
305   Paint(cropped_frame(), fast_path_canvas(), kNone);
306   // Check the corners.
307   EXPECT_EQ(SK_ColorBLACK, GetColorAt(fast_path_canvas(), 0, 0));
308   EXPECT_EQ(SK_ColorRED,   GetColorAt(fast_path_canvas(), kWidth - 1, 0));
309   EXPECT_EQ(SK_ColorGREEN, GetColorAt(fast_path_canvas(), 0, kHeight - 1));
310   EXPECT_EQ(SK_ColorBLUE,  GetColorAt(fast_path_canvas(), kWidth - 1,
311                                                           kHeight - 1));
312   // Check the interior along the border between color regions.  Note that we're
313   // bilinearly upscaling, so we'll need to take care to pick sample points that
314   // are just outside the "zone of resampling".
315   // TODO(sheu): commenting out two checks due to http://crbug.com/158462.
316 #if 0
317   EXPECT_EQ(SK_ColorBLACK, GetColorAt(fast_path_canvas(), kWidth  * 1 / 8 - 1,
318                                                           kHeight * 1 / 6 - 1));
319 #endif
320   EXPECT_EQ(SK_ColorRED,   GetColorAt(fast_path_canvas(), kWidth  * 3 / 8,
321                                                           kHeight * 1 / 6 - 1));
322 #if 0
323   EXPECT_EQ(SK_ColorGREEN, GetColorAt(fast_path_canvas(), kWidth  * 1 / 8 - 1,
324                                                           kHeight * 3 / 6));
325 #endif
326   EXPECT_EQ(SK_ColorBLUE,  GetColorAt(fast_path_canvas(), kWidth  * 3 / 8,
327                                                           kHeight * 3 / 6));
328 }
329
330 TEST_F(SkCanvasVideoRendererTest, SlowPaint_CroppedFrame) {
331   Paint(cropped_frame(), slow_path_canvas(), kNone);
332   // Check the corners.
333   EXPECT_EQ(SK_ColorBLACK, GetColorAt(slow_path_canvas(), 0, 0));
334   EXPECT_EQ(SK_ColorRED,   GetColorAt(slow_path_canvas(), kWidth - 1, 0));
335   EXPECT_EQ(SK_ColorGREEN, GetColorAt(slow_path_canvas(), 0, kHeight - 1));
336   EXPECT_EQ(SK_ColorBLUE,  GetColorAt(slow_path_canvas(), kWidth - 1,
337                                                           kHeight - 1));
338   // Check the interior along the border between color regions.  Note that we're
339   // bilinearly upscaling, so we'll need to take care to pick sample points that
340   // are just outside the "zone of resampling".
341   EXPECT_EQ(SK_ColorBLACK, GetColorAt(slow_path_canvas(), kWidth  * 1 / 8 - 1,
342                                                           kHeight * 1 / 6 - 1));
343   EXPECT_EQ(SK_ColorRED,   GetColorAt(slow_path_canvas(), kWidth  * 3 / 8,
344                                                           kHeight * 1 / 6 - 1));
345   EXPECT_EQ(SK_ColorGREEN, GetColorAt(slow_path_canvas(), kWidth  * 1 / 8 - 1,
346                                                           kHeight * 3 / 6));
347   EXPECT_EQ(SK_ColorBLUE,  GetColorAt(slow_path_canvas(), kWidth  * 3 / 8,
348                                                           kHeight * 3 / 6));
349 }
350
351 }  // namespace media