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