Chromium Code Reviews| 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 "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "cc/output/gl_renderer.h" | 9 #include "cc/output/gl_renderer.h" |
| 10 #include "cc/resources/resource_provider.h" | 10 #include "cc/resources/resource_provider.h" |
| 11 #include "gpu/GLES2/gl2extchromium.h" | 11 #include "gpu/GLES2/gl2extchromium.h" |
| 12 #include "gpu/command_buffer/client/gles2_interface.h" | 12 #include "gpu/command_buffer/client/gles2_interface.h" |
| 13 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
| 14 #include "media/filters/skcanvas_video_renderer.h" | 14 #include "media/filters/skcanvas_video_renderer.h" |
| 15 #include "third_party/khronos/GLES2/gl2.h" | 15 #include "third_party/khronos/GLES2/gl2.h" |
| 16 #include "third_party/khronos/GLES2/gl2ext.h" | 16 #include "third_party/khronos/GLES2/gl2ext.h" |
| 17 #include "ui/gfx/geometry/size_conversions.h" | 17 #include "ui/gfx/geometry/size_conversions.h" |
| 18 | 18 |
| 19 namespace cc { | 19 namespace cc { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 const ResourceFormat kYUVResourceFormat = LUMINANCE_8; | |
| 24 const ResourceFormat kRGBResourceFormat = RGBA_8888; | 23 const ResourceFormat kRGBResourceFormat = RGBA_8888; |
| 25 | 24 |
| 26 class SyncPointClientImpl : public media::VideoFrame::SyncPointClient { | 25 class SyncPointClientImpl : public media::VideoFrame::SyncPointClient { |
| 27 public: | 26 public: |
| 28 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} | 27 explicit SyncPointClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} |
| 29 ~SyncPointClientImpl() override {} | 28 ~SyncPointClientImpl() override {} |
| 30 uint32 InsertSyncPoint() override { | 29 uint32 InsertSyncPoint() override { |
| 31 return GLC(gl_, gl_->InsertSyncPointCHROMIUM()); | 30 return GLC(gl_, gl_->InsertSyncPointCHROMIUM()); |
| 32 } | 31 } |
| 33 void WaitSyncPoint(uint32 sync_point) override { | 32 void WaitSyncPoint(uint32 sync_point) override { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 // Unacceptable inputs. ¯\(°_o)/¯ | 125 // Unacceptable inputs. ¯\(°_o)/¯ |
| 127 case media::VideoFrame::UNKNOWN: | 126 case media::VideoFrame::UNKNOWN: |
| 128 case media::VideoFrame::NV12: | 127 case media::VideoFrame::NV12: |
| 129 break; | 128 break; |
| 130 } | 129 } |
| 131 return false; | 130 return false; |
| 132 } | 131 } |
| 133 | 132 |
| 134 // For frames that we receive in software format, determine the dimensions of | 133 // For frames that we receive in software format, determine the dimensions of |
| 135 // each plane in the frame. | 134 // each plane in the frame. |
| 136 static gfx::Size SoftwarePlaneDimension( | 135 static gfx::Size PlaneDimension( |
|
danakj
2014/12/02 17:03:20
leave this name as is? It refers to the the video
| |
| 137 const scoped_refptr<media::VideoFrame>& input_frame, | 136 const scoped_refptr<media::VideoFrame>& input_frame, |
| 138 ResourceFormat output_resource_format, | 137 bool software_compositor, |
| 139 size_t plane_index) { | 138 size_t plane_index) { |
| 140 if (output_resource_format == kYUVResourceFormat) { | 139 if (!software_compositor) { |
| 141 return media::VideoFrame::PlaneSize( | 140 return media::VideoFrame::PlaneSize( |
| 142 input_frame->format(), plane_index, input_frame->coded_size()); | 141 input_frame->format(), plane_index, input_frame->coded_size()); |
| 143 } | 142 } |
| 144 | |
| 145 DCHECK_EQ(output_resource_format, kRGBResourceFormat); | |
| 146 return input_frame->coded_size(); | 143 return input_frame->coded_size(); |
| 147 } | 144 } |
| 148 | 145 |
| 149 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 146 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| 150 const scoped_refptr<media::VideoFrame>& video_frame) { | 147 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 151 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); | 148 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); |
| 152 media::VideoFrame::Format input_frame_format = video_frame->format(); | 149 media::VideoFrame::Format input_frame_format = video_frame->format(); |
| 153 | 150 |
| 154 #if defined(VIDEO_HOLE) | 151 #if defined(VIDEO_HOLE) |
| 155 if (input_frame_format == media::VideoFrame::HOLE) { | 152 if (input_frame_format == media::VideoFrame::HOLE) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 169 if (input_frame_format != media::VideoFrame::YV12 && | 166 if (input_frame_format != media::VideoFrame::YV12 && |
| 170 input_frame_format != media::VideoFrame::I420 && | 167 input_frame_format != media::VideoFrame::I420 && |
| 171 input_frame_format != media::VideoFrame::YV12A && | 168 input_frame_format != media::VideoFrame::YV12A && |
| 172 input_frame_format != media::VideoFrame::YV12J && | 169 input_frame_format != media::VideoFrame::YV12J && |
| 173 input_frame_format != media::VideoFrame::YV16 && | 170 input_frame_format != media::VideoFrame::YV16 && |
| 174 input_frame_format != media::VideoFrame::YV24) | 171 input_frame_format != media::VideoFrame::YV24) |
| 175 return VideoFrameExternalResources(); | 172 return VideoFrameExternalResources(); |
| 176 | 173 |
| 177 bool software_compositor = context_provider_ == NULL; | 174 bool software_compositor = context_provider_ == NULL; |
| 178 | 175 |
| 179 ResourceFormat output_resource_format = kYUVResourceFormat; | 176 ResourceFormat output_resource_format = |
| 177 resource_provider_->yuv_resource_format(); | |
| 180 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); | 178 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); |
| 181 | 179 |
| 182 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 180 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB |
| 183 // conversion here. That involves an extra copy of each frame to a bitmap. | 181 // conversion here. That involves an extra copy of each frame to a bitmap. |
| 184 // Obviously, this is suboptimal and should be addressed once ubercompositor | 182 // Obviously, this is suboptimal and should be addressed once ubercompositor |
| 185 // starts shaping up. | 183 // starts shaping up. |
| 186 if (software_compositor) { | 184 if (software_compositor) { |
| 187 output_resource_format = kRGBResourceFormat; | 185 output_resource_format = kRGBResourceFormat; |
| 188 output_plane_count = 1; | 186 output_plane_count = 1; |
| 189 } | 187 } |
| 190 | 188 |
| 191 int max_resource_size = resource_provider_->max_texture_size(); | 189 int max_resource_size = resource_provider_->max_texture_size(); |
| 192 std::vector<PlaneResource> plane_resources; | 190 std::vector<PlaneResource> plane_resources; |
| 193 bool allocation_success = true; | 191 bool allocation_success = true; |
| 194 | 192 |
| 195 for (size_t i = 0; i < output_plane_count; ++i) { | 193 for (size_t i = 0; i < output_plane_count; ++i) { |
| 196 gfx::Size output_plane_resource_size = | 194 gfx::Size output_plane_resource_size = |
| 197 SoftwarePlaneDimension(video_frame, output_resource_format, i); | 195 PlaneDimension(video_frame, software_compositor, i); |
| 198 if (output_plane_resource_size.IsEmpty() || | 196 if (output_plane_resource_size.IsEmpty() || |
| 199 output_plane_resource_size.width() > max_resource_size || | 197 output_plane_resource_size.width() > max_resource_size || |
| 200 output_plane_resource_size.height() > max_resource_size) { | 198 output_plane_resource_size.height() > max_resource_size) { |
| 201 allocation_success = false; | 199 allocation_success = false; |
| 202 break; | 200 break; |
| 203 } | 201 } |
| 204 | 202 |
| 205 // Try recycle a previously-allocated resource. | 203 // Try recycle a previously-allocated resource. |
| 206 auto recycled_it = recycled_resources_.end(); | 204 auto recycled_it = recycled_resources_.end(); |
| 207 for (auto it = recycled_resources_.begin(); it != recycled_resources_.end(); | 205 for (auto it = recycled_resources_.begin(); it != recycled_resources_.end(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 plane_resources[0].resource_id); | 288 plane_resources[0].resource_id); |
| 291 external_resources.software_release_callback = | 289 external_resources.software_release_callback = |
| 292 base::Bind(&RecycleResource, AsWeakPtr(), plane_resources[0]); | 290 base::Bind(&RecycleResource, AsWeakPtr(), plane_resources[0]); |
| 293 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; | 291 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; |
| 294 | 292 |
| 295 return external_resources; | 293 return external_resources; |
| 296 } | 294 } |
| 297 | 295 |
| 298 for (size_t i = 0; i < plane_resources.size(); ++i) { | 296 for (size_t i = 0; i < plane_resources.size(); ++i) { |
| 299 // Update each plane's resource id with its content. | 297 // Update each plane's resource id with its content. |
| 300 DCHECK_EQ(plane_resources[i].resource_format, kYUVResourceFormat); | 298 DCHECK_EQ(plane_resources[i].resource_format, |
| 299 resource_provider_->yuv_resource_format()); | |
| 301 | 300 |
| 302 if (!PlaneResourceMatchesUniqueID(plane_resources[i], video_frame.get(), | 301 if (!PlaneResourceMatchesUniqueID(plane_resources[i], video_frame.get(), |
| 303 i)) { | 302 i)) { |
| 304 // We need to transfer data from |video_frame| to the plane resource. | 303 // We need to transfer data from |video_frame| to the plane resource. |
| 305 const uint8_t* input_plane_pixels = video_frame->data(i); | 304 const uint8_t* input_plane_pixels = video_frame->data(i); |
| 306 | 305 |
| 307 gfx::Rect image_rect(0, 0, video_frame->stride(i), | 306 gfx::Rect image_rect(0, 0, video_frame->stride(i), |
| 308 plane_resources[i].resource_size.height()); | 307 plane_resources[i].resource_size.height()); |
| 309 gfx::Rect source_rect(plane_resources[i].resource_size); | 308 gfx::Rect source_rect(plane_resources[i].resource_size); |
| 310 resource_provider_->SetPixels(plane_resources[i].resource_id, | 309 resource_provider_->SetPixels(plane_resources[i].resource_id, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 updater->recycled_resources_.back().resource_format != | 407 updater->recycled_resources_.back().resource_format != |
| 409 data.resource_format) { | 408 data.resource_format) { |
| 410 updater->DeleteResource(updater->recycled_resources_.back().resource_id); | 409 updater->DeleteResource(updater->recycled_resources_.back().resource_id); |
| 411 updater->recycled_resources_.pop_back(); | 410 updater->recycled_resources_.pop_back(); |
| 412 } | 411 } |
| 413 | 412 |
| 414 updater->recycled_resources_.push_back(data); | 413 updater->recycled_resources_.push_back(data); |
| 415 } | 414 } |
| 416 | 415 |
| 417 } // namespace cc | 416 } // namespace cc |
| OLD | NEW |