Home | History | Annotate | Download | only in mac
      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