File ffmpeg-dlopen-openh264.patch of Package ffmpeg-7

355
 
1
From 4739b0c97b3378bdaf737171777fe9a71a53eff1 Mon Sep 17 00:00:00 2001
2
From: Neal Gompa <ngompa@fedoraproject.org>
3
Date: Wed, 12 Oct 2022 09:41:27 -0400
4
Subject: [PATCH] avcodec/openh264: Add the ability to dlopen() OpenH264
5
6
We can't directly depend on OpenH264, but we can weakly link to it
7
and gracefully expose the capability.
8
9
Co-authored-by: Andreas Schneider <asn@cryptomilk.org>
10
Co-authored-by: Neal Gompa <ngompa@fedoraproject.org>
11
12
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
13
Signed-off-by: Neal Gompa <ngompa@fedoraproject.org>
14
---
15
 configure                       |    3 
16
 libavcodec/Makefile             |    1 
17
 libavcodec/libopenh264.c        |    5 +
18
 libavcodec/libopenh264_dlopen.c |  147 ++++++++++++++++++++++++++++++++++++++++
19
 libavcodec/libopenh264_dlopen.h |   58 +++++++++++++++
20
 libavcodec/libopenh264dec.c     |    8 ++
21
 libavcodec/libopenh264enc.c     |    8 ++
22
 7 files changed, 230 insertions(+)
23
 create mode 100644 libavcodec/libopenh264_dlopen.c
24
 create mode 100644 libavcodec/libopenh264_dlopen.h
25
26
Index: ffmpeg-7.1/configure
27
===================================================================
28
--- ffmpeg-7.1.orig/configure
29
+++ ffmpeg-7.1/configure
30
@@ -255,6 +255,7 @@ External library support:
31
   --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
32
   --enable-libopencv       enable video filtering via libopencv [no]
33
   --enable-libopenh264     enable H.264 encoding via OpenH264 [no]
34
+  --enable-libopenh264-dlopen  enable H.264 encoding via dlopen()'ed OpenH264 [no]
35
   --enable-libopenjpeg     enable JPEG 2000 encoding via OpenJPEG [no]
36
   --enable-libopenmpt      enable decoding tracked files via libopenmpt [no]
37
   --enable-libopenvino     enable OpenVINO as a DNN module backend
38
@@ -1939,6 +1940,7 @@ EXTERNAL_LIBRARY_LIST="
39
     libmysofa
40
     libopencv
41
     libopenh264
42
+    libopenh264_dlopen
43
     libopenjpeg
44
     libopenmpt
45
     libopenvino
46
@@ -6966,6 +6968,7 @@ enabled libopencv         && { check_hea
47
                                  require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } ||
48
                                require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; }
49
 enabled libopenh264       && require_pkg_config libopenh264 "openh264 >= 1.3.0" wels/codec_api.h WelsGetCodecVersion
50
+enabled libopenh264_dlopen && enable libopenh264 && add_cppflags "-I$(dirname $(readlink -f "$0"))/ffdlopenhdrs/include -DCONFIG_LIBOPENH264_DLOPEN=1"
51
 enabled libopenjpeg       && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version ||
52
                                { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } }
53
 enabled libopenmpt        && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++"
54
Index: ffmpeg-7.1/libavcodec/Makefile
55
===================================================================
56
--- ffmpeg-7.1.orig/libavcodec/Makefile
57
+++ ffmpeg-7.1/libavcodec/Makefile
58
@@ -1138,6 +1138,7 @@ OBJS-$(CONFIG_LIBMP3LAME_ENCODER)
59
 OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER)  += libopencore-amr.o
60
 OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER)  += libopencore-amr.o
61
 OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER)  += libopencore-amr.o
62
+OBJS-$(CONFIG_LIBOPENH264_DLOPEN)         += libopenh264_dlopen.o
63
 OBJS-$(CONFIG_LIBOPENH264_DECODER)        += libopenh264dec.o libopenh264.o
64
 OBJS-$(CONFIG_LIBOPENH264_ENCODER)        += libopenh264enc.o libopenh264.o
65
 OBJS-$(CONFIG_LIBOPENJPEG_ENCODER)        += libopenjpegenc.o
66
Index: ffmpeg-7.1/libavcodec/libopenh264.c
67
===================================================================
68
--- ffmpeg-7.1.orig/libavcodec/libopenh264.c
69
+++ ffmpeg-7.1/libavcodec/libopenh264.c
70
@@ -20,8 +20,13 @@
71
  */
