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. 14struct 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. 68class 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 131static base::LazyInstance<VideoToolboxGlue::Loader> g_videotoolbox_loader = 132 LAZY_INSTANCE_INITIALIZER; 133 134// static 135const VideoToolboxGlue* VideoToolboxGlue::Get() { 136 return g_videotoolbox_loader.Get().glue(); 137} 138 139VideoToolboxGlue::VideoToolboxGlue() : library_(NULL) { 140} 141 142OSStatus 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 165OSStatus 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 182CVPixelBufferPoolRef VideoToolboxGlue::VTCompressionSessionGetPixelBufferPool( 183 VTCompressionSessionRef session) const { 184 return library_->VTCompressionSessionGetPixelBufferPool(session); 185} 186 187void VideoToolboxGlue::VTCompressionSessionInvalidate( 188 VTCompressionSessionRef session) const { 189 library_->VTCompressionSessionInvalidate(session); 190} 191 192OSStatus 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 201KEY_ACCESSOR(kVTCompressionPropertyKey_AllowFrameReordering) 202KEY_ACCESSOR(kVTCompressionPropertyKey_AverageBitRate) 203KEY_ACCESSOR(kVTCompressionPropertyKey_ColorPrimaries) 204KEY_ACCESSOR(kVTCompressionPropertyKey_ExpectedFrameRate) 205KEY_ACCESSOR(kVTCompressionPropertyKey_MaxKeyFrameInterval) 206KEY_ACCESSOR(kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration) 207KEY_ACCESSOR(kVTCompressionPropertyKey_ProfileLevel) 208KEY_ACCESSOR(kVTCompressionPropertyKey_RealTime) 209KEY_ACCESSOR(kVTCompressionPropertyKey_TransferFunction) 210KEY_ACCESSOR(kVTCompressionPropertyKey_YCbCrMatrix) 211KEY_ACCESSOR(kVTEncodeFrameOptionKey_ForceKeyFrame) 212KEY_ACCESSOR(kVTProfileLevel_H264_Baseline_AutoLevel) 213KEY_ACCESSOR(kVTProfileLevel_H264_Main_AutoLevel) 214KEY_ACCESSOR(kVTProfileLevel_H264_Extended_AutoLevel) 215KEY_ACCESSOR(kVTProfileLevel_H264_High_AutoLevel) 216KEY_ACCESSOR(kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder) 217 218#undef KEY_ACCESSOR 219