Struct Packet

Source
pub struct Packet(/* private fields */);

Implementations§

Source§

impl Packet

Source

pub unsafe fn is_empty(&self) -> bool

Source§

impl Packet

Source

pub fn empty() -> Self

Examples found in repository?
examples/transcode-audio.rs (line 143)
142    fn receive_and_process_encoded_packets(&mut self, octx: &mut format::context::Output) {
143        let mut encoded = ffmpeg_rs::Packet::empty();
144        while self.encoder.receive_packet(&mut encoded).is_ok() {
145            encoded.set_stream(0);
146            encoded.rescale_ts(self.in_time_base, self.out_time_base);
147            encoded.write_interleaved(octx).unwrap();
148        }
149    }
More examples
Hide additional examples
examples/transcode-x264.rs (line 126)
121    fn receive_and_process_encoded_packets(
122        &mut self,
123        octx: &mut format::context::Output,
124        ost_time_base: Rational,
125    ) {
126        let mut encoded = Packet::empty();
127        while self.encoder.receive_packet(&mut encoded).is_ok() {
128            encoded.set_stream(self.ost_index);
129            encoded.rescale_ts(self.decoder.time_base(), ost_time_base);
130            encoded.write_interleaved(octx).unwrap();
131        }
132    }
Source

pub fn new(size: usize) -> Self

Source

pub fn copy(data: &[u8]) -> Self

Source

pub fn borrow(data: &[u8]) -> Borrow<'_>

Source

pub fn shrink(&mut self, size: usize)

Source

pub fn grow(&mut self, size: usize)

Source

pub fn rescale_ts<S, D>(&mut self, source: S, destination: D)
where S: Into<Rational>, D: Into<Rational>,

