| Index: content/common/gpu/media/vt_video_decode_accelerator_mac.cc
|
| diff --git a/content/common/gpu/media/vt_video_decode_accelerator_mac.cc b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
|
| index 50e144b592eb2bdeec06c9baba59155553fd2de8..e4ea5cdf4fdbbf35e0e3c8fe1f6ae2b2c6c8949c 100644
|
| --- a/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
|
| +++ b/content/common/gpu/media/vt_video_decode_accelerator_mac.cc
|
| @@ -74,9 +74,9 @@
|
| BuildImageConfig(CMVideoDimensions coded_dimensions) {
|
| base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config;
|
|
|
| - // Note that 4:2:0 textures cannot be used directly as RGBA in OpenGL, but are
|
| - // lower power than 4:2:2 when composited directly by CoreAnimation.
|
| - int32_t pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
|
| + // 4:2:2 is used over the native 4:2:0 because only 4:2:2 can be directly
|
| + // bound to a texture by CGLTexImageIOSurface2D().
|
| + int32_t pixel_format = kCVPixelFormatType_422YpCbCr8;
|
| #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i)
|
| base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format));
|
| base::ScopedCFTypeRef<CFNumberRef> cf_width(CFINT(coded_dimensions.width));
|
| @@ -85,9 +85,12 @@
|
| if (!cf_pixel_format.get() || !cf_width.get() || !cf_height.get())
|
| return image_config;
|
|
|
| - image_config.reset(CFDictionaryCreateMutable(
|
| - kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
|
| - &kCFTypeDictionaryValueCallBacks));
|
| + image_config.reset(
|
| + CFDictionaryCreateMutable(
|
| + kCFAllocatorDefault,
|
| + 4, // capacity
|
| + &kCFTypeDictionaryKeyCallBacks,
|
| + &kCFTypeDictionaryValueCallBacks));
|
| if (!image_config.get())
|
| return image_config;
|
|
|
| @@ -95,6 +98,8 @@
|
| cf_pixel_format);
|
| CFDictionarySetValue(image_config, kCVPixelBufferWidthKey, cf_width);
|
| CFDictionarySetValue(image_config, kCVPixelBufferHeightKey, cf_height);
|
| + CFDictionarySetValue(image_config, kCVPixelBufferOpenGLCompatibilityKey,
|
| + kCFBooleanTrue);
|
|
|
| return image_config;
|
| }
|
| @@ -283,8 +288,9 @@
|
| }
|
|
|
| VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(
|
| - const MakeContextCurrentCallback& make_context_current,
|
| - const BindImageCallback& bind_image)
|
| + const base::Callback<bool(void)>& make_context_current,
|
| + const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>&
|
| + bind_image)
|
| : make_context_current_(make_context_current),
|
| bind_image_(bind_image),
|
| client_(nullptr),
|
| @@ -1028,21 +1034,41 @@
|
| return false;
|
| }
|
|
|
| - IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(frame.image.get());
|
| -
|
| + IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame.image.get());
|
| + if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile)
|
| + glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
| + gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_RECTANGLE_ARB,
|
| + picture_info->service_texture_id);
|
| + CGLContextObj cgl_context =
|
| + static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle());
|
| + CGLError status = CGLTexImageIOSurface2D(
|
| + cgl_context, // ctx
|
| + GL_TEXTURE_RECTANGLE_ARB, // target
|
| + GL_RGB, // internal_format
|
| + frame.coded_size.width(), // width
|
| + frame.coded_size.height(), // height
|
| + GL_YCBCR_422_APPLE, // format
|
| + GL_UNSIGNED_SHORT_8_8_APPLE, // type
|
| + surface, // io_surface
|
| + 0); // plane
|
| + if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile)
|
| + glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
| + if (status != kCGLNoError) {
|
| + NOTIFY_STATUS("CGLTexImageIOSurface2D()", status, SFT_PLATFORM_ERROR);
|
| + return false;
|
| + }
|
| +
|
| + bool allow_overlay = false;
|
| scoped_refptr<gl::GLImageIOSurface> gl_image(
|
| new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT));
|
| - if (!gl_image->Initialize(io_surface, gfx::GenericSharedMemoryId(),
|
| - gfx::BufferFormat::YUV_420_BIPLANAR)) {
|
| - NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE,
|
| - SFT_PLATFORM_ERROR);
|
| - return false;
|
| - }
|
| -
|
| - // Mark that the image is not bound for sampling. 4:2:0 images need to
|
| - // undergo a separate copy to be displayed.
|
| + if (gl_image->Initialize(surface, gfx::GenericSharedMemoryId(),
|
| + gfx::BufferFormat::BGRA_8888)) {
|
| + allow_overlay = true;
|
| + } else {
|
| + gl_image = nullptr;
|
| + }
|
| bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB,
|
| - gl_image, false);
|
| + gl_image);
|
|
|
| // Assign the new image(s) to the the picture info.
|
| picture_info->gl_image = gl_image;
|
| @@ -1055,7 +1081,8 @@
|
| // resolution changed. We should find the correct API to get the real
|
| // coded size and fix it.
|
| client_->PictureReady(media::Picture(picture_id, frame.bitstream_id,
|
| - gfx::Rect(frame.coded_size), true));
|
| + gfx::Rect(frame.coded_size),
|
| + allow_overlay));
|
| return true;
|
| }
|
|
|
|
|