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

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: 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"
(...skipping 16 matching lines...) Expand all
27 : resource_provider_(resource_provider) { 27 : resource_provider_(resource_provider) {
28 } 28 }
29 29
30 VideoResourceUpdater::~VideoResourceUpdater() { 30 VideoResourceUpdater::~VideoResourceUpdater() {
31 while (!recycled_resources_.empty()) { 31 while (!recycled_resources_.empty()) {
32 resource_provider_->DeleteResource(recycled_resources_.back().resource_id); 32 resource_provider_->DeleteResource(recycled_resources_.back().resource_id);
33 recycled_resources_.pop_back(); 33 recycled_resources_.pop_back();
34 } 34 }
35 } 35 }
36 36
37 VideoFrameExternalResources VideoResourceUpdater::
38 CreateExternalResourcesFromVideoFrame(
39 const scoped_refptr<media::VideoFrame>& video_frame) {
40 if (!VerifyFrame(video_frame))
41 return VideoFrameExternalResources();
42
43 if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE)
44 return CreateForHardwarePlanes(video_frame);
45 else
46 return CreateForSoftwarePlanes(video_frame);
47 }
48
37 bool VideoResourceUpdater::VerifyFrame( 49 bool VideoResourceUpdater::VerifyFrame(
38 const scoped_refptr<media::VideoFrame>& video_frame) { 50 const scoped_refptr<media::VideoFrame>& video_frame) {
39 // If these fail, we'll have to add logic that handles offset bitmap/texture 51 // 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 52 // UVs. For now, just expect (0, 0) offset, since all our decoders so far
41 // don't offset. 53 // don't offset.
42 DCHECK_EQ(video_frame->visible_rect().x(), 0); 54 DCHECK_EQ(video_frame->visible_rect().x(), 0);
43 DCHECK_EQ(video_frame->visible_rect().y(), 0); 55 DCHECK_EQ(video_frame->visible_rect().y(), 0);
44 56
45 switch (video_frame->format()) { 57 switch (video_frame->format()) {
46 // Acceptable inputs. 58 // Acceptable inputs.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 NOTREACHED(); 102 NOTREACHED();
91 } 103 }
92 } 104 }
93 105
94 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); 106 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat));
95 return coded_size; 107 return coded_size;
96 } 108 }
97 109
98 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 110 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
99 const scoped_refptr<media::VideoFrame>& video_frame) { 111 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(); 112 media::VideoFrame::Format input_frame_format = video_frame->format();
104 113
105 #if defined(GOOGLE_TV) 114 #if defined(GOOGLE_TV)
106 if (input_frame_format == media::VideoFrame::HOLE) { 115 if (input_frame_format == media::VideoFrame::HOLE) {
107 VideoFrameExternalResources external_resources; 116 VideoFrameExternalResources external_resources;
108 external_resources.type = VideoFrameExternalResources::HOLE; 117 external_resources.type = VideoFrameExternalResources::HOLE;
109 return external_resources; 118 return external_resources;
110 } 119 }
111 #endif 120 #endif
112 121
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 TextureMailbox(mailbox, 291 TextureMailbox(mailbox,
283 callback_to_free_resource, 292 callback_to_free_resource,
284 plane_resources[i].sync_point)); 293 plane_resources[i].sync_point));
285 } 294 }
286 295
287 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; 296 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE;
288 return external_resources; 297 return external_resources;
289 } 298 }
290 299
291 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( 300 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
292 const scoped_refptr<media::VideoFrame>& video_frame, 301 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(); 302 media::VideoFrame::Format frame_format = video_frame->format();
298 303
299 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); 304 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE);
300 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) 305 if (frame_format != media::VideoFrame::NATIVE_TEXTURE)
301 return VideoFrameExternalResources(); 306 return VideoFrameExternalResources();
302 307
303 WebKit::WebGraphicsContext3D* context = 308 WebKit::WebGraphicsContext3D* context =
304 resource_provider_->GraphicsContext3D(); 309 resource_provider_->GraphicsContext3D();
305 if (!context) 310 if (!context)
306 return VideoFrameExternalResources(); 311 return VideoFrameExternalResources();
307 312
308 VideoFrameExternalResources external_resources; 313 VideoFrameExternalResources external_resources;
309 switch (video_frame->texture_target()) { 314 switch (video_frame->texture_target()) {
310 case GL_TEXTURE_2D: 315 case GL_TEXTURE_2D:
311 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; 316 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE;
312 break; 317 break;
313 case GL_TEXTURE_EXTERNAL_OES: 318 case GL_TEXTURE_EXTERNAL_OES:
314 external_resources.type = 319 external_resources.type =
315 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; 320 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE;
316 break; 321 break;
317 case GL_TEXTURE_RECTANGLE_ARB: 322 case GL_TEXTURE_RECTANGLE_ARB:
318 external_resources.type = VideoFrameExternalResources::IO_SURFACE; 323 external_resources.type = VideoFrameExternalResources::IO_SURFACE;
319 break; 324 break;
320 default: 325 default:
321 NOTREACHED(); 326 NOTREACHED();
322 return VideoFrameExternalResources(); 327 return VideoFrameExternalResources();
323 } 328 }
324 329
325 gpu::Mailbox mailbox; 330 // Hold a reference to the VideoFrame in the callback, so the frame stays
326 GLC(context, context->genMailboxCHROMIUM(mailbox.name)); 331 // alive while the texture is in use. As long as the frame is alive, the
327 GLC(context, context->bindTexture(GL_TEXTURE_2D, video_frame->texture_id())); 332 // texture inside it will not be reused by the decoder.
328 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
329 GLC(context, context->bindTexture(GL_TEXTURE_2D, 0));
330
331 TextureMailbox::ReleaseCallback callback_to_return_resource = 333 TextureMailbox::ReleaseCallback callback_to_return_resource =
332 base::Bind(&ReturnTexture, 334 base::Bind(&ReturnTexture,
333 base::Unretained(resource_provider_), 335 base::Unretained(resource_provider_),
334 release_callback, 336 video_frame);
335 video_frame->texture_id(),
336 mailbox);
337 external_resources.mailboxes.push_back( 337 external_resources.mailboxes.push_back(
338 TextureMailbox(mailbox, callback_to_return_resource)); 338 TextureMailbox(video_frame->texture_mailbox(),
339 callback_to_return_resource));
339 return external_resources; 340 return external_resources;
340 } 341 }
341 342
342 // static 343 // static
343 void VideoResourceUpdater::ReturnTexture( 344 void VideoResourceUpdater::ReturnTexture(
344 ResourceProvider* resource_provider, 345 ResourceProvider* resource_provider,
345 TextureMailbox::ReleaseCallback callback, 346 scoped_refptr<media::VideoFrame> video_frame,
346 unsigned texture_id,
347 gpu::Mailbox mailbox,
348 unsigned sync_point, 347 unsigned sync_point,
349 bool lost_resource) { 348 bool lost_resource) {
350 WebKit::WebGraphicsContext3D* context = 349 if (sync_point) {
351 resource_provider->GraphicsContext3D(); 350 WebKit::WebGraphicsContext3D* context =
352 GLC(context, context->bindTexture(GL_TEXTURE_2D, texture_id)); 351 resource_provider->GraphicsContext3D();
353 GLC(context, context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name)); 352 GLC(context, context->waitSyncPoint(sync_point));
piman 2013/04/11 22:57:58 You need to (shallow) flush here to ensure the vid
354 GLC(context, context->bindTexture(GL_TEXTURE_2D, 0)); 353 }
355 callback.Run(sync_point, lost_resource); 354
355 // Dropping the reference to VideoFrame here releases the texture back to the
356 // decoder.
356 } 357 }
357 358
358 // static 359 // static
359 void VideoResourceUpdater::RecycleResource( 360 void VideoResourceUpdater::RecycleResource(
360 base::WeakPtr<VideoResourceUpdater> updater, 361 base::WeakPtr<VideoResourceUpdater> updater,
361 ResourceProvider* resource_provider, 362 ResourceProvider* resource_provider,
362 RecycleResourceData data, 363 RecycleResourceData data,
363 unsigned sync_point, 364 unsigned sync_point,
364 bool lost_resource) { 365 bool lost_resource) {
365 WebKit::WebGraphicsContext3D* context = 366 WebKit::WebGraphicsContext3D* context =
(...skipping 24 matching lines...) Expand all
390 } 391 }
391 392
392 PlaneResource recycled_resource(data.resource_id, 393 PlaneResource recycled_resource(data.resource_id,
393 data.resource_size, 394 data.resource_size,
394 data.resource_format, 395 data.resource_format,
395 sync_point); 396 sync_point);
396 updater->recycled_resources_.push_back(recycled_resource); 397 updater->recycled_resources_.push_back(recycled_resource);
397 } 398 }
398 399
399 } // namespace cc 400 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698