-
Notifications
You must be signed in to change notification settings - Fork 277
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
FFmpegWriter: Macro & member cleanup, to build with newer releases #809
Conversation
- The `fmt` class member, which was of type AVFormat*, was really just an unnecessary copy of `(AVFormatContext*)oc->oformat`. But we were ASSIGNING into its members, which we were definitely not supposed to be doing. (And in recent FFmpegs, now that `AVFormat` has been `const`d, we can't.) It's gone; now we just use `oc->oformat` anywhere we used to access `fmt`. - The preprocessor macro to allocate a new _stream_ was a mess of cross purposes: It did allocate a stream, but then it also allocated a new AvCodecCtx on newer FFmpeg releases. Worse (and always galling to me), it proceeded to assign to a variable that WASN'T passed in to the macro, just taking it on faith that it would only be used where that variable was defined. That's just... ugh. So I broke it apart into two steps (stream creation and context allocation), realized the stream creation code was the same for all ffmpeg versions and didn't need to be a macro at all, and now a 4-parameter, 6-line magical macro has been replaced with a simple, zero-side-effect one-liner. - I also cleaned up the add_video_stream() code to be more like the add_audio_stream() code, since they were bad-different for no discernible reason.
Codecov Report
@@ Coverage Diff @@
## develop #809 +/- ##
===========================================
- Coverage 50.83% 48.78% -2.06%
===========================================
Files 161 185 +24
Lines 13454 18191 +4737
===========================================
+ Hits 6840 8875 +2035
- Misses 6614 9316 +2702
📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more |
This code now passes, but TBH I'm not 100% confident in it . The part of it I most had to screw with also happens to be the code I'm least familiar with, where it dumps raw frames to disk without using an encoder. I don't believe that code has any unit test coverage at all, really. In fact, I started trying to write a unit test for it... but then realized I don't actually know HOW to steer FFmpegWriter down that code path. I've never been clear on exactly what conditions lead to an Does anyone have any actual usage examples for the "bypassed-encoder" part of FFmpegWriter? @jonoomph ? @eisneinechse ? @jeffski ? (I have vague memories of you maybe mentioning that you were a consumer of that code, I think?) I'd be happy to write a unit test for it, if someone can point me to how. (Specifically, I'm referring to this code, where libopenshot/src/FFmpegWriter.cpp Lines 2125 to 2150 in f2b89e3
(That |
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) | ||
#pragma GCC diagnostic push | ||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||
st->codec->time_base.num = info.video_timebase.num; | ||
st->codec->time_base.den = info.video_timebase.den; | ||
#pragma GCC diagnostic pop | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is removed because you can't assign to values in the codec — it's now const
ed, so even the deprecation-override pragma wouldn't cut it anymore. This was never necessary, whatever it was trying to achieve can't be done the way it was trying to do it. Modifying the AVFormat
, the AVCodec
, or any other ffmpeg structure that's not one of the corresponding contexts (AVFormatContext
, AVCodecContext
, etc.) has always been unsupported, and with the expanded const
-correctness of the latest library versions, is no longer possible.
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) | ||
st->codecpar->codec_id = codec->id; | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced this is necessary — it should be automatic as part of the eventual avcodec_parameters_from_context()
call — but I left it in anyway.
@jonoomph @JacksonRG @eisneinechse @jeffski @AAAANYONE! Our CI is failing, and has been for some time. This PR fixes the build, so even though I'm not confident all of the code is correct (see comments above), last call before I merge it just to get us building again. The only likely casualties are relatively obscure code paths dealing with raw video frames. (Which are also not unit tested, so there's no way for us to know if I broke anything except to just try it and see who complains.) |
@ferdnyc Most of that code was there before I joined and was only kept to keep the compatibility to older, way older, versions of ffmpeg.It would be great if we could do away with this relics and have a more readable source and have a source that passes the CI. I am for it if anyone cares. |
@eisneinechse Yeah, as I said elsewhere (see #784) all of the code that supports FFmpeg < 3.0 is, well, I'll just copy my comments from over there:
There is light at the end of the tunnel, though. JUCE 6.x only supports building with CMake 3.15+, which is way below the version available on FFmpeg 2.x platforms. So a JUCE upgrade will force us to leave those platforms behind whether we want to or not, making their abandonment a much easier sell. (I should really get that upgrade PR in, I suppose.) If we're going to make CMake 3.15 our minimum required version to build the libraries, then we can easily set FFmpeg 3.4 as the minimum required dependency and dump not only all of the 2.x code, but also the 3.0 and 3.2 code paths. That'd let us pare down the macro hell of |
Well, I'mma go ahead and merge this one, as well as #784 after I do the inevitable conflict-resolution. That will also get rid of the warnings about |
This should fix at least part of the issues currently causing our CI builds to fail. It eliminates a member pointer in
openshot::FFmpegWriter
that didn't need to be there (and was being abused while it was), and it vastly simplifies the ugliest macro in all ofFFmpegUtilities.h
.The
fmt
class member, which was of typeAVFormat*
, was reallyjust an unnecessary copy of
(AVFormatContext*)oc->oformat
.But we were ASSIGNING into its members, which we were definitely
not supposed to be doing. (And in recent FFmpegs, now that
AVFormat*
has beenconst
d, we can't.) It's gone; now we justuse
oc->oformat
anywhere we used to accessfmt
.The preprocessor macro to allocate a new stream was a mess of
cross purposes: It did allocate a stream, but then it also
allocated a new
AvCodecCtx
on newer FFmpeg releases. Worse (andalways galling to me), it proceeded to assign to a variable
that WASN'T passed in to the macro, just taking it on faith that
it would only be used where that variable was defined. That's
just... ugh. So I broke it apart into two steps (stream creation
and context allocation), realized the stream creation code was
the same for all ffmpeg versions and didn't need to be a macro
at all, and now a 4-parameter, 6-line magical macro has been
replaced with a simple, zero-side-effect one-liner.
I also cleaned up the
add_video_stream()
code to be more likethe
add_audio_stream()
code, since they were bad-different forno discernible reason.