ffav/codec/
context.rs

1use super::decoder::Decoder;
2use super::encoder::Encoder;
3use super::{threading, Compliance, Debug, Flags, Id, Parameters};
4use crate::ffi::*;
5use crate::media;
6use crate::{Codec, Error};
7use libc::c_int;
8use std::ptr;
9use std::rc::Rc;
10
11pub struct Context {
12    ptr: *mut AVCodecContext,
13    owner: Option<Rc<dyn Drop>>,
14}
15
16unsafe impl Send for Context {}
17
18impl Context {
19    pub unsafe fn wrap(ptr: *mut AVCodecContext, owner: Option<Rc<dyn Drop>>) -> Self {
20        Context { ptr, owner }
21    }
22
23    pub unsafe fn as_ptr(&self) -> *const AVCodecContext {
24        self.ptr as *const _
25    }
26
27    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVCodecContext {
28        self.ptr
29    }
30}
31
32impl Context {
33    pub fn new() -> Self {
34        unsafe {
35            Context {
36                ptr: avcodec_alloc_context3(ptr::null()),
37                owner: None,
38            }
39        }
40    }
41
42    pub fn decoder(self) -> Decoder {
43        Decoder(self)
44    }
45
46    pub fn encoder(self) -> Encoder {
47        Encoder(self)
48    }
49
50    pub fn codec(&self) -> Option<Codec> {
51        unsafe {
52            if (*self.as_ptr()).codec.is_null() {
53                None
54            } else {
55                Some(Codec::wrap((*self.as_ptr()).codec as *mut _))
56            }
57        }
58    }
59
60    pub fn medium(&self) -> media::Type {
61        unsafe { media::Type::from((*self.as_ptr()).codec_type) }
62    }
63
64    pub fn set_flags(&mut self, value: Flags) {
65        unsafe {
66            (*self.as_mut_ptr()).flags = value.bits() as c_int;
67        }
68    }
69
70    pub fn id(&self) -> Id {
71        unsafe { Id::from((*self.as_ptr()).codec_id) }
72    }
73
74    pub fn compliance(&mut self, value: Compliance) {
75        unsafe {
76            (*self.as_mut_ptr()).strict_std_compliance = value.into();
77        }
78    }
79
80    pub fn debug(&mut self, value: Debug) {
81        unsafe {
82            (*self.as_mut_ptr()).debug = value.bits();
83        }
84    }
85
86    pub fn set_threading(&mut self, config: threading::Config) {
87        unsafe {
88            (*self.as_mut_ptr()).thread_type = config.kind.into();
89            (*self.as_mut_ptr()).thread_count = config.count as c_int;
90            (*self.as_mut_ptr()).thread_safe_callbacks = if config.safe { 1 } else { 0 };
91        }
92    }
93
94    pub fn threading(&self) -> threading::Config {
95        unsafe {
96            threading::Config {
97                kind: threading::Type::from((*self.as_ptr()).active_thread_type),
98                count: (*self.as_ptr()).thread_count as usize,
99                safe: (*self.as_ptr()).thread_safe_callbacks != 0,
100            }
101        }
102    }
103
104    pub fn set_parameters<P: Into<Parameters>>(&mut self, parameters: P) -> Result<(), Error> {
105        let parameters = parameters.into();
106
107        unsafe {
108            match avcodec_parameters_to_context(self.as_mut_ptr(), parameters.as_ptr()) {
109                e if e < 0 => Err(Error::from(e)),
110                _ => Ok(()),
111            }
112        }
113    }
114}
115
116impl Default for Context {
117    fn default() -> Self {
118        Self::new()
119    }
120}
121
122impl Drop for Context {
123    fn drop(&mut self) {
124        unsafe {
125            if self.owner.is_none() {
126                avcodec_free_context(&mut self.as_mut_ptr());
127            }
128        }
129    }
130}
131
132impl Clone for Context {
133    fn clone(&self) -> Self {
134        let mut ctx = Context::new();
135        ctx.clone_from(self);
136
137        ctx
138    }
139
140    fn clone_from(&mut self, source: &Self) {
141        unsafe {
142            avcodec_copy_context(self.as_mut_ptr(), source.as_ptr());
143        }
144    }
145}