ffmpeg_the_third/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};
8use crate::ffi::*;
9use crate::media;
10use crate::option;
11use crate::{AsMutPtr, AsPtr};
12use crate::{Codec, Error};
13use libc::c_int;
14
15pub struct Context {
16 ptr: *mut AVCodecContext,
17 owner: Option<Rc<dyn Any>>,
18}
19
20unsafe impl Send for Context {}
21
22impl Context {
23 pub unsafe fn wrap(ptr: *mut AVCodecContext, owner: Option<Rc<dyn Any>>) -> Self {
24 Context { ptr, owner }
25 }
26
27 pub unsafe fn as_ptr(&self) -> *const AVCodecContext {
28 self.ptr as *const _
29 }
30
31 pub unsafe fn as_mut_ptr(&mut self) -> *mut AVCodecContext {
32 self.ptr
33 }
34}
35
36impl Context {
37 pub fn new() -> Self {
38 unsafe {
39 Context {
40 ptr: avcodec_alloc_context3(ptr::null()),
41 owner: None,
42 }
43 }
44 }
45
46 pub fn new_with_codec(codec: Codec) -> Self {
47 unsafe {
48 Context {
49 ptr: avcodec_alloc_context3(codec.as_ptr()),
50 owner: None,
51 }
52 }
53 }
54
55 pub fn from_parameters<P: AsPtr<AVCodecParameters>>(parameters: P) -> Result<Self, Error> {
56 let mut context = Self::new();
57
58 unsafe {
59 match avcodec_parameters_to_context(context.as_mut_ptr(), parameters.as_ptr()) {
60 e if e < 0 => Err(Error::from(e)),
61 _ => Ok(context),
62 }
63 }
64 }
65
66 pub fn decoder(self) -> Decoder {
67 Decoder(self)
68 }
69
70 pub fn encoder(self) -> Encoder {
71 Encoder(self)
72 }
73
74 pub fn codec(&self) -> Option<Codec> {
75 unsafe { Codec::from_raw((*self.as_ptr()).codec) }
76 }
77
78 pub fn medium(&self) -> media::Type {
79 unsafe { media::Type::from((*self.as_ptr()).codec_type) }
80 }
81
82 pub fn set_flags(&mut self, value: Flags) {
83 unsafe {
84 (*self.as_mut_ptr()).flags = value.bits() as c_int;
85 }
86 }
87
88 pub fn id(&self) -> Id {
89 unsafe { Id::from((*self.as_ptr()).codec_id) }
90 }
91
92 pub fn compliance(&mut self, value: Compliance) {
93 unsafe {
94 (*self.as_mut_ptr()).strict_std_compliance = value.into();
95 }
96 }
97
98 pub fn debug(&mut self, value: Debug) {
99 unsafe {
100 (*self.as_mut_ptr()).debug = value.bits();
101 }
102 }
103
104 pub fn set_threading(&mut self, config: threading::Config) {
105 unsafe {
106 (*self.as_mut_ptr()).thread_type = config.kind.into();
107 (*self.as_mut_ptr()).thread_count = config.count as c_int;
108 #[cfg(not(feature = "ffmpeg_6_0"))]
109 {
110 (*self.as_mut_ptr()).thread_safe_callbacks = i32::from(config.safe);
111 }
112 }
113 }
114
115 pub fn threading(&self) -> threading::Config {
116 unsafe {
117 threading::Config {
118 kind: threading::Type::from((*self.as_ptr()).active_thread_type),
119 count: (*self.as_ptr()).thread_count as usize,
120 #[cfg(not(feature = "ffmpeg_6_0"))]
121 safe: (*self.as_ptr()).thread_safe_callbacks != 0,
122 }
123 }
124 }
125
126 pub fn set_parameters<P: AsPtr<AVCodecParameters>>(
127 &mut self,
128 parameters: P,
129 ) -> Result<(), Error> {
130 unsafe {
131 match avcodec_parameters_to_context(self.as_mut_ptr(), parameters.as_ptr()) {
132 e if e < 0 => Err(Error::from(e)),
133 _ => Ok(()),
134 }
135 }
136 }
137}
138
139impl Default for Context {
140 fn default() -> Self {
141 Self::new()
142 }
143}
144
145impl Drop for Context {
146 fn drop(&mut self) {
147 unsafe {
148 if self.owner.is_none() {
149 avcodec_free_context(&mut self.as_mut_ptr());
150 }
151 }
152 }
153}
154
155#[cfg(not(feature = "ffmpeg_5_0"))]
156impl Clone for Context {
157 fn clone(&self) -> Self {
158 let mut ctx = Context::new();
159 ctx.clone_from(self);
160
161 ctx
162 }
163
164 fn clone_from(&mut self, source: &Self) {
165 unsafe {
166 avcodec_copy_context(self.as_mut_ptr(), source.as_ptr());
168 }
169 }
170}
171
172impl AsPtr<AVCodecContext> for Context {
174 fn as_ptr(&self) -> *const AVCodecContext {
175 self.ptr as *const _
176 }
177}
178
179impl AsMutPtr<AVCodecContext> for Context {
180 fn as_mut_ptr(&mut self) -> *mut AVCodecContext {
181 self.ptr as *mut _
182 }
183}
184
185impl option::Settable<AVCodecContext> for Context {}