Examples found in repository?
examples/transcode-audio.rs (line 146)
142    fn receive_and_process_encoded_packets(&mut self, octx: &mut format::context::Output) {
143        let mut encoded = ffmpeg_rs::Packet::empty();
144        while self.encoder.receive_packet(&mut encoded).is_ok() {
145            encoded.set_stream(0);
146            encoded.rescale_ts(self.in_time_base, self.out_time_base);
147            encoded.write_interleaved(octx).unwrap();
148        }
149    }
150
151    fn add_frame_to_filter(&mut self, frame: &ffmpeg_rs::Frame) {
152        self.filter.get("in").unwrap().source().add(frame).unwrap();
153    }
154
155    fn flush_filter(&mut self) {
156        self.filter.get("in").unwrap().source().flush().unwrap();
157    }
158
159    fn get_and_process_filtered_frames(&mut self, octx: &mut format::context::Output) {
160        let mut filtered = frame::Audio::empty();
161        while self
162            .filter
163            .get("out")
164            .unwrap()
165            .sink()
166            .frame(&mut filtered)
167            .is_ok()
168        {
169            self.send_frame_to_encoder(&filtered);
170            self.receive_and_process_encoded_packets(octx);
171        }
172    }
173
174    fn send_packet_to_decoder(&mut self, packet: &ffmpeg_rs::Packet) {
175        self.decoder.send_packet(packet).unwrap();
176    }
177
178    fn send_eof_to_decoder(&mut self) {
179        self.decoder.send_eof().unwrap();
180    }
181
182    fn receive_and_process_decoded_frames(&mut self, octx: &mut format::context::Output) {
183        let mut decoded = frame::Audio::empty();
184        while self.decoder.receive_frame(&mut decoded).is_ok() {
185            let timestamp = decoded.timestamp();
186            decoded.set_pts(timestamp);
187            self.add_frame_to_filter(&decoded);
188            self.get_and_process_filtered_frames(octx);
189        }
190    }
191}
192
193// Transcode the `best` audio stream of the input file into a the output file while applying a
194// given filter. If no filter was specified the stream gets copied (`anull` filter).
195//
196// Example 1: Transcode *.mp3 file to *.wmv while speeding it up
197// transcode-audio in.mp3 out.wmv "atempo=1.2"
198//
199// Example 2: Overlay an audio file
200// transcode-audio in.mp3 out.mp3 "amovie=overlay.mp3 [ov]; [in][ov] amerge [out]"
201//
202// Example 3: Seek to a specified position (in seconds)
203// transcode-audio in.mp3 out.mp3 anull 30
204fn main() {
205    ffmpeg_rs::init().unwrap();
206
207    let input = env::args().nth(1).expect("missing input");
208    let output = env::args().nth(2).expect("missing output");
209    let filter = env::args().nth(3).unwrap_or_else(|| "anull".to_owned());
210    let seek = env::args().nth(4).and_then(|s| s.parse::<i64>().ok());
211
212    let mut ictx = format::input(&input).unwrap();
213    let mut octx = format::output(&output).unwrap();
214    let mut transcoder = transcoder(&mut ictx, &mut octx, &output, &filter).unwrap();
215
216    if let Some(position) = seek {
217        // If the position was given in seconds, rescale it to ffmpegs base timebase.
218        let position = position.rescale((1, 1), rescale::TIME_BASE);
219        // If this seek was embedded in the transcoding loop, a call of `flush()`
220        // for every opened buffer after the successful seek would be advisable.
221        ictx.seek(position, ..position).unwrap();
222    }
223
224    octx.set_metadata(ictx.metadata().to_owned());
225    octx.write_header().unwrap();
226
227    for (stream, mut packet) in ictx.packets() {
228        if stream.index() == transcoder.stream {
229            packet.rescale_ts(stream.time_base(), transcoder.in_time_base);
230            transcoder.send_packet_to_decoder(&packet);
231            transcoder.receive_and_process_decoded_frames(&mut octx);
232        }
233    }
234
235    transcoder.send_eof_to_decoder();
236    transcoder.receive_and_process_decoded_frames(&mut octx);
237
238    transcoder.flush_filter();
239    transcoder.get_and_process_filtered_frames(&mut octx);
240
241    transcoder.send_eof_to_encoder();
242    transcoder.receive_and_process_encoded_packets(&mut octx);
243
244    octx.write_trailer().unwrap();
245}
More examples
Hide additional examples
examples/transcode-x264.rs (line 129)
121    fn receive_and_process_encoded_packets(
122        &mut self,
123        octx: &mut format::context::Output,
124        ost_time_base: Rational,
125    ) {
126        let mut encoded = Packet::empty();
127        while self.encoder.receive_packet(&mut encoded).is_ok() {
128            encoded.set_stream(self.ost_index);
129            encoded.rescale_ts(self.decoder.time_base(), ost_time_base);
130            encoded.write_interleaved(octx).unwrap();
131        }
132    }
133
134    fn log_progress(&mut self, timestamp: f64) {
135        if !self.logging_enabled
136            || (self.frame_count - self.last_log_frame_count < 100
137                && self.last_log_time.elapsed().as_secs_f64() < 1.0)
138        {
139            return;
140        }
141        eprintln!(
142            "time elpased: \t{:8.2}\tframe count: {:8}\ttimestamp: {:8.2}",
143            self.starting_time.elapsed().as_secs_f64(),
144            self.frame_count,
145            timestamp
146        );
147        self.last_log_frame_count = self.frame_count;
148        self.last_log_time = Instant::now();
149    }
150}
151
152fn parse_opts<'a>(s: String) -> Option<Dictionary<'a>> {
153    let mut dict = Dictionary::new();
154    for keyval in s.split_terminator(',') {
155        let tokens: Vec<&str> = keyval.split('=').collect();
156        match tokens[..] {
157            [key, val] => dict.set(key, val),
158            _ => return None,
159        }
160    }
161    Some(dict)
162}
163
164fn main() {
165    let input_file = env::args().nth(1).expect("missing input file");
166    let output_file = env::args().nth(2).expect("missing output file");
167    let x264_opts = parse_opts(
168        env::args()
169            .nth(3)
170            .unwrap_or_else(|| DEFAULT_X264_OPTS.to_string()),
171    )
172    .expect("invalid x264 options string");
173
174    eprintln!("x264 options: {:?}", x264_opts);
175
176    ffmpeg_rs::init().unwrap();
177    log::set_level(log::Level::Info);
178
179    let mut ictx = format::input(&input_file).unwrap();
180    let mut octx = format::output(&output_file).unwrap();
181
182    format::context::input::dump(&ictx, 0, Some(&input_file));
183
184    let best_video_stream_index = ictx
185        .streams()
186        .best(media::Type::Video)
187        .map(|stream| stream.index());
188    let mut stream_mapping: Vec<isize> = vec![0; ictx.nb_streams() as _];
189    let mut ist_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
190    let mut ost_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
191    let mut transcoders = HashMap::new();
192    let mut ost_index = 0;
193    for (ist_index, ist) in ictx.streams().enumerate() {
194        let ist_medium = ist.parameters().codec_type();
195        if ist_medium != media::Type::Audio
196            && ist_medium != media::Type::Video
197            && ist_medium != media::Type::Subtitle
198        {
199            stream_mapping[ist_index] = -1;
200            continue;
201        }
202        stream_mapping[ist_index] = ost_index;
203        ist_time_bases[ist_index] = ist.time_base();
204        if ist_medium == media::Type::Video {
205            // Initialize transcoder for video stream.
206            transcoders.insert(
207                ist_index,
208                Transcoder::new(
209                    &ist,
210                    &mut octx,
211                    ost_index as _,
212                    x264_opts.to_owned(),
213                    Some(ist_index) == best_video_stream_index,
214                )
215                .unwrap(),
216            );
217        } else {
218            // Set up for stream copy for non-video stream.
219            let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
220            ost.set_parameters(ist.parameters());
221            // We need to set codec_tag to 0 lest we run into incompatible codec tag
222            // issues when muxing into a different container format. Unfortunately
223            // there's no high level API to do this (yet).
224            unsafe {
225                (*ost.parameters().as_mut_ptr()).codec_tag = 0;
226            }
227        }
228        ost_index += 1;
229    }
230
231    octx.set_metadata(ictx.metadata().to_owned());
232    format::context::output::dump(&octx, 0, Some(&output_file));
233    octx.write_header().unwrap();
234
235    for (ost_index, _) in octx.streams().enumerate() {
236        ost_time_bases[ost_index] = octx.stream(ost_index as _).unwrap().time_base();
237    }
238
239    for (stream, mut packet) in ictx.packets() {
240        let ist_index = stream.index();
241        let ost_index = stream_mapping[ist_index];
242        if ost_index < 0 {
243            continue;
244        }
245        let ost_time_base = ost_time_bases[ost_index as usize];
246        match transcoders.get_mut(&ist_index) {
247            Some(transcoder) => {
248                packet.rescale_ts(stream.time_base(), transcoder.decoder.time_base());
249                transcoder.send_packet_to_decoder(&packet);
250                transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
251            }
252            None => {
253                // Do stream copy on non-video streams.
254                packet.rescale_ts(ist_time_bases[ist_index], ost_time_base);
255                packet.set_position(-1);
256                packet.set_stream(ost_index as _);
257                packet.write_interleaved(&mut octx).unwrap();
258            }
259        }
260    }
261
262    // Flush encoders and decoders.
263    for (ost_index, transcoder) in transcoders.iter_mut() {
264        let ost_time_base = ost_time_bases[*ost_index];
265        transcoder.send_eof_to_decoder();
266        transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
267        transcoder.send_eof_to_encoder();
268        transcoder.receive_and_process_encoded_packets(&mut octx, ost_time_base);
269    }
270
271    octx.write_trailer().unwrap();
272}
examples/remux.rs (line 51)
6fn main() {
7    let input_file = env::args().nth(1).expect("missing input file");
8    let output_file = env::args().nth(2).expect("missing output file");
9
10    ffmpeg_rs::init().unwrap();
11    log::set_level(log::Level::Warning);
12
13    let mut ictx = format::input(&input_file).unwrap();
14    let mut octx = format::output(&output_file).unwrap();
15
16    let mut stream_mapping = vec![0; ictx.nb_streams() as _];
17    let mut ist_time_bases = vec![Rational(0, 1); ictx.nb_streams() as _];
18    let mut ost_index = 0;
19    for (ist_index, ist) in ictx.streams().enumerate() {
20        let ist_medium = ist.parameters().codec_type();
21        if ist_medium != media::Type::Audio
22            && ist_medium != media::Type::Video
23            && ist_medium != media::Type::Subtitle
24        {
25            stream_mapping[ist_index] = -1;
26            continue;
27        }
28        stream_mapping[ist_index] = ost_index;
29        ist_time_bases[ist_index] = ist.time_base();
30        ost_index += 1;
31        let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
32        ost.set_parameters(ist.parameters());
33        // We need to set codec_tag to 0 lest we run into incompatible codec tag
34        // issues when muxing into a different container format. Unfortunately
35        // there's no high level API to do this (yet).
36        unsafe {
37            (*ost.parameters().as_mut_ptr()).codec_tag = 0;
38        }
39    }
40
41    octx.set_metadata(ictx.metadata().to_owned());
42    octx.write_header().unwrap();
43
44    for (stream, mut packet) in ictx.packets() {
45        let ist_index = stream.index();
46        let ost_index = stream_mapping[ist_index];
47        if ost_index < 0 {
48            continue;
49        }
50        let ost = octx.stream(ost_index as _).unwrap();
51        packet.rescale_ts(ist_time_bases[ist_index], ost.time_base());
52        packet.set_position(-1);
53        packet.set_stream(ost_index as _);
54        packet.write_interleaved(&mut octx).unwrap();
55    }
56
57    octx.write_trailer().unwrap();
58}
Source

