Skip to content

Commit 37472f5

Browse files
committed
fix macos compile
1 parent db662d8 commit 37472f5

File tree

8 files changed

+173
-162
lines changed

8 files changed

+173
-162
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/enc-avfoundation/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
cap-media-info = { path = "../media-info" }
8+
cap-ffmpeg-utils = { path = "../ffmpeg-utils" }
89

910
ffmpeg.workspace = true
1011
thiserror.workspace = true

crates/enc-avfoundation/src/mp4.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use cap_media_info::{AudioInfo, PlanarData, VideoInfo};
1+
use cap_ffmpeg_utils::PlanarData;
2+
use cap_media_info::{AudioInfo, VideoInfo};
23
use cidre::{cm::SampleTimingInfo, objc::Obj, *};
34
use ffmpeg::{ffi::AV_TIME_BASE_Q, frame};
45
use std::path::PathBuf;
Lines changed: 164 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,197 @@
1-
use ffmpeg::format;
2-
use mediafoundation_ffmpeg::{H264StreamMuxer, MuxerConfig};
3-
use std::path::PathBuf;
4-
5-
/// Example of using H264StreamMuxer with an existing FFmpeg output context
6-
/// This demonstrates how to integrate with MP4File or similar structures
7-
fn example_with_shared_output() -> Result<(), Box<dyn std::error::Error>> {
8-
// Initialize FFmpeg
9-
ffmpeg::init()?;
10-
11-
// Create an output context (this would normally be owned by MP4File)
12-
let output_path = PathBuf::from("output.mp4");
13-
let mut output = format::output(&output_path)?;
14-
15-
// Configure the H264 muxer
16-
let config = MuxerConfig {
17-
width: 1920,
18-
height: 1080,
19-
fps: 30,
20-
bitrate: 5_000_000, // 5 Mbps
21-
};
22-
23-
// Add the H264 stream and create the muxer
24-
// Note: We need to add the stream before writing the header
25-
let mut h264_muxer = H264StreamMuxer::add_stream(&mut output, config)?;
26-
27-
// You might also have other streams (like audio) added to the same output
28-
// ... add audio stream here if needed ...
29-
30-
// Write the header after all streams are added
31-
output.write_header()?;
32-
33-
// Now you can write H264 samples from MediaFoundation
1+
fn main() {
342
#[cfg(windows)]
35-
{
36-
// Example: Write samples from MediaFoundation
37-
// let sample: IMFSample = get_sample_from_media_foundation();
38-
// h264_muxer.write_sample(&sample)?;
39-
}
3+
win::main();
4+
}
405

41-
// Or write raw H264 data
42-
let example_h264_data = vec![0, 0, 0, 1, 0x65]; // Example keyframe NAL
43-
h264_muxer.write_h264_data(
44-
&example_h264_data,
45-
0, // pts in microseconds
46-
0, // dts in microseconds
47-
33333, // duration in microseconds (1/30 fps)
48-
true, // is_keyframe
49-
&mut output,
50-
)?;
6+
#[cfg(windows)]
7+
mod win {
8+
use cap_mediafoundation_ffmpeg::{H264StreamMuxer, MuxerConfig};
9+
use ffmpeg::format;
10+
use std::path::PathBuf;
5111

52-
// Finish the muxer (doesn't write trailer)
53-
h264_muxer.finish()?;
12+
/// Example of using H264StreamMuxer with an existing FFmpeg output context
13+
/// This demonstrates how to integrate with MP4File or similar structures
14+
fn example_with_shared_output() -> Result<(), Box<dyn std::error::Error>> {
15+
// Initialize FFmpeg
16+
ffmpeg::init()?;
5417

55-
// Write the trailer (this would be done by MP4File::finish())
56-
output.write_trailer()?;
18+
// Create an output context (this would normally be owned by MP4File)
19+
let output_path = PathBuf::from("output.mp4");
20+
let mut output = format::output(&output_path)?;
5721

58-
Ok(())
59-
}
22+
// Configure the H264 muxer
23+
let config = MuxerConfig {
24+
width: 1920,
25+
height: 1080,
26+
fps: 30,
27+
bitrate: 5_000_000, // 5 Mbps
28+
};
6029

61-
/// Example showing how this would integrate with an MP4File-like structure
62-
struct MP4FileExample {
63-
output: format::context::Output,
64-
h264_muxer: Option<H264StreamMuxer>,
65-
is_finished: bool,
66-
}
30+
// Add the H264 stream and create the muxer
31+
// Note: We need to add the stream before writing the header
32+
let mut h264_muxer = H264StreamMuxer::add_stream(&mut output, config)?;
6733

68-
impl MP4FileExample {
69-
fn new(output_path: PathBuf, video_config: MuxerConfig) -> Result<Self, ffmpeg::Error> {
70-
let mut output = format::output(&output_path)?;
34+
// You might also have other streams (like audio) added to the same output
35+
// ... add audio stream here if needed ...
7136

72-
// Add H264 stream and create muxer
73-
let h264_muxer = H264StreamMuxer::add_stream(&mut output, video_config)?;
37+
// Write the header after all streams are added
38+
output.write_header()?;
7439

75-
// You could add audio streams here too
76-
// ...
40+
// Now you can write H264 samples from MediaFoundation
41+
#[cfg(windows)]
42+
{
43+
// Example: Write samples from MediaFoundation
44+
// let sample: IMFSample = get_sample_from_media_foundation();
45+
// h264_muxer.write_sample(&sample)?;
46+
}
7747

78-
// Write header after all streams are added
79-
output.write_header()?;
48+
// Or write raw H264 data
49+
let example_h264_data = vec![0, 0, 0, 1, 0x65]; // Example keyframe NAL
50+
h264_muxer.write_h264_data(
51+
&example_h264_data,
52+
0, // pts in microseconds
53+
0, // dts in microseconds
54+
33333, // duration in microseconds (1/30 fps)
55+
true, // is_keyframe
56+
&mut output,
57+
)?;
8058

81-
Ok(Self {
82-
output,
83-
h264_muxer: Some(h264_muxer),
84-
is_finished: false,
85-
})
86-
}
59+
// Finish the muxer (doesn't write trailer)
60+
h264_muxer.finish()?;
61+
62+
// Write the trailer (this would be done by MP4File::finish())
63+
output.write_trailer()?;
8764

88-
#[cfg(windows)]
89-
fn write_sample(
90-
&mut self,
91-
sample: &windows::Win32::Media::MediaFoundation::IMFSample,
92-
) -> Result<(), Box<dyn std::error::Error>> {
93-
if let Some(muxer) = &mut self.h264_muxer {
94-
muxer.write_sample(sample, &mut self.output)?;
95-
}
9665
Ok(())
9766
}
9867

99-
fn write_h264_data(
100-
&mut self,
101-
data: &[u8],
102-
pts: i64,
103-
dts: i64,
104-
duration: i64,
105-
is_keyframe: bool,
106-
) -> Result<(), ffmpeg::Error> {
107-
if let Some(muxer) = &mut self.h264_muxer {
108-
muxer.write_h264_data(data, pts, dts, duration, is_keyframe, &mut self.output)?;
109-
}
110-
Ok(())
68+
/// Example showing how this would integrate with an MP4File-like structure
69+
struct MP4FileExample {
70+
output: format::context::Output,
71+
h264_muxer: Option<H264StreamMuxer>,
72+
is_finished: bool,
11173
}
11274

113-
fn finish(&mut self) -> Result<(), ffmpeg::Error> {
114-
if self.is_finished {
115-
return Ok(());
75+
impl MP4FileExample {
76+
fn new(output_path: PathBuf, video_config: MuxerConfig) -> Result<Self, ffmpeg::Error> {
77+
let mut output = format::output(&output_path)?;
78+
79+
// Add H264 stream and create muxer
80+
let h264_muxer = H264StreamMuxer::add_stream(&mut output, video_config)?;
81+
82+
// You could add audio streams here too
83+
// ...
84+
85+
// Write header after all streams are added
86+
output.write_header()?;
87+
88+
Ok(Self {
89+
output,
90+
h264_muxer: Some(h264_muxer),
91+
is_finished: false,
92+
})
11693
}
117-
self.is_finished = true;
11894

119-
if let Some(muxer) = &mut self.h264_muxer {
120-
muxer.finish()?;
95+
#[cfg(windows)]
96+
fn write_sample(
97+
&mut self,
98+
sample: &windows::Win32::Media::MediaFoundation::IMFSample,
99+
) -> Result<(), Box<dyn std::error::Error>> {
100+
if let Some(muxer) = &mut self.h264_muxer {
101+
muxer.write_sample(sample, &mut self.output)?;
102+
}
103+
Ok(())
121104
}
122105

123-
// Write trailer
124-
self.output.write_trailer()?;
125-
Ok(())
126-
}
127-
}
106+
fn write_h264_data(
107+
&mut self,
108+
data: &[u8],
109+
pts: i64,
110+
dts: i64,
111+
duration: i64,
112+
is_keyframe: bool,
113+
) -> Result<(), ffmpeg::Error> {
114+
if let Some(muxer) = &mut self.h264_muxer {
115+
muxer.write_h264_data(data, pts, dts, duration, is_keyframe, &mut self.output)?;
116+
}
117+
Ok(())
118+
}
128119

129-
/// Alternative approach using the owned version for standalone use
130-
fn example_with_owned_muxer() -> Result<(), Box<dyn std::error::Error>> {
131-
use mediafoundation_ffmpeg::H264SampleMuxerOwned;
132-
133-
// Initialize FFmpeg
134-
ffmpeg::init()?;
135-
136-
let config = MuxerConfig {
137-
width: 1920,
138-
height: 1080,
139-
fps: 30,
140-
bitrate: 5_000_000,
141-
};
142-
143-
// Create a standalone muxer that owns its output
144-
let mut muxer = H264SampleMuxerOwned::new_mp4(PathBuf::from("standalone_output.mp4"), config)?;
145-
146-
// Write some H264 data
147-
let example_h264_data = vec![0, 0, 0, 1, 0x65]; // Example keyframe NAL
148-
muxer.write_h264_data(
149-
&example_h264_data,
150-
0, // pts
151-
0, // dts
152-
33333, // duration
153-
true, // is_keyframe
154-
)?;
155-
156-
// The muxer automatically finishes and writes trailer when dropped
157-
muxer.finish()?;
158-
159-
Ok(())
160-
}
120+
fn finish(&mut self) -> Result<(), ffmpeg::Error> {
121+
if self.is_finished {
122+
return Ok(());
123+
}
124+
self.is_finished = true;
161125

162-
fn main() -> Result<(), Box<dyn std::error::Error>> {
163-
println!("Example 1: Using H264StreamMuxer with shared output");
164-
example_with_shared_output()?;
126+
if let Some(muxer) = &mut self.h264_muxer {
127+
muxer.finish()?;
128+
}
165129

166-
println!("\nExample 2: Using H264SampleMuxerOwned for standalone use");
167-
example_with_owned_muxer()?;
130+
// Write trailer
131+
self.output.write_trailer()?;
132+
Ok(())
133+
}
134+
}
135+
136+
/// Alternative approach using the owned version for standalone use
137+
fn example_with_owned_muxer() -> Result<(), Box<dyn std::error::Error>> {
138+
use mediafoundation_ffmpeg::H264SampleMuxerOwned;
168139

169-
println!("\nExample 3: Using MP4FileExample with integrated muxer");
170-
let mut mp4_file = MP4FileExample::new(
171-
PathBuf::from("integrated_output.mp4"),
172-
MuxerConfig {
140+
// Initialize FFmpeg
141+
ffmpeg::init()?;
142+
143+
let config = MuxerConfig {
173144
width: 1920,
174145
height: 1080,
175146
fps: 30,
176147
bitrate: 5_000_000,
177-
},
178-
)?;
148+
};
149+
150+
// Create a standalone muxer that owns its output
151+
let mut muxer =
152+
H264SampleMuxerOwned::new_mp4(PathBuf::from("standalone_output.mp4"), config)?;
179153

180-
// Write some test data
181-
let example_h264_data = vec![0, 0, 0, 1, 0x65];
182-
mp4_file.write_h264_data(&example_h264_data, 0, 0, 33333, true)?;
154+
// Write some H264 data
155+
let example_h264_data = vec![0, 0, 0, 1, 0x65]; // Example keyframe NAL
156+
muxer.write_h264_data(
157+
&example_h264_data,
158+
0, // pts
159+
0, // dts
160+
33333, // duration
161+
true, // is_keyframe
162+
)?;
183163

184-
// Finish writing
185-
mp4_file.finish()?;
164+
// The muxer automatically finishes and writes trailer when dropped
165+
muxer.finish()?;
186166

187-
Ok(())
167+
Ok(())
168+
}
169+
170+
fn main() -> Result<(), Box<dyn std::error::Error>> {
171+
println!("Example 1: Using H264StreamMuxer with shared output");
172+
example_with_shared_output()?;
173+
174+
println!("\nExample 2: Using H264SampleMuxerOwned for standalone use");
175+
example_with_owned_muxer()?;
176+
177+
println!("\nExample 3: Using MP4FileExample with integrated muxer");
178+
let mut mp4_file = MP4FileExample::new(
179+
PathBuf::from("integrated_output.mp4"),
180+
MuxerConfig {
181+
width: 1920,
182+
height: 1080,
183+
fps: 30,
184+
bitrate: 5_000_000,
185+
},
186+
)?;
187+
188+
// Write some test data
189+
let example_h264_data = vec![0, 0, 0, 1, 0x65];
190+
mp4_file.write_h264_data(&example_h264_data, 0, 0, 33333, true)?;
191+
192+
// Finish writing
193+
mp4_file.finish()?;
194+
195+
Ok(())
196+
}
188197
}

crates/recording/src/capture_pipeline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl MakeCapturePipeline for screen_capture::CMSampleBufferCapture {
222222
}
223223
}
224224

225-
#[cfg(windows)]
225+
// #[cfg(windows)]
226226
impl MakeCapturePipeline for screen_capture::Direct3DCapture {
227227
fn make_studio_mode_pipeline(
228228
mut builder: PipelineBuilder,

crates/recording/src/sources/screen_capture/macos.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::*;
2+
use cap_ffmpeg_utils::PlanarData;
23
use cidre::*;
34
use kameo::prelude::*;
45

@@ -93,8 +94,6 @@ impl Message<NewFrame> for FrameHandler {
9394
frame.set_rate(48_000);
9495
let data_bytes_size = buf_list.list().buffers[0].data_bytes_size;
9596
for i in 0..frame.planes() {
96-
use cap_media_info::PlanarData;
97-
9897
frame.plane_data_mut(i).copy_from_slice(
9998
&slice[i * data_bytes_size as usize..(i + 1) * data_bytes_size as usize],
10099
);

0 commit comments

Comments
 (0)