util/dictionary: refactor and make more sound
This commit is contained in:
@ -55,7 +55,12 @@ impl Decoder {
|
|||||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Opened, Error> {
|
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Opened, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if codec.is_decoder() {
|
if codec.is_decoder() {
|
||||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut options.take()) {
|
let mut opts = options.disown();
|
||||||
|
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||||
|
|
||||||
|
Dictionary::own(opts);
|
||||||
|
|
||||||
|
match res {
|
||||||
0 => Ok(Opened(self)),
|
0 => Ok(Opened(self)),
|
||||||
e => Err(Error::from(e))
|
e => Err(Error::from(e))
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,12 @@ impl Audio {
|
|||||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if codec.is_encoder() {
|
if codec.is_encoder() {
|
||||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut options.take()) {
|
let mut opts = options.disown();
|
||||||
|
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||||
|
|
||||||
|
Dictionary::own(opts);
|
||||||
|
|
||||||
|
match res {
|
||||||
0 => Ok(Encoder(self)),
|
0 => Ok(Encoder(self)),
|
||||||
e => Err(Error::from(e))
|
e => Err(Error::from(e))
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,12 @@ impl Subtitle {
|
|||||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if codec.is_encoder() {
|
if codec.is_encoder() {
|
||||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut options.take()) {
|
let mut opts = options.disown();
|
||||||
|
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||||
|
|
||||||
|
Dictionary::own(opts);
|
||||||
|
|
||||||
|
match res {
|
||||||
0 => Ok(Encoder(self)),
|
0 => Ok(Encoder(self)),
|
||||||
e => Err(Error::from(e))
|
e => Err(Error::from(e))
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,12 @@ impl Video {
|
|||||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if codec.is_encoder() {
|
if codec.is_encoder() {
|
||||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut options.take()) {
|
let mut opts = options.disown();
|
||||||
|
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||||
|
|
||||||
|
Dictionary::own(opts);
|
||||||
|
|
||||||
|
match res {
|
||||||
0 => Ok(Encoder(self)),
|
0 => Ok(Encoder(self)),
|
||||||
e => Err(Error::from(e))
|
e => Err(Error::from(e))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use std::ptr;
|
|||||||
|
|
||||||
use ffi::*;
|
use ffi::*;
|
||||||
use libc::{c_int, c_uint};
|
use libc::{c_int, c_uint};
|
||||||
use ::{media, Stream, StreamMut, Dictionary};
|
use ::{media, Stream, StreamMut, DictionaryRef};
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
ptr: *mut AVFormatContext,
|
ptr: *mut AVFormatContext,
|
||||||
@ -60,9 +60,9 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata(&self) -> Dictionary {
|
pub fn metadata(&self) -> DictionaryRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
Dictionary::wrap((*self.as_ptr()).metadata)
|
DictionaryRef::wrap((*self.as_ptr()).metadata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,12 @@ impl Output {
|
|||||||
|
|
||||||
pub fn write_header_with(&mut self, options: Dictionary) -> Result<(), Error> {
|
pub fn write_header_with(&mut self, options: Dictionary) -> Result<(), Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut opts = options.take();
|
let mut opts = options.disown();
|
||||||
let status = avformat_write_header(self.as_mut_ptr(), &mut opts);
|
let res = avformat_write_header(self.as_mut_ptr(), &mut opts);
|
||||||
|
|
||||||
Dictionary::own(opts);
|
Dictionary::own(opts);
|
||||||
|
|
||||||
match status {
|
match res {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
e => Err(Error::from(e)),
|
e => Err(Error::from(e)),
|
||||||
}
|
}
|
||||||
|
@ -100,14 +100,16 @@ pub fn open_with<P: AsRef<Path>>(path: &P, format: &Format, options: Dictionary)
|
|||||||
unsafe {
|
unsafe {
|
||||||
let mut ps = ptr::null_mut();
|
let mut ps = ptr::null_mut();
|
||||||
let path = from_path(path);
|
let path = from_path(path);
|
||||||
let mut opts = options.take();
|
let mut opts = options.disown();
|
||||||
|
|
||||||
match format {
|
match format {
|
||||||
&Format::Input(ref format) => {
|
&Format::Input(ref format) => {
|
||||||
match avformat_open_input(&mut ps, path.as_ptr(), format.as_ptr(), &mut opts) {
|
let res = avformat_open_input(&mut ps, path.as_ptr(), format.as_ptr(), &mut opts);
|
||||||
0 => {
|
|
||||||
Dictionary::own(opts);
|
|
||||||
|
|
||||||
|
Dictionary::own(opts);
|
||||||
|
|
||||||
|
match res {
|
||||||
|
0 => {
|
||||||
match avformat_find_stream_info(ps, ptr::null_mut()) {
|
match avformat_find_stream_info(ps, ptr::null_mut()) {
|
||||||
0 => Ok(Context::Input(context::Input::wrap(ps))),
|
0 => Ok(Context::Input(context::Input::wrap(ps))),
|
||||||
e => Err(Error::from(e)),
|
e => Err(Error::from(e)),
|
||||||
@ -156,12 +158,13 @@ pub fn input_with<P: AsRef<Path>>(path: &P, options: Dictionary) -> Result<conte
|
|||||||
unsafe {
|
unsafe {
|
||||||
let mut ps = ptr::null_mut();
|
let mut ps = ptr::null_mut();
|
||||||
let path = from_path(path);
|
let path = from_path(path);
|
||||||
let mut opts = options.take();
|
let mut opts = options.disown();
|
||||||
|
let res = avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), &mut opts);
|
||||||
|
|
||||||
match avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), &mut opts) {
|
Dictionary::own(opts);
|
||||||
|
|
||||||
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
Dictionary::own(opts);
|
|
||||||
|
|
||||||
match avformat_find_stream_info(ps, ptr::null_mut()) {
|
match avformat_find_stream_info(ps, ptr::null_mut()) {
|
||||||
0 => Ok(context::Input::wrap(ps)),
|
0 => Ok(context::Input::wrap(ps)),
|
||||||
e => Err(Error::from(e))
|
e => Err(Error::from(e))
|
||||||
|
@ -9,7 +9,10 @@ pub use sys as ffi;
|
|||||||
|
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub use util::error::Error;
|
pub use util::error::Error;
|
||||||
pub use util::dictionary::Dictionary;
|
pub use util::dictionary;
|
||||||
|
pub use util::dictionary::Owned as Dictionary;
|
||||||
|
pub use util::dictionary::Ref as DictionaryRef;
|
||||||
|
pub use util::dictionary::Mut as DictionaryMut;
|
||||||
pub use util::rational::{self, Rational};
|
pub use util::rational::{self, Rational};
|
||||||
pub use util::media;
|
pub use util::media;
|
||||||
pub use util::picture;
|
pub use util::picture;
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
use std::marker::PhantomData;
|
|
||||||
use std::ptr;
|
|
||||||
use std::ffi::{CStr, CString};
|
|
||||||
use std::str::from_utf8_unchecked;
|
|
||||||
|
|
||||||
use ffi::*;
|
|
||||||
|
|
||||||
pub struct Dictionary<'a> {
|
|
||||||
ptr: *mut AVDictionary,
|
|
||||||
|
|
||||||
_own: bool,
|
|
||||||
_marker: PhantomData<&'a ()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Dictionary<'a> {
|
|
||||||
pub unsafe fn wrap(ptr: *mut AVDictionary) -> Self {
|
|
||||||
Dictionary { ptr: ptr, _own: false, _marker: PhantomData }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn own(ptr: *mut AVDictionary) -> Self {
|
|
||||||
Dictionary { ptr: ptr, _own: true, _marker: PhantomData }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn as_ptr(&self) -> *const AVDictionary {
|
|
||||||
self.ptr as *const _
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVDictionary {
|
|
||||||
self.ptr
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn take(mut self) -> *mut AVDictionary {
|
|
||||||
self._own = false;
|
|
||||||
self.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Dictionary<'a> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Dictionary { ptr: ptr::null_mut(), _own: true, _marker: PhantomData }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set(&mut self, key: &str, value: &str) {
|
|
||||||
unsafe {
|
|
||||||
let key = CString::new(key).unwrap();
|
|
||||||
let value = CString::new(value).unwrap();
|
|
||||||
let mut ptr = self.as_mut_ptr();
|
|
||||||
|
|
||||||
if av_dict_set(&mut ptr, key.as_ptr(), value.as_ptr(), 0) < 0 {
|
|
||||||
panic!("out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.ptr = ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&'a self, key: &str) -> Option<&'a str> {
|
|
||||||
unsafe {
|
|
||||||
let key = CString::new(key).unwrap();
|
|
||||||
let entry = av_dict_get(self.as_ptr(), key.as_ptr(), ptr::null_mut(), 0);
|
|
||||||
|
|
||||||
if entry.is_null() {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Some(from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> DictionaryIter {
|
|
||||||
unsafe {
|
|
||||||
DictionaryIter::new(self.as_ptr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Clone for Dictionary<'a> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
let mut dictionary = Dictionary::new();
|
|
||||||
dictionary.clone_from(self);
|
|
||||||
|
|
||||||
dictionary
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_from(&mut self, source: &Self) {
|
|
||||||
unsafe {
|
|
||||||
let mut ptr = self.as_mut_ptr();
|
|
||||||
av_dict_copy(&mut ptr, source.as_ptr(), 0);
|
|
||||||
self.ptr = ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> IntoIterator for &'a Dictionary<'a> {
|
|
||||||
type Item = (&'a str, &'a str);
|
|
||||||
type IntoIter = DictionaryIter<'a>;
|
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
self.iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Drop for Dictionary<'a> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
if self._own && self.as_ptr() != ptr::null() {
|
|
||||||
av_dict_free(&mut self.as_mut_ptr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DictionaryIter<'a> {
|
|
||||||
ptr: *const AVDictionary,
|
|
||||||
cur: *mut AVDictionaryEntry,
|
|
||||||
|
|
||||||
_marker: PhantomData<&'a Dictionary<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DictionaryIter<'a> {
|
|
||||||
pub fn new(dictionary: *const AVDictionary) -> Self {
|
|
||||||
DictionaryIter {
|
|
||||||
ptr: dictionary,
|
|
||||||
cur: ptr::null_mut(),
|
|
||||||
|
|
||||||
_marker: PhantomData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for DictionaryIter<'a> {
|
|
||||||
type Item = (&'a str, &'a str);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
|
||||||
unsafe {
|
|
||||||
let empty = CString::new("").unwrap();
|
|
||||||
let entry = av_dict_get(self.ptr, empty.as_ptr(), self.cur, AV_DICT_IGNORE_SUFFIX);
|
|
||||||
|
|
||||||
if !entry.is_null() {
|
|
||||||
let key = from_utf8_unchecked(CStr::from_ptr((*entry).key).to_bytes());
|
|
||||||
let val = from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes());
|
|
||||||
|
|
||||||
self.cur = entry;
|
|
||||||
|
|
||||||
Some((key, val))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
58
src/util/dictionary/immutable.rs
Normal file
58
src/util/dictionary/immutable.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ptr;
|
||||||
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use super::{Iter, Owned};
|
||||||
|
|
||||||
|
pub struct Ref<'a> {
|
||||||
|
ptr: *const AVDictionary,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Ref<'a> {
|
||||||
|
pub unsafe fn wrap(ptr: *const AVDictionary) -> Self {
|
||||||
|
Ref { ptr: ptr, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_ptr(&self) -> *const AVDictionary {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Ref<'a> {
|
||||||
|
pub fn get(&'a self, key: &str) -> Option<&'a str> {
|
||||||
|
unsafe {
|
||||||
|
let key = CString::new(key).unwrap();
|
||||||
|
let entry = av_dict_get(self.as_ptr(), key.as_ptr(), ptr::null_mut(), 0);
|
||||||
|
|
||||||
|
if entry.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> Iter {
|
||||||
|
unsafe {
|
||||||
|
Iter::new(self.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_owned(&self) -> Owned {
|
||||||
|
self.iter().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoIterator for &'a Ref<'a> {
|
||||||
|
type Item = (&'a str, &'a str);
|
||||||
|
type IntoIter = Iter<'a>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.iter()
|
||||||
|
}
|
||||||
|
}
|
47
src/util/dictionary/iter.rs
Normal file
47
src/util/dictionary/iter.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ptr;
|
||||||
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
pub struct Iter<'a> {
|
||||||
|
ptr: *const AVDictionary,
|
||||||
|
cur: *mut AVDictionaryEntry,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iter<'a> {
|
||||||
|
pub fn new(dictionary: *const AVDictionary) -> Self {
|
||||||
|
Iter {
|
||||||
|
ptr: dictionary,
|
||||||
|
cur: ptr::null_mut(),
|
||||||
|
|
||||||
|
_marker: PhantomData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for Iter<'a> {
|
||||||
|
type Item = (&'a str, &'a str);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||||
|
unsafe {
|
||||||
|
let empty = CString::new("").unwrap();
|
||||||
|
let entry = av_dict_get(self.ptr, empty.as_ptr(), self.cur, AV_DICT_IGNORE_SUFFIX);
|
||||||
|
|
||||||
|
if !entry.is_null() {
|
||||||
|
let key = from_utf8_unchecked(CStr::from_ptr((*entry).key).to_bytes());
|
||||||
|
let val = from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes());
|
||||||
|
|
||||||
|
self.cur = entry;
|
||||||
|
|
||||||
|
Some((key, val))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/util/dictionary/mod.rs
Normal file
11
src/util/dictionary/mod.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
mod immutable;
|
||||||
|
pub use self::immutable::Ref;
|
||||||
|
|
||||||
|
mod mutable;
|
||||||
|
pub use self::mutable::Ref as Mut;
|
||||||
|
|
||||||
|
mod owned;
|
||||||
|
pub use self::owned::Owned;
|
||||||
|
|
||||||
|
mod iter;
|
||||||
|
pub use self::iter::Iter;
|
47
src/util/dictionary/mutable.rs
Normal file
47
src/util/dictionary/mutable.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use super::immutable;
|
||||||
|
|
||||||
|
pub struct Ref<'a> {
|
||||||
|
ptr: *mut AVDictionary,
|
||||||
|
imm: immutable::Ref<'a>,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Ref<'a> {
|
||||||
|
pub unsafe fn wrap(ptr: *mut AVDictionary) -> Self {
|
||||||
|
Ref { ptr: ptr, imm: immutable::Ref::wrap(ptr), _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_mut_ptr(&self) -> *mut AVDictionary {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Ref<'a> {
|
||||||
|
pub fn set(&mut self, key: &str, value: &str) {
|
||||||
|
unsafe {
|
||||||
|
let key = CString::new(key).unwrap();
|
||||||
|
let value = CString::new(value).unwrap();
|
||||||
|
let mut ptr = self.as_mut_ptr();
|
||||||
|
|
||||||
|
if av_dict_set(&mut ptr, key.as_ptr(), value.as_ptr(), 0) < 0 {
|
||||||
|
panic!("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ptr = ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref for Ref<'a> {
|
||||||
|
type Target = immutable::Ref<'a>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.imm
|
||||||
|
}
|
||||||
|
}
|
82
src/util/dictionary/owned.rs
Normal file
82
src/util/dictionary/owned.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use super::mutable;
|
||||||
|
|
||||||
|
pub struct Owned<'a> {
|
||||||
|
inner: mutable::Ref<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Owned<'a> {
|
||||||
|
pub unsafe fn own(ptr: *mut AVDictionary) -> Self {
|
||||||
|
Owned { inner: mutable::Ref::wrap(ptr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn disown(mut self) -> *mut AVDictionary {
|
||||||
|
let result = self.inner.as_mut_ptr();
|
||||||
|
self.inner = mutable::Ref::wrap(ptr::null_mut());
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Owned<'a> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
unsafe {
|
||||||
|
Owned { inner: mutable::Ref::wrap(ptr::null_mut()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> FromIterator<(&'b str, &'b str)> for Owned<'a> {
|
||||||
|
fn from_iter<T: IntoIterator<Item=(&'b str, &'b str)>>(iterator: T) -> Self {
|
||||||
|
let mut result = Owned::new();
|
||||||
|
|
||||||
|
for (key, value) in iterator {
|
||||||
|
result.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref for Owned<'a> {
|
||||||
|
type Target = mutable::Ref<'a>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DerefMut for Owned<'a> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Clone for Owned<'a> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let mut dictionary = Owned::new();
|
||||||
|
dictionary.clone_from(self);
|
||||||
|
|
||||||
|
dictionary
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_from(&mut self, source: &Self) {
|
||||||
|
unsafe {
|
||||||
|
let mut ptr = self.as_mut_ptr();
|
||||||
|
av_dict_copy(&mut ptr, source.as_ptr(), 0);
|
||||||
|
self.inner = mutable::Ref::wrap(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for Owned<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
av_dict_free(&mut self.inner.as_mut_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ pub use self::flag::Flags;
|
|||||||
|
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use ffi::*;
|
use ffi::*;
|
||||||
use ::Dictionary;
|
use ::{Dictionary, DictionaryRef};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
pub struct Packet {
|
pub struct Packet {
|
||||||
@ -106,15 +106,15 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata(&self) -> Dictionary {
|
pub fn metadata(&self) -> DictionaryRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
Dictionary::wrap(av_frame_get_metadata(self.as_ptr()))
|
DictionaryRef::wrap(av_frame_get_metadata(self.as_ptr()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_metadata(&mut self, value: Dictionary) {
|
pub fn set_metadata(&mut self, value: Dictionary) {
|
||||||
unsafe {
|
unsafe {
|
||||||
av_frame_set_metadata(self.as_mut_ptr(), value.take());
|
av_frame_set_metadata(self.as_mut_ptr(), value.disown());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use std::str::from_utf8_unchecked;
|
|||||||
|
|
||||||
use ffi::*;
|
use ffi::*;
|
||||||
use super::Frame;
|
use super::Frame;
|
||||||
use ::Dictionary;
|
use ::DictionaryRef;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
@ -108,9 +108,9 @@ impl<'a> SideData<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn metadata(&self) -> Dictionary {
|
pub fn metadata(&self) -> DictionaryRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
Dictionary::wrap((*self.as_ptr()).metadata)
|
DictionaryRef::wrap((*self.as_ptr()).metadata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user