<div dir="ltr">I never said the opposite.<br>I listened to your advice, you are right. there was never any question of having a logging instance for each thread, but the object makes it possible to have a link between the threads.<br><br>the logging is not based on an instance but on a static class.<br><br>I have nothing to hide, I show you my code, as you can see, there is never any mention of an object in the code.<div><br></div><div>the question is just how to call code at the end of ffmpeg's worker thread.<br><br>because in the code in c to call java it is necessary.<br><br>1/ attach the c thread to the java thread<br>                 <b>res =(*javaVM)->AttachCurrentThreadAsDaemon(javaVM, (void**)&jniEnv, NULL);  </b><br>2/ make your code, your blah blah<br><br>3/ at the closure of the thread in c, detach the java thread<br><div><pre class="gmail-line-numbers gmail-language-cpp" style="box-sizing:border-box;overflow:auto;font-family:Consolas,Monaco,"andale mono","ubuntu mono",monospace;font-size:14px;border:none;border-radius:0px;margin-top:0px;margin-bottom:0px;background:0px 0px;color:rgb(0,0,0);word-break:normal;line-height:1.5;padding:1em 1em 1em 3.8em;font-weight:700"><b style="font-family:Arial,Helvetica,sans-serif;font-size:small;color:rgb(34,34,34)">(*javaVM)-></b>DetachCurrentThread(<b style="font-family:Arial,Helvetica,sans-serif;font-size:small;color:rgb(34,34,34)">javaVM</b>);</pre></div><div><br></div><div><br></div><div>don't see evil everywhere, I asked a question, I heard your advice, I followed it<br><br>Cordially<br></div><div><br></div><div><br></div><div><b>#include <jni.h><br>#include <libavdevice/avdevice.h><br><br>#include <pthread.h><br><br>#define LOGGER_CLASS "fr/ms/ffmpeg/FFMPEG_LOG"<br>#define THREAD_FFMPEG_WORKER "FFMPEG-Worker-%i"<br><br>JavaVM *javaVM;<br><br>__thread JNIEnv *jniEnv;<br><br>jclass clazzLogger;<br>jmethodID jMethodGetLogLevel;<br>jmethodID jMethodGetLogLevelValue;<br><br>jmethodID callLoggerMethod;<br><br>int compteur = 0;<br><br>int init_JNI() {<br>      if (jniEnv == NULL) {<br>         int res = (*javaVM)->GetEnv(javaVM, (void**)&jniEnv, JNI_VERSION_1_8);<br>         if (res == JNI_EDETACHED) {<br>                   JavaVMAttachArgs args;<br>                        args.version = JNI_VERSION_1_8;<br>                       <a href="http://args.name">args.name</a> = malloc(128);<br>                 sprintf(<a href="http://args.name">args.name</a>, THREAD_FFMPEG_WORKER, compteur);<br>                      res =(*javaVM)->AttachCurrentThreadAsDaemon(javaVM, (void**)&jniEnv, NULL);<br>                    if (res != JNI_OK) {<br>                          return res;<br>                   }<br>                     compteur++;<br>           }<br>     }<br>     return JNI_OK;<br>}<br><br>void wrapper_logger(void *ptr, int level, const char* fmt, va_list vl){<br>  if (init_JNI() != JNI_OK) {<br>           return;<br>       }<br><br>   jobject enumObjLogLevel = (*jniEnv)->CallStaticObjectMethod(jniEnv, clazzLogger, jMethodGetLogLevel);<br><br>    if ((*jniEnv)->ExceptionOccurred(jniEnv)) {<br>                (*jniEnv)->ExceptionClear(jniEnv);<br>         (*jniEnv)->DeleteLocalRef(jniEnv, enumObjLogLevel);<br>                return;<br>       }<br><br>   int av_level = (int) (*jniEnv)->CallIntMethod(jniEnv, enumObjLogLevel, jMethodGetLogLevelValue);<br>   (*jniEnv)->DeleteLocalRef(jniEnv, enumObjLogLevel);<br>        if ((*jniEnv)->ExceptionOccurred(jniEnv)) {<br>                (*jniEnv)->ExceptionClear(jniEnv);<br>         return;<br>       }<br><br>   if (level > av_level)<br>              return;<br><br>     char buffer[1024];<br><br>  int res = vsprintf(buffer, fmt, vl);<br><br>         if (res < 0)<br>              return;<br><br>     jstring jstr = (*jniEnv)->NewStringUTF(jniEnv, buffer);<br>    if (jstr != NULL) {<br>           (*jniEnv)->CallStaticVoidMethod(jniEnv, clazzLogger, callLoggerMethod, level, jstr);<br>               (*jniEnv)->DeleteLocalRef(jniEnv, jstr);<br>           if ((*jniEnv)->ExceptionOccurred(jniEnv)) {<br>                        (*jniEnv)->ExceptionClear(jniEnv);<br>                 return;<br>               }<br>     }<br>}<br><br>int init_logger() {<br>   clazzLogger = (*jniEnv)->FindClass(jniEnv, LOGGER_CLASS);<br>  clazzLogger = (*jniEnv)->NewGlobalRef(jniEnv,clazzLogger);<br> jMethodGetLogLevel = (*jniEnv)->GetStaticMethodID(jniEnv, clazzLogger, "getLogLevel", "()Lfr/ms/ffmpeg/FFMPEG_AV_LOG;");<br>       jobject enumObjLogLevel = (*jniEnv)->CallStaticObjectMethod(jniEnv, clazzLogger, jMethodGetLogLevel);<br>      jthrowable exc = (*jniEnv)->ExceptionOccurred(jniEnv);<br>     if (exc) {<br>            (*jniEnv)->ExceptionClear(jniEnv);<br>         return -1;<br>    }<br>     jclass enumClass = (*jniEnv)->GetObjectClass(jniEnv, enumObjLogLevel);<br>     jMethodGetLogLevelValue = (*jniEnv)->GetMethodID(jniEnv, enumClass, "getValue", "()I");<br>        int av_level = (int) (*jniEnv)->CallIntMethod(jniEnv, enumObjLogLevel, jMethodGetLogLevelValue);<br><br> exc = (*jniEnv)->ExceptionOccurred(jniEnv);<br>        if (exc) {<br>            (*jniEnv)->ExceptionClear(jniEnv);<br>         return -1;<br>    }<br><br>   callLoggerMethod = (*jniEnv)->GetStaticMethodID(jniEnv, clazzLogger, "callLogger0", "(ILjava/lang/String;)V");<br><br>       return JNI_OK;<br>}<br><br>jint JNI_OnLoad(JavaVM *vm, void *reserved) {<br>    javaVM = vm;<br><br>        if ((*vm)->GetEnv(vm, (void**)&jniEnv, JNI_VERSION_1_8) != JNI_OK)<br>             return -1;<br><br>  if (init_logger() != JNI_OK)<br>          return -1;<br><br>  av_log_set_callback(wrapper_logger);<br><br>        avdevice_register_all();<br>      avformat_network_init();<br><br>    return JNI_VERSION_1_8;<br>}<br><br>void JNI_OnUnload(JavaVM *vm, void *reserved) {<br> (*jniEnv)->DeleteLocalRef(jniEnv, clazzLogger);<br>}</b><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le jeu. 24 mars 2022 à 15:55, Dan Egnor <<a href="mailto:egnor@ofb.net">egnor@ofb.net</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 24, 2022, 3:59 AM Algarve Branqueira <<a href="mailto:branqueira@gmail.com" target="_blank">branqueira@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I tried this method but it doesn't work with ffmpeg on windows with mingw.<br>I must have forgotten a few things.<br><br> what disturbs me the most is that at the end of the video conversion, ffmpeg kills its threads for decoding and encoding but we don't have a simple solution to execute an end method.<br><br>I attached the jvm so I basically need to destroy the thread called a simple "DetachCurrentThread" method.<br><div><br></div><div>Any idea :)</div></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">As you know, my best idea is to rethink your life choices and not try to get log messages attributed to specific instances, instead treating them as a single global stream used for developer diagnostics. I think you're swimming against the flow trying to do anything else.</div><div dir="auto"><br></div><div dir="auto">But I don't think you'll find this helpful?</div><div dir="auto"><br></div><div dir="auto">-- egnor</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
</blockquote></div></div></div>
_______________________________________________<br>
Libav-user mailing list<br>
<a href="mailto:Libav-user@ffmpeg.org" target="_blank">Libav-user@ffmpeg.org</a><br>
<a href="https://ffmpeg.org/mailman/listinfo/libav-user" rel="noreferrer" target="_blank">https://ffmpeg.org/mailman/listinfo/libav-user</a><br>
<br>
To unsubscribe, visit link above, or email<br>
<a href="mailto:libav-user-request@ffmpeg.org" target="_blank">libav-user-request@ffmpeg.org</a> with subject "unsubscribe".<br>
</blockquote></div>