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

Side by Side Diff: media/video/gpu_memory_buffer_video_frame_pool.cc

Issue 2121043002: 16 bpp video stream capture, render and WebGL usage - Realsense R200 & SR300 support. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: scoping Y8 out. Created 4 years, 2 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 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 "media/video/gpu_memory_buffer_video_frame_pool.h" 5 #include "media/video/gpu_memory_buffer_video_frame_pool.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <stdint.h> 10 #include <stdint.h>
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 struct PlaneResource { 79 struct PlaneResource {
80 gfx::Size size; 80 gfx::Size size;
81 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer; 81 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
82 unsigned texture_id = 0u; 82 unsigned texture_id = 0u;
83 unsigned image_id = 0u; 83 unsigned image_id = 0u;
84 gpu::Mailbox mailbox; 84 gpu::Mailbox mailbox;
85 }; 85 };
86 86
87 // All the resources needed to compose a frame. 87 // All the resources needed to compose a frame.
88 struct FrameResources { 88 struct FrameResources {
89 explicit FrameResources(const gfx::Size& size) : size(size) {} 89 explicit FrameResources(const gfx::Size& size, VideoPixelFormat format)
90 : size(size), format(format) {}
90 void SetIsInUse(bool in_use) { in_use_ = in_use; } 91 void SetIsInUse(bool in_use) { in_use_ = in_use; }
91 bool IsInUse() const { return in_use_; } 92 bool IsInUse() const { return in_use_; }
92 93
93 const gfx::Size size; 94 const gfx::Size size;
95 VideoPixelFormat format;
94 PlaneResource plane_resources[VideoFrame::kMaxPlanes]; 96 PlaneResource plane_resources[VideoFrame::kMaxPlanes];
95 97
96 private: 98 private:
97 bool in_use_ = true; 99 bool in_use_ = true;
98 }; 100 };
99 101
100 // Copy |video_frame| data into |frame_resouces| 102 // Copy |video_frame| data into |frame_resouces|
101 // and calls |done| when done. 103 // and calls |done| when done.
102 void CopyVideoFrameToGpuMemoryBuffers( 104 void CopyVideoFrameToGpuMemoryBuffers(
103 const scoped_refptr<VideoFrame>& video_frame, 105 const scoped_refptr<VideoFrame>& video_frame,
(...skipping 10 matching lines...) Expand all
114 // This has to be run on |media_task_runner_| where |frame_ready_cb| will also 116 // This has to be run on |media_task_runner_| where |frame_ready_cb| will also
115 // be run. 117 // be run.
116 void BindAndCreateMailboxesHardwareFrameResources( 118 void BindAndCreateMailboxesHardwareFrameResources(
117 const scoped_refptr<VideoFrame>& video_frame, 119 const scoped_refptr<VideoFrame>& video_frame,
118 FrameResources* frame_resources, 120 FrameResources* frame_resources,
119 const FrameReadyCB& frame_ready_cb); 121 const FrameReadyCB& frame_ready_cb);
120 122
121 // Return true if |resources| can be used to represent a frame for 123 // Return true if |resources| can be used to represent a frame for
122 // specific |format| and |size|. 124 // specific |format| and |size|.
123 static bool AreFrameResourcesCompatible(const FrameResources* resources, 125 static bool AreFrameResourcesCompatible(const FrameResources* resources,
124 const gfx::Size& size) { 126 const gfx::Size& size,
125 return size == resources->size; 127 VideoPixelFormat format) {
128 return size == resources->size && format == resources->format;
126 } 129 }
127 130
128 // Get the resources needed for a frame out of the pool, or create them if 131 // Get the resources needed for a frame out of the pool, or create them if
129 // necessary. 132 // necessary.
130 // This also drops the LRU resources that can't be reuse for this frame. 133 // This also drops the LRU resources that can't be reuse for this frame.
131 FrameResources* GetOrCreateFrameResources(const gfx::Size& size, 134 FrameResources* GetOrCreateFrameResources(const gfx::Size& size,
132 VideoPixelFormat format); 135 VideoPixelFormat format);
133 136
134 // Callback called when a VideoFrame generated with GetFrameResources is no 137 // Callback called when a VideoFrame generated with GetFrameResources is no
135 // longer referenced. 138 // longer referenced.
(...skipping 12 matching lines...) Expand all
148 scoped_refptr<base::TaskRunner> worker_task_runner_; 151 scoped_refptr<base::TaskRunner> worker_task_runner_;
149 152
150 // Interface to GPU related operations. 153 // Interface to GPU related operations.
151 GpuVideoAcceleratorFactories* gpu_factories_; 154 GpuVideoAcceleratorFactories* gpu_factories_;
152 155
153 // Pool of resources. 156 // Pool of resources.
154 std::list<FrameResources*> resources_pool_; 157 std::list<FrameResources*> resources_pool_;
155 158
156 // TODO(dcastagna): change the following type from VideoPixelFormat to 159 // TODO(dcastagna): change the following type from VideoPixelFormat to
157 // BufferFormat. 160 // BufferFormat.
161 // Pixel format of the hardware video frames for I420 and YV12 video.
158 VideoPixelFormat output_format_; 162 VideoPixelFormat output_format_;
Daniele Castagna 2016/10/10 18:42:31 This is changing slightly with crrev.com/238244300
aleksandar.stojiljkovic 2016/10/11 18:29:54 Done. CL split to: crrev.com/2410923002: GpuMemory
159 163
164 // If texture_rg is supported, gpu memory buffers can be used for R8 and RG8.
165 bool texture_rg_available_ = false;
166 bool texture_rg_available_initialized_ = false;
167
160 DISALLOW_COPY_AND_ASSIGN(PoolImpl); 168 DISALLOW_COPY_AND_ASSIGN(PoolImpl);
161 }; 169 };
162 170
163 namespace { 171 namespace {
164 172
165 // VideoFrame copies to GpuMemoryBuffers will be split in copies where the 173 // VideoFrame copies to GpuMemoryBuffers will be split in copies where the
166 // output size is |kBytesPerCopyTarget| bytes and run in parallel. 174 // output size is |kBytesPerCopyTarget| bytes and run in parallel.
167 const size_t kBytesPerCopyTarget = 1024 * 1024; // 1MB 175 const size_t kBytesPerCopyTarget = 1024 * 1024; // 1MB
168 176
169 // Return the GpuMemoryBuffer format to use for a specific VideoPixelFormat
170 // and plane.
171 gfx::BufferFormat GpuMemoryBufferFormat(VideoPixelFormat format, size_t plane) {
172 switch (format) {
173 case PIXEL_FORMAT_I420:
174 DCHECK_LE(plane, 2u);
175 return gfx::BufferFormat::R_8;
176 case PIXEL_FORMAT_NV12:
177 DCHECK_LE(plane, 1u);
178 return gfx::BufferFormat::YUV_420_BIPLANAR;
179 case PIXEL_FORMAT_UYVY:
180 DCHECK_EQ(0u, plane);
181 return gfx::BufferFormat::UYVY_422;
182 default:
183 NOTREACHED();
184 return gfx::BufferFormat::BGRA_8888;
185 }
186 }
187
188 unsigned ImageInternalFormat(VideoPixelFormat format, size_t plane) { 177 unsigned ImageInternalFormat(VideoPixelFormat format, size_t plane) {
189 switch (format) { 178 switch (format) {
190 case PIXEL_FORMAT_I420: 179 case PIXEL_FORMAT_I420:
191 DCHECK_LE(plane, 2u); 180 DCHECK_LE(plane, 2u);
192 return GL_RED_EXT; 181 return GL_RED_EXT;
193 case PIXEL_FORMAT_NV12: 182 case PIXEL_FORMAT_NV12:
194 DCHECK_LE(plane, 1u); 183 DCHECK_LE(plane, 1u);
195 return GL_RGB_YCBCR_420V_CHROMIUM; 184 return GL_RGB_YCBCR_420V_CHROMIUM;
196 case PIXEL_FORMAT_UYVY: 185 case PIXEL_FORMAT_UYVY:
197 DCHECK_EQ(0u, plane); 186 DCHECK_EQ(0u, plane);
198 return GL_RGB_YCBCR_422_CHROMIUM; 187 return GL_RGB_YCBCR_422_CHROMIUM;
188 case PIXEL_FORMAT_Y16:
189 DCHECK_EQ(0u, plane);
190 return GL_RG_EXT;
199 default: 191 default:
200 NOTREACHED(); 192 NOTREACHED();
201 return 0; 193 return 0;
202 } 194 }
203 } 195 }
204 196
205 // The number of output planes to be copied in each iteration. 197 // The number of output planes to be copied in each iteration.
206 size_t PlanesPerCopy(VideoPixelFormat format) { 198 size_t PlanesPerCopy(VideoPixelFormat format) {
207 switch (format) { 199 switch (format) {
208 case PIXEL_FORMAT_I420: 200 case PIXEL_FORMAT_I420:
209 case PIXEL_FORMAT_UYVY: 201 case PIXEL_FORMAT_UYVY:
202 case PIXEL_FORMAT_Y16:
210 return 1; 203 return 1;
211 case PIXEL_FORMAT_NV12: 204 case PIXEL_FORMAT_NV12:
212 return 2; 205 return 2;
213 default: 206 default:
214 NOTREACHED(); 207 NOTREACHED();
215 return 0; 208 return 0;
216 } 209 }
217 } 210 }
218 211
219 // The number of output rows to be copied in each iteration. 212 // The number of output rows to be copied in each iteration.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 first_row / 2 * source_frame->stride(VideoFrame::kUPlane), 298 first_row / 2 * source_frame->stride(VideoFrame::kUPlane),
306 source_frame->stride(VideoFrame::kUPlane), 299 source_frame->stride(VideoFrame::kUPlane),
307 source_frame->visible_data(VideoFrame::kVPlane) + 300 source_frame->visible_data(VideoFrame::kVPlane) +
308 first_row / 2 * source_frame->stride(VideoFrame::kVPlane), 301 first_row / 2 * source_frame->stride(VideoFrame::kVPlane),
309 source_frame->stride(VideoFrame::kVPlane), 302 source_frame->stride(VideoFrame::kVPlane),
310 output + first_row * dest_stride, dest_stride, width, rows); 303 output + first_row * dest_stride, dest_stride, width, rows);
311 } 304 }
312 done.Run(); 305 done.Run();
313 } 306 }
314 307
308 void CopyRowsToGPUBuffer(int first_row,
309 int rows,
310 int width,
311 const scoped_refptr<VideoFrame>& source_frame,
312 uint8_t* output,
313 int dest_stride,
314 const base::Closure& done) {
315 int row_bytes = VideoFrame::RowBytes(0, source_frame->format(), width);
316 TRACE_EVENT2("media", "CopyRowsToGPUBuffer", "bytes_per_row", row_bytes,
317 "rows", rows);
318 if (output) {
319 DCHECK_NE(dest_stride, 0);
320 DCHECK_LE(row_bytes, std::abs(dest_stride));
321 const int source_stride = source_frame->stride(0);
322 const uint8_t* source =
323 source_frame->visible_data(0) + first_row * source_stride;
324 uint8_t* dest = output + first_row * dest_stride;
325 for (int i = 0; i < rows; ++i)
326 memcpy(dest + i * dest_stride, source + i * source_stride, row_bytes);
327 }
328 done.Run();
329 }
330
315 gfx::Size CodedSize(const scoped_refptr<VideoFrame>& video_frame, 331 gfx::Size CodedSize(const scoped_refptr<VideoFrame>& video_frame,
316 VideoPixelFormat output_format) { 332 VideoPixelFormat output_format) {
317 DCHECK(gfx::Rect(video_frame->coded_size()) 333 DCHECK(gfx::Rect(video_frame->coded_size())
318 .Contains(video_frame->visible_rect())); 334 .Contains(video_frame->visible_rect()));
319 DCHECK((video_frame->visible_rect().x() & 1) == 0); 335 DCHECK((video_frame->visible_rect().x() & 1) == 0);
320 gfx::Size output; 336 gfx::Size output;
321 switch (output_format) { 337 switch (output_format) {
322 case PIXEL_FORMAT_I420: 338 case PIXEL_FORMAT_I420:
323 case PIXEL_FORMAT_NV12: 339 case PIXEL_FORMAT_NV12:
324 DCHECK((video_frame->visible_rect().y() & 1) == 0); 340 DCHECK((video_frame->visible_rect().y() & 1) == 0);
325 output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1, 341 output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1,
326 (video_frame->visible_rect().height() + 1) & ~1); 342 (video_frame->visible_rect().height() + 1) & ~1);
327 break; 343 break;
328 case PIXEL_FORMAT_UYVY: 344 case PIXEL_FORMAT_UYVY:
329 output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1, 345 output = gfx::Size((video_frame->visible_rect().width() + 1) & ~1,
330 video_frame->visible_rect().height()); 346 video_frame->visible_rect().height());
331 break; 347 break;
348 case PIXEL_FORMAT_Y16:
349 output = video_frame->visible_rect().size();
350 break;
332 default: 351 default:
333 NOTREACHED(); 352 NOTREACHED();
334 } 353 }
335 DCHECK(gfx::Rect(video_frame->coded_size()).Contains(gfx::Rect(output))); 354 DCHECK(gfx::Rect(video_frame->coded_size()).Contains(gfx::Rect(output)));
336 return output; 355 return output;
337 } 356 }
338 } // unnamed namespace 357 } // unnamed namespace
339 358
340 // Creates a VideoFrame backed by native textures starting from a software 359 // Creates a VideoFrame backed by native textures starting from a software
341 // VideoFrame. 360 // VideoFrame.
342 // The data contained in |video_frame| is copied into the VideoFrame passed to 361 // The data contained in |video_frame| is copied into the VideoFrame passed to
343 // |frame_ready_cb|. 362 // |frame_ready_cb|.
344 // This has to be called on the thread where |media_task_runner_| is current. 363 // This has to be called on the thread where |media_task_runner_| is current.
345 void GpuMemoryBufferVideoFramePool::PoolImpl::CreateHardwareFrame( 364 void GpuMemoryBufferVideoFramePool::PoolImpl::CreateHardwareFrame(
346 const scoped_refptr<VideoFrame>& video_frame, 365 const scoped_refptr<VideoFrame>& video_frame,
347 const FrameReadyCB& frame_ready_cb) { 366 const FrameReadyCB& frame_ready_cb) {
348 DCHECK(media_task_runner_->BelongsToCurrentThread()); 367 DCHECK(media_task_runner_->BelongsToCurrentThread());
349 // Lazily initialize output_format_ since VideoFrameOutputFormat() has to be 368 media::VideoPixelFormat output_format = PIXEL_FORMAT_UNKNOWN;
350 // called on the media_thread while this object might be instantiated on any.
351 if (output_format_ == PIXEL_FORMAT_UNKNOWN)
352 output_format_ = gpu_factories_->VideoFrameOutputFormat();
353
354 if (output_format_ == PIXEL_FORMAT_UNKNOWN) {
355 frame_ready_cb.Run(video_frame);
356 return;
357 }
358 switch (video_frame->format()) { 369 switch (video_frame->format()) {
359 // Supported cases. 370 // Supported cases.
360 case PIXEL_FORMAT_YV12: 371 case PIXEL_FORMAT_YV12:
361 case PIXEL_FORMAT_I420: 372 case PIXEL_FORMAT_I420: {
373 // Lazily initialize output_format_ since VideoFrameOutputFormat() has to
374 // be called on the media_thread while this object might be instantiated
375 // on any.
376 if (output_format_ == PIXEL_FORMAT_UNKNOWN) {
377 output_format_ =
378 gpu_factories_->VideoFrameOutputFormat(PIXEL_FORMAT_I420);
379 }
380 output_format = output_format_;
381 break;
382 }
383 case PIXEL_FORMAT_Y16:
384 // Lazily initialize texture_rg_available_.
385 if (!texture_rg_available_initialized_) {
386 texture_rg_available_initialized_ = true;
387 texture_rg_available_ = gpu_factories_->VideoFrameOutputFormat(
388 PIXEL_FORMAT_Y16) == PIXEL_FORMAT_Y16;
389 }
390 output_format =
391 texture_rg_available_ ? video_frame->format() : PIXEL_FORMAT_UNKNOWN;
362 break; 392 break;
363 // Unsupported cases. 393 // Unsupported cases.
364 case PIXEL_FORMAT_YV12A: 394 case PIXEL_FORMAT_YV12A:
365 case PIXEL_FORMAT_YV16: 395 case PIXEL_FORMAT_YV16:
366 case PIXEL_FORMAT_YV24: 396 case PIXEL_FORMAT_YV24:
367 case PIXEL_FORMAT_NV12: 397 case PIXEL_FORMAT_NV12:
368 case PIXEL_FORMAT_NV21: 398 case PIXEL_FORMAT_NV21:
369 case PIXEL_FORMAT_UYVY: 399 case PIXEL_FORMAT_UYVY:
370 case PIXEL_FORMAT_YUY2: 400 case PIXEL_FORMAT_YUY2:
371 case PIXEL_FORMAT_ARGB: 401 case PIXEL_FORMAT_ARGB:
372 case PIXEL_FORMAT_XRGB: 402 case PIXEL_FORMAT_XRGB:
373 case PIXEL_FORMAT_RGB24: 403 case PIXEL_FORMAT_RGB24:
374 case PIXEL_FORMAT_RGB32: 404 case PIXEL_FORMAT_RGB32:
375 case PIXEL_FORMAT_MJPEG: 405 case PIXEL_FORMAT_MJPEG:
376 case PIXEL_FORMAT_MT21: 406 case PIXEL_FORMAT_MT21:
377 case PIXEL_FORMAT_YUV420P9: 407 case PIXEL_FORMAT_YUV420P9:
378 case PIXEL_FORMAT_YUV422P9: 408 case PIXEL_FORMAT_YUV422P9:
379 case PIXEL_FORMAT_YUV444P9: 409 case PIXEL_FORMAT_YUV444P9:
380 case PIXEL_FORMAT_YUV420P10: 410 case PIXEL_FORMAT_YUV420P10:
381 case PIXEL_FORMAT_YUV422P10: 411 case PIXEL_FORMAT_YUV422P10:
382 case PIXEL_FORMAT_YUV444P10: 412 case PIXEL_FORMAT_YUV444P10:
383 case PIXEL_FORMAT_YUV420P12: 413 case PIXEL_FORMAT_YUV420P12:
384 case PIXEL_FORMAT_YUV422P12: 414 case PIXEL_FORMAT_YUV422P12:
385 case PIXEL_FORMAT_YUV444P12: 415 case PIXEL_FORMAT_YUV444P12:
386 case PIXEL_FORMAT_Y8: 416 case PIXEL_FORMAT_Y8:
387 case PIXEL_FORMAT_Y16:
388 case PIXEL_FORMAT_UNKNOWN: 417 case PIXEL_FORMAT_UNKNOWN:
389 frame_ready_cb.Run(video_frame); 418 break;
390 return; 419 }
420 if (output_format == PIXEL_FORMAT_UNKNOWN) {
421 frame_ready_cb.Run(video_frame);
422 return;
391 } 423 }
392 424
393 const gfx::Size coded_size = CodedSize(video_frame, output_format_); 425 const gfx::Size coded_size = CodedSize(video_frame, output_format);
394 // Acquire resources. Incompatible ones will be dropped from the pool. 426 // Acquire resources. Incompatible ones will be dropped from the pool.
395 FrameResources* frame_resources = 427 FrameResources* frame_resources =
396 GetOrCreateFrameResources(coded_size, output_format_); 428 GetOrCreateFrameResources(coded_size, output_format);
397 if (!frame_resources) { 429 if (!frame_resources) {
398 frame_ready_cb.Run(video_frame); 430 frame_ready_cb.Run(video_frame);
399 return; 431 return;
400 } 432 }
401 433
402 worker_task_runner_->PostTask( 434 worker_task_runner_->PostTask(
403 FROM_HERE, base::Bind(&PoolImpl::CopyVideoFrameToGpuMemoryBuffers, this, 435 FROM_HERE, base::Bind(&PoolImpl::CopyVideoFrameToGpuMemoryBuffers, this,
404 video_frame, frame_resources, frame_ready_cb)); 436 video_frame, frame_resources, frame_ready_cb));
405 } 437 }
406 438
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 } 491 }
460 492
461 // Copies |video_frame| into |frame_resources| asynchronously, posting n tasks 493 // Copies |video_frame| into |frame_resources| asynchronously, posting n tasks
462 // that will be synchronized by a barrier. 494 // that will be synchronized by a barrier.
463 // After the barrier is passed OnCopiesDone will be called. 495 // After the barrier is passed OnCopiesDone will be called.
464 void GpuMemoryBufferVideoFramePool::PoolImpl::CopyVideoFrameToGpuMemoryBuffers( 496 void GpuMemoryBufferVideoFramePool::PoolImpl::CopyVideoFrameToGpuMemoryBuffers(
465 const scoped_refptr<VideoFrame>& video_frame, 497 const scoped_refptr<VideoFrame>& video_frame,
466 FrameResources* frame_resources, 498 FrameResources* frame_resources,
467 const FrameReadyCB& frame_ready_cb) { 499 const FrameReadyCB& frame_ready_cb) {
468 // Compute the number of tasks to post and create the barrier. 500 // Compute the number of tasks to post and create the barrier.
469 const size_t num_planes = VideoFrame::NumPlanes(output_format_); 501 const size_t num_planes = VideoFrame::NumPlanes(frame_resources->format);
470 const size_t planes_per_copy = PlanesPerCopy(output_format_); 502 const size_t planes_per_copy = PlanesPerCopy(frame_resources->format);
471 const gfx::Size coded_size = CodedSize(video_frame, output_format_); 503 const gfx::Size coded_size = CodedSize(video_frame, frame_resources->format);
472 size_t copies = 0; 504 size_t copies = 0;
473 for (size_t i = 0; i < num_planes; i += planes_per_copy) { 505 for (size_t i = 0; i < num_planes; i += planes_per_copy) {
474 const int rows = VideoFrame::Rows(i, output_format_, coded_size.height()); 506 const int rows =
507 VideoFrame::Rows(i, frame_resources->format, coded_size.height());
475 const int rows_per_copy = 508 const int rows_per_copy =
476 RowsPerCopy(i, output_format_, coded_size.width()); 509 RowsPerCopy(i, frame_resources->format, coded_size.width());
477 copies += rows / rows_per_copy; 510 copies += rows / rows_per_copy;
478 if (rows % rows_per_copy) 511 if (rows % rows_per_copy)
479 ++copies; 512 ++copies;
480 } 513 }
481 const base::Closure copies_done = 514 const base::Closure copies_done =
482 base::Bind(&PoolImpl::OnCopiesDone, this, video_frame, frame_resources, 515 base::Bind(&PoolImpl::OnCopiesDone, this, video_frame, frame_resources,
483 frame_ready_cb); 516 frame_ready_cb);
484 const base::Closure barrier = base::BarrierClosure(copies, copies_done); 517 const base::Closure barrier = base::BarrierClosure(copies, copies_done);
485 518
486 // Post all the async tasks. 519 // Post all the async tasks.
487 for (size_t i = 0; i < num_planes; i += planes_per_copy) { 520 for (size_t i = 0; i < num_planes; i += planes_per_copy) {
488 gfx::GpuMemoryBuffer* buffer = 521 gfx::GpuMemoryBuffer* buffer =
489 frame_resources->plane_resources[i].gpu_memory_buffer.get(); 522 frame_resources->plane_resources[i].gpu_memory_buffer.get();
490 523
491 if (!buffer || !buffer->Map()) { 524 if (!buffer || !buffer->Map()) {
492 DLOG(ERROR) << "Could not get or Map() buffer"; 525 DLOG(ERROR) << "Could not get or Map() buffer";
493 return; 526 return;
494 } 527 }
495 DCHECK_EQ(planes_per_copy, 528 DCHECK_EQ(planes_per_copy,
496 gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat())); 529 gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat()));
497 530
498 const int rows = VideoFrame::Rows(i, output_format_, coded_size.height()); 531 const int rows =
532 VideoFrame::Rows(i, frame_resources->format, coded_size.height());
499 const int rows_per_copy = 533 const int rows_per_copy =
500 RowsPerCopy(i, output_format_, coded_size.width()); 534 RowsPerCopy(i, frame_resources->format, coded_size.width());
501 535
502 for (int row = 0; row < rows; row += rows_per_copy) { 536 for (int row = 0; row < rows; row += rows_per_copy) {
503 const int rows_to_copy = std::min(rows_per_copy, rows - row); 537 const int rows_to_copy = std::min(rows_per_copy, rows - row);
504 switch (output_format_) { 538 switch (frame_resources->format) {
505 case PIXEL_FORMAT_I420: { 539 case PIXEL_FORMAT_I420: {
506 const int bytes_per_row = 540 const int bytes_per_row = VideoFrame::RowBytes(
507 VideoFrame::RowBytes(i, output_format_, coded_size.width()); 541 i, frame_resources->format, coded_size.width());
508 worker_task_runner_->PostTask( 542 worker_task_runner_->PostTask(
509 FROM_HERE, base::Bind(&CopyRowsToI420Buffer, row, rows_to_copy, 543 FROM_HERE, base::Bind(&CopyRowsToI420Buffer, row, rows_to_copy,
510 bytes_per_row, video_frame->visible_data(i), 544 bytes_per_row, video_frame->visible_data(i),
511 video_frame->stride(i), 545 video_frame->stride(i),
512 static_cast<uint8_t*>(buffer->memory(0)), 546 static_cast<uint8_t*>(buffer->memory(0)),
513 buffer->stride(0), barrier)); 547 buffer->stride(0), barrier));
514 break; 548 break;
515 } 549 }
516 case PIXEL_FORMAT_NV12: 550 case PIXEL_FORMAT_NV12:
517 worker_task_runner_->PostTask( 551 worker_task_runner_->PostTask(
518 FROM_HERE, base::Bind(&CopyRowsToNV12Buffer, row, rows_to_copy, 552 FROM_HERE, base::Bind(&CopyRowsToNV12Buffer, row, rows_to_copy,
519 coded_size.width(), video_frame, 553 coded_size.width(), video_frame,
520 static_cast<uint8_t*>(buffer->memory(0)), 554 static_cast<uint8_t*>(buffer->memory(0)),
521 buffer->stride(0), 555 buffer->stride(0),
522 static_cast<uint8_t*>(buffer->memory(1)), 556 static_cast<uint8_t*>(buffer->memory(1)),
523 buffer->stride(1), barrier)); 557 buffer->stride(1), barrier));
524 break; 558 break;
525 case PIXEL_FORMAT_UYVY: 559 case PIXEL_FORMAT_UYVY:
526 worker_task_runner_->PostTask( 560 worker_task_runner_->PostTask(
527 FROM_HERE, base::Bind(&CopyRowsToUYVYBuffer, row, rows_to_copy, 561 FROM_HERE, base::Bind(&CopyRowsToUYVYBuffer, row, rows_to_copy,
528 coded_size.width(), video_frame, 562 coded_size.width(), video_frame,
529 static_cast<uint8_t*>(buffer->memory(0)), 563 static_cast<uint8_t*>(buffer->memory(0)),
530 buffer->stride(0), barrier)); 564 buffer->stride(0), barrier));
531 break; 565 break;
566 case PIXEL_FORMAT_Y16:
567 worker_task_runner_->PostTask(
568 FROM_HERE, base::Bind(&CopyRowsToGPUBuffer, row, rows_to_copy,
569 coded_size.width(), video_frame,
570 static_cast<uint8_t*>(buffer->memory(0)),
571 buffer->stride(0), barrier));
572 break;
532 default: 573 default:
533 NOTREACHED(); 574 NOTREACHED();
534 } 575 }
535 } 576 }
536 } 577 }
537 } 578 }
538 579
539 void GpuMemoryBufferVideoFramePool::PoolImpl:: 580 void GpuMemoryBufferVideoFramePool::PoolImpl::
540 BindAndCreateMailboxesHardwareFrameResources( 581 BindAndCreateMailboxesHardwareFrameResources(
541 const scoped_refptr<VideoFrame>& video_frame, 582 const scoped_refptr<VideoFrame>& video_frame,
542 FrameResources* frame_resources, 583 FrameResources* frame_resources,
543 const FrameReadyCB& frame_ready_cb) { 584 const FrameReadyCB& frame_ready_cb) {
544 std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock( 585 std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock(
545 gpu_factories_->GetGLContextLock()); 586 gpu_factories_->GetGLContextLock());
546 if (!lock) { 587 if (!lock) {
547 frame_ready_cb.Run(video_frame); 588 frame_ready_cb.Run(video_frame);
548 return; 589 return;
549 } 590 }
550 gpu::gles2::GLES2Interface* gles2 = lock->ContextGL(); 591 gpu::gles2::GLES2Interface* gles2 = lock->ContextGL();
551 592
552 const size_t num_planes = VideoFrame::NumPlanes(output_format_); 593 const size_t num_planes = VideoFrame::NumPlanes(frame_resources->format);
553 const size_t planes_per_copy = PlanesPerCopy(output_format_); 594 const size_t planes_per_copy = PlanesPerCopy(frame_resources->format);
554 const gfx::Size coded_size = CodedSize(video_frame, output_format_); 595 const gfx::Size coded_size = CodedSize(video_frame, frame_resources->format);
555 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; 596 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes];
556 // Set up the planes creating the mailboxes needed to refer to the textures. 597 // Set up the planes creating the mailboxes needed to refer to the textures.
557 for (size_t i = 0; i < num_planes; i += planes_per_copy) { 598 for (size_t i = 0; i < num_planes; i += planes_per_copy) {
558 PlaneResource& plane_resource = frame_resources->plane_resources[i]; 599 PlaneResource& plane_resource = frame_resources->plane_resources[i];
559 const gfx::BufferFormat buffer_format = 600 const gfx::BufferFormat buffer_format =
560 GpuMemoryBufferFormat(output_format_, i); 601 VideoFrame::BufferFormat(frame_resources->format);
561 unsigned texture_target = gpu_factories_->ImageTextureTarget(buffer_format); 602 unsigned texture_target = gpu_factories_->ImageTextureTarget(buffer_format);
562 // Bind the texture and create or rebind the image. 603 // Bind the texture and create or rebind the image.
563 gles2->BindTexture(texture_target, plane_resource.texture_id); 604 gles2->BindTexture(texture_target, plane_resource.texture_id);
564 605
565 if (plane_resource.gpu_memory_buffer && !plane_resource.image_id) { 606 if (plane_resource.gpu_memory_buffer && !plane_resource.image_id) {
566 const size_t width = 607 const size_t width =
567 VideoFrame::Columns(i, output_format_, coded_size.width()); 608 VideoFrame::Columns(i, frame_resources->format, coded_size.width());
568 const size_t height = 609 const size_t height =
569 VideoFrame::Rows(i, output_format_, coded_size.height()); 610 VideoFrame::Rows(i, frame_resources->format, coded_size.height());
570 plane_resource.image_id = gles2->CreateImageCHROMIUM( 611 plane_resource.image_id = gles2->CreateImageCHROMIUM(
571 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height, 612 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height,
572 ImageInternalFormat(output_format_, i)); 613 ImageInternalFormat(frame_resources->format, i));
573 } else if (plane_resource.image_id) { 614 } else if (plane_resource.image_id) {
574 gles2->ReleaseTexImage2DCHROMIUM(texture_target, plane_resource.image_id); 615 gles2->ReleaseTexImage2DCHROMIUM(texture_target, plane_resource.image_id);
575 } 616 }
576 if (plane_resource.image_id) 617 if (plane_resource.image_id)
577 gles2->BindTexImage2DCHROMIUM(texture_target, plane_resource.image_id); 618 gles2->BindTexImage2DCHROMIUM(texture_target, plane_resource.image_id);
578 mailbox_holders[i] = gpu::MailboxHolder(plane_resource.mailbox, 619 mailbox_holders[i] = gpu::MailboxHolder(plane_resource.mailbox,
579 gpu::SyncToken(), texture_target); 620 gpu::SyncToken(), texture_target);
580 } 621 }
581 622
582 // Insert a sync_token, this is needed to make sure that the textures the 623 // Insert a sync_token, this is needed to make sure that the textures the
583 // mailboxes refer to will be used only after all the previous commands posted 624 // mailboxes refer to will be used only after all the previous commands posted
584 // in the command buffer have been processed. 625 // in the command buffer have been processed.
585 const GLuint64 fence_sync = gles2->InsertFenceSyncCHROMIUM(); 626 const GLuint64 fence_sync = gles2->InsertFenceSyncCHROMIUM();
586 gles2->OrderingBarrierCHROMIUM(); 627 gles2->OrderingBarrierCHROMIUM();
587 628
588 gpu::SyncToken sync_token; 629 gpu::SyncToken sync_token;
589 gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); 630 gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
590 for (size_t i = 0; i < num_planes; i += planes_per_copy) 631 for (size_t i = 0; i < num_planes; i += planes_per_copy)
591 mailbox_holders[i].sync_token = sync_token; 632 mailbox_holders[i].sync_token = sync_token;
592 633
593 634
594 auto release_mailbox_callback = BindToCurrentLoop( 635 auto release_mailbox_callback = BindToCurrentLoop(
595 base::Bind(&PoolImpl::MailboxHoldersReleased, this, frame_resources)); 636 base::Bind(&PoolImpl::MailboxHoldersReleased, this, frame_resources));
596 637
597 // Consumers should sample from NV12 textures as if they're XRGB. 638 // Consumers should sample from NV12 textures as if they're XRGB.
598 VideoPixelFormat frame_format = 639 VideoPixelFormat frame_format = (frame_resources->format == PIXEL_FORMAT_NV12)
599 output_format_ == PIXEL_FORMAT_NV12 ? PIXEL_FORMAT_XRGB : output_format_; 640 ? PIXEL_FORMAT_XRGB
641 : frame_resources->format;
600 DCHECK_EQ(VideoFrame::NumPlanes(frame_format) * planes_per_copy, num_planes); 642 DCHECK_EQ(VideoFrame::NumPlanes(frame_format) * planes_per_copy, num_planes);
601 643
602 // Create the VideoFrame backed by native textures. 644 // Create the VideoFrame backed by native textures.
603 gfx::Size visible_size = video_frame->visible_rect().size(); 645 gfx::Size visible_size = video_frame->visible_rect().size();
604 scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures( 646 scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures(
605 frame_format, mailbox_holders, release_mailbox_callback, coded_size, 647 frame_format, mailbox_holders, release_mailbox_callback, coded_size,
606 gfx::Rect(visible_size), video_frame->natural_size(), 648 gfx::Rect(visible_size), video_frame->natural_size(),
607 video_frame->timestamp()); 649 video_frame->timestamp());
608 650
609 if (!frame) { 651 if (!frame) {
610 release_mailbox_callback.Run(gpu::SyncToken()); 652 release_mailbox_callback.Run(gpu::SyncToken());
611 frame_ready_cb.Run(video_frame); 653 frame_ready_cb.Run(video_frame);
612 return; 654 return;
613 } 655 }
614 656
615 frame->set_color_space(video_frame->ColorSpace()); 657 frame->set_color_space(video_frame->ColorSpace());
616 658
617 bool allow_overlay = false; 659 bool allow_overlay = false;
618 switch (output_format_) { 660 switch (frame_resources->format) {
619 case PIXEL_FORMAT_I420: 661 case PIXEL_FORMAT_I420:
620 allow_overlay = 662 allow_overlay =
621 video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY); 663 video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY);
622 break; 664 break;
623 case PIXEL_FORMAT_NV12: 665 case PIXEL_FORMAT_NV12:
624 case PIXEL_FORMAT_UYVY: 666 case PIXEL_FORMAT_UYVY:
667 case PIXEL_FORMAT_Y16:
625 allow_overlay = true; 668 allow_overlay = true;
626 break; 669 break;
627 default: 670 default:
628 break; 671 break;
629 } 672 }
630 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, 673 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY,
631 allow_overlay); 674 allow_overlay);
632 675
633 base::TimeTicks render_time; 676 base::TimeTicks render_time;
634 if (video_frame->metadata()->GetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, 677 if (video_frame->metadata()->GetTimeTicks(VideoFrameMetadata::REFERENCE_TIME,
(...skipping 24 matching lines...) Expand all
659 // Tries to find the resources in the pool or create them. 702 // Tries to find the resources in the pool or create them.
660 // Incompatible resources will be dropped. 703 // Incompatible resources will be dropped.
661 GpuMemoryBufferVideoFramePool::PoolImpl::FrameResources* 704 GpuMemoryBufferVideoFramePool::PoolImpl::FrameResources*
662 GpuMemoryBufferVideoFramePool::PoolImpl::GetOrCreateFrameResources( 705 GpuMemoryBufferVideoFramePool::PoolImpl::GetOrCreateFrameResources(
663 const gfx::Size& size, 706 const gfx::Size& size,
664 VideoPixelFormat format) { 707 VideoPixelFormat format) {
665 auto it = resources_pool_.begin(); 708 auto it = resources_pool_.begin();
666 while (it != resources_pool_.end()) { 709 while (it != resources_pool_.end()) {
667 FrameResources* frame_resources = *it; 710 FrameResources* frame_resources = *it;
668 if (!frame_resources->IsInUse()) { 711 if (!frame_resources->IsInUse()) {
669 if (AreFrameResourcesCompatible(frame_resources, size)) { 712 if (AreFrameResourcesCompatible(frame_resources, size, format)) {
670 frame_resources->SetIsInUse(true); 713 frame_resources->SetIsInUse(true);
671 return frame_resources; 714 return frame_resources;
672 } else { 715 } else {
673 resources_pool_.erase(it++); 716 resources_pool_.erase(it++);
674 DeleteFrameResources(gpu_factories_, frame_resources); 717 DeleteFrameResources(gpu_factories_, frame_resources);
675 delete frame_resources; 718 delete frame_resources;
676 } 719 }
677 } else { 720 } else {
678 it++; 721 it++;
679 } 722 }
680 } 723 }
681 724
682 // Create the resources. 725 // Create the resources.
683 std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock( 726 std::unique_ptr<GpuVideoAcceleratorFactories::ScopedGLContextLock> lock(
684 gpu_factories_->GetGLContextLock()); 727 gpu_factories_->GetGLContextLock());
685 if (!lock) 728 if (!lock)
686 return nullptr; 729 return nullptr;
687 730
688 gpu::gles2::GLES2Interface* gles2 = lock->ContextGL(); 731 gpu::gles2::GLES2Interface* gles2 = lock->ContextGL();
689 gles2->ActiveTexture(GL_TEXTURE0); 732 gles2->ActiveTexture(GL_TEXTURE0);
690 size_t num_planes = VideoFrame::NumPlanes(format); 733 size_t num_planes = VideoFrame::NumPlanes(format);
691 FrameResources* frame_resources = new FrameResources(size); 734 FrameResources* frame_resources = new FrameResources(size, format);
692 resources_pool_.push_back(frame_resources); 735 resources_pool_.push_back(frame_resources);
693 for (size_t i = 0; i < num_planes; i += PlanesPerCopy(format)) { 736 for (size_t i = 0; i < num_planes; i += PlanesPerCopy(format)) {
694 PlaneResource& plane_resource = frame_resources->plane_resources[i]; 737 PlaneResource& plane_resource = frame_resources->plane_resources[i];
695 const size_t width = VideoFrame::Columns(i, format, size.width()); 738 const size_t width = VideoFrame::Columns(i, format, size.width());
696 const size_t height = VideoFrame::Rows(i, format, size.height()); 739 const size_t height = VideoFrame::Rows(i, format, size.height());
697 plane_resource.size = gfx::Size(width, height); 740 plane_resource.size = gfx::Size(width, height);
698 741
699 const gfx::BufferFormat buffer_format = GpuMemoryBufferFormat(format, i); 742 const gfx::BufferFormat buffer_format = VideoFrame::BufferFormat(format);
700 plane_resource.gpu_memory_buffer = gpu_factories_->AllocateGpuMemoryBuffer( 743 plane_resource.gpu_memory_buffer = gpu_factories_->AllocateGpuMemoryBuffer(
701 plane_resource.size, buffer_format, 744 plane_resource.size, buffer_format,
702 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); 745 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE);
703 746
704 unsigned texture_target = gpu_factories_->ImageTextureTarget(buffer_format); 747 unsigned texture_target = gpu_factories_->ImageTextureTarget(buffer_format);
705 gles2->GenTextures(1, &plane_resource.texture_id); 748 gles2->GenTextures(1, &plane_resource.texture_id);
706 gles2->BindTexture(texture_target, plane_resource.texture_id); 749 gles2->BindTexture(texture_target, plane_resource.texture_id);
707 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 750 if (format == PIXEL_FORMAT_Y16) {
708 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 751 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
752 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
753 } else {
754 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
755 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
756 }
709 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 757 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
710 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 758 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
711 gles2->GenMailboxCHROMIUM(plane_resource.mailbox.name); 759 gles2->GenMailboxCHROMIUM(plane_resource.mailbox.name);
712 gles2->ProduceTextureCHROMIUM(texture_target, plane_resource.mailbox.name); 760 gles2->ProduceTextureCHROMIUM(texture_target, plane_resource.mailbox.name);
713 } 761 }
714 return frame_resources; 762 return frame_resources;
715 } 763 }
716 764
717 // static 765 // static
718 void GpuMemoryBufferVideoFramePool::PoolImpl::DeleteFrameResources( 766 void GpuMemoryBufferVideoFramePool::PoolImpl::DeleteFrameResources(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 } 818 }
771 819
772 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame( 820 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame(
773 const scoped_refptr<VideoFrame>& video_frame, 821 const scoped_refptr<VideoFrame>& video_frame,
774 const FrameReadyCB& frame_ready_cb) { 822 const FrameReadyCB& frame_ready_cb) {
775 DCHECK(video_frame); 823 DCHECK(video_frame);
776 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); 824 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb);
777 } 825 }
778 826
779 } // namespace media 827 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/skcanvas_video_renderer_unittest.cc ('k') | third_party/WebKit/Source/core/html/HTMLVideoElement.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698