Lines 1-2155
Link Here
|
1 |
diff -urN cmake/modules/FindFFMPEG.cmake.orig cmake/modules/FindFFMPEG.cmake |
|
|
2 |
--- cmake/modules/FindFFMPEG.cmake.orig 2023-03-11 22:16:38.000000000 +0000 |
3 |
+++ cmake/modules/FindFFMPEG.cmake 2023-04-19 10:01:30.831589000 +0000 |
4 |
@@ -151,14 +151,14 @@ |
5 |
set(REQUIRED_FFMPEG_VERSION undef) |
6 |
else() |
7 |
# required ffmpeg library versions |
8 |
- set(REQUIRED_FFMPEG_VERSION 4.4.1) |
9 |
- set(_avcodec_ver ">=58.134.100") |
10 |
- set(_avfilter_ver ">=7.110.100") |
11 |
- set(_avformat_ver ">=58.76.100") |
12 |
- set(_avutil_ver ">=56.70.100") |
13 |
- set(_postproc_ver ">=55.9.100") |
14 |
- set(_swresample_ver ">=3.9.100") |
15 |
- set(_swscale_ver ">=5.9.100") |
16 |
+ set(REQUIRED_FFMPEG_VERSION 6.0.0) |
17 |
+ set(_avcodec_ver ">=60.2.100") |
18 |
+ set(_avfilter_ver ">=9.3.100") |
19 |
+ set(_avformat_ver ">=60.3.100") |
20 |
+ set(_avutil_ver ">=58.2.100") |
21 |
+ set(_postproc_ver ">=57.1.100") |
22 |
+ set(_swresample_ver ">=4.10.100") |
23 |
+ set(_swscale_ver ">=7.1.100") |
24 |
endif() |
25 |
|
26 |
# Allows building with external ffmpeg not found in system paths, |
27 |
diff -urN tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch.orig tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch |
28 |
--- tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch.orig 2023-03-11 22:16:38.000000000 +0000 |
29 |
+++ tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch 2023-04-19 10:01:22.854832000 +0000 |
30 |
@@ -11,7 +11,7 @@ |
31 |
index d7a3f507e8..4b85e881b1 100755 |
32 |
--- a/configure |
33 |
+++ b/configure |
34 |
-@@ -6530,6 +6530,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP |
35 |
+@@ -6728,6 +6728,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP |
36 |
check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto || |
37 |
check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || |
38 |
check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || |
39 |
diff -urN tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch.orig tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch |
40 |
--- tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch.orig 2023-03-11 22:16:38.000000000 +0000 |
41 |
+++ tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch 2023-04-19 10:01:22.854952000 +0000 |
42 |
@@ -11,16 +11,16 @@ |
43 |
index 4b85e881b1..da457705d1 100755 |
44 |
--- a/configure |
45 |
+++ b/configure |
46 |
-@@ -7627,6 +7627,9 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST \ |
47 |
+@@ -7825,6 +7825,9 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST \ |
48 |
+ print_config CONFIG_ "$config_files" $CONFIG_LIST \ |
49 |
$CONFIG_EXTRA \ |
50 |
- $ALL_COMPONENTS \ |
51 |
|
52 |
+echo "#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H == 0" >> $TMPH |
53 |
+echo "#undef HAVE_UNISTD_H" >> $TMPH |
54 |
+echo "#endif" >> $TMPH |
55 |
echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH |
56 |
- echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.mak |
57 |
|
58 |
+ # Do not overwrite an unchanged config.h to avoid superfluous rebuilds. |
59 |
-- |
60 |
2.29.2 |
61 |
|
62 |
diff -urN tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch.orig tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch |
63 |
--- tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch.orig 2023-03-11 22:16:38.000000000 +0000 |
64 |
+++ tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch 2023-04-19 10:01:22.855081000 +0000 |
65 |
@@ -11,7 +11,7 @@ |
66 |
index da457705d1..e3a8f45ff4 100755 |
67 |
--- a/configure |
68 |
+++ b/configure |
69 |
-@@ -5440,6 +5440,8 @@ case $target_os in |
70 |
+@@ -5566,6 +5566,8 @@ case $target_os in |
71 |
enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres |
72 |
enabled x86_32 && check_ldflags -Wl,--large-address-aware |
73 |
shlibdir_default="$bindir_default" |
74 |
@@ -20,7 +20,7 @@ |
75 |
SLIBPREF="" |
76 |
SLIBSUF=".dll" |
77 |
SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' |
78 |
-@@ -5489,6 +5491,8 @@ case $target_os in |
79 |
+@@ -5615,6 +5617,8 @@ case $target_os in |
80 |
fi |
81 |
enabled x86_32 && check_ldflags -LARGEADDRESSAWARE |
82 |
shlibdir_default="$bindir_default" |
83 |
diff -urN tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch.orig tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch |
84 |
--- tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch.orig 2023-03-11 22:16:38.000000000 +0000 |
85 |
+++ tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch 2023-04-19 10:01:22.855205000 +0000 |
86 |
@@ -11,7 +11,7 @@ |
87 |
index e3a8f45ff4..983d7e1078 100755 |
88 |
--- a/configure |
89 |
+++ b/configure |
90 |
-@@ -6358,7 +6358,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && |
91 |
+@@ -6541,7 +6541,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && |
92 |
die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } |
93 |
enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas |
94 |
enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2 |
95 |
diff -urN tools/depends/target/ffmpeg/CMakeLists.txt.orig tools/depends/target/ffmpeg/CMakeLists.txt |
96 |
--- tools/depends/target/ffmpeg/CMakeLists.txt.orig 2023-03-11 22:16:38.000000000 +0000 |
97 |
+++ tools/depends/target/ffmpeg/CMakeLists.txt 2023-04-19 10:01:22.854687000 +0000 |
98 |
@@ -92,6 +92,7 @@ |
99 |
elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded) |
100 |
list(APPEND ffmpeg_conf --disable-crystalhd |
101 |
--enable-videotoolbox |
102 |
+ --disable-filter=yadif_videotoolbox |
103 |
--target-os=darwin |
104 |
) |
105 |
elseif(CORE_SYSTEM_NAME STREQUAL osx) |
106 |
diff -urN tools/depends/target/ffmpeg/FFMPEG-VERSION.orig tools/depends/target/ffmpeg/FFMPEG-VERSION |
107 |
--- tools/depends/target/ffmpeg/FFMPEG-VERSION.orig 2023-03-11 22:16:38.000000000 +0000 |
108 |
+++ tools/depends/target/ffmpeg/FFMPEG-VERSION 2023-04-19 10:02:41.108169000 +0000 |
109 |
@@ -1,5 +1,5 @@ |
110 |
LIBNAME=ffmpeg |
111 |
-BASE_URL=https://github.com/xbmc/FFmpeg |
112 |
-VERSION=4.4.1-Nexus-Alpha1 |
113 |
+VERSION=6.0 |
114 |
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz |
115 |
-SHA512=8beb04d577b5251e74b0d52f4d130997a8ba94bbd488c7c8309e6b45095c27807e150212888ce3a384b23dff52f8df1a7bde5407bae924ddc363f8125c0616c5 |
116 |
+SHA512=b3214328f2792364353f38c6b46a71d4970c071d8656b20780abf0e02950167d0933eae825c09102cf8fb19fc679ac444bf1f41a448b624eaa5ea6b0f0bdf4f5 |
117 |
+ |
118 |
diff -urN xbmc/cdrip/EncoderFFmpeg.cpp.orig xbmc/cdrip/EncoderFFmpeg.cpp |
119 |
--- xbmc/cdrip/EncoderFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
120 |
+++ xbmc/cdrip/EncoderFFmpeg.cpp 2023-04-19 10:01:22.848595000 +0000 |
121 |
@@ -11,6 +11,7 @@ |
122 |
#include "ServiceBroker.h" |
123 |
#include "addons/Addon.h" |
124 |
#include "addons/AddonManager.h" |
125 |
+#include "cores/FFmpeg.h" |
126 |
#include "settings/Settings.h" |
127 |
#include "settings/SettingsComponent.h" |
128 |
#include "utils/StringUtils.h" |
129 |
@@ -19,24 +20,9 @@ |
130 |
#include "utils/log.h" |
131 |
|
132 |
using namespace KODI::CDRIP; |
133 |
+using FFMPEG_HELP_TOOLS::FFMpegErrorToString; |
134 |
+using FFMPEG_HELP_TOOLS::FFMpegException; |
135 |
|
136 |
-namespace |
137 |
-{ |
138 |
- |
139 |
-struct EncoderException : public std::exception |
140 |
-{ |
141 |
- std::string s; |
142 |
- template<typename... Args> |
143 |
- EncoderException(const std::string& fmt, Args&&... args) |
144 |
- : s(StringUtils::Format(fmt, std::forward<Args>(args)...)) |
145 |
- { |
146 |
- } |
147 |
- ~EncoderException() throw() {} // Updated |
148 |
- const char* what() const throw() { return s.c_str(); } |
149 |
-}; |
150 |
- |
151 |
-} /* namespace */ |
152 |
- |
153 |
bool CEncoderFFmpeg::Init() |
154 |
{ |
155 |
try |
156 |
@@ -54,7 +40,7 @@ |
157 |
} |
158 |
else |
159 |
{ |
160 |
- throw EncoderException("Could not get add-on: {}", addonId); |
161 |
+ throw FFMpegException("Could not get add-on: {}", addonId); |
162 |
} |
163 |
|
164 |
// Hack fix about PTS on generated files. |
165 |
@@ -66,50 +52,50 @@ |
166 |
else if (addonId == "audioencoder.kodi.builtin.wma") |
167 |
m_samplesCountMultiply = 1000; |
168 |
else |
169 |
- throw EncoderException("Internal add-on id \"{}\" not known as usable", addonId); |
170 |
+ throw FFMpegException("Internal add-on id \"{}\" not known as usable", addonId); |
171 |
|
172 |
const std::string filename = URIUtils::GetFileName(m_strFile); |
173 |
|
174 |
m_formatCtx = avformat_alloc_context(); |
175 |
if (!m_formatCtx) |
176 |
- throw EncoderException("Could not allocate output format context"); |
177 |
+ throw FFMpegException("Could not allocate output format context"); |
178 |
|
179 |
m_bcBuffer = static_cast<uint8_t*>(av_malloc(BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE)); |
180 |
if (!m_bcBuffer) |
181 |
- throw EncoderException("Could not allocate buffer"); |
182 |
+ throw FFMpegException("Could not allocate buffer"); |
183 |
|
184 |
m_formatCtx->pb = avio_alloc_context(m_bcBuffer, BUFFER_SIZE, AVIO_FLAG_WRITE, this, nullptr, |
185 |
avio_write_callback, avio_seek_callback); |
186 |
if (!m_formatCtx->pb) |
187 |
- throw EncoderException("Failed to allocate ByteIOContext"); |
188 |
+ throw FFMpegException("Failed to allocate ByteIOContext"); |
189 |
|
190 |
/* Guess the desired container format based on the file extension. */ |
191 |
m_formatCtx->oformat = av_guess_format(nullptr, filename.c_str(), nullptr); |
192 |
if (!m_formatCtx->oformat) |
193 |
- throw EncoderException("Could not find output file format"); |
194 |
+ throw FFMpegException("Could not find output file format"); |
195 |
|
196 |
m_formatCtx->url = av_strdup(filename.c_str()); |
197 |
if (!m_formatCtx->url) |
198 |
- throw EncoderException("Could not allocate url"); |
199 |
+ throw FFMpegException("Could not allocate url"); |
200 |
|
201 |
/* Find the encoder to be used by its name. */ |
202 |
- AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec); |
203 |
+ const AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec); |
204 |
if (!codec) |
205 |
- throw EncoderException("Unable to find a suitable FFmpeg encoder"); |
206 |
+ throw FFMpegException("Unable to find a suitable FFmpeg encoder"); |
207 |
|
208 |
/* Create a new audio stream in the output file container. */ |
209 |
m_stream = avformat_new_stream(m_formatCtx, nullptr); |
210 |
if (!m_stream) |
211 |
- throw EncoderException("Failed to allocate AVStream context"); |
212 |
+ throw FFMpegException("Failed to allocate AVStream context"); |
213 |
|
214 |
m_codecCtx = avcodec_alloc_context3(codec); |
215 |
if (!m_codecCtx) |
216 |
- throw EncoderException("Failed to allocate the encoder context"); |
217 |
+ throw FFMpegException("Failed to allocate the encoder context"); |
218 |
|
219 |
/* Set the basic encoder parameters. |
220 |
* The input file's sample rate is used to avoid a sample rate conversion. */ |
221 |
- m_codecCtx->channels = m_iInChannels; |
222 |
- m_codecCtx->channel_layout = av_get_default_channel_layout(m_iInChannels); |
223 |
+ av_channel_layout_uninit(&m_codecCtx->ch_layout); |
224 |
+ av_channel_layout_default(&m_codecCtx->ch_layout, m_iInChannels); |
225 |
m_codecCtx->sample_rate = m_iInSampleRate; |
226 |
m_codecCtx->sample_fmt = codec->sample_fmts[0]; |
227 |
m_codecCtx->bit_rate = bitrate; |
228 |
@@ -128,14 +114,14 @@ |
229 |
|
230 |
int err = avcodec_open2(m_codecCtx, codec, nullptr); |
231 |
if (err < 0) |
232 |
- throw EncoderException("Failed to open the codec {} (error '{}')", |
233 |
- codec->long_name ? codec->long_name : codec->name, |
234 |
- FFmpegErrorToString(err)); |
235 |
+ throw FFMpegException("Failed to open the codec {} (error '{}')", |
236 |
+ codec->long_name ? codec->long_name : codec->name, |
237 |
+ FFMpegErrorToString(err)); |
238 |
|
239 |
err = avcodec_parameters_from_context(m_stream->codecpar, m_codecCtx); |
240 |
if (err < 0) |
241 |
- throw EncoderException("Failed to copy encoder parameters to output stream (error '{}')", |
242 |
- FFmpegErrorToString(err)); |
243 |
+ throw FFMpegException("Failed to copy encoder parameters to output stream (error '{}')", |
244 |
+ FFMpegErrorToString(err)); |
245 |
|
246 |
m_inFormat = GetInputFormat(m_iInBitsPerSample); |
247 |
m_outFormat = m_codecCtx->sample_fmt; |
248 |
@@ -150,44 +136,48 @@ |
249 |
|
250 |
m_bufferFrame = av_frame_alloc(); |
251 |
if (!m_bufferFrame || !m_buffer) |
252 |
- throw EncoderException("Failed to allocate necessary buffers"); |
253 |
+ throw FFMpegException("Failed to allocate necessary buffers"); |
254 |
|
255 |
m_bufferFrame->nb_samples = m_codecCtx->frame_size; |
256 |
m_bufferFrame->format = m_inFormat; |
257 |
- m_bufferFrame->channel_layout = m_codecCtx->channel_layout; |
258 |
+ |
259 |
+ av_channel_layout_uninit(&m_bufferFrame->ch_layout); |
260 |
+ av_channel_layout_copy(&m_bufferFrame->ch_layout, &m_codecCtx->ch_layout); |
261 |
+ |
262 |
m_bufferFrame->sample_rate = m_codecCtx->sample_rate; |
263 |
|
264 |
err = av_frame_get_buffer(m_bufferFrame, 0); |
265 |
if (err < 0) |
266 |
- throw EncoderException("Could not allocate output frame samples (error '{}')", |
267 |
- FFmpegErrorToString(err)); |
268 |
+ throw FFMpegException("Could not allocate output frame samples (error '{}')", |
269 |
+ FFMpegErrorToString(err)); |
270 |
|
271 |
avcodec_fill_audio_frame(m_bufferFrame, m_iInChannels, m_inFormat, m_buffer, m_neededBytes, 0); |
272 |
|
273 |
if (m_needConversion) |
274 |
{ |
275 |
- m_swrCtx = swr_alloc_set_opts(nullptr, m_codecCtx->channel_layout, m_outFormat, |
276 |
- m_codecCtx->sample_rate, m_codecCtx->channel_layout, m_inFormat, |
277 |
+ int ret = swr_alloc_set_opts2(&m_swrCtx, &m_codecCtx->ch_layout, m_outFormat, |
278 |
+ m_codecCtx->sample_rate, &m_codecCtx->ch_layout, m_inFormat, |
279 |
m_codecCtx->sample_rate, 0, nullptr); |
280 |
- if (!m_swrCtx || swr_init(m_swrCtx) < 0) |
281 |
- throw EncoderException("Failed to initialize the resampler"); |
282 |
+ if (ret || swr_init(m_swrCtx) < 0) |
283 |
+ throw FFMpegException("Failed to initialize the resampler"); |
284 |
|
285 |
m_resampledBufferSize = |
286 |
av_samples_get_buffer_size(nullptr, m_iInChannels, m_neededFrames, m_outFormat, 0); |
287 |
m_resampledBuffer = static_cast<uint8_t*>(av_malloc(m_resampledBufferSize)); |
288 |
m_resampledFrame = av_frame_alloc(); |
289 |
if (!m_resampledBuffer || !m_resampledFrame) |
290 |
- throw EncoderException("Failed to allocate a frame for resampling"); |
291 |
+ throw FFMpegException("Failed to allocate a frame for resampling"); |
292 |
|
293 |
m_resampledFrame->nb_samples = m_neededFrames; |
294 |
m_resampledFrame->format = m_outFormat; |
295 |
- m_resampledFrame->channel_layout = m_codecCtx->channel_layout; |
296 |
+ av_channel_layout_uninit(&m_resampledFrame->ch_layout); |
297 |
+ av_channel_layout_copy(&m_resampledFrame->ch_layout, &m_codecCtx->ch_layout); |
298 |
m_resampledFrame->sample_rate = m_codecCtx->sample_rate; |
299 |
|
300 |
err = av_frame_get_buffer(m_resampledFrame, 0); |
301 |
if (err < 0) |
302 |
- throw EncoderException("Could not allocate output resample frame samples (error '{}')", |
303 |
- FFmpegErrorToString(err)); |
304 |
+ throw FFMpegException("Could not allocate output resample frame samples (error '{}')", |
305 |
+ FFMpegErrorToString(err)); |
306 |
|
307 |
avcodec_fill_audio_frame(m_resampledFrame, m_iInChannels, m_outFormat, m_resampledBuffer, |
308 |
m_resampledBufferSize, 0); |
309 |
@@ -204,7 +194,7 @@ |
310 |
/* write the header */ |
311 |
err = avformat_write_header(m_formatCtx, nullptr); |
312 |
if (err != 0) |
313 |
- throw EncoderException("Failed to write the header (error '{}')", FFmpegErrorToString(err)); |
314 |
+ throw FFMpegException("Failed to write the header (error '{}')", FFMpegErrorToString(err)); |
315 |
|
316 |
CLog::Log(LOGDEBUG, "CEncoderFFmpeg::{} - Successfully initialized with muxer {} and codec {}", |
317 |
__func__, |
318 |
@@ -212,16 +202,19 @@ |
319 |
: m_formatCtx->oformat->name, |
320 |
codec->long_name ? codec->long_name : codec->name); |
321 |
} |
322 |
- catch (EncoderException& caught) |
323 |
+ catch (const FFMpegException& caught) |
324 |
{ |
325 |
CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what()); |
326 |
|
327 |
av_freep(&m_buffer); |
328 |
+ av_channel_layout_uninit(&m_bufferFrame->ch_layout); |
329 |
av_frame_free(&m_bufferFrame); |
330 |
swr_free(&m_swrCtx); |
331 |
+ av_channel_layout_uninit(&m_resampledFrame->ch_layout); |
332 |
av_frame_free(&m_resampledFrame); |
333 |
av_freep(&m_resampledBuffer); |
334 |
av_free(m_bcBuffer); |
335 |
+ av_channel_layout_uninit(&m_codecCtx->ch_layout); |
336 |
avcodec_free_context(&m_codecCtx); |
337 |
if (m_formatCtx) |
338 |
{ |
339 |
@@ -299,7 +292,7 @@ |
340 |
if (swr_convert(m_swrCtx, m_resampledFrame->data, m_neededFrames, |
341 |
const_cast<const uint8_t**>(m_bufferFrame->extended_data), |
342 |
m_neededFrames) < 0) |
343 |
- throw EncoderException("Error resampling audio"); |
344 |
+ throw FFMpegException("Error resampling audio"); |
345 |
|
346 |
frame = m_resampledFrame; |
347 |
} |
348 |
@@ -316,8 +309,8 @@ |
349 |
m_bufferSize = 0; |
350 |
err = avcodec_send_frame(m_codecCtx, frame); |
351 |
if (err < 0) |
352 |
- throw EncoderException("Error sending a frame for encoding (error '{}')", __func__, |
353 |
- FFmpegErrorToString(err)); |
354 |
+ throw FFMpegException("Error sending a frame for encoding (error '{}')", |
355 |
+ FFMpegErrorToString(err)); |
356 |
|
357 |
while (err >= 0) |
358 |
{ |
359 |
@@ -329,19 +322,18 @@ |
360 |
} |
361 |
else if (err < 0) |
362 |
{ |
363 |
- throw EncoderException("Error during encoding (error '{}')", __func__, |
364 |
- FFmpegErrorToString(err)); |
365 |
+ throw FFMpegException("Error during encoding (error '{}')", FFMpegErrorToString(err)); |
366 |
} |
367 |
|
368 |
err = av_write_frame(m_formatCtx, pkt); |
369 |
if (err < 0) |
370 |
- throw EncoderException("Failed to write the frame data (error '{}')", __func__, |
371 |
- FFmpegErrorToString(err)); |
372 |
+ throw FFMpegException("Failed to write the frame data (error '{}')", |
373 |
+ FFMpegErrorToString(err)); |
374 |
|
375 |
av_packet_unref(pkt); |
376 |
} |
377 |
} |
378 |
- catch (EncoderException& caught) |
379 |
+ catch (const FFMpegException& caught) |
380 |
{ |
381 |
CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what()); |
382 |
} |
383 |
@@ -366,8 +358,10 @@ |
384 |
|
385 |
/* Flush if needed */ |
386 |
av_freep(&m_buffer); |
387 |
+ av_channel_layout_uninit(&m_bufferFrame->ch_layout); |
388 |
av_frame_free(&m_bufferFrame); |
389 |
swr_free(&m_swrCtx); |
390 |
+ av_channel_layout_uninit(&m_resampledFrame->ch_layout); |
391 |
av_frame_free(&m_resampledFrame); |
392 |
av_freep(&m_resampledBuffer); |
393 |
m_needConversion = false; |
394 |
@@ -379,6 +373,7 @@ |
395 |
|
396 |
/* cleanup */ |
397 |
av_free(m_bcBuffer); |
398 |
+ av_channel_layout_uninit(&m_codecCtx->ch_layout); |
399 |
avcodec_free_context(&m_codecCtx); |
400 |
av_freep(&m_formatCtx->pb); |
401 |
avformat_free_context(m_formatCtx); |
402 |
@@ -400,14 +395,6 @@ |
403 |
case 32: |
404 |
return AV_SAMPLE_FMT_S32; |
405 |
default: |
406 |
- throw EncoderException("Invalid input bits per sample"); |
407 |
+ throw FFMpegException("Invalid input bits per sample"); |
408 |
} |
409 |
-} |
410 |
- |
411 |
-std::string CEncoderFFmpeg::FFmpegErrorToString(int err) |
412 |
-{ |
413 |
- std::string text; |
414 |
- text.reserve(AV_ERROR_MAX_STRING_SIZE); |
415 |
- av_strerror(err, text.data(), AV_ERROR_MAX_STRING_SIZE); |
416 |
- return text; |
417 |
} |
418 |
diff -urN xbmc/cdrip/EncoderFFmpeg.h.orig xbmc/cdrip/EncoderFFmpeg.h |
419 |
--- xbmc/cdrip/EncoderFFmpeg.h.orig 2023-03-11 22:16:38.000000000 +0000 |
420 |
+++ xbmc/cdrip/EncoderFFmpeg.h 2023-04-19 10:01:22.835616000 +0000 |
421 |
@@ -39,7 +39,6 @@ |
422 |
void SetTag(const std::string& tag, const std::string& value); |
423 |
bool WriteFrame(); |
424 |
AVSampleFormat GetInputFormat(int inBitsPerSample); |
425 |
- std::string FFmpegErrorToString(int err); |
426 |
|
427 |
AVFormatContext* m_formatCtx{nullptr}; |
428 |
AVCodecContext* m_codecCtx{nullptr}; |
429 |
diff -urN xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp.orig xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp |
430 |
--- xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
431 |
+++ xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp 2023-04-19 10:01:22.848879000 +0000 |
432 |
@@ -10,14 +10,25 @@ |
433 |
#define DTS_ENCODE_BITRATE 1411200 |
434 |
|
435 |
#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" |
436 |
-#include "cores/AudioEngine/Utils/AEUtil.h" |
437 |
+ |
438 |
#include "ServiceBroker.h" |
439 |
-#include "utils/log.h" |
440 |
+#include "cores/AudioEngine/Utils/AEUtil.h" |
441 |
+#include "cores/FFmpeg.h" |
442 |
#include "settings/Settings.h" |
443 |
#include "settings/SettingsComponent.h" |
444 |
-#include <string.h> |
445 |
+#include "utils/log.h" |
446 |
+ |
447 |
+extern "C" |
448 |
+{ |
449 |
+#include <libavutil/channel_layout.h> |
450 |
+} |
451 |
+ |
452 |
#include <cassert> |
453 |
+#include <string.h> |
454 |
|
455 |
+using FFMPEG_HELP_TOOLS::FFMpegErrorToString; |
456 |
+using FFMPEG_HELP_TOOLS::FFMpegException; |
457 |
+ |
458 |
CAEEncoderFFmpeg::CAEEncoderFFmpeg() : m_CodecCtx(NULL), m_SwrCtx(NULL) |
459 |
{ |
460 |
} |
461 |
@@ -26,6 +37,7 @@ |
462 |
{ |
463 |
Reset(); |
464 |
swr_free(&m_SwrCtx); |
465 |
+ av_channel_layout_uninit(&m_CodecCtx->ch_layout); |
466 |
avcodec_free_context(&m_CodecCtx); |
467 |
} |
468 |
|
469 |
@@ -81,7 +93,7 @@ |
470 |
|
471 |
bool ac3 = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH); |
472 |
|
473 |
- AVCodec *codec = NULL; |
474 |
+ const AVCodec* codec = nullptr; |
475 |
|
476 |
/* fallback to ac3 if we support it, we might not have DTS support */ |
477 |
if (ac3) |
478 |
@@ -102,7 +114,8 @@ |
479 |
|
480 |
m_CodecCtx->bit_rate = m_BitRate; |
481 |
m_CodecCtx->sample_rate = format.m_sampleRate; |
482 |
- m_CodecCtx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK; |
483 |
+ av_channel_layout_uninit(&m_CodecCtx->ch_layout); |
484 |
+ av_channel_layout_from_mask(&m_CodecCtx->ch_layout, AV_CH_LAYOUT_5POINT1_BACK); |
485 |
|
486 |
/* select a suitable data format */ |
487 |
if (codec->sample_fmts) |
488 |
@@ -179,22 +192,28 @@ |
489 |
LOGERROR, |
490 |
"CAEEncoderFFmpeg::Initialize - Unable to find a suitable data format for the codec ({})", |
491 |
m_CodecName); |
492 |
+ av_channel_layout_uninit(&m_CodecCtx->ch_layout); |
493 |
avcodec_free_context(&m_CodecCtx); |
494 |
return false; |
495 |
} |
496 |
} |
497 |
|
498 |
- m_CodecCtx->channels = BuildChannelLayout(m_CodecCtx->channel_layout, m_Layout); |
499 |
+ uint64_t mask = m_CodecCtx->ch_layout.u.mask; |
500 |
+ av_channel_layout_uninit(&m_CodecCtx->ch_layout); |
501 |
+ av_channel_layout_from_mask(&m_CodecCtx->ch_layout, mask); |
502 |
+ m_CodecCtx->ch_layout.nb_channels = BuildChannelLayout(mask, m_Layout); |
503 |
|
504 |
/* open the codec */ |
505 |
if (avcodec_open2(m_CodecCtx, codec, NULL)) |
506 |
{ |
507 |
+ av_channel_layout_uninit(&m_CodecCtx->ch_layout); |
508 |
avcodec_free_context(&m_CodecCtx); |
509 |
return false; |
510 |
} |
511 |
|
512 |
format.m_frames = m_CodecCtx->frame_size; |
513 |
- format.m_frameSize = m_CodecCtx->channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3); |
514 |
+ int channels = m_CodecCtx->ch_layout.nb_channels; |
515 |
+ format.m_frameSize = channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3); |
516 |
format.m_channelLayout = m_Layout; |
517 |
|
518 |
m_CurrentFormat = format; |
519 |
@@ -204,14 +223,14 @@ |
520 |
|
521 |
if (m_NeedConversion) |
522 |
{ |
523 |
- m_SwrCtx = swr_alloc_set_opts(NULL, |
524 |
- m_CodecCtx->channel_layout, m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate, |
525 |
- m_CodecCtx->channel_layout, AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, |
526 |
- 0, NULL); |
527 |
- if (!m_SwrCtx || swr_init(m_SwrCtx) < 0) |
528 |
+ int ret = swr_alloc_set_opts2(&m_SwrCtx, &m_CodecCtx->ch_layout, m_CodecCtx->sample_fmt, |
529 |
+ m_CodecCtx->sample_rate, &m_CodecCtx->ch_layout, |
530 |
+ AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, 0, NULL); |
531 |
+ if (ret || swr_init(m_SwrCtx) < 0) |
532 |
{ |
533 |
CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Initialize - Failed to initialise resampler."); |
534 |
swr_free(&m_SwrCtx); |
535 |
+ av_channel_layout_uninit(&m_CodecCtx->ch_layout); |
536 |
avcodec_free_context(&m_CodecCtx); |
537 |
return false; |
538 |
} |
539 |
@@ -242,62 +261,83 @@ |
540 |
|
541 |
int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_size) |
542 |
{ |
543 |
- int got_output; |
544 |
- AVFrame *frame; |
545 |
+ int size = 0; |
546 |
+ int err = AVERROR_UNKNOWN; |
547 |
+ AVFrame* frame = nullptr; |
548 |
+ AVPacket* pkt = nullptr; |
549 |
|
550 |
if (!m_CodecCtx) |
551 |
- return 0; |
552 |
+ return size; |
553 |
|
554 |
- /* allocate the input frame |
555 |
- * sadly, we have to alloc/dealloc it everytime since we have no guarantee the |
556 |
- * data argument will be constant over iterated calls and the frame needs to |
557 |
- * setup pointers inside data */ |
558 |
- frame = av_frame_alloc(); |
559 |
- if (!frame) |
560 |
- return 0; |
561 |
+ try |
562 |
+ { |
563 |
+ /* allocate the input frame and output packet |
564 |
+ * sadly, we have to alloc/dealloc it everytime since we have no guarantee the |
565 |
+ * data argument will be constant over iterated calls and the frame needs to |
566 |
+ * setup pointers inside data */ |
567 |
+ frame = av_frame_alloc(); |
568 |
+ pkt = av_packet_alloc(); |
569 |
+ if (!frame || !pkt) |
570 |
+ throw FFMpegException( |
571 |
+ "Failed to allocate \"AVFrame\" or \"AVPacket\" for encoding (error '{}')", |
572 |
+ strerror(errno)); |
573 |
|
574 |
- frame->nb_samples = m_CodecCtx->frame_size; |
575 |
- frame->format = m_CodecCtx->sample_fmt; |
576 |
- frame->channel_layout = m_CodecCtx->channel_layout; |
577 |
- frame->channels = m_CodecCtx->channels; |
578 |
+ frame->nb_samples = m_CodecCtx->frame_size; |
579 |
+ frame->format = m_CodecCtx->sample_fmt; |
580 |
+ av_channel_layout_uninit(&frame->ch_layout); |
581 |
+ av_channel_layout_copy(&frame->ch_layout, &m_CodecCtx->ch_layout); |
582 |
+ int channelNum = m_CodecCtx->ch_layout.nb_channels; |
583 |
|
584 |
- avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, |
585 |
- in, in_size, 0); |
586 |
+ avcodec_fill_audio_frame(frame, channelNum, m_CodecCtx->sample_fmt, in, in_size, 0); |
587 |
|
588 |
- /* initialize the output packet */ |
589 |
- AVPacket* pkt = av_packet_alloc(); |
590 |
- if (!pkt) |
591 |
+ /* encode it */ |
592 |
+ err = avcodec_send_frame(m_CodecCtx, frame); |
593 |
+ if (err < 0) |
594 |
+ throw FFMpegException("Error sending a frame for encoding (error '{}')", |
595 |
+ FFMpegErrorToString(err)); |
596 |
+ |
597 |
+ err = avcodec_receive_packet(m_CodecCtx, pkt); |
598 |
+ //! @TODO: This is a workaround for our current design. The caller should be made |
599 |
+ // aware of the potential error values to use the ffmpeg API in a proper way, which means |
600 |
+ // copying with EAGAIN and multiple packet output. |
601 |
+ // For the current situation there is a relationship implicitely assumed of: |
602 |
+ // 1 frame in - 1 packet out. This holds true in practice but the API does not guarantee it. |
603 |
+ if (err >= 0) |
604 |
+ { |
605 |
+ if (pkt->size <= out_size) |
606 |
+ { |
607 |
+ memset(out, 0, out_size); |
608 |
+ memcpy(out, pkt->data, pkt->size); |
609 |
+ size = pkt->size; |
610 |
+ } |
611 |
+ else |
612 |
+ { |
613 |
+ CLog::LogF(LOGERROR, "Encoded pkt size ({}) is bigger than buffer ({})", pkt->size, |
614 |
+ out_size); |
615 |
+ } |
616 |
+ av_packet_unref(pkt); |
617 |
+ } |
618 |
+ else |
619 |
+ { |
620 |
+ CLog::LogF(LOGERROR, "Error receiving encoded paket ({})", err); |
621 |
+ } |
622 |
+ } |
623 |
+ catch (const FFMpegException& caught) |
624 |
{ |
625 |
- CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - av_packet_alloc failed: {}", __FUNCTION__, |
626 |
- strerror(errno)); |
627 |
- av_frame_free(&frame); |
628 |
- return 0; |
629 |
+ CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - {}", __func__, caught.what()); |
630 |
} |
631 |
|
632 |
- pkt->size = out_size; |
633 |
- pkt->data = out; |
634 |
+ av_channel_layout_uninit(&frame->ch_layout); |
635 |
|
636 |
- /* encode it */ |
637 |
- int ret = avcodec_encode_audio2(m_CodecCtx, pkt, frame, &got_output); |
638 |
- |
639 |
- int size = pkt->size; |
640 |
- |
641 |
/* free temporary data */ |
642 |
av_frame_free(&frame); |
643 |
|
644 |
/* free the packet */ |
645 |
av_packet_free(&pkt); |
646 |
|
647 |
- if (ret < 0 || !got_output) |
648 |
- { |
649 |
- CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Encoding failed"); |
650 |
- return 0; |
651 |
- } |
652 |
- |
653 |
/* return the number of frames used */ |
654 |
return size; |
655 |
} |
656 |
- |
657 |
|
658 |
int CAEEncoderFFmpeg::GetData(uint8_t **data) |
659 |
{ |
660 |
diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp |
661 |
--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
662 |
+++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp 2023-04-19 10:01:22.849708000 +0000 |
663 |
@@ -16,17 +16,16 @@ |
664 |
#include "ActiveAESound.h" |
665 |
#include "ActiveAEStream.h" |
666 |
#include "ServiceBroker.h" |
667 |
+#include "cores/AudioEngine/AEResampleFactory.h" |
668 |
+#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" |
669 |
#include "cores/AudioEngine/Interfaces/IAudioCallback.h" |
670 |
-#include "cores/AudioEngine/Utils/AEUtil.h" |
671 |
#include "cores/AudioEngine/Utils/AEStreamData.h" |
672 |
#include "cores/AudioEngine/Utils/AEStreamInfo.h" |
673 |
-#include "cores/AudioEngine/AEResampleFactory.h" |
674 |
-#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" |
675 |
- |
676 |
+#include "cores/AudioEngine/Utils/AEUtil.h" |
677 |
#include "settings/Settings.h" |
678 |
#include "settings/SettingsComponent.h" |
679 |
-#include "windowing/WinSystem.h" |
680 |
#include "utils/log.h" |
681 |
+#include "windowing/WinSystem.h" |
682 |
|
683 |
using namespace std::chrono_literals; |
684 |
|
685 |
@@ -3043,8 +3042,8 @@ |
686 |
AVFormatContext *fmt_ctx = nullptr; |
687 |
AVCodecContext *dec_ctx = nullptr; |
688 |
AVIOContext *io_ctx; |
689 |
- AVInputFormat *io_fmt = nullptr; |
690 |
- AVCodec *dec = nullptr; |
691 |
+ const AVInputFormat* io_fmt = nullptr; |
692 |
+ const AVCodec* dec = nullptr; |
693 |
SampleConfig config; |
694 |
|
695 |
// No custom deleter until sound is registered |
696 |
@@ -3096,8 +3095,8 @@ |
697 |
AVCodecID codecId = fmt_ctx->streams[0]->codecpar->codec_id; |
698 |
dec = avcodec_find_decoder(codecId); |
699 |
config.sample_rate = fmt_ctx->streams[0]->codecpar->sample_rate; |
700 |
- config.channels = fmt_ctx->streams[0]->codecpar->channels; |
701 |
- config.channel_layout = fmt_ctx->streams[0]->codecpar->channel_layout; |
702 |
+ config.channels = fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; |
703 |
+ config.channel_layout = fmt_ctx->streams[0]->codecpar->ch_layout.u.mask; |
704 |
} |
705 |
} |
706 |
if (dec == nullptr) |
707 |
@@ -3113,10 +3112,14 @@ |
708 |
|
709 |
dec_ctx = avcodec_alloc_context3(dec); |
710 |
dec_ctx->sample_rate = config.sample_rate; |
711 |
- dec_ctx->channels = config.channels; |
712 |
+ AVChannelLayout layout = {}; |
713 |
if (!config.channel_layout) |
714 |
- config.channel_layout = av_get_default_channel_layout(config.channels); |
715 |
- dec_ctx->channel_layout = config.channel_layout; |
716 |
+ av_channel_layout_default(&layout, config.channels); |
717 |
+ else |
718 |
+ av_channel_layout_from_mask(&layout, config.channel_layout); |
719 |
+ config.channel_layout = layout.u.mask; |
720 |
+ av_channel_layout_copy(&dec_ctx->ch_layout, &layout); |
721 |
+ av_channel_layout_uninit(&layout); |
722 |
|
723 |
AVPacket* avpkt = av_packet_alloc(); |
724 |
if (!avpkt) |
725 |
@@ -3183,6 +3186,7 @@ |
726 |
|
727 |
av_packet_free(&avpkt); |
728 |
av_frame_free(&decoded_frame); |
729 |
+ av_channel_layout_uninit(&dec_ctx->ch_layout); |
730 |
avcodec_free_context(&dec_ctx); |
731 |
avformat_close_input(&fmt_ctx); |
732 |
if (io_ctx) |
733 |
diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp |
734 |
--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
735 |
+++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp 2023-04-19 10:01:22.849964000 +0000 |
736 |
@@ -12,8 +12,8 @@ |
737 |
#include <algorithm> |
738 |
|
739 |
extern "C" { |
740 |
-#include <libavfilter/avfilter.h> |
741 |
#include <libavcodec/avcodec.h> |
742 |
+#include <libavfilter/avfilter.h> |
743 |
#include <libavfilter/buffersink.h> |
744 |
#include <libavfilter/buffersrc.h> |
745 |
#include <libswresample/swresample.h> |
746 |
@@ -171,7 +171,10 @@ |
747 |
} |
748 |
|
749 |
if (m_pOutFrame) |
750 |
+ { |
751 |
+ av_channel_layout_uninit(&m_pOutFrame->ch_layout); |
752 |
av_frame_free(&m_pOutFrame); |
753 |
+ } |
754 |
|
755 |
if (m_pConvertFrame) |
756 |
av_frame_free(&m_pConvertFrame); |
757 |
@@ -205,10 +208,9 @@ |
758 |
if (!frame) |
759 |
return -1; |
760 |
|
761 |
- int channels = av_get_channel_layout_nb_channels(m_channelLayout); |
762 |
- |
763 |
- frame->channel_layout = m_channelLayout; |
764 |
- frame->channels = channels; |
765 |
+ av_channel_layout_uninit(&frame->ch_layout); |
766 |
+ av_channel_layout_from_mask(&frame->ch_layout, m_channelLayout); |
767 |
+ int channels = frame->ch_layout.nb_channels; |
768 |
frame->sample_rate = m_sampleRate; |
769 |
frame->nb_samples = src_samples; |
770 |
frame->format = m_sampleFormat; |
771 |
@@ -224,6 +226,7 @@ |
772 |
src_buffer[0], src_bufsize, 16); |
773 |
if (result < 0) |
774 |
{ |
775 |
+ av_channel_layout_uninit(&frame->ch_layout); |
776 |
av_frame_free(&frame); |
777 |
CLog::Log(LOGERROR, "CActiveAEFilter::ProcessFilter - avcodec_fill_audio_frame failed"); |
778 |
m_filterEof = true; |
779 |
@@ -231,6 +234,7 @@ |
780 |
} |
781 |
|
782 |
result = av_buffersrc_write_frame(m_pFilterCtxIn, frame); |
783 |
+ av_channel_layout_uninit(&frame->ch_layout); |
784 |
av_frame_free(&frame); |
785 |
if (result < 0) |
786 |
{ |
787 |
@@ -284,7 +288,8 @@ |
788 |
{ |
789 |
av_frame_unref(m_pOutFrame); |
790 |
m_pOutFrame->format = m_sampleFormat; |
791 |
- m_pOutFrame->channel_layout = m_channelLayout; |
792 |
+ av_channel_layout_uninit(&m_pOutFrame->ch_layout); |
793 |
+ av_channel_layout_from_mask(&m_pOutFrame->ch_layout, m_channelLayout); |
794 |
m_pOutFrame->sample_rate = m_sampleRate; |
795 |
result = swr_convert_frame(m_pConvertCtx, m_pOutFrame, m_pConvertFrame); |
796 |
av_frame_unref(m_pConvertFrame); |
797 |
@@ -302,7 +307,10 @@ |
798 |
|
799 |
if (m_hasData) |
800 |
{ |
801 |
- int channels = av_get_channel_layout_nb_channels(m_channelLayout); |
802 |
+ AVChannelLayout layout = {}; |
803 |
+ av_channel_layout_from_mask(&layout, m_channelLayout); |
804 |
+ int channels = layout.nb_channels; |
805 |
+ av_channel_layout_uninit(&layout); |
806 |
int planes = av_sample_fmt_is_planar(m_sampleFormat) ? channels : 1; |
807 |
int samples = std::min(dst_samples, m_pOutFrame->nb_samples - m_sampleOffset); |
808 |
int bytes = samples * av_get_bytes_per_sample(m_sampleFormat) * channels / planes; |
809 |
diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp |
810 |
--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
811 |
+++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp 2023-04-19 10:01:22.850224000 +0000 |
812 |
@@ -49,15 +49,30 @@ |
813 |
m_doesResample = true; |
814 |
|
815 |
if (m_dst_chan_layout == 0) |
816 |
- m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); |
817 |
+ { |
818 |
+ AVChannelLayout layout = {}; |
819 |
+ av_channel_layout_default(&layout, m_dst_channels); |
820 |
+ m_dst_chan_layout = layout.u.mask; |
821 |
+ av_channel_layout_uninit(&layout); |
822 |
+ } |
823 |
if (m_src_chan_layout == 0) |
824 |
- m_src_chan_layout = av_get_default_channel_layout(m_src_channels); |
825 |
+ { |
826 |
+ AVChannelLayout layout = {}; |
827 |
+ av_channel_layout_default(&layout, m_src_channels); |
828 |
+ m_src_chan_layout = layout.u.mask; |
829 |
+ av_channel_layout_uninit(&layout); |
830 |
+ } |
831 |
|
832 |
- m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, m_dst_fmt, m_dst_rate, |
833 |
- m_src_chan_layout, m_src_fmt, m_src_rate, |
834 |
- 0, NULL); |
835 |
+ AVChannelLayout dstChLayout = {}; |
836 |
+ AVChannelLayout srcChLayout = {}; |
837 |
|
838 |
- if (!m_pContext) |
839 |
+ av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout); |
840 |
+ av_channel_layout_from_mask(&srcChLayout, m_src_chan_layout); |
841 |
+ |
842 |
+ int ret = swr_alloc_set_opts2(&m_pContext, &dstChLayout, m_dst_fmt, m_dst_rate, &srcChLayout, |
843 |
+ m_src_fmt, m_src_rate, 0, NULL); |
844 |
+ |
845 |
+ if (ret) |
846 |
{ |
847 |
CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed"); |
848 |
return false; |
849 |
@@ -126,10 +141,12 @@ |
850 |
else if (upmix && m_src_channels == 2 && m_dst_channels > 2) |
851 |
{ |
852 |
memset(m_rematrix, 0, sizeof(m_rematrix)); |
853 |
+ av_channel_layout_uninit(&dstChLayout); |
854 |
+ av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout); |
855 |
for (int out=0; out<m_dst_channels; out++) |
856 |
{ |
857 |
- uint64_t out_chan = av_channel_layout_extract_channel(m_dst_chan_layout, out); |
858 |
- switch(out_chan) |
859 |
+ AVChannel outChan = av_channel_layout_channel_from_index(&dstChLayout, out); |
860 |
+ switch (outChan) |
861 |
{ |
862 |
case AV_CH_FRONT_LEFT: |
863 |
case AV_CH_BACK_LEFT: |
864 |
@@ -153,6 +170,8 @@ |
865 |
break; |
866 |
} |
867 |
} |
868 |
+ |
869 |
+ av_channel_layout_uninit(&dstChLayout); |
870 |
|
871 |
if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) |
872 |
{ |
873 |
diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp |
874 |
--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
875 |
+++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp 2023-04-19 10:01:22.844169000 +0000 |
876 |
@@ -88,7 +88,7 @@ |
877 |
for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++) |
878 |
{ |
879 |
avLast = avCur; |
880 |
- avCur = CAEUtil::GetAVChannel(m_format.m_channelLayout[i]); |
881 |
+ avCur = CAEUtil::GetAVChannelMask(m_format.m_channelLayout[i]); |
882 |
if(avCur < avLast) |
883 |
{ |
884 |
needRemap = true; |
885 |
diff -urN xbmc/cores/AudioEngine/Utils/AEUtil.cpp.orig xbmc/cores/AudioEngine/Utils/AEUtil.cpp |
886 |
--- xbmc/cores/AudioEngine/Utils/AEUtil.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
887 |
+++ xbmc/cores/AudioEngine/Utils/AEUtil.cpp 2023-04-19 10:01:22.850463000 +0000 |
888 |
@@ -19,10 +19,6 @@ |
889 |
#include <xmmintrin.h> |
890 |
#endif |
891 |
|
892 |
-extern "C" { |
893 |
-#include <libavutil/channel_layout.h> |
894 |
-} |
895 |
- |
896 |
void AEDelayStatus::SetDelay(double d) |
897 |
{ |
898 |
delay = d; |
899 |
@@ -550,34 +546,64 @@ |
900 |
} |
901 |
} |
902 |
|
903 |
-uint64_t CAEUtil::GetAVChannel(enum AEChannel aechannel) |
904 |
+uint64_t CAEUtil::GetAVChannelMask(enum AEChannel aechannel) |
905 |
{ |
906 |
+ enum AVChannel ch = GetAVChannel(aechannel); |
907 |
+ if (ch == AV_CHAN_NONE) |
908 |
+ return 0; |
909 |
+ return (1ULL << ch); |
910 |
+} |
911 |
+ |
912 |
+enum AVChannel CAEUtil::GetAVChannel(enum AEChannel aechannel) |
913 |
+{ |
914 |
switch (aechannel) |
915 |
{ |
916 |
- case AE_CH_FL: return AV_CH_FRONT_LEFT; |
917 |
- case AE_CH_FR: return AV_CH_FRONT_RIGHT; |
918 |
- case AE_CH_FC: return AV_CH_FRONT_CENTER; |
919 |
- case AE_CH_LFE: return AV_CH_LOW_FREQUENCY; |
920 |
- case AE_CH_BL: return AV_CH_BACK_LEFT; |
921 |
- case AE_CH_BR: return AV_CH_BACK_RIGHT; |
922 |
- case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER; |
923 |
- case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER; |
924 |
- case AE_CH_BC: return AV_CH_BACK_CENTER; |
925 |
- case AE_CH_SL: return AV_CH_SIDE_LEFT; |
926 |
- case AE_CH_SR: return AV_CH_SIDE_RIGHT; |
927 |
- case AE_CH_TC: return AV_CH_TOP_CENTER; |
928 |
- case AE_CH_TFL: return AV_CH_TOP_FRONT_LEFT; |
929 |
- case AE_CH_TFC: return AV_CH_TOP_FRONT_CENTER; |
930 |
- case AE_CH_TFR: return AV_CH_TOP_FRONT_RIGHT; |
931 |
- case AE_CH_TBL: return AV_CH_TOP_BACK_LEFT; |
932 |
- case AE_CH_TBC: return AV_CH_TOP_BACK_CENTER; |
933 |
- case AE_CH_TBR: return AV_CH_TOP_BACK_RIGHT; |
934 |
- default: |
935 |
- return 0; |
936 |
+ case AE_CH_FL: |
937 |
+ return AV_CHAN_FRONT_LEFT; |
938 |
+ case AE_CH_FR: |
939 |
+ return AV_CHAN_FRONT_RIGHT; |
940 |
+ case AE_CH_FC: |
941 |
+ return AV_CHAN_FRONT_CENTER; |
942 |
+ case AE_CH_LFE: |
943 |
+ return AV_CHAN_LOW_FREQUENCY; |
944 |
+ case AE_CH_BL: |
945 |
+ return AV_CHAN_BACK_LEFT; |
946 |
+ case AE_CH_BR: |
947 |
+ return AV_CHAN_BACK_RIGHT; |
948 |
+ case AE_CH_FLOC: |
949 |
+ return AV_CHAN_FRONT_LEFT_OF_CENTER; |
950 |
+ case AE_CH_FROC: |
951 |
+ return AV_CHAN_FRONT_RIGHT_OF_CENTER; |
952 |
+ case AE_CH_BC: |
953 |
+ return AV_CHAN_BACK_CENTER; |
954 |
+ case AE_CH_SL: |
955 |
+ return AV_CHAN_SIDE_LEFT; |
956 |
+ case AE_CH_SR: |
957 |
+ return AV_CHAN_SIDE_RIGHT; |
958 |
+ case AE_CH_TC: |
959 |
+ return AV_CHAN_TOP_CENTER; |
960 |
+ case AE_CH_TFL: |
961 |
+ return AV_CHAN_TOP_FRONT_LEFT; |
962 |
+ case AE_CH_TFC: |
963 |
+ return AV_CHAN_TOP_FRONT_CENTER; |
964 |
+ case AE_CH_TFR: |
965 |
+ return AV_CHAN_TOP_FRONT_RIGHT; |
966 |
+ case AE_CH_TBL: |
967 |
+ return AV_CHAN_TOP_BACK_LEFT; |
968 |
+ case AE_CH_TBC: |
969 |
+ return AV_CHAN_TOP_BACK_CENTER; |
970 |
+ case AE_CH_TBR: |
971 |
+ return AV_CHAN_TOP_BACK_RIGHT; |
972 |
+ default: |
973 |
+ return AV_CHAN_NONE; |
974 |
} |
975 |
} |
976 |
|
977 |
int CAEUtil::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) |
978 |
{ |
979 |
- return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); |
980 |
+ AVChannelLayout ch_layout = {}; |
981 |
+ av_channel_layout_from_mask(&ch_layout, layout); |
982 |
+ int idx = av_channel_layout_index_from_channel(&ch_layout, GetAVChannel(aechannel)); |
983 |
+ av_channel_layout_uninit(&ch_layout); |
984 |
+ return idx; |
985 |
} |
986 |
diff -urN xbmc/cores/AudioEngine/Utils/AEUtil.h.orig xbmc/cores/AudioEngine/Utils/AEUtil.h |
987 |
--- xbmc/cores/AudioEngine/Utils/AEUtil.h.orig 2023-03-11 22:16:38.000000000 +0000 |
988 |
+++ xbmc/cores/AudioEngine/Utils/AEUtil.h 2023-04-19 10:01:22.850626000 +0000 |
989 |
@@ -13,6 +13,7 @@ |
990 |
#include <math.h> |
991 |
|
992 |
extern "C" { |
993 |
+#include <libavutil/channel_layout.h> |
994 |
#include <libavutil/samplefmt.h> |
995 |
} |
996 |
|
997 |
@@ -171,6 +172,7 @@ |
998 |
static uint64_t GetAVChannelLayout(const CAEChannelInfo &info); |
999 |
static CAEChannelInfo GetAEChannelLayout(uint64_t layout); |
1000 |
static AVSampleFormat GetAVSampleFormat(AEDataFormat format); |
1001 |
- static uint64_t GetAVChannel(enum AEChannel aechannel); |
1002 |
+ static uint64_t GetAVChannelMask(enum AEChannel aechannel); |
1003 |
+ static enum AVChannel GetAVChannel(enum AEChannel aechannel); |
1004 |
static int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); |
1005 |
}; |
1006 |
diff -urN xbmc/cores/FFmpeg.cpp.orig xbmc/cores/FFmpeg.cpp |
1007 |
--- xbmc/cores/FFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1008 |
+++ xbmc/cores/FFmpeg.cpp 2023-04-19 10:01:22.850804000 +0000 |
1009 |
@@ -16,11 +16,29 @@ |
1010 |
#include "utils/StringUtils.h" |
1011 |
#include "utils/log.h" |
1012 |
|
1013 |
+extern "C" |
1014 |
+{ |
1015 |
+#include <libavcodec/bsf.h> |
1016 |
+} |
1017 |
+ |
1018 |
#include <map> |
1019 |
#include <mutex> |
1020 |
|
1021 |
static thread_local CFFmpegLog* CFFmpegLogTls; |
1022 |
|
1023 |
+namespace FFMPEG_HELP_TOOLS |
1024 |
+{ |
1025 |
+ |
1026 |
+std::string FFMpegErrorToString(int err) |
1027 |
+{ |
1028 |
+ std::string text; |
1029 |
+ text.resize(AV_ERROR_MAX_STRING_SIZE); |
1030 |
+ av_strerror(err, text.data(), AV_ERROR_MAX_STRING_SIZE); |
1031 |
+ return text; |
1032 |
+} |
1033 |
+ |
1034 |
+} // namespace FFMPEG_HELP_TOOLS |
1035 |
+ |
1036 |
void CFFmpegLog::SetLogLevel(int level) |
1037 |
{ |
1038 |
CFFmpegLog::ClearLogLevel(); |
1039 |
@@ -117,3 +135,128 @@ |
1040 |
buffer.erase(0, start); |
1041 |
} |
1042 |
|
1043 |
+std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, |
1044 |
+ const AVCodecParserContext* parserCtx, |
1045 |
+ AVCodecContext* codecCtx) |
1046 |
+{ |
1047 |
+ constexpr int FF_MAX_EXTRADATA_SIZE = ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE); |
1048 |
+ |
1049 |
+ if (!pkt) |
1050 |
+ return std::make_tuple(nullptr, 0); |
1051 |
+ |
1052 |
+ uint8_t* extraData = nullptr; |
1053 |
+ int extraDataSize = 0; |
1054 |
+ |
1055 |
+ /* extract_extradata bitstream filter is implemented only |
1056 |
+ * for certain codecs, as noted in discussion of PR#21248 |
1057 |
+ */ |
1058 |
+ |
1059 |
+ AVCodecID codecId = codecCtx->codec_id; |
1060 |
+ |
1061 |
+ // clang-format off |
1062 |
+ if ( |
1063 |
+ codecId != AV_CODEC_ID_MPEG1VIDEO && |
1064 |
+ codecId != AV_CODEC_ID_MPEG2VIDEO && |
1065 |
+ codecId != AV_CODEC_ID_H264 && |
1066 |
+ codecId != AV_CODEC_ID_HEVC && |
1067 |
+ codecId != AV_CODEC_ID_MPEG4 && |
1068 |
+ codecId != AV_CODEC_ID_VC1 && |
1069 |
+ codecId != AV_CODEC_ID_AV1 && |
1070 |
+ codecId != AV_CODEC_ID_AVS2 && |
1071 |
+ codecId != AV_CODEC_ID_AVS3 && |
1072 |
+ codecId != AV_CODEC_ID_CAVS |
1073 |
+ ) |
1074 |
+ // clang-format on |
1075 |
+ return std::make_tuple(nullptr, 0); |
1076 |
+ |
1077 |
+ const AVBitStreamFilter* f = av_bsf_get_by_name("extract_extradata"); |
1078 |
+ if (!f) |
1079 |
+ return std::make_tuple(nullptr, 0); |
1080 |
+ |
1081 |
+ AVBSFContext* bsf = nullptr; |
1082 |
+ int ret = av_bsf_alloc(f, &bsf); |
1083 |
+ if (ret < 0) |
1084 |
+ return std::make_tuple(nullptr, 0); |
1085 |
+ |
1086 |
+ bsf->par_in->codec_id = codecId; |
1087 |
+ |
1088 |
+ ret = av_bsf_init(bsf); |
1089 |
+ if (ret < 0) |
1090 |
+ { |
1091 |
+ av_bsf_free(&bsf); |
1092 |
+ return std::make_tuple(nullptr, 0); |
1093 |
+ } |
1094 |
+ |
1095 |
+ AVPacket* dstPkt = av_packet_alloc(); |
1096 |
+ if (!dstPkt) |
1097 |
+ { |
1098 |
+ CLog::LogF(LOGERROR, "failed to allocate packet"); |
1099 |
+ |
1100 |
+ av_bsf_free(&bsf); |
1101 |
+ return std::make_tuple(nullptr, 0); |
1102 |
+ } |
1103 |
+ AVPacket* pktRef = dstPkt; |
1104 |
+ |
1105 |
+ ret = av_packet_ref(pktRef, pkt); |
1106 |
+ if (ret < 0) |
1107 |
+ { |
1108 |
+ av_bsf_free(&bsf); |
1109 |
+ av_packet_free(&dstPkt); |
1110 |
+ return std::make_tuple(nullptr, 0); |
1111 |
+ } |
1112 |
+ |
1113 |
+ ret = av_bsf_send_packet(bsf, pktRef); |
1114 |
+ if (ret < 0) |
1115 |
+ { |
1116 |
+ av_packet_unref(pktRef); |
1117 |
+ av_bsf_free(&bsf); |
1118 |
+ av_packet_free(&dstPkt); |
1119 |
+ return std::make_tuple(nullptr, 0); |
1120 |
+ } |
1121 |
+ |
1122 |
+ ret = 0; |
1123 |
+ while (ret >= 0) |
1124 |
+ { |
1125 |
+ ret = av_bsf_receive_packet(bsf, pktRef); |
1126 |
+ if (ret < 0) |
1127 |
+ { |
1128 |
+ if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) |
1129 |
+ break; |
1130 |
+ |
1131 |
+ continue; |
1132 |
+ } |
1133 |
+ |
1134 |
+ size_t retExtraDataSize = 0; |
1135 |
+ uint8_t* retExtraData = |
1136 |
+ av_packet_get_side_data(pktRef, AV_PKT_DATA_NEW_EXTRADATA, &retExtraDataSize); |
1137 |
+ if (retExtraData && retExtraDataSize > 0 && retExtraDataSize < FF_MAX_EXTRADATA_SIZE) |
1138 |
+ { |
1139 |
+ extraData = static_cast<uint8_t*>(av_malloc(retExtraDataSize + AV_INPUT_BUFFER_PADDING_SIZE)); |
1140 |
+ if (!extraData) |
1141 |
+ { |
1142 |
+ CLog::LogF(LOGERROR, "failed to allocate {} bytes for extradata", retExtraDataSize); |
1143 |
+ |
1144 |
+ av_packet_unref(pktRef); |
1145 |
+ av_bsf_free(&bsf); |
1146 |
+ av_packet_free(&dstPkt); |
1147 |
+ return std::make_tuple(nullptr, 0); |
1148 |
+ } |
1149 |
+ |
1150 |
+ CLog::LogF(LOGDEBUG, "fetching extradata, extradata_size({})", retExtraDataSize); |
1151 |
+ |
1152 |
+ memcpy(extraData, retExtraData, retExtraDataSize); |
1153 |
+ memset(extraData + retExtraDataSize, 0, AV_INPUT_BUFFER_PADDING_SIZE); |
1154 |
+ extraDataSize = retExtraDataSize; |
1155 |
+ |
1156 |
+ av_packet_unref(pktRef); |
1157 |
+ break; |
1158 |
+ } |
1159 |
+ |
1160 |
+ av_packet_unref(pktRef); |
1161 |
+ } |
1162 |
+ |
1163 |
+ av_bsf_free(&bsf); |
1164 |
+ av_packet_free(&dstPkt); |
1165 |
+ |
1166 |
+ return std::make_tuple(extraData, extraDataSize); |
1167 |
+} |
1168 |
diff -urN xbmc/cores/FFmpeg.h.orig xbmc/cores/FFmpeg.h |
1169 |
--- xbmc/cores/FFmpeg.h.orig 2023-03-11 22:16:38.000000000 +0000 |
1170 |
+++ xbmc/cores/FFmpeg.h 2023-04-19 10:01:22.850926000 +0000 |
1171 |
@@ -10,6 +10,7 @@ |
1172 |
|
1173 |
#include "ServiceBroker.h" |
1174 |
#include "utils/CPUInfo.h" |
1175 |
+#include "utils/StringUtils.h" |
1176 |
|
1177 |
extern "C" { |
1178 |
#include <libavcodec/avcodec.h> |
1179 |
@@ -21,6 +22,26 @@ |
1180 |
#include <libpostproc/postprocess.h> |
1181 |
} |
1182 |
|
1183 |
+#include <tuple> |
1184 |
+ |
1185 |
+namespace FFMPEG_HELP_TOOLS |
1186 |
+{ |
1187 |
+ |
1188 |
+struct FFMpegException : public std::exception |
1189 |
+{ |
1190 |
+ std::string s; |
1191 |
+ template<typename... Args> |
1192 |
+ FFMpegException(const std::string& fmt, Args&&... args) |
1193 |
+ : s(StringUtils::Format(fmt, std::forward<Args>(args)...)) |
1194 |
+ { |
1195 |
+ } |
1196 |
+ const char* what() const noexcept override { return s.c_str(); } |
1197 |
+}; |
1198 |
+ |
1199 |
+std::string FFMpegErrorToString(int err); |
1200 |
+ |
1201 |
+} // namespace FFMPEG_HELP_TOOLS |
1202 |
+ |
1203 |
inline int PPCPUFlags() |
1204 |
{ |
1205 |
unsigned int cpuFeatures = CServiceBroker::GetCPUInfo()->GetCPUFeatures(); |
1206 |
@@ -51,3 +72,6 @@ |
1207 |
int level; |
1208 |
}; |
1209 |
|
1210 |
+std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, |
1211 |
+ const AVCodecParserContext* parserCtx, |
1212 |
+ AVCodecContext* codecCtx); |
1213 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp |
1214 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1215 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp 2023-04-19 10:01:30.826672000 +0000 |
1216 |
@@ -7,14 +7,16 @@ |
1217 |
*/ |
1218 |
|
1219 |
#include "DVDAudioCodecFFmpeg.h" |
1220 |
-#include "ServiceBroker.h" |
1221 |
+ |
1222 |
#include "../../DVDStreamInfo.h" |
1223 |
-#include "utils/log.h" |
1224 |
+#include "DVDCodecs/DVDCodecs.h" |
1225 |
+#include "ServiceBroker.h" |
1226 |
+#include "cores/AudioEngine/Utils/AEUtil.h" |
1227 |
+#include "cores/FFmpeg.h" |
1228 |
#include "settings/AdvancedSettings.h" |
1229 |
#include "settings/Settings.h" |
1230 |
#include "settings/SettingsComponent.h" |
1231 |
-#include "DVDCodecs/DVDCodecs.h" |
1232 |
-#include "cores/AudioEngine/Utils/AEUtil.h" |
1233 |
+#include "utils/log.h" |
1234 |
|
1235 |
extern "C" { |
1236 |
#include <libavutil/opt.h> |
1237 |
@@ -44,7 +46,7 @@ |
1238 |
return false; |
1239 |
} |
1240 |
|
1241 |
- AVCodec* pCodec = NULL; |
1242 |
+ const AVCodec* pCodec = nullptr; |
1243 |
bool allowdtshddecode = true; |
1244 |
|
1245 |
// set any special options |
1246 |
@@ -71,13 +73,28 @@ |
1247 |
m_pCodecContext->debug = 0; |
1248 |
m_pCodecContext->workaround_bugs = 1; |
1249 |
|
1250 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
1251 |
if (pCodec->capabilities & AV_CODEC_CAP_TRUNCATED) |
1252 |
m_pCodecContext->flags |= AV_CODEC_FLAG_TRUNCATED; |
1253 |
+#endif |
1254 |
|
1255 |
m_matrixEncoding = AV_MATRIX_ENCODING_NONE; |
1256 |
m_channels = 0; |
1257 |
- m_pCodecContext->channels = hints.channels; |
1258 |
- m_hint_layout = hints.channellayout; |
1259 |
+ av_channel_layout_uninit(&m_pCodecContext->ch_layout); |
1260 |
+ |
1261 |
+ if (hints.channels > 0 && hints.channellayout > 0) |
1262 |
+ { |
1263 |
+ m_pCodecContext->ch_layout.order = AV_CHANNEL_ORDER_NATIVE; |
1264 |
+ m_pCodecContext->ch_layout.nb_channels = hints.channels; |
1265 |
+ m_pCodecContext->ch_layout.u.mask = hints.channellayout; |
1266 |
+ } |
1267 |
+ else if (hints.channels > 0) |
1268 |
+ { |
1269 |
+ av_channel_layout_default(&m_pCodecContext->ch_layout, hints.channels); |
1270 |
+ } |
1271 |
+ |
1272 |
+ m_hint_layout = m_pCodecContext->ch_layout.u.mask; |
1273 |
+ |
1274 |
m_pCodecContext->sample_rate = hints.samplerate; |
1275 |
m_pCodecContext->block_align = hints.blockalign; |
1276 |
m_pCodecContext->bit_rate = hints.bitrate; |
1277 |
@@ -259,12 +276,13 @@ |
1278 |
m_format.m_frameSize = m_format.m_channelLayout.Count() * |
1279 |
CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3; |
1280 |
|
1281 |
- int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? m_pFrame->channels : 1; |
1282 |
+ int channels = m_pFrame->ch_layout.nb_channels; |
1283 |
+ int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? channels : 1; |
1284 |
+ |
1285 |
for (int i=0; i<planes; i++) |
1286 |
dst[i] = m_pFrame->extended_data[i]; |
1287 |
|
1288 |
- return m_pFrame->nb_samples * m_pFrame->channels * |
1289 |
- av_get_bytes_per_sample(m_pCodecContext->sample_fmt); |
1290 |
+ return m_pFrame->nb_samples * channels * av_get_bytes_per_sample(m_pCodecContext->sample_fmt); |
1291 |
} |
1292 |
|
1293 |
return 0; |
1294 |
@@ -278,7 +296,7 @@ |
1295 |
|
1296 |
int CDVDAudioCodecFFmpeg::GetChannels() |
1297 |
{ |
1298 |
- return m_pCodecContext->channels; |
1299 |
+ return m_pCodecContext->ch_layout.nb_channels; |
1300 |
} |
1301 |
|
1302 |
int CDVDAudioCodecFFmpeg::GetSampleRate() |
1303 |
@@ -345,28 +363,33 @@ |
1304 |
|
1305 |
void CDVDAudioCodecFFmpeg::BuildChannelMap() |
1306 |
{ |
1307 |
- if (m_channels == m_pCodecContext->channels && m_layout == m_pCodecContext->channel_layout) |
1308 |
+ int codecChannels = m_pCodecContext->ch_layout.nb_channels; |
1309 |
+ uint64_t codecChannelLayout = m_pCodecContext->ch_layout.u.mask; |
1310 |
+ if (m_channels == codecChannels && m_layout == codecChannelLayout) |
1311 |
return; //nothing to do here |
1312 |
|
1313 |
- m_channels = m_pCodecContext->channels; |
1314 |
- m_layout = m_pCodecContext->channel_layout; |
1315 |
+ m_channels = codecChannels; |
1316 |
+ m_layout = codecChannelLayout; |
1317 |
|
1318 |
int64_t layout; |
1319 |
|
1320 |
- int bits = count_bits(m_pCodecContext->channel_layout); |
1321 |
- if (bits == m_pCodecContext->channels) |
1322 |
- layout = m_pCodecContext->channel_layout; |
1323 |
+ int bits = count_bits(codecChannelLayout); |
1324 |
+ if (bits == codecChannels) |
1325 |
+ layout = codecChannelLayout; |
1326 |
else |
1327 |
{ |
1328 |
CLog::Log(LOGINFO, |
1329 |
"CDVDAudioCodecFFmpeg::GetChannelMap - FFmpeg reported {} channels, but the layout " |
1330 |
"contains {} - trying hints", |
1331 |
- m_pCodecContext->channels, bits); |
1332 |
- if (static_cast<int>(count_bits(m_hint_layout)) == m_pCodecContext->channels) |
1333 |
+ codecChannels, bits); |
1334 |
+ if (static_cast<int>(count_bits(m_hint_layout)) == codecChannels) |
1335 |
layout = m_hint_layout; |
1336 |
else |
1337 |
{ |
1338 |
- layout = av_get_default_channel_layout(m_pCodecContext->channels); |
1339 |
+ AVChannelLayout def_layout = {}; |
1340 |
+ av_channel_layout_default(&def_layout, codecChannels); |
1341 |
+ layout = def_layout.u.mask; |
1342 |
+ av_channel_layout_uninit(&def_layout); |
1343 |
CLog::Log(LOGINFO, "Using default layout..."); |
1344 |
} |
1345 |
} |
1346 |
@@ -392,7 +415,7 @@ |
1347 |
if (layout & AV_CH_TOP_BACK_CENTER ) m_channelLayout += AE_CH_BC ; |
1348 |
if (layout & AV_CH_TOP_BACK_RIGHT ) m_channelLayout += AE_CH_BR ; |
1349 |
|
1350 |
- m_channels = m_pCodecContext->channels; |
1351 |
+ m_channels = codecChannels; |
1352 |
} |
1353 |
|
1354 |
CAEChannelInfo CDVDAudioCodecFFmpeg::GetChannelMap() |
1355 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp |
1356 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1357 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp 2023-04-19 10:01:22.851350000 +0000 |
1358 |
@@ -10,6 +10,7 @@ |
1359 |
|
1360 |
#include "DVDOverlayImage.h" |
1361 |
#include "DVDStreamInfo.h" |
1362 |
+#include "cores/FFmpeg.h" |
1363 |
#include "cores/VideoPlayer/Interface/DemuxPacket.h" |
1364 |
#include "cores/VideoPlayer/Interface/TimingConstants.h" |
1365 |
#include "utils/EndianSwap.h" |
1366 |
@@ -39,7 +40,7 @@ |
1367 |
if (hints.codec == AV_CODEC_ID_EIA_608) |
1368 |
return false; |
1369 |
|
1370 |
- AVCodec* pCodec = avcodec_find_decoder(hints.codec); |
1371 |
+ const AVCodec* pCodec = avcodec_find_decoder(hints.codec); |
1372 |
if (!pCodec) |
1373 |
{ |
1374 |
CLog::Log(LOGDEBUG, "{} - Unable to find codec {}", __FUNCTION__, hints.codec); |
1375 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp |
1376 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1377 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp 2023-04-19 10:01:30.832626000 +0000 |
1378 |
@@ -12,6 +12,7 @@ |
1379 |
#include "DVDCodecs/DVDFactoryCodec.h" |
1380 |
#include "DVDStreamInfo.h" |
1381 |
#include "ServiceBroker.h" |
1382 |
+#include "cores/FFmpeg.h" |
1383 |
#include "cores/VideoPlayer/Interface/TimingConstants.h" |
1384 |
#include "cores/VideoPlayer/VideoRenderers/RenderManager.h" |
1385 |
#include "cores/VideoSettings.h" |
1386 |
@@ -27,12 +28,13 @@ |
1387 |
#include <mutex> |
1388 |
|
1389 |
extern "C" { |
1390 |
-#include <libavutil/opt.h> |
1391 |
-#include <libavutil/mastering_display_metadata.h> |
1392 |
#include <libavfilter/avfilter.h> |
1393 |
#include <libavfilter/buffersink.h> |
1394 |
#include <libavfilter/buffersrc.h> |
1395 |
+#include <libavutil/mastering_display_metadata.h> |
1396 |
+#include <libavutil/opt.h> |
1397 |
#include <libavutil/pixdesc.h> |
1398 |
+#include <libavutil/video_enc_params.h> |
1399 |
} |
1400 |
|
1401 |
#ifndef TARGET_POSIX |
1402 |
@@ -327,7 +329,7 @@ |
1403 |
m_hints = hints; |
1404 |
m_options = options; |
1405 |
|
1406 |
- AVCodec* pCodec = nullptr; |
1407 |
+ const AVCodec* pCodec = nullptr; |
1408 |
|
1409 |
m_iOrientation = hints.orientation; |
1410 |
|
1411 |
@@ -368,6 +370,10 @@ |
1412 |
m_pCodecContext->get_format = GetFormat; |
1413 |
m_pCodecContext->codec_tag = hints.codec_tag; |
1414 |
|
1415 |
+#if LIBAVCODEC_VERSION_MAJOR >= 60 |
1416 |
+ m_pCodecContext->flags = AV_CODEC_FLAG_COPY_OPAQUE; |
1417 |
+#endif |
1418 |
+ |
1419 |
// setup threading model |
1420 |
if (!(hints.codecOptions & CODEC_FORCE_SOFTWARE)) |
1421 |
{ |
1422 |
@@ -543,9 +549,10 @@ |
1423 |
CLog::Log(LOGDEBUG, "CDVDVideoCodecFFmpeg - Updated codec: {}", m_name); |
1424 |
} |
1425 |
|
1426 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
1427 |
union pts_union |
1428 |
{ |
1429 |
- double pts_d; |
1430 |
+ double pts_d; |
1431 |
int64_t pts_i; |
1432 |
}; |
1433 |
|
1434 |
@@ -555,6 +562,7 @@ |
1435 |
u.pts_d = pts; |
1436 |
return u.pts_i; |
1437 |
} |
1438 |
+#endif |
1439 |
|
1440 |
bool CDVDVideoCodecFFmpeg::AddData(const DemuxPacket &packet) |
1441 |
{ |
1442 |
@@ -573,7 +581,10 @@ |
1443 |
m_started = true; |
1444 |
|
1445 |
m_dts = packet.dts; |
1446 |
+ |
1447 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
1448 |
m_pCodecContext->reordered_opaque = pts_dtoi(packet.pts); |
1449 |
+#endif |
1450 |
|
1451 |
AVPacket* avpkt = av_packet_alloc(); |
1452 |
if (!avpkt) |
1453 |
@@ -1048,24 +1059,27 @@ |
1454 |
pVideoPicture->qscale_type = 0; |
1455 |
|
1456 |
AVFrameSideData* sd; |
1457 |
- sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_QP_TABLE_PROPERTIES); |
1458 |
+ |
1459 |
+ // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 |
1460 |
+ sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_VIDEO_ENC_PARAMS); |
1461 |
if (sd) |
1462 |
{ |
1463 |
- struct qp_properties |
1464 |
- { |
1465 |
- int stride; |
1466 |
- int type; |
1467 |
- }; |
1468 |
+ unsigned int mb_h = (m_pFrame->height + 15) / 16; |
1469 |
+ unsigned int mb_w = (m_pFrame->width + 15) / 16; |
1470 |
+ unsigned int nb_mb = mb_h * mb_w; |
1471 |
+ unsigned int block_idx; |
1472 |
|
1473 |
- auto qp = reinterpret_cast<qp_properties*>(sd->data); |
1474 |
- |
1475 |
- sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_QP_TABLE_DATA); |
1476 |
- if (sd && sd->buf && qp) |
1477 |
+ auto par = reinterpret_cast<AVVideoEncParams*>(sd->data); |
1478 |
+ if (par->type == AV_VIDEO_ENC_PARAMS_MPEG2 && (par->nb_blocks == 0 || par->nb_blocks == nb_mb)) |
1479 |
{ |
1480 |
- // this seems wrong but it's what ffmpeg does internally |
1481 |
- pVideoPicture->qp_table = reinterpret_cast<int8_t*>(sd->buf->data); |
1482 |
- pVideoPicture->qstride = qp->stride; |
1483 |
- pVideoPicture->qscale_type = qp->type; |
1484 |
+ pVideoPicture->qstride = mb_w; |
1485 |
+ pVideoPicture->qscale_type = par->type; |
1486 |
+ pVideoPicture->qp_table = static_cast<int8_t*>(av_malloc(nb_mb)); |
1487 |
+ for (block_idx = 0; block_idx < nb_mb; block_idx++) |
1488 |
+ { |
1489 |
+ AVVideoBlockParams* b = av_video_enc_params_block(par, block_idx); |
1490 |
+ pVideoPicture->qp_table[block_idx] = par->qp + b->delta_qp; |
1491 |
+ } |
1492 |
} |
1493 |
} |
1494 |
|
1495 |
@@ -1159,8 +1173,9 @@ |
1496 |
const AVFilter* outFilter = avfilter_get_by_name("buffersink"); // should be last filter in the graph for now |
1497 |
|
1498 |
std::string args = StringUtils::Format( |
1499 |
- "{}:{}:{}:{}:{}:{}:{}", m_pCodecContext->width, m_pCodecContext->height, |
1500 |
- m_pCodecContext->pix_fmt, m_pCodecContext->time_base.num ? m_pCodecContext->time_base.num : 1, |
1501 |
+ "video_size={}x{}:pix_fmt={}:time_base={}/{}:pixel_aspect={}/{}", m_pCodecContext->width, |
1502 |
+ m_pCodecContext->height, m_pCodecContext->pix_fmt, |
1503 |
+ m_pCodecContext->time_base.num ? m_pCodecContext->time_base.num : 1, |
1504 |
m_pCodecContext->time_base.num ? m_pCodecContext->time_base.den : 1, |
1505 |
m_pCodecContext->sample_aspect_ratio.num != 0 ? m_pCodecContext->sample_aspect_ratio.num : 1, |
1506 |
m_pCodecContext->sample_aspect_ratio.num != 0 ? m_pCodecContext->sample_aspect_ratio.den : 1); |
1507 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp |
1508 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1509 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp 2023-04-19 10:01:22.851870000 +0000 |
1510 |
@@ -118,6 +118,8 @@ |
1511 |
m_pMode, m_pContext, |
1512 |
pSource->pict_type | pSource->qscale_type ? PP_PICT_TYPE_QP2 : 0); |
1513 |
|
1514 |
+ // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 |
1515 |
+ av_free(pSource->qp_table); |
1516 |
|
1517 |
pPicture->SetParams(*pSource); |
1518 |
if (pPicture->videoBuffer) |
1519 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp |
1520 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1521 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp 2023-04-19 10:01:30.833014000 +0000 |
1522 |
@@ -973,7 +973,8 @@ |
1523 |
m_event.Set(); |
1524 |
m_avD3D11Context = av_d3d11va_alloc_context(); |
1525 |
m_avD3D11Context->cfg = reinterpret_cast<D3D11_VIDEO_DECODER_CONFIG*>(av_mallocz(sizeof(D3D11_VIDEO_DECODER_CONFIG))); |
1526 |
- m_avD3D11Context->surface = reinterpret_cast<ID3D11VideoDecoderOutputView**>(av_mallocz_array(32, sizeof(ID3D11VideoDecoderOutputView*))); |
1527 |
+ m_avD3D11Context->surface = reinterpret_cast<ID3D11VideoDecoderOutputView**>( |
1528 |
+ av_calloc(32, sizeof(ID3D11VideoDecoderOutputView*))); |
1529 |
m_bufferPool.reset(); |
1530 |
|
1531 |
DX::Windowing()->Register(this); |
1532 |
@@ -1538,8 +1539,6 @@ |
1533 |
return -1; |
1534 |
} |
1535 |
|
1536 |
- pic->reordered_opaque = avctx->reordered_opaque; |
1537 |
- |
1538 |
for (unsigned i = 0; i < 4; i++) |
1539 |
{ |
1540 |
pic->data[i] = nullptr; |
1541 |
@@ -1555,6 +1554,10 @@ |
1542 |
return -1; |
1543 |
} |
1544 |
pic->buf[0] = buffer; |
1545 |
+ |
1546 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
1547 |
+ pic->reordered_opaque = avctx->reordered_opaque; |
1548 |
+#endif |
1549 |
|
1550 |
Acquire(); |
1551 |
|
1552 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp |
1553 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1554 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp 2023-04-19 10:01:30.833643000 +0000 |
1555 |
@@ -868,7 +868,10 @@ |
1556 |
} |
1557 |
pic->buf[0] = buffer; |
1558 |
|
1559 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
1560 |
pic->reordered_opaque = avctx->reordered_opaque; |
1561 |
+#endif |
1562 |
+ |
1563 |
va->Acquire(); |
1564 |
return 0; |
1565 |
} |
1566 |
@@ -1259,7 +1262,9 @@ |
1567 |
|
1568 |
IHardwareDecoder* CDecoder::Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt) |
1569 |
{ |
1570 |
- if (fmt == AV_PIX_FMT_VAAPI_VLD && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(SETTING_VIDEOPLAYER_USEVAAPI)) |
1571 |
+ // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4fdda160f4039fc2ae33edfd27765c9/doc/APIchanges#L18-L26 |
1572 |
+ if (fmt == AV_PIX_FMT_VAAPI && |
1573 |
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(SETTING_VIDEOPLAYER_USEVAAPI)) |
1574 |
return new VAAPI::CDecoder(processInfo); |
1575 |
|
1576 |
return nullptr; |
1577 |
@@ -2966,10 +2971,11 @@ |
1578 |
const AVFilter* srcFilter = avfilter_get_by_name("buffer"); |
1579 |
const AVFilter* outFilter = avfilter_get_by_name("buffersink"); |
1580 |
|
1581 |
- std::string args = StringUtils::Format("{}:{}:{}:{}:{}:{}:{}", m_config.vidWidth, |
1582 |
- m_config.vidHeight, AV_PIX_FMT_NV12, 1, 1, |
1583 |
- (m_config.aspect.num != 0) ? m_config.aspect.num : 1, |
1584 |
- (m_config.aspect.num != 0) ? m_config.aspect.den : 1); |
1585 |
+ std::string args = |
1586 |
+ StringUtils::Format("video_size={}x{}:pix_fmt={}:time_base={}/{}:pixel_aspect={}/{}", |
1587 |
+ m_config.vidWidth, m_config.vidHeight, AV_PIX_FMT_NV12, 1, 1, |
1588 |
+ (m_config.aspect.num != 0) ? m_config.aspect.num : 1, |
1589 |
+ (m_config.aspect.num != 0) ? m_config.aspect.den : 1); |
1590 |
|
1591 |
if (avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", args.c_str(), NULL, m_pFilterGraph) < 0) |
1592 |
{ |
1593 |
diff -urN xbmc/cores/VideoPlayer/DVDCodecs/Video/VDPAU.cpp.orig xbmc/cores/VideoPlayer/DVDCodecs/Video/VDPAU.cpp |
1594 |
--- xbmc/cores/VideoPlayer/DVDCodecs/Video/VDPAU.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1595 |
+++ xbmc/cores/VideoPlayer/DVDCodecs/Video/VDPAU.cpp 2023-04-19 10:01:30.834410000 +0000 |
1596 |
@@ -1045,7 +1045,10 @@ |
1597 |
} |
1598 |
pic->buf[0] = buffer; |
1599 |
|
1600 |
- pic->reordered_opaque= avctx->reordered_opaque; |
1601 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
1602 |
+ pic->reordered_opaque = avctx->reordered_opaque; |
1603 |
+#endif |
1604 |
+ |
1605 |
return 0; |
1606 |
} |
1607 |
|
1608 |
diff -urN xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp.orig xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp |
1609 |
--- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1610 |
+++ xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp 2023-04-19 10:01:22.852749000 +0000 |
1611 |
@@ -10,13 +10,13 @@ |
1612 |
|
1613 |
#include "DVDDemuxUtils.h" |
1614 |
#include "DVDInputStreams/DVDInputStream.h" |
1615 |
+#include "cores/FFmpeg.h" |
1616 |
#include "cores/VideoPlayer/Interface/TimingConstants.h" |
1617 |
#include "utils/log.h" |
1618 |
|
1619 |
+#include <tuple> |
1620 |
#include <utility> |
1621 |
|
1622 |
-#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE) |
1623 |
- |
1624 |
class CDemuxStreamClientInternal |
1625 |
{ |
1626 |
public: |
1627 |
@@ -130,7 +130,7 @@ |
1628 |
|
1629 |
if (stream->m_context == nullptr) |
1630 |
{ |
1631 |
- AVCodec *codec = avcodec_find_decoder(st->codec); |
1632 |
+ const AVCodec* codec = avcodec_find_decoder(st->codec); |
1633 |
if (codec == nullptr) |
1634 |
{ |
1635 |
CLog::Log(LOGERROR, "{} - can't find decoder", __FUNCTION__); |
1636 |
@@ -149,17 +149,26 @@ |
1637 |
stream->m_context->time_base.den = DVD_TIME_BASE; |
1638 |
} |
1639 |
|
1640 |
- if (stream->m_parser_split && stream->m_parser->parser->split) |
1641 |
+ if (stream->m_parser_split && stream->m_parser && stream->m_parser->parser) |
1642 |
{ |
1643 |
- int len = stream->m_parser->parser->split(stream->m_context, pkt->pData, pkt->iSize); |
1644 |
- if (len > 0 && len < FF_MAX_EXTRADATA_SIZE) |
1645 |
+ AVPacket* avpkt = av_packet_alloc(); |
1646 |
+ if (!avpkt) |
1647 |
{ |
1648 |
+ CLog::LogF(LOGERROR, "av_packet_alloc failed: {}", strerror(errno)); |
1649 |
+ return false; |
1650 |
+ } |
1651 |
+ |
1652 |
+ avpkt->data = pkt->pData; |
1653 |
+ avpkt->size = pkt->iSize; |
1654 |
+ avpkt->dts = avpkt->pts = AV_NOPTS_VALUE; |
1655 |
+ |
1656 |
+ auto [retExtraData, len] = GetPacketExtradata(avpkt, stream->m_parser, stream->m_context); |
1657 |
+ if (len > 0) |
1658 |
+ { |
1659 |
st->changes++; |
1660 |
st->disabled = false; |
1661 |
st->ExtraSize = len; |
1662 |
- st->ExtraData = std::make_unique<uint8_t[]>(len + AV_INPUT_BUFFER_PADDING_SIZE); |
1663 |
- memcpy(st->ExtraData.get(), pkt->pData, len); |
1664 |
- memset(st->ExtraData.get() + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); |
1665 |
+ st->ExtraData = std::unique_ptr<uint8_t[]>(retExtraData); |
1666 |
stream->m_parser_split = false; |
1667 |
change = true; |
1668 |
CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - split extradata"); |
1669 |
@@ -167,21 +176,12 @@ |
1670 |
// Allow ffmpeg to transport codec information to stream->m_context |
1671 |
if (!avcodec_open2(stream->m_context, stream->m_context->codec, nullptr)) |
1672 |
{ |
1673 |
- AVPacket* avpkt = av_packet_alloc(); |
1674 |
- if (!avpkt) |
1675 |
- { |
1676 |
- CLog::Log(LOGERROR, "CDVDDemuxClient::{} - av_packet_alloc failed: {}", __FUNCTION__, |
1677 |
- strerror(errno)); |
1678 |
- return false; |
1679 |
- } |
1680 |
- avpkt->data = pkt->pData; |
1681 |
- avpkt->size = pkt->iSize; |
1682 |
- avpkt->dts = avpkt->pts = AV_NOPTS_VALUE; |
1683 |
avcodec_send_packet(stream->m_context, avpkt); |
1684 |
avcodec_close(stream->m_context); |
1685 |
- av_packet_free(&avpkt); |
1686 |
} |
1687 |
} |
1688 |
+ |
1689 |
+ av_packet_free(&avpkt); |
1690 |
} |
1691 |
|
1692 |
uint8_t *outbuf = nullptr; |
1693 |
@@ -219,10 +219,12 @@ |
1694 |
case STREAM_AUDIO: |
1695 |
{ |
1696 |
CDemuxStreamClientInternalTpl<CDemuxStreamAudio>* sta = static_cast<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>*>(st); |
1697 |
- if (stream->m_context->channels != sta->iChannels && stream->m_context->channels != 0) |
1698 |
+ int streamChannels = stream->m_context->ch_layout.nb_channels; |
1699 |
+ if (streamChannels != sta->iChannels && streamChannels != 0) |
1700 |
{ |
1701 |
- CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - ({}) channels changed from {} to {}", st->uniqueId, sta->iChannels, stream->m_context->channels); |
1702 |
- sta->iChannels = stream->m_context->channels; |
1703 |
+ CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - ({}) channels changed from {} to {}", |
1704 |
+ st->uniqueId, sta->iChannels, streamChannels); |
1705 |
+ sta->iChannels = streamChannels; |
1706 |
sta->changes++; |
1707 |
sta->disabled = false; |
1708 |
} |
1709 |
@@ -234,7 +236,7 @@ |
1710 |
sta->changes++; |
1711 |
sta->disabled = false; |
1712 |
} |
1713 |
- if (stream->m_context->channels) |
1714 |
+ if (streamChannels) |
1715 |
st->changes = -1; // stop parsing |
1716 |
break; |
1717 |
} |
1718 |
diff -urN xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp.orig xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp |
1719 |
--- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
1720 |
+++ xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp 2023-04-19 10:01:30.828436000 +0000 |
1721 |
@@ -34,10 +34,12 @@ |
1722 |
|
1723 |
#include <mutex> |
1724 |
#include <sstream> |
1725 |
+#include <tuple> |
1726 |
#include <utility> |
1727 |
|
1728 |
extern "C" |
1729 |
{ |
1730 |
+#include "libavutil/channel_layout.h" |
1731 |
#include "libavutil/pixdesc.h" |
1732 |
} |
1733 |
|
1734 |
@@ -104,8 +106,6 @@ |
1735 |
} |
1736 |
} // namespace |
1737 |
|
1738 |
-#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE) |
1739 |
- |
1740 |
std::string CDemuxStreamAudioFFmpeg::GetStreamName() |
1741 |
{ |
1742 |
if (!m_stream) |
1743 |
@@ -235,7 +235,7 @@ |
1744 |
|
1745 |
bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool fileinfo) |
1746 |
{ |
1747 |
- AVInputFormat* iformat = NULL; |
1748 |
+ const AVInputFormat* iformat = nullptr; |
1749 |
std::string strFile; |
1750 |
m_streaminfo = !pInput->IsRealtime() && !m_reopen; |
1751 |
m_reopen = false; |
1752 |
@@ -323,7 +323,6 @@ |
1753 |
} |
1754 |
if (result < 0) |
1755 |
{ |
1756 |
- m_pFormatContext->flags |= AVFMT_FLAG_PRIV_OPT; |
1757 |
if (avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0) |
1758 |
{ |
1759 |
CLog::Log(LOGDEBUG, "Error, could not open file {}", CURL::GetRedacted(strFile)); |
1760 |
@@ -335,7 +334,6 @@ |
1761 |
avformat_close_input(&m_pFormatContext); |
1762 |
m_pFormatContext = avformat_alloc_context(); |
1763 |
m_pFormatContext->interrupt_callback = int_cb; |
1764 |
- m_pFormatContext->flags &= ~AVFMT_FLAG_PRIV_OPT; |
1765 |
AVDictionary* options = GetFFMpegOptionsFromInput(); |
1766 |
av_dict_set_int(&options, "load_all_variants", 0, AV_OPT_SEARCH_CHILDREN); |
1767 |
if (avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0) |
1768 |
@@ -422,9 +420,7 @@ |
1769 |
// is present, we assume it is PCM audio. |
1770 |
// AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS |
1771 |
// may be just padded. |
1772 |
- AVInputFormat* iformat2; |
1773 |
- iformat2 = av_find_input_format("spdif"); |
1774 |
- |
1775 |
+ const AVInputFormat* iformat2 = av_find_input_format("spdif"); |
1776 |
if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) |
1777 |
{ |
1778 |
iformat = iformat2; |
1779 |
@@ -544,12 +540,6 @@ |
1780 |
m_streaminfo = true; |
1781 |
} |
1782 |
|
1783 |
- if (iformat && (strcmp(iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0)) |
1784 |
- { |
1785 |
- if (URIUtils::IsRemote(strFile)) |
1786 |
- m_pFormatContext->iformat->flags |= AVFMT_NOGENSEARCH; |
1787 |
- } |
1788 |
- |
1789 |
// we need to know if this is matroska, avi or sup later |
1790 |
m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" |
1791 |
m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; |
1792 |
@@ -604,9 +594,6 @@ |
1793 |
// if format can be nonblocking, let's use that |
1794 |
m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK; |
1795 |
|
1796 |
- // deprecated, will be always set in future versions |
1797 |
- m_pFormatContext->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; |
1798 |
- |
1799 |
UpdateCurrentPTS(); |
1800 |
|
1801 |
// select the correct program if requested |
1802 |
@@ -647,7 +634,10 @@ |
1803 |
{ |
1804 |
int idx = m_pFormatContext->programs[i]->stream_index[j]; |
1805 |
AVStream* st = m_pFormatContext->streams[idx]; |
1806 |
- if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 0) || |
1807 |
+ // Related to https://patchwork.ffmpeg.org/project/ffmpeg/patch/20210429143825.53040-1-jamrial@gmail.com/ |
1808 |
+ // has been replaced with AVSTREAM_EVENT_FLAG_NEW_PACKETS. |
1809 |
+ if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && |
1810 |
+ (st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)) || |
1811 |
(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate > 0)) |
1812 |
{ |
1813 |
nProgram = i; |
1814 |
@@ -1218,8 +1208,11 @@ |
1815 |
else if (stream->type == STREAM_AUDIO) |
1816 |
{ |
1817 |
CDemuxStreamAudioFFmpeg* audiostream = dynamic_cast<CDemuxStreamAudioFFmpeg*>(stream); |
1818 |
- if (audiostream && (audiostream->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->channels || |
1819 |
- audiostream->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->sample_rate)) |
1820 |
+ int codecparChannels = |
1821 |
+ m_pFormatContext->streams[pPacket->iStreamId]->codecpar->ch_layout.nb_channels; |
1822 |
+ if (audiostream && (audiostream->iChannels != codecparChannels || |
1823 |
+ audiostream->iSampleRate != |
1824 |
+ m_pFormatContext->streams[pPacket->iStreamId]->codecpar->sample_rate)) |
1825 |
{ |
1826 |
// content has changed |
1827 |
stream = AddStream(pPacket->iStreamId); |
1828 |
@@ -1401,9 +1394,10 @@ |
1829 |
if (idx >= 0) |
1830 |
{ |
1831 |
AVStream* stream = m_pFormatContext->streams[idx]; |
1832 |
- if (stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE) |
1833 |
+ |
1834 |
+ if (stream && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE) |
1835 |
{ |
1836 |
- double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num); |
1837 |
+ double ts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num); |
1838 |
m_currentPts = ts; |
1839 |
} |
1840 |
} |
1841 |
@@ -1614,14 +1608,20 @@ |
1842 |
{ |
1843 |
CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(pStream); |
1844 |
stream = st; |
1845 |
- st->iChannels = pStream->codecpar->channels; |
1846 |
+ int codecparChannels = pStream->codecpar->ch_layout.nb_channels; |
1847 |
+ int codecparChannelLayout = pStream->codecpar->ch_layout.u.mask; |
1848 |
+ st->iChannels = codecparChannels; |
1849 |
+ st->iChannelLayout = codecparChannelLayout; |
1850 |
st->iSampleRate = pStream->codecpar->sample_rate; |
1851 |
st->iBlockAlign = pStream->codecpar->block_align; |
1852 |
st->iBitRate = static_cast<int>(pStream->codecpar->bit_rate); |
1853 |
st->iBitsPerSample = pStream->codecpar->bits_per_raw_sample; |
1854 |
- st->iChannelLayout = pStream->codecpar->channel_layout; |
1855 |
char buf[32] = {}; |
1856 |
- av_get_channel_layout_string(buf, 31, st->iChannels, st->iChannelLayout); |
1857 |
+ // https://github.com/FFmpeg/FFmpeg/blob/6ccc3989d15/doc/APIchanges#L50-L53 |
1858 |
+ AVChannelLayout layout = {}; |
1859 |
+ av_channel_layout_from_mask(&layout, st->iChannelLayout); |
1860 |
+ av_channel_layout_describe(&layout, buf, sizeof(buf)); |
1861 |
+ av_channel_layout_uninit(&layout); |
1862 |
st->m_channelLayoutName = buf; |
1863 |
if (st->iBitsPerSample == 0) |
1864 |
st->iBitsPerSample = pStream->codecpar->bits_per_coded_sample; |
1865 |
@@ -1663,16 +1663,6 @@ |
1866 |
st->iFpsScale = 0; |
1867 |
} |
1868 |
|
1869 |
- if (pStream->codec_info_nb_frames > 0 && |
1870 |
- pStream->codec_info_nb_frames <= 2 && |
1871 |
- m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) |
1872 |
- { |
1873 |
- CLog::Log(LOGDEBUG, "{} - fps may be unreliable since ffmpeg decoded only {} frame(s)", |
1874 |
- __FUNCTION__, pStream->codec_info_nb_frames); |
1875 |
- st->iFpsRate = 0; |
1876 |
- st->iFpsScale = 0; |
1877 |
- } |
1878 |
- |
1879 |
st->iWidth = pStream->codecpar->width; |
1880 |
st->iHeight = pStream->codecpar->height; |
1881 |
st->fAspect = SelectAspect(pStream, st->bForcedAspect); |
1882 |
@@ -1693,7 +1683,8 @@ |
1883 |
st->colorRange = pStream->codecpar->color_range; |
1884 |
st->hdr_type = DetermineHdrType(pStream); |
1885 |
|
1886 |
- int size = 0; |
1887 |
+ // https://github.com/FFmpeg/FFmpeg/blob/release/5.0/doc/APIchanges |
1888 |
+ size_t size = 0; |
1889 |
uint8_t* side_data = nullptr; |
1890 |
|
1891 |
side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &size); |
1892 |
@@ -2103,7 +2094,7 @@ |
1893 |
return strName; |
1894 |
} |
1895 |
|
1896 |
- AVCodec* codec = avcodec_find_decoder(stream->codec); |
1897 |
+ const AVCodec* codec = avcodec_find_decoder(stream->codec); |
1898 |
if (codec) |
1899 |
strName = avcodec_get_name(codec->id); |
1900 |
} |
1901 |
@@ -2158,8 +2149,8 @@ |
1902 |
if (m_pFormatContext->streams[idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) |
1903 |
{ |
1904 |
CDemuxStreamAudioFFmpeg* audiostream = dynamic_cast<CDemuxStreamAudioFFmpeg*>(stream); |
1905 |
- if (audiostream && |
1906 |
- m_pFormatContext->streams[idx]->codecpar->channels != audiostream->iChannels) |
1907 |
+ int codecparChannels = m_pFormatContext->streams[idx]->codecpar->ch_layout.nb_channels; |
1908 |
+ if (audiostream && codecparChannels != audiostream->iChannels) |
1909 |
{ |
1910 |
return true; |
1911 |
} |
1912 |
@@ -2279,7 +2270,7 @@ |
1913 |
|
1914 |
parser->second->m_parserCtx = av_parser_init(st->codecpar->codec_id); |
1915 |
|
1916 |
- AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id); |
1917 |
+ const AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id); |
1918 |
if (codec == nullptr) |
1919 |
{ |
1920 |
CLog::Log(LOGERROR, "{} - can't find decoder", __FUNCTION__); |
1921 |
@@ -2295,45 +2286,37 @@ |
1922 |
|
1923 |
if (parser->second->m_parserCtx && |
1924 |
parser->second->m_parserCtx->parser && |
1925 |
- parser->second->m_parserCtx->parser->split && |
1926 |
!st->codecpar->extradata) |
1927 |
{ |
1928 |
- int i = parser->second->m_parserCtx->parser->split(parser->second->m_codecCtx, pkt->data, pkt->size); |
1929 |
- if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) |
1930 |
+ auto [retExtraData, i] = |
1931 |
+ GetPacketExtradata(pkt, parser->second->m_parserCtx, parser->second->m_codecCtx); |
1932 |
+ if (i > 0) |
1933 |
{ |
1934 |
- st->codecpar->extradata = (uint8_t*)av_malloc(i + AV_INPUT_BUFFER_PADDING_SIZE); |
1935 |
- if (st->codecpar->extradata) |
1936 |
+ st->codecpar->extradata_size = i; |
1937 |
+ st->codecpar->extradata = retExtraData; |
1938 |
+ |
1939 |
+ if (parser->second->m_parserCtx->parser->parser_parse) |
1940 |
{ |
1941 |
- CLog::Log(LOGDEBUG, |
1942 |
- "CDVDDemuxFFmpeg::ParsePacket() fetching extradata, extradata_size({})", i); |
1943 |
- st->codecpar->extradata_size = i; |
1944 |
- memcpy(st->codecpar->extradata, pkt->data, i); |
1945 |
- memset(st->codecpar->extradata + i, 0, AV_INPUT_BUFFER_PADDING_SIZE); |
1946 |
+ parser->second->m_codecCtx->extradata = st->codecpar->extradata; |
1947 |
+ parser->second->m_codecCtx->extradata_size = st->codecpar->extradata_size; |
1948 |
+ const uint8_t* outbufptr; |
1949 |
+ int bufSize; |
1950 |
+ parser->second->m_parserCtx->flags |= PARSER_FLAG_COMPLETE_FRAMES; |
1951 |
+ parser->second->m_parserCtx->parser->parser_parse(parser->second->m_parserCtx, |
1952 |
+ parser->second->m_codecCtx, &outbufptr, |
1953 |
+ &bufSize, pkt->data, pkt->size); |
1954 |
+ parser->second->m_codecCtx->extradata = nullptr; |
1955 |
+ parser->second->m_codecCtx->extradata_size = 0; |
1956 |
|
1957 |
- if (parser->second->m_parserCtx->parser->parser_parse) |
1958 |
+ if (parser->second->m_parserCtx->width != 0) |
1959 |
{ |
1960 |
- parser->second->m_codecCtx->extradata = st->codecpar->extradata; |
1961 |
- parser->second->m_codecCtx->extradata_size = st->codecpar->extradata_size; |
1962 |
- const uint8_t* outbufptr; |
1963 |
- int bufSize; |
1964 |
- parser->second->m_parserCtx->flags |= PARSER_FLAG_COMPLETE_FRAMES; |
1965 |
- parser->second->m_parserCtx->parser->parser_parse(parser->second->m_parserCtx, |
1966 |
- parser->second->m_codecCtx, |
1967 |
- &outbufptr, &bufSize, |
1968 |
- pkt->data, pkt->size); |
1969 |
- parser->second->m_codecCtx->extradata = nullptr; |
1970 |
- parser->second->m_codecCtx->extradata_size = 0; |
1971 |
- |
1972 |
- if (parser->second->m_parserCtx->width != 0) |
1973 |
- { |
1974 |
- st->codecpar->width = parser->second->m_parserCtx->width; |
1975 |
- st->codecpar->height = parser->second->m_parserCtx->height; |
1976 |
- } |
1977 |
- else |
1978 |
- { |
1979 |
- CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::ParsePacket() invalid width/height"); |
1980 |
- } |
1981 |
+ st->codecpar->width = parser->second->m_parserCtx->width; |
1982 |
+ st->codecpar->height = parser->second->m_parserCtx->height; |
1983 |
} |
1984 |
+ else |
1985 |
+ { |
1986 |
+ CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::ParsePacket() invalid width/height"); |
1987 |
+ } |
1988 |
} |
1989 |
} |
1990 |
} |
1991 |
@@ -2357,7 +2340,8 @@ |
1992 |
{ |
1993 |
if (!m_startTime) |
1994 |
{ |
1995 |
- m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; |
1996 |
+ m_startTime = |
1997 |
+ av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; |
1998 |
m_seekStream = idx; |
1999 |
} |
2000 |
return TRANSPORT_STREAM_STATE::READY; |
2001 |
@@ -2377,7 +2361,8 @@ |
2002 |
{ |
2003 |
if (!m_startTime) |
2004 |
{ |
2005 |
- m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; |
2006 |
+ m_startTime = |
2007 |
+ av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; |
2008 |
m_seekStream = i; |
2009 |
} |
2010 |
return TRANSPORT_STREAM_STATE::READY; |
2011 |
@@ -2410,7 +2395,8 @@ |
2012 |
{ |
2013 |
if (!m_startTime) |
2014 |
{ |
2015 |
- m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; |
2016 |
+ m_startTime = |
2017 |
+ av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; |
2018 |
m_seekStream = idx; |
2019 |
} |
2020 |
return TRANSPORT_STREAM_STATE::READY; |
2021 |
@@ -2430,7 +2416,8 @@ |
2022 |
{ |
2023 |
if (!m_startTime) |
2024 |
{ |
2025 |
- m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; |
2026 |
+ m_startTime = |
2027 |
+ av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; |
2028 |
m_seekStream = i; |
2029 |
} |
2030 |
return TRANSPORT_STREAM_STATE::READY; |
2031 |
diff -urN xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp.orig xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp |
2032 |
--- xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
2033 |
+++ xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp 2023-04-19 10:01:22.853712000 +0000 |
2034 |
@@ -12,6 +12,7 @@ |
2035 |
#include "addons/addoninfo/AddonType.h" |
2036 |
#include "addons/binary-addons/AddonDll.h" |
2037 |
#include "addons/kodi-dev-kit/include/kodi/addon-instance/VideoCodec.h" |
2038 |
+#include "cores/FFmpeg.h" |
2039 |
#include "cores/VideoPlayer/DVDDemuxers/DVDDemux.h" |
2040 |
#include "cores/VideoPlayer/DVDDemuxers/DVDDemuxUtils.h" |
2041 |
#include "cores/VideoPlayer/Interface/DemuxCrypto.h" |
2042 |
@@ -392,7 +393,7 @@ |
2043 |
return nullptr; |
2044 |
|
2045 |
std::string codecName(stream->m_codecName); |
2046 |
- AVCodec* codec = nullptr; |
2047 |
+ const AVCodec* codec = nullptr; |
2048 |
|
2049 |
if (stream->m_streamType != INPUTSTREAM_TYPE_TELETEXT && |
2050 |
stream->m_streamType != INPUTSTREAM_TYPE_RDS && stream->m_streamType != INPUTSTREAM_TYPE_ID3) |
2051 |
diff -urN xbmc/filesystem/AudioBookFileDirectory.cpp.orig xbmc/filesystem/AudioBookFileDirectory.cpp |
2052 |
--- xbmc/filesystem/AudioBookFileDirectory.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
2053 |
+++ xbmc/filesystem/AudioBookFileDirectory.cpp 2023-04-19 10:01:22.853859000 +0000 |
2054 |
@@ -11,6 +11,7 @@ |
2055 |
#include "TextureDatabase.h" |
2056 |
#include "URL.h" |
2057 |
#include "Util.h" |
2058 |
+#include "cores/FFmpeg.h" |
2059 |
#include "filesystem/File.h" |
2060 |
#include "guilib/LocalizeStrings.h" |
2061 |
#include "music/tags/MusicInfoTag.h" |
2062 |
@@ -149,7 +150,7 @@ |
2063 |
|
2064 |
m_ioctx->max_packet_size = 32768; |
2065 |
|
2066 |
- AVInputFormat* iformat=nullptr; |
2067 |
+ const AVInputFormat* iformat = nullptr; |
2068 |
av_probe_input_buffer(m_ioctx, &iformat, url.Get().c_str(), nullptr, 0, 0); |
2069 |
|
2070 |
bool contains = false; |
2071 |
diff -urN xbmc/guilib/FFmpegImage.cpp.orig xbmc/guilib/FFmpegImage.cpp |
2072 |
--- xbmc/guilib/FFmpegImage.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
2073 |
+++ xbmc/guilib/FFmpegImage.cpp 2023-04-19 10:01:30.832285000 +0000 |
2074 |
@@ -52,7 +52,7 @@ |
2075 |
AVFrame* frame_temporary = nullptr; |
2076 |
SwsContext* sws = nullptr; |
2077 |
AVCodecContext* avOutctx = nullptr; |
2078 |
- AVCodec* codec = nullptr; |
2079 |
+ const AVCodec* codec = nullptr; |
2080 |
~ThumbDataManagement() |
2081 |
{ |
2082 |
av_free(intermediateBuffer); |
2083 |
@@ -198,7 +198,7 @@ |
2084 |
bool is_png = (bufSize > 3 && buffer[1] == 'P' && buffer[2] == 'N' && buffer[3] == 'G'); |
2085 |
bool is_tiff = (bufSize > 2 && buffer[0] == 'I' && buffer[1] == 'I' && buffer[2] == '*'); |
2086 |
|
2087 |
- AVInputFormat* inp = nullptr; |
2088 |
+ const AVInputFormat* inp = nullptr; |
2089 |
if (is_jpeg) |
2090 |
inp = av_find_input_format("image2"); |
2091 |
else if (m_strMimeType == "image/apng") |
2092 |
@@ -236,7 +236,7 @@ |
2093 |
return false; |
2094 |
} |
2095 |
AVCodecParameters* codec_params = m_fctx->streams[0]->codecpar; |
2096 |
- AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); |
2097 |
+ const AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); |
2098 |
m_codec_ctx = avcodec_alloc_context3(codec); |
2099 |
if (!m_codec_ctx) |
2100 |
{ |
2101 |
@@ -294,7 +294,15 @@ |
2102 |
return nullptr; |
2103 |
} |
2104 |
//we need milliseconds |
2105 |
- frame->pkt_duration = av_rescale_q(frame->pkt_duration, m_fctx->streams[0]->time_base, AVRational{ 1, 1000 }); |
2106 |
+ |
2107 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
2108 |
+ frame->pkt_duration = |
2109 |
+ av_rescale_q(frame->pkt_duration, m_fctx->streams[0]->time_base, AVRational{1, 1000}); |
2110 |
+#else |
2111 |
+ frame->duration = |
2112 |
+ av_rescale_q(frame->duration, m_fctx->streams[0]->time_base, AVRational{1, 1000}); |
2113 |
+#endif |
2114 |
+ |
2115 |
m_height = frame->height; |
2116 |
m_width = frame->width; |
2117 |
m_originalWidth = m_width; |
2118 |
@@ -745,7 +753,13 @@ |
2119 |
if (avframe == nullptr) |
2120 |
return nullptr; |
2121 |
std::shared_ptr<Frame> frame(new Frame()); |
2122 |
+ |
2123 |
+#if LIBAVCODEC_VERSION_MAJOR < 60 |
2124 |
frame->m_delay = (unsigned int)avframe->pkt_duration; |
2125 |
+#else |
2126 |
+ frame->m_delay = (unsigned int)avframe->duration; |
2127 |
+#endif |
2128 |
+ |
2129 |
frame->m_pitch = avframe->width * 4; |
2130 |
frame->m_pImage = (unsigned char*) av_malloc(avframe->height * frame->m_pitch); |
2131 |
DecodeFrame(avframe, avframe->width, avframe->height, frame->m_pitch, frame->m_pImage); |
2132 |
diff -urN xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp.orig xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp |
2133 |
--- xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
2134 |
+++ xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp 2023-04-19 10:01:22.854258000 +0000 |
2135 |
@@ -58,7 +58,7 @@ |
2136 |
if (file.IoControl(IOCTRL_SEEK_POSSIBLE, NULL) != 1) |
2137 |
ioctx->seekable = 0; |
2138 |
|
2139 |
- AVInputFormat* iformat=NULL; |
2140 |
+ const AVInputFormat* iformat = nullptr; |
2141 |
av_probe_input_buffer(ioctx, &iformat, strFileName.c_str(), NULL, 0, 0); |
2142 |
|
2143 |
if (avformat_open_input(&fctx, strFileName.c_str(), iformat, NULL) < 0) |
2144 |
diff -urN xbmc/video/tags/VideoTagLoaderFFmpeg.cpp.orig xbmc/video/tags/VideoTagLoaderFFmpeg.cpp |
2145 |
--- xbmc/video/tags/VideoTagLoaderFFmpeg.cpp.orig 2023-03-11 22:16:38.000000000 +0000 |
2146 |
+++ xbmc/video/tags/VideoTagLoaderFFmpeg.cpp 2023-04-19 10:01:22.854418000 +0000 |
2147 |
@@ -65,7 +65,7 @@ |
2148 |
if (m_file->IoControl(IOCTRL_SEEK_POSSIBLE, nullptr) != 1) |
2149 |
m_ioctx->seekable = 0; |
2150 |
|
2151 |
- AVInputFormat* iformat = nullptr; |
2152 |
+ const AVInputFormat* iformat = nullptr; |
2153 |
av_probe_input_buffer(m_ioctx, &iformat, m_item.GetPath().c_str(), nullptr, 0, 0); |
2154 |
if (avformat_open_input(&m_fctx, m_item.GetPath().c_str(), iformat, nullptr) < 0) |
2155 |
{ |