1use std::fmt::Debug;
2
3use crate::{avcodec::codec_parameters::CodecParameters, avformat::FormatContext};
4use libav_sys_ng::{AVCodec, AVRational, AVStream};
5use crate::{avcodec::CodecContext};
6
7pub struct Stream {
8 pub(crate) _stream: *mut libav_sys_ng::AVStream,
9}
10
11impl Stream {
12 pub fn new(format_ctx: &mut FormatContext, codec: Option<&CodecContext>) -> Option<Stream> {
13 unsafe {
14 let raw_fc = format_ctx.raw_mut();
15
16 let raw_codec = match codec {
17 Some(c) => c.raw_codec(),
18 None => core::ptr::null::<AVCodec>(),
19 };
20
21 let stream = libav_sys_ng::avformat_new_stream(raw_fc, raw_codec);
22
23 if stream.is_null() {
24 return None;
25 }
26
27 Some(Stream { _stream: stream })
28 }
29 }
30
31 pub fn codec_parameters(&self) -> CodecParameters {
32 unsafe {
33 CodecParameters {
34 _p: (*self._stream).codecpar,
35 }
36 }
37 }
38
39 pub fn id(&self) -> i32 {
40 unsafe { (*self._stream).id }
41 }
42
43 pub fn index(&self) -> i32 {
44 unsafe { (*self._stream).index }
45 }
46
47 pub fn time_base(&self) -> AVRational {
48 unsafe { (*self._stream).time_base }
49 }
50
51 pub fn duration(&self) -> i64 {
52 unsafe { (*self._stream).duration }
53 }
54
55 pub fn duration_sec(&self) -> f64 {
56 let time_base = self.time_base();
57 let duration = self.duration();
58
59 (duration as f64 * time_base.num as f64) / time_base.den as f64
60 }
61
62 pub unsafe fn raw(&self) -> &AVStream {
63 &*self._stream.cast()
64 }
65
66 pub unsafe fn raw_mut(&mut self) -> &mut AVStream {
67 &mut *self._stream
68 }
69}
70
71impl Debug for Stream {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 unsafe {
74 let index = (*self._stream).index;
75 let id = (*self._stream).id;
76 let codec_parameters = CodecParameters {
77 _p: (*self._stream).codecpar,
78 };
79
80 let time_base = self.time_base();
81 let start_time = (*self._stream).start_time;
82 let duration = self.duration();
83
84 let nb_frames = (*self._stream).nb_frames;
85
86 let avg_frame_rate = (*self._stream).avg_frame_rate;
87 let r_frame_rate = (*self._stream).r_frame_rate;
88
89 f.debug_struct("Stream")
90 .field("id", &id)
91 .field("index", &index)
92 .field("codecpar", &codec_parameters)
93 .field("time_base", &time_base)
94 .field("start_time", &start_time)
95 .field("nb_frames", &nb_frames)
96 .field("duration", &duration)
97 .field("avg_frame_rate", &avg_frame_rate)
98 .field("r_frame_rate", &r_frame_rate)
99 .finish()
100 }
101 }
102}