| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "cc/output/gl_renderer.h" | 8 #include "cc/output/gl_renderer.h" |
| 9 #include "cc/resources/resource_provider.h" | 9 #include "cc/resources/resource_provider.h" |
| 10 #include "gpu/GLES2/gl2extchromium.h" | 10 #include "gpu/GLES2/gl2extchromium.h" |
| 11 #include "media/base/video_frame.h" | 11 #include "media/base/video_frame.h" |
| 12 #include "media/filters/skcanvas_video_renderer.h" | 12 #include "media/filters/skcanvas_video_renderer.h" |
| 13 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" | 13 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" |
| 14 #include "third_party/khronos/GLES2/gl2.h" | 14 #include "third_party/khronos/GLES2/gl2.h" |
| 15 #include "third_party/khronos/GLES2/gl2ext.h" | 15 #include "third_party/khronos/GLES2/gl2ext.h" |
| 16 #include "ui/gfx/size_conversions.h" | 16 #include "ui/gfx/size_conversions.h" |
| 17 | 17 |
| 18 const unsigned kYUVResourceFormat = GL_LUMINANCE; | 18 namespace cc { |
| 19 const unsigned kRGBResourceFormat = GL_RGBA; | |
| 20 | 19 |
| 21 namespace cc { | 20 const ResourceFormat kYUVResourceFormat = LUMINANCE_8; |
| 21 const ResourceFormat kRGBResourceFormat = RGBA_8888; |
| 22 | 22 |
| 23 VideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {} | 23 VideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {} |
| 24 | 24 |
| 25 VideoFrameExternalResources::~VideoFrameExternalResources() {} | 25 VideoFrameExternalResources::~VideoFrameExternalResources() {} |
| 26 | 26 |
| 27 VideoResourceUpdater::VideoResourceUpdater(ContextProvider* context_provider, | 27 VideoResourceUpdater::VideoResourceUpdater(ContextProvider* context_provider, |
| 28 ResourceProvider* resource_provider) | 28 ResourceProvider* resource_provider) |
| 29 : context_provider_(context_provider), | 29 : context_provider_(context_provider), |
| 30 resource_provider_(resource_provider) { | 30 resource_provider_(resource_provider) { |
| 31 } | 31 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 break; | 83 break; |
| 84 } | 84 } |
| 85 return false; | 85 return false; |
| 86 } | 86 } |
| 87 | 87 |
| 88 // For frames that we receive in software format, determine the dimensions of | 88 // For frames that we receive in software format, determine the dimensions of |
| 89 // each plane in the frame. | 89 // each plane in the frame. |
| 90 static gfx::Size SoftwarePlaneDimension( | 90 static gfx::Size SoftwarePlaneDimension( |
| 91 media::VideoFrame::Format input_frame_format, | 91 media::VideoFrame::Format input_frame_format, |
| 92 gfx::Size coded_size, | 92 gfx::Size coded_size, |
| 93 GLenum output_resource_format, | 93 ResourceFormat output_resource_format, |
| 94 int plane_index) { | 94 int plane_index) { |
| 95 if (output_resource_format == kYUVResourceFormat) { | 95 if (output_resource_format == kYUVResourceFormat) { |
| 96 if (plane_index == media::VideoFrame::kYPlane || | 96 if (plane_index == media::VideoFrame::kYPlane || |
| 97 plane_index == media::VideoFrame::kAPlane) | 97 plane_index == media::VideoFrame::kAPlane) |
| 98 return coded_size; | 98 return coded_size; |
| 99 | 99 |
| 100 switch (input_frame_format) { | 100 switch (input_frame_format) { |
| 101 case media::VideoFrame::YV12: | 101 case media::VideoFrame::YV12: |
| 102 case media::VideoFrame::YV12A: | 102 case media::VideoFrame::YV12A: |
| 103 return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 0.5f)); | 103 return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 0.5f)); |
| 104 case media::VideoFrame::YV16: | 104 case media::VideoFrame::YV16: |
| 105 return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 1.f)); | 105 return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 1.f)); |
| 106 | 106 |
| 107 case media::VideoFrame::INVALID: | 107 case media::VideoFrame::INVALID: |
| 108 case media::VideoFrame::RGB32: | 108 case media::VideoFrame::RGB32: |
| 109 case media::VideoFrame::EMPTY: | 109 case media::VideoFrame::EMPTY: |
| 110 case media::VideoFrame::I420: | 110 case media::VideoFrame::I420: |
| 111 case media::VideoFrame::NATIVE_TEXTURE: | 111 case media::VideoFrame::NATIVE_TEXTURE: |
| 112 #if defined(GOOGLE_TV) | 112 #if defined(GOOGLE_TV) |
| 113 case media::VideoFrame::HOLE: | 113 case media::VideoFrame::HOLE: |
| 114 #endif | 114 #endif |
| 115 NOTREACHED(); | 115 NOTREACHED(); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); | 119 DCHECK_EQ(output_resource_format, kRGBResourceFormat); |
| 120 return coded_size; | 120 return coded_size; |
| 121 } | 121 } |
| 122 | 122 |
| 123 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 123 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| 124 const scoped_refptr<media::VideoFrame>& video_frame) { | 124 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 125 media::VideoFrame::Format input_frame_format = video_frame->format(); | 125 media::VideoFrame::Format input_frame_format = video_frame->format(); |
| 126 | 126 |
| 127 #if defined(GOOGLE_TV) | 127 #if defined(GOOGLE_TV) |
| 128 if (input_frame_format == media::VideoFrame::HOLE) { | 128 if (input_frame_format == media::VideoFrame::HOLE) { |
| 129 VideoFrameExternalResources external_resources; | 129 VideoFrameExternalResources external_resources; |
| 130 external_resources.type = VideoFrameExternalResources::HOLE; | 130 external_resources.type = VideoFrameExternalResources::HOLE; |
| 131 return external_resources; | 131 return external_resources; |
| 132 } | 132 } |
| 133 #endif | 133 #endif |
| 134 | 134 |
| 135 // Only YUV software video frames are supported. | 135 // Only YUV software video frames are supported. |
| 136 DCHECK(input_frame_format == media::VideoFrame::YV12 || | 136 DCHECK(input_frame_format == media::VideoFrame::YV12 || |
| 137 input_frame_format == media::VideoFrame::YV12A || | 137 input_frame_format == media::VideoFrame::YV12A || |
| 138 input_frame_format == media::VideoFrame::YV16); | 138 input_frame_format == media::VideoFrame::YV16); |
| 139 if (input_frame_format != media::VideoFrame::YV12 && | 139 if (input_frame_format != media::VideoFrame::YV12 && |
| 140 input_frame_format != media::VideoFrame::YV12A && | 140 input_frame_format != media::VideoFrame::YV12A && |
| 141 input_frame_format != media::VideoFrame::YV16) | 141 input_frame_format != media::VideoFrame::YV16) |
| 142 return VideoFrameExternalResources(); | 142 return VideoFrameExternalResources(); |
| 143 | 143 |
| 144 bool software_compositor = context_provider_ == NULL; | 144 bool software_compositor = context_provider_ == NULL; |
| 145 | 145 |
| 146 GLenum output_resource_format = kYUVResourceFormat; | 146 ResourceFormat output_resource_format = kYUVResourceFormat; |
| 147 size_t output_plane_count = | 147 size_t output_plane_count = |
| 148 (input_frame_format == media::VideoFrame::YV12A) ? 4 : 3; | 148 (input_frame_format == media::VideoFrame::YV12A) ? 4 : 3; |
| 149 | 149 |
| 150 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 150 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB |
| 151 // conversion here. That involves an extra copy of each frame to a bitmap. | 151 // conversion here. That involves an extra copy of each frame to a bitmap. |
| 152 // Obviously, this is suboptimal and should be addressed once ubercompositor | 152 // Obviously, this is suboptimal and should be addressed once ubercompositor |
| 153 // starts shaping up. | 153 // starts shaping up. |
| 154 if (software_compositor) { | 154 if (software_compositor) { |
| 155 output_resource_format = kRGBResourceFormat; | 155 output_resource_format = kRGBResourceFormat; |
| 156 output_plane_count = 1; | 156 output_plane_count = 1; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 187 recycled_resources_.erase(recycled_resources_.begin() + i); | 187 recycled_resources_.erase(recycled_resources_.begin() + i); |
| 188 break; | 188 break; |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 | 191 |
| 192 if (resource_id == 0) { | 192 if (resource_id == 0) { |
| 193 // TODO(danakj): Abstract out hw/sw resource create/delete from | 193 // TODO(danakj): Abstract out hw/sw resource create/delete from |
| 194 // ResourceProvider and stop using ResourceProvider in this class. | 194 // ResourceProvider and stop using ResourceProvider in this class. |
| 195 resource_id = | 195 resource_id = |
| 196 resource_provider_->CreateResource(output_plane_resource_size, | 196 resource_provider_->CreateResource(output_plane_resource_size, |
| 197 output_resource_format, | |
| 198 GL_CLAMP_TO_EDGE, | 197 GL_CLAMP_TO_EDGE, |
| 199 ResourceProvider::TextureUsageAny); | 198 ResourceProvider::TextureUsageAny, |
| 199 output_resource_format); |
| 200 | 200 |
| 201 DCHECK(mailbox.IsZero()); | 201 DCHECK(mailbox.IsZero()); |
| 202 | 202 |
| 203 if (!software_compositor) { | 203 if (!software_compositor) { |
| 204 DCHECK(context_provider_); | 204 DCHECK(context_provider_); |
| 205 | 205 |
| 206 WebKit::WebGraphicsContext3D* context = | 206 WebKit::WebGraphicsContext3D* context = |
| 207 context_provider_->Context3d(); | 207 context_provider_->Context3d(); |
| 208 | 208 |
| 209 GLC(context, context->genMailboxCHROMIUM(mailbox.name)); | 209 GLC(context, context->genMailboxCHROMIUM(mailbox.name)); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 external_resources.software_release_callback = | 277 external_resources.software_release_callback = |
| 278 base::Bind(&RecycleResource, AsWeakPtr(), recycle_data); | 278 base::Bind(&RecycleResource, AsWeakPtr(), recycle_data); |
| 279 | 279 |
| 280 | 280 |
| 281 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; | 281 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; |
| 282 return external_resources; | 282 return external_resources; |
| 283 } | 283 } |
| 284 | 284 |
| 285 for (size_t i = 0; i < plane_resources.size(); ++i) { | 285 for (size_t i = 0; i < plane_resources.size(); ++i) { |
| 286 // Update each plane's resource id with its content. | 286 // Update each plane's resource id with its content. |
| 287 DCHECK_EQ(plane_resources[i].resource_format, | 287 DCHECK_EQ(plane_resources[i].resource_format, kYUVResourceFormat); |
| 288 static_cast<unsigned>(kYUVResourceFormat)); | |
| 289 | 288 |
| 290 const uint8_t* input_plane_pixels = video_frame->data(i); | 289 const uint8_t* input_plane_pixels = video_frame->data(i); |
| 291 | 290 |
| 292 gfx::Rect image_rect(0, | 291 gfx::Rect image_rect(0, |
| 293 0, | 292 0, |
| 294 video_frame->stride(i), | 293 video_frame->stride(i), |
| 295 plane_resources[i].resource_size.height()); | 294 plane_resources[i].resource_size.height()); |
| 296 gfx::Rect source_rect(plane_resources[i].resource_size); | 295 gfx::Rect source_rect(plane_resources[i].resource_size); |
| 297 resource_provider_->SetPixels(plane_resources[i].resource_id, | 296 resource_provider_->SetPixels(plane_resources[i].resource_id, |
| 298 input_plane_pixels, | 297 input_plane_pixels, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 } | 394 } |
| 396 | 395 |
| 397 PlaneResource recycled_resource(data.resource_id, | 396 PlaneResource recycled_resource(data.resource_id, |
| 398 data.resource_size, | 397 data.resource_size, |
| 399 data.resource_format, | 398 data.resource_format, |
| 400 data.mailbox); | 399 data.mailbox); |
| 401 updater->recycled_resources_.push_back(recycled_resource); | 400 updater->recycled_resources_.push_back(recycled_resource); |
| 402 } | 401 } |
| 403 | 402 |
| 404 } // namespace cc | 403 } // namespace cc |
| OLD | NEW |