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/khronos/GLES2/gl2.h" | 13 #include "third_party/khronos/GLES2/gl2.h" |
14 #include "third_party/khronos/GLES2/gl2ext.h" | 14 #include "third_party/khronos/GLES2/gl2ext.h" |
15 #include "ui/gfx/size_conversions.h" | 15 #include "ui/gfx/size_conversions.h" |
16 | 16 |
17 const unsigned kYUVResourceFormat = GL_LUMINANCE; | 17 const unsigned kYUVResourceFormat = GL_LUMINANCE; |
18 const unsigned kRGBResourceFormat = GL_RGBA; | 18 const unsigned kRGBResourceFormat = GL_RGBA; |
19 | 19 |
20 namespace cc { | 20 namespace cc { |
21 | 21 |
22 VideoFrameExternalResources::VideoFrameExternalResources() | 22 VideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {} |
23 : type(NONE), hardware_resource(0) {} | |
24 | 23 |
25 VideoFrameExternalResources::~VideoFrameExternalResources() {} | 24 VideoFrameExternalResources::~VideoFrameExternalResources() {} |
26 | 25 |
27 VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider) | 26 VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider) |
28 : resource_provider_(resource_provider) { | 27 : resource_provider_(resource_provider) { |
29 } | 28 } |
30 | 29 |
31 VideoResourceUpdater::~VideoResourceUpdater() { | 30 VideoResourceUpdater::~VideoResourceUpdater() { |
32 while (!all_resources_.empty()) { | 31 while (!all_resources_.empty()) { |
33 resource_provider_->DeleteResource(all_resources_.back()); | 32 resource_provider_->DeleteResource(all_resources_.back()); |
34 all_resources_.pop_back(); | 33 all_resources_.pop_back(); |
35 } | 34 } |
36 } | 35 } |
37 | 36 |
38 void VideoResourceUpdater::DeleteResource(unsigned resource_id) { | 37 void VideoResourceUpdater::DeleteResource(unsigned resource_id) { |
39 resource_provider_->DeleteResource(resource_id); | 38 resource_provider_->DeleteResource(resource_id); |
40 all_resources_.erase(std::remove(all_resources_.begin(), | 39 all_resources_.erase(std::remove(all_resources_.begin(), |
41 all_resources_.end(), | 40 all_resources_.end(), |
42 resource_id)); | 41 resource_id)); |
43 } | 42 } |
44 | 43 |
| 44 VideoFrameExternalResources VideoResourceUpdater:: |
| 45 CreateExternalResourcesFromVideoFrame( |
| 46 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 47 if (!VerifyFrame(video_frame)) |
| 48 return VideoFrameExternalResources(); |
| 49 |
| 50 if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE) |
| 51 return CreateForHardwarePlanes(video_frame); |
| 52 else |
| 53 return CreateForSoftwarePlanes(video_frame); |
| 54 } |
| 55 |
45 bool VideoResourceUpdater::VerifyFrame( | 56 bool VideoResourceUpdater::VerifyFrame( |
46 const scoped_refptr<media::VideoFrame>& video_frame) { | 57 const scoped_refptr<media::VideoFrame>& video_frame) { |
47 // If these fail, we'll have to add logic that handles offset bitmap/texture | 58 // If these fail, we'll have to add logic that handles offset bitmap/texture |
48 // UVs. For now, just expect (0, 0) offset, since all our decoders so far | 59 // UVs. For now, just expect (0, 0) offset, since all our decoders so far |
49 // don't offset. | 60 // don't offset. |
50 DCHECK_EQ(video_frame->visible_rect().x(), 0); | 61 DCHECK_EQ(video_frame->visible_rect().x(), 0); |
51 DCHECK_EQ(video_frame->visible_rect().y(), 0); | 62 DCHECK_EQ(video_frame->visible_rect().y(), 0); |
52 | 63 |
53 switch (video_frame->format()) { | 64 switch (video_frame->format()) { |
54 // Acceptable inputs. | 65 // Acceptable inputs. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 NOTREACHED(); | 112 NOTREACHED(); |
102 } | 113 } |
103 } | 114 } |
104 | 115 |
105 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); | 116 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); |
106 return coded_size; | 117 return coded_size; |
107 } | 118 } |
108 | 119 |
109 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 120 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
110 const scoped_refptr<media::VideoFrame>& video_frame) { | 121 const scoped_refptr<media::VideoFrame>& video_frame) { |
111 if (!VerifyFrame(video_frame)) | |
112 return VideoFrameExternalResources(); | |
113 | |
114 media::VideoFrame::Format input_frame_format = video_frame->format(); | 122 media::VideoFrame::Format input_frame_format = video_frame->format(); |
115 | 123 |
116 #if defined(GOOGLE_TV) | 124 #if defined(GOOGLE_TV) |
117 if (input_frame_format == media::VideoFrame::HOLE) { | 125 if (input_frame_format == media::VideoFrame::HOLE) { |
118 VideoFrameExternalResources external_resources; | 126 VideoFrameExternalResources external_resources; |
119 external_resources.type = VideoFrameExternalResources::HOLE; | 127 external_resources.type = VideoFrameExternalResources::HOLE; |
120 return external_resources; | 128 return external_resources; |
121 } | 129 } |
122 #endif | 130 #endif |
123 | 131 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 recycle_data); | 309 recycle_data); |
302 external_resources.mailboxes.push_back( | 310 external_resources.mailboxes.push_back( |
303 TextureMailbox(plane_resources[i].mailbox, | 311 TextureMailbox(plane_resources[i].mailbox, |
304 callback_to_free_resource)); | 312 callback_to_free_resource)); |
305 } | 313 } |
306 | 314 |
307 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; | 315 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; |
308 return external_resources; | 316 return external_resources; |
309 } | 317 } |
310 | 318 |
| 319 static void ReturnTexture( |
| 320 scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder, |
| 321 unsigned sync_point, |
| 322 bool lost_resource) { |
| 323 mailbox_holder->Return(sync_point); |
| 324 } |
| 325 |
311 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( | 326 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( |
312 const scoped_refptr<media::VideoFrame>& video_frame) { | 327 const scoped_refptr<media::VideoFrame>& video_frame) { |
313 if (!VerifyFrame(video_frame)) | |
314 return VideoFrameExternalResources(); | |
315 | |
316 media::VideoFrame::Format frame_format = video_frame->format(); | 328 media::VideoFrame::Format frame_format = video_frame->format(); |
317 | 329 |
318 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); | 330 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); |
319 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) | 331 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) |
320 return VideoFrameExternalResources(); | 332 return VideoFrameExternalResources(); |
321 | 333 |
322 WebKit::WebGraphicsContext3D* context = | 334 WebKit::WebGraphicsContext3D* context = |
323 resource_provider_->GraphicsContext3D(); | 335 resource_provider_->GraphicsContext3D(); |
324 if (!context) | 336 if (!context) |
325 return VideoFrameExternalResources(); | 337 return VideoFrameExternalResources(); |
326 | 338 |
327 VideoFrameExternalResources external_resources; | 339 VideoFrameExternalResources external_resources; |
328 switch (video_frame->texture_target()) { | 340 switch (video_frame->texture_target()) { |
329 case GL_TEXTURE_2D: | 341 case GL_TEXTURE_2D: |
330 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; | 342 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; |
331 break; | 343 break; |
332 case GL_TEXTURE_EXTERNAL_OES: | 344 case GL_TEXTURE_EXTERNAL_OES: |
333 external_resources.type = | 345 external_resources.type = |
334 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; | 346 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; |
335 break; | 347 break; |
336 case GL_TEXTURE_RECTANGLE_ARB: | 348 case GL_TEXTURE_RECTANGLE_ARB: |
337 external_resources.type = VideoFrameExternalResources::IO_SURFACE; | 349 external_resources.type = VideoFrameExternalResources::IO_SURFACE; |
338 break; | 350 break; |
339 default: | 351 default: |
340 NOTREACHED(); | 352 NOTREACHED(); |
341 return VideoFrameExternalResources(); | 353 return VideoFrameExternalResources(); |
342 } | 354 } |
343 | 355 |
344 external_resources.hardware_resource = | 356 scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder = |
345 resource_provider_->CreateResourceFromExternalTexture( | 357 video_frame->texture_mailbox(); |
346 video_frame->texture_target(), | |
347 video_frame->texture_id()); | |
348 if (external_resources.hardware_resource) | |
349 all_resources_.push_back(external_resources.hardware_resource); | |
350 | 358 |
351 TextureMailbox::ReleaseCallback callback_to_return_resource = | 359 TextureMailbox::ReleaseCallback callback_to_return_resource = |
352 base::Bind(&ReturnTexture, | 360 base::Bind(&ReturnTexture, mailbox_holder); |
353 AsWeakPtr(), | 361 |
354 external_resources.hardware_resource); | 362 external_resources.mailboxes.push_back( |
355 external_resources.hardware_release_callback = callback_to_return_resource; | 363 TextureMailbox(mailbox_holder->mailbox(), |
| 364 callback_to_return_resource, |
| 365 video_frame->texture_target(), |
| 366 mailbox_holder->sync_point())); |
356 return external_resources; | 367 return external_resources; |
357 } | 368 } |
358 | 369 |
359 // static | 370 // static |
360 void VideoResourceUpdater::ReturnTexture( | |
361 base::WeakPtr<VideoResourceUpdater> updater, | |
362 unsigned resource_id, | |
363 unsigned sync_point, | |
364 bool lost_resource) { | |
365 if (!updater.get()) { | |
366 // Resource was already deleted. | |
367 return; | |
368 } | |
369 | |
370 updater->DeleteResource(resource_id); | |
371 } | |
372 | |
373 // static | |
374 void VideoResourceUpdater::RecycleResource( | 371 void VideoResourceUpdater::RecycleResource( |
375 base::WeakPtr<VideoResourceUpdater> updater, | 372 base::WeakPtr<VideoResourceUpdater> updater, |
376 RecycleResourceData data, | 373 RecycleResourceData data, |
377 unsigned sync_point, | 374 unsigned sync_point, |
378 bool lost_resource) { | 375 bool lost_resource) { |
379 if (!updater.get()) { | 376 if (!updater.get()) { |
380 // Resource was already deleted. | 377 // Resource was already deleted. |
381 return; | 378 return; |
382 } | 379 } |
383 | 380 |
(...skipping 16 matching lines...) Expand all Loading... |
400 } | 397 } |
401 | 398 |
402 PlaneResource recycled_resource(data.resource_id, | 399 PlaneResource recycled_resource(data.resource_id, |
403 data.resource_size, | 400 data.resource_size, |
404 data.resource_format, | 401 data.resource_format, |
405 data.mailbox); | 402 data.mailbox); |
406 updater->recycled_resources_.push_back(recycled_resource); | 403 updater->recycled_resources_.push_back(recycled_resource); |
407 } | 404 } |
408 | 405 |
409 } // namespace cc | 406 } // namespace cc |
OLD | NEW |