1pub mod audio;
4pub mod bsf;
5pub mod video;
6
7use std::{
8 ffi::{CStr, CString},
9 fmt::{self, Display, Formatter},
10 os::raw::{c_char, c_int, c_void},
11 ptr, slice,
12};
13
14use crate::{
15 codec::{
16 audio::{ChannelLayoutRef, SampleFormat},
17 video::PixelFormat,
18 },
19 packet::Packet,
20 Error,
21};
22
23#[cfg(codec_params_side_data)]
24use crate::packet::{SideDataRef, SideDataType};
25
26extern "C" {
27 fn ffw_audio_codec_parameters_new(codec: *const c_char) -> *mut c_void;
28 fn ffw_video_codec_parameters_new(codec: *const c_char) -> *mut c_void;
29 fn ffw_subtitle_codec_parameters_new(codec: *const c_char) -> *mut c_void;
30 fn ffw_codec_parameters_clone(params: *const c_void) -> *mut c_void;
31 fn ffw_codec_parameters_is_audio_codec(params: *const c_void) -> c_int;
32 fn ffw_codec_parameters_is_video_codec(params: *const c_void) -> c_int;
33 fn ffw_codec_parameters_is_subtitle_codec(params: *const c_void) -> c_int;
34 fn ffw_codec_parameters_get_decoder_name(params: *const c_void) -> *const c_char;
35 fn ffw_codec_parameters_get_encoder_name(params: *const c_void) -> *const c_char;
36 fn ffw_codec_parameters_get_bit_rate(params: *const c_void) -> i64;
37 fn ffw_codec_parameters_get_format(params: *const c_void) -> c_int;
38 fn ffw_codec_parameters_get_width(params: *const c_void) -> c_int;
39 fn ffw_codec_parameters_get_height(params: *const c_void) -> c_int;
40 fn ffw_codec_parameters_get_sample_rate(params: *const c_void) -> c_int;
41 fn ffw_codec_parameters_get_channel_layout(params: *const c_void) -> *const c_void;
42 fn ffw_codec_parameters_get_codec_tag(params: *const c_void) -> u32;
43 fn ffw_codec_parameters_get_extradata(params: *mut c_void) -> *mut c_void;
44 fn ffw_codec_parameters_get_extradata_size(params: *const c_void) -> c_int;
45 fn ffw_codec_parameters_set_bit_rate(params: *mut c_void, bit_rate: i64);
46 fn ffw_codec_parameters_set_format(params: *mut c_void, format: c_int);
47 fn ffw_codec_parameters_set_width(params: *mut c_void, width: c_int);
48 fn ffw_codec_parameters_set_height(params: *mut c_void, height: c_int);
49 fn ffw_codec_parameters_set_sample_rate(params: *mut c_void, rate: c_int);
50 fn ffw_codec_parameters_set_channel_layout(params: *mut c_void, layout: *const c_void)
51 -> c_int;
52 fn ffw_codec_parameters_set_codec_tag(params: *mut c_void, codec_tag: u32);
53 fn ffw_codec_parameters_set_extradata(
54 params: *mut c_void,
55 extradata: *const u8,
56 size: c_int,
57 ) -> c_int;
58 fn ffw_codec_parameters_free(params: *mut c_void);
59
60 #[cfg(codec_params_side_data)]
61 fn ffw_codec_parameters_get_nb_coded_side_data(params: *const c_void) -> usize;
62
63 #[cfg(codec_params_side_data)]
64 fn ffw_codec_parameters_get_coded_side_data(
65 params: *const c_void,
66 index: usize,
67 ) -> *const c_void;
68
69 #[cfg(codec_params_side_data)]
70 fn ffw_codec_parameters_add_coded_side_data(
71 params: *mut c_void,
72 data_type: c_int,
73 data: *const u8,
74 size: usize,
75 ) -> c_int;
76
77 fn ffw_decoder_new(codec: *const c_char) -> *mut c_void;
78 fn ffw_decoder_from_codec_parameters(params: *const c_void) -> *mut c_void;
79 fn ffw_decoder_set_extradata(decoder: *mut c_void, extradata: *const u8, size: c_int) -> c_int;
80 fn ffw_decoder_set_initial_option(
81 decoder: *mut c_void,
82 key: *const c_char,
83 value: *const c_char,
84 ) -> c_int;
85 fn ffw_decoder_set_pkt_timebase(decoder: *mut c_void, num: c_int, den: c_int);
86 fn ffw_decoder_open(decoder: *mut c_void) -> c_int;
87 fn ffw_decoder_push_packet(decoder: *mut c_void, packet: *const c_void) -> c_int;
88 fn ffw_decoder_take_frame(decoder: *mut c_void, frame: *mut *mut c_void) -> c_int;
89 fn ffw_decoder_get_codec_parameters(decoder: *const c_void) -> *mut c_void;
90 fn ffw_decoder_free(decoder: *mut c_void);
91
92 fn ffw_encoder_new(codec: *const c_char) -> *mut c_void;
93 fn ffw_encoder_from_codec_parameters(params: *const c_void) -> *mut c_void;
94 fn ffw_encoder_get_codec_parameters(encoder: *const c_void) -> *mut c_void;
95 fn ffw_encoder_get_pixel_format(encoder: *const c_void) -> c_int;
96 fn ffw_encoder_get_width(encoder: *const c_void) -> c_int;
97 fn ffw_encoder_get_height(encoder: *const c_void) -> c_int;
98 fn ffw_encoder_get_sample_format(encoder: *const c_void) -> c_int;
99 fn ffw_encoder_get_sample_rate(encoder: *const c_void) -> c_int;
100 fn ffw_encoder_get_channel_layout(encoder: *const c_void) -> *const c_void;
101 fn ffw_encoder_get_frame_size(encoder: *const c_void) -> c_int;
102 fn ffw_encoder_set_time_base(encoder: *mut c_void, num: c_int, den: c_int);
103 fn ffw_encoder_set_bit_rate(encoder: *mut c_void, bit_rate: i64);
104 fn ffw_encoder_set_pixel_format(encoder: *mut c_void, format: c_int);
105 fn ffw_encoder_set_width(encoder: *mut c_void, width: c_int);
106 fn ffw_encoder_set_height(encoder: *mut c_void, height: c_int);
107 fn ffw_encoder_set_sample_format(encoder: *mut c_void, format: c_int);
108 fn ffw_encoder_set_sample_rate(encoder: *mut c_void, sample_rate: c_int);
109 fn ffw_encoder_set_channel_layout(encoder: *mut c_void, layout: *const c_void) -> c_int;
110 fn ffw_encoder_set_codec_tag(encoder: *mut c_void, codec_tag: u32);
111 fn ffw_encoder_set_initial_option(
112 encoder: *mut c_void,
113 key: *const c_char,
114 value: *const c_char,
115 ) -> c_int;
116 fn ffw_encoder_open(encoder: *mut c_void) -> c_int;
117 fn ffw_encoder_push_frame(encoder: *mut c_void, frame: *const c_void) -> c_int;
118 fn ffw_encoder_take_packet(encoder: *mut c_void, packet: *mut *mut c_void) -> c_int;
119 fn ffw_encoder_free(encoder: *mut c_void);
120}
121
122#[derive(Debug, Clone)]
124enum CodecErrorVariant {
125 Error(Error),
127 Again(&'static str),
130}
131
132#[derive(Debug, Clone)]
134pub struct CodecError {
135 variant: CodecErrorVariant,
136}
137
138impl CodecError {
139 fn error<T>(msg: T) -> Self
141 where
142 T: ToString,
143 {
144 Self {
145 variant: CodecErrorVariant::Error(Error::new(msg)),
146 }
147 }
148
149 fn from_raw_error_code(code: c_int) -> Self {
151 Self::from(Error::from_raw_error_code(code))
152 }
153
154 fn again(msg: &'static str) -> Self {
156 Self {
157 variant: CodecErrorVariant::Again(msg),
158 }
159 }
160
161 #[inline]
163 pub fn is_again(&self) -> bool {
164 matches!(&self.variant, CodecErrorVariant::Again(_))
165 }
166
167 #[inline]
169 pub fn into_inner(self) -> Option<Error> {
170 if let CodecErrorVariant::Error(err) = self.variant {
171 Some(err)
172 } else {
173 None
174 }
175 }
176
177 pub fn unwrap_inner(self) -> Error {
179 match self.variant {
180 CodecErrorVariant::Error(err) => err,
181 CodecErrorVariant::Again(msg) => panic!("{}", msg),
182 }
183 }
184}
185
186impl Display for CodecError {
187 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
188 match &self.variant {
189 CodecErrorVariant::Again(msg) => write!(f, "{}", msg),
190 CodecErrorVariant::Error(err) => write!(f, "{}", err),
191 }
192 }
193}
194
195impl std::error::Error for CodecError {}
196
197impl From<Error> for CodecError {
198 #[inline]
199 fn from(err: Error) -> Self {
200 Self {
201 variant: CodecErrorVariant::Error(err),
202 }
203 }
204}
205
206#[cfg(codec_params_side_data)]
208pub struct SideDataIter<'a> {
209 params: &'a InnerCodecParameters,
210 index: usize,
211 len: usize,
212}
213
214#[cfg(codec_params_side_data)]
215impl<'a> Iterator for SideDataIter<'a> {
216 type Item = &'a SideDataRef;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 if self.index == self.len {
220 return None;
221 }
222
223 let side_data = unsafe {
224 SideDataRef::from_raw_ptr(ffw_codec_parameters_get_coded_side_data(
225 self.params.ptr,
226 self.index,
227 ))
228 };
229
230 self.index += 1;
231
232 Some(side_data)
233 }
234
235 fn size_hint(&self) -> (usize, Option<usize>) {
236 let hint = self.len - self.index;
237
238 (hint, Some(hint))
239 }
240}
241
242#[cfg(codec_params_side_data)]
243impl ExactSizeIterator for SideDataIter<'_> {}
244
245struct InnerCodecParameters {
247 ptr: *mut c_void,
248}
249
250impl InnerCodecParameters {
251 unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
253 Self { ptr }
254 }
255
256 fn as_ptr(&self) -> *const c_void {
258 self.ptr
259 }
260
261 fn is_audio_codec(&self) -> bool {
263 unsafe { ffw_codec_parameters_is_audio_codec(self.ptr) != 0 }
264 }
265
266 fn is_video_codec(&self) -> bool {
268 unsafe { ffw_codec_parameters_is_video_codec(self.ptr) != 0 }
269 }
270
271 fn is_subtitle_codec(&self) -> bool {
273 unsafe { ffw_codec_parameters_is_subtitle_codec(self.ptr) != 0 }
274 }
275
276 fn get_decoder_name(&self) -> Option<&'static str> {
279 unsafe {
280 let ptr = ffw_codec_parameters_get_decoder_name(self.ptr);
281
282 if ptr.is_null() {
283 None
284 } else {
285 let name = CStr::from_ptr(ptr as _);
286
287 Some(name.to_str().unwrap())
288 }
289 }
290 }
291
292 fn get_encoder_name(&self) -> Option<&'static str> {
295 unsafe {
296 let ptr = ffw_codec_parameters_get_encoder_name(self.ptr);
297
298 if ptr.is_null() {
299 None
300 } else {
301 let name = CStr::from_ptr(ptr as _);
302
303 Some(name.to_str().unwrap())
304 }
305 }
306 }
307
308 fn get_codec_tag(&self) -> CodecTag {
310 let codec_tag = unsafe { ffw_codec_parameters_get_codec_tag(self.ptr) };
311
312 codec_tag.into()
313 }
314
315 fn set_codec_tag<T>(&mut self, codec_tag: T)
317 where
318 T: Into<CodecTag>,
319 {
320 let codec_tag = codec_tag.into();
321
322 unsafe {
323 ffw_codec_parameters_set_codec_tag(self.ptr, codec_tag.into());
324 }
325 }
326
327 fn get_bit_rate(&self) -> u64 {
329 unsafe { ffw_codec_parameters_get_bit_rate(self.ptr) as _ }
330 }
331
332 fn set_bit_rate(&mut self, bit_rate: u64) {
334 unsafe {
335 ffw_codec_parameters_set_bit_rate(self.ptr, bit_rate as _);
336 }
337 }
338
339 fn get_sample_format(&self) -> SampleFormat {
341 unsafe { SampleFormat::from_raw(ffw_codec_parameters_get_format(self.ptr)) }
342 }
343
344 fn set_sample_format(&mut self, format: SampleFormat) {
346 unsafe {
347 ffw_codec_parameters_set_format(self.ptr, format.into_raw());
348 }
349 }
350
351 fn get_sample_rate(&self) -> u32 {
353 unsafe { ffw_codec_parameters_get_sample_rate(self.ptr) as _ }
354 }
355
356 fn set_sample_rate(&mut self, rate: u32) {
358 assert!(rate > 0);
359
360 unsafe {
361 ffw_codec_parameters_set_sample_rate(self.ptr, rate as _);
362 }
363 }
364
365 fn get_channel_layout(&self) -> &ChannelLayoutRef {
367 unsafe { ChannelLayoutRef::from_raw_ptr(ffw_codec_parameters_get_channel_layout(self.ptr)) }
368 }
369
370 fn set_channel_layout(&mut self, layout: &ChannelLayoutRef) {
372 let ret = unsafe { ffw_codec_parameters_set_channel_layout(self.ptr, layout.as_ptr()) };
373
374 if ret != 0 {
375 panic!("unable to copy channel layout");
376 }
377 }
378
379 fn get_pixel_format(&self) -> PixelFormat {
381 unsafe { PixelFormat::from_raw(ffw_codec_parameters_get_format(self.ptr)) }
382 }
383
384 fn set_pixel_format(&mut self, format: PixelFormat) {
386 unsafe {
387 ffw_codec_parameters_set_format(self.ptr, format.into_raw());
388 }
389 }
390
391 fn get_width(&self) -> usize {
393 unsafe { ffw_codec_parameters_get_width(self.ptr) as _ }
394 }
395
396 fn set_width(&mut self, width: usize) {
398 unsafe {
399 ffw_codec_parameters_set_width(self.ptr, width as _);
400 }
401 }
402
403 fn get_height(&self) -> usize {
405 unsafe { ffw_codec_parameters_get_height(self.ptr) as _ }
406 }
407
408 fn set_height(&mut self, height: usize) {
410 unsafe {
411 ffw_codec_parameters_set_height(self.ptr, height as _);
412 }
413 }
414
415 fn get_extradata(&self) -> Option<&[u8]> {
417 unsafe {
418 let data = ffw_codec_parameters_get_extradata(self.ptr) as *const u8;
419 let size = ffw_codec_parameters_get_extradata_size(self.ptr) as usize;
420
421 if data.is_null() {
422 None
423 } else {
424 Some(slice::from_raw_parts(data, size))
425 }
426 }
427 }
428
429 fn set_extradata<T>(&mut self, data: Option<T>)
431 where
432 T: AsRef<[u8]>,
433 {
434 let data = data.as_ref().map(|d| d.as_ref());
435
436 let ptr;
437 let size;
438
439 if let Some(data) = data {
440 ptr = data.as_ptr();
441 size = data.len();
442 } else {
443 ptr = ptr::null();
444 size = 0;
445 }
446
447 let res = unsafe { ffw_codec_parameters_set_extradata(self.ptr, ptr, size as _) };
448
449 if res < 0 {
450 panic!("unable to allocate extradata");
451 }
452 }
453
454 #[cfg(codec_params_side_data)]
456 fn get_coded_side_data(&self) -> SideDataIter<'_> {
457 let len = unsafe { ffw_codec_parameters_get_nb_coded_side_data(self.ptr) };
458
459 SideDataIter {
460 params: self,
461 index: 0,
462 len,
463 }
464 }
465
466 #[cfg(codec_params_side_data)]
468 fn add_coded_side_data(&mut self, data_type: SideDataType, data: &[u8]) -> Result<(), Error> {
469 let ret = unsafe {
470 ffw_codec_parameters_add_coded_side_data(
471 self.ptr,
472 data_type.into_raw(),
473 data.as_ptr(),
474 data.len(),
475 )
476 };
477
478 if ret < 0 {
479 Err(Error::from_raw_error_code(ret))
480 } else {
481 Ok(())
482 }
483 }
484}
485
486impl Drop for InnerCodecParameters {
487 fn drop(&mut self) {
488 unsafe { ffw_codec_parameters_free(self.ptr) }
489 }
490}
491
492impl Clone for InnerCodecParameters {
493 fn clone(&self) -> Self {
494 let ptr = unsafe { ffw_codec_parameters_clone(self.ptr) };
495
496 if ptr.is_null() {
497 panic!("unable to clone codec parameters");
498 }
499
500 Self { ptr }
501 }
502}
503
504unsafe impl Send for InnerCodecParameters {}
505unsafe impl Sync for InnerCodecParameters {}
506
507#[derive(Clone)]
509enum CodecParametersVariant {
510 Audio(AudioCodecParameters),
511 Video(VideoCodecParameters),
512 Subtitle(SubtitleCodecParameters),
513 Other(OtherCodecParameters),
514}
515
516impl CodecParametersVariant {
517 unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
519 let inner = InnerCodecParameters::from_raw_ptr(ptr);
520
521 if inner.is_audio_codec() {
522 Self::Audio(AudioCodecParameters::from(inner))
523 } else if inner.is_video_codec() {
524 Self::Video(VideoCodecParameters::from(inner))
525 } else if inner.is_subtitle_codec() {
526 Self::Subtitle(SubtitleCodecParameters::from(inner))
527 } else {
528 Self::Other(OtherCodecParameters::from(inner))
529 }
530 }
531}
532
533impl AsRef<InnerCodecParameters> for CodecParametersVariant {
534 fn as_ref(&self) -> &InnerCodecParameters {
535 match self {
536 Self::Audio(audio) => audio.as_ref(),
537 Self::Video(video) => video.as_ref(),
538 Self::Subtitle(subtitle) => subtitle.as_ref(),
539 Self::Other(other) => other.as_ref(),
540 }
541 }
542}
543
544#[derive(Clone)]
546pub struct CodecParameters {
547 inner: CodecParametersVariant,
548}
549
550impl CodecParameters {
551 pub(crate) unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
553 Self {
554 inner: CodecParametersVariant::from_raw_ptr(ptr),
555 }
556 }
557
558 pub(crate) fn as_ptr(&self) -> *const c_void {
560 self.inner.as_ref().as_ptr()
561 }
562
563 pub fn is_audio_codec(&self) -> bool {
565 self.inner.as_ref().is_audio_codec()
566 }
567
568 pub fn is_video_codec(&self) -> bool {
570 self.inner.as_ref().is_video_codec()
571 }
572
573 pub fn is_subtitle_codec(&self) -> bool {
575 self.inner.as_ref().is_subtitle_codec()
576 }
577
578 pub fn decoder_name(&self) -> Option<&'static str> {
581 self.inner.as_ref().get_decoder_name()
582 }
583
584 pub fn encoder_name(&self) -> Option<&'static str> {
587 self.inner.as_ref().get_encoder_name()
588 }
589
590 pub fn as_audio_codec_parameters(&self) -> Option<&AudioCodecParameters> {
592 if let CodecParametersVariant::Audio(params) = &self.inner {
593 Some(params)
594 } else {
595 None
596 }
597 }
598
599 pub fn as_video_codec_parameters(&self) -> Option<&VideoCodecParameters> {
601 if let CodecParametersVariant::Video(params) = &self.inner {
602 Some(params)
603 } else {
604 None
605 }
606 }
607
608 pub fn as_subtitle_codec_parameters(&self) -> Option<&SubtitleCodecParameters> {
610 if let CodecParametersVariant::Subtitle(params) = &self.inner {
611 Some(params)
612 } else {
613 None
614 }
615 }
616
617 pub fn into_audio_codec_parameters(self) -> Option<AudioCodecParameters> {
619 if let CodecParametersVariant::Audio(params) = self.inner {
620 Some(params)
621 } else {
622 None
623 }
624 }
625
626 pub fn into_video_codec_parameters(self) -> Option<VideoCodecParameters> {
628 if let CodecParametersVariant::Video(params) = self.inner {
629 Some(params)
630 } else {
631 None
632 }
633 }
634
635 pub fn into_subtitle_codec_parameters(self) -> Option<SubtitleCodecParameters> {
637 if let CodecParametersVariant::Subtitle(params) = self.inner {
638 Some(params)
639 } else {
640 None
641 }
642 }
643}
644
645impl From<AudioCodecParameters> for CodecParameters {
646 #[inline]
647 fn from(params: AudioCodecParameters) -> Self {
648 Self {
649 inner: CodecParametersVariant::Audio(params),
650 }
651 }
652}
653
654impl From<VideoCodecParameters> for CodecParameters {
655 #[inline]
656 fn from(params: VideoCodecParameters) -> Self {
657 Self {
658 inner: CodecParametersVariant::Video(params),
659 }
660 }
661}
662impl From<SubtitleCodecParameters> for CodecParameters {
663 #[inline]
664 fn from(params: SubtitleCodecParameters) -> Self {
665 Self {
666 inner: CodecParametersVariant::Subtitle(params),
667 }
668 }
669}
670
671pub struct AudioCodecParametersBuilder {
673 inner: InnerCodecParameters,
674}
675
676impl AudioCodecParametersBuilder {
677 fn new(codec: &str) -> Result<Self, Error> {
679 let codec = CString::new(codec).expect("invalid codec name");
680
681 let ptr = unsafe { ffw_audio_codec_parameters_new(codec.as_ptr() as *const _) };
682
683 if ptr.is_null() {
684 return Err(Error::new("unknown codec"));
685 }
686
687 let params = unsafe { InnerCodecParameters::from_raw_ptr(ptr) };
688
689 let res = AudioCodecParametersBuilder { inner: params };
690
691 Ok(res)
692 }
693
694 pub fn bit_rate(mut self, bit_rate: u64) -> Self {
696 self.inner.set_bit_rate(bit_rate);
697 self
698 }
699
700 pub fn sample_format(mut self, format: SampleFormat) -> Self {
702 self.inner.set_sample_format(format);
703 self
704 }
705
706 pub fn sample_rate(mut self, rate: u32) -> Self {
708 self.inner.set_sample_rate(rate);
709 self
710 }
711
712 pub fn channel_layout(mut self, layout: &ChannelLayoutRef) -> Self {
714 self.inner.set_channel_layout(layout);
715 self
716 }
717
718 pub fn codec_tag<T>(mut self, codec_tag: T) -> Self
720 where
721 T: Into<CodecTag>,
722 {
723 self.inner.set_codec_tag(codec_tag);
724 self
725 }
726
727 pub fn extradata<T>(mut self, data: Option<T>) -> Self
729 where
730 T: AsRef<[u8]>,
731 {
732 self.inner.set_extradata(data);
733 self
734 }
735
736 #[cfg(codec_params_side_data)]
738 pub fn add_coded_side_data(
739 &mut self,
740 data_type: SideDataType,
741 data: &[u8],
742 ) -> Result<(), Error> {
743 self.inner.add_coded_side_data(data_type, data)
744 }
745
746 #[inline]
748 pub fn build(self) -> AudioCodecParameters {
749 AudioCodecParameters { inner: self.inner }
750 }
751}
752
753impl From<AudioCodecParameters> for AudioCodecParametersBuilder {
754 #[inline]
755 fn from(params: AudioCodecParameters) -> Self {
756 Self {
757 inner: params.inner,
758 }
759 }
760}
761
762#[derive(Clone)]
764pub struct AudioCodecParameters {
765 inner: InnerCodecParameters,
766}
767
768impl AudioCodecParameters {
769 pub fn builder(codec: &str) -> Result<AudioCodecParametersBuilder, Error> {
771 AudioCodecParametersBuilder::new(codec)
772 }
773
774 pub(crate) fn as_ptr(&self) -> *const c_void {
776 self.inner.ptr
777 }
778
779 pub fn decoder_name(&self) -> Option<&'static str> {
782 self.inner.get_decoder_name()
783 }
784
785 pub fn encoder_name(&self) -> Option<&'static str> {
788 self.inner.get_encoder_name()
789 }
790
791 pub fn bit_rate(&self) -> u64 {
793 self.inner.get_bit_rate()
794 }
795
796 pub fn sample_format(&self) -> SampleFormat {
798 self.inner.get_sample_format()
799 }
800
801 pub fn sample_rate(&self) -> u32 {
803 self.inner.get_sample_rate()
804 }
805
806 pub fn channel_layout(&self) -> &ChannelLayoutRef {
808 self.inner.get_channel_layout()
809 }
810
811 pub fn codec_tag(&self) -> CodecTag {
813 self.inner.get_codec_tag()
814 }
815
816 pub fn extradata(&self) -> Option<&[u8]> {
818 self.inner.get_extradata()
819 }
820
821 #[cfg(codec_params_side_data)]
823 pub fn coded_side_data(&self) -> SideDataIter<'_> {
824 self.inner.get_coded_side_data()
825 }
826}
827
828impl AsRef<InnerCodecParameters> for AudioCodecParameters {
829 fn as_ref(&self) -> &InnerCodecParameters {
830 &self.inner
831 }
832}
833
834impl From<InnerCodecParameters> for AudioCodecParameters {
835 fn from(params: InnerCodecParameters) -> Self {
836 Self { inner: params }
837 }
838}
839
840pub struct VideoCodecParametersBuilder {
842 inner: InnerCodecParameters,
843}
844
845impl VideoCodecParametersBuilder {
846 fn new(codec: &str) -> Result<Self, Error> {
848 let codec = CString::new(codec).expect("invalid codec name");
849
850 let ptr = unsafe { ffw_video_codec_parameters_new(codec.as_ptr() as *const _) };
851
852 if ptr.is_null() {
853 return Err(Error::new("unknown codec"));
854 }
855
856 let params = unsafe { InnerCodecParameters::from_raw_ptr(ptr) };
857
858 let res = VideoCodecParametersBuilder { inner: params };
859
860 Ok(res)
861 }
862
863 pub fn bit_rate(mut self, bit_rate: u64) -> Self {
865 self.inner.set_bit_rate(bit_rate);
866 self
867 }
868
869 pub fn pixel_format(mut self, format: PixelFormat) -> Self {
871 self.inner.set_pixel_format(format);
872 self
873 }
874
875 pub fn width(mut self, width: usize) -> Self {
877 self.inner.set_width(width);
878 self
879 }
880
881 pub fn height(mut self, height: usize) -> Self {
883 self.inner.set_height(height);
884 self
885 }
886
887 pub fn codec_tag<T>(mut self, codec_tag: T) -> Self
889 where
890 T: Into<CodecTag>,
891 {
892 self.inner.set_codec_tag(codec_tag);
893 self
894 }
895
896 pub fn extradata<T>(mut self, data: Option<T>) -> Self
898 where
899 T: AsRef<[u8]>,
900 {
901 self.inner.set_extradata(data);
902 self
903 }
904
905 #[cfg(codec_params_side_data)]
907 pub fn add_coded_side_data(
908 &mut self,
909 data_type: SideDataType,
910 data: &[u8],
911 ) -> Result<(), Error> {
912 self.inner.add_coded_side_data(data_type, data)
913 }
914
915 #[inline]
917 pub fn build(self) -> VideoCodecParameters {
918 VideoCodecParameters { inner: self.inner }
919 }
920}
921
922impl From<VideoCodecParameters> for VideoCodecParametersBuilder {
923 #[inline]
924 fn from(params: VideoCodecParameters) -> VideoCodecParametersBuilder {
925 VideoCodecParametersBuilder {
926 inner: params.inner,
927 }
928 }
929}
930
931#[derive(Clone)]
933pub struct VideoCodecParameters {
934 inner: InnerCodecParameters,
935}
936
937impl VideoCodecParameters {
938 pub fn builder(codec: &str) -> Result<VideoCodecParametersBuilder, Error> {
940 VideoCodecParametersBuilder::new(codec)
941 }
942
943 pub(crate) fn as_ptr(&self) -> *const c_void {
945 self.inner.ptr
946 }
947
948 pub fn decoder_name(&self) -> Option<&'static str> {
951 self.inner.get_decoder_name()
952 }
953
954 pub fn encoder_name(&self) -> Option<&'static str> {
957 self.inner.get_encoder_name()
958 }
959
960 pub fn bit_rate(&self) -> u64 {
962 self.inner.get_bit_rate()
963 }
964
965 pub fn pixel_format(&self) -> PixelFormat {
967 self.inner.get_pixel_format()
968 }
969
970 pub fn width(&self) -> usize {
972 self.inner.get_width()
973 }
974
975 pub fn height(&self) -> usize {
977 self.inner.get_height()
978 }
979
980 pub fn codec_tag(&self) -> CodecTag {
982 self.inner.get_codec_tag()
983 }
984
985 pub fn extradata(&self) -> Option<&[u8]> {
987 self.inner.get_extradata()
988 }
989
990 #[cfg(codec_params_side_data)]
992 pub fn coded_side_data(&self) -> SideDataIter<'_> {
993 self.inner.get_coded_side_data()
994 }
995}
996
997impl AsRef<InnerCodecParameters> for VideoCodecParameters {
998 fn as_ref(&self) -> &InnerCodecParameters {
999 &self.inner
1000 }
1001}
1002
1003impl From<InnerCodecParameters> for VideoCodecParameters {
1004 fn from(params: InnerCodecParameters) -> Self {
1005 Self { inner: params }
1006 }
1007}
1008
1009#[derive(Clone)]
1011pub struct SubtitleCodecParameters {
1012 inner: InnerCodecParameters,
1013}
1014
1015impl SubtitleCodecParameters {
1016 pub fn new(codec: &str) -> Result<Self, Error> {
1017 let codec = CString::new(codec).expect("invalid codec name");
1018
1019 let ptr = unsafe { ffw_subtitle_codec_parameters_new(codec.as_ptr() as *const _) };
1020
1021 if ptr.is_null() {
1022 return Err(Error::new("unknown codec"));
1023 }
1024
1025 let params = unsafe { InnerCodecParameters::from_raw_ptr(ptr) };
1026
1027 let res = SubtitleCodecParameters { inner: params };
1028 Ok(res)
1029 }
1030
1031 pub fn decoder_name(&self) -> Option<&'static str> {
1034 self.inner.get_decoder_name()
1035 }
1036
1037 pub fn encoder_name(&self) -> Option<&'static str> {
1040 self.inner.get_encoder_name()
1041 }
1042}
1043
1044impl AsRef<InnerCodecParameters> for SubtitleCodecParameters {
1045 fn as_ref(&self) -> &InnerCodecParameters {
1046 &self.inner
1047 }
1048}
1049
1050impl From<InnerCodecParameters> for SubtitleCodecParameters {
1051 fn from(params: InnerCodecParameters) -> Self {
1052 Self { inner: params }
1053 }
1054}
1055
1056#[derive(Clone)]
1058struct OtherCodecParameters {
1059 inner: InnerCodecParameters,
1060}
1061
1062impl AsRef<InnerCodecParameters> for OtherCodecParameters {
1063 fn as_ref(&self) -> &InnerCodecParameters {
1064 &self.inner
1065 }
1066}
1067
1068impl From<InnerCodecParameters> for OtherCodecParameters {
1069 fn from(params: InnerCodecParameters) -> Self {
1070 Self { inner: params }
1071 }
1072}
1073
1074#[derive(Copy, Clone, PartialEq)]
1076pub struct CodecTag(u32);
1077
1078impl From<u32> for CodecTag {
1079 #[inline]
1080 fn from(value: u32) -> Self {
1081 Self(value)
1082 }
1083}
1084
1085impl From<CodecTag> for u32 {
1086 #[inline]
1087 fn from(value: CodecTag) -> Self {
1088 value.0
1089 }
1090}
1091
1092impl From<&[u8; 4]> for CodecTag {
1093 #[inline]
1094 fn from(value: &[u8; 4]) -> Self {
1095 Self(u32::from_le_bytes(*value))
1096 }
1097}
1098
1099pub trait Decoder {
1108 type CodecParameters;
1109 type Frame;
1110
1111 fn codec_parameters(&self) -> Self::CodecParameters;
1113
1114 fn push(&mut self, packet: Packet) -> Result<(), Error> {
1120 self.try_push(packet).map_err(|err| err.unwrap_inner())
1121 }
1122
1123 fn try_push(&mut self, packet: Packet) -> Result<(), CodecError>;
1125
1126 fn flush(&mut self) -> Result<(), Error> {
1132 self.try_flush().map_err(|err| err.unwrap_inner())
1133 }
1134
1135 fn try_flush(&mut self) -> Result<(), CodecError>;
1137
1138 fn take(&mut self) -> Result<Option<Self::Frame>, Error>;
1140}
1141
1142pub trait Encoder {
1151 type CodecParameters;
1152 type Frame;
1153
1154 fn codec_parameters(&self) -> Self::CodecParameters;
1156
1157 fn push(&mut self, frame: Self::Frame) -> Result<(), Error> {
1163 self.try_push(frame).map_err(|err| err.unwrap_inner())
1164 }
1165
1166 fn try_push(&mut self, frame: Self::Frame) -> Result<(), CodecError>;
1168
1169 fn flush(&mut self) -> Result<(), Error> {
1175 self.try_flush().map_err(|err| err.unwrap_inner())
1176 }
1177
1178 fn try_flush(&mut self) -> Result<(), CodecError>;
1180
1181 fn take(&mut self) -> Result<Option<Packet>, Error>;
1183}
1184
1185pub trait Filter {
1194 type Frame;
1195
1196 fn push(&mut self, frame: Self::Frame) -> Result<(), Error> {
1202 self.try_push(frame).map_err(|err| err.unwrap_inner())
1203 }
1204
1205 fn try_push(&mut self, frame: Self::Frame) -> Result<(), CodecError>;
1207
1208 fn flush(&mut self) -> Result<(), Error> {
1214 self.try_flush().map_err(|err| err.unwrap_inner())
1215 }
1216
1217 fn try_flush(&mut self) -> Result<(), CodecError>;
1219
1220 fn take(&mut self) -> Result<Option<Self::Frame>, Error>;
1222}