-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ffmpeg v5.1.1 seems broken #118
Comments
I see this same problem using |
On the same versions as @marcusstenbeck, I also see the same problem on macOS. It is my first time using this crate as well as ffmpeg as lib, so I was thought that I was doing something wrong 😅 |
I did a quick test and seems like if we pass a codec to impl Context {
pub fn new() -> Self {
unsafe {
let codec = super::encoder::find_by_name("libx264").unwrap();
Context {
ptr: avcodec_alloc_context3(codec.as_ptr()),
owner: None,
}
}
} The function docs can be found here. This was the code that I used to test: let encoder = AvContext::from_parameters(writer_stream.parameters())?
.encoder()
.video()?; |
Even with the change of @gil0mendes, I'm still unable to instantiate a 'open' a libx264 encoder. Did anyone manage to get the x264 transcoding example working on ffmpeg 5.0.0 or higher? |
Finding myself in the same seat as @SnyderTheOne, unable to run the x264 transcoding example with ffmpeg 5.1.1 |
Test available
|
Encountering this issue as well on FFmpeg 5.1.2 (ffmpeg-next 6.0.0) let mut context = codec::context::Context::new_with_codec(
decoder::find(ist.parameters().id()).expect("failed to find decoder"),
);
context.set_parameters(ist.parameters())?;
let decoder = context.decoder().video()?;
let codec = encoder::find(codec::Id::H264).expect("failed to find encoder");
let mut ost = octx.add_stream(codec)?;
let mut context = codec::context::Context::new_with_codec(codec);
context.set_parameters(ost.parameters())?;
let mut encoder = context.encoder().video()?;
encoder.set_height(decoder.height());
encoder.set_width(decoder.width());
encoder.set_aspect_ratio(decoder.aspect_ratio());
encoder.set_format(decoder.format());
encoder.set_frame_rate(decoder.frame_rate());
encoder.set_time_base(decoder.frame_rate().unwrap().invert()); // called `Option::unwrap()` on a `None` value |
Looks like there were several breaking changes to the ffmpeg API that have not made it to the APIs for this project, leading to this (and other) examples not working. For example: this line:
results in a call to:
Pre ffmpeg 5, the avformat_new_stream() function worked like this:
But ffmpeg v5 and greater now ignores the codec information.
So various parameters on the stream related to the codec are not being set, and therefore:
sets up an encoder (i.e. codec context) based on parameters (ost.parameters()) that won't have been correctly set. Note that this example doesn't necessarily explain the fact that frame_rate is not set, but is indicative of the fact that there are likely (many) other breaking changes in the ffmpeg codebase that have not been propagated through this codebase. Note that I've tried getting this transcoder code to work with ffmpeg versions <= 4 and they still break. The only success I had was reverting both ffmpeg AND this repo to a commit from October 2021. Unfortunately I'm not experienced enough with rust to be able to offer suggestions as to fixes right now. |
Further to my earlier comment, the following will work for setting the framerate, provided you want the output (encoder) rate to equal the input (decoder rate):
The
Could also be used. Here, I'm just making the frame_rate and time_base equivalent to those found on the input stream. Alas, the code then breaks at:
due to an
call with bad data (it complains that no codec is being passed, likely as a result of incorrect encoder (context) setup as outlined in my previous comment. |
After messing around with this crate I've now found quite a few breaking API changes......... there don't appear to be any decent safe bindings for ffmpeg for rust......... so have abandoned rust ffmpeg in favor of gstreamer, which has excellent rust support. |
I'm looking for a crate that I can create a DASH init.mp4 and many segment files from RGB frames. I believe this crate to be the one to do so, but it seems to be currently broken. Hopefully, someone will fix it soon. |
I have a working encoder implementation here (MIT licensed): https://github.com/nununoisy/spc-presenter-rs/tree/v0.1.1/src/video_builder I've verified it works for:
I've tested it with FFmpeg 4.4 on Linux, FFmpeg 5 on Windows (from vcpkg on msvc), and FFmpeg 6 on Linux. FFmpeg 6 requires this code in your // Call this somewhere in main()
fn ffmpeg_sys_version_detect() {
for (name, _value) in std::env::vars() {
if name.starts_with("DEP_FFMPEG_") {
println!(
r#"cargo:rustc-cfg=feature="{}""#,
name["DEP_FFMPEG_".len()..name.len()].to_lowercase()
);
}
}
} I did need to write some |
I just started a project using this crate and am seeing this issue attempting to implement the transcode-x264 example. Is there a workaround for this or a reason a PR hasn't been merged to address it? |
For anyone else running into this, the library does have support for v6+ (and the v7 that just launched today, props to the guy who merged that on launch day 🥳 ), but as mentioned above, the API is a little different than v4, and the transcoding x264 example is assuming ffmpeg v4. The fix is very simple to make it v6/v7 compatible: // old
let output_context = ffmpeg::codec::context::Context::from_parameters(otx.parameters())?;
// new
let codec = ffmpeg::encoder::find(ffmpeg::codec::Id::H264)?;
let output_context = ffmpeg::codec::context::Context::new_with_codec(codec); also, toward the end of encoder = encoder.open_with(libx264_opts)?; |
hi! Would you make a PR with a conditional compilation depending on the ffmpeg version (like this for instance https://github.com/zmwangx/rust-ffmpeg/blob/master/src/codec/capabilities.rs#L9) that would make it compatible with ffmpeg6 onwards? I wouldn't mind merging it :) |
Hello,
Thank you for your work on this project. It allows a lot of awesome implementations of ffmpeg.
I'm trying to make this work with
ffmpeg
v5.1.1 (withffmpeg-next
v5.1.1).However I'm facing many issues with the
transcode-x264.rs
example.Here is an output of running the example:
As you can see, the
decoder.frame_rate()
isNone
but it's not the case when using v4.If I try to enforce
frame_rate
andtime_base
with static values, I have this error:Any idea?
Edit 1
FYI, if I log the output of
decoder.frame_rate()
anddecoder.time_base()
, I get:fr: None, tb: Rational(0/2)
Edit 2:
If I enforce the codec using
encoder.open_as_with()
, I get another error:Edit 3
Another interesting input:
It seems that the method
codec::context::Context::from_parameters
is not including the codec.The text was updated successfully, but these errors were encountered: