use std::ptr; use ffmpeg_sys_next::{avcodec_parameters_from_context, avformat_new_stream, AVRational, AVStream}; use super::codec_context::CodecContext; use super::format_context::FormatContext; use super::WrapperType; use crate::error::VideoEncoderError; use crate::status::FfmpegSysStatus; pub struct Stream(*mut AVStream); impl Stream { pub fn new(format_context: &mut FormatContext) -> Result { let video_st = unsafe { avformat_new_stream(format_context.get_inner_mut(), ptr::null()) }; if video_st.is_null() { return Err(VideoEncoderError::FfmpegSysError { message: "Could not allocate the video stream.", error_code: FfmpegSysStatus::Unknown, }); } unsafe { (*video_st).id = ((*format_context.get_inner()).nb_streams - 1) as i32; }; Ok(Stream(video_st)) } pub fn set_time_base(&mut self, time_base: AVRational) { unsafe { (*self.get_inner_mut()).time_base = time_base } } pub fn get_time_base(&self) -> AVRational { unsafe { (*self.get_inner()).time_base } } pub fn set_context(&mut self, context: &CodecContext) -> Result<(), VideoEncoderError> { let err = unsafe { avcodec_parameters_from_context((*self.0).codecpar, context.get_inner()) }; let status = FfmpegSysStatus::from_ffmpeg_sys_error(err); if status.is_error() { return Err(VideoEncoderError::FfmpegSysError { message: "Failed to set codec parameters.", error_code: status, }); } Ok(()) } } impl WrapperType for Stream { type OUT = AVStream; fn get_inner(&self) -> *const Self::OUT { self.0 } fn get_inner_mut(&mut self) -> *mut Self::OUT { self.0 } }