Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video toolbox Integration #5

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[workspace]
members = ["core-audio-types", "core-graphics", "core-video", "core-media", "av-foundation", "screen-capture-kit"]
members = ["core-audio-types", "core-graphics", "core-video", "core-media", "av-foundation", "screen-capture-kit", "video-toolbox"]
21 changes: 21 additions & 0 deletions video-toolbox/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "video-toolbox"
version = "0.1.1"
edition = "2018"
authors = [
"Billy Lindeman <[email protected]>",
"luozijun <[email protected]>"
]
description = "Bindings to VideoToolBox for OS X and iOS"
license = "MIT"


[dependencies]
libc = "0.2"
core-foundation = "0.9"
core-media = { path = "../core-media" }
core-video = { path = "../core-video" }

[dev-dependencies]
core-foundation = "0.9"

21 changes: 21 additions & 0 deletions video-toolbox/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 寧靜

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
59 changes: 59 additions & 0 deletions video-toolbox/examples/list_encoders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
extern crate core_foundation;
extern crate video_toolbox;

use core_foundation::array::{CFArray, CFArrayCreate, CFArrayRef};
use core_foundation::base::{CFIndexConvertible, TCFType, kCFAllocatorDefault};
use core_foundation::dictionary::{
CFDictionary, CFDictionaryCreate, CFDictionaryRef, kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks,
};
use core_foundation::string::CFString;

use video_toolbox::utilities::{
VTCopyVideoEncoderList, kVTVideoEncoderList_CodecName, kVTVideoEncoderList_CodecType, kVTVideoEncoderList_DisplayName,
kVTVideoEncoderList_EncoderID, kVTVideoEncoderList_EncoderName,
};

use std::mem;
use std::ptr;

unsafe fn run() {
println!("kVTVideoEncoderList_CodecType: {:?}", CFString::wrap_under_create_rule(kVTVideoEncoderList_CodecType));
println!("kVTVideoEncoderList_EncoderID: {:?}", CFString::wrap_under_create_rule(kVTVideoEncoderList_EncoderID));
println!("kVTVideoEncoderList_CodecName: {:?}", CFString::wrap_under_create_rule(kVTVideoEncoderList_CodecName));
println!("kVTVideoEncoderList_EncoderName: {:?}", CFString::wrap_under_create_rule(kVTVideoEncoderList_EncoderName));
println!("kVTVideoEncoderList_DisplayName: {:?}", CFString::wrap_under_create_rule(kVTVideoEncoderList_DisplayName));
println!("\n\n\n");

let keys: Vec<CFString> = vec![
CFString::new("CodecName"),
CFString::new("CodecType"),
CFString::new("EncoderID"),
CFString::new("EncoderName"),
CFString::new("DisplayName"),
];

let values: Vec<CFString> = vec![CFString::new(""), CFString::new(""), CFString::new(""), CFString::new(""), CFString::new("")];

let opts_ref: CFDictionaryRef = CFDictionaryCreate(
kCFAllocatorDefault,
mem::transmute(keys.as_ptr()),
mem::transmute(values.as_ptr()),
keys.len().to_CFIndex(),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks,
);

let mut result_ref: CFArrayRef = CFArrayCreate(kCFAllocatorDefault, ptr::null_mut(), 0.to_CFIndex(), ptr::null());

let ret_code = VTCopyVideoEncoderList(opts_ref, &mut result_ref);

println!("opts: {:?}", CFDictionary::<CFString, CFString>::wrap_under_create_rule(opts_ref));
println!("ret_code: {:?}", ret_code);
println!("result: {:?}", CFArray::<CFString>::wrap_under_create_rule(result_ref));
}

