1 // Copyright 2013 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/video/capture/mac/coremedia_glue.h" 6 7 #include <dlfcn.h> 8 9 #include "base/logging.h" 10 #include "base/lazy_instance.h" 11 12 namespace { 13 14 // This class is used to retrieve some CoreMedia library functions. It must be 15 // used as a LazyInstance so that it is initialised once and in a thread-safe 16 // way. Normally no work is done in constructors: LazyInstance is an exception. 17 class CoreMediaLibraryInternal { 18 public: 19 typedef CoreMediaGlue::CMTime (*CMTimeMakeMethod)(int64_t, int32_t); 20 typedef CVImageBufferRef (*CMSampleBufferGetImageBufferMethod)( 21 CoreMediaGlue::CMSampleBufferRef); 22 typedef FourCharCode (*CMFormatDescriptionGetMediaSubTypeMethod)( 23 CoreMediaGlue::CMFormatDescriptionRef desc); 24 typedef CoreMediaGlue::CMVideoDimensions 25 (*CMVideoFormatDescriptionGetDimensionsMethod)( 26 CoreMediaGlue::CMVideoFormatDescriptionRef videoDesc); 27 28 CoreMediaLibraryInternal() { 29 NSBundle* bundle = [NSBundle 30 bundleWithPath:@"/System/Library/Frameworks/CoreMedia.framework"]; 31 32 const char* path = [[bundle executablePath] fileSystemRepresentation]; 33 CHECK(path); 34 void* library_handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL); 35 CHECK(library_handle) << dlerror(); 36 37 // Now extract the methods. 38 cm_time_make_ = reinterpret_cast<CMTimeMakeMethod>( 39 dlsym(library_handle, "CMTimeMake")); 40 CHECK(cm_time_make_) << dlerror(); 41 42 cm_sample_buffer_get_image_buffer_method_ = 43 reinterpret_cast<CMSampleBufferGetImageBufferMethod>( 44 dlsym(library_handle, "CMSampleBufferGetImageBuffer")); 45 CHECK(cm_sample_buffer_get_image_buffer_method_) << dlerror(); 46 47 cm_format_description_get_media_sub_type_method_ = 48 reinterpret_cast<CMFormatDescriptionGetMediaSubTypeMethod>( 49 dlsym(library_handle, "CMFormatDescriptionGetMediaSubType")); 50 CHECK(cm_format_description_get_media_sub_type_method_) << dlerror(); 51 52 cm_video_format_description_get_dimensions_method_ = 53 reinterpret_cast<CMVideoFormatDescriptionGetDimensionsMethod>( 54 dlsym(library_handle, "CMVideoFormatDescriptionGetDimensions")); 55 CHECK(cm_video_format_description_get_dimensions_method_) << dlerror(); 56 } 57 58 const CMTimeMakeMethod& cm_time_make() const { return cm_time_make_; } 59 const CMSampleBufferGetImageBufferMethod& 60 cm_sample_buffer_get_image_buffer_method() const { 61 return cm_sample_buffer_get_image_buffer_method_; 62 } 63 const CMFormatDescriptionGetMediaSubTypeMethod& 64 cm_format_description_get_media_sub_type_method() const { 65 return cm_format_description_get_media_sub_type_method_; 66 } 67 const CMVideoFormatDescriptionGetDimensionsMethod& 68 cm_video_format_description_get_dimensions_method() const { 69 return cm_video_format_description_get_dimensions_method_; 70 } 71 72 private: 73 CMTimeMakeMethod cm_time_make_; 74 CMSampleBufferGetImageBufferMethod cm_sample_buffer_get_image_buffer_method_; 75 CMFormatDescriptionGetMediaSubTypeMethod 76 cm_format_description_get_media_sub_type_method_; 77 CMVideoFormatDescriptionGetDimensionsMethod 78 cm_video_format_description_get_dimensions_method_; 79 80 DISALLOW_COPY_AND_ASSIGN(CoreMediaLibraryInternal); 81 }; 82 83 } // namespace 84 85 static base::LazyInstance<CoreMediaLibraryInternal> g_coremedia_handle = 86 LAZY_INSTANCE_INITIALIZER; 87 88 // static 89 CoreMediaGlue::CMTime CoreMediaGlue::CMTimeMake(int64_t value, 90 int32_t timescale) { 91 return g_coremedia_handle.Get().cm_time_make()(value, timescale); 92 } 93 94 // static 95 CVImageBufferRef CoreMediaGlue::CMSampleBufferGetImageBuffer( 96 CMSampleBufferRef buffer) { 97 return g_coremedia_handle.Get().cm_sample_buffer_get_image_buffer_method()( 98 buffer); 99 } 100 101 // static 102 FourCharCode CoreMediaGlue::CMFormatDescriptionGetMediaSubType( 103 CMFormatDescriptionRef desc) { 104 return g_coremedia_handle.Get() 105 .cm_format_description_get_media_sub_type_method()(desc); 106 } 107 108 // static 109 CoreMediaGlue::CMVideoDimensions 110 CoreMediaGlue::CMVideoFormatDescriptionGetDimensions( 111 CMVideoFormatDescriptionRef videoDesc) { 112 return g_coremedia_handle.Get() 113 .cm_video_format_description_get_dimensions_method()(videoDesc); 114 } 115