pub fn flags(&self) -> Flags

Source

pub fn set_flags(&mut self, value: Flags)

Source

pub fn is_key(&self) -> bool

Source

pub fn is_corrupt(&self) -> bool

Source

pub fn stream(&self) -> usize

Source

pub fn set_stream(&mut self, index: usize)

Examples found in repository?
examples/transcode-audio.rs (line 145)
142    fn receive_and_process_encoded_packets(&mut self, octx: &mut format::context::Output) {
143        let mut encoded = ffmpeg_rs::Packet::empty();
144        while self.encoder.receive_packet(&mut encoded).is_ok() {
145            encoded.set_stream(0);
146            encoded.rescale_ts(self.in_time_base, self.out_time_base);
147            encoded.write_interleaved(octx).unwrap();
148        }
149    }
More examples
Hide additional examples
examples/transcode-x264.rs (line 128)
121    fn receive_and_process_encoded_packets(
122        &mut self,
123        octx: &mut format::context::Output,
124        ost_time_base: Rational,
125    ) {
126        let mut encoded = Packet::empty();
127        while self.encoder.receive_packet(&mut encoded).is_ok() {
128            encoded.set_stream(self.ost_index);
129            encoded.rescale_ts(self.decoder.time_base(), ost_time_base);
130            encoded.write_interleaved(octx).unwrap();
131        }
132    }
133
134    fn log_progress(&mut self, timestamp: f64) {
135        if !self.logging_enabled
136            || (self.frame_count - self.last_log_frame_count < 100
137                && self.last_log_time.elapsed().as_secs_f64() < 1.0)
138        {
139            return;
140        }
141        eprintln!(
142            "time elpased: \t{:8.2}\tframe count: {:8}\ttimestamp: {:8.2}",
143            self.starting_time.elapsed().as_secs_f64(),
144            self.frame_count,
145            timestamp
146        );
147        self.last_log_frame_count = self.frame_count;
148        self.last_log_time = Instant::now();
149    }
150}
151
152fn parse_opts<'a>(s: String) -> Option<Dictionary<'a>> {
153    let mut dict = Dictionary::new();
154    for keyval in s.split_terminator(',') {
155        let tokens: Vec<&str> = keyval.split('=').collect();
156        match tokens[..] {
157            [key, val] => dict.set(key, val),
158            _ => return None,
159        }
160    }
161    Some(dict)
162}
163
164fn main() {
165    let input_file = env::args().nth(1).expect("missing input file");
166    let output_file = env::args().nth(2).expect("missing output file");
167    let x264_opts = parse_opts(
168        env::args()
169            .nth(3)
170            .unwrap_or_else(|| DEFAULT_X264_OPTS.to_string()),
171    )
172    .expect("invalid x264 options string");
173
174    eprintln!("x264 options: {:?}", x264_opts);
175
176    ffmpeg_rs::init().unwrap();
177    log::set_level(log::Level::Info);
178
179    let mut ictx = format::input(&input_file).unwrap();
180    let mut octx = format::output(&output_file).unwrap();
181
182    format::context::input::dump(&ictx, 0, Some(&input_file));
183
184    let best_video_stream_index = ictx
185        .streams()
186        .best(media::Type::Video)
187        .map(|stream| stream.index());
188    let mut stream_mapping: Vec<isize> = vec![0; ictx.nb_streams() as _];
189    let mut ist_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
190    let mut ost_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
191    let mut transcoders = HashMap::new();
192    let mut ost_index = 0;
193    for (ist_index, ist) in ictx.streams().enumerate() {
194        let ist_medium = ist.parameters().codec_type();
195        if ist_medium != media::Type::Audio
196            && ist_medium != media::Type::Video
197            && ist_medium != media::Type::Subtitle
198        {
199            stream_mapping[ist_index] = -1;
200            continue;
201        }
202        stream_mapping[ist_index] = ost_index;
203        ist_time_bases[ist_index] = ist.time_base();
204        if ist_medium == media::Type::Video {
205            // Initialize transcoder for video stream.
206            transcoders.insert(
207                ist_index,
208                Transcoder::new(
209                    &ist,
210                    &mut octx,
211                    ost_index as _,
212                    x264_opts.to_owned(),
213                    Some(ist_index) == best_video_stream_index,
214                )
215                .unwrap(),
216            );
217        } else {
218            // Set up for stream copy for non-video stream.
219            let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
220            ost.set_parameters(ist.parameters());
221            // We need to set codec_tag to 0 lest we run into incompatible codec tag
222            // issues when muxing into a different container format. Unfortunately
223            // there's no high level API to do this (yet).
224            unsafe {
225                (*ost.parameters().as_mut_ptr()).codec_tag = 0;
226            }
227        }
228        ost_index += 1;
229    }
230
231    octx.set_metadata(ictx.metadata().to_owned());
232    format::context::output::dump(&octx, 0, Some(&output_file));
233    octx.write_header().unwrap();
234
235    for (ost_index, _) in octx.streams().enumerate() {
236        ost_time_bases[ost_index] = octx.stream(ost_index as _).unwrap().time_base();
237    }
238
239    for (stream, mut packet) in ictx.packets() {
240        let ist_index = stream.index();
241        let ost_index = stream_mapping[ist_index];
242        if ost_index < 0 {
243            continue;
244        }
245        let ost_time_base = ost_time_bases[ost_index as usize];
246        match transcoders.get_mut(&ist_index) {
247            Some(transcoder) => {
248                packet.rescale_ts(stream.time_base(), transcoder.decoder.time_base());
249                transcoder.send_packet_to_decoder(&packet);
250                transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
251            }
252            None => {
253                // Do stream copy on non-video streams.
254                packet.rescale_ts(ist_time_bases[ist_index], ost_time_base);
255                packet.set_position(-1);
256                packet.set_stream(ost_index as _);
257                packet.write_interleaved(&mut octx).unwrap();
258            }
259        }
260    }
261
262    // Flush encoders and decoders.
263    for (ost_index, transcoder) in transcoders.iter_mut() {
264        let ost_time_base = ost_time_bases[*ost_index];
265        transcoder.send_eof_to_decoder();
266        transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
267        transcoder.send_eof_to_encoder();
268        transcoder.receive_and_process_encoded_packets(&mut octx, ost_time_base);
269    }
270
271    octx.write_trailer().unwrap();
272}
examples/remux.rs (line 53)
6fn main() {
7    let input_file = env::args().nth(1).expect("missing input file");
8    let output_file = env::args().nth(2).expect("missing output file");
9
10    ffmpeg_rs::init().unwrap();
11    log::set_level(log::Level::Warning);
12
13    let mut ictx = format::input(&input_file).unwrap();
14    let mut octx = format::output(&output_file).unwrap();
15
16    let mut stream_mapping = vec![0; ictx.nb_streams() as _];
17    let mut ist_time_bases = vec![Rational(0, 1); ictx.nb_streams() as _];
18    let mut ost_index = 0;
19    for (ist_index, ist) in ictx.streams().enumerate() {
20        let ist_medium = ist.parameters().codec_type();
21        if ist_medium != media::Type::Audio
22            && ist_medium != media::Type::Video
23            && ist_medium != media::Type::Subtitle
24        {
25            stream_mapping[ist_index] = -1;
26            continue;
27        }
28        stream_mapping[ist_index] = ost_index;
29        ist_time_bases[ist_index] = ist.time_base();
30        ost_index += 1;
31        let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
32        ost.set_parameters(ist.parameters());
33        // We need to set codec_tag to 0 lest we run into incompatible codec tag
34        // issues when muxing into a different container format. Unfortunately
35        // there's no high level API to do this (yet).
36        unsafe {
37            (*ost.parameters().as_mut_ptr()).codec_tag = 0;
38        }
39    }
40
41    octx.set_metadata(ictx.metadata().to_owned());
42    octx.write_header().unwrap();
43
44    for (stream, mut packet) in ictx.packets() {
45        let ist_index = stream.index();
46        let ost_index = stream_mapping[ist_index];
47        if ost_index < 0 {
48            continue;
49        }
50        let ost = octx.stream(ost_index as _).unwrap();
51        packet.rescale_ts(ist_time_bases[ist_index], ost.time_base());
52        packet.set_position(-1);
53        packet.set_stream(ost_index as _);
54        packet.write_interleaved(&mut octx).unwrap();
55    }
56
57    octx.write_trailer().unwrap();
58}
Source

