Read the frame data out of the CMSampleBuffer

Still not sending it anywhere, but think I'm reading it correctly.
This commit is contained in:
Nathan Sobo 2022-08-31 13:36:29 -06:00 committed by Antonio Scandurra
parent 047b5114f1
commit b51abc5a63
5 changed files with 69 additions and 10 deletions

1
Cargo.lock generated
View file

@ -757,6 +757,7 @@ dependencies = [
"anyhow",
"bindgen",
"block",
"byteorder",
"bytes",
"cocoa",
"core-foundation",

View file

@ -4,10 +4,6 @@ version = "0.1.0"
edition = "2021"
description = "An example of screen capture"
[package.metadata.bundle]
name = "Capture"
identifier = "dev.zed.Capture"
[dependencies]
gpui = { path = "../gpui" }
media = { path = "../media" }
@ -15,6 +11,7 @@ media = { path = "../media" }
anyhow = "1.0.38"
block = "0.1"
bytes = "1.2"
byteorder = "1.4"
cocoa = "0.24"
core-foundation = "0.9.3"
core-graphics = "0.22.3"

View file

@ -1,5 +0,0 @@
#!/bin/bash
cargo bundle
TTY=`tty`
open ../../target/debug/bundle/osx/Capture.app --stdout $TTY --stderr $TTY

View file

@ -3,6 +3,7 @@ mod compression_session;
use crate::{bindings::SCStreamOutputType, compression_session::CompressionSession};
use block::ConcreteBlock;
use byteorder::{BigEndian, ReadBytesExt};
use bytes::BytesMut;
use cocoa::{
base::{id, nil, YES},
@ -128,6 +129,25 @@ impl ScreenCaptureView {
let nal_unit = compression_buffer.split();
}
}
let data = sample_buffer.data();
let mut data = data.bytes();
const AVCC_HEADER_LENGTH: usize = 4;
while data.len() - AVCC_HEADER_LENGTH > 0 {
let nal_unit_len = match data.read_u32::<BigEndian>() {
Ok(len) => len as usize,
Err(error) => {
log::error!("error decoding nal unit length: {}", error);
return;
}
};
compression_buffer.extend_from_slice(&START_CODE);
compression_buffer.extend_from_slice(&data[..nal_unit_len as usize]);
data = &data[nal_unit_len..];
let nal_unit = compression_buffer.split();
}
},
)
.unwrap();

View file

@ -269,6 +269,14 @@ pub mod core_media {
))
}
}
pub fn data(&self) -> CMBlockBuffer {
unsafe {
CMBlockBuffer::wrap_under_get_rule(CMSampleBufferGetDataBuffer(
self.as_concrete_TypeRef(),
))
}
}
}
#[link(name = "CoreMedia", kind = "framework")]
@ -285,11 +293,11 @@ pub mod core_media {
timing_info_out: *mut CMSampleTimingInfo,
) -> OSStatus;
fn CMSampleBufferGetFormatDescription(buffer: CMSampleBufferRef) -> CMFormatDescriptionRef;
fn CMSampleBufferGetDataBuffer(sample_buffer: CMSampleBufferRef) -> CMBlockBufferRef;
}
#[repr(C)]
pub struct __CMFormatDescription(c_void);
// The ref type must be a pointer to the underlying struct.
pub type CMFormatDescriptionRef = *const __CMFormatDescription;
declare_TCFType!(CMFormatDescription, CMFormatDescriptionRef);
@ -350,6 +358,44 @@ pub mod core_media {
NALUnitHeaderLengthOut: *mut isize,
) -> OSStatus;
}
#[repr(C)]
pub struct __CMBlockBuffer(c_void);
pub type CMBlockBufferRef = *const __CMBlockBuffer;
declare_TCFType!(CMBlockBuffer, CMBlockBufferRef);
impl_TCFType!(CMBlockBuffer, CMBlockBufferRef, CMBlockBufferGetTypeID);
impl_CFTypeDescription!(CMBlockBuffer);
impl CMBlockBuffer {
pub fn bytes(&self) -> &[u8] {
unsafe {
let mut bytes = ptr::null();
let mut len = 0;
let result = CMBlockBufferGetDataPointer(
self.as_concrete_TypeRef(),
0,
&mut 0,
&mut len,
&mut bytes,
);
assert!(result == 0, "could not get block buffer data");
std::slice::from_raw_parts(bytes, len)
}
}
}
#[link(name = "CoreMedia", kind = "framework")]
extern "C" {
fn CMBlockBufferGetTypeID() -> CFTypeID;
fn CMBlockBufferGetDataPointer(
buffer: CMBlockBufferRef,
offset: usize,
length_at_offset_out: *mut usize,
total_length_out: *mut usize,
data_pointer_out: *mut *const u8,
) -> OSStatus;
}
}
pub mod video_toolbox {