Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: content/renderer/media/webmediaplayer_ms_compositor.cc

Issue 2153093003: WebMediaPlayerMsCompositor: use correct ARGB/ABGR, use SkSurface/SkPixmap ISO SkBitmap (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "content/renderer/media/webmediaplayer_ms_compositor.h" 5 #include "content/renderer/media/webmediaplayer_ms_compositor.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <string> 8 #include <string>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/hash.h" 11 #include "base/hash.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "content/common/gpu/client/context_provider_command_buffer.h" 14 #include "content/common/gpu/client/context_provider_command_buffer.h"
15 #include "content/renderer/media/webmediaplayer_ms.h" 15 #include "content/renderer/media/webmediaplayer_ms.h"
16 #include "content/renderer/render_thread_impl.h" 16 #include "content/renderer/render_thread_impl.h"
17 #include "media/base/media_switches.h" 17 #include "media/base/media_switches.h"
18 #include "media/base/video_frame.h" 18 #include "media/base/video_frame.h"
19 #include "media/base/video_util.h" 19 #include "media/base/video_util.h"
20 #include "media/filters/video_renderer_algorithm.h" 20 #include "media/filters/video_renderer_algorithm.h"
21 #include "media/renderers/skcanvas_video_renderer.h" 21 #include "media/renderers/skcanvas_video_renderer.h"
22 #include "skia/ext/platform_canvas.h" 22 #include "skia/ext/platform_canvas.h"
23 #include "third_party/WebKit/public/platform/WebMediaStream.h" 23 #include "third_party/WebKit/public/platform/WebMediaStream.h"
24 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 24 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
26 #include "third_party/libyuv/include/libyuv/convert.h" 26 #include "third_party/libyuv/include/libyuv/convert.h"
27 #include "third_party/libyuv/include/libyuv/planar_functions.h" 27 #include "third_party/libyuv/include/libyuv/planar_functions.h"
28 #include "third_party/libyuv/include/libyuv/video_common.h" 28 #include "third_party/libyuv/include/libyuv/video_common.h"
29 #include "third_party/skia/include/core/SkSurface.h"
29 30
30 namespace content { 31 namespace content {
31 32
32 namespace { 33 namespace {
33 34
34 // This function copies |frame| to a new I420 or YV12A media::VideoFrame. 35 // This function copies |frame| to a new I420 or YV12A media::VideoFrame.
35 scoped_refptr<media::VideoFrame> CopyFrame( 36 scoped_refptr<media::VideoFrame> CopyFrame(
36 const scoped_refptr<media::VideoFrame>& frame, 37 const scoped_refptr<media::VideoFrame>& frame,
37 media::SkCanvasVideoRenderer* video_renderer) { 38 media::SkCanvasVideoRenderer* video_renderer) {
38 scoped_refptr<media::VideoFrame> new_frame; 39 scoped_refptr<media::VideoFrame> new_frame;
39 if (frame->HasTextures()) { 40 if (frame->HasTextures()) {
40 DCHECK(frame->format() == media::PIXEL_FORMAT_ARGB || 41 DCHECK(frame->format() == media::PIXEL_FORMAT_ARGB ||
41 frame->format() == media::PIXEL_FORMAT_XRGB || 42 frame->format() == media::PIXEL_FORMAT_XRGB ||
42 frame->format() == media::PIXEL_FORMAT_I420 || 43 frame->format() == media::PIXEL_FORMAT_I420 ||
43 frame->format() == media::PIXEL_FORMAT_UYVY || 44 frame->format() == media::PIXEL_FORMAT_UYVY ||
44 frame->format() == media::PIXEL_FORMAT_NV12); 45 frame->format() == media::PIXEL_FORMAT_NV12);
45 new_frame = media::VideoFrame::CreateFrame( 46 new_frame = media::VideoFrame::CreateFrame(
46 media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(), 47 media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(),
47 frame->natural_size(), frame->timestamp()); 48 frame->natural_size(), frame->timestamp());
48 SkBitmap bitmap;
49 bitmap.allocN32Pixels(frame->visible_rect().width(),
50 frame->visible_rect().height());
51 SkCanvas canvas(bitmap);
52 49
53 auto* provider = 50 // TODO(mcasas): Reuse |surface| (as long as frame->visible_rect() doesn't
Daniele Castagna 2016/07/18 16:51:23 Why? Is it expensive to create one?
mcasas 2016/07/18 17:40:42 It boils down to creating a Raster N32 memory, whi
emircan 2016/07/18 18:24:25 Since the use-case here is for pausing media strea
mcasas 2016/07/18 18:33:14 Oh gotcha, removing the TODO then.
51 // change) by moving it and CopyFrame() to WebMediaPlayerMSCompositor.
52 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
53 frame->visible_rect().width(), frame->visible_rect().height());
54
55 ContextProviderCommandBuffer* const provider =
54 RenderThreadImpl::current()->SharedMainThreadContextProvider().get(); 56 RenderThreadImpl::current()->SharedMainThreadContextProvider().get();
55 if (provider) { 57 if (surface && provider) {
Daniele Castagna 2016/07/18 16:51:23 It seems like surface can be null only if we can't
mcasas 2016/07/18 17:40:43 It could also be null due to incorrect width/heigh
56 const media::Context3D context_3d = 58 DCHECK(provider->ContextGL());
57 media::Context3D(provider->ContextGL(), provider->GrContext()); 59 video_renderer->Copy(
58 DCHECK(context_3d.gl); 60 frame.get(), surface->getCanvas(),
59 video_renderer->Copy(frame.get(), &canvas, context_3d); 61 media::Context3D(provider->ContextGL(), provider->GrContext()));
60 } else { 62 } else {
61 // GPU Process crashed. 63 // Return a black frame (yuv = {0, 0x80, 0x80}).
62 bitmap.eraseColor(SK_ColorTRANSPARENT); 64 return media::VideoFrame::CreateColorFrame(
65 frame->visible_rect().size(), 0u, 0x80, 0x80, frame->timestamp());
63 } 66 }
64 libyuv::ARGBToI420(reinterpret_cast<uint8_t*>(bitmap.getPixels()), 67
65 bitmap.rowBytes(), 68 SkPixmap pixmap;
66 new_frame->visible_data(media::VideoFrame::kYPlane), 69 const bool result = surface->getCanvas()->peekPixels(&pixmap);
67 new_frame->stride(media::VideoFrame::kYPlane), 70 DCHECK(result) << "Error trying to access SkSurface's pixels";
68 new_frame->visible_data(media::VideoFrame::kUPlane), 71
69 new_frame->stride(media::VideoFrame::kUPlane), 72 const uint32 source_pixel_format =
70 new_frame->visible_data(media::VideoFrame::kVPlane), 73 (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
71 new_frame->stride(media::VideoFrame::kVPlane), 74 : libyuv::FOURCC_ARGB;
72 bitmap.width(), bitmap.height()); 75 libyuv::ConvertToI420(
76 static_cast<uint8*>(pixmap.writable_addr(0, 0)),
Daniele Castagna 2016/07/18 16:51:23 nit: can you use addr instead of writable_addr?
mcasas 2016/07/18 17:40:43 Good catch, done
77 pixmap.getSize64(),
Daniele Castagna 2016/07/18 16:51:23 nit: getSafeSize64 seems to be <= than size64, sho
mcasas 2016/07/18 17:40:43 Done.
78 new_frame->data(media::VideoFrame::kYPlane),
emircan 2016/07/18 18:24:25 Consider the case for coded_size() is different th
mcasas 2016/07/18 18:33:14 Done.
79 new_frame->stride(media::VideoFrame::kYPlane),
80 new_frame->data(media::VideoFrame::kUPlane),
81 new_frame->stride(media::VideoFrame::kUPlane),
82 new_frame->data(media::VideoFrame::kVPlane),
83 new_frame->stride(media::VideoFrame::kVPlane), 0 /* crop_x */,
84 0 /* crop_y */, pixmap.width(), pixmap.height(),
85 new_frame->coded_size().width(), new_frame->coded_size().height(),
86 libyuv::kRotate0, source_pixel_format);
73 } else { 87 } else {
74 DCHECK(frame->IsMappable()); 88 DCHECK(frame->IsMappable());
75 DCHECK(frame->format() == media::PIXEL_FORMAT_YV12 || 89 DCHECK(frame->format() == media::PIXEL_FORMAT_YV12 ||
76 frame->format() == media::PIXEL_FORMAT_YV12A || 90 frame->format() == media::PIXEL_FORMAT_YV12A ||
77 frame->format() == media::PIXEL_FORMAT_I420); 91 frame->format() == media::PIXEL_FORMAT_I420);
78 const gfx::Size& coded_size = frame->coded_size(); 92 const gfx::Size& coded_size = frame->coded_size();
79 new_frame = media::VideoFrame::CreateFrame( 93 new_frame = media::VideoFrame::CreateFrame(
80 media::IsOpaque(frame->format()) ? media::PIXEL_FORMAT_I420 94 media::IsOpaque(frame->format()) ? media::PIXEL_FORMAT_I420
81 : media::PIXEL_FORMAT_YV12A, 95 : media::PIXEL_FORMAT_YV12A,
82 coded_size, frame->visible_rect(), frame->natural_size(), 96 coded_size, frame->visible_rect(), frame->natural_size(),
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 } 441 }
428 442
429 if (!rendering_frame_buffer_) { 443 if (!rendering_frame_buffer_) {
430 rendering_frame_buffer_.reset(new media::VideoRendererAlgorithm( 444 rendering_frame_buffer_.reset(new media::VideoRendererAlgorithm(
431 base::Bind(&WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks, 445 base::Bind(&WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks,
432 base::Unretained(this)))); 446 base::Unretained(this))));
433 } 447 }
434 } 448 }
435 449
436 } // namespace content 450 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698