Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Side by Side Diff: cc/resources/video_resource_updater.cc

Issue 14199002: Send hardware video frames with mailboxes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ifdefed Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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() : type(NONE) {} 22 VideoFrameExternalResources::VideoFrameExternalResources()
23 #ifdef VIDEO_FRAME_MAILBOX
24 : type(NONE) {}
25 #else
26 : type(NONE),
27 hardware_resource(0) {}
28 #endif
23 29
24 VideoFrameExternalResources::~VideoFrameExternalResources() {} 30 VideoFrameExternalResources::~VideoFrameExternalResources() {}
25 31
26 VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider) 32 VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider)
27 : resource_provider_(resource_provider) { 33 : resource_provider_(resource_provider) {
28 } 34 }
29 35
30 VideoResourceUpdater::~VideoResourceUpdater() { 36 VideoResourceUpdater::~VideoResourceUpdater() {
31 while (!recycled_resources_.empty()) { 37 while (!recycled_resources_.empty()) {
32 resource_provider_->DeleteResource(recycled_resources_.back().resource_id); 38 resource_provider_->DeleteResource(recycled_resources_.back().resource_id);
33 recycled_resources_.pop_back(); 39 recycled_resources_.pop_back();
34 } 40 }
35 } 41 }
36 42
43 VideoFrameExternalResources VideoResourceUpdater::
44 CreateExternalResourcesFromVideoFrame(
45 const scoped_refptr<media::VideoFrame>& video_frame) {
46 if (!VerifyFrame(video_frame))
47 return VideoFrameExternalResources();
48
49 if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE)
50 return CreateForHardwarePlanes(video_frame);
51 else
52 return CreateForSoftwarePlanes(video_frame);
53 }
54
37 bool VideoResourceUpdater::VerifyFrame( 55 bool VideoResourceUpdater::VerifyFrame(
38 const scoped_refptr<media::VideoFrame>& video_frame) { 56 const scoped_refptr<media::VideoFrame>& video_frame) {
39 // If these fail, we'll have to add logic that handles offset bitmap/texture 57 // If these fail, we'll have to add logic that handles offset bitmap/texture
40 // UVs. For now, just expect (0, 0) offset, since all our decoders so far 58 // UVs. For now, just expect (0, 0) offset, since all our decoders so far
41 // don't offset. 59 // don't offset.
42 DCHECK_EQ(video_frame->visible_rect().x(), 0); 60 DCHECK_EQ(video_frame->visible_rect().x(), 0);
43 DCHECK_EQ(video_frame->visible_rect().y(), 0); 61 DCHECK_EQ(video_frame->visible_rect().y(), 0);
44 62
45 switch (video_frame->format()) { 63 switch (video_frame->format()) {
46 // Acceptable inputs. 64 // Acceptable inputs.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 NOTREACHED(); 108 NOTREACHED();
91 } 109 }
92 } 110 }
93 111
94 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); 112 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat));
95 return coded_size; 113 return coded_size;
96 } 114 }
97 115
98 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 116 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
99 const scoped_refptr<media::VideoFrame>& video_frame) { 117 const scoped_refptr<media::VideoFrame>& video_frame) {
100 if (!VerifyFrame(video_frame))
101 return VideoFrameExternalResources();
102
103 media::VideoFrame::Format input_frame_format = video_frame->format(); 118 media::VideoFrame::Format input_frame_format = video_frame->format();
104 119
105 #if defined(GOOGLE_TV) 120 #if defined(GOOGLE_TV)
106 if (input_frame_format == media::VideoFrame::HOLE) { 121 if (input_frame_format == media::VideoFrame::HOLE) {
107 VideoFrameExternalResources external_resources; 122 VideoFrameExternalResources external_resources;
108 external_resources.type = VideoFrameExternalResources::HOLE; 123 external_resources.type = VideoFrameExternalResources::HOLE;
109 return external_resources; 124 return external_resources;
110 } 125 }
111 #endif 126 #endif
112 127
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 TextureMailbox(mailbox, 297 TextureMailbox(mailbox,
283 callback_to_free_resource, 298 callback_to_free_resource,
284 plane_resources[i].sync_point)); 299 plane_resources[i].sync_point));
285 } 300 }
286 301
287 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; 302 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
288 return external_resources; 303 return external_resources;
289 } 304 }
290 305
291 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( 306 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
292 const scoped_refptr<media::VideoFrame>& video_frame, 307 const scoped_refptr<media::VideoFrame>& video_frame) {
293 const TextureMailbox::ReleaseCallback& release_callback) {
294 if (!VerifyFrame(video_frame))
295 return VideoFrameExternalResources();
296
297 media::VideoFrame::Format frame_format = video_frame->format(); 308 media::VideoFrame::Format frame_format = video_frame->format();
298 309
299 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); 310 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE);
300 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) 311 if (frame_format != media::VideoFrame::NATIVE_TEXTURE)
301 return VideoFrameExternalResources(); 312 return VideoFrameExternalResources();
302 313
303 WebKit::WebGraphicsContext3D* context = 314 WebKit::WebGraphicsContext3D* context =
304 resource_provider_->GraphicsContext3D(); 315 resource_provider_->GraphicsContext3D();
305 if (!context) 316 if (!context)
306 return VideoFrameExternalResources(); 317 return VideoFrameExternalResources();
307 318
308 VideoFrameExternalResources external_resources; 319 VideoFrameExternalResources external_resources;
309 switch (video_frame->texture_target()) { 320 switch (video_frame->texture_target()) {
310 case GL_TEXTURE_2D: 321 case GL_TEXTURE_2D:
311 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; 322 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE;
312 break; 323 break;
313 case GL_TEXTURE_EXTERNAL_OES: 324 case GL_TEXTURE_EXTERNAL_OES:
314 external_resources.type = 325 external_resources.type =
315 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; 326 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE;
316 break; 327 break;
317 case GL_TEXTURE_RECTANGLE_ARB: 328 case GL_TEXTURE_RECTANGLE_ARB:
318 external_resources.type = VideoFrameExternalResources::IO_SURFACE; 329 external_resources.type = VideoFrameExternalResources::IO_SURFACE;
319 break; 330 break;
320 default: 331 default:
321 NOTREACHED(); 332 NOTREACHED();
322 return VideoFrameExternalResources(); 333 return VideoFrameExternalResources();
323 } 334 }
324 335
325 gpu::Mailbox mailbox; 336 #ifndef VIDEO_FRAME_MAILBOX
326 GLC(context, context->genMailboxCHROMIUM(mailbox.name)); 337 ResourceProvider::ResourceId hardware_resource = 0;
327 GLC(context, context->bindTexture(GL_TEXTURE_2D, video_frame->texture_id())); 338 hardware_resource = resource_provider_->CreateResourceFromExternalTexture(
328 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name)); 339 video_frame->texture_id());
329 GLC(context, context->bindTexture(GL_TEXTURE_2D, 0)); 340 #endif
330 341
342 // Hold a reference to the VideoFrame in the callback, so the frame stays
343 // alive while the texture is in use. As long as the frame is alive, the
344 // texture inside it will not be reused by the decoder.
331 TextureMailbox::ReleaseCallback callback_to_return_resource = 345 TextureMailbox::ReleaseCallback callback_to_return_resource =
346 #ifdef VIDEO_FRAME_MAILBOX
347 base::Bind(&ReturnTexture, video_frame);
348 #else
332 base::Bind(&ReturnTexture, 349 base::Bind(&ReturnTexture,
350 video_frame,
333 base::Unretained(resource_provider_), 351 base::Unretained(resource_provider_),
334 release_callback, 352 hardware_resource);
335 video_frame->texture_id(), 353 #endif
336 mailbox); 354
337 external_resources.mailboxes.push_back( 355 #ifdef VIDEO_FRAME_MAILBOX
338 TextureMailbox(mailbox, callback_to_return_resource)); 356 external_resources.mailboxes.push_back(
357 TextureMailbox(video_frame->texture_mailbox(),
358 callback_to_return_resource,
359 video_frame->texture_mailbox_sync_point()));
360 #else
361 external_resources.hardware_resource = hardware_resource;
362 external_resources.hardware_release_callback = callback_to_return_resource;
363 #endif
339 return external_resources; 364 return external_resources;
340 } 365 }
341 366
342 // static 367 // static
343 void VideoResourceUpdater::ReturnTexture( 368 void VideoResourceUpdater::ReturnTexture(
369 scoped_refptr<media::VideoFrame> video_frame,
370 #ifndef VIDEO_FRAME_MAILBOX
344 ResourceProvider* resource_provider, 371 ResourceProvider* resource_provider,
345 TextureMailbox::ReleaseCallback callback, 372 unsigned resource_id,
346 unsigned texture_id, 373 #endif
347 gpu::Mailbox mailbox,
348 unsigned sync_point, 374 unsigned sync_point,
349 bool lost_resource) { 375 bool lost_resource) {
350 WebKit::WebGraphicsContext3D* context = 376 #ifndef VIDEO_FRAME_MAILBOX
351 resource_provider->GraphicsContext3D(); 377 resource_provider->DeleteResource(resource_id);
352 GLC(context, context->bindTexture(GL_TEXTURE_2D, texture_id)); 378 #else
353 GLC(context, context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name)); 379 video_frame->set_texture_mailbox_sync_point(sync_point);
354 GLC(context, context->bindTexture(GL_TEXTURE_2D, 0)); 380 #endif
355 callback.Run(sync_point, lost_resource); 381
382 // Dropping the reference to VideoFrame here releases the texture back to the
383 // decoder.
356 } 384 }
357 385
358 // static 386 // static
359 void VideoResourceUpdater::RecycleResource( 387 void VideoResourceUpdater::RecycleResource(
360 base::WeakPtr<VideoResourceUpdater> updater, 388 base::WeakPtr<VideoResourceUpdater> updater,
361 ResourceProvider* resource_provider, 389 ResourceProvider* resource_provider,
362 RecycleResourceData data, 390 RecycleResourceData data,
363 unsigned sync_point, 391 unsigned sync_point,
364 bool lost_resource) { 392 bool lost_resource) {
365 WebKit::WebGraphicsContext3D* context = 393 WebKit::WebGraphicsContext3D* context =
(...skipping 24 matching lines...) Expand all
390 } 418 }
391 419
392 PlaneResource recycled_resource(data.resource_id, 420 PlaneResource recycled_resource(data.resource_id,
393 data.resource_size, 421 data.resource_size,
394 data.resource_format, 422 data.resource_format,
395 sync_point); 423 sync_point);
396 updater->recycled_resources_.push_back(recycled_resource); 424 updater->recycled_resources_.push_back(recycled_resource);
397 } 425 }
398 426
399 } // namespace cc 427 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698