qtav-1.12.0.patchset revision 2c9a7c9d
1From dd02092df2454cee17ff5293cb383082fdcce293 Mon Sep 17 00:00:00 2001 2From: 0xFelix <evostar@gmx.de> 3Date: Tue, 12 Dec 2017 13:24:34 +0100 4Subject: Remove usage of deprecated avfiltergraph.h header 5 6 7diff --git a/src/QtAV/private/AVCompat.h b/src/QtAV/private/AVCompat.h 8index e387868..e6225e9 100644 9--- a/src/QtAV/private/AVCompat.h 10+++ b/src/QtAV/private/AVCompat.h 11@@ -59,6 +59,7 @@ extern "C" 12 #include <libavutil/parseutils.h> 13 #include <libavutil/pixdesc.h> 14 #include <libavutil/avstring.h> 15+#include <libavfilter/version.h> 16 17 #if !FFMPEG_MODULE_CHECK(LIBAVUTIL, 51, 73, 101) 18 #include <libavutil/channel_layout.h> 19@@ -79,8 +80,11 @@ extern "C" 20 #endif //QTAV_HAVE(AVRESAMPLE) 21 22 #if QTAV_HAVE(AVFILTER) 23+#if LIBAVFILTER_VERSION_INT < AV_VERSION_INT(3,8,0) 24 #include <libavfilter/avfiltergraph.h> /*code is here for old version*/ 25+#else 26 #include <libavfilter/avfilter.h> 27+#endif 28 #include <libavfilter/buffersink.h> 29 #include <libavfilter/buffersrc.h> 30 #endif //QTAV_HAVE(AVFILTER) 31-- 322.21.0 33 34 35From 68334c99231118758475e5218adc2e818b7a0f7b Mon Sep 17 00:00:00 2001 36From: Felix Matouschek <felix@matouschek.org> 37Date: Sat, 11 Nov 2017 10:13:06 +0100 38Subject: Make QtAV build with newer versions of FFmpeg 39 40 41diff --git a/src/AVMuxer.cpp b/src/AVMuxer.cpp 42index 729d94a..10d85bb 100644 43--- a/src/AVMuxer.cpp 44+++ b/src/AVMuxer.cpp 45@@ -122,7 +122,7 @@ AVStream *AVMuxer::Private::addStream(AVFormatContext* ctx, const QString &codec 46 c->time_base = s->time_base; 47 /* Some formats want stream headers to be separate. */ 48 if (ctx->oformat->flags & AVFMT_GLOBALHEADER) 49- c->flags |= CODEC_FLAG_GLOBAL_HEADER; 50+ c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; 51 // expose avctx to encoder and set properties in encoder? 52 // list codecs for a given format in ui 53 return s; 54diff --git a/src/QtAV/private/AVCompat.h b/src/QtAV/private/AVCompat.h 55index e6225e9..944cfd7 100644 56--- a/src/QtAV/private/AVCompat.h 57+++ b/src/QtAV/private/AVCompat.h 58@@ -460,3 +460,15 @@ const char *get_codec_long_name(AVCodecID id); 59 } } while(0) 60 61 #endif //QTAV_COMPAT_H 62+ 63+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,33,0) 64+#define AV_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER 65+#endif 66+ 67+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,56,100) 68+#define AV_INPUT_BUFFER_MIN_SIZE FF_MIN_BUFFER_SIZE 69+#endif 70+ 71+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(56,56,100) 72+#define AV_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE 73+#endif 74diff --git a/src/codec/audio/AudioEncoderFFmpeg.cpp b/src/codec/audio/AudioEncoderFFmpeg.cpp 75index 93a0506..f67fb27 100644 76--- a/src/codec/audio/AudioEncoderFFmpeg.cpp 77+++ b/src/codec/audio/AudioEncoderFFmpeg.cpp 78@@ -153,8 +153,8 @@ bool AudioEncoderFFmpegPrivate::open() 79 } else { 80 buffer_size = frame_size*format_used.bytesPerSample()*format_used.channels()*2+200; 81 } 82- if (buffer_size < FF_MIN_BUFFER_SIZE) 83- buffer_size = FF_MIN_BUFFER_SIZE; 84+ if (buffer_size < AV_INPUT_BUFFER_MIN_SIZE) 85+ buffer_size = AV_INPUT_BUFFER_MIN_SIZE; 86 buffer.resize(buffer_size); 87 return true; 88 } 89diff --git a/src/codec/video/VideoEncoderFFmpeg.cpp b/src/codec/video/VideoEncoderFFmpeg.cpp 90index 7c5ed42..671efa7 100644 91--- a/src/codec/video/VideoEncoderFFmpeg.cpp 92+++ b/src/codec/video/VideoEncoderFFmpeg.cpp 93@@ -245,7 +245,7 @@ bool VideoEncoderFFmpegPrivate::open() 94 applyOptionsForContext(); 95 AV_ENSURE_OK(avcodec_open2(avctx, codec, &dict), false); 96 // from mpv ao_lavc 97- const int buffer_size = qMax<int>(qMax<int>(width*height*6+200, FF_MIN_BUFFER_SIZE), sizeof(AVPicture));//?? 98+ const int buffer_size = qMax<int>(qMax<int>(width*height*6+200, AV_INPUT_BUFFER_MIN_SIZE), sizeof(AVPicture));//?? 99 buffer.resize(buffer_size); 100 return true; 101 } 102diff --git a/src/filter/LibAVFilter.cpp b/src/filter/LibAVFilter.cpp 103index 1915120..8993a91 100644 104--- a/src/filter/LibAVFilter.cpp 105+++ b/src/filter/LibAVFilter.cpp 106@@ -120,7 +120,10 @@ public: 107 // pixel_aspect==sar, pixel_aspect is more compatible 108 QString buffersrc_args = args; 109 qDebug("buffersrc_args=%s", buffersrc_args.toUtf8().constData()); 110- AVFilter *buffersrc = avfilter_get_by_name(video ? "buffer" : "abuffer"); 111+#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(7,0,0) 112+ const 113+#endif 114+ AVFilter *buffersrc = avfilter_get_by_name(video ? "buffer" : "abuffer"); 115 Q_ASSERT(buffersrc); 116 AV_ENSURE_OK(avfilter_graph_create_filter(&in_filter_ctx, 117 buffersrc, 118@@ -128,6 +131,9 @@ public: 119 filter_graph) 120 , false); 121 /* buffer video sink: to terminate the filter chain. */ 122+#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(7,0,0) 123+ const 124+#endif 125 AVFilter *buffersink = avfilter_get_by_name(video ? "buffersink" : "abuffersink"); 126 Q_ASSERT(buffersink); 127 AV_ENSURE_OK(avfilter_graph_create_filter(&out_filter_ctx, buffersink, "out", 128diff --git a/src/subtitle/SubtitleProcessorFFmpeg.cpp b/src/subtitle/SubtitleProcessorFFmpeg.cpp 129index 30ee936..1755c38 100644 130--- a/src/subtitle/SubtitleProcessorFFmpeg.cpp 131+++ b/src/subtitle/SubtitleProcessorFFmpeg.cpp 132@@ -249,7 +249,7 @@ bool SubtitleProcessorFFmpeg::processHeader(const QByteArray &codec, const QByte 133 codec_ctx->time_base.den = 1000; 134 if (!data.isEmpty()) { 135 av_free(codec_ctx->extradata); 136- codec_ctx->extradata = (uint8_t*)av_mallocz(data.size() + FF_INPUT_BUFFER_PADDING_SIZE); 137+ codec_ctx->extradata = (uint8_t*)av_mallocz(data.size() + AV_INPUT_BUFFER_PADDING_SIZE); 138 if (!codec_ctx->extradata) 139 return false; 140 codec_ctx->extradata_size = data.size(); 141-- 1422.21.0 143 144 145From 9336c7619b41418c97b6262aaaf433f4dc1ddd39 Mon Sep 17 00:00:00 2001 146From: Johannes Huber <johu@gentoo.org> 147Date: Wed, 6 Sep 2017 23:30:42 +0200 148Subject: Fix multilib install 149 150 151diff --git a/CMakeLists.txt b/CMakeLists.txt 152index ef7ade0..11f8603 100644 153--- a/CMakeLists.txt 154+++ b/CMakeLists.txt 155@@ -66,7 +66,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # for .moc 156 set(CMAKE_AUTOMOC ON) 157 if(NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 158 set(QTAV_INSTALL_HEADERS ${CMAKE_INSTALL_PREFIX}/include) 159- set(QTAV_INSTALL_LIBS ${CMAKE_INSTALL_PREFIX}/lib) 160+ set(QTAV_INSTALL_LIBS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) 161 set(QTAV_INSTALL_BINS ${CMAKE_INSTALL_PREFIX}/bin) 162 set(QTAV_INSTALL_QML ${CMAKE_INSTALL_PREFIX}/qml) 163 else() 164-- 1652.21.0 166 167 168From ec7adb96023306de5387f3a3130022fcdad7552f Mon Sep 17 00:00:00 2001 169From: Gerasim Troeglazov <3dEyes@gmail.com> 170Date: Wed, 1 May 2019 21:12:05 +1000 171Subject: Add missing header 172 173 174diff --git a/contrib/capi/capi.h b/contrib/capi/capi.h 175new file mode 100644 176index 0000000..df7c8ee 177--- /dev/null 178+++ b/contrib/capi/capi.h 179@@ -0,0 +1,518 @@ 180+/****************************************************************************** 181+ Use C API in C++ dynamically and no link. Header only. 182+ Use it with a code generation tool: https://github.com/wang-bin/mkapi 183+ Copyright (C) 2014-2017 Wang Bin <wbsecg1@gmail.com> 184+ 185+ This library is free software; you can redistribute it and/or 186+ modify it under the terms of the GNU Lesser General Public 187+ License as published by the Free Software Foundation; either 188+ version 2.1 of the License, or (at your option) any later version. 189+ 190+ This library is distributed in the hope that it will be useful, 191+ but WITHOUT ANY WARRANTY; without even the implied warranty of 192+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 193+ Lesser General Public License for more details. 194+ 195+ You should have received a copy of the GNU Lesser General Public 196+ License along with this library; if not, write to the Free Software 197+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 198+******************************************************************************/ 199+// no class based implementation: https://github.com/wang-bin/dllapi . limitation: can not reload library 200+#ifndef CAPI_H 201+#define CAPI_H 202+ 203+/*! 204+ How To Use: (see test/zlib) 205+ use the header and source from code gerenrated from: https://github.com/wang-bin/mkapi 206+ */ 207+ 208+#include <cstddef> //ptrdiff_t 209+#include <cstdio> 210+#include <cassert> 211+#include <string.h> 212+ 213+#define CAPI_IS(X) (defined CAPI_IS_##X && CAPI_IS_##X) 214+/*! 215+ * you can define CAPI_IS_LAZY_RESOLVE 0 before including capi.h. then all symbols will be resolved in constructor. 216+ * default resolving a symbol at it's first call 217+ */ 218+#ifndef CAPI_IS_LAZY_RESOLVE 219+#define CAPI_IS_LAZY_RESOLVE 1 220+#endif 221+namespace capi { 222+namespace version { 223+ enum { 224+ Major = 0, Minor = 7, Patch = 1, 225+ Value = ((Major&0xff)<<16) | ((Minor&0xff)<<8) | (Patch&0xff) 226+ }; 227+ static const char name[] = { Major + '0', '.', Minor + '0', '.', Patch + '0', 0 }; 228+} //namespace version 229+// set lib name with version 230+enum { 231+ NoVersion = -1, /// library name without major version, for example libz.so 232+ EndVersion = -2 233+}; 234+/********************************** The following code is only used in .cpp **************************************************/ 235+/*! 236+ * -Library names: 237+ static const char* zlib[] = { 238+ #ifdef CAPI_TARGET_OS_WIN 239+ "zlib", 240+ #else 241+ "z", 242+ #endif 243+ /usr/local/lib/libmyz.so, // absolute path is ok 244+ NULL}; 245+ CAPI_BEGIN_DLL(zlib, ::capi::dso) // the 2nd parameter is a dynamic shared object loader class. \sa dll_helper class 246+ ... 247+ * -Multiple library versions 248+ An example to open libz.so, libz.so.1, libz.so.0 on unix 249+ static const int ver[] = { ::capi::NoVersion, 1, 0, ::capi::EndVersion }; 250+ CAPI_BEGIN_DLL_VER(zlib, ver, ::capi::dso) 251+ ... 252+ */ 253+class dso { 254+ void *handle; 255+ char full_name[512]; 256+ dso(const dso&); 257+ dso& operator=(const dso&); 258+public: 259+ static inline char* path_from_handle(void* handle, char* path, int path_len); 260+ dso(): handle(0) {} 261+ virtual ~dso() { unload();} 262+ inline void setFileName(const char* name); 263+ inline void setFileNameAndVersion(const char* name, int ver); 264+ inline bool load(); 265+ inline bool unload(); 266+ bool isLoaded() const { return !!handle;} 267+ virtual void* resolve(const char* symbol) { return resolve(symbol, true);} 268+ const char* path() const { return full_name;} // loaded path 269+protected: 270+ inline void* load(const char* name); 271+ inline bool unload(void* lib); 272+ inline void* resolve(const char* sym, bool try_); 273+}; 274+} //namespace capi 275+/// DLL_CLASS is a library loader and symbols resolver class. Must implement api like capi::dso (the same function name and return type, but string parameter type can be different): 276+/// unload() must support ref count. i.e. do unload if no one is using the real library 277+/// Currently you can use ::capi::dso and QLibrary for DLL_CLASS. You can also use your own library resolver 278+#define CAPI_BEGIN_DLL(names, DLL_CLASS) \ 279+ class api_dll : public ::capi::internal::dll_helper<DLL_CLASS> { \ 280+ public: api_dll() : ::capi::internal::dll_helper<DLL_CLASS>(names) CAPI_DLL_BODY_DEFINE 281+#define CAPI_BEGIN_DLL_VER(names, versions, DLL_CLASS) \ 282+ class api_dll : public ::capi::internal::dll_helper<DLL_CLASS> { \ 283+ public: api_dll() : ::capi::internal::dll_helper<DLL_CLASS>(names, versions) CAPI_DLL_BODY_DEFINE 284+#if CAPI_IS(LAZY_RESOLVE) 285+#define CAPI_END_DLL() } api_t; api_t api; }; 286+#else 287+#define CAPI_END_DLL() }; 288+#endif 289+#define CAPI_DEFINE_DLL api::api():dll(new api_dll()){} \ 290+ api::~api(){delete dll;} \ 291+ bool api::loaded() const { return dll->isLoaded();} \ 292+ namespace capi { \ 293+ static api_dll* dll = NULL; \ 294+ bool loaded() { \ 295+ if (!dll) dll = new api_dll(); \ 296+ return dll->isLoaded(); \ 297+ } \ 298+ } 299+ 300+/*! 301+ * N: number of arguments 302+ * R: return type 303+ * name: api name 304+ * ...: api arguments with only types, wrapped by CAPI_ARGn, n=0,1,2,...13 305+ * The symbol of the api is "name". Otherwise, use CAPI_DEFINE instead. 306+ * example: 307+ * 1. const char* zlibVersion() 308+ * CAPI_DEFINE(const char* zlibVersion, CAPI_ARG0()) 309+ * 2. const char* zError(int) // get error string from zlib error code 310+ * CAPI_DEFINE(const char*, zError, CAPI_ARG1(int)) 311+ */ 312+#if CAPI_IS(LAZY_RESOLVE) 313+#define CAPI_DEFINE(R, name, ...) EXPAND(CAPI_DEFINE2_X(R, name, name, __VA_ARGS__)) /* not ##__VA_ARGS__ !*/ 314+#define CAPI_DEFINE_ENTRY(R, name, ...) EXPAND(CAPI_DEFINE_ENTRY_X(R, name, name, __VA_ARGS__)) 315+#define CAPI_DEFINE_M_ENTRY(R, M, name, ...) EXPAND(CAPI_DEFINE_M_ENTRY_X(R, M, name, name, __VA_ARGS__)) 316+#else 317+#define CAPI_DEFINE(R, name, ...) EXPAND(CAPI_DEFINE_X(R, name, __VA_ARGS__)) /* not ##__VA_ARGS__ !*/ 318+#define CAPI_DEFINE_ENTRY(R, name, ...) EXPAND(CAPI_DEFINE_RESOLVER_X(R, name, name, __VA_ARGS__)) 319+#define CAPI_DEFINE_M_ENTRY(R, M, name, ...) EXPAND(CAPI_DEFINE_M_RESOLVER_X(R, M, name, name, __VA_ARGS__)) 320+#endif 321+//EXPAND(CAPI_DEFINE##N(R, name, #name, __VA_ARGS__)) 322+ 323+///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 324+/************The followings are used internally**********/ 325+#if CAPI_IS(LAZY_RESOLVE) 326+#define CAPI_DLL_BODY_DEFINE { memset(&api, 0, sizeof(api));} typedef struct { 327+#else 328+#define CAPI_DLL_BODY_DEFINE { CAPI_DBG_RESOLVE("capi resolved dll symbols...");} 329+#endif 330+#define CAPI_DEFINE_T_V(R, name, ARG_T, ARG_T_V, ARG_V) \ 331+ R api::name ARG_T_V { \ 332+ CAPI_DBG_CALL(" "); \ 333+ assert(dll && dll->isLoaded() && "dll is not loaded"); \ 334+ return dll->name ARG_V; \ 335+ } 336+#define CAPI_DEFINE2_T_V(R, name, sym, ARG_T, ARG_T_V, ARG_V) \ 337+ R api::name ARG_T_V { \ 338+ CAPI_DBG_CALL(" "); \ 339+ assert(dll && dll->isLoaded() && "dll is not loaded"); \ 340+ if (!dll->api.name) { \ 341+ dll->api.name = (api_dll::api_t::name##_t)dll->resolve(#sym); \ 342+ CAPI_DBG_RESOLVE("dll::api_t::" #name ": @%p", dll->api.name); \ 343+ } \ 344+ assert(dll->api.name && "failed to resolve " #R #sym #ARG_T_V); \ 345+ return dll->api.name ARG_V; \ 346+ } 347+/* 348+ * TODO: choose 1 of below 349+ * - use CAPI_LINKAGE and remove CAPI_DEFINE_M_ENTRY_X & CAPI_DEFINE_M_RESOLVER_X 350+ * - also pass a linkage parameter to CAPI_NS_DEFINE_T_V & CAPI_NS_DEFINE2_T_V 351+ */ 352+#ifndef CAPI_LINKAGE 353+#define CAPI_LINKAGE 354+#endif //CAPI_LINKAGE 355+#define CAPI_NS_DEFINE_T_V(R, name, ARG_T, ARG_T_V, ARG_V) \ 356+ namespace capi { \ 357+ using capi::dll; \ 358+ R CAPI_LINKAGE name ARG_T_V { \ 359+ CAPI_DBG_CALL(" "); \ 360+ if (!dll) dll = new api_dll(); \ 361+ assert(dll && dll->isLoaded() && "dll is not loaded"); \ 362+ return dll->name ARG_V; \ 363+ } } 364+#define CAPI_NS_DEFINE2_T_V(R, name, sym, ARG_T, ARG_T_V, ARG_V) \ 365+ namespace capi { \ 366+ using capi::dll; \ 367+ R CAPI_LINKAGE name ARG_T_V { \ 368+ CAPI_DBG_CALL(" "); \ 369+ if (!dll) dll = new api_dll(); \ 370+ assert(dll && dll->isLoaded() && "dll is not loaded"); \ 371+ if (!dll->api.name) { \ 372+ dll->api.name = (api_dll::api_t::name##_t)dll->resolve(#sym); \ 373+ CAPI_DBG_RESOLVE("dll::api_t::" #name ": @%p", dll->api.name); \ 374+ } \ 375+ assert(dll->api.name && "failed to resolve " #R #sym #ARG_T_V); \ 376+ return dll->api.name ARG_V; \ 377+ } } 378+ 379+// nested class can not call non-static members outside the class, so hack the address here 380+// need -Wno-invalid-offsetof 381+#define CAPI_DEFINE_M_RESOLVER_T_V(R, M, name, sym, ARG_T, ARG_T_V, ARG_V) \ 382+ public: \ 383+ typedef R (M *name##_t) ARG_T; \ 384+ name##_t name; \ 385+ private: \ 386+ struct name##_resolver_t { \ 387+ name##_resolver_t() { \ 388+ const ptrdiff_t diff = ptrdiff_t(&((api_dll*)0)->name##_resolver) - ptrdiff_t(&((api_dll*)0)->name); \ 389+ name##_t *p = (name##_t*)((char*)this - diff); \ 390+ api_dll* dll = (api_dll*)((char*)this - ((ptrdiff_t)(&((api_dll*)0)->name##_resolver))); \ 391+ if (!dll->isLoaded()) { \ 392+ CAPI_WARN_LOAD("dll not loaded"); \ 393+ *p = NULL; \ 394+ return; \ 395+ } \ 396+ *p = (name##_t)dll->resolve(#sym); \ 397+ if (*p) { CAPI_DBG_RESOLVE("dll::" #name ": @%p", *p); } \ 398+ else { CAPI_WARN_RESOLVE("capi resolve error '" #name "'"); } \ 399+ } \ 400+ } name##_resolver; 401+ 402+#if defined(__GNUC__) 403+# define CAPI_FUNC_INFO __PRETTY_FUNCTION__ 404+#elif defined(_MSC_VER) 405+# define CAPI_FUNC_INFO __FUNCSIG__ 406+#else 407+# define CAPI_FUNC_INFO __FUNCTION__ 408+#endif 409+#ifdef DEBUG 410+#define DEBUG_LOAD 411+#define DEBUG_RESOLVE 412+#define DEBUG_CALL 413+#endif //DEBUG 414+#if defined(DEBUG) || defined(DEBUG_LOAD) || defined(DEBUG_RESOLVE) || defined(DEBUG_CALL) 415+#define CAPI_LOG(STDWHERE, fmt, ...) do {fprintf(STDWHERE, "[%s] %s@%d: " fmt "\n", __FILE__, CAPI_FUNC_INFO, __LINE__, ##__VA_ARGS__); fflush(STDWHERE);} while(0); 416+#else 417+#define CAPI_LOG(...) 418+#endif //DEBUG 419+#ifdef DEBUG_LOAD 420+#define CAPI_DBG_LOAD(...) EXPAND(CAPI_LOG(stdout, ##__VA_ARGS__)) 421+#define CAPI_WARN_LOAD(...) EXPAND(CAPI_LOG(stderr, ##__VA_ARGS__)) 422+#else 423+#define CAPI_DBG_LOAD(...) 424+#define CAPI_WARN_LOAD(...) 425+#endif //DEBUG_LOAD 426+#ifdef DEBUG_RESOLVE 427+#define CAPI_DBG_RESOLVE(...) EXPAND(CAPI_LOG(stdout, ##__VA_ARGS__)) 428+#define CAPI_WARN_RESOLVE(...) EXPAND(CAPI_LOG(stderr, ##__VA_ARGS__)) 429+#else 430+#define CAPI_DBG_RESOLVE(...) 431+#define CAPI_WARN_RESOLVE(...) 432+#endif //DEBUG_RESOLVE 433+#ifdef DEBUG_CALL 434+#define CAPI_DBG_CALL(...) EXPAND(CAPI_LOG(stdout, ##__VA_ARGS__)) 435+#define CAPI_WARN_CALL(...) EXPAND(CAPI_LOG(stderr, ##__VA_ARGS__)) 436+#else 437+#define CAPI_DBG_CALL(...) 438+#define CAPI_WARN_CALL(...) 439+#endif //DEBUG_CALL 440+//fully expand. used by VC. VC will not expand __VA_ARGS__ but treats it as 1 parameter 441+#define EXPAND(expr) expr //TODO: rename CAPI_EXPAND 442+#if defined(_WIN32) // http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system 443+#define CAPI_TARGET_OS_WIN 1 444+#include <windows.h> 445+#ifdef WINAPI_FAMILY 446+#include <winapifamily.h> 447+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 448+#define CAPI_TARGET_OS_WINRT 1 449+#endif 450+#endif //WINAPI_FAMILY 451+#endif 452+#if defined(__APPLE__) 453+#define CAPI_TARGET_OS_MAC 1 454+#include <mach-o/dyld.h> 455+#endif 456+#ifndef CAPI_TARGET_OS_WIN 457+#if !defined(__APPLE__) && !defined(__HAIKU__) 458+#include <link.h> // for link_map. qnx: sys/link.h 459+#endif 460+#include <dlfcn.h> 461+#endif 462+namespace capi { 463+namespace internal { 464+// the following code is for the case DLL=QLibrary + QT_NO_CAST_FROM_ASCII 465+// you can add a new qstr_wrap like class and a specialization of dso_trait to support a new string type before/after include "capi.h" 466+struct qstr_wrap { 467+ static const char* fromLatin1(const char* s) {return s;} 468+}; 469+template<class T> struct dso_trait { 470+ typedef const char* str_t; 471+ typedef qstr_wrap qstr_t; 472+}; 473+//can not explicit specialization of 'trait' in class scope 474+#if defined(QLIBRARY_H) && defined(QT_CORE_LIB) 475+template<> struct dso_trait<QLibrary> { 476+ typedef QString str_t; 477+ typedef QString qstr_t; 478+}; 479+#endif 480+// base ctor dll_helper("name")=>derived members in decl order(resolvers)=>derived ctor 481+static const int kDefaultVersions[] = {::capi::NoVersion, ::capi::EndVersion}; 482+template <class DLL> class dll_helper { //no CAPI_EXPORT required 483+ DLL m_lib; 484+ typename dso_trait<DLL>::str_t strType(const char* s) { 485+ return dso_trait<DLL>::qstr_t::fromLatin1(s); 486+ } 487+public: 488+ dll_helper(const char* names[], const int versions[] = kDefaultVersions) { 489+ static bool is_1st = true; 490+ if (is_1st) { 491+ is_1st = false; 492+ fprintf(stderr, "capi::version: %s\n", ::capi::version::name); 493+ } 494+ for (int i = 0; names[i]; ++i) { 495+ for (int j = 0; versions[j] != ::capi::EndVersion; ++j) { 496+ if (versions[j] == ::capi::NoVersion) 497+ m_lib.setFileName(strType(names[i])); 498+ else 499+ m_lib.setFileNameAndVersion(strType(names[i]), versions[j]); 500+ if (m_lib.load()) { 501+ CAPI_DBG_LOAD("capi loaded {library name: %s, version: %d}: %s", names[i], versions[j], m_lib.path()); 502+ return; 503+ } 504+ CAPI_WARN_LOAD("capi can not load {library name: %s, version %d}", names[i], versions[j]); 505+ } 506+ } 507+ } 508+ virtual ~dll_helper() { m_lib.unload();} 509+ bool isLoaded() const { return m_lib.isLoaded(); } 510+ void* resolve(const char *symbol) { return (void*)m_lib.resolve(symbol);} 511+}; 512+#ifdef CAPI_TARGET_OS_WIN 513+ static const char kPre[] = ""; 514+ static const char kExt[] = ".dll"; 515+#else 516+ static const char kPre[] = "lib"; 517+#ifdef CAPI_TARGET_OS_MAC 518+ static const char kExt[] = ".dylib"; 519+#else 520+ static const char kExt[] = ".so"; 521+#endif 522+#endif 523+} //namespace internal 524+#ifdef CAPI_TARGET_OS_WIN 525+#define CAPI_SNPRINTF _snprintf 526+#define CAPI_SNWPRINTF _snwprintf 527+#else 528+#define CAPI_SNPRINTF snprintf 529+#define CAPI_SNWPRINTF snwprintf 530+#endif 531+void dso::setFileName(const char* name) { 532+ CAPI_DBG_LOAD("dso.setFileName(\"%s\")", name); 533+ if (name[0] == '/') 534+ CAPI_SNPRINTF(full_name, sizeof(full_name), "%s", name); 535+ else 536+ CAPI_SNPRINTF(full_name, sizeof(full_name), "%s%s%s", internal::kPre, name, internal::kExt); 537+} 538+void dso::setFileNameAndVersion(const char* name, int ver) { 539+ CAPI_DBG_LOAD("dso.setFileNameAndVersion(\"%s\", %d)", name, ver); 540+ if (ver >= 0) { 541+#if defined(CAPI_TARGET_OS_WIN) // ignore version on win. xxx-V.dll? 542+ CAPI_SNPRINTF(full_name, sizeof(full_name), "%s%s%s", internal::kPre, name, internal::kExt); 543+#elif defined(CAPI_TARGET_OS_MAC) 544+ CAPI_SNPRINTF(full_name, sizeof(full_name), "%s%s.%d%s", internal::kPre, name, ver, internal::kExt); 545+#else 546+ CAPI_SNPRINTF(full_name, sizeof(full_name), "%s%s%s.%d", internal::kPre, name, internal::kExt, ver); 547+#endif 548+ } else { 549+ setFileName(name); 550+ } 551+} 552+bool dso::load() { 553+ handle = load(full_name); 554+ path_from_handle(handle, full_name, sizeof(full_name)); 555+ return !!handle; 556+} 557+bool dso::unload() { 558+ if (!isLoaded()) 559+ return true; 560+ if (!unload(handle)) 561+ return false; 562+ handle = NULL; //TODO: check ref? 563+ return true; 564+} 565+void* dso::load(const char* name) { 566+ CAPI_DBG_LOAD("dso.load: %s", name); 567+#ifdef CAPI_TARGET_OS_WIN 568+#ifdef CAPI_TARGET_OS_WINRT 569+ wchar_t wname[strlen(name)+1]; 570+ CAPI_SNWPRINTF(wname, sizeof(wname), L"%s", name); 571+ return (void*)::LoadPackagedLibrary(wname, 0); 572+#else 573+ return (void*)::LoadLibraryExA(name, NULL, 0); //DONT_RESOLVE_DLL_REFERENCES 574+#endif 575+#else 576+ return ::dlopen(name, RTLD_LAZY|RTLD_LOCAL); // try no prefix name if error? TODO: ios |RTLD_GLOBAL? 577+#endif 578+} 579+bool dso::unload(void* h) { 580+#ifdef CAPI_TARGET_OS_WIN 581+ if (!::FreeLibrary(static_cast<HMODULE>(h))) //return 0 if error. ref counted 582+ return false; 583+#else 584+ if (::dlclose(handle) != 0) //ref counted 585+ return false; 586+#endif 587+ return true; 588+} 589+void* dso::resolve(const char* sym, bool try_) { 590+ const char* s = sym; 591+ char _s[512]; // old a.out systems add an underscore in front of symbols 592+ if (!try_) {//previous has no '_', now has '_' 593+ CAPI_SNPRINTF(_s, sizeof(_s), "_%s", sym); 594+ s = _s; 595+ } 596+ CAPI_DBG_RESOLVE("dso.resolve(\"%s\", %d)", s, try_); 597+#ifdef CAPI_TARGET_OS_WIN 598+ void *ptr = (void*)::GetProcAddress((HMODULE)handle, s); 599+#else 600+ void *ptr = ::dlsym(handle, s); 601+#endif 602+ if (!ptr && try_) 603+ return resolve(sym, false); 604+ return ptr; 605+} 606+ 607+char* dso::path_from_handle(void* handle, char* path, int path_len) 608+{ 609+ if (!handle) 610+ return nullptr;; 611+#if (CAPI_TARGET_OS_WIN+0) 612+ GetModuleFileNameA(HMODULE(handle), path, path_len); 613+#elif defined(__APPLE__) 614+ for (size_t i = _dyld_image_count(); i > 0; --i) { 615+ const char* name = _dyld_get_image_name(i); 616+ void* h = dlopen(name, RTLD_LAZY); 617+ dlclose(h); 618+ if ((ptrdiff_t(handle) - ptrdiff_t(h))>>2 == 0) { 619+ CAPI_SNPRINTF(path, path_len, "%s", name); 620+ break; 621+ } 622+ } 623+#elif (__ANDROID__+0) 624+ // from boost.dll 625+ typedef struct soinfo { 626+ // if defined(__work_around_b_24465209__), then an array of char[128] goes here. 627+ // Unfortunately, __work_around_b_24465209__ is visible only during compilation of Android's linker 628+ const void* phdr; 629+ size_t phnum; 630+ void* entry; 631+ void* base; 632+ // ... // Ignoring remaning parts of the structure 633+ } soinfo; 634+ static const size_t work_around_b_24465209__offset = 128; 635+ Dl_info info; 636+ const soinfo* si = reinterpret_cast<soinfo*>(intptr_t(handle)+work_around_b_24465209__offset); 637+ if (dladdr(si->base, &info)) 638+ CAPI_SNPRINTF(path, path_len, "%s", info.dli_fname); 639+#elif defined(RTLD_DEFAULT) && !defined(__HAIKU__) // check (0+__USE_GNU+__ELF__)? weak dlinfo? // mac, mingw, cygwin has no dlinfo 640+ const link_map* m = static_cast<const link_map*>(handle); 641+# if defined(__FreeBSD__) 642+ if (dlinfo(handle, RTLD_DI_LINKMAP, &m) < 0) 643+ m = NULL; 644+# endif 645+ if (m->l_name && m->l_name[0]) 646+ CAPI_SNPRINTF(path, path_len, "%s", m->l_name); 647+#endif 648+ return path; 649+} 650+} //namespace capi 651+ 652+#if defined(_MSC_VER) 653+#pragma warning(disable:4098) //vc return void 654+#endif //_MSC_VER 655+#ifdef __GNUC__ 656+//gcc: ((T*)0)->member 657+//no #pragma GCC diagnostic push/pop around because code is defined as a macro 658+#pragma GCC diagnostic ignored "-Winvalid-offsetof" 659+#endif 660+/*! 661+ * used by .cpp to define the api 662+ * e.g. CAPI_DEFINE(cl_int, clGetPlatformIDs, "clGetPlatformIDs", CAPI_ARG3(cl_uint, cl_platform_id*, cl_uint*)) 663+ * sym: symbol of the api in library. 664+ * Defines both namespace style and class style. User can choose which one to use at runtime by adding a macro before including the header or not: #define SOMELIB_CAPI_NS 665+ * See test/zlib/zlib_api.h 666+ */ 667+#define CAPI_DEFINE_X(R, name, ARG_T, ARG_T_V, ARG_V) \ 668+ CAPI_DEFINE_T_V(R, name, ARG_T, ARG_T_V, ARG_V) \ 669+ CAPI_NS_DEFINE_T_V(R, name, ARG_T, ARG_T_V, ARG_V) 670+/* declare and define the symbol resolvers*/ 671+#define EMPTY_LINKAGE 672+#define CAPI_DEFINE_RESOLVER_X(R, name, sym, ARG_T, ARG_T_V, ARG_V) CAPI_DEFINE_M_RESOLVER_T_V(R, EMPTY_LINKAGE, name, sym, ARG_T, ARG_T_V, ARG_V) 673+// api with linkage modifier 674+#define CAPI_DEFINE_M_RESOLVER_X(R, M, name, sym, ARG_T, ARG_T_V, ARG_V) CAPI_DEFINE_M_RESOLVER_T_V(R, M, name, sym, ARG_T, ARG_T_V, ARG_V) 675+ 676+#define CAPI_DEFINE2_X(R, name, sym, ARG_T, ARG_T_V, ARG_V) \ 677+ CAPI_DEFINE2_T_V(R, name, sym, ARG_T, ARG_T_V, ARG_V) \ 678+ CAPI_NS_DEFINE2_T_V(R, name, sym, ARG_T, ARG_T_V, ARG_V) 679+#define CAPI_DEFINE_ENTRY_X(R, name, sym, ARG_T, ARG_T_V, ARG_V) CAPI_DEFINE_M_ENTRY_X(R, EMPTY_LINKAGE, name, sym, ARG_T, ARG_T_V, ARG_V) 680+#define CAPI_DEFINE_M_ENTRY_X(R, M, sym, name, ARG_T, ARG_T_V, ARG_V) typedef R (M *name##_t) ARG_T; name##_t name; 681+ 682+#define CAPI_ARG0() (), (), () 683+#define CAPI_ARG1(P1) (P1), (P1 p1), (p1) 684+#define CAPI_ARG2(P1, P2) (P1, P2), (P1 p1, P2 p2), (p1, p2) 685+#define CAPI_ARG3(P1, P2, P3) (P1, P2, P3), (P1 p1, P2 p2, P3 p3), (p1, p2, p3) 686+#define CAPI_ARG4(P1, P2, P3, P4) (P1, P2, P3, P4), (P1 p1, P2 p2, P3 p3, P4 p4), (p1, p2, p3, p4) 687+#define CAPI_ARG5(P1, P2, P3, P4, P5) (P1, P2, P3, P4, P5), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5), (p1, p2, p3, p4, p5) 688+#define CAPI_ARG6(P1, P2, P3, P4, P5, P6) (P1, P2, P3, P4, P5, P6), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6), (p1, p2, p3, p4, p5, p6) 689+#define CAPI_ARG7(P1, P2, P3, P4, P5, P6, P7) (P1, P2, P3, P4, P5, P6, P7), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7), (p1, p2, p3, p4, p5, p6, p7) 690+#define CAPI_ARG8(P1, P2, P3, P4, P5, P6, P7, P8) (P1, P2, P3, P4, P5, P6, P7, P8), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8), (p1, p2, p3, p4, p5, p6, p7, p8) 691+#define CAPI_ARG9(P1, P2, P3, P4, P5, P6, P7, P8, P9) (P1, P2, P3, P4, P5, P6, P7, P8, P9), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9), (p1, p2, p3, p4, p5, p6, p7, p8, p9) 692+#define CAPI_ARG10(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) 693+#define CAPI_ARG11(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) 694+#define CAPI_ARG12(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) 695+#define CAPI_ARG13(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13), (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12, P13 p13), (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13) 696+ 697+#endif // CAPI_H 698-- 6992.21.0 700 701 702From 288576ecf68eae240ce3348e17072ef297837db2 Mon Sep 17 00:00:00 2001 703From: Gerasim Troeglazov <3dEyes@gmail.com> 704Date: Wed, 1 May 2019 21:45:39 +1000 705Subject: Install path for Haiku 706 707 708diff --git a/CMakeLists.txt b/CMakeLists.txt 709index 11f8603..77826ca 100644 710--- a/CMakeLists.txt 711+++ b/CMakeLists.txt 712@@ -77,6 +77,14 @@ else() 713 set(QTAV_INSTALL_QML ${QT_INSTALL_QML}) 714 endif() 715 716+if(HAIKU) 717+ set(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "default install path" FORCE) 718+ set(QTAV_INSTALL_HEADERS ${CMAKE_INSTALL_HEADERS}) 719+ set(QTAV_INSTALL_LIBS ${CMAKE_INSTALL_LIBS}) 720+ set(QTAV_INSTALL_BINS ${CMAKE_INSTALL_BINS}) 721+ set(QTAV_INSTALL_QML ${CMAKE_INSTALL_QML}) 722+endif() 723+ 724 message(STATUS "Qt version: ${Qt5Core_VERSION_STRING}") 725 message(STATUS "Qt prefix: ${QT_INSTALL_PREFIX}") 726 message(STATUS "QtAV headers prefix: ${QTAV_INSTALL_HEADERS}") 727-- 7282.21.0 729 730