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

Side by Side Diff: content/common/gpu/media/vt_video_decode_accelerator_mac.cc

Issue 1822173002: Mac: Decode hardware to 420 instead of 422 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix name Created 4 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <algorithm> 5 #include <algorithm>
6 6
7 #include <CoreVideo/CoreVideo.h> 7 #include <CoreVideo/CoreVideo.h>
8 #include <OpenGL/CGLIOSurface.h> 8 #include <OpenGL/CGLIOSurface.h>
9 #include <OpenGL/gl.h> 9 #include <OpenGL/gl.h>
10 #include <stddef.h> 10 #include <stddef.h>
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // Maximum number of frames to queue for reordering before we stop asking for 67 // Maximum number of frames to queue for reordering before we stop asking for
68 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the 68 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the
69 // reorder queue.) 69 // reorder queue.)
70 static const int kMaxReorderQueueSize = 16; 70 static const int kMaxReorderQueueSize = 16;
71 71
72 // Build an |image_config| dictionary for VideoToolbox initialization. 72 // Build an |image_config| dictionary for VideoToolbox initialization.
73 static base::ScopedCFTypeRef<CFMutableDictionaryRef> 73 static base::ScopedCFTypeRef<CFMutableDictionaryRef>
74 BuildImageConfig(CMVideoDimensions coded_dimensions) { 74 BuildImageConfig(CMVideoDimensions coded_dimensions) {
75 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config; 75 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config;
76 76
77 // 4:2:2 is used over the native 4:2:0 because only 4:2:2 can be directly 77 // Note that 4:2:0 textures cannot be used directly as RGBA in OpenGL, but are
78 // bound to a texture by CGLTexImageIOSurface2D(). 78 // lower power than 4:2:2 when composited directly by CoreAnimation.
79 int32_t pixel_format = kCVPixelFormatType_422YpCbCr8; 79 int32_t pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
80 #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i) 80 #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i)
81 base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format)); 81 base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format));
82 base::ScopedCFTypeRef<CFNumberRef> cf_width(CFINT(coded_dimensions.width)); 82 base::ScopedCFTypeRef<CFNumberRef> cf_width(CFINT(coded_dimensions.width));
83 base::ScopedCFTypeRef<CFNumberRef> cf_height(CFINT(coded_dimensions.height)); 83 base::ScopedCFTypeRef<CFNumberRef> cf_height(CFINT(coded_dimensions.height));
84 #undef CFINT 84 #undef CFINT
85 if (!cf_pixel_format.get() || !cf_width.get() || !cf_height.get()) 85 if (!cf_pixel_format.get() || !cf_width.get() || !cf_height.get())
86 return image_config; 86 return image_config;
87 87
88 image_config.reset( 88 image_config.reset(CFDictionaryCreateMutable(
89 CFDictionaryCreateMutable( 89 kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
90 kCFAllocatorDefault, 90 &kCFTypeDictionaryValueCallBacks));
91 4, // capacity
92 &kCFTypeDictionaryKeyCallBacks,
93 &kCFTypeDictionaryValueCallBacks));
94 if (!image_config.get()) 91 if (!image_config.get())
95 return image_config; 92 return image_config;
96 93
97 CFDictionarySetValue(image_config, kCVPixelBufferPixelFormatTypeKey, 94 CFDictionarySetValue(image_config, kCVPixelBufferPixelFormatTypeKey,
98 cf_pixel_format); 95 cf_pixel_format);
99 CFDictionarySetValue(image_config, kCVPixelBufferWidthKey, cf_width); 96 CFDictionarySetValue(image_config, kCVPixelBufferWidthKey, cf_width);
100 CFDictionarySetValue(image_config, kCVPixelBufferHeightKey, cf_height); 97 CFDictionarySetValue(image_config, kCVPixelBufferHeightKey, cf_height);
101 CFDictionarySetValue(image_config, kCVPixelBufferOpenGLCompatibilityKey,
102 kCFBooleanTrue);
103 98
104 return image_config; 99 return image_config;
105 } 100 }
106 101
107 // Create a VTDecompressionSession using the provided |pps| and |sps|. If 102 // Create a VTDecompressionSession using the provided |pps| and |sps|. If
108 // |require_hardware| is true, the session must uses real hardware decoding 103 // |require_hardware| is true, the session must uses real hardware decoding
109 // (as opposed to software decoding inside of VideoToolbox) to be considered 104 // (as opposed to software decoding inside of VideoToolbox) to be considered
110 // successful. 105 // successful.
111 // 106 //
112 // TODO(sandersd): Merge with ConfigureDecoder(), as the code is very similar. 107 // TODO(sandersd): Merge with ConfigureDecoder(), as the code is very similar.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 if (lhs->pic_order_cnt != rhs->pic_order_cnt) 276 if (lhs->pic_order_cnt != rhs->pic_order_cnt)
282 return lhs->pic_order_cnt > rhs->pic_order_cnt; 277 return lhs->pic_order_cnt > rhs->pic_order_cnt;
283 // If |pic_order_cnt| is the same, fall back on using the bitstream order. 278 // If |pic_order_cnt| is the same, fall back on using the bitstream order.
284 // TODO(sandersd): Assign a sequence number in Decode() and use that instead. 279 // TODO(sandersd): Assign a sequence number in Decode() and use that instead.
285 // TODO(sandersd): Using the sequence number, ensure that frames older than 280 // TODO(sandersd): Using the sequence number, ensure that frames older than
286 // |kMaxReorderQueueSize| are ordered first, regardless of |pic_order_cnt|. 281 // |kMaxReorderQueueSize| are ordered first, regardless of |pic_order_cnt|.
287 return lhs->bitstream_id > rhs->bitstream_id; 282 return lhs->bitstream_id > rhs->bitstream_id;
288 } 283 }
289 284
290 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator( 285 VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(
291 const base::Callback<bool(void)>& make_context_current, 286 const MakeContextCurrentCallback& make_context_current,
292 const base::Callback<void(uint32_t, uint32_t, scoped_refptr<gl::GLImage>)>& 287 const BindImageCallback& bind_image)
293 bind_image)
294 : make_context_current_(make_context_current), 288 : make_context_current_(make_context_current),
295 bind_image_(bind_image), 289 bind_image_(bind_image),
296 client_(nullptr), 290 client_(nullptr),
297 state_(STATE_DECODING), 291 state_(STATE_DECODING),
298 format_(nullptr), 292 format_(nullptr),
299 session_(nullptr), 293 session_(nullptr),
300 last_sps_id_(-1), 294 last_sps_id_(-1),
301 last_pps_id_(-1), 295 last_pps_id_(-1),
302 config_changed_(false), 296 config_changed_(false),
303 missing_idr_logged_(false), 297 missing_idr_logged_(false),
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); 1021 PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get();
1028 DCHECK(!picture_info->cv_image); 1022 DCHECK(!picture_info->cv_image);
1029 DCHECK(!picture_info->gl_image); 1023 DCHECK(!picture_info->gl_image);
1030 1024
1031 if (!make_context_current_.Run()) { 1025 if (!make_context_current_.Run()) {
1032 DLOG(ERROR) << "Failed to make GL context current"; 1026 DLOG(ERROR) << "Failed to make GL context current";
1033 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); 1027 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR);
1034 return false; 1028 return false;
1035 } 1029 }
1036 1030
1037 IOSurfaceRef surface = CVPixelBufferGetIOSurface(frame.image.get()); 1031 IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(frame.image.get());
1038 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile) 1032
1039 glEnable(GL_TEXTURE_RECTANGLE_ARB); 1033 scoped_refptr<gl::GLImageIOSurface> gl_image(
1040 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_RECTANGLE_ARB, 1034 new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT));
1041 picture_info->service_texture_id); 1035 if (!gl_image->Initialize(io_surface, gfx::GenericSharedMemoryId(),
1042 CGLContextObj cgl_context = 1036 gfx::BufferFormat::YUV_420_BIPLANAR)) {
1043 static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle()); 1037 NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE,
1044 CGLError status = CGLTexImageIOSurface2D( 1038 SFT_PLATFORM_ERROR);
1045 cgl_context, // ctx
1046 GL_TEXTURE_RECTANGLE_ARB, // target
1047 GL_RGB, // internal_format
1048 frame.coded_size.width(), // width
1049 frame.coded_size.height(), // height
1050 GL_YCBCR_422_APPLE, // format
1051 GL_UNSIGNED_SHORT_8_8_APPLE, // type
1052 surface, // io_surface
1053 0); // plane
1054 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGLCoreProfile)
1055 glDisable(GL_TEXTURE_RECTANGLE_ARB);
1056 if (status != kCGLNoError) {
1057 NOTIFY_STATUS("CGLTexImageIOSurface2D()", status, SFT_PLATFORM_ERROR);
1058 return false; 1039 return false;
1059 } 1040 }
1060 1041
1061 bool allow_overlay = false; 1042 // Mark that the image is not bound for sampling. 4:2:0 images need to
1062 scoped_refptr<gl::GLImageIOSurface> gl_image( 1043 // undergo a separate copy to be displayed.
1063 new gl::GLImageIOSurface(frame.coded_size, GL_BGRA_EXT));
1064 if (gl_image->Initialize(surface, gfx::GenericSharedMemoryId(),
1065 gfx::BufferFormat::BGRA_8888)) {
1066 allow_overlay = true;
1067 } else {
1068 gl_image = nullptr;
1069 }
1070 bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB, 1044 bind_image_.Run(picture_info->client_texture_id, GL_TEXTURE_RECTANGLE_ARB,
1071 gl_image); 1045 gl_image, false);
1072 1046
1073 // Assign the new image(s) to the the picture info. 1047 // Assign the new image(s) to the the picture info.
1074 picture_info->gl_image = gl_image; 1048 picture_info->gl_image = gl_image;
1075 picture_info->cv_image = frame.image; 1049 picture_info->cv_image = frame.image;
1076 available_picture_ids_.pop_back(); 1050 available_picture_ids_.pop_back();
1077 1051
1078 // TODO(sandersd): Currently, the size got from 1052 // TODO(sandersd): Currently, the size got from
1079 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to 1053 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to
1080 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in 1054 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in
1081 // resolution changed. We should find the correct API to get the real 1055 // resolution changed. We should find the correct API to get the real
1082 // coded size and fix it. 1056 // coded size and fix it.
1083 client_->PictureReady(media::Picture(picture_id, frame.bitstream_id, 1057 client_->PictureReady(media::Picture(picture_id, frame.bitstream_id,
1084 gfx::Rect(frame.coded_size), 1058 gfx::Rect(frame.coded_size), true));
1085 allow_overlay));
1086 return true; 1059 return true;
1087 } 1060 }
1088 1061
1089 void VTVideoDecodeAccelerator::NotifyError( 1062 void VTVideoDecodeAccelerator::NotifyError(
1090 Error vda_error_type, 1063 Error vda_error_type,
1091 VTVDASessionFailureType session_failure_type) { 1064 VTVDASessionFailureType session_failure_type) {
1092 DCHECK_LT(session_failure_type, SFT_MAX + 1); 1065 DCHECK_LT(session_failure_type, SFT_MAX + 1);
1093 if (!gpu_thread_checker_.CalledOnValidThread()) { 1066 if (!gpu_thread_checker_.CalledOnValidThread()) {
1094 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( 1067 gpu_task_runner_->PostTask(FROM_HERE, base::Bind(
1095 &VTVideoDecodeAccelerator::NotifyError, weak_this_, vda_error_type, 1068 &VTVideoDecodeAccelerator::NotifyError, weak_this_, vda_error_type,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 SupportedProfile profile; 1130 SupportedProfile profile;
1158 profile.profile = supported_profile; 1131 profile.profile = supported_profile;
1159 profile.min_resolution.SetSize(16, 16); 1132 profile.min_resolution.SetSize(16, 16);
1160 profile.max_resolution.SetSize(4096, 2160); 1133 profile.max_resolution.SetSize(4096, 2160);
1161 profiles.push_back(profile); 1134 profiles.push_back(profile);
1162 } 1135 }
1163 return profiles; 1136 return profiles;
1164 } 1137 }
1165 1138
1166 } // namespace content 1139 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/vt_video_decode_accelerator_mac.h ('k') | media/video/video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698