AVPKit
Global.cpp
1 /*******************************************************************************
2  * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved.
3  *
4  * This file is part of AVPKit.
5  *
6  * AVPKit is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * AVPKit is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with AVPKit. If not, see <http://www.gnu.org/licenses/>.
18  *******************************************************************************/
19 
20 #include <cmath>
21 #include <cstring>
22 
23 #include <com/avpkit/ferry/JNIHelper.h>
24 #include <com/avpkit/ferry/Logger.h>
25 #include <com/avpkit/ferry/Mutex.h>
26 
27 
28 #include <com/avpkit/core/Global.h>
29 #include <com/avpkit/core/FfmpegIncludes.h>
30 #include <com/avpkit/core/Container.h>
31 #include <com/avpkit/core/ContainerFormat.h>
32 #include <com/avpkit/core/Codec.h>
33 #include <com/avpkit/core/Rational.h>
34 #include <com/avpkit/core/AudioSamples.h>
35 #include <com/avpkit/core/VideoPicture.h>
36 #include <com/avpkit/core/AudioResampler.h>
37 #include <com/avpkit/core/VideoResampler.h>
38 #include <com/avpkit/core/MediaDataWrapper.h>
39 #include <com/avpkit/core/config.h>
40 
50 namespace com { namespace avpkit { namespace core
51 {
52  using namespace com::avpkit::ferry;
53 
54  /*
55  * This function will be called back by Ffmpeg anytime
56  * it wants to log. We then use it to dump
57  * stuff into our own logs.
58  */
59  static void
60  core_log_callback(void* ptr, int level, const char* fmt, va_list va)
61  {
62  static Logger* ffmpegLogger = 0;
63  AVClass* avc = ptr ? *(AVClass**)ptr : 0;
64 
65  int currentLevel = av_log_get_level();
66 // fprintf(stderr, "current level: %d; log level: %d\n", level, currentLevel);
67  if (level > currentLevel || currentLevel < AV_LOG_PANIC)
68  // just return
69  return;
70 
71  if (!ffmpegLogger)
72  {
73  Global::lock();
74  if (!ffmpegLogger)
75  ffmpegLogger = Logger::getStaticLogger( "org.ffmpeg" );
77  }
78 
79  Logger::Level logLevel;
80  if (level <= AV_LOG_ERROR)
81  logLevel = Logger::LEVEL_ERROR;
82  else if (level <= AV_LOG_WARNING)
83  logLevel = Logger::LEVEL_WARN;
84  else if (level <= AV_LOG_INFO)
85  logLevel = Logger::LEVEL_INFO;
86  else if (level <= AV_LOG_DEBUG)
87  logLevel = Logger::LEVEL_DEBUG;
88  else
89  logLevel = Logger::LEVEL_TRACE;
90 
91  // Revise the format string to add additional useful info
92  char revisedFmt[1024];
93  revisedFmt[sizeof(revisedFmt)-1] = 0;
94  if (avc)
95  {
96  snprintf(revisedFmt, sizeof(revisedFmt), "[%s @ %p] %s",
97  avc->item_name(ptr), ptr, fmt);
98  }
99  else
100  {
101  snprintf(revisedFmt, sizeof(revisedFmt), "%s", fmt);
102  }
103  int len = strlen(revisedFmt);
104  if (len > 0 && revisedFmt[len-1] == '\n')
105  {
106  revisedFmt[len-1]=0;
107  --len;
108  }
109  if (len > 0)
110  // it's not useful to pass in filenames and line numbers here.
111  ffmpegLogger->logVA(0, 0, logLevel, revisedFmt, va);
112  }
113 
114  int
116  {
117  JNIHelper* helper = JNIHelper::getHelper();
118  int retval = 0;
119  if (helper) {
120  retval = helper->isInterrupted();
121  }
122  return retval;
123  }
124 
125  static int core_lockmgr_cb(void** ctx, enum AVLockOp op)
126  {
127  if (!ctx)
128  return 1;
129 
130  int retval=0;
132  static_cast<com::avpkit::ferry::Mutex*>(*ctx);
133  switch(op)
134  {
135  case AV_LOCK_CREATE:
136  mutex = com::avpkit::ferry::Mutex::make();
137  *ctx = mutex;
138  retval = !mutex;
139  break;
140  case AV_LOCK_DESTROY:
141  if (mutex) mutex->release();
142  *ctx = 0;
143  break;
144  case AV_LOCK_OBTAIN:
145  if (mutex) mutex->lock();
146  break;
147  case AV_LOCK_RELEASE:
148  if (mutex) mutex->unlock();
149  break;
150  }
151  return retval;
152  }
153 
154  Global* Global :: sGlobal = 0;
155 
156  void
158  {
159  if (!sGlobal)
160  {
161  av_lockmgr_register(core_lockmgr_cb);
162  av_log_set_callback(core_log_callback);
163  av_log_set_level(AV_LOG_ERROR); // Only log errors by default
164  av_register_all();
165  avformat_network_init();
166  // and set up filter support
167  avfilter_register_all();
168 
169  // and set up the device library for webcam support
170  avdevice_register_all();
171 
172  // turn down logging
173  sGlobal = new Global();
174  }
175  }
176  void
178  {
179  avformat_network_deinit();
180  }
181 
182  void
183  Global :: destroyStaticGlobal(JavaVM*vm,void*closure)
184  {
185  Global *val = (Global*)closure;
186  if (!vm && val) {
187  av_lockmgr_register(0);
188  delete val;
189  }
190  }
191 
192  Global :: Global()
193  {
194  com::avpkit::ferry::JNIHelper::sRegisterTerminationCallback(
195  Global::destroyStaticGlobal,
196  this);
197  mLock = com::avpkit::ferry::Mutex::make();
198  }
199 
200  Global :: ~Global()
201  {
202  if (mLock)
203  mLock->release();
204  }
205 
206  void
208  {
209  Global::init();
210  if (sGlobal && sGlobal->mLock)
211  sGlobal->mLock->lock();
212  }
213 
214  void
216  {
217  Global::init();
218  if (sGlobal && sGlobal->mLock)
219  sGlobal->mLock->unlock();
220  }
221 
222  int64_t
224  {
225  return ((int64_t)getVersionMajor())<<48 | ((int64_t)getVersionMinor())<<32 | (int64_t)getVersionRevision();
226  }
227  int32_t
229  {
230  Global::init();
231  return VS_LIB_MAJOR_VERSION;
232  }
233  int32_t
235  {
236  Global::init();
237  return VS_LIB_MINOR_VERSION;
238  }
239  int32_t
241  {
242  Global::init();
243  return VS_REVISION;
244  }
245 
246  const char *
248  {
249  Global::init();
250  return PACKAGE_VERSION "." VS_STRINGIFY(VS_REVISION);
251  }
252  int32_t
254  {
255  Global::init();
256  return LIBAVFORMAT_VERSION_INT;
257  }
258  const char *
260  {
261  Global::init();
262  return AV_STRINGIFY(LIBAVFORMAT_VERSION);
263  }
264  int
266  {
267  Global::init();
268  return LIBAVCODEC_VERSION_INT;
269  }
270  const char *
272  {
273  Global::init();
274  return AV_STRINGIFY(LIBAVCODEC_VERSION);
275  }
276 
277  void
279  {
280  Global::init();
281  if (level < AV_LOG_PANIC)
282  av_log_set_level(AV_LOG_QUIET);
283  else if (level < AV_LOG_FATAL)
284  av_log_set_level(AV_LOG_PANIC);
285  else if (level < AV_LOG_ERROR)
286  av_log_set_level(AV_LOG_FATAL);
287  else if (level < AV_LOG_WARNING)
288  av_log_set_level(AV_LOG_ERROR);
289  else if (level < AV_LOG_INFO)
290  av_log_set_level(AV_LOG_WARNING);
291  else if (level < AV_LOG_VERBOSE)
292  av_log_set_level(AV_LOG_INFO);
293  else if (level < AV_LOG_DEBUG)
294  av_log_set_level(AV_LOG_VERBOSE);
295  else
296  av_log_set_level(AV_LOG_DEBUG);
297 // fprintf(stderr, "FFmpeg logging level = %d\n", av_log_get_level());
298  }
299 }}}
A collection of static functions that refer to the entire package (like version getters).
Definition: Global.h:43
static int avioInterruptCB(void *)
Internal Only.
Definition: Global.cpp:115
static void deinit()
Internal Only.
Definition: Global.cpp:177
static void unlock()
Unlock the global lock.
Definition: Global.cpp:215
static const char * getVersionStr()
Get a string representation of the version of this library.
Definition: Global.cpp:247
static const char * getAVCodecVersionStr()
Get the version of the FFMPEG libavcodec library we are compiled against.
Definition: Global.cpp:271
static const char * getAVFormatVersionStr()
Get the version of the FFMPEG libavformat library we are compiled against.
Definition: Global.cpp:259
static int32_t getVersionRevision()
Get the revision number of this library.
Definition: Global.cpp:240
static int32_t getVersionMinor()
Get the minor version number of this library.
Definition: Global.cpp:234
static int64_t getVersion()
Returns a 64 bit version number for this library.
Definition: Global.cpp:223
static void setFFmpegLoggingLevel(int32_t level)
Internal Only.
Definition: Global.cpp:278
static int getAVCodecVersion()
Get the version of the FFMPEG libavcodec library we are compiled against.
Definition: Global.cpp:265
static void init()
Internal Only.
Definition: Global.cpp:157
static void lock()
Performs a global-level lock of the AVPKIT library.
Definition: Global.cpp:207
static int getAVFormatVersion()
Get the version of the FFMPEG libavformat library we are compiled against.
Definition: Global.cpp:253
static int32_t getVersionMajor()
Get the major version number of this library.
Definition: Global.cpp:228
The JNIHelper object contains a series of methods designed to assist functions when running inside a ...
Definition: JNIHelper.h:37
Internal Only.
Definition: Logger.h:48
static Logger * getStaticLogger(const char *aLoggerName)
Get a Logger object, but ask the Logger code to free it up once the JavaVM shuts down.
Definition: Logger.cpp:177
Level
Different logging levels (noiseness) supported by us.
Definition: Logger.h:54
Internal Only.
Definition: Mutex.h:41
virtual int32_t release()
Internal Only.
Definition: RefCounted.cpp:70
This library contains routines used by AVPKit libraries for "ferry"ing Java objects to and from nativ...
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...