1use std::ffi::CStr;
2use std::str::from_utf8_unchecked;
3
4use super::{Audio, Capabilities, Id, Profile, Video};
5use ffi::*;
6use {media, Error};
7
8#[derive(PartialEq, Eq, Copy, Clone)]
9pub struct Codec {
10 ptr: *mut AVCodec,
11}
12
13unsafe impl Send for Codec {}
14unsafe impl Sync for Codec {}
15
16impl Codec {
17 pub unsafe fn wrap(ptr: *mut AVCodec) -> Self {
18 Codec { ptr }
19 }
20
21 pub unsafe fn as_ptr(&self) -> *const AVCodec {
22 self.ptr as *const _
23 }
24
25 pub unsafe fn as_mut_ptr(&mut self) -> *mut AVCodec {
26 self.ptr
27 }
28}
29
30impl Codec {
31 pub fn is_encoder(&self) -> bool {
32 unsafe { av_codec_is_encoder(self.as_ptr()) != 0 }
33 }
34
35 pub fn is_decoder(&self) -> bool {
36 unsafe { av_codec_is_decoder(self.as_ptr()) != 0 }
37 }
38
39 pub fn name(&self) -> &str {
40 unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) }
41 }
42
43 pub fn description(&self) -> &str {
44 unsafe {
45 let long_name = (*self.as_ptr()).long_name;
46 if long_name.is_null() {
47 ""
48 } else {
49 from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
50 }
51 }
52 }
53
54 pub fn medium(&self) -> media::Type {
55 unsafe { media::Type::from((*self.as_ptr()).type_) }
56 }
57
58 pub fn id(&self) -> Id {
59 unsafe { Id::from((*self.as_ptr()).id) }
60 }
61
62 pub fn is_video(&self) -> bool {
63 self.medium() == media::Type::Video
64 }
65
66 pub fn video(self) -> Result<Video, Error> {
67 unsafe {
68 if self.medium() == media::Type::Video {
69 Ok(Video::new(self))
70 } else {
71 Err(Error::InvalidData)
72 }
73 }
74 }
75
76 pub fn is_audio(&self) -> bool {
77 self.medium() == media::Type::Audio
78 }
79
80 pub fn audio(self) -> Result<Audio, Error> {
81 unsafe {
82 if self.medium() == media::Type::Audio {
83 Ok(Audio::new(self))
84 } else {
85 Err(Error::InvalidData)
86 }
87 }
88 }
89
90 pub fn max_lowres(&self) -> i32 {
91 unsafe { (*self.as_ptr()).max_lowres.into() }
92 }
93
94 pub fn capabilities(&self) -> Capabilities {
95 unsafe { Capabilities::from_bits_truncate((*self.as_ptr()).capabilities as u32) }
96 }
97
98 pub fn profiles(&self) -> Option<ProfileIter> {
99 unsafe {
100 if (*self.as_ptr()).profiles.is_null() {
101 None
102 } else {
103 Some(ProfileIter::new(self.id(), (*self.as_ptr()).profiles))
104 }
105 }
106 }
107}
108
109pub struct ProfileIter {
110 id: Id,
111 ptr: *const AVProfile,
112}
113
114impl ProfileIter {
115 pub fn new(id: Id, ptr: *const AVProfile) -> Self {
116 ProfileIter { id, ptr }
117 }
118}
119
120impl Iterator for ProfileIter {
121 type Item = Profile;
122
123 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
124 unsafe {
125 if (*self.ptr).profile == FF_PROFILE_UNKNOWN {
126 return None;
127 }
128
129 let profile: Profile = Profile::from((self.id, (*self.ptr).profile));
130 self.ptr = self.ptr.offset(count:1);
131
132 Some(profile)
133 }
134 }
135}
136