pub struct Packet(/* private fields */);
Implementations§
Source§impl Packet
impl Packet
Sourcepub fn empty() -> Self
pub fn empty() -> Self
Examples found in repository?
More 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 }
pub fn new(size: usize) -> Self
pub fn copy(data: &[u8]) -> Self
pub fn borrow(data: &[u8]) -> Borrow<'_>
pub fn shrink(&mut self, size: usize)
pub fn grow(&mut self, size: usize)
Sourcepub fn rescale_ts<S, D>(&mut self, source: S, destination: D)
pub fn rescale_ts<S, D>(&mut self, source: S, destination: D)
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
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}
pub fn flags(&self) -> Flags
pub fn set_flags(&mut self, value: Flags)
pub fn is_key(&self) -> bool
pub fn is_corrupt(&self) -> bool
pub fn stream(&self) -> usize
Sourcepub fn set_stream(&mut self, index: usize)
pub fn set_stream(&mut self, index: usize)
Examples found in repository?
More 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}
pub fn pts(&self) -> Option<i64>
pub fn set_pts(&mut self, value: Option<i64>)
pub fn dts(&self) -> Option<i64>
pub fn set_dts(&mut self, value: Option<i64>)
pub fn size(&self) -> usize
pub fn duration(&self) -> i64
pub fn set_duration(&mut self, value: i64)
pub fn position(&self) -> isize
Sourcepub fn set_position(&mut self, value: isize)
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
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}
pub fn convergence(&self) -> isize
pub fn side_data(&self) -> SideDataIter<'_> ⓘ
pub fn data(&self) -> Option<&[u8]>
pub fn data_mut(&mut self) -> Option<&mut [u8]>
pub fn read(&mut self, format: &mut Input) -> Result<(), Error>
pub fn write(&self, format: &mut Output) -> Result<bool, Error>
Sourcepub fn write_interleaved(&self, format: &mut Output) -> Result<(), Error>
pub fn write_interleaved(&self, format: &mut Output) -> Result<(), Error>
Examples found in repository?
More 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§
impl Send for Packet
impl Sync for Packet
Auto Trait Implementations§
impl Freeze for Packet
impl RefUnwindSafe for Packet
impl Unpin for Packet
impl UnwindSafe for Packet
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more