Merge ~liushuyu-011/ubuntu/+source/performous:ubuntu/devel into ubuntu/+source/performous:ubuntu/devel

Proposed by Zixing Liu
Status: Merged
Merged at revision: 66a3de78f036912cf58410267831160aba033f76
Proposed branch: ~liushuyu-011/ubuntu/+source/performous:ubuntu/devel
Merge into: ubuntu/+source/performous:ubuntu/devel
Diff against target: 213 lines (+192/-0)
3 files modified
debian/changelog (+7/-0)
debian/patches/ffmpeg-5.1.patch (+184/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Vladimir Petko (community) Approve
Review via email: mp+473476@code.launchpad.net

Description of the change

This merge proposal backports a patch from performous upstream to fix FTBFS with FFmpeg 7

To post a comment you must log in.
Revision history for this message
Vladimir Petko (vpa1977) wrote :

- Please add ftbfs bug and reference it in the changelog/patch
- Please run quilt refresh.
- Needs PPA build

review: Needs Fixing
Revision history for this message
Zixing Liu (liushuyu-011) wrote :
Revision history for this message
Vladimir Petko (vpa1977) wrote :

Looks fine, but the https://launchpad.net/ubuntu/+source/aubio is still pending publication.
Will wait for it to get published.

Revision history for this message
Vladimir Petko (vpa1977) wrote :

  Uploading performous_1.3.0+ds-1ubuntu1.dsc: done.
  Uploading performous_1.3.0+ds-1ubuntu1.debian.tar.xz: done.
  Uploading performous_1.3.0+ds-1ubuntu1_source.buildinfo: done.
  Uploading performous_1.3.0+ds-1ubuntu1_source.changes: done.
Successfully uploaded packages.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index b91202e..7af8159 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+performous (1.3.0+ds-1ubuntu1) oracular; urgency=medium
7+
8+ * d/p/ffmpeg-5.1.patch: add a patch to fix FTBFS with FFmpeg 7
9+ (LP: #2080271, #2080302).
10+
11+ -- Zixing Liu <zixing.liu@canonical.com> Wed, 18 Sep 2024 15:47:56 -0600
12+
13 performous (1.3.0+ds-1build5) oracular; urgency=medium
14
15 * Rebuild against new libavcodec61.
16diff --git a/debian/patches/ffmpeg-5.1.patch b/debian/patches/ffmpeg-5.1.patch
17new file mode 100644
18index 0000000..ecf4b34
19--- /dev/null
20+++ b/debian/patches/ffmpeg-5.1.patch
21@@ -0,0 +1,184 @@
22+Description: ffmpeg: Use AVChannelLayout API when available
23+ This adds support for ffmpeg@5.1+
24+Author: Gregorio Litenstein <g.litenstein@gmail.com>
25+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/performous/+bug/2080302
26+Origin: upstream, https://github.com/performous/performous/commit/f26c27bf74b85fa3e3b150682ab9ecf9aecb3c50
27+Last-Update: 2024-09-18
28+---
29+diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
30+index db204fb885..f2bc349c4f 100644
31+--- a/game/ffmpeg.cc
32++++ b/game/ffmpeg.cc
33+@@ -6,8 +6,8 @@
34+ #include "util.hh"
35+
36+ #include "aubio/aubio.h"
37+-#include <memory>
38+ #include <iostream>
39++#include <memory>
40+ #include <sstream>
41+ #include <stdexcept>
42+ #include <system_error>
43+@@ -31,6 +31,11 @@ extern "C" {
44+
45+ #define AUDIO_CHANNELS 2
46+
47++#if !defined(__PRETTY_FUNCTION__) && defined(_MSC_VER)
48++#define __PRETTY_FUNCTION__ __FUNCSIG__
49++#endif
50++
51++#define FFMPEG_CHECKED(func, args, caller) FFmpeg::check(func args, caller)
52+
53+ namespace {
54+ std::string ffversion(unsigned ver) {
55+@@ -229,18 +234,13 @@ static void printFFmpegInfo() {
56+ #endif
57+ }
58+
59+-class FFmpeg::Error: public std::runtime_error {
60+- public:
61+- Error(const FFmpeg &self, int errorValue): std::runtime_error(msgFmt(self, errorValue)) {}
62+- private:
63+- static std::string msgFmt(const FFmpeg &self, int errorValue) {
64++std::string FFmpeg::Error::msgFmt(const FFmpeg &self, int errorValue, const char *func) {
65+ char message[AV_ERROR_MAX_STRING_SIZE];
66+ av_strerror(errorValue, message, AV_ERROR_MAX_STRING_SIZE);
67+ std::ostringstream oss;
68+- oss << "FFmpeg Error: Processing file " << self.m_filename << " code=" << errorValue << ", error=" << message;
69++ oss << "FFmpeg Error: Processing file " << self.m_filename << " code=" << errorValue << ", error=" << message << ", in function=" << func;
70+ return oss.str();
71+- }
72+-};
73++}
74+
75+ FFmpeg::FFmpeg(fs::path const& _filename, int mediaType) : m_filename(_filename) {
76+ static std::once_flag static_infos;
77+@@ -249,12 +249,10 @@ FFmpeg::FFmpeg(fs::path const& _filename, int mediaType) : m_filename(_filename)
78+ av_log_set_level(AV_LOG_ERROR);
79+ {
80+ AVFormatContext *avfctx = nullptr;
81+- auto err = avformat_open_input(&avfctx, m_filename.string().c_str(), nullptr, nullptr);
82+- if (err) throw Error(*this, err);
83++ FFMPEG_CHECKED(avformat_open_input, (&avfctx, m_filename.string().c_str(), nullptr, nullptr), __PRETTY_FUNCTION__);
84+ m_formatContext.reset(avfctx);
85+ }
86+- auto err = avformat_find_stream_info(m_formatContext.get(), nullptr);
87+- if (err < 0) throw Error(*this, err);
88++ FFMPEG_CHECKED(avformat_find_stream_info, (m_formatContext.get(), nullptr), __PRETTY_FUNCTION__);
89+ m_formatContext->flags |= AVFMT_FLAG_GENPTS;
90+ // Find a track and open the codec
91+ #if (LIBAVFORMAT_VERSION_INT) >= (AV_VERSION_INT(59, 0, 100))
92+@@ -262,7 +260,7 @@ FFmpeg::FFmpeg(fs::path const& _filename, int mediaType) : m_filename(_filename)
93+ #endif
94+ AVCodec* codec = nullptr;
95+ m_streamId = av_find_best_stream(m_formatContext.get(), static_cast<AVMediaType>(mediaType), -1, -1, &codec, 0);
96+- if (m_streamId < 0) throw Error(*this, m_streamId);
97++ if (m_streamId < 0) throw Error(*this, m_streamId, __PRETTY_FUNCTION__);
98+
99+ decltype(m_codecContext) pCodecCtx{avcodec_alloc_context3(codec), avcodec_free_context};
100+ avcodec_parameters_to_context(pCodecCtx.get(), m_formatContext->streams[m_streamId]->codecpar);
101+@@ -270,8 +268,7 @@ FFmpeg::FFmpeg(fs::path const& _filename, int mediaType) : m_filename(_filename)
102+ static std::mutex s_avcodec_mutex;
103+ // ffmpeg documentation is clear on the fact that avcodec_open2 is not thread safe.
104+ std::lock_guard<std::mutex> l(s_avcodec_mutex);
105+- err = avcodec_open2(pCodecCtx.get(), codec, nullptr);
106+- if (err < 0) throw Error(*this, err);
107++ FFMPEG_CHECKED(avcodec_open2, (pCodecCtx.get(), codec, nullptr), __PRETTY_FUNCTION__);
108+ }
109+ pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
110+ m_codecContext = std::move(pCodecCtx);
111+@@ -290,13 +287,29 @@ AudioFFmpeg::AudioFFmpeg(fs::path const& filename, int rate, AudioCb audioCb) :
112+ // setup resampler
113+ m_resampleContext.reset(swr_alloc());
114+ if (!m_resampleContext) throw std::runtime_error("Cannot create resampling context");
115+- av_opt_set_int(m_resampleContext.get(), "in_channel_layout", m_codecContext->channel_layout ? static_cast<std::int64_t>(m_codecContext->channel_layout) : av_get_default_channel_layout(m_codecContext->channels), 0);
116+- av_opt_set_int(m_resampleContext.get(), "out_channel_layout", av_get_default_channel_layout(AUDIO_CHANNELS), 0);
117+- av_opt_set_int(m_resampleContext.get(), "in_sample_rate", m_codecContext->sample_rate, 0);
118+- av_opt_set_int(m_resampleContext.get(), "out_sample_rate", static_cast<int>(m_rate), 0);
119+- av_opt_set_int(m_resampleContext.get(), "in_sample_fmt", m_codecContext->sample_fmt, 0);
120+- av_opt_set_int(m_resampleContext.get(), "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
121+- swr_init(m_resampleContext.get());
122++
123++#if (LIBAVFORMAT_VERSION_INT) >= (AV_VERSION_INT(59,0,0))
124++ AVChannelLayout inLayout;
125++ AVChannelLayout outLayout;
126++ av_channel_layout_default(&outLayout, AUDIO_CHANNELS);
127++ if (m_codecContext->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
128++ FFMPEG_CHECKED(av_channel_layout_copy, (&inLayout, &m_codecContext->ch_layout), __PRETTY_FUNCTION__);
129++ }
130++ else {
131++ av_channel_layout_default(&inLayout, m_codecContext->ch_layout.nb_channels);
132++ }
133++ av_channel_layout_default(&outLayout, AUDIO_CHANNELS);
134++ FFMPEG_CHECKED(av_opt_set_chlayout, (m_resampleContext.get(), "in_chlayout", &inLayout, 0), __PRETTY_FUNCTION__);
135++ FFMPEG_CHECKED(av_opt_set_chlayout, (m_resampleContext.get(), "out_chlayout", &outLayout, 0), __PRETTY_FUNCTION__);
136++#else
137++ FFMPEG_CHECKED(av_opt_set_int, (m_resampleContext.get(), "in_channel_layout", m_codecContext->channel_layout ? static_cast<std::int64_t>(m_codecContext->channel_layout) : av_get_default_channel_layout(m_codecContext->channels), 0), __PRETTY_FUNCTION__);
138++ FFMPEG_CHECKED(av_opt_set_int, (m_resampleContext.get(), "out_channel_layout", av_get_default_channel_layout(AUDIO_CHANNELS), 0), __PRETTY_FUNCTION__);
139++#endif
140++ FFMPEG_CHECKED(av_opt_set_int, (m_resampleContext.get(), "in_sample_rate", m_codecContext->sample_rate, 0), __PRETTY_FUNCTION__);
141++ FFMPEG_CHECKED(av_opt_set_int, (m_resampleContext.get(), "out_sample_rate", static_cast<int>(m_rate), 0), __PRETTY_FUNCTION__);
142++ FFMPEG_CHECKED(av_opt_set_sample_fmt, (m_resampleContext.get(), "in_sample_fmt", m_codecContext->sample_fmt, 0), __PRETTY_FUNCTION__);
143++ FFMPEG_CHECKED(av_opt_set_sample_fmt, (m_resampleContext.get(), "out_sample_fmt", AV_SAMPLE_FMT_S16, 0), __PRETTY_FUNCTION__);
144++ FFMPEG_CHECKED(swr_init, (m_resampleContext.get()), __PRETTY_FUNCTION__);
145+ }
146+
147+ double FFmpeg::duration() const { return double(m_formatContext->duration) / double(AV_TIME_BASE); }
148+@@ -319,7 +332,7 @@ void FFmpeg::handleOneFrame() {
149+ // End of file: no more data to read.
150+ throw Eof();
151+ } else if(ret < 0) {
152+- throw Error(*this, ret);
153++ throw Error(*this, ret, __PRETTY_FUNCTION__);
154+ }
155+
156+ if (pkt->stream_index != m_streamId) continue;
157+@@ -332,7 +345,7 @@ void FFmpeg::handleOneFrame() {
158+ // no room for new data, need to get more frames out of the decoder by
159+ // calling avcodec_receive_frame()
160+ } else if(ret < 0) {
161+- throw Error(*this, ret);
162++ throw Error(*this, ret, __PRETTY_FUNCTION__);
163+ }
164+ handleSomeFrames();
165+ read_one = true;
166+@@ -364,7 +377,7 @@ void FFmpeg::handleSomeFrames() {
167+ // not enough data to decode a frame, go read more and feed more to the decoder
168+ break;
169+ } else if (ret < 0) {
170+- throw Error(*this, ret);
171++ throw Error(*this, ret, __PRETTY_FUNCTION__);
172+ }
173+ // frame is available here
174+ if (frame->pts != std::int64_t(AV_NOPTS_VALUE)) {
175+diff --git a/game/ffmpeg.hh b/game/ffmpeg.hh
176+index 337091f5b6..e3b54a64a9 100644
177+--- a/game/ffmpeg.hh
178++++ b/game/ffmpeg.hh
179+@@ -19,6 +19,7 @@
180+
181+ // ffmpeg forward declarations
182+ extern "C" {
183++ struct AVChannelLayout;
184+ struct AVCodecContext;
185+ struct AVFormatContext;
186+ struct AVFrame;
187+@@ -35,9 +36,17 @@ class FFmpeg {
188+ public:
189+ // Exceptions thrown by class
190+ class Eof: public std::exception {};
191+- class Error;
192++ class Error : public std::runtime_error {
193++ public:
194++ Error(const FFmpeg &self, int errorValue, const char *func): std::runtime_error(msgFmt(self, errorValue, func)) {}
195++ private:
196++ static std::string msgFmt(const FFmpeg &self, int errorValue, const char *func);
197++ };
198+ friend Error;
199+
200++ void inline check(int errorCode, const char* func = "") {
201++ if (errorCode < 0) throw Error(*this, errorCode, func);
202++ };
203+ /// Decode file, depending on media type audio.
204+ FFmpeg(fs::path const& filename, int mediaType);
205+
206diff --git a/debian/patches/series b/debian/patches/series
207index 06230cb..fd2d275 100644
208--- a/debian/patches/series
209+++ b/debian/patches/series
210@@ -1,2 +1,3 @@
211 ced.patch
212 no-Werror.patch
213+ffmpeg-5.1.patch

Subscribers

People subscribed via source and target branches

to all changes: