Skip to content

Commit

Permalink
Extend media glue code to support the VideoToolbox cast video encoder.
Browse files Browse the repository at this point in the history
BUG=409897
R=rsesek, DaleCurtis

Review URL: https://codereview.chromium.org/531863002

Cr-Commit-Position: refs/heads/master@{#294654}
  • Loading branch information
jfroy authored and Commit bot committed Sep 12, 2014
1 parent 9cb142f commit 79fae2e
Show file tree
Hide file tree
Showing 7 changed files with 639 additions and 1 deletion.
3 changes: 3 additions & 0 deletions media/base/mac/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ source_set("mac") {
"avfoundation_glue.mm",
"coremedia_glue.h",
"coremedia_glue.mm",
"corevideo_glue.h",
"videotoolbox_glue.h",
"videotoolbox_glue.mm",
]
set_sources_assignment_filter(sources_assignment_filter)
}
52 changes: 52 additions & 0 deletions media/base/mac/coremedia_glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,20 @@ class MEDIA_EXPORT CoreMediaGlue {
CMTimeEpoch epoch;
} CMTime;

// Originally from CMBlockBuffer.h
typedef uint32_t CMBlockBufferFlags;
typedef struct OpaqueCMBlockBuffer* CMBlockBufferRef;
typedef struct {
uint32_t version;
void* (*AllocateBlock)(void*, size_t);
void (*FreeBlock)(void*, void*, size_t);
void* refCon;
} CMBlockBufferCustomBlockSource;