pub fn pts(&self) -> Option<i64>

Source

pub fn set_pts(&mut self, value: Option<i64>)

Source

pub fn dts(&self) -> Option<i64>

Source

pub fn set_dts(&mut self, value: Option<i64>)

Source

pub fn size(&self) -> usize

Source

pub fn duration(&self) -> i64

Source

pub fn set_duration(&mut self, value: i64)

Source

pub fn position(&self) -> isize

Source

pub fn set_position(&mut self, value: isize)

Examples found in repository?
examples/remux.rs (line 52)
6fn main() {
7    let input_file = env::args().nth(1).expect("missing input file");
8    let output_file = env::args().nth(2).expect("missing output file");
9
10    ffmpeg_rs::init().unwrap();
11    log::set_level(log::Level::Warning);
12
13    let mut ictx = format::input(&input_file).unwrap();
14    let mut octx = format::output(&output_file).unwrap();
15
16    let mut stream_mapping = vec![0; ictx.nb_streams() as _];
17    let mut ist_time_bases = vec![Rational(0, 1); ictx.nb_streams() as _];
18    let mut ost_index = 0;
19    for (ist_index, ist) in ictx.streams().enumerate() {
20        let ist_medium = ist.parameters().codec_type();
21        if ist_medium != media::Type::Audio
22            && ist_medium != media::Type::Video
23            && ist_medium != media::Type::Subtitle
24        {
25            stream_mapping[ist_index] = -1;
26            continue;
27        }
28        stream_mapping[ist_index] = ost_index;
29        ist_time_bases[ist_index] = ist.time_base();
30        ost_index += 1;
31        let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
32        ost.set_parameters(ist.parameters());
33        // We need to set codec_tag to 0 lest we run into incompatible codec tag
34        // issues when muxing into a different container format. Unfortunately
35        // there's no high level API to do this (yet).
36        unsafe {
37            (*ost.parameters().as_mut_ptr()).codec_tag = 0;
38        }
39    }
40
41    octx.set_metadata(ictx.metadata().to_owned());
42    octx.write_header().unwrap();
43
44    for (stream, mut packet) in ictx.packets() {
45        let ist_index = stream.index();
46        let ost_index = stream_mapping[ist_index];
47        if ost_index < 0 {
48            continue;
49        }
50        let ost = octx.stream(ost_index as _).unwrap();
51        packet.rescale_ts(ist_time_bases[ist_index], ost.time_base());
52        packet.set_position(-1);
53        packet.set_stream(ost_index as _);
54        packet.write_interleaved(&mut octx).unwrap();
55    }
56
57    octx.write_trailer().unwrap();
58}
More examples
Hide additional examples
examples/transcode-x264.rs (line 255)
164fn main() {
165    let input_file = env::args().nth(1).expect("missing input file");
166    let output_file = env::args().nth(2).expect("missing output file");
167    let x264_opts = parse_opts(
168        env::args()
169            .nth(3)
170            .unwrap_or_else(|| DEFAULT_X264_OPTS.to_string()),
171    )
172    .expect("invalid x264 options string");
173
174    eprintln!("x264 options: {:?}", x264_opts);
175
176    ffmpeg_rs::init().unwrap();
177    log::set_level(log::Level::Info);
178
179    let mut ictx = format::input(&input_file).unwrap();
180    let mut octx = format::output(&output_file).unwrap();
181
182    format::context::input::dump(&ictx, 0, Some(&input_file));
183
184    let best_video_stream_index = ictx
185        .streams()
186        .best(media::Type::Video)
187        .map(|stream| stream.index());
188    let mut stream_mapping: Vec<isize> = vec![0; ictx.nb_streams() as _];
189    let mut ist_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
190    let mut ost_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
191    let mut transcoders = HashMap::new();
192    let mut ost_index = 0;
193    for (ist_index, ist) in ictx.streams().enumerate() {
194        let ist_medium = ist.parameters().codec_type();
195        if ist_medium != media::Type::Audio
196            && ist_medium != media::Type::Video
197            && ist_medium != media::Type::Subtitle
198        {
199            stream_mapping[ist_index] = -1;
200            continue;
201        }
202        stream_mapping[ist_index] = ost_index;
203        ist_time_bases[ist_index] = ist.time_base();
204        if ist_medium == media::Type::Video {
205            // Initialize transcoder for video stream.
206            transcoders.insert(
207                ist_index,
208                Transcoder::new(
209                    &ist,
210                    &mut octx,
211                    ost_index as _,
212                    x264_opts.to_owned(),
213                    Some(ist_index) == best_video_stream_index,
214                )
215                .unwrap(),
216            );
217        } else {
218            // Set up for stream copy for non-video stream.
219            let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
220            ost.set_parameters(ist.parameters());
221            // We need to set codec_tag to 0 lest we run into incompatible codec tag
222            // issues when muxing into a different container format. Unfortunately
223            // there's no high level API to do this (yet).
224            unsafe {
225                (*ost.parameters().as_mut_ptr()).codec_tag = 0;
226            }
227        }
228        ost_index += 1;
229    }
230
231    octx.set_metadata(ictx.metadata().to_owned());
232    format::context::output::dump(&octx, 0, Some(&output_file));
233    octx.write_header().unwrap();
234
235    for (ost_index, _) in octx.streams().enumerate() {
236        ost_time_bases[ost_index] = octx.stream(ost_index as _).unwrap().time_base();
237    }
238
239    for (stream, mut packet) in ictx.packets() {
240        let ist_index = stream.index();
241        let ost_index = stream_mapping[ist_index];
242        if ost_index < 0 {
243            continue;
244        }
245        let ost_time_base = ost_time_bases[ost_index as usize];
246        match transcoders.get_mut(&ist_index) {
247            Some(transcoder) => {
248                packet.rescale_ts(stream.time_base(), transcoder.decoder.time_base());
249                transcoder.send_packet_to_decoder(&packet);
250                transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
251            }
252            None => {
253                // Do stream copy on non-video streams.
254                packet.rescale_ts(ist_time_bases[ist_index], ost_time_base);
255                packet.set_position(-1);
256                packet.set_stream(ost_index as _);
257                packet.write_interleaved(&mut octx).unwrap();
258            }
259        }
260    }
261
262    // Flush encoders and decoders.
263    for (ost_index, transcoder) in transcoders.iter_mut() {
264        let ost_time_base = ost_time_bases[*ost_index];
265        transcoder.send_eof_to_decoder();
266        transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
267        transcoder.send_eof_to_encoder();
268        transcoder.receive_and_process_encoded_packets(&mut octx, ost_time_base);
269    }
270
271    octx.write_trailer().unwrap();
272}
Source

