[FFmpeg-devel] [PATCH 3/5] lavu/jni: add helpers to manage android application contexts
matthieu.bouron at gmail.com
Mon Oct 12 12:07:21 CEST 2015
On Sun, Oct 11, 2015 at 09:13:39AM -0400, Ronald S. Bultje wrote:
> On Fri, Oct 9, 2015 at 12:26 PM, Matthieu Bouron <matthieu.bouron at gmail.com>
> > From: Matthieu Bouron <matthieu.bouron at stupeflix.com>
> > ---
> > libavutil/jni.c | 104
> > +++++++++++++++++++++++++++++++++++++++++++++++
> > libavutil/jni.h | 28 +++++++++++++
> > libavutil/jni_internal.c | 30 ++++++++++++++
> > libavutil/jni_internal.h | 11 +++++
> > 4 files changed, 173 insertions(+)
> (Personal opinion only - applies to this whole patch set), this stuff had
> no place anywhere in libavutil.
> I don't even think it has any place anywhere in libavanything, but
> certainly not in libavutil. Libavdevice _maybe_, and then really only for
> android devices (other systems can have JNI, and you'd be sitting with all
> this stuff and deps in your libav*.so/a which does nothing), but far, far,
> far away from our core APIs. You could accomplish this by having a jni
> dependency in configure which is only enabled when the android context
> subsystem is enabled, so non-android builds are not affected by this.
I agree that only enabling the JNI stuff on the Android would be better as
the end goal for now is to only target the Android platform.
> All of this is just to get I/O in your Android app right? What's the issue
> with setting AVFormatContext->io before calling avformat_open_input() and
> implementing a custom input? Is it that each app would rewrite the same
> code? Or am I missing something super-obvious?
All this JNI stuff is not to only get I/O from an Android Application, but
to support MediaCodec for pre-5.0 android devices (the MediaCodec C api is
only available since 5.0).
The JNI helpers have been put to lavu to provide an API for the
* to register the Java virtual machine (which is intended to be done
once since only one java vm is allowed per process on Android. It should
be done in JNI_OnLoad when the library is loaded). I patched locally the
av_jni_register_java_vm to make it thread-safe. Once a java vm is
registered, successive call to this function will return immediately.
There is an issue with this approach, the application (end user) has to
register the java vm manually. If ffmpeg is used through a lib, the lib
has to tell the user to call this function or its own init function which
will call av_jni_register_java_vm.
The other approach would be to use JNI_GetCreatedJavaVMS so it would
work seamlessly. However, this function is not public on Android and
should be dlopened from the current process or from libdvm for devices
that run dalvik or from libart for devices that run art. I personally
don't like this approach but I will give it a try.
For reference it is done this way in gstreamer:
* to register the application context / application class loader (which
is meant to be done once at the start of the application). Same here, I
patched locally to make it thread-safe and that it can only be
As for why I've put the content resolver support in lavf/file.c:
* the Content Resolver gives you a fd, and the code to manipulate it
can be shared with the one from lavf/file.c as opposed to maintain a
copy of file.c somewhere else, which I find less robust.
More information about the ffmpeg-devel