fn main() {
unsafe {
run();
}
}
13 changes: 13 additions & 0 deletions video-toolbox/src/base.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct VTInt32Point {
pub x: i32,
pub y: i32,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct VTInt32Size {
pub width: i32,
pub height: i32,
}
193 changes: 193 additions & 0 deletions video-toolbox/src/compression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
use core_foundation::base::{Boolean, CFAllocatorRef, CFTypeID, CFTypeRef, OSStatus};
use core_foundation::dictionary::CFDictionaryRef;
use core_foundation::string::CFStringRef;
use core_media::base::CMItemCount;
use core_media::format_description::CMVideoCodecType;
use core_media::sample_buffer::CMSampleBufferRef;
use core_media::time::CMTime;
use core_media::time_range::CMTimeRange;
use core_video::image_buffer::CVImageBufferRef;
use core_video::pixel_buffer_pool::CVPixelBufferPoolRef;
use libc::{c_int, c_void};

pub const kVTUnlimitedFrameDelayCount: c_int = -1;

pub type VTEncodeInfoFlags = u32;
pub type VTCompressionSessionOptionFlags = u32;

pub type VTCompressionSessionRef = CFTypeRef;
pub type VTCompressionOutputCallback = extern "C" fn(
outputCallbackRefCon: *mut c_void,
sourceFrameRefCon: *mut c_void,
status: OSStatus,
infoFlags: VTEncodeInfoFlags,
sampleBuffer: CMSampleBufferRef,
);
pub type VTCompressionOutputHandler = extern "C" fn(status: OSStatus, infoFlags: VTEncodeInfoFlags, sampleBuffer: CMSampleBufferRef);

// VTEncodeInfoFlags
//
// Informational status for encoding -- non-error flags
pub const kVTEncodeInfo_Asynchronous: VTEncodeInfoFlags = 1 << 0;
pub const kVTEncodeInfo_FrameDropped: VTEncodeInfoFlags = 1 << 1;

// VTCompressionSessionOptionFlags
//
pub const kVTCompressionSessionBeginFinalPass: VTCompressionSessionOptionFlags = 1 << 0;

#[link(name = "VideoToolBox", kind = "framework")]
extern "C" {
pub static kVTVideoEncoderSpecification_EncoderID: CFStringRef;

// Creating Sessions
pub fn VTCompressionSessionCreate(
allocator: CFAllocatorRef,
width: i32,
height: i32,
codecType: CMVideoCodecType,
encoderSpecification: CFDictionaryRef,
sourceImageBufferAttributes: CFDictionaryRef,
compressedDataAllocator: CFAllocatorRef,
outputCallback: VTCompressionOutputCallback,
outputCallbackRefCon: *mut c_void,
compressionSessionOut: *mut VTCompressionSessionRef,
) -> OSStatus;
// Configuring Sessions
pub static kVTCompressionPropertyKey_NumberOfPendingFrames: CFStringRef;
pub static kVTCompressionPropertyKey_PixelBufferPoolIsShared: CFStringRef;
pub static kVTCompressionPropertyKey_VideoEncoderPixelBufferAttributes: CFStringRef;
pub static kVTCompressionPropertyKey_MaxKeyFrameInterval: CFStringRef;
pub static kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration: CFStringRef;
pub static kVTCompressionPropertyKey_AllowTemporalCompression: CFStringRef;
pub static kVTCompressionPropertyKey_AllowFrameReordering: CFStringRef;
pub static kVTCompressionPropertyKey_AverageBitRate: CFStringRef;
pub static kVTCompressionPropertyKey_DataRateLimits: CFStringRef;
pub static kVTCompressionPropertyKey_Quality: CFStringRef;
pub static kVTCompressionPropertyKey_MoreFramesBeforeStart: CFStringRef;
pub static kVTCompressionPropertyKey_MoreFramesAfterEnd: CFStringRef;
pub static kVTCompressionPropertyKey_ProfileLevel: CFStringRef;
pub static kVTProfileLevel_HEVC_Main_AutoLevel: CFStringRef;
pub static kVTProfileLevel_HEVC_Main10_AutoLevel: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_1_3: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_3_0: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_3_1: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_3_2: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_4_0: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_4_1: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_4_2: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_5_0: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_5_1: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_5_2: CFStringRef;
pub static kVTProfileLevel_H264_Baseline_AutoLevel: CFStringRef;
pub static kVTProfileLevel_H264_Main_3_0: CFStringRef;
pub static kVTProfileLevel_H264_Main_3_1: CFStringRef;
pub static kVTProfileLevel_H264_Main_3_2: CFStringRef;
pub static kVTProfileLevel_H264_Main_4_0: CFStringRef;
pub static kVTProfileLevel_H264_Main_4_1: CFStringRef;
pub static kVTProfileLevel_H264_Main_4_2: CFStringRef;
pub static kVTProfileLevel_H264_Main_5_0: CFStringRef;
pub static kVTProfileLevel_H264_Main_5_1: CFStringRef;
pub static kVTProfileLevel_H264_Main_5_2: CFStringRef;
pub static kVTProfileLevel_H264_Main_AutoLevel: CFStringRef;
pub static kVTProfileLevel_H264_Extended_5_0: CFStringRef;
pub static kVTProfileLevel_H264_Extended_AutoLevel: CFStringRef;
pub static kVTProfileLevel_H264_High_3_0: CFStringRef;
pub static kVTProfileLevel_H264_High_3_1: CFStringRef;
pub static kVTProfileLevel_H264_High_3_2: CFStringRef;
pub static kVTProfileLevel_H264_High_4_0: CFStringRef;
pub static kVTProfileLevel_H264_High_4_1: CFStringRef;
pub static kVTProfileLevel_H264_High_4_2: CFStringRef;
pub static kVTProfileLevel_H264_High_5_0: CFStringRef;
pub static kVTProfileLevel_H264_High_5_1: CFStringRef;
pub static kVTProfileLevel_H264_High_5_2: CFStringRef;
pub static kVTProfileLevel_H264_High_AutoLevel: CFStringRef;
pub static kVTProfileLevel_MP4V_Simple_L0: CFStringRef;
pub static kVTProfileLevel_MP4V_Simple_L1: CFStringRef;
pub static kVTProfileLevel_MP4V_Simple_L2: CFStringRef;
pub static kVTProfileLevel_MP4V_Simple_L3: CFStringRef;
pub static kVTProfileLevel_MP4V_Main_L2: CFStringRef;
pub static kVTProfileLevel_MP4V_Main_L3: CFStringRef;
pub static kVTProfileLevel_MP4V_Main_L4: CFStringRef;
pub static kVTProfileLevel_MP4V_AdvancedSimple_L0: CFStringRef;
pub static kVTProfileLevel_MP4V_AdvancedSimple_L1: CFStringRef;
pub static kVTProfileLevel_MP4V_AdvancedSimple_L2: CFStringRef;
pub static kVTProfileLevel_MP4V_AdvancedSimple_L3: CFStringRef;
pub static kVTProfileLevel_MP4V_AdvancedSimple_L4: CFStringRef;
pub static kVTProfileLevel_H263_Profile0_Level10: CFStringRef;
pub static kVTProfileLevel_H263_Profile0_Level45: CFStringRef;
pub static kVTProfileLevel_H263_Profile3_Level45: CFStringRef;
pub static kVTCompressionPropertyKey_H264EntropyMode: CFStringRef;
pub static kVTH264EntropyMode_CAVLC: CFStringRef;
pub static kVTH264EntropyMode_CABAC: CFStringRef;
pub static kVTCompressionPropertyKey_Depth: CFStringRef;
pub static kVTCompressionPropertyKey_MaxFrameDelayCount: CFStringRef;
pub static kVTCompressionPropertyKey_MaxH264SliceBytes: CFStringRef;
pub static kVTCompressionPropertyKey_RealTime: CFStringRef;
pub static kVTCompressionPropertyKey_SourceFrameCount: CFStringRef;
pub static kVTCompressionPropertyKey_ExpectedFrameRate: CFStringRef;
pub static kVTCompressionPropertyKey_ExpectedDuration: CFStringRef;
pub static kVTCompressionPropertyKey_BaseLayerFrameRate: CFStringRef;
pub static kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder: CFStringRef;
pub static kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder: CFStringRef;
pub static kVTVideoEncoderSpecification_EnableLowLatencyRateControl: CFStringRef;
pub static kVTCompressionPropertyKey_UsingHardwareAcceleratedVideoEncoder: CFStringRef;
pub static kVTEncodeFrameOptionKey_ForceKeyFrame: CFStringRef;
pub static kVTCompressionPropertyKey_CleanAperture: CFStringRef;
pub static kVTCompressionPropertyKey_PixelAspectRatio: CFStringRef;
pub static kVTCompressionPropertyKey_FieldCount: CFStringRef;
pub static kVTCompressionPropertyKey_FieldDetail: CFStringRef;
pub static kVTCompressionPropertyKey_AspectRatio16x9: CFStringRef;
pub static kVTCompressionPropertyKey_ProgressiveScan: CFStringRef;
pub static kVTCompressionPropertyKey_ColorPrimaries: CFStringRef;
pub static kVTCompressionPropertyKey_TransferFunction: CFStringRef;
pub static kVTCompressionPropertyKey_YCbCrMatrix: CFStringRef;
pub static kVTCompressionPropertyKey_ICCProfile: CFStringRef;
pub static kVTCompressionPropertyKey_MasteringDisplayColorVolume: CFStringRef;
pub static kVTCompressionPropertyKey_ContentLightLevelInfo: CFStringRef;
pub static kVTCompressionPropertyKey_PixelTransferProperties: CFStringRef;
pub static kVTCompressionPropertyKey_MultiPassStorage: CFStringRef;
pub static kVTCompressionPropertyKey_EncoderID: CFStringRef;

// Encoding Frames
pub fn VTCompressionSessionPrepareToEncodeFrames(session: VTCompressionSessionRef) -> OSStatus;
pub fn VTCompressionSessionEncodeFrame(
session: VTCompressionSessionRef,
imageBuffer: CVImageBufferRef,
presentationTimeStamp: CMTime,
duration: CMTime,
frameProperties: CFDictionaryRef,
sourceFrameRefcon: *mut c_void,
infoFlagsOut: *mut VTEncodeInfoFlags,
) -> OSStatus;
pub fn VTCompressionSessionEncodeFrameWithOutputHandler(
session: VTCompressionSessionRef,
imageBuffer: CVImageBufferRef,
presentationTimeStamp: CMTime,
duration: CMTime,
frameProperties: CFDictionaryRef,
infoFlagsOut: *mut VTEncodeInfoFlags,
outputHandler: VTCompressionOutputHandler,
) -> OSStatus;
pub fn VTCompressionSessionCompleteFrames(session: VTCompressionSessionRef, completeUntilPresentationTimeStamp: CMTime) -> OSStatus;

// Inspecting Sessions
pub fn VTCompressionSessionGetPixelBufferPool(session: VTCompressionSessionRef) -> CVPixelBufferPoolRef;
pub fn VTCompressionSessionGetTypeID() -> CFTypeID;

// Performing Multipass Compression
pub fn VTCompressionSessionBeginPass(
session: VTCompressionSessionRef,
beginPassFlags: VTCompressionSessionOptionFlags,
reserved: *mut u32,
) -> OSStatus;
pub fn VTCompressionSessionEndPass(session: VTCompressionSessionRef, furtherPassesRequestedOut: *mut Boolean, reserved: *mut u32) -> OSStatus;
pub fn VTCompressionSessionGetTimeRangesForNextPass(
session: VTCompressionSessionRef,
timeRangeCountOut: *mut CMItemCount,
timeRangeArrayOut: *const CMTimeRange,
) -> OSStatus;

// Ending Sessions
pub fn VTCompressionSessionInvalidate(session: VTCompressionSessionRef);

}
Loading