pub fn convergence(&self) -> isize

Source

pub fn side_data(&self) -> SideDataIter<'_>

Source

pub fn data(&self) -> Option<&[u8]>

Source

pub fn data_mut(&mut self) -> Option<&mut [u8]>

Source

pub fn read(&mut self, format: &mut Input) -> Result<(), Error>

Source

pub fn write(&self, format: &mut Output) -> Result<bool, Error>

Source

pub fn write_interleaved(&self, format: &mut Output) -> Result<(), Error>

Examples found in repository?
examples/transcode-audio.rs (line 147)
142    fn receive_and_process_encoded_packets(&mut self, octx: &mut format::context::Output) {
143        let mut encoded = ffmpeg_rs::Packet::empty();
144        while self.encoder.receive_packet(&mut encoded).is_ok() {
145            encoded.set_stream(0);
146            encoded.rescale_ts(self.in_time_base, self.out_time_base);
147            encoded.write_interleaved(octx).unwrap();
148        }
149    }
More examples
Hide additional examples
examples/transcode-x264.rs (line 130)
121    fn receive_and_process_encoded_packets(
122        &mut self,
123        octx: &mut format::context::Output,
124        ost_time_base: Rational,
125    ) {
126        let mut encoded = Packet::empty();
127        while self.encoder.receive_packet(&mut encoded).is_ok() {
128            encoded.set_stream(self.ost_index);
129            encoded.rescale_ts(self.decoder.time_base(), ost_time_base);
130            encoded.write_interleaved(octx).unwrap();
131        }
132    }
133
134    fn log_progress(&mut self, timestamp: f64) {
135        if !self.logging_enabled
136            || (self.frame_count - self.last_log_frame_count < 100
137                && self.last_log_time.elapsed().as_secs_f64() < 1.0)
138        {
139            return;
140        }
141        eprintln!(
142            "time elpased: \t{:8.2}\tframe count: {:8}\ttimestamp: {:8.2}",
143            self.starting_time.elapsed().as_secs_f64(),
144            self.frame_count,
145            timestamp
146        );
147        self.last_log_frame_count = self.frame_count;
148        self.last_log_time = Instant::now();
149    }
150}
151
152fn parse_opts<'a>(s: String) -> Option<Dictionary<'a>> {
153    let mut dict = Dictionary::new();
154    for keyval in s.split_terminator(',') {
155        let tokens: Vec<&str> = keyval.split('=').collect();
156        match tokens[..] {
157            [key, val] => dict.set(key, val),
158            _ => return None,
159        }
160    }
161    Some(dict)
162}
163
164fn main() {
165    let input_file = env::args().nth(1).expect("missing input file");
166    let output_file = env::args().nth(2).expect("missing output file");
167    let x264_opts = parse_opts(
168        env::args()
169            .nth(3)
170            .unwrap_or_else(|| DEFAULT_X264_OPTS.to_string()),
171    )
172    .expect("invalid x264 options string");
173
174    eprintln!("x264 options: {:?}", x264_opts);
175
176    ffmpeg_rs::init().unwrap();
177    log::set_level(log::Level::Info);
178
179    let mut ictx = format::input(&input_file).unwrap();
180    let mut octx = format::output(&output_file).unwrap();
181
182    format::context::input::dump(&ictx, 0, Some(&input_file));
183
184    let best_video_stream_index = ictx
185        .streams()
186        .best(media::Type::Video)
187        .map(|stream| stream.index());
188    let mut stream_mapping: Vec<isize> = vec![0; ictx.nb_streams() as _];
189    let mut ist_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
190    let mut ost_time_bases = vec![Rational(0, 0); ictx.nb_streams() as _];
191    let mut transcoders = HashMap::new();
192    let mut ost_index = 0;
193    for (ist_index, ist) in ictx.streams().enumerate() {
194        let ist_medium = ist.parameters().codec_type();
195        if ist_medium != media::Type::Audio
196            && ist_medium != media::Type::Video
197            && ist_medium != media::Type::Subtitle
198        {
199            stream_mapping[ist_index] = -1;
200            continue;
201        }
202        stream_mapping[ist_index] = ost_index;
203        ist_time_bases[ist_index] = ist.time_base();
204        if ist_medium == media::Type::Video {
205            // Initialize transcoder for video stream.
206            transcoders.insert(
207                ist_index,
208                Transcoder::new(
209                    &ist,
210                    &mut octx,
211                    ost_index as _,
212                    x264_opts.to_owned(),
213                    Some(ist_index) == best_video_stream_index,
214                )
215                .unwrap(),
216            );
217        } else {
218            // Set up for stream copy for non-video stream.
219            let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
220            ost.set_parameters(ist.parameters());
221            // We need to set codec_tag to 0 lest we run into incompatible codec tag
222            // issues when muxing into a different container format. Unfortunately
223            // there's no high level API to do this (yet).
224            unsafe {
225                (*ost.parameters().as_mut_ptr()).codec_tag = 0;
226            }
227        }
228        ost_index += 1;
229    }
230
231    octx.set_metadata(ictx.metadata().to_owned());
232    format::context::output::dump(&octx, 0, Some(&output_file));
233    octx.write_header().unwrap();
234
235    for (ost_index, _) in octx.streams().enumerate() {
236        ost_time_bases[ost_index] = octx.stream(ost_index as _).unwrap().time_base();
237    }
238
239    for (stream, mut packet) in ictx.packets() {
240        let ist_index = stream.index();
241        let ost_index = stream_mapping[ist_index];
242        if ost_index < 0 {
243            continue;
244        }
245        let ost_time_base = ost_time_bases[ost_index as usize];
246        match transcoders.get_mut(&ist_index) {
247            Some(transcoder) => {
248                packet.rescale_ts(stream.time_base(), transcoder.decoder.time_base());
249                transcoder.send_packet_to_decoder(&packet);
250                transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
251            }
252            None => {
253                // Do stream copy on non-video streams.
254                packet.rescale_ts(ist_time_bases[ist_index], ost_time_base);
255                packet.set_position(-1);
256                packet.set_stream(ost_index as _);
257                packet.write_interleaved(&mut octx).unwrap();
258            }
259        }
260    }
261
262    // Flush encoders and decoders.
263    for (ost_index, transcoder) in transcoders.iter_mut() {
264        let ost_time_base = ost_time_bases[*ost_index];
265        transcoder.send_eof_to_decoder();
266        transcoder.receive_and_process_decoded_frames(&mut octx, ost_time_base);
267        transcoder.send_eof_to_encoder();
268        transcoder.receive_and_process_encoded_packets(&mut octx, ost_time_base);
269    }
270
271    octx.write_trailer().unwrap();
272}
examples/remux.rs (line 54)
6fn main() {
7    let input_file = env::args().nth(1).expect("missing input file");
8    let output_file = env::args().nth(2).expect("missing output file");
9
10    ffmpeg_rs::init().unwrap();
11    log::set_level(log::Level::Warning);
12
13    let mut ictx = format::input(&input_file).unwrap();
14    let mut octx = format::output(&output_file).unwrap();
15
16    let mut stream_mapping = vec![0; ictx.nb_streams() as _];
17    let mut ist_time_bases = vec![Rational(0, 1); ictx.nb_streams() as _];
18    let mut ost_index = 0;
19    for (ist_index, ist) in ictx.streams().enumerate() {
20        let ist_medium = ist.parameters().codec_type();
21        if ist_medium != media::Type::Audio
22            && ist_medium != media::Type::Video
23            && ist_medium != media::Type::Subtitle
24        {
25            stream_mapping[ist_index] = -1;
26            continue;
27        }
28        stream_mapping[ist_index] = ost_index;
29        ist_time_bases[ist_index] = ist.time_base();
30        ost_index += 1;
31        let mut ost = octx.add_stream(encoder::find(codec::Id::None)).unwrap();
32        ost.set_parameters(ist.parameters());
33        // We need to set codec_tag to 0 lest we run into incompatible codec tag
34        // issues when muxing into a different container format. Unfortunately
35        // there's no high level API to do this (yet).
36        unsafe {
37            (*ost.parameters().as_mut_ptr()).codec_tag = 0;
38        }
39    }
40
41    octx.set_metadata(ictx.metadata().to_owned());
42    octx.write_header().unwrap();
43
44    for (stream, mut packet) in ictx.packets() {
45        let ist_index = stream.index();
46        let ost_index = stream_mapping[ist_index];
47        if ost_index < 0 {
48            continue;
49        }
50        let ost = octx.stream(ost_index as _).unwrap();
51        packet.rescale_ts(ist_time_bases[ist_index], ost.time_base());
52        packet.set_position(-1);
53        packet.set_stream(ost_index as _);
54        packet.write_interleaved(&mut octx).unwrap();
55    }
56
57    octx.write_trailer().unwrap();
58}

Trait Implementations§

Source§

impl Clone for Packet

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Drop for Packet

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Mut for Packet

Source§

impl Ref for Packet

Source§

impl Send for Packet

Source§

impl Sync for Packet

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.