[Libav-user] variable scope into callback av_log_set_callback and multi threading

Algarve Branqueira branqueira at gmail.com
Mon Mar 14 11:35:15 EET 2022


Hello,

I describe my application quickly before talking about my problem.

For more than a year, my application has been running very well for a
client.
It is a web application which displays on an html page with different
cameras.
It is a Java application that makes a JNI call for each camera.
The C code connects using the rtsp protocol to the different cameras and
the ffmpeg library converts the rtsp stream to mpeg1.
The mpeg1 data is uploaded on the Java side and then various things are
done to  use a JavaScript library to display the video.

This works perfectly and the instance has been running on a raspberry for
over a year.

Now I would like to activate multi-threading on decoding and encoding, it
works well except when I want to use my own logger.

Let me explain.

In my code, I use:

            *av_log_set_callback*

This allows me to retrieve messages from the ffmpeg to java side with log4j.
So far no problem.
But if we take the doc, we see this:

The callback must be thread safe, even if the application does not use
threads itself as some codecs are multithreaded.

Unfortunately in the callback code, I use JNI methods, for example:

            * (*jniEnv)->CallVoidMethod(jniEnv, jobj, callLoggerMethod,
level, jstr);*

I explain little for those who don't know JNI (I'm on ffmpeg forum and not
Java :))
To call this method, I must already have the following 2 objects jniEnv and
jobj.
These 2 variables are obtained at the time of the input call in c, example:

               *JNIEXPORT void JNICALL
Java_ffmpeg_RTSPToMPEG1_rtspToFfmpeg0 (JNIEnv *env, jobject obj)*

It is in this method that all processing for decoding and encoding video.

The difficulty is that the callback signature of the logger is as follows:

              *  void wrapper_logger(void *ptr, int level, const char* fmt,
va_list vl)*

I therefore no longer have the JNIEnv *env variable (this is not a problem
because i can recover it otherwise) but it is above all that I no longer
have the obj variable.

For the moment in mono thread on the decoding and the encoding, I kept it
in a variable thread local storage, example:









*__thread JNIEnv *jniEnv;                   __thread jobject jobj;
         JNIEXPORT void JNICALL Java_fr_ms_ffmpeg_RTSPToMPEG1_rtspToFfmpeg0
(JNIEnv *env, jobject obj) {                            jniEnv = env;
                      jobj = obj;                            ...
               etc..*

And like that I use the 2 variables without problems.


Of course someone can tell me why I am not using a global variable but that
is not possible, there is not only one call to the method
"Java_fr_ms_ffmpeg_RTSPToMPEG1_rtspToFfmpeg0"

But x calls for x cameras in the same instance.


So my question is this,

How can I in the callback method (for me wrapper_logger) retrieve the
"jobj" variable (make it any variable of the main method) when the decoder
or the encoder is in another thread?
I hope I explained my problem well.

Thanks,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20220314/0f00c1f8/attachment.htm>


More information about the Libav-user mailing list