ffmpeg_next/codec/
context.rs1use 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, Rational};
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 new_with_codec(codec: Codec) -> Self {
45 unsafe {
46 Context {
47 ptr: avcodec_alloc_context3(codec.as_ptr()),
48 owner: None,
49 }
50 }
51 }
52
53 pub fn from_parameters<P: Into<Parameters>>(parameters: P) -> Result<Self, Error> {
54 let parameters = parameters.into();
55 let mut context = Self::new();
56
57 unsafe {
58 match avcodec_parameters_to_context(context.as_mut_ptr(), parameters.as_ptr()) {
59 e if e < 0 => Err(Error::from(e)),
60 _ => Ok(context),
61 }
62 }
63 }
64
65 pub fn decoder(self) -> Decoder {
66 Decoder(self)
67 }
68
69 pub fn encoder(self) -> Encoder {
70 Encoder(self)
71 }
72
73 pub fn codec(&self) -> Option<Codec> {
74 unsafe {
75 if (*self.as_ptr()).codec.is_null() {
76 None
77 } else {
78 Some(Codec::wrap((*self.as_ptr()).codec as *mut _))
79 }
80 }
81 }
82
83 pub fn medium(&self) -> media::Type {
84 unsafe { media::Type::from((*self.as_ptr()).codec_type) }
85 }
86
87 pub fn set_flags(&mut self, value: Flags) {
88 unsafe {
89 (*self.as_mut_ptr()).flags = value.bits() as c_int;
90 }
91 }
92
93 pub fn id(&self) -> Id {
94 unsafe { Id::from((*self.as_ptr()).codec_id) }
95 }
96
97 pub fn compliance(&mut self, value: Compliance) {
98 unsafe {
99 (*self.as_mut_ptr()).strict_std_compliance = value.into();
100 }
101 }
102
103 pub fn debug(&mut self, value: Debug) {
104 unsafe {
105 (*self.as_mut_ptr()).debug = value.bits();
106 }
107 }
108
109 pub fn set_threading(&mut self, config: threading::Config) {
110 unsafe {
111 (*self.as_mut_ptr()).thread_type = config.kind.into();
112 (*self.as_mut_ptr()).thread_count = config.count as c_int;
113 #[cfg(not(feature = "ffmpeg_6_0"))]
114 {
115 (*self.as_mut_ptr()).thread_safe_callbacks = if config.safe { 1 } else { 0 };
116 }
117 }
118 }
119
120 pub fn threading(&self) -> threading::Config {
121 unsafe {
122 threading::Config {
123 kind: threading::Type::from((*self.as_ptr()).active_thread_type),
124 count: (*self.as_ptr()).thread_count as usize,
125 #[cfg(not(feature = "ffmpeg_6_0"))]
126 safe: (*self.as_ptr()).thread_safe_callbacks != 0,
127 }
128 }
129 }
130
131 pub fn set_parameters<P: Into<Parameters>>(&mut self, parameters: P) -> Result<(), Error> {
132 let parameters = parameters.into();
133
134 unsafe {
135 match avcodec_parameters_to_context(self.as_mut_ptr(), parameters.as_ptr()) {
136 e if e < 0 => Err(Error::from(e)),
137 _ => Ok(()),
138 }
139 }
140 }
141
142 pub fn time_base(&self) -> Rational {
143 unsafe { Rational::from((*self.as_ptr()).time_base) }
144 }
145
146 pub fn set_time_base<R: Into<Rational>>(&mut self, value: R) {
147 unsafe {
148 (*self.as_mut_ptr()).time_base = value.into().into();
149 }
150 }
151
152 pub fn frame_rate(&self) -> Rational {
153 unsafe { Rational::from((*self.as_ptr()).framerate) }
154 }
155
156 pub fn set_frame_rate<R: Into<Rational>>(&mut self, value: Option<R>) {
157 unsafe {
158 if let Some(value) = value {
159 (*self.as_mut_ptr()).framerate = value.into().into();
160 } else {
161 (*self.as_mut_ptr()).framerate.num = 0;
162 (*self.as_mut_ptr()).framerate.den = 1;
163 }
164 }
165 }
166}
167
168impl Default for Context {
169 fn default() -> Self {
170 Self::new()
171 }
172}
173
174impl Drop for Context {
175 fn drop(&mut self) {
176 unsafe {
177 if self.owner.is_none() {
178 avcodec_free_context(&mut self.as_mut_ptr());
179 }
180 }
181 }
182}
183
184#[cfg(not(feature = "ffmpeg_5_0"))]
185impl Clone for Context {
186 fn clone(&self) -> Self {
187 let mut ctx = Context::new();
188 ctx.clone_from(self);
189
190 ctx
191 }
192
193 fn clone_from(&mut self, source: &Self) {
194 unsafe {
195 avcodec_copy_context(self.as_mut_ptr(), source.as_ptr());
197 }
198 }
199}