Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / media / base / mac / videotoolbox_glue.mm
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.
4
5 #include "media/base/mac/videotoolbox_glue.h"
6
7 #include <dlfcn.h>
8 #import <Foundation/Foundation.h>
9
10 #include "base/lazy_instance.h"
11 #include "base/memory/scoped_ptr.h"
12
13 // This class stores VideoToolbox library symbol pointers.
14 struct VideoToolboxGlue::Library {
15   typedef OSStatus (*VTCompressionSessionCreateMethod)(
16       CFAllocatorRef,
17       int32_t,
18       int32_t,
19       CoreMediaGlue::CMVideoCodecType,
20       CFDictionaryRef,
21       CFDictionaryRef,
22       CFAllocatorRef,
23       VTCompressionOutputCallback,
24       void*,
25       VTCompressionSessionRef*);
26   typedef OSStatus (*VTCompressionSessionEncodeFrameMethod)(
27       VTCompressionSessionRef,
28       CVImageBufferRef,
29       CoreMediaGlue::CMTime,
30       CoreMediaGlue::CMTime,
31       CFDictionaryRef,
32       void*,
33       VTEncodeInfoFlags*);
34   typedef CVPixelBufferPoolRef (*VTCompressionSessionGetPixelBufferPoolMethod)(
35       VTCompressionSessionRef);
36   typedef void (*VTCompressionSessionInvalidateMethod)(VTCompressionSessionRef);
37   typedef OSStatus (*VTSessionSetPropertyMethod)(VTSessionRef,
38                                                  CFStringRef,
39                                                  CFTypeRef);
40
41   VTCompressionSessionCreateMethod VTCompressionSessionCreate;
42   VTCompressionSessionEncodeFrameMethod VTCompressionSessionEncodeFrame;
43   VTCompressionSessionGetPixelBufferPoolMethod
44       VTCompressionSessionGetPixelBufferPool;
45   VTCompressionSessionInvalidateMethod VTCompressionSessionInvalidate;
46   VTSessionSetPropertyMethod VTSessionSetProperty;
47
48   CFStringRef* kVTCompressionPropertyKey_AllowFrameReordering;
49   CFStringRef* kVTCompressionPropertyKey_AverageBitRate;
50   CFStringRef* kVTCompressionPropertyKey_ColorPrimaries;
51   CFStringRef* kVTCompressionPropertyKey_ExpectedFrameRate;
52   CFStringRef* kVTCompressionPropertyKey_MaxKeyFrameInterval;
53   CFStringRef* kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration;
54   CFStringRef* kVTCompressionPropertyKey_ProfileLevel;
55   CFStringRef* kVTCompressionPropertyKey_RealTime;
56   CFStringRef* kVTCompressionPropertyKey_TransferFunction;
57   CFStringRef* kVTCompressionPropertyKey_YCbCrMatrix;
58   CFStringRef* kVTEncodeFrameOptionKey_ForceKeyFrame;
59   CFStringRef* kVTProfileLevel_H264_Baseline_AutoLevel;
60   CFStringRef* kVTProfileLevel_H264_Main_AutoLevel;
61   CFStringRef* kVTProfileLevel_H264_Extended_AutoLevel;
62   CFStringRef* kVTProfileLevel_H264_High_AutoLevel;
63   CFStringRef*
64       kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder;
65 };
66
67 // Lazy-instance responsible for loading VideoToolbox.
68 class VideoToolboxGlue::Loader {
69  public:
70   Loader() {
71     NSBundle* bundle = [NSBundle
72         bundleWithPath:@"/System/Library/Frameworks/VideoToolbox.framework"];
73     const char* path = [[bundle executablePath] fileSystemRepresentation];
74     if (!path)
75       return;
76
77     handle_ = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
78     if (!handle_)
79       return;
80
81 #define LOAD_SYMBOL(SYMBOL)                                             \
82   if (!LoadSymbol(#SYMBOL, reinterpret_cast<void**>(&library_.SYMBOL))) \
83     return;
84
85     LOAD_SYMBOL(VTCompressionSessionCreate)
86     LOAD_SYMBOL(VTCompressionSessionEncodeFrame)
87     LOAD_SYMBOL(VTCompressionSessionGetPixelBufferPool)
88     LOAD_SYMBOL(VTCompressionSessionInvalidate)
89     LOAD_SYMBOL(VTSessionSetProperty)
90
91     LOAD_SYMBOL(kVTCompressionPropertyKey_AllowFrameReordering)
92     LOAD_SYMBOL(kVTCompressionPropertyKey_AverageBitRate)
93     LOAD_SYMBOL(kVTCompressionPropertyKey_ColorPrimaries)
94     LOAD_SYMBOL(kVTCompressionPropertyKey_ExpectedFrameRate)
95     LOAD_SYMBOL(kVTCompressionPropertyKey_MaxKeyFrameInterval)
96     LOAD_SYMBOL(kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration)
97     LOAD_SYMBOL(kVTCompressionPropertyKey_ProfileLevel)
98     LOAD_SYMBOL(kVTCompressionPropertyKey_RealTime)
99     LOAD_SYMBOL(kVTCompressionPropertyKey_TransferFunction)
100     LOAD_SYMBOL(kVTCompressionPropertyKey_YCbCrMatrix)
101     LOAD_SYMBOL(kVTEncodeFrameOptionKey_ForceKeyFrame);
102     LOAD_SYMBOL(kVTProfileLevel_H264_Baseline_AutoLevel)
103     LOAD_SYMBOL(kVTProfileLevel_H264_Main_AutoLevel)
104     LOAD_SYMBOL(kVTProfileLevel_H264_Extended_AutoLevel)
105     LOAD_SYMBOL(kVTProfileLevel_H264_High_AutoLevel)
106     LOAD_SYMBOL(
107         kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder)
108
109 #undef LOAD_SYMBOL
110
111     glue_.library_ = &library_;
112   }
113
114   const VideoToolboxGlue* glue() const {
115     return (glue_.library_) ? &glue_ : NULL;
116   }
117
118  private:
119   bool LoadSymbol(const char* name, void** symbol_out) {
120     *symbol_out = dlsym(handle_, name);
121     return *symbol_out != NULL;
122   }
123
124   Library library_;
125   VideoToolboxGlue glue_;
126   void* handle_;
127
128   DISALLOW_COPY_AND_ASSIGN(Loader);
129 };
130
131 static base::LazyInstance<VideoToolboxGlue::Loader> g_videotoolbox_loader =
132     LAZY_INSTANCE_INITIALIZER;
133
134 // static
135 const VideoToolboxGlue* VideoToolboxGlue::Get() {
136   return g_videotoolbox_loader.Get().glue();
137 }
138
139 VideoToolboxGlue::VideoToolboxGlue() : library_(NULL) {
140 }
141
142 OSStatus VideoToolboxGlue::VTCompressionSessionCreate(
143     CFAllocatorRef allocator,
144     int32_t width,
145     int32_t height,
146     CoreMediaGlue::CMVideoCodecType codecType,
147     CFDictionaryRef encoderSpecification,
148     CFDictionaryRef sourceImageBufferAttributes,
149     CFAllocatorRef compressedDataAllocator,
150     VTCompressionOutputCallback outputCallback,
151     void* outputCallbackRefCon,
152     VTCompressionSessionRef* compressionSessionOut) const {
153   return library_->VTCompressionSessionCreate(allocator,
154                                               width,
155                                               height,
156                                               codecType,
157                                               encoderSpecification,
158                                               sourceImageBufferAttributes,
159                                               compressedDataAllocator,
160                                               outputCallback,
161                                               outputCallbackRefCon,
162                                               compressionSessionOut);
163 }
164
165 OSStatus VideoToolboxGlue::VTCompressionSessionEncodeFrame(
166     VTCompressionSessionRef session,
167     CVImageBufferRef imageBuffer,
168     CoreMediaGlue::CMTime presentationTimeStamp,
169     CoreMediaGlue::CMTime duration,
170     CFDictionaryRef frameProperties,
171     void* sourceFrameRefCon,
172     VTEncodeInfoFlags* infoFlagsOut) const {
173   return library_->VTCompressionSessionEncodeFrame(session,
174                                                    imageBuffer,
175                                                    presentationTimeStamp,
176                                                    duration,
177                                                    frameProperties,
178                                                    sourceFrameRefCon,
179                                                    infoFlagsOut);
180 }
181
182 CVPixelBufferPoolRef VideoToolboxGlue::VTCompressionSessionGetPixelBufferPool(
183     VTCompressionSessionRef session) const {
184   return library_->VTCompressionSessionGetPixelBufferPool(session);
185 }
186
187 void VideoToolboxGlue::VTCompressionSessionInvalidate(
188     VTCompressionSessionRef session) const {
189   library_->VTCompressionSessionInvalidate(session);
190 }
191
192 OSStatus VideoToolboxGlue::VTSessionSetProperty(VTSessionRef session,
193                                                 CFStringRef propertyKey,
194                                                 CFTypeRef propertyValue) const {
195   return library_->VTSessionSetProperty(session, propertyKey, propertyValue);
196 }
197
198 #define KEY_ACCESSOR(KEY) \
199   CFStringRef VideoToolboxGlue::KEY() const { return *library_->KEY; }
200
201 KEY_ACCESSOR(kVTCompressionPropertyKey_AllowFrameReordering)
202 KEY_ACCESSOR(kVTCompressionPropertyKey_AverageBitRate)
203 KEY_ACCESSOR(kVTCompressionPropertyKey_ColorPrimaries)
204 KEY_ACCESSOR(kVTCompressionPropertyKey_ExpectedFrameRate)
205 KEY_ACCESSOR(kVTCompressionPropertyKey_MaxKeyFrameInterval)
206 KEY_ACCESSOR(kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration)
207 KEY_ACCESSOR(kVTCompressionPropertyKey_ProfileLevel)
208 KEY_ACCESSOR(kVTCompressionPropertyKey_RealTime)
209 KEY_ACCESSOR(kVTCompressionPropertyKey_TransferFunction)
210 KEY_ACCESSOR(kVTCompressionPropertyKey_YCbCrMatrix)
211 KEY_ACCESSOR(kVTEncodeFrameOptionKey_ForceKeyFrame)
212 KEY_ACCESSOR(kVTProfileLevel_H264_Baseline_AutoLevel)
213 KEY_ACCESSOR(kVTProfileLevel_H264_Main_AutoLevel)
214 KEY_ACCESSOR(kVTProfileLevel_H264_Extended_AutoLevel)
215 KEY_ACCESSOR(kVTProfileLevel_H264_High_AutoLevel)
216 KEY_ACCESSOR(kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder)
217
218 #undef KEY_ACCESSOR