| OLD | NEW |
| 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 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // output size is |kBytesPerCopyTarget| bytes and run in parallel. | 154 // output size is |kBytesPerCopyTarget| bytes and run in parallel. |
| 155 const size_t kBytesPerCopyTarget = 1024 * 1024; // 1MB | 155 const size_t kBytesPerCopyTarget = 1024 * 1024; // 1MB |
| 156 | 156 |
| 157 // Return the GpuMemoryBuffer format to use for a specific VideoPixelFormat | 157 // Return the GpuMemoryBuffer format to use for a specific VideoPixelFormat |
| 158 // and plane. | 158 // and plane. |
| 159 gfx::BufferFormat GpuMemoryBufferFormat(VideoPixelFormat format, size_t plane) { | 159 gfx::BufferFormat GpuMemoryBufferFormat(VideoPixelFormat format, size_t plane) { |
| 160 switch (format) { | 160 switch (format) { |
| 161 case PIXEL_FORMAT_I420: | 161 case PIXEL_FORMAT_I420: |
| 162 DCHECK_LE(plane, 2u); | 162 DCHECK_LE(plane, 2u); |
| 163 return gfx::BufferFormat::R_8; | 163 return gfx::BufferFormat::R_8; |
| 164 case PIXEL_FORMAT_NV12: |
| 165 DCHECK_LE(plane, 1u); |
| 166 return gfx::BufferFormat::YUV_420_BIPLANAR; |
| 164 case PIXEL_FORMAT_UYVY: | 167 case PIXEL_FORMAT_UYVY: |
| 165 DCHECK_EQ(0u, plane); | 168 DCHECK_EQ(0u, plane); |
| 166 return gfx::BufferFormat::UYVY_422; | 169 return gfx::BufferFormat::UYVY_422; |
| 167 default: | 170 default: |
| 168 NOTREACHED(); | 171 NOTREACHED(); |
| 169 return gfx::BufferFormat::BGRA_8888; | 172 return gfx::BufferFormat::BGRA_8888; |
| 170 } | 173 } |
| 171 } | 174 } |
| 172 | 175 |
| 173 unsigned ImageInternalFormat(VideoPixelFormat format, size_t plane) { | 176 unsigned ImageInternalFormat(VideoPixelFormat format, size_t plane) { |
| 174 switch (format) { | 177 switch (format) { |
| 175 case PIXEL_FORMAT_I420: | 178 case PIXEL_FORMAT_I420: |
| 176 DCHECK_LE(plane, 2u); | 179 DCHECK_LE(plane, 2u); |
| 177 return GL_R8_EXT; | 180 return GL_R8_EXT; |
| 181 case PIXEL_FORMAT_NV12: |
| 182 DCHECK_LE(plane, 1u); |
| 183 DLOG(WARNING) << "NV12 format not supported yet"; |
| 184 return 0; // TODO(andresantoso): Implement extension for NV12. |
| 178 case PIXEL_FORMAT_UYVY: | 185 case PIXEL_FORMAT_UYVY: |
| 179 DCHECK_EQ(0u, plane); | 186 DCHECK_EQ(0u, plane); |
| 180 return GL_RGB_YCBCR_422_CHROMIUM; | 187 return GL_RGB_YCBCR_422_CHROMIUM; |
| 181 default: | 188 default: |
| 182 NOTREACHED(); | 189 NOTREACHED(); |
| 183 return 0; | 190 return 0; |
| 184 } | 191 } |
| 185 } | 192 } |
| 186 | 193 |
| 194 // The number of output planes to be copied in each iteration. |
| 195 size_t PlanesPerCopy(VideoPixelFormat format) { |
| 196 switch (format) { |
| 197 case PIXEL_FORMAT_I420: |
| 198 case PIXEL_FORMAT_UYVY: |
| 199 return 1; |
| 200 case PIXEL_FORMAT_NV12: |
| 201 return 2; |
| 202 default: |
| 203 NOTREACHED(); |
| 204 return 0; |
| 205 } |
| 206 } |
| 207 |
| 208 // The number of output rows to be copied in each iteration. |
| 209 int RowsPerCopy(size_t plane, VideoPixelFormat format, int width) { |
| 210 int bytes_per_row = VideoFrame::RowBytes(plane, format, width); |
| 211 if (format == PIXEL_FORMAT_NV12) { |
| 212 DCHECK_EQ(0u, plane); |
| 213 bytes_per_row += VideoFrame::RowBytes(1, format, width); |
| 214 } |
| 215 // Copy an even number of lines, and at least one. |
| 216 return std::max<size_t>((kBytesPerCopyTarget / bytes_per_row) & ~1, 1); |
| 217 } |
| 218 |
| 187 void CopyRowsToI420Buffer(int first_row, | 219 void CopyRowsToI420Buffer(int first_row, |
| 188 int rows, | 220 int rows, |
| 189 int bytes_per_row, | 221 int bytes_per_row, |
| 190 const uint8* source, | 222 const uint8* source, |
| 191 int source_stride, | 223 int source_stride, |
| 192 uint8* output, | 224 uint8* output, |
| 193 int dest_stride, | 225 int dest_stride, |
| 194 const base::Closure& done) { | 226 const base::Closure& done) { |
| 195 TRACE_EVENT2("media", "CopyRowsToI420Buffer", "bytes_per_row", bytes_per_row, | 227 TRACE_EVENT2("media", "CopyRowsToI420Buffer", "bytes_per_row", bytes_per_row, |
| 196 "rows", rows); | 228 "rows", rows); |
| 197 DCHECK_NE(dest_stride, 0); | 229 DCHECK_NE(dest_stride, 0); |
| 198 DCHECK_LE(bytes_per_row, std::abs(dest_stride)); | 230 DCHECK_LE(bytes_per_row, std::abs(dest_stride)); |
| 199 DCHECK_LE(bytes_per_row, source_stride); | 231 DCHECK_LE(bytes_per_row, source_stride); |
| 200 for (int row = first_row; row < first_row + rows; ++row) { | 232 for (int row = first_row; row < first_row + rows; ++row) { |
| 201 memcpy(output + dest_stride * row, source + source_stride * row, | 233 memcpy(output + dest_stride * row, source + source_stride * row, |
| 202 bytes_per_row); | 234 bytes_per_row); |
| 203 } | 235 } |
| 204 done.Run(); | 236 done.Run(); |
| 205 } | 237 } |
| 206 | 238 |
| 239 void CopyRowsToNV12Buffer(int first_row, |
| 240 int rows, |
| 241 int bytes_per_row, |
| 242 const scoped_refptr<VideoFrame>& source_frame, |
| 243 uint8* dest_y, |
| 244 int dest_stride_y, |
| 245 uint8* dest_uv, |
| 246 int dest_stride_uv, |
| 247 const base::Closure& done) { |
| 248 TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "bytes_per_row", bytes_per_row, |
| 249 "rows", rows); |
| 250 DCHECK_NE(dest_stride_y, 0); |
| 251 DCHECK_NE(dest_stride_uv, 0); |
| 252 DCHECK_LE(bytes_per_row, std::abs(dest_stride_y)); |
| 253 DCHECK_LE(bytes_per_row, std::abs(dest_stride_uv)); |
| 254 DCHECK_EQ(0, first_row % 2); |
| 255 libyuv::I420ToNV12( |
| 256 source_frame->data(VideoFrame::kYPlane) + |
| 257 first_row * source_frame->stride(VideoFrame::kYPlane), |
| 258 source_frame->stride(VideoFrame::kYPlane), |
| 259 source_frame->data(VideoFrame::kUPlane) + |
| 260 first_row / 2 * source_frame->stride(VideoFrame::kUPlane), |
| 261 source_frame->stride(VideoFrame::kUPlane), |
| 262 source_frame->data(VideoFrame::kVPlane) + |
| 263 first_row / 2 * source_frame->stride(VideoFrame::kVPlane), |
| 264 source_frame->stride(VideoFrame::kVPlane), |
| 265 dest_y + first_row * dest_stride_y, dest_stride_y, |
| 266 dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, |
| 267 bytes_per_row, rows); |
| 268 done.Run(); |
| 269 } |
| 270 |
| 207 void CopyRowsToUYVYBuffer(int first_row, | 271 void CopyRowsToUYVYBuffer(int first_row, |
| 208 int rows, | 272 int rows, |
| 209 int width, | 273 int width, |
| 210 const scoped_refptr<VideoFrame>& source_frame, | 274 const scoped_refptr<VideoFrame>& source_frame, |
| 211 uint8* output, | 275 uint8* output, |
| 212 int dest_stride, | 276 int dest_stride, |
| 213 const base::Closure& done) { | 277 const base::Closure& done) { |
| 214 TRACE_EVENT2("media", "CopyRowsToUYVYBuffer", "bytes_per_row", width * 2, | 278 TRACE_EVENT2("media", "CopyRowsToUYVYBuffer", "bytes_per_row", width * 2, |
| 215 "rows", rows); | 279 "rows", rows); |
| 216 DCHECK_NE(dest_stride, 0); | 280 DCHECK_NE(dest_stride, 0); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 | 355 |
| 292 worker_task_runner_->PostTask( | 356 worker_task_runner_->PostTask( |
| 293 FROM_HERE, base::Bind(&PoolImpl::CopyVideoFrameToGpuMemoryBuffers, this, | 357 FROM_HERE, base::Bind(&PoolImpl::CopyVideoFrameToGpuMemoryBuffers, this, |
| 294 video_frame, frame_resources, frame_ready_cb)); | 358 video_frame, frame_resources, frame_ready_cb)); |
| 295 } | 359 } |
| 296 | 360 |
| 297 void GpuMemoryBufferVideoFramePool::PoolImpl::OnCopiesDone( | 361 void GpuMemoryBufferVideoFramePool::PoolImpl::OnCopiesDone( |
| 298 const scoped_refptr<VideoFrame>& video_frame, | 362 const scoped_refptr<VideoFrame>& video_frame, |
| 299 FrameResources* frame_resources, | 363 FrameResources* frame_resources, |
| 300 const FrameReadyCB& frame_ready_cb) { | 364 const FrameReadyCB& frame_ready_cb) { |
| 301 const size_t planes = VideoFrame::NumPlanes(output_format_); | 365 for (const auto& plane_resource : frame_resources->plane_resources) { |
| 302 for (size_t i = 0; i < planes; ++i) { | 366 if (plane_resource.gpu_memory_buffer) |
| 303 frame_resources->plane_resources[i].gpu_memory_buffer->Unmap(); | 367 plane_resource.gpu_memory_buffer->Unmap(); |
| 304 } | 368 } |
| 305 | 369 |
| 306 media_task_runner_->PostTask( | 370 media_task_runner_->PostTask( |
| 307 FROM_HERE, | 371 FROM_HERE, |
| 308 base::Bind(&PoolImpl::BindAndCreateMailboxesHardwareFrameResources, this, | 372 base::Bind(&PoolImpl::BindAndCreateMailboxesHardwareFrameResources, this, |
| 309 video_frame, frame_resources, frame_ready_cb)); | 373 video_frame, frame_resources, frame_ready_cb)); |
| 310 } | 374 } |
| 311 | 375 |
| 312 // Copies |video_frame| into |frame_resources| asynchronously, posting n tasks | 376 // Copies |video_frame| into |frame_resources| asynchronously, posting n tasks |
| 313 // that will be synchronized by a barrier. | 377 // that will be synchronized by a barrier. |
| 314 // After the barrier is passed OnCopiesDone will be called. | 378 // After the barrier is passed OnCopiesDone will be called. |
| 315 void GpuMemoryBufferVideoFramePool::PoolImpl::CopyVideoFrameToGpuMemoryBuffers( | 379 void GpuMemoryBufferVideoFramePool::PoolImpl::CopyVideoFrameToGpuMemoryBuffers( |
| 316 const scoped_refptr<VideoFrame>& video_frame, | 380 const scoped_refptr<VideoFrame>& video_frame, |
| 317 FrameResources* frame_resources, | 381 FrameResources* frame_resources, |
| 318 const FrameReadyCB& frame_ready_cb) { | 382 const FrameReadyCB& frame_ready_cb) { |
| 319 // Compute the number of tasks to post and create the barrier. | 383 // Compute the number of tasks to post and create the barrier. |
| 320 const size_t dest_planes = VideoFrame::NumPlanes(output_format_); | 384 const size_t num_planes = VideoFrame::NumPlanes(output_format_); |
| 385 const size_t planes_per_copy = PlanesPerCopy(output_format_); |
| 321 gfx::Size size = video_frame->visible_rect().size(); | 386 gfx::Size size = video_frame->visible_rect().size(); |
| 322 size_t copies = 0; | 387 size_t copies = 0; |
| 323 for (size_t i = 0; i < dest_planes; ++i) { | 388 for (size_t i = 0; i < num_planes; i += planes_per_copy) { |
| 324 int rows = VideoFrame::Rows(i, output_format_, size.height()); | 389 const int rows = VideoFrame::Rows(i, output_format_, size.height()); |
| 325 int bytes_per_row = VideoFrame::RowBytes(i, output_format_, size.width()); | 390 const int rows_per_copy = RowsPerCopy(i, output_format_, size.width()); |
| 326 // Copy a even number of lines, and at least one. | |
| 327 int rows_per_copy = | |
| 328 std::max<size_t>((kBytesPerCopyTarget / bytes_per_row) & ~1, 1); | |
| 329 copies += rows / rows_per_copy; | 391 copies += rows / rows_per_copy; |
| 330 if (rows % rows_per_copy) | 392 if (rows % rows_per_copy) |
| 331 ++copies; | 393 ++copies; |
| 332 } | 394 } |
| 333 base::Closure copies_done = | 395 base::Closure copies_done = |
| 334 base::Bind(&PoolImpl::OnCopiesDone, this, video_frame, frame_resources, | 396 base::Bind(&PoolImpl::OnCopiesDone, this, video_frame, frame_resources, |
| 335 frame_ready_cb); | 397 frame_ready_cb); |
| 336 base::Closure barrier = base::BarrierClosure(copies, copies_done); | 398 base::Closure barrier = base::BarrierClosure(copies, copies_done); |
| 399 |
| 337 // Post all the async tasks. | 400 // Post all the async tasks. |
| 338 for (size_t i = 0; i < dest_planes; ++i) { | 401 for (size_t i = 0; i < num_planes; i += planes_per_copy) { |
| 339 int rows = VideoFrame::Rows(i, output_format_, size.height()); | 402 gfx::GpuMemoryBuffer* buffer = |
| 340 int bytes_per_row = VideoFrame::RowBytes(i, output_format_, size.width()); | 403 frame_resources->plane_resources[i].gpu_memory_buffer.get(); |
| 341 int rows_per_copy = | 404 DCHECK(buffer); |
| 342 std::max<size_t>((kBytesPerCopyTarget / bytes_per_row) & ~1, 1); | 405 DCHECK_EQ(planes_per_copy, |
| 406 gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat())); |
| 407 uint8* dest_buffers[VideoFrame::kMaxPlanes]; |
| 408 int dest_strides[VideoFrame::kMaxPlanes]; |
| 409 bool rv = buffer->Map(reinterpret_cast<void**>(dest_buffers)); |
| 410 DCHECK(rv); |
| 411 buffer->GetStride(dest_strides); |
| 343 | 412 |
| 344 void* data = nullptr; | 413 const int rows = VideoFrame::Rows(i, output_format_, size.height()); |
| 345 DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat( | 414 const int rows_per_copy = RowsPerCopy(i, output_format_, size.width()); |
| 346 GpuMemoryBufferFormat(output_format_, i))); | |
| 347 bool rv = frame_resources->plane_resources[i].gpu_memory_buffer->Map(&data); | |
| 348 DCHECK(rv); | |
| 349 uint8* mapped_buffer = static_cast<uint8*>(data); | |
| 350 | |
| 351 int dest_stride = 0; | |
| 352 frame_resources->plane_resources[i].gpu_memory_buffer->GetStride( | |
| 353 &dest_stride); | |
| 354 | 415 |
| 355 for (int row = 0; row < rows; row += rows_per_copy) { | 416 for (int row = 0; row < rows; row += rows_per_copy) { |
| 417 const int rows_to_copy = std::min(rows_per_copy, rows - row); |
| 356 switch (output_format_) { | 418 switch (output_format_) { |
| 357 case PIXEL_FORMAT_I420: | 419 case PIXEL_FORMAT_I420: { |
| 420 const int bytes_per_row = |
| 421 VideoFrame::RowBytes(i, output_format_, size.width()); |
| 358 worker_task_runner_->PostTask( | 422 worker_task_runner_->PostTask( |
| 359 FROM_HERE, | 423 FROM_HERE, |
| 360 base::Bind(&CopyRowsToI420Buffer, row, | 424 base::Bind(&CopyRowsToI420Buffer, row, rows_to_copy, |
| 361 std::min(rows_per_copy, rows - row), bytes_per_row, | 425 bytes_per_row, video_frame->data(i), |
| 362 video_frame->data(i), video_frame->stride(i), | 426 video_frame->stride(i), dest_buffers[0], |
| 363 mapped_buffer, dest_stride, barrier)); | 427 dest_strides[0], barrier)); |
| 428 break; |
| 429 } |
| 430 case PIXEL_FORMAT_NV12: |
| 431 worker_task_runner_->PostTask( |
| 432 FROM_HERE, |
| 433 base::Bind(&CopyRowsToNV12Buffer, row, rows_to_copy, |
| 434 size.width(), video_frame, dest_buffers[0], |
| 435 dest_strides[0], dest_buffers[1], dest_strides[1], |
| 436 barrier)); |
| 364 break; | 437 break; |
| 365 case PIXEL_FORMAT_UYVY: | 438 case PIXEL_FORMAT_UYVY: |
| 366 worker_task_runner_->PostTask( | 439 worker_task_runner_->PostTask( |
| 367 FROM_HERE, | 440 FROM_HERE, |
| 368 base::Bind(&CopyRowsToUYVYBuffer, row, | 441 base::Bind(&CopyRowsToUYVYBuffer, row, rows_to_copy, size.width(), |
| 369 std::min(rows_per_copy, rows - row), size.width(), | 442 video_frame, dest_buffers[0], dest_strides[0], |
| 370 video_frame, mapped_buffer, dest_stride, barrier)); | 443 barrier)); |
| 371 break; | 444 break; |
| 372 default: | 445 default: |
| 373 NOTREACHED(); | 446 NOTREACHED(); |
| 374 } | 447 } |
| 375 } | 448 } |
| 376 } | 449 } |
| 377 } | 450 } |
| 378 | 451 |
| 379 void GpuMemoryBufferVideoFramePool::PoolImpl:: | 452 void GpuMemoryBufferVideoFramePool::PoolImpl:: |
| 380 BindAndCreateMailboxesHardwareFrameResources( | 453 BindAndCreateMailboxesHardwareFrameResources( |
| 381 const scoped_refptr<VideoFrame>& video_frame, | 454 const scoped_refptr<VideoFrame>& video_frame, |
| 382 FrameResources* frame_resources, | 455 FrameResources* frame_resources, |
| 383 const FrameReadyCB& frame_ready_cb) { | 456 const FrameReadyCB& frame_ready_cb) { |
| 384 gpu::gles2::GLES2Interface* gles2 = gpu_factories_->GetGLES2Interface(); | 457 gpu::gles2::GLES2Interface* gles2 = gpu_factories_->GetGLES2Interface(); |
| 385 if (!gles2) { | 458 if (!gles2) { |
| 386 frame_ready_cb.Run(video_frame); | 459 frame_ready_cb.Run(video_frame); |
| 387 return; | 460 return; |
| 388 } | 461 } |
| 389 | 462 |
| 390 const size_t planes = VideoFrame::NumPlanes(output_format_); | 463 const size_t num_planes = VideoFrame::NumPlanes(output_format_); |
| 464 const size_t planes_per_copy = PlanesPerCopy(output_format_); |
| 391 const gfx::Size size = video_frame->visible_rect().size(); | 465 const gfx::Size size = video_frame->visible_rect().size(); |
| 392 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; | 466 gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes]; |
| 393 // Set up the planes creating the mailboxes needed to refer to the textures. | 467 // Set up the planes creating the mailboxes needed to refer to the textures. |
| 394 for (size_t i = 0; i < planes; ++i) { | 468 for (size_t i = 0; i < num_planes; i += planes_per_copy) { |
| 395 PlaneResource& plane_resource = frame_resources->plane_resources[i]; | 469 PlaneResource& plane_resource = frame_resources->plane_resources[i]; |
| 470 DCHECK(plane_resource.gpu_memory_buffer); |
| 396 // Bind the texture and create or rebind the image. | 471 // Bind the texture and create or rebind the image. |
| 397 gles2->BindTexture(texture_target_, plane_resource.texture_id); | 472 gles2->BindTexture(texture_target_, plane_resource.texture_id); |
| 398 | 473 |
| 399 if (plane_resource.gpu_memory_buffer && !plane_resource.image_id) { | 474 if (!plane_resource.image_id) { |
| 400 const size_t width = VideoFrame::Columns(i, output_format_, size.width()); | 475 const size_t width = VideoFrame::Columns(i, output_format_, size.width()); |
| 401 const size_t height = VideoFrame::Rows(i, output_format_, size.height()); | 476 const size_t height = VideoFrame::Rows(i, output_format_, size.height()); |
| 402 plane_resource.image_id = gles2->CreateImageCHROMIUM( | 477 plane_resource.image_id = gles2->CreateImageCHROMIUM( |
| 403 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height, | 478 plane_resource.gpu_memory_buffer->AsClientBuffer(), width, height, |
| 404 ImageInternalFormat(output_format_, i)); | 479 ImageInternalFormat(output_format_, i)); |
| 405 } else { | 480 } else { |
| 406 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, | 481 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, |
| 407 plane_resource.image_id); | 482 plane_resource.image_id); |
| 408 } | 483 } |
| 409 gles2->BindTexImage2DCHROMIUM(texture_target_, plane_resource.image_id); | 484 gles2->BindTexImage2DCHROMIUM(texture_target_, plane_resource.image_id); |
| 410 mailbox_holders[i] = | 485 mailbox_holders[i] = |
| 411 gpu::MailboxHolder(plane_resource.mailbox, texture_target_, 0); | 486 gpu::MailboxHolder(plane_resource.mailbox, texture_target_, 0); |
| 412 } | 487 } |
| 413 | 488 |
| 414 // Insert a sync_point, this is needed to make sure that the textures the | 489 // Insert a sync_point, this is needed to make sure that the textures the |
| 415 // mailboxes refer to will be used only after all the previous commands posted | 490 // mailboxes refer to will be used only after all the previous commands posted |
| 416 // in the command buffer have been processed. | 491 // in the command buffer have been processed. |
| 417 unsigned sync_point = gles2->InsertSyncPointCHROMIUM(); | 492 unsigned sync_point = gles2->InsertSyncPointCHROMIUM(); |
| 418 for (size_t i = 0; i < planes; ++i) { | 493 for (size_t i = 0; i < num_planes; i += planes_per_copy) |
| 419 mailbox_holders[i].sync_point = sync_point; | 494 mailbox_holders[i].sync_point = sync_point; |
| 420 } | |
| 421 | 495 |
| 422 scoped_refptr<VideoFrame> frame; | 496 scoped_refptr<VideoFrame> frame; |
| 423 // Create the VideoFrame backed by native textures. | 497 // Create the VideoFrame backed by native textures. |
| 424 switch (output_format_) { | 498 switch (output_format_) { |
| 425 case PIXEL_FORMAT_I420: | 499 case PIXEL_FORMAT_I420: |
| 426 frame = VideoFrame::WrapYUV420NativeTextures( | 500 frame = VideoFrame::WrapYUV420NativeTextures( |
| 427 mailbox_holders[VideoFrame::kYPlane], | 501 mailbox_holders[VideoFrame::kYPlane], |
| 428 mailbox_holders[VideoFrame::kUPlane], | 502 mailbox_holders[VideoFrame::kUPlane], |
| 429 mailbox_holders[VideoFrame::kVPlane], | 503 mailbox_holders[VideoFrame::kVPlane], |
| 430 base::Bind(&PoolImpl::MailboxHoldersReleased, this, frame_resources), | 504 base::Bind(&PoolImpl::MailboxHoldersReleased, this, frame_resources), |
| 431 size, video_frame->visible_rect(), video_frame->natural_size(), | 505 size, video_frame->visible_rect(), video_frame->natural_size(), |
| 432 video_frame->timestamp()); | 506 video_frame->timestamp()); |
| 433 if (video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY)) | 507 if (video_frame->metadata()->IsTrue(VideoFrameMetadata::ALLOW_OVERLAY)) |
| 434 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); | 508 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); |
| 435 break; | 509 break; |
| 510 case PIXEL_FORMAT_NV12: |
| 436 case PIXEL_FORMAT_UYVY: | 511 case PIXEL_FORMAT_UYVY: |
| 437 frame = VideoFrame::WrapNativeTexture( | 512 frame = VideoFrame::WrapNativeTexture( |
| 438 PIXEL_FORMAT_UYVY, mailbox_holders[VideoFrame::kYPlane], | 513 output_format_, mailbox_holders[VideoFrame::kYPlane], |
| 439 base::Bind(&PoolImpl::MailboxHoldersReleased, this, frame_resources), | 514 base::Bind(&PoolImpl::MailboxHoldersReleased, this, frame_resources), |
| 440 size, video_frame->visible_rect(), video_frame->natural_size(), | 515 size, video_frame->visible_rect(), video_frame->natural_size(), |
| 441 video_frame->timestamp()); | 516 video_frame->timestamp()); |
| 442 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); | 517 frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); |
| 443 break; | 518 break; |
| 444 default: | 519 default: |
| 445 NOTREACHED(); | 520 NOTREACHED(); |
| 446 } | 521 } |
| 447 frame_ready_cb.Run(frame); | 522 frame_ready_cb.Run(frame); |
| 448 } | 523 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 } else { | 556 } else { |
| 482 it++; | 557 it++; |
| 483 } | 558 } |
| 484 } | 559 } |
| 485 | 560 |
| 486 // Create the resources. | 561 // Create the resources. |
| 487 gpu::gles2::GLES2Interface* gles2 = gpu_factories_->GetGLES2Interface(); | 562 gpu::gles2::GLES2Interface* gles2 = gpu_factories_->GetGLES2Interface(); |
| 488 if (!gles2) | 563 if (!gles2) |
| 489 return nullptr; | 564 return nullptr; |
| 490 gles2->ActiveTexture(GL_TEXTURE0); | 565 gles2->ActiveTexture(GL_TEXTURE0); |
| 491 size_t planes = VideoFrame::NumPlanes(format); | 566 size_t num_planes = VideoFrame::NumPlanes(format); |
| 492 FrameResources* frame_resources = new FrameResources(size); | 567 FrameResources* frame_resources = new FrameResources(size); |
| 493 resources_pool_.push_back(frame_resources); | 568 resources_pool_.push_back(frame_resources); |
| 494 for (size_t i = 0; i < planes; ++i) { | 569 for (size_t i = 0; i < num_planes; i += PlanesPerCopy(format)) { |
| 495 PlaneResource& plane_resource = frame_resources->plane_resources[i]; | 570 PlaneResource& plane_resource = frame_resources->plane_resources[i]; |
| 496 const size_t width = VideoFrame::Columns(i, format, size.width()); | 571 const size_t width = VideoFrame::Columns(i, format, size.width()); |
| 497 const size_t height = VideoFrame::Rows(i, format, size.height()); | 572 const size_t height = VideoFrame::Rows(i, format, size.height()); |
| 498 const gfx::Size plane_size(width, height); | 573 const gfx::Size plane_size(width, height); |
| 499 | 574 |
| 575 const gfx::BufferFormat buffer_format = GpuMemoryBufferFormat(format, i); |
| 500 plane_resource.gpu_memory_buffer = gpu_factories_->AllocateGpuMemoryBuffer( | 576 plane_resource.gpu_memory_buffer = gpu_factories_->AllocateGpuMemoryBuffer( |
| 501 plane_size, GpuMemoryBufferFormat(format, i), gfx::BufferUsage::MAP); | 577 plane_size, buffer_format, gfx::BufferUsage::MAP); |
| 502 | 578 |
| 503 gles2->GenTextures(1, &plane_resource.texture_id); | 579 gles2->GenTextures(1, &plane_resource.texture_id); |
| 504 gles2->BindTexture(texture_target_, plane_resource.texture_id); | 580 gles2->BindTexture(texture_target_, plane_resource.texture_id); |
| 505 gles2->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 581 gles2->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 506 gles2->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 582 gles2->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 507 gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 583 gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 508 gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 584 gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 509 gles2->GenMailboxCHROMIUM(plane_resource.mailbox.name); | 585 gles2->GenMailboxCHROMIUM(plane_resource.mailbox.name); |
| 510 gles2->ProduceTextureCHROMIUM(texture_target_, plane_resource.mailbox.name); | 586 gles2->ProduceTextureCHROMIUM(texture_target_, plane_resource.mailbox.name); |
| 511 } | 587 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 } | 644 } |
| 569 | 645 |
| 570 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame( | 646 void GpuMemoryBufferVideoFramePool::MaybeCreateHardwareFrame( |
| 571 const scoped_refptr<VideoFrame>& video_frame, | 647 const scoped_refptr<VideoFrame>& video_frame, |
| 572 const FrameReadyCB& frame_ready_cb) { | 648 const FrameReadyCB& frame_ready_cb) { |
| 573 DCHECK(video_frame); | 649 DCHECK(video_frame); |
| 574 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); | 650 pool_impl_->CreateHardwareFrame(video_frame, frame_ready_cb); |
| 575 } | 651 } |
| 576 | 652 |
| 577 } // namespace media | 653 } // namespace media |
| OLD | NEW |