Chromium Code Reviews| Index: cc/resources/video_resource_updater.cc |
| diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc |
| index e77cd7505af1c58cecfbfe1f07bb0d32f9641a01..facae16223181d59fb1b4863025f4f87cd418d09 100644 |
| --- a/cc/resources/video_resource_updater.cc |
| +++ b/cc/resources/video_resource_updater.cc |
| @@ -346,6 +346,12 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| for (size_t i = 0; i < output_plane_count; ++i) { |
| gfx::Size output_plane_resource_size = |
| SoftwarePlaneDimension(video_frame.get(), software_compositor, i); |
| + ResourceFormat plane_resource_format = output_resource_format; |
| + if ((input_frame_format == media::PIXEL_FORMAT_NV12) && (i == 1)) { |
|
danakj
2016/04/13 00:24:18
If all of this is for tests I'd prefer to just not
|
| + // A two-byte-per-pixel format would avoid wasting space, but this is |
| + // only used in testing. |
| + plane_resource_format = RGBA_8888; |
| + } |
| if (output_plane_resource_size.IsEmpty() || |
| output_plane_resource_size.width() > max_resource_size || |
| output_plane_resource_size.height() > max_resource_size) { |
| @@ -356,7 +362,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| ResourceList::iterator resource_it = all_resources_.end(); |
| for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { |
| if (it->resource_size == output_plane_resource_size && |
| - it->resource_format == output_resource_format) { |
| + it->resource_format == plane_resource_format) { |
| if (PlaneResourceMatchesUniqueID(*it, video_frame.get(), i)) { |
| // Bingo, we found a resource that already contains the data we are |
| // planning to put in it. It's safe to reuse it even if |
| @@ -383,7 +389,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| if (resource_it == all_resources_.end()) { |
| const bool is_immutable = true; |
| resource_it = |
| - AllocateResource(output_plane_resource_size, output_resource_format, |
| + AllocateResource(output_plane_resource_size, plane_resource_format, |
| !software_compositor, is_immutable); |
| } |
| if (resource_it == all_resources_.end()) |
| @@ -440,9 +446,6 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| for (size_t i = 0; i < plane_resources.size(); ++i) { |
| PlaneResource& plane_resource = *plane_resources[i]; |
| // Update each plane's resource id with its content. |
| - DCHECK_EQ(plane_resource.resource_format, |
| - resource_provider_->YuvResourceFormat(bits_per_channel)); |
| - |
| if (!PlaneResourceMatchesUniqueID(plane_resource, video_frame.get(), i)) { |
| // We need to transfer data from |video_frame| to the plane resource. |
| // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. |
| @@ -463,6 +466,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| bool needs_conversion = false; |
| int shift = 0; |
| + bool needs_expansion = false; |
| // LUMINANCE_F16 uses half-floats, so we always need a conversion step. |
| if (plane_resource.resource_format == LUMINANCE_F16) { |
| @@ -475,6 +479,11 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| // shift the data down and create an 8-bit texture. |
| needs_conversion = true; |
| shift = bits_per_channel - 8; |
| + } else if ((input_frame_format == media::PIXEL_FORMAT_NV12) && (i == 1)) { |
| + DCHECK_EQ(RGBA_8888, plane_resource.resource_format); |
| + needs_conversion = true; |
| + // Expand each 2 byte pixel into 4 bytes. |
| + needs_expansion = true; |
| } |
| const uint8_t* pixels; |
| if (static_cast<int>(upload_image_stride) == video_stride_bytes && |
| @@ -508,6 +517,16 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| video_frame->data(i) + (video_stride_bytes * row)); |
| for (size_t i = 0; i < bytes_per_row; i++) |
| dst[i] = src[i] >> shift; |
| + } else if (needs_expansion) { |
| + uint32_t* dst = reinterpret_cast<uint32_t*>( |
| + &upload_pixels_[upload_image_stride * row]); |
| + const uint8_t* src = |
| + video_frame->data(i) + (video_stride_bytes * row); |
| + for (size_t i = 0; i < bytes_per_row / 4; i++) { |
| + // The first channel (U) goes in the R component, and the second |
| + // (V) goes in the G component. B and A are black. |
| + dst[i] = ((src[i * 2] << 24) | (src[i * 2 + 1] << 16)); |
| + } |
| } else { |
| // Input and output are the same size and format, but |
| // differ in stride, copy one row at a time. |