OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <GLES3/gl3.h> | 5 #include <GLES3/gl3.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/memory/aligned_memory.h" | 9 #include "base/memory/aligned_memory.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "cc/paint/paint_canvas.h" |
| 12 #include "cc/paint/paint_flags.h" |
| 13 #include "cc/paint/paint_surface.h" |
11 #include "gpu/GLES2/gl2extchromium.h" | 14 #include "gpu/GLES2/gl2extchromium.h" |
12 #include "gpu/command_buffer/client/gles2_interface_stub.h" | 15 #include "gpu/command_buffer/client/gles2_interface_stub.h" |
13 #include "media/base/timestamp_constants.h" | 16 #include "media/base/timestamp_constants.h" |
14 #include "media/base/video_frame.h" | 17 #include "media/base/video_frame.h" |
15 #include "media/base/video_util.h" | 18 #include "media/base/video_util.h" |
16 #include "media/renderers/skcanvas_video_renderer.h" | 19 #include "media/renderers/skcanvas_video_renderer.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
18 #include "third_party/libyuv/include/libyuv/convert.h" | 21 #include "third_party/libyuv/include/libyuv/convert.h" |
19 #include "third_party/skia/include/core/SkCanvas.h" | |
20 #include "third_party/skia/include/core/SkImage.h" | 22 #include "third_party/skia/include/core/SkImage.h" |
21 #include "third_party/skia/include/core/SkRefCnt.h" | 23 #include "third_party/skia/include/core/SkRefCnt.h" |
22 #include "third_party/skia/include/core/SkSurface.h" | |
23 #include "third_party/skia/include/gpu/GrContext.h" | 24 #include "third_party/skia/include/gpu/GrContext.h" |
24 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" | 25 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" |
25 #include "ui/gfx/geometry/rect_f.h" | 26 #include "ui/gfx/geometry/rect_f.h" |
26 | 27 |
27 using media::VideoFrame; | 28 using media::VideoFrame; |
28 | 29 |
29 namespace media { | 30 namespace media { |
30 | 31 |
31 static const int kWidth = 320; | 32 static const int kWidth = 320; |
32 static const int kHeight = 240; | 33 static const int kHeight = 240; |
33 static const gfx::RectF kNaturalRect(kWidth, kHeight); | 34 static const gfx::RectF kNaturalRect(kWidth, kHeight); |
34 | 35 |
35 // Helper for filling a |canvas| with a solid |color|. | 36 // Helper for filling a |canvas| with a solid |color|. |
36 void FillCanvas(SkCanvas* canvas, SkColor color) { | 37 void FillCanvas(cc::PaintCanvas* canvas, SkColor color) { |
37 canvas->clear(color); | 38 canvas->clear(color); |
38 } | 39 } |
39 | 40 |
40 // Helper for returning the color of a solid |canvas|. | 41 // Helper for returning the color of a solid |canvas|. |
41 SkColor GetColorAt(SkCanvas* canvas, int x, int y) { | 42 SkColor GetColorAt(cc::PaintCanvas* canvas, int x, int y) { |
42 SkBitmap bitmap; | 43 SkBitmap bitmap; |
43 if (!bitmap.tryAllocN32Pixels(1, 1)) | 44 if (!bitmap.tryAllocN32Pixels(1, 1)) |
44 return 0; | 45 return 0; |
45 if (!canvas->readPixels(&bitmap, x, y)) | 46 if (!canvas->readPixels(&bitmap, x, y)) |
46 return 0; | 47 return 0; |
47 return bitmap.getColor(0, 0); | 48 return bitmap.getColor(0, 0); |
48 } | 49 } |
49 | 50 |
50 SkColor GetColor(SkCanvas* canvas) { | 51 SkColor GetColor(cc::PaintCanvas* canvas) { |
51 return GetColorAt(canvas, 0, 0); | 52 return GetColorAt(canvas, 0, 0); |
52 } | 53 } |
53 | 54 |
54 // Generate frame pixels to provided |external_memory| and wrap it as frame. | 55 // Generate frame pixels to provided |external_memory| and wrap it as frame. |
55 scoped_refptr<VideoFrame> CreateTestY16Frame(const gfx::Size& coded_size, | 56 scoped_refptr<VideoFrame> CreateTestY16Frame(const gfx::Size& coded_size, |
56 const gfx::Rect& visible_rect, | 57 const gfx::Rect& visible_rect, |
57 void* external_memory, | 58 void* external_memory, |
58 base::TimeDelta timestamp) { | 59 base::TimeDelta timestamp) { |
59 const int offset_x = visible_rect.x(); | 60 const int offset_x = visible_rect.x(); |
60 const int offset_y = visible_rect.y(); | 61 const int offset_y = visible_rect.y(); |
(...skipping 21 matching lines...) Expand all Loading... |
82 kNone, | 83 kNone, |
83 kRed, | 84 kRed, |
84 kGreen, | 85 kGreen, |
85 kBlue, | 86 kBlue, |
86 }; | 87 }; |
87 | 88 |
88 SkCanvasVideoRendererTest(); | 89 SkCanvasVideoRendererTest(); |
89 ~SkCanvasVideoRendererTest() override; | 90 ~SkCanvasVideoRendererTest() override; |
90 | 91 |
91 // Paints to |canvas| using |renderer_| without any frame data. | 92 // Paints to |canvas| using |renderer_| without any frame data. |
92 void PaintWithoutFrame(SkCanvas* canvas); | 93 void PaintWithoutFrame(cc::PaintCanvas* canvas); |
93 | 94 |
94 // Paints the |video_frame| to the |canvas| using |renderer_|, setting the | 95 // Paints the |video_frame| to the |canvas| using |renderer_|, setting the |
95 // color of |video_frame| to |color| first. | 96 // color of |video_frame| to |color| first. |
96 void Paint(const scoped_refptr<VideoFrame>& video_frame, | 97 void Paint(const scoped_refptr<VideoFrame>& video_frame, |
97 SkCanvas* canvas, | 98 cc::PaintCanvas* canvas, |
98 Color color); | 99 Color color); |
99 void PaintRotated(const scoped_refptr<VideoFrame>& video_frame, | 100 void PaintRotated(const scoped_refptr<VideoFrame>& video_frame, |
100 SkCanvas* canvas, | 101 cc::PaintCanvas* canvas, |
101 const gfx::RectF& dest_rect, | 102 const gfx::RectF& dest_rect, |
102 Color color, | 103 Color color, |
103 SkBlendMode mode, | 104 SkBlendMode mode, |
104 VideoRotation video_rotation); | 105 VideoRotation video_rotation); |
105 | 106 |
106 void Copy(const scoped_refptr<VideoFrame>& video_frame, SkCanvas* canvas); | 107 void Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 108 cc::PaintCanvas* canvas); |
107 | 109 |
108 // Getters for various frame sizes. | 110 // Getters for various frame sizes. |
109 scoped_refptr<VideoFrame> natural_frame() { return natural_frame_; } | 111 scoped_refptr<VideoFrame> natural_frame() { return natural_frame_; } |
110 scoped_refptr<VideoFrame> larger_frame() { return larger_frame_; } | 112 scoped_refptr<VideoFrame> larger_frame() { return larger_frame_; } |
111 scoped_refptr<VideoFrame> smaller_frame() { return smaller_frame_; } | 113 scoped_refptr<VideoFrame> smaller_frame() { return smaller_frame_; } |
112 scoped_refptr<VideoFrame> cropped_frame() { return cropped_frame_; } | 114 scoped_refptr<VideoFrame> cropped_frame() { return cropped_frame_; } |
113 | 115 |
114 // Standard canvas. | 116 // Standard canvas. |
115 SkCanvas* target_canvas() { return &target_canvas_; } | 117 cc::PaintCanvas* target_canvas() { return &target_canvas_; } |
116 | 118 |
117 protected: | 119 protected: |
118 SkCanvasVideoRenderer renderer_; | 120 SkCanvasVideoRenderer renderer_; |
119 | 121 |
120 scoped_refptr<VideoFrame> natural_frame_; | 122 scoped_refptr<VideoFrame> natural_frame_; |
121 scoped_refptr<VideoFrame> larger_frame_; | 123 scoped_refptr<VideoFrame> larger_frame_; |
122 scoped_refptr<VideoFrame> smaller_frame_; | 124 scoped_refptr<VideoFrame> smaller_frame_; |
123 scoped_refptr<VideoFrame> cropped_frame_; | 125 scoped_refptr<VideoFrame> cropped_frame_; |
124 | 126 |
125 SkCanvas target_canvas_; | 127 cc::PaintCanvas target_canvas_; |
126 base::MessageLoop message_loop_; | 128 base::MessageLoop message_loop_; |
127 | 129 |
128 DISALLOW_COPY_AND_ASSIGN(SkCanvasVideoRendererTest); | 130 DISALLOW_COPY_AND_ASSIGN(SkCanvasVideoRendererTest); |
129 }; | 131 }; |
130 | 132 |
131 static SkBitmap AllocBitmap(int width, int height) { | 133 static SkBitmap AllocBitmap(int width, int height) { |
132 SkBitmap bitmap; | 134 SkBitmap bitmap; |
133 bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType)); | 135 bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType)); |
134 bitmap.eraseColor(0); | 136 bitmap.eraseColor(0); |
135 return bitmap; | 137 return bitmap; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 cropped_frame()->data(VideoFrame::kYPlane), | 229 cropped_frame()->data(VideoFrame::kYPlane), |
228 cropped_frame()->stride(VideoFrame::kYPlane), | 230 cropped_frame()->stride(VideoFrame::kYPlane), |
229 cropped_frame()->data(VideoFrame::kUPlane), | 231 cropped_frame()->data(VideoFrame::kUPlane), |
230 cropped_frame()->stride(VideoFrame::kUPlane), | 232 cropped_frame()->stride(VideoFrame::kUPlane), |
231 cropped_frame()->data(VideoFrame::kVPlane), | 233 cropped_frame()->data(VideoFrame::kVPlane), |
232 cropped_frame()->stride(VideoFrame::kVPlane), 16, 16); | 234 cropped_frame()->stride(VideoFrame::kVPlane), 16, 16); |
233 } | 235 } |
234 | 236 |
235 SkCanvasVideoRendererTest::~SkCanvasVideoRendererTest() {} | 237 SkCanvasVideoRendererTest::~SkCanvasVideoRendererTest() {} |
236 | 238 |
237 void SkCanvasVideoRendererTest::PaintWithoutFrame(SkCanvas* canvas) { | 239 void SkCanvasVideoRendererTest::PaintWithoutFrame(cc::PaintCanvas* canvas) { |
238 SkPaint paint; | 240 cc::PaintFlags flags; |
239 paint.setFilterQuality(kLow_SkFilterQuality); | 241 flags.setFilterQuality(kLow_SkFilterQuality); |
240 renderer_.Paint(nullptr, canvas, kNaturalRect, paint, VIDEO_ROTATION_0, | 242 renderer_.Paint(nullptr, canvas, kNaturalRect, flags, VIDEO_ROTATION_0, |
241 Context3D()); | 243 Context3D()); |
242 } | 244 } |
243 | 245 |
244 void SkCanvasVideoRendererTest::Paint( | 246 void SkCanvasVideoRendererTest::Paint( |
245 const scoped_refptr<VideoFrame>& video_frame, | 247 const scoped_refptr<VideoFrame>& video_frame, |
246 SkCanvas* canvas, | 248 cc::PaintCanvas* canvas, |
247 Color color) { | 249 Color color) { |
248 PaintRotated(video_frame, canvas, kNaturalRect, color, SkBlendMode::kSrcOver, | 250 PaintRotated(video_frame, canvas, kNaturalRect, color, SkBlendMode::kSrcOver, |
249 VIDEO_ROTATION_0); | 251 VIDEO_ROTATION_0); |
250 } | 252 } |
251 | 253 |
252 void SkCanvasVideoRendererTest::PaintRotated( | 254 void SkCanvasVideoRendererTest::PaintRotated( |
253 const scoped_refptr<VideoFrame>& video_frame, | 255 const scoped_refptr<VideoFrame>& video_frame, |
254 SkCanvas* canvas, | 256 cc::PaintCanvas* canvas, |
255 const gfx::RectF& dest_rect, | 257 const gfx::RectF& dest_rect, |
256 Color color, | 258 Color color, |
257 SkBlendMode mode, | 259 SkBlendMode mode, |
258 VideoRotation video_rotation) { | 260 VideoRotation video_rotation) { |
259 switch (color) { | 261 switch (color) { |
260 case kNone: | 262 case kNone: |
261 break; | 263 break; |
262 case kRed: | 264 case kRed: |
263 media::FillYUV(video_frame.get(), 76, 84, 255); | 265 media::FillYUV(video_frame.get(), 76, 84, 255); |
264 break; | 266 break; |
265 case kGreen: | 267 case kGreen: |
266 media::FillYUV(video_frame.get(), 149, 43, 21); | 268 media::FillYUV(video_frame.get(), 149, 43, 21); |
267 break; | 269 break; |
268 case kBlue: | 270 case kBlue: |
269 media::FillYUV(video_frame.get(), 29, 255, 107); | 271 media::FillYUV(video_frame.get(), 29, 255, 107); |
270 break; | 272 break; |
271 } | 273 } |
272 SkPaint paint; | 274 cc::PaintFlags flags; |
273 paint.setBlendMode(mode); | 275 flags.setBlendMode(mode); |
274 paint.setFilterQuality(kLow_SkFilterQuality); | 276 flags.setFilterQuality(kLow_SkFilterQuality); |
275 renderer_.Paint(video_frame, canvas, dest_rect, paint, video_rotation, | 277 renderer_.Paint(video_frame, canvas, dest_rect, flags, video_rotation, |
276 Context3D()); | 278 Context3D()); |
277 } | 279 } |
278 | 280 |
279 void SkCanvasVideoRendererTest::Copy( | 281 void SkCanvasVideoRendererTest::Copy( |
280 const scoped_refptr<VideoFrame>& video_frame, | 282 const scoped_refptr<VideoFrame>& video_frame, |
281 SkCanvas* canvas) { | 283 cc::PaintCanvas* canvas) { |
282 renderer_.Copy(video_frame, canvas, Context3D()); | 284 renderer_.Copy(video_frame, canvas, Context3D()); |
283 } | 285 } |
284 | 286 |
285 TEST_F(SkCanvasVideoRendererTest, NoFrame) { | 287 TEST_F(SkCanvasVideoRendererTest, NoFrame) { |
286 // Test that black gets painted over canvas. | 288 // Test that black gets painted over canvas. |
287 FillCanvas(target_canvas(), SK_ColorRED); | 289 FillCanvas(target_canvas(), SK_ColorRED); |
288 PaintWithoutFrame(target_canvas()); | 290 PaintWithoutFrame(target_canvas()); |
289 EXPECT_EQ(SK_ColorBLACK, GetColor(target_canvas())); | 291 EXPECT_EQ(SK_ColorBLACK, GetColor(target_canvas())); |
290 } | 292 } |
291 | 293 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 kHeight * 1 / 6 - 1)); | 361 kHeight * 1 / 6 - 1)); |
360 EXPECT_EQ(SK_ColorRED, | 362 EXPECT_EQ(SK_ColorRED, |
361 GetColorAt(target_canvas(), kWidth * 3 / 8, kHeight * 1 / 6 - 1)); | 363 GetColorAt(target_canvas(), kWidth * 3 / 8, kHeight * 1 / 6 - 1)); |
362 EXPECT_EQ(SK_ColorGREEN, | 364 EXPECT_EQ(SK_ColorGREEN, |
363 GetColorAt(target_canvas(), kWidth * 1 / 8 - 1, kHeight * 3 / 6)); | 365 GetColorAt(target_canvas(), kWidth * 1 / 8 - 1, kHeight * 3 / 6)); |
364 EXPECT_EQ(SK_ColorBLUE, | 366 EXPECT_EQ(SK_ColorBLUE, |
365 GetColorAt(target_canvas(), kWidth * 3 / 8, kHeight * 3 / 6)); | 367 GetColorAt(target_canvas(), kWidth * 3 / 8, kHeight * 3 / 6)); |
366 } | 368 } |
367 | 369 |
368 TEST_F(SkCanvasVideoRendererTest, CroppedFrame_NoScaling) { | 370 TEST_F(SkCanvasVideoRendererTest, CroppedFrame_NoScaling) { |
369 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 371 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
370 const gfx::Rect crop_rect = cropped_frame()->visible_rect(); | 372 const gfx::Rect crop_rect = cropped_frame()->visible_rect(); |
371 | 373 |
372 // Force painting to a non-zero position on the destination bitmap, to check | 374 // Force painting to a non-zero position on the destination bitmap, to check |
373 // if the coordinates are calculated properly. | 375 // if the coordinates are calculated properly. |
374 const int offset_x = 10; | 376 const int offset_x = 10; |
375 const int offset_y = 15; | 377 const int offset_y = 15; |
376 canvas.translate(offset_x, offset_y); | 378 canvas.translate(offset_x, offset_y); |
377 | 379 |
378 // Create a destination canvas with dimensions and scale which would not | 380 // Create a destination canvas with dimensions and scale which would not |
379 // cause scaling. | 381 // cause scaling. |
380 canvas.scale(static_cast<SkScalar>(crop_rect.width()) / kWidth, | 382 canvas.scale(static_cast<SkScalar>(crop_rect.width()) / kWidth, |
381 static_cast<SkScalar>(crop_rect.height()) / kHeight); | 383 static_cast<SkScalar>(crop_rect.height()) / kHeight); |
382 | 384 |
383 Paint(cropped_frame(), &canvas, kNone); | 385 Paint(cropped_frame(), &canvas, kNone); |
384 | 386 |
385 // Check the corners. | 387 // Check the corners. |
386 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, offset_x, offset_y)); | 388 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, offset_x, offset_y)); |
387 EXPECT_EQ(SK_ColorRED, | 389 EXPECT_EQ(SK_ColorRED, |
388 GetColorAt(&canvas, offset_x + crop_rect.width() - 1, offset_y)); | 390 GetColorAt(&canvas, offset_x + crop_rect.width() - 1, offset_y)); |
389 EXPECT_EQ(SK_ColorGREEN, | 391 EXPECT_EQ(SK_ColorGREEN, |
390 GetColorAt(&canvas, offset_x, offset_y + crop_rect.height() - 1)); | 392 GetColorAt(&canvas, offset_x, offset_y + crop_rect.height() - 1)); |
391 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, offset_x + crop_rect.width() - 1, | 393 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, offset_x + crop_rect.width() - 1, |
392 offset_y + crop_rect.height() - 1)); | 394 offset_y + crop_rect.height() - 1)); |
393 } | 395 } |
394 | 396 |
395 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_90) { | 397 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_90) { |
396 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 398 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
397 PaintRotated(cropped_frame(), &canvas, kNaturalRect, kNone, | 399 PaintRotated(cropped_frame(), &canvas, kNaturalRect, kNone, |
398 SkBlendMode::kSrcOver, VIDEO_ROTATION_90); | 400 SkBlendMode::kSrcOver, VIDEO_ROTATION_90); |
399 // Check the corners. | 401 // Check the corners. |
400 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, 0, 0)); | 402 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, 0, 0)); |
401 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, 0)); | 403 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, 0)); |
402 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); | 404 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); |
403 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, 0, kHeight - 1)); | 405 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, 0, kHeight - 1)); |
404 } | 406 } |
405 | 407 |
406 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_180) { | 408 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_180) { |
407 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 409 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
408 PaintRotated(cropped_frame(), &canvas, kNaturalRect, kNone, | 410 PaintRotated(cropped_frame(), &canvas, kNaturalRect, kNone, |
409 SkBlendMode::kSrcOver, VIDEO_ROTATION_180); | 411 SkBlendMode::kSrcOver, VIDEO_ROTATION_180); |
410 // Check the corners. | 412 // Check the corners. |
411 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, 0, 0)); | 413 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, 0, 0)); |
412 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, 0)); | 414 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, 0)); |
413 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); | 415 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); |
414 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, 0, kHeight - 1)); | 416 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, 0, kHeight - 1)); |
415 } | 417 } |
416 | 418 |
417 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_270) { | 419 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_270) { |
418 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 420 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
419 PaintRotated(cropped_frame(), &canvas, kNaturalRect, kNone, | 421 PaintRotated(cropped_frame(), &canvas, kNaturalRect, kNone, |
420 SkBlendMode::kSrcOver, VIDEO_ROTATION_270); | 422 SkBlendMode::kSrcOver, VIDEO_ROTATION_270); |
421 // Check the corners. | 423 // Check the corners. |
422 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, 0, 0)); | 424 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, 0, 0)); |
423 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, 0)); | 425 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, 0)); |
424 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); | 426 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); |
425 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, 0, kHeight - 1)); | 427 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, 0, kHeight - 1)); |
426 } | 428 } |
427 | 429 |
428 TEST_F(SkCanvasVideoRendererTest, Video_Translate) { | 430 TEST_F(SkCanvasVideoRendererTest, Video_Translate) { |
429 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 431 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
430 FillCanvas(&canvas, SK_ColorMAGENTA); | 432 FillCanvas(&canvas, SK_ColorMAGENTA); |
431 | 433 |
432 PaintRotated(cropped_frame(), &canvas, | 434 PaintRotated(cropped_frame(), &canvas, |
433 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), | 435 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), |
434 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_0); | 436 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_0); |
435 // Check the corners of quadrant 2 and 4. | 437 // Check the corners of quadrant 2 and 4. |
436 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); | 438 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); |
437 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); | 439 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); |
438 EXPECT_EQ(SK_ColorMAGENTA, | 440 EXPECT_EQ(SK_ColorMAGENTA, |
439 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); | 441 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); |
440 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1)); | 442 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1)); |
441 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth / 2, kHeight / 2)); | 443 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth / 2, kHeight / 2)); |
442 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight / 2)); | 444 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight / 2)); |
443 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); | 445 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); |
444 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth / 2, kHeight - 1)); | 446 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth / 2, kHeight - 1)); |
445 } | 447 } |
446 | 448 |
447 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_90) { | 449 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_90) { |
448 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 450 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
449 FillCanvas(&canvas, SK_ColorMAGENTA); | 451 FillCanvas(&canvas, SK_ColorMAGENTA); |
450 | 452 |
451 PaintRotated(cropped_frame(), &canvas, | 453 PaintRotated(cropped_frame(), &canvas, |
452 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), | 454 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), |
453 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_90); | 455 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_90); |
454 // Check the corners of quadrant 2 and 4. | 456 // Check the corners of quadrant 2 and 4. |
455 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); | 457 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); |
456 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); | 458 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); |
457 EXPECT_EQ(SK_ColorMAGENTA, | 459 EXPECT_EQ(SK_ColorMAGENTA, |
458 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); | 460 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); |
459 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1)); | 461 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1)); |
460 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth / 2, kHeight / 2)); | 462 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth / 2, kHeight / 2)); |
461 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight / 2)); | 463 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight / 2)); |
462 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); | 464 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); |
463 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth / 2, kHeight - 1)); | 465 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth / 2, kHeight - 1)); |
464 } | 466 } |
465 | 467 |
466 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_180) { | 468 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_180) { |
467 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 469 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
468 FillCanvas(&canvas, SK_ColorMAGENTA); | 470 FillCanvas(&canvas, SK_ColorMAGENTA); |
469 | 471 |
470 PaintRotated(cropped_frame(), &canvas, | 472 PaintRotated(cropped_frame(), &canvas, |
471 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), | 473 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), |
472 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_180); | 474 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_180); |
473 // Check the corners of quadrant 2 and 4. | 475 // Check the corners of quadrant 2 and 4. |
474 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); | 476 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); |
475 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); | 477 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); |
476 EXPECT_EQ(SK_ColorMAGENTA, | 478 EXPECT_EQ(SK_ColorMAGENTA, |
477 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); | 479 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); |
478 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1)); | 480 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1)); |
479 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth / 2, kHeight / 2)); | 481 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth / 2, kHeight / 2)); |
480 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight / 2)); | 482 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight / 2)); |
481 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); | 483 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight - 1)); |
482 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth / 2, kHeight - 1)); | 484 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth / 2, kHeight - 1)); |
483 } | 485 } |
484 | 486 |
485 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_270) { | 487 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_270) { |
486 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 488 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
487 FillCanvas(&canvas, SK_ColorMAGENTA); | 489 FillCanvas(&canvas, SK_ColorMAGENTA); |
488 | 490 |
489 PaintRotated(cropped_frame(), &canvas, | 491 PaintRotated(cropped_frame(), &canvas, |
490 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), | 492 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2), |
491 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_270); | 493 kNone, SkBlendMode::kSrcOver, VIDEO_ROTATION_270); |
492 // Check the corners of quadrant 2 and 4. | 494 // Check the corners of quadrant 2 and 4. |
493 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); | 495 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0)); |
494 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); | 496 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0)); |
495 EXPECT_EQ(SK_ColorMAGENTA, | 497 EXPECT_EQ(SK_ColorMAGENTA, |
496 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); | 498 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 const int stride = bitmap.width() + offset_x; | 551 const int stride = bitmap.width() + offset_x; |
550 const size_t byte_size = stride * (bitmap.height() + offset_y) * 2; | 552 const size_t byte_size = stride * (bitmap.height() + offset_y) * 2; |
551 std::unique_ptr<unsigned char, base::AlignedFreeDeleter> memory( | 553 std::unique_ptr<unsigned char, base::AlignedFreeDeleter> memory( |
552 static_cast<unsigned char*>(base::AlignedAlloc( | 554 static_cast<unsigned char*>(base::AlignedAlloc( |
553 byte_size, media::VideoFrame::kFrameAddressAlignment))); | 555 byte_size, media::VideoFrame::kFrameAddressAlignment))); |
554 const gfx::Rect rect(offset_x, offset_y, bitmap.width(), bitmap.height()); | 556 const gfx::Rect rect(offset_x, offset_y, bitmap.width(), bitmap.height()); |
555 scoped_refptr<media::VideoFrame> video_frame = | 557 scoped_refptr<media::VideoFrame> video_frame = |
556 CreateTestY16Frame(gfx::Size(stride, offset_y + bitmap.height()), rect, | 558 CreateTestY16Frame(gfx::Size(stride, offset_y + bitmap.height()), rect, |
557 memory.get(), cropped_frame()->timestamp()); | 559 memory.get(), cropped_frame()->timestamp()); |
558 | 560 |
559 SkCanvas canvas(bitmap); | 561 cc::PaintCanvas canvas(bitmap); |
560 SkPaint paint; | 562 cc::PaintFlags flags; |
561 paint.setFilterQuality(kNone_SkFilterQuality); | 563 flags.setFilterQuality(kNone_SkFilterQuality); |
562 renderer_.Paint(video_frame, &canvas, | 564 renderer_.Paint(video_frame, &canvas, |
563 gfx::RectF(bitmap.width(), bitmap.height()), paint, | 565 gfx::RectF(bitmap.width(), bitmap.height()), flags, |
564 VIDEO_ROTATION_0, Context3D()); | 566 VIDEO_ROTATION_0, Context3D()); |
565 SkAutoLockPixels lock(bitmap); | 567 SkAutoLockPixels lock(bitmap); |
566 for (int j = 0; j < bitmap.height(); j++) { | 568 for (int j = 0; j < bitmap.height(); j++) { |
567 for (int i = 0; i < bitmap.width(); i++) { | 569 for (int i = 0; i < bitmap.width(); i++) { |
568 const int value = i + j * bitmap.width(); | 570 const int value = i + j * bitmap.width(); |
569 EXPECT_EQ(SkColorSetRGB(value, value, value), bitmap.getColor(i, j)); | 571 EXPECT_EQ(SkColorSetRGB(value, value, value), bitmap.getColor(i, j)); |
570 } | 572 } |
571 } | 573 } |
572 } | 574 } |
573 | 575 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 | 638 |
637 // Test that SkCanvasVideoRendererTest::Paint doesn't crash when GrContext is | 639 // Test that SkCanvasVideoRendererTest::Paint doesn't crash when GrContext is |
638 // abandoned. | 640 // abandoned. |
639 TEST_F(SkCanvasVideoRendererTest, ContextLost) { | 641 TEST_F(SkCanvasVideoRendererTest, ContextLost) { |
640 sk_sp<const GrGLInterface> null_interface(GrGLCreateNullInterface()); | 642 sk_sp<const GrGLInterface> null_interface(GrGLCreateNullInterface()); |
641 sk_sp<GrContext> gr_context(GrContext::Create( | 643 sk_sp<GrContext> gr_context(GrContext::Create( |
642 kOpenGL_GrBackend, | 644 kOpenGL_GrBackend, |
643 reinterpret_cast<GrBackendContext>(null_interface.get()))); | 645 reinterpret_cast<GrBackendContext>(null_interface.get()))); |
644 gr_context->abandonContext(); | 646 gr_context->abandonContext(); |
645 | 647 |
646 SkCanvas canvas(AllocBitmap(kWidth, kHeight)); | 648 cc::PaintCanvas canvas(AllocBitmap(kWidth, kHeight)); |
647 | 649 |
648 TestGLES2Interface gles2; | 650 TestGLES2Interface gles2; |
649 Context3D context_3d(&gles2, gr_context.get()); | 651 Context3D context_3d(&gles2, gr_context.get()); |
650 gfx::Size size(kWidth, kHeight); | 652 gfx::Size size(kWidth, kHeight); |
651 gpu::MailboxHolder holders[VideoFrame::kMaxPlanes] = {gpu::MailboxHolder( | 653 gpu::MailboxHolder holders[VideoFrame::kMaxPlanes] = {gpu::MailboxHolder( |
652 gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_RECTANGLE_ARB)}; | 654 gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_RECTANGLE_ARB)}; |
653 auto video_frame = VideoFrame::WrapNativeTextures( | 655 auto video_frame = VideoFrame::WrapNativeTextures( |
654 PIXEL_FORMAT_UYVY, holders, base::Bind(MailboxHoldersReleased), size, | 656 PIXEL_FORMAT_UYVY, holders, base::Bind(MailboxHoldersReleased), size, |
655 gfx::Rect(size), size, kNoTimestamp); | 657 gfx::Rect(size), size, kNoTimestamp); |
656 | 658 |
657 SkPaint paint; | 659 cc::PaintFlags flags; |
658 paint.setFilterQuality(kLow_SkFilterQuality); | 660 flags.setFilterQuality(kLow_SkFilterQuality); |
659 renderer_.Paint(video_frame, &canvas, kNaturalRect, paint, VIDEO_ROTATION_90, | 661 renderer_.Paint(video_frame, &canvas, kNaturalRect, flags, VIDEO_ROTATION_90, |
660 context_3d); | 662 context_3d); |
661 } | 663 } |
662 | 664 |
663 void EmptyCallback(const gpu::SyncToken& sync_token) {} | 665 void EmptyCallback(const gpu::SyncToken& sync_token) {} |
664 | 666 |
665 TEST_F(SkCanvasVideoRendererTest, CorrectFrameSizeToVisibleRect) { | 667 TEST_F(SkCanvasVideoRendererTest, CorrectFrameSizeToVisibleRect) { |
666 int fWidth{16}, fHeight{16}; | 668 int fWidth{16}, fHeight{16}; |
667 SkImageInfo imInfo = | 669 SkImageInfo imInfo = |
668 SkImageInfo::MakeN32(fWidth, fHeight, kOpaque_SkAlphaType); | 670 SkImageInfo::MakeN32(fWidth, fHeight, kOpaque_SkAlphaType); |
669 | 671 |
670 sk_sp<const GrGLInterface> glInterface(GrGLCreateNullInterface()); | 672 sk_sp<const GrGLInterface> glInterface(GrGLCreateNullInterface()); |
671 sk_sp<GrContext> grContext( | 673 sk_sp<GrContext> grContext( |
672 GrContext::Create(kOpenGL_GrBackend, | 674 GrContext::Create(kOpenGL_GrBackend, |
673 reinterpret_cast<GrBackendContext>(glInterface.get()))); | 675 reinterpret_cast<GrBackendContext>(glInterface.get()))); |
674 | 676 |
675 sk_sp<SkSurface> skSurface = | 677 sk_sp<cc::PaintSurface> surface = cc::PaintSurface::MakeRenderTarget( |
676 SkSurface::MakeRenderTarget(grContext.get(), SkBudgeted::kYes, imInfo); | 678 grContext.get(), SkBudgeted::kYes, imInfo); |
677 SkCanvas* canvas = skSurface->getCanvas(); | 679 cc::PaintCanvas* canvas = surface->getCanvas(); |
678 | 680 |
679 TestGLES2Interface gles2; | 681 TestGLES2Interface gles2; |
680 Context3D context_3d(&gles2, grContext.get()); | 682 Context3D context_3d(&gles2, grContext.get()); |
681 gfx::Size coded_size(fWidth, fHeight); | 683 gfx::Size coded_size(fWidth, fHeight); |
682 gfx::Size visible_size(fWidth / 2, fHeight / 2); | 684 gfx::Size visible_size(fWidth / 2, fHeight / 2); |
683 | 685 |
684 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; | 686 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; |
685 for (size_t i = 0; i < VideoFrame::kMaxPlanes; i++) { | 687 for (size_t i = 0; i < VideoFrame::kMaxPlanes; i++) { |
686 mailbox_holders[i] = gpu::MailboxHolder( | 688 mailbox_holders[i] = gpu::MailboxHolder( |
687 gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_RECTANGLE_ARB); | 689 gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_RECTANGLE_ARB); |
688 } | 690 } |
689 | 691 |
690 auto video_frame = VideoFrame::WrapNativeTextures( | 692 auto video_frame = VideoFrame::WrapNativeTextures( |
691 PIXEL_FORMAT_I420, mailbox_holders, base::Bind(EmptyCallback), coded_size, | 693 PIXEL_FORMAT_I420, mailbox_holders, base::Bind(EmptyCallback), coded_size, |
692 gfx::Rect(visible_size), visible_size, | 694 gfx::Rect(visible_size), visible_size, |
693 base::TimeDelta::FromMilliseconds(4)); | 695 base::TimeDelta::FromMilliseconds(4)); |
694 | 696 |
695 gfx::RectF visible_rect(visible_size.width(), visible_size.height()); | 697 gfx::RectF visible_rect(visible_size.width(), visible_size.height()); |
696 SkPaint paint; | 698 cc::PaintFlags flags; |
697 renderer_.Paint(video_frame, canvas, visible_rect, paint, VIDEO_ROTATION_0, | 699 renderer_.Paint(video_frame, canvas, visible_rect, flags, VIDEO_ROTATION_0, |
698 context_3d); | 700 context_3d); |
699 | 701 |
700 EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().width()); | 702 EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().width()); |
701 EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().height()); | 703 EXPECT_EQ(fWidth / 2, renderer_.LastImageDimensionsForTesting().height()); |
702 } | 704 } |
703 | 705 |
704 TEST_F(SkCanvasVideoRendererTest, TexImage2D_Y16_RGBA32F) { | 706 TEST_F(SkCanvasVideoRendererTest, TexImage2D_Y16_RGBA32F) { |
705 // Create test frame. | 707 // Create test frame. |
706 // |offset_x| and |offset_y| define visible rect's offset to coded rect. | 708 // |offset_x| and |offset_y| define visible rect's offset to coded rect. |
707 const int offset_x = 3; | 709 const int offset_x = 3; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 EXPECT_EQ(expected_value, data[(i + j * width)]); | 803 EXPECT_EQ(expected_value, data[(i + j * width)]); |
802 } | 804 } |
803 } | 805 } |
804 }); | 806 }); |
805 SkCanvasVideoRenderer::TexSubImage2D(GL_TEXTURE_2D, &gles2, video_frame.get(), | 807 SkCanvasVideoRenderer::TexSubImage2D(GL_TEXTURE_2D, &gles2, video_frame.get(), |
806 0, GL_RED, GL_FLOAT, 2 /*xoffset*/, | 808 0, GL_RED, GL_FLOAT, 2 /*xoffset*/, |
807 1 /*yoffset*/, false /*flip_y*/, true); | 809 1 /*yoffset*/, false /*flip_y*/, true); |
808 } | 810 } |
809 | 811 |
810 } // namespace media | 812 } // namespace media |
OLD | NEW |