// Originally from CMFormatDescription.h.
typedef const struct opaqueCMFormatDescription* CMFormatDescriptionRef;
typedef CMFormatDescriptionRef CMVideoFormatDescriptionRef;
typedef FourCharCode CMVideoCodecType;
typedef struct {
int32_t width;
int32_t height;
Expand All @@ -40,6 +51,12 @@ class MEDIA_EXPORT CoreMediaGlue {
};
enum {
kCMVideoCodecType_JPEG_OpenDML = 'dmb1',
kCMVideoCodecType_H264 = 'avc1',
};

// Originally from CMFormatDescriptionBridge.h
enum {
kCMFormatDescriptionBridgeError_InvalidParameter = -12712,
};

// Originally from CMSampleBuffer.h.
Expand All @@ -48,15 +65,50 @@ class MEDIA_EXPORT CoreMediaGlue {
// Originally from CMTime.h.
static CMTime CMTimeMake(int64_t value, int32_t timescale);

// Originally from CMBlockBuffer.h
static OSStatus CMBlockBufferCreateContiguous(
CFAllocatorRef structureAllocator,
CMBlockBufferRef sourceBuffer,
CFAllocatorRef blockAllocator,
const CMBlockBufferCustomBlockSource* customBlockSource,
size_t offsetToData,
size_t dataLength,
CMBlockBufferFlags flags,
CMBlockBufferRef* newBBufOut);
static size_t CMBlockBufferGetDataLength(CMBlockBufferRef theBuffer);
static OSStatus CMBlockBufferGetDataPointer(CMBlockBufferRef theBuffer,
size_t offset,
size_t* lengthAtOffset,
size_t* totalLength,
char** dataPointer);
static Boolean CMBlockBufferIsRangeContiguous(CMBlockBufferRef theBuffer,
size_t offset,
size_t length);

// Originally from CMSampleBuffer.h.
static CMBlockBufferRef CMSampleBufferGetDataBuffer(CMSampleBufferRef sbuf);
static CMFormatDescriptionRef CMSampleBufferGetFormatDescription(
CMSampleBufferRef sbuf);
static CVImageBufferRef CMSampleBufferGetImageBuffer(
CMSampleBufferRef buffer);
static CFArrayRef CMSampleBufferGetSampleAttachmentsArray(
CMSampleBufferRef sbuf,
Boolean createIfNecessary);
static CFStringRef kCMSampleAttachmentKey_NotSync();

// Originally from CMFormatDescription.h.
static FourCharCode CMFormatDescriptionGetMediaSubType(
CMFormatDescriptionRef desc);
static CMVideoDimensions CMVideoFormatDescriptionGetDimensions(
CMVideoFormatDescriptionRef videoDesc);
static OSStatus CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
CMFormatDescriptionRef videoDesc,
size_t parameterSetIndex,
const uint8_t** parameterSetPointerOut,
size_t* parameterSetSizeOut,
size_t* parameterSetCountOut,
int* NALUnitHeaderLengthOut)
/*__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)*/;

private:
DISALLOW_IMPLICIT_CONSTRUCTORS(CoreMediaGlue);
Expand Down
226 changes: 225 additions & 1 deletion media/base/mac/coremedia_glue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,52 @@
class CoreMediaLibraryInternal {
public:
typedef CoreMediaGlue::CMTime (*CMTimeMakeMethod)(int64_t, int32_t);

typedef OSStatus (*CMBlockBufferCreateContiguousMethod)(
CFAllocatorRef,
CoreMediaGlue::CMBlockBufferRef,
CFAllocatorRef,
const CoreMediaGlue::CMBlockBufferCustomBlockSource*,
size_t,
size_t,
CoreMediaGlue::CMBlockBufferFlags,
CoreMediaGlue::CMBlockBufferRef*);
typedef size_t (*CMBlockBufferGetDataLengthMethod)(
CoreMediaGlue::CMBlockBufferRef);
typedef OSStatus (*CMBlockBufferGetDataPointerMethod)(
CoreMediaGlue::CMBlockBufferRef,
size_t,
size_t*,
size_t*,
char**);
typedef Boolean (*CMBlockBufferIsRangeContiguousMethod)(
CoreMediaGlue::CMBlockBufferRef,
size_t,
size_t);

typedef CoreMediaGlue::CMBlockBufferRef (*CMSampleBufferGetDataBufferMethod)(
CoreMediaGlue::CMSampleBufferRef);
typedef CoreMediaGlue::CMFormatDescriptionRef (
*CMSampleBufferGetFormatDescriptionMethod)(
CoreMediaGlue::CMSampleBufferRef);
typedef CVImageBufferRef (*CMSampleBufferGetImageBufferMethod)(
CoreMediaGlue::CMSampleBufferRef);
typedef CFArrayRef (*CMSampleBufferGetSampleAttachmentsArrayMethod)(
CoreMediaGlue::CMSampleBufferRef,
Boolean);

typedef FourCharCode (*CMFormatDescriptionGetMediaSubTypeMethod)(
CoreMediaGlue::CMFormatDescriptionRef desc);
typedef CoreMediaGlue::CMVideoDimensions
(*CMVideoFormatDescriptionGetDimensionsMethod)(
CoreMediaGlue::CMVideoFormatDescriptionRef videoDesc);
typedef OSStatus (*CMVideoFormatDescriptionGetH264ParameterSetAtIndexMethod)(
CoreMediaGlue::CMFormatDescriptionRef,
size_t,
const uint8_t**,
size_t*,
size_t*,
int*);

CoreMediaLibraryInternal() {
NSBundle* bundle = [NSBundle
Expand All @@ -40,27 +79,99 @@ typedef FourCharCode (*CMFormatDescriptionGetMediaSubTypeMethod)(
dlsym(library_handle, "CMTimeMake"));
CHECK(cm_time_make_) << dlerror();

cm_block_buffer_create_contiguous_method_ =
reinterpret_cast<CMBlockBufferCreateContiguousMethod>(
dlsym(library_handle, "CMBlockBufferCreateContiguous"));
CHECK(cm_block_buffer_create_contiguous_method_) << dlerror();
cm_block_buffer_get_data_length_method_ =
reinterpret_cast<CMBlockBufferGetDataLengthMethod>(
dlsym(library_handle, "CMBlockBufferGetDataLength"));
CHECK(cm_block_buffer_get_data_length_method_) << dlerror();
cm_block_buffer_get_data_pointer_method_ =
reinterpret_cast<CMBlockBufferGetDataPointerMethod>(
dlsym(library_handle, "CMBlockBufferGetDataPointer"));
CHECK(cm_block_buffer_get_data_pointer_method_) << dlerror();
cm_block_buffer_is_range_contiguous_method_ =
reinterpret_cast<CMBlockBufferIsRangeContiguousMethod>(
dlsym(library_handle, "CMBlockBufferIsRangeContiguous"));
CHECK(cm_block_buffer_is_range_contiguous_method_) << dlerror();

cm_sample_buffer_get_data_buffer_method_ =
reinterpret_cast<CMSampleBufferGetDataBufferMethod>(
dlsym(library_handle, "CMSampleBufferGetDataBuffer"));
CHECK(cm_sample_buffer_get_data_buffer_method_) << dlerror();
cm_sample_buffer_get_format_description_method_ =
reinterpret_cast<CMSampleBufferGetFormatDescriptionMethod>(
dlsym(library_handle, "CMSampleBufferGetFormatDescription"));
CHECK(cm_sample_buffer_get_format_description_method_) << dlerror();
cm_sample_buffer_get_image_buffer_method_ =
reinterpret_cast<CMSampleBufferGetImageBufferMethod>(
dlsym(library_handle, "CMSampleBufferGetImageBuffer"));
CHECK(cm_sample_buffer_get_image_buffer_method_) << dlerror();
cm_sample_buffer_get_sample_attachments_array_method_ =
reinterpret_cast<CMSampleBufferGetSampleAttachmentsArrayMethod>(
dlsym(library_handle, "CMSampleBufferGetSampleAttachmentsArray"));
CHECK(cm_sample_buffer_get_sample_attachments_array_method_) << dlerror();
k_cm_sample_attachment_key_not_sync_ = reinterpret_cast<CFStringRef*>(
dlsym(library_handle, "kCMSampleAttachmentKey_NotSync"));
CHECK(k_cm_sample_attachment_key_not_sync_) << dlerror();

cm_format_description_get_media_sub_type_method_ =
reinterpret_cast<CMFormatDescriptionGetMediaSubTypeMethod>(
dlsym(library_handle, "CMFormatDescriptionGetMediaSubType"));
CHECK(cm_format_description_get_media_sub_type_method_) << dlerror();

cm_video_format_description_get_dimensions_method_ =
reinterpret_cast<CMVideoFormatDescriptionGetDimensionsMethod>(
dlsym(library_handle, "CMVideoFormatDescriptionGetDimensions"));
CHECK(cm_video_format_description_get_dimensions_method_) << dlerror();

// Available starting (OS X 10.9, iOS 7), allow to be null.
cm_video_format_description_get_h264_parameter_set_at_index_method_ =
reinterpret_cast<
CMVideoFormatDescriptionGetH264ParameterSetAtIndexMethod>(
dlsym(library_handle,
"CMVideoFormatDescriptionGetH264ParameterSetAtIndex"));
}

const CMTimeMakeMethod& cm_time_make() const { return cm_time_make_; }

const CMBlockBufferCreateContiguousMethod&
cm_block_buffer_create_contiguous_method() const {
return cm_block_buffer_create_contiguous_method_;
}
const CMBlockBufferGetDataLengthMethod&
cm_block_buffer_get_data_length_method() const {
return cm_block_buffer_get_data_length_method_;
}
const CMBlockBufferGetDataPointerMethod&
cm_block_buffer_get_data_pointer_method() const {
return cm_block_buffer_get_data_pointer_method_;
}
const CMBlockBufferIsRangeContiguousMethod&
cm_block_buffer_is_range_contiguous_method() const {
return cm_block_buffer_is_range_contiguous_method_;
}

const CMSampleBufferGetDataBufferMethod&
cm_sample_buffer_get_data_buffer_method() const {
return cm_sample_buffer_get_data_buffer_method_;
}
const CMSampleBufferGetFormatDescriptionMethod&
cm_sample_buffer_get_format_description_method() const {
return cm_sample_buffer_get_format_description_method_;
}
const CMSampleBufferGetImageBufferMethod&
cm_sample_buffer_get_image_buffer_method() const {
return cm_sample_buffer_get_image_buffer_method_;
}
const CMSampleBufferGetSampleAttachmentsArrayMethod&
cm_sample_buffer_get_sample_attachments_array_method() const {
return cm_sample_buffer_get_sample_attachments_array_method_;
}
CFStringRef* const& k_cm_sample_attachment_key_not_sync() const {
return k_cm_sample_attachment_key_not_sync_;
}

const CMFormatDescriptionGetMediaSubTypeMethod&
cm_format_description_get_media_sub_type_method() const {
return cm_format_description_get_media_sub_type_method_;
Expand All @@ -69,14 +180,34 @@ typedef FourCharCode (*CMFormatDescriptionGetMediaSubTypeMethod)(
cm_video_format_description_get_dimensions_method() const {
return cm_video_format_description_get_dimensions_method_;
}
const CMVideoFormatDescriptionGetH264ParameterSetAtIndexMethod&
cm_video_format_description_get_h264_parameter_set_at_index_method() const {
return cm_video_format_description_get_h264_parameter_set_at_index_method_;
}

private:
CMTimeMakeMethod cm_time_make_;

CMBlockBufferCreateContiguousMethod cm_block_buffer_create_contiguous_method_;
CMBlockBufferGetDataLengthMethod cm_block_buffer_get_data_length_method_;
CMBlockBufferGetDataPointerMethod cm_block_buffer_get_data_pointer_method_;
CMBlockBufferIsRangeContiguousMethod
cm_block_buffer_is_range_contiguous_method_;

CMSampleBufferGetDataBufferMethod cm_sample_buffer_get_data_buffer_method_;
CMSampleBufferGetFormatDescriptionMethod
cm_sample_buffer_get_format_description_method_;
CMSampleBufferGetImageBufferMethod cm_sample_buffer_get_image_buffer_method_;
CMSampleBufferGetSampleAttachmentsArrayMethod
cm_sample_buffer_get_sample_attachments_array_method_;
CFStringRef* k_cm_sample_attachment_key_not_sync_;

CMFormatDescriptionGetMediaSubTypeMethod
cm_format_description_get_media_sub_type_method_;
CMVideoFormatDescriptionGetDimensionsMethod
cm_video_format_description_get_dimensions_method_;
CMVideoFormatDescriptionGetH264ParameterSetAtIndexMethod
cm_video_format_description_get_h264_parameter_set_at_index_method_;

DISALLOW_COPY_AND_ASSIGN(CoreMediaLibraryInternal);
};
Expand All @@ -92,13 +223,88 @@ typedef FourCharCode (*CMFormatDescriptionGetMediaSubTypeMethod)(
return g_coremedia_handle.Get().cm_time_make()(value, timescale);
}

// static
OSStatus CoreMediaGlue::CMBlockBufferCreateContiguous(
CFAllocatorRef structureAllocator,
CMBlockBufferRef sourceBuffer,
CFAllocatorRef blockAllocator,
const CMBlockBufferCustomBlockSource* customBlockSource,
size_t offsetToData,
size_t dataLength,
CMBlockBufferFlags flags,
CMBlockBufferRef* newBBufOut) {
return g_coremedia_handle.Get().cm_block_buffer_create_contiguous_method()(
structureAllocator,
sourceBuffer,
blockAllocator,
customBlockSource,
offsetToData,
dataLength,
flags,
newBBufOut);
}

// static
size_t CoreMediaGlue::CMBlockBufferGetDataLength(CMBlockBufferRef theBuffer) {
return g_coremedia_handle.Get().cm_block_buffer_get_data_length_method()(
theBuffer);
}

// static
OSStatus CoreMediaGlue::CMBlockBufferGetDataPointer(CMBlockBufferRef theBuffer,
size_t offset,
size_t* lengthAtOffset,
size_t* totalLength,
char** dataPointer) {
return g_coremedia_handle.Get().cm_block_buffer_get_data_pointer_method()(
theBuffer, offset, lengthAtOffset, totalLength, dataPointer);
}

// static
Boolean CoreMediaGlue::CMBlockBufferIsRangeContiguous(
CMBlockBufferRef theBuffer,
size_t offset,
size_t length) {
return g_coremedia_handle.Get().cm_block_buffer_is_range_contiguous_method()(
theBuffer, offset, length);
}

// static
CoreMediaGlue::CMBlockBufferRef CoreMediaGlue::CMSampleBufferGetDataBuffer(
CMSampleBufferRef sbuf) {
return g_coremedia_handle.Get().cm_sample_buffer_get_data_buffer_method()(
sbuf);
}

// static
CoreMediaGlue::CMFormatDescriptionRef
CoreMediaGlue::CMSampleBufferGetFormatDescription(
CoreMediaGlue::CMSampleBufferRef sbuf) {
return g_coremedia_handle.Get()
.cm_sample_buffer_get_format_description_method()(sbuf);
}

// static
CVImageBufferRef CoreMediaGlue::CMSampleBufferGetImageBuffer(
CMSampleBufferRef buffer) {
return g_coremedia_handle.Get().cm_sample_buffer_get_image_buffer_method()(
buffer);
}

// static
CFArrayRef CoreMediaGlue::CMSampleBufferGetSampleAttachmentsArray(
CMSampleBufferRef sbuf,
Boolean createIfNecessary) {
return g_coremedia_handle.Get()
.cm_sample_buffer_get_sample_attachments_array_method()(
sbuf, createIfNecessary);
}

// static
CFStringRef CoreMediaGlue::kCMSampleAttachmentKey_NotSync() {
return *g_coremedia_handle.Get().k_cm_sample_attachment_key_not_sync();
}

// static
FourCharCode CoreMediaGlue::CMFormatDescriptionGetMediaSubType(
CMFormatDescriptionRef desc) {
Expand All @@ -113,3 +319,21 @@ typedef FourCharCode (*CMFormatDescriptionGetMediaSubTypeMethod)(
return g_coremedia_handle.Get()
.cm_video_format_description_get_dimensions_method()(videoDesc);
}

// static
OSStatus CoreMediaGlue::CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
CMFormatDescriptionRef videoDesc,
size_t parameterSetIndex,
const uint8_t** parameterSetPointerOut,
size_t* parameterSetSizeOut,
size_t* parameterSetCountOut,
int* NALUnitHeaderLengthOut) {
return g_coremedia_handle.Get()
.cm_video_format_description_get_h264_parameter_set_at_index_method()(
videoDesc,
parameterSetIndex,
parameterSetPointerOut,
parameterSetSizeOut,
parameterSetCountOut,
NALUnitHeaderLengthOut);
}
Loading

0 comments on commit 79fae2e

Please sign in to comment.