72
 
73
 #include <string.h>
74
+
75
+#ifdef CONFIG_LIBOPENH264_DLOPEN
76
+#include "libopenh264_dlopen.h"
77
+#else
78
 #include <wels/codec_api.h>
79
 #include <wels/codec_ver.h>
80
+#endif
81
 
82
 #include "libavutil/error.h"
83
 #include "libavutil/log.h"
84
Index: ffmpeg-7.1/libavcodec/libopenh264_dlopen.c
85
===================================================================
86
--- /dev/null
87
+++ ffmpeg-7.1/libavcodec/libopenh264_dlopen.c
88
@@ -0,0 +1,147 @@
89
+/*
90
+ * OpenH264 dlopen code
91
+ *
92
+ * Copyright (C) 2022 Andreas Schneider <asn@cryptomilk.org>
93
+ *
94
+ * This file is part of FFmpeg.
95
+ *
96
+ * FFmpeg is free software; you can redistribute it and/or
97
+ * modify it under the terms of the GNU Lesser General Public
98
+ * License as published by the Free Software Foundation; either
99
+ * version 2.1 of the License, or (at your option) any later version.
100
+ *
101
+ * FFmpeg is distributed in the hope that it will be useful,
102
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
103
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
104
+ * Lesser General Public License for more details.
105
+ *
106
+ * You should have received a copy of the GNU Lesser General Public
107
+ * License along with FFmpeg; if not, write to the Free Software
108
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
109
+ */
110
+
111
+#include <dlfcn.h>
112
+
113
+#include "libopenh264_dlopen.h"
114
+
115
+/*
116
+ * The symbol binding makes sure we do not run into strict aliasing issues which
117
+ * can lead into segfaults.
118
+ */
119
+typedef int (*__oh264_WelsCreateSVCEncoder)(ISVCEncoder **);
120
+typedef void (*__oh264_WelsDestroySVCEncoder)(ISVCEncoder *);
121
+typedef int (*__oh264_WelsGetDecoderCapability)(SDecoderCapability *);
122
+typedef long (*__oh264_WelsCreateDecoder)(ISVCDecoder **);
123
+typedef void (*__oh264_WelsDestroyDecoder)(ISVCDecoder *);
124
+typedef OpenH264Version (*__oh264_WelsGetCodecVersion)(void);
125
+typedef void (*__oh264_WelsGetCodecVersionEx)(OpenH264Version *);
126
+
127
+#define OH264_SYMBOL_ENTRY(i)                                                  \
128
+  union {                                                                      \
129
+    __oh264_##i f;                                                             \
130
+    void *obj;                                                                 \
131
+  } _oh264_##i
132
+
133
+struct oh264_symbols {
134
+  OH264_SYMBOL_ENTRY(WelsCreateSVCEncoder);
135
+  OH264_SYMBOL_ENTRY(WelsDestroySVCEncoder);
136
+  OH264_SYMBOL_ENTRY(WelsGetDecoderCapability);
137
+  OH264_SYMBOL_ENTRY(WelsCreateDecoder);
138
+  OH264_SYMBOL_ENTRY(WelsDestroyDecoder);
139
+  OH264_SYMBOL_ENTRY(WelsGetCodecVersion);
140
+  OH264_SYMBOL_ENTRY(WelsGetCodecVersionEx);
141
+};
142
+
143
+/* Symbols are bound by loadLibOpenH264() */
144
+static struct oh264_symbols openh264_symbols;
145
+
146
+int oh264_WelsCreateSVCEncoder(ISVCEncoder **ppEncoder) {
147
+  return openh264_symbols._oh264_WelsCreateSVCEncoder.f(ppEncoder);
148
+}
149
+
150
+void oh264_WelsDestroySVCEncoder(ISVCEncoder *pEncoder) {
151
+  return openh264_symbols._oh264_WelsDestroySVCEncoder.f(pEncoder);
152
+}
153
+
154
+int oh264_WelsGetDecoderCapability(SDecoderCapability *pDecCapability) {
155
+  return openh264_symbols._oh264_WelsGetDecoderCapability.f(pDecCapability);
156
+}
157
+
158
+long oh264_WelsCreateDecoder(ISVCDecoder **ppDecoder) {
159
+  return openh264_symbols._oh264_WelsCreateDecoder.f(ppDecoder);
160
+}
161
+
162
+void oh264_WelsDestroyDecoder(ISVCDecoder *pDecoder) {
163
+  return openh264_symbols._oh264_WelsDestroyDecoder.f(pDecoder);
164
+}
165
+
166
+OpenH264Version oh264_WelsGetCodecVersion(void) {
167
+  return openh264_symbols._oh264_WelsGetCodecVersion.f();
168
+}
169
+
170
+void oh264_WelsGetCodecVersionEx(OpenH264Version *pVersion) {
171
+  openh264_symbols._oh264_WelsGetCodecVersionEx.f(pVersion);
172
+}
173
+
174
+static void *_oh264_bind_symbol(AVCodecContext *avctx,
175
+                                void *handle,
176
+                                const char *sym_name) {
177
+    void *sym = NULL;
178
+
179
+    sym = dlsym(handle, sym_name);
180
+    if (sym == NULL) {
181
+        const char *err = dlerror();
182
+        av_log(avctx,
183
+               AV_LOG_WARNING,
184
+               "%s: Failed to bind %s\n",
185
+               err,
186
+               sym_name);
187
+        return NULL;
188
+    }
189
+
190
+    return sym;
191
+}
192
+
193
+#define oh264_bind_symbol(avctx, handle, sym_name)                           \
194
+  if (openh264_symbols._oh264_##sym_name.obj == NULL) {                      \
195
+    openh264_symbols._oh264_##sym_name.obj = _oh264_bind_symbol(avctx, handle, #sym_name); \
196
+    if (openh264_symbols._oh264_##sym_name.obj == NULL) {                    \
197
+      return 1;                                                              \
198
+    }                                                                        \
199
+  }
200
+
201
+int loadLibOpenH264(AVCodecContext *avctx) {
202
+  static bool initialized = false;
203
+  void *libopenh264 = NULL;
204
+  const char *err = NULL;
205
+
206
+  if (initialized) {
207
+      return 0;
208
+  }
209
+
210
+#define OPENH264_LIB "libopenh264.so.7"
211
+  libopenh264 = dlopen(OPENH264_LIB, RTLD_LAZY);
212
+  err = dlerror();
213
+  if (err != NULL) {
214
+    av_log(avctx, AV_LOG_WARNING,
215
+           "%s: %s is missing, openh264 support will be disabled\n", err,
216
+           OPENH264_LIB);
217
+
218
+    if (libopenh264 != NULL) {
219
+      dlclose(libopenh264);
220
+    }
221
+    return 1;
222
+  }
223
+
224
+  oh264_bind_symbol(avctx, libopenh264, WelsCreateSVCEncoder);
225
+  oh264_bind_symbol(avctx, libopenh264, WelsDestroySVCEncoder);
226
+  oh264_bind_symbol(avctx, libopenh264, WelsGetDecoderCapability);
227
+  oh264_bind_symbol(avctx, libopenh264, WelsCreateDecoder);
228
+  oh264_bind_symbol(avctx, libopenh264, WelsDestroyDecoder);
229
+  oh264_bind_symbol(avctx, libopenh264, WelsGetCodecVersion);
230
+  oh264_bind_symbol(avctx, libopenh264, WelsGetCodecVersionEx);
231
+
232
+  initialized = true;
233
+
234
+  return 0;
235
+}
236
Index: ffmpeg-7.1/libavcodec/libopenh264_dlopen.h
237
===================================================================
238
--- /dev/null
239
+++ ffmpeg-7.1/libavcodec/libopenh264_dlopen.h
240
@@ -0,0 +1,58 @@
241
+/*
242
+ * OpenH264 dlopen code
243
+ *
244
+ * Copyright (C) 2022 Andreas Schneider <asn@cryptomilk.org>
245
+ *
246
+ * This file is part of FFmpeg.
247
+ *
248
+ * FFmpeg is free software; you can redistribute it and/or
249
+ * modify it under the terms of the GNU Lesser General Public
250
+ * License as published by the Free Software Foundation; either
251
+ * version 2.1 of the License, or (at your option) any later version.
252
+ *
253
+ * FFmpeg is distributed in the hope that it will be useful,
254
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
255
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
256
+ * Lesser General Public License for more details.
257
+ *
258
+ * You should have received a copy of the GNU Lesser General Public
259
+ * License along with FFmpeg; if not, write to the Free Software
260
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
261
+ */
262
+
263
+#ifndef HAVE_LIBOPENH264_DLOPEN_H
264
+#define HAVE_LIBOPENH264_DLOPEN_H
265
+
266
+#ifdef CONFIG_LIBOPENH264_DLOPEN
267
+
268
+#include <wels/codec_api.h>
269
+#include <wels/codec_ver.h>
270
+
271
+#include "avcodec.h"
272
+
273
+int oh264_WelsCreateSVCEncoder(ISVCEncoder **ppEncoder);
274
+#define WelsCreateSVCEncoder oh264_WelsCreateSVCEncoder
275
+
276
+void oh264_WelsDestroySVCEncoder(ISVCEncoder *pEncoder);
277
+#define WelsDestroySVCEncoder oh264_WelsDestroySVCEncoder
278
+
279
+int oh264_WelsGetDecoderCapability(SDecoderCapability *pDecCapability);
280
+#define WelsGetDecoderCapability oh264_WelsGetDecoderCapability
281
+
282
+long oh264_WelsCreateDecoder(ISVCDecoder **ppDecoder);
283
+#define WelsCreateDecoder oh264_WelsCreateDecoder
284
+
285
+void oh264_WelsDestroyDecoder(ISVCDecoder *pDecoder);
286
+#define WelsDestroyDecoder oh264_WelsDestroyDecoder
287
+
288
+OpenH264Version oh264_WelsGetCodecVersion(void);
289
+#define WelsGetCodecVersion oh264_WelsGetCodecVersion
290
+
291
+void oh264_WelsGetCodecVersionEx(OpenH264Version *pVersion);
292
+#define WelsGetCodecVersionEx oh264_WelsGetCodecVersionEx
293
+
294
+int loadLibOpenH264(AVCodecContext *avctx);
295
+
296
+#endif /* CONFIG_LIBOPENH264_DLOPEN */
297
+
298
+#endif /* HAVE_LIBOPENH264_DLOPEN_H */
299
Index: ffmpeg-7.1/libavcodec/libopenh264dec.c
300
===================================================================
301
--- ffmpeg-7.1.orig/libavcodec/libopenh264dec.c
302
+++ ffmpeg-7.1/libavcodec/libopenh264dec.c
303
@@ -19,8 +19,12 @@
304
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
305
  */
