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

Side by Side Diff: media/filters/skcanvas_video_renderer.cc

Issue 864113002: Pepper: PPB_VideoDecoder software fallback should support all YUV formats. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 10 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
OLDNEW
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 "media/filters/skcanvas_video_renderer.h" 5 #include "media/filters/skcanvas_video_renderer.h"
6 6
7 #include "gpu/GLES2/gl2extchromium.h" 7 #include "gpu/GLES2/gl2extchromium.h"
8 #include "gpu/command_buffer/client/gles2_interface.h" 8 #include "gpu/command_buffer/client/gles2_interface.h"
9 #include "gpu/command_buffer/common/mailbox_holder.h" 9 #include "gpu/command_buffer/common/mailbox_holder.h"
10 #include "media/base/video_frame.h" 10 #include "media/base/video_frame.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 return false; 84 return false;
85 } 85 }
86 NOTREACHED() << "Invalid videoframe format provided: " << format; 86 NOTREACHED() << "Invalid videoframe format provided: " << format;
87 return false; 87 return false;
88 } 88 }
89 89
90 bool IsYUVOrNative(media::VideoFrame::Format format) { 90 bool IsYUVOrNative(media::VideoFrame::Format format) {
91 return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE; 91 return IsYUV(format) || format == media::VideoFrame::NATIVE_TEXTURE;
92 } 92 }
93 93
94 // Converts a |video_frame| to raw |rgb_pixels|.
95 void ConvertVideoFrameToRGBPixels(
96 const scoped_refptr<media::VideoFrame>& video_frame,
97 void* rgb_pixels,
98 size_t row_bytes) {
99 DCHECK(IsYUVOrNative(video_frame->format()))
100 << video_frame->format();
101 if (IsYUV(video_frame->format())) {
102 DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane),
103 video_frame->stride(media::VideoFrame::kVPlane));
104 }
105
106 size_t y_offset = 0;
107 size_t uv_offset = 0;
108 if (IsYUV(video_frame->format())) {
109 int y_shift = (video_frame->format() == media::VideoFrame::YV16) ? 0 : 1;
110 // Use the "left" and "top" of the destination rect to locate the offset
111 // in Y, U and V planes.
112 y_offset = (video_frame->stride(media::VideoFrame::kYPlane) *
113 video_frame->visible_rect().y()) +
114 video_frame->visible_rect().x();
115 // For format YV12, there is one U, V value per 2x2 block.
116 // For format YV16, there is one U, V value per 2x1 block.
117 uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) *
118 (video_frame->visible_rect().y() >> y_shift)) +
119 (video_frame->visible_rect().x() >> 1);
120 }
121
122 switch (video_frame->format()) {
123 case VideoFrame::YV12:
124 case VideoFrame::I420:
125 LIBYUV_I420_TO_ARGB(
126 video_frame->data(VideoFrame::kYPlane) + y_offset,
127 video_frame->stride(VideoFrame::kYPlane),
128 video_frame->data(VideoFrame::kUPlane) + uv_offset,
129 video_frame->stride(VideoFrame::kUPlane),
130 video_frame->data(VideoFrame::kVPlane) + uv_offset,
131 video_frame->stride(VideoFrame::kVPlane),
132 static_cast<uint8*>(rgb_pixels),
133 row_bytes,
134 video_frame->visible_rect().width(),
135 video_frame->visible_rect().height());
136 break;
137
138 case VideoFrame::YV12J:
139 ConvertYUVToRGB32(
140 video_frame->data(VideoFrame::kYPlane) + y_offset,
141 video_frame->data(VideoFrame::kUPlane) + uv_offset,
142 video_frame->data(VideoFrame::kVPlane) + uv_offset,
143 static_cast<uint8*>(rgb_pixels),
144 video_frame->visible_rect().width(),
145 video_frame->visible_rect().height(),
146 video_frame->stride(VideoFrame::kYPlane),
147 video_frame->stride(VideoFrame::kUPlane),
148 row_bytes,
149 YV12J);
150 break;
151
152 case VideoFrame::YV12HD:
153 ConvertYUVToRGB32(
154 video_frame->data(VideoFrame::kYPlane) + y_offset,
155 video_frame->data(VideoFrame::kUPlane) + uv_offset,
156 video_frame->data(VideoFrame::kVPlane) + uv_offset,
157 static_cast<uint8*>(rgb_pixels),
158 video_frame->visible_rect().width(),
159 video_frame->visible_rect().height(),
160 video_frame->stride(VideoFrame::kYPlane),
161 video_frame->stride(VideoFrame::kUPlane),
162 row_bytes,
163 YV12HD);
164 break;
165
166 case VideoFrame::YV16:
167 LIBYUV_I422_TO_ARGB(
168 video_frame->data(VideoFrame::kYPlane) + y_offset,
169 video_frame->stride(VideoFrame::kYPlane),
170 video_frame->data(VideoFrame::kUPlane) + uv_offset,
171 video_frame->stride(VideoFrame::kUPlane),
172 video_frame->data(VideoFrame::kVPlane) + uv_offset,
173 video_frame->stride(VideoFrame::kVPlane),
174 static_cast<uint8*>(rgb_pixels),
175 row_bytes,
176 video_frame->visible_rect().width(),
177 video_frame->visible_rect().height());
178 break;
179
180 case VideoFrame::YV12A:
181 // Since libyuv doesn't support YUVA, fallback to media, which is not ARM
182 // optimized.
183 // TODO(fbarchard, mtomasz): Use libyuv, then copy the alpha channel.
184 ConvertYUVAToARGB(
185 video_frame->data(VideoFrame::kYPlane) + y_offset,
186 video_frame->data(VideoFrame::kUPlane) + uv_offset,
187 video_frame->data(VideoFrame::kVPlane) + uv_offset,
188 video_frame->data(VideoFrame::kAPlane),
189 static_cast<uint8*>(rgb_pixels),
190 video_frame->visible_rect().width(),
191 video_frame->visible_rect().height(),
192 video_frame->stride(VideoFrame::kYPlane),
193 video_frame->stride(VideoFrame::kUPlane),
194 video_frame->stride(VideoFrame::kAPlane),
195 row_bytes,
196 YV12);
197 break;
198
199 case VideoFrame::YV24:
200 libyuv::I444ToARGB(
201 video_frame->data(VideoFrame::kYPlane) + y_offset,
202 video_frame->stride(VideoFrame::kYPlane),
203 video_frame->data(VideoFrame::kUPlane) + uv_offset,
204 video_frame->stride(VideoFrame::kUPlane),
205 video_frame->data(VideoFrame::kVPlane) + uv_offset,
206 video_frame->stride(VideoFrame::kVPlane),
207 static_cast<uint8*>(rgb_pixels),
208 row_bytes,
209 video_frame->visible_rect().width(),
210 video_frame->visible_rect().height());
211 #if SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
212 SK_A32_SHIFT == 24
213 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels),
214 row_bytes,
215 static_cast<uint8*>(rgb_pixels),
216 row_bytes,
217 video_frame->visible_rect().width(),
218 video_frame->visible_rect().height());
219 #endif
220 break;
221
222 case VideoFrame::NATIVE_TEXTURE: {
223 SkBitmap tmp;
224 tmp.installPixels(
225 SkImageInfo::MakeN32Premul(video_frame->visible_rect().width(),
226 video_frame->visible_rect().height()),
227 rgb_pixels,
228 row_bytes);
229 video_frame->ReadPixelsFromNativeTexture(tmp);
230 break;
231 }
232
233 #if defined(VIDEO_HOLE)
234 case VideoFrame::HOLE:
235 #endif // defined(VIDEO_HOLE)
236 case VideoFrame::ARGB:
237 case VideoFrame::UNKNOWN:
238 case VideoFrame::NV12:
239 NOTREACHED();
240 }
241 }
242
243 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap, 94 bool IsSkBitmapProperlySizedTexture(const SkBitmap* bitmap,
244 const gfx::Size& size) { 95 const gfx::Size& size) {
245 return bitmap->getTexture() && bitmap->width() == size.width() && 96 return bitmap->getTexture() && bitmap->width() == size.width() &&
246 bitmap->height() == size.height(); 97 bitmap->height() == size.height();
247 } 98 }
248 99
249 bool AllocateSkBitmapTexture(GrContext* gr, 100 bool AllocateSkBitmapTexture(GrContext* gr,
250 SkBitmap* bitmap, 101 SkBitmap* bitmap,
251 const gfx::Size& size) { 102 const gfx::Size& size) {
252 DCHECK(gr); 103 DCHECK(gr);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 bool onGetPixels(const SkImageInfo& info, 188 bool onGetPixels(const SkImageInfo& info,
338 void* pixels, 189 void* pixels,
339 size_t row_bytes, 190 size_t row_bytes,
340 SkPMColor ctable[], 191 SkPMColor ctable[],
341 int* ctable_count) override { 192 int* ctable_count) override {
342 if (!frame_.get()) 193 if (!frame_.get())
343 return false; 194 return false;
344 if (!pixels) 195 if (!pixels)
345 return false; 196 return false;
346 // If skia couldn't do the YUV conversion on GPU, we will on CPU. 197 // If skia couldn't do the YUV conversion on GPU, we will on CPU.
347 ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes); 198 SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
199 frame_, pixels, row_bytes);
348 return true; 200 return true;
349 } 201 }
350 202
351 bool onGetYUV8Planes(SkISize sizes[3], 203 bool onGetYUV8Planes(SkISize sizes[3],
352 void* planes[3], 204 void* planes[3],
353 size_t row_bytes[3], 205 size_t row_bytes[3],
354 SkYUVColorSpace* color_space) override { 206 SkYUVColorSpace* color_space) override {
355 if (!frame_.get() || !IsYUV(frame_->format()) || 207 if (!frame_.get() || !IsYUV(frame_->format()) ||
356 // TODO(rileya): Skia currently doesn't support Rec709 YUV conversion, 208 // TODO(rileya): Skia currently doesn't support Rec709 YUV conversion,
357 // Remove this case once it does. As-is we will fall back on the 209 // Remove this case once it does. As-is we will fall back on the
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 accelerated_generator_->set_frame(nullptr); 417 accelerated_generator_->set_frame(nullptr);
566 } 418 }
567 419
568 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, 420 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
569 SkCanvas* canvas) { 421 SkCanvas* canvas) {
570 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff, 422 Paint(video_frame, canvas, video_frame->visible_rect(), 0xff,
571 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, Context3D()); 423 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, Context3D());
572 } 424 }
573 425
574 // static 426 // static
427 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
428 const scoped_refptr<media::VideoFrame>& video_frame,
429 void* rgb_pixels,
430 size_t row_bytes) {
431 DCHECK(IsYUVOrNative(video_frame->format()))
432 << video_frame->format();
433 if (IsYUV(video_frame->format())) {
434 DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane),
435 video_frame->stride(media::VideoFrame::kVPlane));
436 }
437
438 size_t y_offset = 0;
439 size_t uv_offset = 0;
440 if (IsYUV(video_frame->format())) {
441 int y_shift = (video_frame->format() == media::VideoFrame::YV16) ? 0 : 1;
442 // Use the "left" and "top" of the destination rect to locate the offset
443 // in Y, U and V planes.
444 y_offset = (video_frame->stride(media::VideoFrame::kYPlane) *
445 video_frame->visible_rect().y()) +
446 video_frame->visible_rect().x();
447 // For format YV12, there is one U, V value per 2x2 block.
448 // For format YV16, there is one U, V value per 2x1 block.
449 uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) *
450 (video_frame->visible_rect().y() >> y_shift)) +
451 (video_frame->visible_rect().x() >> 1);
452 }
453
454 switch (video_frame->format()) {
455 case VideoFrame::YV12:
456 case VideoFrame::I420:
457 LIBYUV_I420_TO_ARGB(
458 video_frame->data(VideoFrame::kYPlane) + y_offset,
459 video_frame->stride(VideoFrame::kYPlane),
460 video_frame->data(VideoFrame::kUPlane) + uv_offset,
461 video_frame->stride(VideoFrame::kUPlane),
462 video_frame->data(VideoFrame::kVPlane) + uv_offset,
463 video_frame->stride(VideoFrame::kVPlane),
464 static_cast<uint8*>(rgb_pixels),
465 row_bytes,
466 video_frame->visible_rect().width(),
467 video_frame->visible_rect().height());
468 break;
469
470 case VideoFrame::YV12J:
471 ConvertYUVToRGB32(
472 video_frame->data(VideoFrame::kYPlane) + y_offset,
473 video_frame->data(VideoFrame::kUPlane) + uv_offset,
474 video_frame->data(VideoFrame::kVPlane) + uv_offset,
475 static_cast<uint8*>(rgb_pixels),
476 video_frame->visible_rect().width(),
477 video_frame->visible_rect().height(),
478 video_frame->stride(VideoFrame::kYPlane),
479 video_frame->stride(VideoFrame::kUPlane),
480 row_bytes,
481 YV12J);
482 break;
483
484 case VideoFrame::YV12HD:
485 ConvertYUVToRGB32(
486 video_frame->data(VideoFrame::kYPlane) + y_offset,
487 video_frame->data(VideoFrame::kUPlane) + uv_offset,
488 video_frame->data(VideoFrame::kVPlane) + uv_offset,
489 static_cast<uint8*>(rgb_pixels),
490 video_frame->visible_rect().width(),
491 video_frame->visible_rect().height(),
492 video_frame->stride(VideoFrame::kYPlane),
493 video_frame->stride(VideoFrame::kUPlane),
494 row_bytes,
495 YV12HD);
496 break;
497
498 case VideoFrame::YV16:
499 LIBYUV_I422_TO_ARGB(
500 video_frame->data(VideoFrame::kYPlane) + y_offset,
501 video_frame->stride(VideoFrame::kYPlane),
502 video_frame->data(VideoFrame::kUPlane) + uv_offset,
503 video_frame->stride(VideoFrame::kUPlane),
504 video_frame->data(VideoFrame::kVPlane) + uv_offset,
505 video_frame->stride(VideoFrame::kVPlane),
506 static_cast<uint8*>(rgb_pixels),
507 row_bytes,
508 video_frame->visible_rect().width(),
509 video_frame->visible_rect().height());
510 break;
511
512 case VideoFrame::YV12A:
513 // Since libyuv doesn't support YUVA, fallback to media, which is not ARM
514 // optimized.
515 // TODO(fbarchard, mtomasz): Use libyuv, then copy the alpha channel.
516 ConvertYUVAToARGB(
517 video_frame->data(VideoFrame::kYPlane) + y_offset,
518 video_frame->data(VideoFrame::kUPlane) + uv_offset,
519 video_frame->data(VideoFrame::kVPlane) + uv_offset,
520 video_frame->data(VideoFrame::kAPlane),
521 static_cast<uint8*>(rgb_pixels),
522 video_frame->visible_rect().width(),
523 video_frame->visible_rect().height(),
524 video_frame->stride(VideoFrame::kYPlane),
525 video_frame->stride(VideoFrame::kUPlane),
526 video_frame->stride(VideoFrame::kAPlane),
527 row_bytes,
528 YV12);
529 break;
530
531 case VideoFrame::YV24:
532 libyuv::I444ToARGB(
533 video_frame->data(VideoFrame::kYPlane) + y_offset,
534 video_frame->stride(VideoFrame::kYPlane),
535 video_frame->data(VideoFrame::kUPlane) + uv_offset,
536 video_frame->stride(VideoFrame::kUPlane),
537 video_frame->data(VideoFrame::kVPlane) + uv_offset,
538 video_frame->stride(VideoFrame::kVPlane),
539 static_cast<uint8*>(rgb_pixels),
540 row_bytes,
541 video_frame->visible_rect().width(),
542 video_frame->visible_rect().height());
543 #if SK_R32_SHIFT == 0 && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16 && \
544 SK_A32_SHIFT == 24
545 libyuv::ARGBToABGR(static_cast<uint8*>(rgb_pixels),
546 row_bytes,
547 static_cast<uint8*>(rgb_pixels),
548 row_bytes,
549 video_frame->visible_rect().width(),
550 video_frame->visible_rect().height());
551 #endif
552 break;
553
554 case VideoFrame::NATIVE_TEXTURE: {
555 SkBitmap tmp;
556 tmp.installPixels(
557 SkImageInfo::MakeN32Premul(video_frame->visible_rect().width(),
558 video_frame->visible_rect().height()),
559 rgb_pixels,
560 row_bytes);
561 video_frame->ReadPixelsFromNativeTexture(tmp);
562 break;
563 }
564
565 #if defined(VIDEO_HOLE)
566 case VideoFrame::HOLE:
567 #endif // defined(VIDEO_HOLE)
568 case VideoFrame::ARGB:
569 case VideoFrame::UNKNOWN:
570 case VideoFrame::NV12:
571 NOTREACHED();
572 }
573 }
574
575 // static
575 void SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture( 576 void SkCanvasVideoRenderer::CopyVideoFrameTextureToGLTexture(
576 gpu::gles2::GLES2Interface* gl, 577 gpu::gles2::GLES2Interface* gl,
577 VideoFrame* video_frame, 578 VideoFrame* video_frame,
578 unsigned int texture, 579 unsigned int texture,
579 unsigned int level, 580 unsigned int level,
580 unsigned int internal_format, 581 unsigned int internal_format,
581 unsigned int type, 582 unsigned int type,
582 bool premultiply_alpha, 583 bool premultiply_alpha,
583 bool flip_y) { 584 bool flip_y) {
584 DCHECK(video_frame && video_frame->format() == VideoFrame::NATIVE_TEXTURE); 585 DCHECK(video_frame && video_frame->format() == VideoFrame::NATIVE_TEXTURE);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 last_frame_timestamp_ = media::kNoTimestamp(); 617 last_frame_timestamp_ = media::kNoTimestamp();
617 } 618 }
618 619
619 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() { 620 void SkCanvasVideoRenderer::ResetAcceleratedLastFrame() {
620 accelerated_last_frame_.reset(); 621 accelerated_last_frame_.reset();
621 accelerated_generator_ = nullptr; 622 accelerated_generator_ = nullptr;
622 accelerated_last_frame_timestamp_ = media::kNoTimestamp(); 623 accelerated_last_frame_timestamp_ = media::kNoTimestamp();
623 } 624 }
624 625
625 } // namespace media 626 } // namespace media
OLDNEW
« content/renderer/pepper/video_decoder_shim.cc ('K') | « media/filters/skcanvas_video_renderer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698