Invalid argument error in transcode-x264.rs
Thank you very much for providing ffmpeg-the-third! The example provided transcode-x264.rs does not work for me. I get the following error
[NULL @ 000001967e2c5440] No codec provided to avcodec_open2()
thread 'main' panicked at examples\transcode-x264.rs:69:14:
error opening libx264 encoder with supplied settings: ffmpeg::Error(22: Invalid argument)
The corresponding example works with ffmpeg-next, but I have already built the decoding part of my program around ffmpeg-the-third, so I would prefer to keep using ffmpeg-the-third.
I have tried to create the encoder with other methods, for example with codec::context::Context::new() but I have not succeded.
I have only tried binary distributions off ffmpeg, I have not tried to build my own.
OS: Windows 11 ffmpeg versions tested:
- 7.1-full_build-www.gyan.dev
- 7.1-152-gd72536008a-20250114
- 6.1.1-full_build-www.gyan.dev
try this: https://github.com/phial3/ffmpeg-third
This seems to be caused by Context::from_parameters not setting the AVCodecContext.codec field. You could call open_as_with(x264_codec, x264_opts) for a quick workaround, but this should be properly handled by the crate IMHO.
There also seems to be another problem with the example, as seen in this upstream issue: https://github.com/zmwangx/rust-ffmpeg/issues/118. See that thread for some possible workarounds.
The examples have not gotten much attention recently because other things are higher priority, i.e. fixing old, unsound code and improving APIs that were written when Rust was a lot less mature.
try this: https://github.com/phial3/ffmpeg-third
Thank you, but I got the same problem i ffmpeg-third as well.
This seems to be caused by
Context::from_parametersnot setting theAVCodecContext.codecfield. You could callopen_as_with(x264_codec, x264_opts)for a quick workaround, but this should be properly handled by the crate IMHO.There also seems to be another problem with the example, as seen in this upstream issue: zmwangx/rust-ffmpeg#118. See that thread for some possible workarounds.
The examples have not gotten much attention recently because other things are higher priority, i.e. fixing old, unsound code and improving APIs that were written when Rust was a lot less mature.
Thank you! If I understand correctly, your suggestion is to replace
encoder.open_with(x264_opts)
by
let x264_codec = encoder::find(codec::Id::H264);
encoder.open_as_with(x264_codec, x264_opts)
When I do that, I instead get the error
[libx264 @ 000001d2b2392500] broken ffmpeg default settings detected
[libx264 @ 000001d2b2392500] use an encoding preset (e.g. -vpre medium)
[libx264 @ 000001d2b2392500] preset usage: -vpre <speed> -vpre <profile>
[libx264 @ 000001d2b2392500] speed presets are listed in x264 --help
[libx264 @ 000001d2b2392500] profile is optional; x264 defaults to high
thread 'main' panicked at examples\transcode-x264.rs:70:14:
error opening libx264 encoder with supplied settings: ffmpeg::Error(542398533: Generic error in an external library)
I also read issue #118 as you suggested, but it is above my capacity to sort out all the things that are said there. I just tried to follow the last comment there, but there seems to be no function called ffmpeg::codec::context::Context::new_with_codec()
src/format/context/output.rs line 71:
pub fn add_stream<T, E: traits::Encoder<T>>(&mut self, codec: E) -> Result<StreamMut, Error> {
let codec = codec.encoder();
let codec = codec.map_or(ptr::null(), |c| c.as_ptr());
let ptr = avformat_new_stream(self.as_mut_ptr(), codec);
......
}
the c parameters in avformat_new_stream is do nothing, the result is
so we have to use the way avcodec_alloc_context3(codec).
see here: https://ffmpeg.org/doxygen/trunk/group__lavf__core.html#gaf2c94216a6a19144e86cac843a0a4409
Thank you for investigating this. I'll take a look later today and see if we can't fix this and make it usable
Thank you for investigating this. I'll take a look later today and see if we can't fix this and make it usable
That's all be resolved at https://github.com/phial3/ffmpeg-third, please review it. @erith835 Please try again.
Thank you for investigating this. I'll take a look later today and see if we can't fix this and make it usable
That's all be resolved at https://github.com/phial3/ffmpeg-third, please review it. @erith835 Please try again.
Thank you. Now the example works in ffmpeg-third. So should I try to migrate from ffmpeg-the-thrid to ffmpeg-third, or will the fix reach ffmpeg-the-third soon?
Actually, I don't even know how to switch to ffmpeg-third, because its not in crates.io.
If you've fixed it in a fork, a PR is very welcome :)
If you've fixed it in a fork, a PR is very welcome :)
I would be happy to contribute this PR. However, before submitting it, could you please review the following areas to ensure they are reasonable? If there are any issues, please point them out:
- The changes made to the new method for Context in
src/codec/context.rs:
pub fn new(codec: Option<Codec>) -> Self {
unsafe {
Context {
ptr: match codec {
Some(c) => avcodec_alloc_context3(c.as_ptr()),
None => avcodec_alloc_context3(ptr::null()),
},
owner: None,
}
}
}
- The newly added
set_parameters_intomethod insrc/format/stream/stream_mut.rs. I believe this approach is easier and better than the one, used by the original author (https://github.com/zmwangx/rust-ffmpeg). However, there is a conflict with the previous method that implements the traitAsPtr<AVCodecParameters>:
pub fn set_parameters_into<P: Into<codec::Parameters>>(&mut self, parameters: P) {
let parameters = parameters.into();
unsafe {
avcodec_parameters_copy((*self.as_mut_ptr()).codecpar, parameters.as_ptr());
}
}
Let me know if you'd like any further changes!
1 is perfectly reasonable. Maybe a doc comment should be added that you are not allowed to call avcodec_open2 with a different codec than specified in new (see ffmpeg docs), just to make sure. (if you call new(None), any codec is fine for avcodec_open2)
2 also looks reasonable, but I'm not sure what types even implement Into<Parameters> at the moment. Or did you add implementations for that in your branch?
1 is perfectly reasonable. Maybe a doc comment should be added that you are not allowed to call
avcodec_open2with a different codec than specified innew(see ffmpeg docs), just to make sure. (if you callnew(None), any codec is fine foravcodec_open2)2 also looks reasonable, but I'm not sure what types even implement
Into<Parameters>at the moment. Or did you add implementations for that in your branch?
Sorry it took so long,please fix the CI check, I'll sync it up.