306
 
307
+#ifdef CONFIG_LIBOPENH264_DLOPEN
308
+#include "libopenh264_dlopen.h"
309
+#else
310
 #include <wels/codec_api.h>
311
 #include <wels/codec_ver.h>
312
+#endif
313
 
314
 #include "libavutil/common.h"
315
 #include "libavutil/fifo.h"
316
@@ -55,6 +59,10 @@ static av_cold int svc_decode_init(AVCod
317
     int log_level;
318
     WelsTraceCallback callback_function;
319
 
320
+#ifdef CONFIG_LIBOPENH264_DLOPEN
321
+    if (loadLibOpenH264(avctx))
322
+         return AVERROR_DECODER_NOT_FOUND;
323
+#endif
324
     if (WelsCreateDecoder(&s->decoder)) {
325
         av_log(avctx, AV_LOG_ERROR, "Unable to create decoder\n");
326
         return AVERROR_UNKNOWN;
327
Index: ffmpeg-7.1/libavcodec/libopenh264enc.c
328
===================================================================
329
--- ffmpeg-7.1.orig/libavcodec/libopenh264enc.c
330
+++ ffmpeg-7.1/libavcodec/libopenh264enc.c
331
@@ -19,8 +19,12 @@
332
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
333
  */
334
 
335
+#ifdef CONFIG_LIBOPENH264_DLOPEN
336
+#include "libopenh264_dlopen.h"
337
+#else
338
 #include <wels/codec_api.h>
339
 #include <wels/codec_ver.h>
340
+#endif
341
 
342
 #include "libavutil/attributes.h"
343
 #include "libavutil/common.h"
344
@@ -114,6 +118,10 @@ static av_cold int svc_encode_init(AVCod
345
     WelsTraceCallback callback_function;
346
     AVCPBProperties *props;
347
 
348
+#ifdef CONFIG_LIBOPENH264_DLOPEN
349
+    if (loadLibOpenH264(avctx))
350
+         return AVERROR_ENCODER_NOT_FOUND;
351
+#endif
352
     if (WelsCreateSVCEncoder(&s->encoder)) {
353
         av_log(avctx, AV_LOG_ERROR, "Unable to create encoder\n");
354
         return AVERROR_UNKNOWN;
355