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
3 // found in the LICENSE file.
5 #include "media/base/mac/videotoolbox_glue.h"
8 #import <Foundation/Foundation.h>
10 #include "base/lazy_instance.h"
11 #include "base/memory/scoped_ptr.h"
13 // This class stores VideoToolbox library symbol pointers.
14 struct VideoToolboxGlue::Library {
15 typedef OSStatus (*VTCompressionSessionCreateMethod)(
19 CoreMediaGlue::CMVideoCodecType,
23 VTCompressionOutputCallback,
25 VTCompressionSessionRef*);
26 typedef OSStatus (*VTCompressionSessionEncodeFrameMethod)(
27 VTCompressionSessionRef,
29 CoreMediaGlue::CMTime,
30 CoreMediaGlue::CMTime,
34 typedef CVPixelBufferPoolRef (*VTCompressionSessionGetPixelBufferPoolMethod)(
35 VTCompressionSessionRef);
36 typedef void (*VTCompressionSessionInvalidateMethod)(VTCompressionSessionRef);
37 typedef OSStatus (*VTCompressionSessionCompleteFramesMethod)(
38 VTCompressionSessionRef,
39 CoreMediaGlue::CMTime);
40 typedef OSStatus (*VTSessionSetPropertyMethod)(VTSessionRef,
44 VTCompressionSessionCreateMethod VTCompressionSessionCreate;
45 VTCompressionSessionEncodeFrameMethod VTCompressionSessionEncodeFrame;
46 VTCompressionSessionGetPixelBufferPoolMethod
47 VTCompressionSessionGetPixelBufferPool;
48 VTCompressionSessionInvalidateMethod VTCompressionSessionInvalidate;
49 VTCompressionSessionCompleteFramesMethod VTCompressionSessionCompleteFrames;
50 VTSessionSetPropertyMethod VTSessionSetProperty;
52 CFStringRef* kVTCompressionPropertyKey_AllowFrameReordering;
53 CFStringRef* kVTCompressionPropertyKey_AverageBitRate;
54 CFStringRef* kVTCompressionPropertyKey_ColorPrimaries;
55 CFStringRef* kVTCompressionPropertyKey_ExpectedFrameRate;
56 CFStringRef* kVTCompressionPropertyKey_MaxFrameDelayCount;
57 CFStringRef* kVTCompressionPropertyKey_MaxKeyFrameInterval;
58 CFStringRef* kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration;
59 CFStringRef* kVTCompressionPropertyKey_ProfileLevel;
60 CFStringRef* kVTCompressionPropertyKey_RealTime;
61 CFStringRef* kVTCompressionPropertyKey_TransferFunction;
62 CFStringRef* kVTCompressionPropertyKey_YCbCrMatrix;
63 CFStringRef* kVTEncodeFrameOptionKey_ForceKeyFrame;
64 CFStringRef* kVTProfileLevel_H264_Baseline_AutoLevel;
65 CFStringRef* kVTProfileLevel_H264_Main_AutoLevel;
66 CFStringRef* kVTProfileLevel_H264_Extended_AutoLevel;
67 CFStringRef* kVTProfileLevel_H264_High_AutoLevel;
69 kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder;
72 // Lazy-instance responsible for loading VideoToolbox.
73 class VideoToolboxGlue::Loader {
76 NSBundle* bundle = [NSBundle
77 bundleWithPath:@"/System/Library/Frameworks/VideoToolbox.framework"];
78 const char* path = [[bundle executablePath] fileSystemRepresentation];
82 handle_ = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
86 #define LOAD_SYMBOL(SYMBOL) \
87 if (!LoadSymbol(#SYMBOL, reinterpret_cast<void**>(&library_.SYMBOL))) \
90 LOAD_SYMBOL(VTCompressionSessionCreate)
91 LOAD_SYMBOL(VTCompressionSessionEncodeFrame)
92 LOAD_SYMBOL(VTCompressionSessionGetPixelBufferPool)
93 LOAD_SYMBOL(VTCompressionSessionInvalidate)
94 LOAD_SYMBOL(VTCompressionSessionCompleteFrames)
95 LOAD_SYMBOL(VTSessionSetProperty)
97 LOAD_SYMBOL(kVTCompressionPropertyKey_AllowFrameReordering)
98 LOAD_SYMBOL(kVTCompressionPropertyKey_AverageBitRate)
99 LOAD_SYMBOL(kVTCompressionPropertyKey_ColorPrimaries)
100 LOAD_SYMBOL(kVTCompressionPropertyKey_ExpectedFrameRate)
101 LOAD_SYMBOL(kVTCompressionPropertyKey_MaxFrameDelayCount)
102 LOAD_SYMBOL(kVTCompressionPropertyKey_MaxKeyFrameInterval)
103 LOAD_SYMBOL(kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration)
104 LOAD_SYMBOL(kVTCompressionPropertyKey_ProfileLevel)
105 LOAD_SYMBOL(kVTCompressionPropertyKey_RealTime)
106 LOAD_SYMBOL(kVTCompressionPropertyKey_TransferFunction)
107 LOAD_SYMBOL(kVTCompressionPropertyKey_YCbCrMatrix)
108 LOAD_SYMBOL(kVTEncodeFrameOptionKey_ForceKeyFrame);
109 LOAD_SYMBOL(kVTProfileLevel_H264_Baseline_AutoLevel)
110 LOAD_SYMBOL(kVTProfileLevel_H264_Main_AutoLevel)
111 LOAD_SYMBOL(kVTProfileLevel_H264_Extended_AutoLevel)
112 LOAD_SYMBOL(kVTProfileLevel_H264_High_AutoLevel)
114 kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder)
118 glue_.library_ = &library_;
121 const VideoToolboxGlue* glue() const {
122 return (glue_.library_) ? &glue_ : NULL;
126 bool LoadSymbol(const char* name, void** symbol_out) {
127 *symbol_out = dlsym(handle_, name);
128 return *symbol_out != NULL;
132 VideoToolboxGlue glue_;
135 DISALLOW_COPY_AND_ASSIGN(Loader);
138 static base::LazyInstance<VideoToolboxGlue::Loader> g_videotoolbox_loader =
139 LAZY_INSTANCE_INITIALIZER;
142 const VideoToolboxGlue* VideoToolboxGlue::Get() {
143 return g_videotoolbox_loader.Get().glue();
146 VideoToolboxGlue::VideoToolboxGlue() : library_(NULL) {
149 OSStatus VideoToolboxGlue::VTCompressionSessionCreate(
150 CFAllocatorRef allocator,
153 CoreMediaGlue::CMVideoCodecType codecType,
154 CFDictionaryRef encoderSpecification,
155 CFDictionaryRef sourceImageBufferAttributes,
156 CFAllocatorRef compressedDataAllocator,
157 VTCompressionOutputCallback outputCallback,
158 void* outputCallbackRefCon,
159 VTCompressionSessionRef* compressionSessionOut) const {
160 return library_->VTCompressionSessionCreate(allocator,
164 encoderSpecification,
165 sourceImageBufferAttributes,
166 compressedDataAllocator,
168 outputCallbackRefCon,
169 compressionSessionOut);
172 OSStatus VideoToolboxGlue::VTCompressionSessionEncodeFrame(
173 VTCompressionSessionRef session,
174 CVImageBufferRef imageBuffer,
175 CoreMediaGlue::CMTime presentationTimeStamp,
176 CoreMediaGlue::CMTime duration,
177 CFDictionaryRef frameProperties,
178 void* sourceFrameRefCon,
179 VTEncodeInfoFlags* infoFlagsOut) const {
180 return library_->VTCompressionSessionEncodeFrame(session,
182 presentationTimeStamp,
189 CVPixelBufferPoolRef VideoToolboxGlue::VTCompressionSessionGetPixelBufferPool(
190 VTCompressionSessionRef session) const {
191 return library_->VTCompressionSessionGetPixelBufferPool(session);
194 void VideoToolboxGlue::VTCompressionSessionInvalidate(
195 VTCompressionSessionRef session) const {
196 library_->VTCompressionSessionInvalidate(session);
199 OSStatus VideoToolboxGlue::VTCompressionSessionCompleteFrames(
200 VTCompressionSessionRef session,
201 CoreMediaGlue::CMTime completeUntilPresentationTimeStamp) const {
202 return library_->VTCompressionSessionCompleteFrames(
203 session, completeUntilPresentationTimeStamp);
206 OSStatus VideoToolboxGlue::VTSessionSetProperty(VTSessionRef session,
207 CFStringRef propertyKey,
208 CFTypeRef propertyValue) const {
209 return library_->VTSessionSetProperty(session, propertyKey, propertyValue);
212 #define KEY_ACCESSOR(KEY) \
213 CFStringRef VideoToolboxGlue::KEY() const { return *library_->KEY; }
215 KEY_ACCESSOR(kVTCompressionPropertyKey_AllowFrameReordering)
216 KEY_ACCESSOR(kVTCompressionPropertyKey_AverageBitRate)
217 KEY_ACCESSOR(kVTCompressionPropertyKey_ColorPrimaries)
218 KEY_ACCESSOR(kVTCompressionPropertyKey_ExpectedFrameRate)
219 KEY_ACCESSOR(kVTCompressionPropertyKey_MaxFrameDelayCount)
220 KEY_ACCESSOR(kVTCompressionPropertyKey_MaxKeyFrameInterval)
221 KEY_ACCESSOR(kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration)
222 KEY_ACCESSOR(kVTCompressionPropertyKey_ProfileLevel)
223 KEY_ACCESSOR(kVTCompressionPropertyKey_RealTime)
224 KEY_ACCESSOR(kVTCompressionPropertyKey_TransferFunction)
225 KEY_ACCESSOR(kVTCompressionPropertyKey_YCbCrMatrix)
226 KEY_ACCESSOR(kVTEncodeFrameOptionKey_ForceKeyFrame)
227 KEY_ACCESSOR(kVTProfileLevel_H264_Baseline_AutoLevel)
228 KEY_ACCESSOR(kVTProfileLevel_H264_Main_AutoLevel)
229 KEY_ACCESSOR(kVTProfileLevel_H264_Extended_AutoLevel)
230 KEY_ACCESSOR(kVTProfileLevel_H264_High_AutoLevel)
231 KEY_ACCESSOR(kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder)