Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package DVDStyler for openSUSE:Factory checked in at 2022-11-09 12:58:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/DVDStyler (Old) and /work/SRC/openSUSE:Factory/.DVDStyler.new.1597 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "DVDStyler" Wed Nov 9 12:58:30 2022 rev:12 rq:1034830 version:3.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/DVDStyler/DVDStyler.changes 2022-08-02 22:09:19.481795452 +0200 +++ /work/SRC/openSUSE:Factory/.DVDStyler.new.1597/DVDStyler.changes 2022-11-09 12:58:38.428755527 +0100 @@ -1,0 +2,7 @@ +Sat Nov 5 09:51:47 UTC 2022 - Christophe Giboudeaux <christo...@krop.fr> + +- Add upstream changes to allow building DVDStyler with FFmpeg5: + * 0001-fixed-encoding-of-silent-audio-file.patch + * dvdstyler-ffmpeg5.patch + +------------------------------------------------------------------- New: ---- 0001-fixed-encoding-of-silent-audio-file.patch dvdstyler-ffmpeg5.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ DVDStyler.spec ++++++ --- /var/tmp/diff_new_pack.cHmBM3/_old 2022-11-09 12:58:38.876758053 +0100 +++ /var/tmp/diff_new_pack.cHmBM3/_new 2022-11-09 12:58:38.880758075 +0100 @@ -33,6 +33,10 @@ Patch0: reproducible.patch # PATCH-FIX-UPSTREAM -- https://sourceforge.net/p/dvdstyler/discussion/318795/thread/b40e1d871f/993d/attachment/fix.patch Patch1: fix.patch +# PATCH-FIX-UPSTREAM +Patch2: 0001-fixed-encoding-of-silent-audio-file.patch +# FFmpeg5 support +Patch3: dvdstyler-ffmpeg5.patch BuildRequires: bison #!BuildIgnore: wxWidgets-3_2-devel BuildRequires: dvd+rw-tools ++++++ 0001-fixed-encoding-of-silent-audio-file.patch ++++++ >From e3cf3b06d521973303db567e29984b44b112269d Mon Sep 17 00:00:00 2001 From: ntalex <nta...@sf.net> Date: Wed, 17 Nov 2021 20:08:46 +0100 Subject: [PATCH] fixed encoding of silent audio file --- src/mediaenc_ffmpeg.cpp | 199 +++++++++++++++++++++++++--------------- src/mediaenc_ffmpeg.h | 6 +- 2 files changed, 130 insertions(+), 75 deletions(-) diff --git a/src/mediaenc_ffmpeg.cpp b/src/mediaenc_ffmpeg.cpp index 01db671..c591458 100644 --- a/src/mediaenc_ffmpeg.cpp +++ b/src/mediaenc_ffmpeg.cpp @@ -45,11 +45,11 @@ wxFfmpegMediaEncoder::wxFfmpegMediaEncoder(int threadCount) { m_audioCodec = NULL; m_nextVideoPts = 0; m_nextAudioPts = 0; - m_samples = NULL; m_audioFrame = NULL; m_picture = NULL; m_imgConvertCtx = NULL; m_videoOutbuf = NULL; + m_audioFile = NULL; } wxFfmpegMediaEncoder::~wxFfmpegMediaEncoder() { @@ -74,6 +74,18 @@ void print_error(const char *filename, int err) { bool wxFfmpegMediaEncoder::BeginEncode(const wxString& fileName, VideoFormat videoFormat, AudioFormat audioFormat, AspectRatio aspectRatio, int videoBitrate, bool cbr) { EndEncode(); + if (videoFormat == vfNONE) { + AVCodecID codecId = audioFormat == afAC3 ? AV_CODEC_ID_AC3 : AV_CODEC_ID_MP2; + if (!addAudioStream(codecId)) + return false; + + m_audioFile = fopen((const char*) fileName.ToUTF8(), "wb"); + if (!m_audioFile) { + wxLogError("Could not open '%s'", fileName.c_str()); + return false; + } + return true; + } AVOutputFormat* outputFormat = NULL; if (videoFormat == vfNONE || audioFormat == afNONE) outputFormat = av_guess_format(NULL, (const char*) fileName.ToUTF8(), NULL); @@ -136,7 +148,6 @@ AVFrame* allocPicture(AVPixelFormat pix_fmt, int width, int height) { AVFrame* frame = av_frame_alloc(); if (!frame) return NULL; -#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(53, 0, 0) frame->width = width; frame->height = height; frame->format = pix_fmt; @@ -144,15 +155,6 @@ AVFrame* allocPicture(AVPixelFormat pix_fmt, int width, int height) { av_free(frame); return NULL; } -#else - int size = avpicture_get_size(pix_fmt, width, height); - uint8_t* picture_buf = (uint8_t*) av_malloc(size); - if (!picture_buf) { - av_free(frame); - return NULL; - } - avpicture_fill((AVPicture *) frame, picture_buf, pix_fmt, width, height); -#endif return frame; } @@ -252,25 +254,21 @@ bool wxFfmpegMediaEncoder::addAudioStream(int codecId) { m_audioStm = NULL; return true; } - m_audioStm = avformat_new_stream(m_outputCtx, NULL); - if (!m_audioStm) { - wxLogError(wxT("Could not alloc stream")); - return false; + if (m_outputCtx != NULL) { + m_audioStm = avformat_new_stream(m_outputCtx, NULL); + if (!m_audioStm) { + wxLogError(wxT("Could not alloc stream")); + return false; + } + m_audioStm->id = 1; } - m_audioStm->id = 1; // find the audio encoder and open it AVCodec* encoder = NULL; AVSampleFormat sampleFmt = AV_SAMPLE_FMT_S16; if ((AVCodecID) codecId == AV_CODEC_ID_AC3) { - // There are 2 ac3 encoders (float and integer). Depending on libav implementation/version/fork, - // one or the other may work. So we try both. - encoder = avcodec_find_encoder_by_name("ac3_fixed"); - if (!hasSampleFmt(encoder, sampleFmt)) { - // Try the encoding from float format - sampleFmt = AV_SAMPLE_FMT_FLTP; - encoder = avcodec_find_encoder((AVCodecID) codecId ); - } + sampleFmt = AV_SAMPLE_FMT_FLTP; + encoder = avcodec_find_encoder((AVCodecID) codecId ); } else { sampleFmt = AV_SAMPLE_FMT_S16; encoder = avcodec_find_encoder((AVCodecID) codecId ); @@ -285,54 +283,52 @@ bool wxFfmpegMediaEncoder::addAudioStream(int codecId) { AVCodecContext* c = m_audioCodec; c->thread_count = m_threadCount; - c->codec_id = (AVCodecID) codecId; - c->codec_type = AVMEDIA_TYPE_AUDIO; c->bit_rate = 64000; c->sample_rate = 48000; c->sample_fmt = sampleFmt; c->channels = 2; c->channel_layout = AV_CH_LAYOUT_STEREO; - c->time_base = (AVRational){ 1, c->sample_rate }; - // some formats want stream headers to be separate - if(m_outputCtx->oformat->flags & AVFMT_GLOBALHEADER) - c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - - m_audioStm->time_base = c->time_base; + if (m_audioStm && avcodec_parameters_from_context(m_audioStm->codecpar, c) < 0) { + wxLogError("Failed to copy encoder parameters to output audio stream"); + return false; + } if (avcodec_open2(c, encoder, NULL) < 0) { wxLogError(wxT("Could not open audio codec")); return false; } - if (avcodec_parameters_from_context(m_audioStm->codecpar, c) < 0) { - wxLogError("Failed to copy encoder parameters to output audio stream"); + + m_audioFrame = av_frame_alloc(); + if (!m_audioFrame) { + wxLogError("Could not allocate audio frame"); return false; } - m_samples = (int16_t*) av_malloc(c->frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels); - memset(m_samples, 0, c->frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels); - - m_audioFrame = av_frame_alloc(); m_audioFrame->nb_samples = c->frame_size; - avcodec_fill_audio_frame(m_audioFrame, c->channels, c->sample_fmt, (uint8_t *) m_samples, c->frame_size - * av_get_bytes_per_sample(c->sample_fmt) * c->channels, 1); + m_audioFrame->format = c->sample_fmt; + m_audioFrame->channel_layout = c->channel_layout; + + int ret = av_frame_get_buffer(m_audioFrame, 0); // allocate the data buffers + if (ret < 0) { + wxLogError("Could not allocate audio data buffers"); + return false; + } + ret = av_frame_make_writable(m_audioFrame); + if (ret < 0) + return false; + for (int i = 0; i < c->channels; i++) { + uint16_t *samples = (uint16_t*)m_audioFrame->data[i]; + memset(samples, 0, c->frame_size * av_get_bytes_per_sample(c->sample_fmt)); + } return true; } void wxFfmpegMediaEncoder::CloseAudioEncoder() { - if (!m_audioStm) - return; - if (m_samples) { - av_freep(&m_samples); - } - if (m_audioFrame) { - av_frame_free(&m_audioFrame); - } + av_frame_free(&m_audioFrame); + avcodec_free_context(&m_audioCodec); m_audioStm = NULL; - if (m_audioCodec != NULL) { - avcodec_close(m_audioCodec); - } } void wxFfmpegMediaEncoder::CloseVideoEncoder() { @@ -345,10 +341,8 @@ void wxFfmpegMediaEncoder::CloseVideoEncoder() { av_freep(&m_picture); } av_freep(&m_videoOutbuf); + avcodec_free_context(&m_videoCodec); m_videoStm = NULL; - if (m_videoCodec != NULL) { - avcodec_close(m_videoCodec); - } } bool wxFfmpegMediaEncoder::EncodeImage(wxImage image, int frames, AbstractProgressDialog* progressDialog) { @@ -390,20 +384,77 @@ bool wxFfmpegMediaEncoder::EncodeImage(wxImage image, int frames, AbstractProgre return true; } +int encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, FILE *output) { + int ret; + + /* send the frame for encoding */ + ret = avcodec_send_frame(ctx, frame); + if (ret < 0) { + wxLogError("Error sending the frame to the encoder"); + return ret; + } + + /* read all the available output packets (in general there may be any + * number of them */ + while (ret >= 0) { + ret = avcodec_receive_packet(ctx, pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return 0; + else if (ret < 0) { + wxLogError("Error encoding audio frame"); + return ret; + } + + fwrite(pkt->data, 1, pkt->size, output); + av_packet_unref(pkt); + } + + return 0; +} + bool wxFfmpegMediaEncoder::EncodeAudio(double duration, AbstractProgressDialog* progressDialog) { - // encode audio - while (true) { - double audioPts = m_audioStm ? ((double) m_nextAudioPts) * m_audioCodec->time_base.num - / m_audioCodec->time_base.den : 0.0; - if (progressDialog->WasCanceled()) + if (m_outputCtx != NULL) { + // encode audio stream + while (true) { + double audioPts = m_audioCodec ? ((double) m_nextAudioPts) * m_audioCodec->time_base.num + / m_audioCodec->time_base.den : 0.0; + if (progressDialog->WasCanceled()) + return false; + + if (!m_audioCodec || audioPts >= duration) + break; + + // write interleaved audio and video frames + if (!writeAudioFrame()) + return false; + } + } else { + // encode audio file + AVCodecContext* c = m_audioCodec; + + AVPacket* pkt = av_packet_alloc(); + if (!pkt) { + wxLogError("could not allocate the packet"); return false; + } + + int64_t pts = 0; + while (true) { + double audioPts = ((double) pts) * c->time_base.num /c->time_base.den; + if (progressDialog->WasCanceled()) + return false; + if (audioPts >= duration) + break; + + pts += m_audioFrame->nb_samples; + if (encode(c, m_audioFrame, pkt, m_audioFile) < 0) + return false; + } - if (!m_audioStm || audioPts >= duration) - break; + // flush the encoder + encode(c, NULL, pkt, m_audioFile); - // write interleaved audio and video frames - if (!writeAudioFrame()) - return false; + av_packet_free(&pkt); } return true; } @@ -429,7 +480,6 @@ int encode(AVCodecContext *avctx, AVPacket *pkt, AVFrame *frame, int *got_packet return ret; } - bool wxFfmpegMediaEncoder::writeAudioFrame() { AVPacket pkt = { 0 }; // data and size must be 0; int got_packet; @@ -495,14 +545,17 @@ bool wxFfmpegMediaEncoder::writeVideoFrame() { } void wxFfmpegMediaEncoder::EndEncode() { - if (!m_outputCtx) - return; - - // write the trailer - if (m_outputCtx->nb_streams) - av_write_trailer(m_outputCtx); - - CloseEncoder(); + if (m_outputCtx) { + // write the trailer + if (m_outputCtx->nb_streams) + av_write_trailer(m_outputCtx); + + CloseEncoder(); + } else if (m_audioFile != NULL) { + fclose(m_audioFile); + m_audioFile = NULL; + CloseAudioEncoder(); + } } void wxFfmpegMediaEncoder::CloseEncoder() { diff --git a/src/mediaenc_ffmpeg.h b/src/mediaenc_ffmpeg.h index bf4ad65..74d8210 100644 --- a/src/mediaenc_ffmpeg.h +++ b/src/mediaenc_ffmpeg.h @@ -48,7 +48,6 @@ private: bool addVideoStream(int codecId, VideoFormat videoFormat, AspectRatio aspectRatio, int videoBitrate, bool cbr); bool addAudioStream(int codecId); - int16_t* m_samples; AVFrame* m_audioFrame; void CloseAudioEncoder(); @@ -57,12 +56,15 @@ private: uint8_t* m_videoOutbuf; void CloseVideoEncoder(); - void getAudioFrame(int nbChannels); + /** writes a silent audio frame */ bool writeAudioFrame(); /** writes m_picture */ bool writeVideoFrame(); void CloseEncoder(); + + /** used to encode audio file **/ + FILE* m_audioFile; }; #endif // WX_FFMPEG_MEDIA_ENCODER_H -- 2.38.0 ++++++ dvdstyler-ffmpeg5.patch ++++++ Origin: upstream Author: NtAlex <ntalex at sf.net> diff --git a/src/mediaenc_ffmpeg.cpp b/src/mediaenc_ffmpeg.cpp index c591458..29e1954 100644 --- a/src/mediaenc_ffmpeg.cpp +++ b/src/mediaenc_ffmpeg.cpp @@ -30,6 +30,7 @@ extern "C" { #include <libswscale/swscale.h> #include <libavutil/mathematics.h> #include <libavutil/avstring.h> +#include <libavcodec/avcodec.h> } #define AUDIO_BUF_SIZE 524288 @@ -57,10 +58,15 @@ wxFfmpegMediaEncoder::~wxFfmpegMediaEncoder() { } wxString wxFfmpegMediaEncoder::GetBackendVersion() { +#ifdef LIBAVFORMAT_VERSION_INT return wxString::Format(wxT("libavformat %d.%d.%d, libavcodec %d.%d.%d, libavutil %d.%d.%d"), LIBAVFORMAT_VERSION_INT >> 16, LIBAVFORMAT_VERSION_INT >> 8 & 0xFF, LIBAVFORMAT_VERSION_INT & 0xFF, LIBAVCODEC_VERSION_INT >> 16, LIBAVCODEC_VERSION_INT >> 8 & 0xFF, LIBAVCODEC_VERSION_INT & 0xFF, LIBAVUTIL_VERSION_INT >> 16, LIBAVUTIL_VERSION_INT >> 8 & 0xFF, LIBAVUTIL_VERSION_INT & 0xFF); +#else + return wxString::Format(wxT("libavformat %d, libavcodec %d, libavutil %d"), + LIBAVCODEC_VERSION_MAJOR, LIBAVFORMAT_VERSION_MAJOR, LIBAVUTIL_VERSION_MAJOR); +#endif } void print_error(const char *filename, int err) { @@ -86,7 +92,10 @@ bool wxFfmpegMediaEncoder::BeginEncode(const wxString& fileName, VideoFormat vid } return true; } - AVOutputFormat* outputFormat = NULL; +#if LIBAVCODEC_VERSION_MAJOR > 58 + const +#endif +AVOutputFormat* outputFormat = NULL; if (videoFormat == vfNONE || audioFormat == afNONE) outputFormat = av_guess_format(NULL, (const char*) fileName.ToUTF8(), NULL); else @@ -95,13 +104,15 @@ bool wxFfmpegMediaEncoder::BeginEncode(const wxString& fileName, VideoFormat vid wxLogError(wxT("Cannot open output format")); return false; } - outputFormat->video_codec = videoFormat == vfNONE ? AV_CODEC_ID_NONE : AV_CODEC_ID_MPEG2VIDEO; + + AVCodecID video_codec = videoFormat == vfNONE ? AV_CODEC_ID_NONE : AV_CODEC_ID_MPEG2VIDEO; + AVCodecID audio_codec; if (audioFormat == afNONE) - outputFormat->audio_codec = AV_CODEC_ID_NONE; + audio_codec = AV_CODEC_ID_NONE; else if (audioFormat == afAC3) - outputFormat->audio_codec = AV_CODEC_ID_AC3; + audio_codec = AV_CODEC_ID_AC3; else - outputFormat->audio_codec = AV_CODEC_ID_MP2; + audio_codec = AV_CODEC_ID_MP2; m_outputCtx = NULL; avformat_alloc_output_context2(&m_outputCtx, outputFormat, NULL, (const char*) fileName.ToUTF8()); @@ -113,9 +124,9 @@ bool wxFfmpegMediaEncoder::BeginEncode(const wxString& fileName, VideoFormat vid m_outputCtx->packet_size = 2048; // add video and audio streams - if (!addVideoStream(outputFormat->video_codec, videoFormat, aspectRatio, videoBitrate, cbr)) + if (!addVideoStream(video_codec, videoFormat, aspectRatio, videoBitrate, cbr)) return false; - if (!addAudioStream(outputFormat->audio_codec)) + if (!addAudioStream(audio_codec)) return false; // open the output file @@ -172,7 +183,7 @@ bool wxFfmpegMediaEncoder::addVideoStream(int codecId, VideoFormat videoFormat, m_videoStm->id = 0; // find the video encoder and open it - AVCodec* encoder = avcodec_find_encoder((AVCodecID) codecId); + auto* encoder = avcodec_find_encoder((AVCodecID) codecId); if (!encoder) { wxLogError(wxT("Video codec not found")); return false; @@ -264,7 +275,7 @@ bool wxFfmpegMediaEncoder::addAudioStream(int codecId) { } // find the audio encoder and open it - AVCodec* encoder = NULL; + const AVCodec* encoder = NULL; AVSampleFormat sampleFmt = AV_SAMPLE_FMT_S16; if ((AVCodecID) codecId == AV_CODEC_ID_AC3) { sampleFmt = AV_SAMPLE_FMT_FLTP;