Skip to main content

AMFLibrary

Struct AMFLibrary 

Source
pub struct AMFLibrary { /* private fields */ }

Implementations§

Source§

impl AMFLibrary

Source

pub fn query_version(&self) -> Result<u64, AMFResult>

Examples found in repository?
examples/simple_encode.rs (line 63)
61fn main() {
62    let library = amf_init().unwrap();
63    let version = library.query_version().unwrap();
64    let factory = library.init_factory(version).unwrap();
65    let trace = factory.get_trace().unwrap();
66    trace.set_writer_enabled::<AMFTraceWriterConsole>(true);
67    trace.set_writer_enabled::<AMFTraceWriterDebugOutput>(true);
68
69    let context = factory.create_context().unwrap();
70    let context = context.cast::<AMFContext1>().unwrap();
71    #[cfg(windows)]
72    if MEMORY_TYPE == amffi::core::data::AMFMemoryType::DX11 {
73        context
74            .init_dx11(
75                None,
76                amffi::core::data::AMFDXVersion::DX11_0,
77            )
78            .unwrap()
79    }
80    if MEMORY_TYPE == amffi::core::data::AMFMemoryType::Vulkan {
81        context.init_vulkan(None).unwrap();
82    }
83
84    let (surface_1, surface_2) = prepare_fill_from_host(&context).unwrap();
85
86    let encoder = factory
87        .create_component(&context, CODECS[CODEC_IDX])
88        .unwrap();
89
90    if CODECS[CODEC_IDX] == AMF_VIDEO_ENCODER_VCE_AVC {
91        encoder
92            .set_property(
93                AMF_VIDEO_ENCODER_USAGE,
94                AMFVideoEncoderUsage::Transcoding as i64,
95            )
96            .unwrap();
97        encoder
98            .set_property(AMF_VIDEO_ENCODER_TARGET_BITRATE, 5_000_000i64)
99            .unwrap();
100        let size = AMFSize::new(WIDTH, HEIGHT);
101        encoder
102            .set_property(AMF_VIDEO_ENCODER_FRAMESIZE, size)
103            .unwrap();
104        let rate = AMFRate::new(30, 1);
105        encoder
106            .set_property(AMF_VIDEO_ENCODER_FRAMERATE, rate)
107            .unwrap();
108    }
109
110    if CODECS[CODEC_IDX] == AMF_VIDEO_ENCODER_HEVC {
111        encoder
112            .set_property(
113                AMF_VIDEO_ENCODER_HEVC_USAGE,
114                AMFVideoEncoderHevcUsage::Transcoding as i64,
115            )
116            .unwrap();
117        encoder
118            .set_property(AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, 5_000_000i64)
119            .unwrap();
120        let size = AMFSize::new(WIDTH, HEIGHT);
121        encoder
122            .set_property(AMF_VIDEO_ENCODER_HEVC_FRAMESIZE, size)
123            .unwrap();
124        let rate = AMFRate::new(30, 1);
125        encoder
126            .set_property(AMF_VIDEO_ENCODER_HEVC_FRAMERATE, rate)
127            .unwrap();
128    }
129
130    if CODECS[CODEC_IDX] == AMF_VIDEO_ENCODER_AV1 {
131        encoder
132            .set_property(
133                AMF_VIDEO_ENCODER_AV1_USAGE,
134                AMFVideoEncoderHevcUsage::Transcoding as i64,
135            )
136            .unwrap();
137        encoder
138            .set_property(AMF_VIDEO_ENCODER_AV1_TARGET_BITRATE, 5_000_000i64)
139            .unwrap();
140        let size = AMFSize::new(WIDTH, HEIGHT);
141        encoder
142            .set_property(AMF_VIDEO_ENCODER_AV1_FRAMESIZE, size)
143            .unwrap();
144        let rate = AMFRate::new(30, 1);
145        encoder
146            .set_property(AMF_VIDEO_ENCODER_AV1_FRAMERATE, rate)
147            .unwrap();
148    }
149
150    encoder
151        .init(amffi::core::surface::AMFSurfaceFormat::Nv12, WIDTH, HEIGHT)
152        .unwrap();
153
154    let handle = std::thread::spawn({
155        let encoder = encoder.clone();
156        move || {
157            let mut file = File::create(CODEC_PATH[CODEC_IDX]).unwrap();
158            loop {
159                let output = encoder.query_output();
160                match output {
161                    Ok(data) => {
162                        let buffer: AMFBuffer = data.cast().unwrap();
163                        file.write_all(unsafe {
164                            std::slice::from_raw_parts(
165                                buffer.get_native() as _,
166                                buffer.get_size() as usize,
167                            )
168                        })
169                        .unwrap();
170                    }
171                    Err(AMFError::Eof) => {
172                        break;
173                    }
174                    Err(AMFError::Repeat) => {}
175                    Err(e) => panic!("{e:?}"),
176                }
177            }
178        }
179    });
180
181    let mut submitted = 0;
182    let mut surface_in = None;
183
184    let mut x_pos = 0;
185    let mut y_pos = 0;
186
187    while submitted < 600 {
188        if surface_in.is_none() {
189            surface_in = Some(
190                context
191                    .alloc_surface(
192                        MEMORY_TYPE,
193                        amffi::core::surface::AMFSurfaceFormat::Nv12,
194                        WIDTH,
195                        HEIGHT,
196                    )
197                    .unwrap(),
198            );
199
200            #[cfg(windows)]
201            if MEMORY_TYPE == amffi::core::data::AMFMemoryType::DX11 {
202                fill_surface_dx11(
203                    &context,
204                    &surface_in.clone().unwrap(),
205                    &surface_1,
206                    &surface_2,
207                    &mut x_pos,
208                    &mut y_pos,
209                );
210            }
211
212            if MEMORY_TYPE == amffi::core::data::AMFMemoryType::Vulkan {
213                fill_surface_vulkan(
214                    &context,
215                    &surface_in.clone().unwrap(),
216                    &surface_1,
217                    &surface_2,
218                    &mut x_pos,
219                    &mut y_pos,
220                );
221            }
222        }
223
224        let instant = Instant::now();
225        surface_in = if let Some(surface) = &surface_in {
226            surface
227                .set_property(
228                    widecstr!("StartTimeProperty"),
229                    Instant::now().duration_since(instant).as_nanos() as i64,
230                )
231                .unwrap();
232            let result = encoder.submit_input(surface);
233            match result {
234                Ok(()) => {
235                    submitted += 1;
236                    None
237                }
238                Err(AMFError::InputFull) => {
239                    std::thread::sleep(Duration::from_millis(1));
240                    surface_in
241                }
242                Err(e) => panic!("{e:?}"),
243            }
244        } else {
245            surface_in
246        };
247    }
248    let mut res = encoder.drain();
249    while res != Ok(()) {
250        res = encoder.drain();
251    }
252
253    // Stop the encoding thread, even though it's already finished
254    let _ = handle.join();
255
256    encoder.terminate().unwrap();
257}
Source

