gyunaev / karlyriceditor

lyrics editor and CD+G/video exporter for Karaoke
http://www.ulduzsoft.com/linux/karaoke-lyrics-editor/
GNU General Public License v3.0
55 stars 16 forks source link

Add support for ffmpeg 5.0 ? #13

Open marillat opened 2 years ago

marillat commented 2 years ago

Could you add support for ffmpeg 5.0 ?

The first error is

ffmpegvideodecoder.cpp:107:44: error: invalid conversion from 'const AVCodec*' to 'AVCodec*' [-fpermissive]
  107 |         AVCodec *dec = avcodec_find_decoder( stream->codecpar->codec_id );
      |                        ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                            |
      |                                            const AVCodec*
make[1]: *** [Makefile:877: ffmpegvideodecoder.o] Error 1
assen-totin commented 1 year ago

Yep... a year later, apparently, still unsupported.

This particular issue is easy to fix: declare your AVCodec variables to be const as the ffmpeg API has changed and now returns a constant.

Much more unpleasant seems another problem: export has no audio, because ffmpeg continuously throws an error (once every frame?) that it refuses to accept a non-final frame that has frame_size=64 set.

There are also other errors - AC3 export does not work as there is some 'type' that has changed and a value of '7' is shown, whatever it may be. Also, import of WAV files does not work - an error is shown saying resampler could not be initialised (I have a vague feeling that my self-patched version of release 2.2 was able to load a WAV file).

assen-totin commented 1 year ago

Yep, fixing the missing audio is just part of the story. If ffpmeg receives a frame with less samples than its frame_size, it assumes this is the last frame, so it drops any subsequent frames. See here: https://ffmpeg.org/doxygen/trunk/encode_8c_source.html

A very (c)rude workaround that works for me:

        //FIXME: Skip a starting decodedAudioFrame if nb_samples is less than the number in the context.
        //qWarning( "Current frame nb_samples: %d", decodedAudioFrame->nb_samples);
        if ((! audioSamplesOut) && (decodedAudioFrame->nb_samples < m_aplayer->aCodecCtx->frame_size)) {
            qWarning( "droping an initial audio frame: too few nb_samples: %d (frame_size: %d)", decodedAudioFrame->nb_samples, m_aplayer->aCodecCtx->frame_size );
            av_frame_unref( resampledAudioframe );
            continue;
        }

More "fun": even with this fix, the audio truncates shortly before the end of the video. Why? Because videoencodingprofiles.cpp hard-codes the audio sampling rate for each profile to 44100 Hz - but this is wrong, in many cases it would be 48000 Hz. With the hard-coded value, the program will only write as many samples as there would be for 44100 Hz, ending the output prematurely. Proper solution would be to get the sampling frequency from m_aplayer->aCodecCtx->sample_rate - but, as I'm lazy and re-encode the video clips anyway, I just changed p.sampleRate=48000 for the one profile I use in videoencodingprofiles.cpp.

Some AC3 "fun": the error of supported sample format is because AC3 uses AV_SAMPLE_FMT_S32P and you don't check for this value (enum value for AV_SAMPLE_FMT_S32P is 7, the count starts at -1 - see https://ffmpeg.org/doxygen/3.3/group__lavu__sampfmts.html#gaf9a51ca15301871723577c730b5865c5). Adding it could be done in ffmpegvideoencoder.cpp like this:

        else if ( isAudioSampleFormatSupported( audioCodec->sample_fmts, AV_SAMPLE_FMT_S32P ) )
            audioCodecCtx->sample_fmt = AV_SAMPLE_FMT_S32P;

This, however, is not enough, as ffmpeg somehow expects frame-size=1536 while the audio context has 1152, resulting in the audio stream being denied after the first frame; this still needs investigation, but I don't have the time for it as I don;t need AC3 at all.