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