OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "cc/resources/video_resource_updater.h" | 5 #include "cc/resources/video_resource_updater.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 switch (video_frame->mailbox_holder(0).texture_target) { | 60 switch (video_frame->mailbox_holder(0).texture_target) { |
61 case GL_TEXTURE_EXTERNAL_OES: | 61 case GL_TEXTURE_EXTERNAL_OES: |
62 return VideoFrameExternalResources::YUV_RESOURCE; | 62 return VideoFrameExternalResources::YUV_RESOURCE; |
63 case GL_TEXTURE_RECTANGLE_ARB: | 63 case GL_TEXTURE_RECTANGLE_ARB: |
64 return VideoFrameExternalResources::RGB_RESOURCE; | 64 return VideoFrameExternalResources::RGB_RESOURCE; |
65 default: | 65 default: |
66 NOTREACHED(); | 66 NOTREACHED(); |
67 break; | 67 break; |
68 } | 68 } |
69 break; | 69 break; |
| 70 case media::PIXEL_FORMAT_Y16: |
| 71 return VideoFrameExternalResources::Y16_RESOURCE; |
| 72 break; |
70 case media::PIXEL_FORMAT_YV12: | 73 case media::PIXEL_FORMAT_YV12: |
71 case media::PIXEL_FORMAT_YV16: | 74 case media::PIXEL_FORMAT_YV16: |
72 case media::PIXEL_FORMAT_YV24: | 75 case media::PIXEL_FORMAT_YV24: |
73 case media::PIXEL_FORMAT_YV12A: | 76 case media::PIXEL_FORMAT_YV12A: |
74 case media::PIXEL_FORMAT_NV21: | 77 case media::PIXEL_FORMAT_NV21: |
75 case media::PIXEL_FORMAT_YUY2: | 78 case media::PIXEL_FORMAT_YUY2: |
76 case media::PIXEL_FORMAT_RGB24: | 79 case media::PIXEL_FORMAT_RGB24: |
77 case media::PIXEL_FORMAT_RGB32: | 80 case media::PIXEL_FORMAT_RGB32: |
78 case media::PIXEL_FORMAT_MJPEG: | 81 case media::PIXEL_FORMAT_MJPEG: |
79 case media::PIXEL_FORMAT_MT21: | 82 case media::PIXEL_FORMAT_MT21: |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 case media::PIXEL_FORMAT_YUV420P9: | 277 case media::PIXEL_FORMAT_YUV420P9: |
275 case media::PIXEL_FORMAT_YUV422P9: | 278 case media::PIXEL_FORMAT_YUV422P9: |
276 case media::PIXEL_FORMAT_YUV444P9: | 279 case media::PIXEL_FORMAT_YUV444P9: |
277 bits_per_channel = 9; | 280 bits_per_channel = 9; |
278 break; | 281 break; |
279 case media::PIXEL_FORMAT_YUV420P10: | 282 case media::PIXEL_FORMAT_YUV420P10: |
280 case media::PIXEL_FORMAT_YUV422P10: | 283 case media::PIXEL_FORMAT_YUV422P10: |
281 case media::PIXEL_FORMAT_YUV444P10: | 284 case media::PIXEL_FORMAT_YUV444P10: |
282 bits_per_channel = 10; | 285 bits_per_channel = 10; |
283 break; | 286 break; |
| 287 case media::PIXEL_FORMAT_Y16: |
| 288 bits_per_channel = 16; |
| 289 break; |
284 } | 290 } |
285 | 291 |
286 // Only YUV software video frames are supported. | 292 // Only YUV and Y16 software video frames are supported. |
287 if (!media::IsYuvPlanar(input_frame_format)) { | 293 const bool isYuvPlanar = media::IsYuvPlanar(input_frame_format); |
| 294 if (!(isYuvPlanar || input_frame_format == media::PIXEL_FORMAT_Y16)) { |
288 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); | 295 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); |
289 return VideoFrameExternalResources(); | 296 return VideoFrameExternalResources(); |
290 } | 297 } |
291 | 298 |
292 const bool software_compositor = context_provider_ == NULL; | 299 const bool software_compositor = context_provider_ == NULL; |
293 | 300 |
294 ResourceFormat output_resource_format = | 301 if (input_frame_format == media::PIXEL_FORMAT_Y16 && software_compositor) { |
295 resource_provider_->YuvResourceFormat(bits_per_channel); | 302 // TODO(astojilj) Y16 software compositor support. |
| 303 NOTREACHED() << "Software compositor is not supporting PIXEL_FORMAT_Y16"; |
| 304 return VideoFrameExternalResources(); |
| 305 } |
| 306 |
| 307 ResourceFormat output_resource_format = isYuvPlanar |
| 308 ? resource_provider_->YuvResourceFormat(bits_per_channel) |
| 309 : resource_provider_->Y16ResourceFormat(bits_per_channel); |
296 | 310 |
297 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); | 311 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); |
298 | 312 |
299 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 313 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB |
300 // conversion here. That involves an extra copy of each frame to a bitmap. | 314 // conversion here. That involves an extra copy of each frame to a bitmap. |
301 // Obviously, this is suboptimal and should be addressed once ubercompositor | 315 // Obviously, this is suboptimal and should be addressed once ubercompositor |
302 // starts shaping up. | 316 // starts shaping up. |
303 if (software_compositor) { | 317 if (software_compositor) { |
304 output_resource_format = kRGBResourceFormat; | 318 output_resource_format = kRGBResourceFormat; |
305 output_plane_count = 1; | 319 output_plane_count = 1; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 | 442 |
429 bool needs_conversion = false; | 443 bool needs_conversion = false; |
430 int shift = 0; | 444 int shift = 0; |
431 | 445 |
432 // LUMINANCE_F16 uses half-floats, so we always need a conversion step. | 446 // LUMINANCE_F16 uses half-floats, so we always need a conversion step. |
433 if (plane_resource.resource_format() == LUMINANCE_F16) { | 447 if (plane_resource.resource_format() == LUMINANCE_F16) { |
434 needs_conversion = true; | 448 needs_conversion = true; |
435 // Note that the current method of converting integers to half-floats | 449 // Note that the current method of converting integers to half-floats |
436 // stops working if you have more than 10 bits of data. | 450 // stops working if you have more than 10 bits of data. |
437 DCHECK_LE(bits_per_channel, 10); | 451 DCHECK_LE(bits_per_channel, 10); |
| 452 } else if (plane_resource.resource_format() == RG_88) { |
| 453 DCHECK_EQ(bits_per_channel, 16); |
438 } else if (bits_per_channel > 8) { | 454 } else if (bits_per_channel > 8) { |
439 // If bits_per_channel > 8 and we can't use LUMINANCE_F16, we need to | 455 // If bits_per_channel > 8 and we can't use LUMINANCE_F16, we need to |
440 // shift the data down and create an 8-bit texture. | 456 // shift the data down and create an 8-bit texture. |
441 needs_conversion = true; | 457 needs_conversion = true; |
442 shift = bits_per_channel - 8; | 458 shift = bits_per_channel - 8; |
443 } | 459 } |
444 const uint8_t* pixels; | 460 const uint8_t* pixels; |
445 if (static_cast<int>(upload_image_stride) == video_stride_bytes && | 461 if (static_cast<int>(upload_image_stride) == video_stride_bytes && |
446 !needs_conversion) { | 462 !needs_conversion) { |
447 pixels = video_frame->data(i); | 463 pixels = video_frame->data(i); |
448 } else { | 464 } else { |
| 465 if (!isYuvPlanar) { |
| 466 for (ResourceList::iterator resource_it : plane_resources) |
| 467 resource_it->remove_ref(); |
| 468 NOTREACHED() << "Conversion not supported for :" |
| 469 << media::VideoPixelFormatToString(input_frame_format); |
| 470 return VideoFrameExternalResources(); |
| 471 } |
449 // Avoid malloc for each frame/plane if possible. | 472 // Avoid malloc for each frame/plane if possible. |
450 size_t needed_size = | 473 size_t needed_size = |
451 upload_image_stride * resource_size_pixels.height(); | 474 upload_image_stride * resource_size_pixels.height(); |
452 if (upload_pixels_.size() < needed_size) | 475 if (upload_pixels_.size() < needed_size) |
453 upload_pixels_.resize(needed_size); | 476 upload_pixels_.resize(needed_size); |
454 | 477 |
455 for (int row = 0; row < resource_size_pixels.height(); ++row) { | 478 for (int row = 0; row < resource_size_pixels.height(); ++row) { |
456 if (plane_resource.resource_format() == LUMINANCE_F16) { | 479 if (plane_resource.resource_format() == LUMINANCE_F16) { |
457 uint16_t* dst = reinterpret_cast<uint16_t*>( | 480 uint16_t* dst = reinterpret_cast<uint16_t*>( |
458 &upload_pixels_[upload_image_stride * row]); | 481 &upload_pixels_[upload_image_stride * row]); |
(...skipping 25 matching lines...) Expand all Loading... |
484 } | 507 } |
485 pixels = &upload_pixels_[0]; | 508 pixels = &upload_pixels_[0]; |
486 } | 509 } |
487 | 510 |
488 resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, | 511 resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, |
489 resource_size_pixels); | 512 resource_size_pixels); |
490 plane_resource.SetUniqueId(video_frame->unique_id(), i); | 513 plane_resource.SetUniqueId(video_frame->unique_id(), i); |
491 } | 514 } |
492 | 515 |
493 if (plane_resource.resource_format() == LUMINANCE_F16) { | 516 if (plane_resource.resource_format() == LUMINANCE_F16) { |
| 517 DCHECK(isYuvPlanar); |
494 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the | 518 // By OR-ing with 0x3800, 10-bit numbers become half-floats in the |
495 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). | 519 // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). |
496 // | 520 // |
497 // Half-floats are evaluated as: | 521 // Half-floats are evaluated as: |
498 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); | 522 // float value = pow(2.0, exponent - 25) * (0x400 + fraction); |
499 // | 523 // |
500 // In our case the exponent is 14 (since we or with 0x3800) and | 524 // In our case the exponent is 14 (since we or with 0x3800) and |
501 // pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and | 525 // pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and |
502 // pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and | 526 // pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and |
503 // [0..0.24951171875] for 9-bit. | 527 // [0..0.24951171875] for 9-bit. |
(...skipping 10 matching lines...) Expand all Loading... |
514 } | 538 } |
515 | 539 |
516 external_resources.mailboxes.push_back( | 540 external_resources.mailboxes.push_back( |
517 TextureMailbox(plane_resource.mailbox(), gpu::SyncToken(), | 541 TextureMailbox(plane_resource.mailbox(), gpu::SyncToken(), |
518 resource_provider_->GetResourceTextureTarget( | 542 resource_provider_->GetResourceTextureTarget( |
519 plane_resource.resource_id()))); | 543 plane_resource.resource_id()))); |
520 external_resources.release_callbacks.push_back(base::Bind( | 544 external_resources.release_callbacks.push_back(base::Bind( |
521 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); | 545 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); |
522 } | 546 } |
523 | 547 |
524 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; | 548 external_resources.type = (input_frame_format == media::PIXEL_FORMAT_Y16) |
| 549 ? VideoFrameExternalResources::Y16_RESOURCE |
| 550 : VideoFrameExternalResources::YUV_RESOURCE; |
525 return external_resources; | 551 return external_resources; |
526 } | 552 } |
527 | 553 |
528 // static | 554 // static |
529 void VideoResourceUpdater::ReturnTexture( | 555 void VideoResourceUpdater::ReturnTexture( |
530 base::WeakPtr<VideoResourceUpdater> updater, | 556 base::WeakPtr<VideoResourceUpdater> updater, |
531 const scoped_refptr<media::VideoFrame>& video_frame, | 557 const scoped_refptr<media::VideoFrame>& video_frame, |
532 const gpu::SyncToken& sync_token, | 558 const gpu::SyncToken& sync_token, |
533 bool lost_resource, | 559 bool lost_resource, |
534 BlockingTaskRunner* main_thread_task_runner) { | 560 BlockingTaskRunner* main_thread_task_runner) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 if (lost_resource) { | 717 if (lost_resource) { |
692 resource_it->clear_refs(); | 718 resource_it->clear_refs(); |
693 updater->DeleteResource(resource_it); | 719 updater->DeleteResource(resource_it); |
694 return; | 720 return; |
695 } | 721 } |
696 | 722 |
697 resource_it->remove_ref(); | 723 resource_it->remove_ref(); |
698 } | 724 } |
699 | 725 |
700 } // namespace cc | 726 } // namespace cc |
OLD | NEW |