mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
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:
parent
047b5114f1
commit
b51abc5a63
5 changed files with 69 additions and 10 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -757,6 +757,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"block",
|
"block",
|
||||||
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
|
|
|
@ -4,10 +4,6 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "An example of screen capture"
|
description = "An example of screen capture"
|
||||||
|
|
||||||
[package.metadata.bundle]
|
|
||||||
name = "Capture"
|
|
||||||
identifier = "dev.zed.Capture"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
media = { path = "../media" }
|
media = { path = "../media" }
|
||||||
|
@ -15,6 +11,7 @@ media = { path = "../media" }
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
block = "0.1"
|
block = "0.1"
|
||||||
bytes = "1.2"
|
bytes = "1.2"
|
||||||
|
byteorder = "1.4"
|
||||||
cocoa = "0.24"
|
cocoa = "0.24"
|
||||||
core-foundation = "0.9.3"
|
core-foundation = "0.9.3"
|
||||||
core-graphics = "0.22.3"
|
core-graphics = "0.22.3"
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cargo bundle
|
|
||||||
TTY=`tty`
|
|
||||||
open ../../target/debug/bundle/osx/Capture.app --stdout $TTY --stderr $TTY
|
|
|
@ -3,6 +3,7 @@ mod compression_session;
|
||||||
|
|
||||||
use crate::{bindings::SCStreamOutputType, compression_session::CompressionSession};
|
use crate::{bindings::SCStreamOutputType, compression_session::CompressionSession};
|
||||||
use block::ConcreteBlock;
|
use block::ConcreteBlock;
|
||||||
|
use byteorder::{BigEndian, ReadBytesExt};
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
base::{id, nil, YES},
|
base::{id, nil, YES},
|
||||||
|
@ -128,6 +129,25 @@ impl ScreenCaptureView {
|
||||||
let nal_unit = compression_buffer.split();
|
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();
|
.unwrap();
|
||||||
|
|
|
@ -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")]
|
#[link(name = "CoreMedia", kind = "framework")]
|
||||||
|
@ -285,11 +293,11 @@ pub mod core_media {
|
||||||
timing_info_out: *mut CMSampleTimingInfo,
|
timing_info_out: *mut CMSampleTimingInfo,
|
||||||
) -> OSStatus;
|
) -> OSStatus;
|
||||||
fn CMSampleBufferGetFormatDescription(buffer: CMSampleBufferRef) -> CMFormatDescriptionRef;
|
fn CMSampleBufferGetFormatDescription(buffer: CMSampleBufferRef) -> CMFormatDescriptionRef;
|
||||||
|
fn CMSampleBufferGetDataBuffer(sample_buffer: CMSampleBufferRef) -> CMBlockBufferRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct __CMFormatDescription(c_void);
|
pub struct __CMFormatDescription(c_void);
|
||||||
// The ref type must be a pointer to the underlying struct.
|
|
||||||
pub type CMFormatDescriptionRef = *const __CMFormatDescription;
|
pub type CMFormatDescriptionRef = *const __CMFormatDescription;
|
||||||
|
|
||||||
declare_TCFType!(CMFormatDescription, CMFormatDescriptionRef);
|
declare_TCFType!(CMFormatDescription, CMFormatDescriptionRef);
|
||||||
|
@ -350,6 +358,44 @@ pub mod core_media {
|
||||||
NALUnitHeaderLengthOut: *mut isize,
|
NALUnitHeaderLengthOut: *mut isize,
|
||||||
) -> OSStatus;
|
) -> 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 {
|
pub mod video_toolbox {
|
||||||
|
|
Loading…
Reference in a new issue