pub fn init_factory(&self, version_number: u64) -> Result<AMFFactory, AMFResult>

Examples found in repository?
examples/debug.rs (line 10)
8fn main() {
9    let lib = amffi::amf_init().unwrap();
10    let factory = lib.init_factory(AMF_VERSION).unwrap();
11    let debug = factory.get_debug().unwrap();
12    let trace = factory.get_trace().unwrap();
13    trace.set_writer_enabled::<AMFTraceWriterConsole>(true);
14    trace.set_writer_enabled::<AMFTraceWriterDebugOutput>(true);
15
16    debug.asserts_enable(false);
17    println!("asserts_enabled: {}", debug.asserts_enabled());
18    debug.asserts_enable(true);
19    println!("asserts_enabled: {}", debug.asserts_enabled());
20
21    println!(
22        "performance_monitor: {}",
23        debug.performance_monitor_enabled()
24    );
25    debug.enable_performance_monitor(true);
26    println!("asserts_enabled: {}", debug.performance_monitor_enabled());
27
28    trace
29        .trace_w(
30            amffi::core::trace::AMFTraceLevel::Info,
31            "AMFTraceTest",
32            format!("Write something out to the enabled traces"),
33        )
34        .unwrap();
35}
More examples
Hide additional examples
examples/simple_encode.rs (line 64)
61fn main() {
62    let library = amf_init().unwrap();
63    let version = library.query_version().unwrap();
64    let factory = library.init_factory(version).unwrap();
65    let trace = factory.get_trace().unwrap();
66    trace.set_writer_enabled::<AMFTraceWriterConsole>(true);
67    trace.set_writer_enabled::<AMFTraceWriterDebugOutput>(true);
68
69    let context = factory.create_context().unwrap();
70    let context = context.cast::<AMFContext1>().unwrap();
71    #[cfg(windows)]
72    if MEMORY_TYPE == amffi::core::data::AMFMemoryType::DX11 {
73        context
74            .init_dx11(
75                None,
76                amffi::core::data::AMFDXVersion::DX11_0,
77            )
78            .unwrap()
79    }
80    if MEMORY_TYPE == amffi::core::data::AMFMemoryType::Vulkan {
81        context.init_vulkan(None).unwrap();
82    }
83
84    let (surface_1, surface_2) = prepare_fill_from_host(&context).unwrap();
85
86    let encoder = factory
87        .create_component(&context, CODECS[CODEC_IDX])
88        .unwrap();
89
90    if CODECS[CODEC_IDX] == AMF_VIDEO_ENCODER_VCE_AVC {
91        encoder
92            .set_property(
93                AMF_VIDEO_ENCODER_USAGE,
94                AMFVideoEncoderUsage::Transcoding as i64,
95            )
96            .unwrap();
97        encoder
98            .set_property(AMF_VIDEO_ENCODER_TARGET_BITRATE, 5_000_000i64)
99            .unwrap();
100        let size = AMFSize::new(WIDTH, HEIGHT);
101        encoder
102            .set_property(AMF_VIDEO_ENCODER_FRAMESIZE, size)
103            .unwrap();
104        let rate = AMFRate::new(30, 1);
105        encoder
106            .set_property(AMF_VIDEO_ENCODER_FRAMERATE, rate)
107            .unwrap();
108    }
109
110    if CODECS[CODEC_IDX] == AMF_VIDEO_ENCODER_HEVC {
111        encoder
112            .set_property(
113                AMF_VIDEO_ENCODER_HEVC_USAGE,
114                AMFVideoEncoderHevcUsage::Transcoding as i64,
115            )
116            .unwrap();
117        encoder
118            .set_property(AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, 5_000_000i64)
119            .unwrap();
120        let size = AMFSize::new(WIDTH, HEIGHT);
121        encoder
122            .set_property(AMF_VIDEO_ENCODER_HEVC_FRAMESIZE, size)
123            .unwrap();
124        let rate = AMFRate::new(30, 1);
125        encoder
126            .set_property(AMF_VIDEO_ENCODER_HEVC_FRAMERATE, rate)
127            .unwrap();
128    }
129
130    if CODECS[CODEC_IDX] == AMF_VIDEO_ENCODER_AV1 {
131        encoder
132            .set_property(
133                AMF_VIDEO_ENCODER_AV1_USAGE,
134                AMFVideoEncoderHevcUsage::Transcoding as i64,
135            )
136            .unwrap();
137        encoder
138            .set_property(AMF_VIDEO_ENCODER_AV1_TARGET_BITRATE, 5_000_000i64)
139            .unwrap();
140        let size = AMFSize::new(WIDTH, HEIGHT);
141        encoder
142            .set_property(AMF_VIDEO_ENCODER_AV1_FRAMESIZE, size)
143            .unwrap();
144        let rate = AMFRate::new(30, 1);
145        encoder
146            .set_property(AMF_VIDEO_ENCODER_AV1_FRAMERATE, rate)
147            .unwrap();
148    }
149
150    encoder
151        .init(amffi::core::surface::AMFSurfaceFormat::Nv12, WIDTH, HEIGHT)
152        .unwrap();
153
154    let handle = std::thread::spawn({
155        let encoder = encoder.clone();
156        move || {
157            let mut file = File::create(CODEC_PATH[CODEC_IDX]).unwrap();
158            loop {
159                let output = encoder.query_output();
160                match output {
161                    Ok(data) => {
162                        let buffer: AMFBuffer = data.cast().unwrap();
163                        file.write_all(unsafe {
164                            std::slice::from_raw_parts(
165                                buffer.get_native() as _,
166                                buffer.get_size() as usize,
167                            )
168                        })
169                        .unwrap();
170                    }
171                    Err(AMFError::Eof) => {
172                        break;
173                    }
174                    Err(AMFError::Repeat) => {}
175                    Err(e) => panic!("{e:?}"),
176                }
177            }
178        }
179    });
180
181    let mut submitted = 0;
182    let mut surface_in = None;
183
184    let mut x_pos = 0;
185    let mut y_pos = 0;
186
187    while submitted < 600 {
188        if surface_in.is_none() {
189            surface_in = Some(
190                context
191                    .alloc_surface(
192                        MEMORY_TYPE,
193                        amffi::core::surface::AMFSurfaceFormat::Nv12,
194                        WIDTH,
195                        HEIGHT,
196                    )
197                    .unwrap(),
198            );
199
200            #[cfg(windows)]
201            if MEMORY_TYPE == amffi::core::data::AMFMemoryType::DX11 {
202                fill_surface_dx11(
203                    &context,
204                    &surface_in.clone().unwrap(),
205                    &surface_1,
206                    &surface_2,
207                    &mut x_pos,
208                    &mut y_pos,
209                );
210            }
211
212            if MEMORY_TYPE == amffi::core::data::AMFMemoryType::Vulkan {
213                fill_surface_vulkan(
214                    &context,
215                    &surface_in.clone().unwrap(),
216                    &surface_1,
217                    &surface_2,
218                    &mut x_pos,
219                    &mut y_pos,
220                );
221            }
222        }
223
224        let instant = Instant::now();
225        surface_in = if let Some(surface) = &surface_in {
226            surface
227                .set_property(
228                    widecstr!("StartTimeProperty"),
229                    Instant::now().duration_since(instant).as_nanos() as i64,
230                )
231                .unwrap();
232            let result = encoder.submit_input(surface);
233            match result {
234                Ok(()) => {
235                    submitted += 1;
236                    None
237                }
238                Err(AMFError::InputFull) => {
239                    std::thread::sleep(Duration::from_millis(1));
240                    surface_in
241                }
242                Err(e) => panic!("{e:?}"),
243            }
244        } else {
245            surface_in
246        };
247    }
248    let mut res = encoder.drain();
249    while res != Ok(()) {
250        res = encoder.drain();
251    }
252
253    // Stop the encoding thread, even though it's already finished
254    let _ = handle.join();
255
256    encoder.terminate().unwrap();
257}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.