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