ffmpeg_next_crossfix/codec/
context.rs

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