[Android] libvlc: add std_logger.c
Thomas Guillem
git at videolan.org
Tue Apr 21 15:19:19 CEST 2015
vlc-ports/android | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Apr 21 15:17:43 2015 +0200| [8472a726328829e0272a76bd29402993ecd2766c] | committer: Thomas Guillem
libvlc: add std_logger.c
By default, stdout/stderr are deactivated, i.e. they are opened on /dev/null.
std_logger_Open will duplicate stdout and stderr fd on a write end of a pipe. A
thread will be created and will print the read end of the pipe.
Standard output will be printed with "VLC-std" TAG with debug priority.
Standard error will be printed with "VLC-std" TAG with error priority.
It's not activated by default since we don't want to mess up with the
application file descriptors.
> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=8472a726328829e0272a76bd29402993ecd2766c
---
libvlc/jni/Android.mk | 1 +
libvlc/jni/libvlcjni.c | 12 +++
libvlc/jni/std_logger.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++
libvlc/jni/std_logger.h | 34 +++++++++
4 files changed, 234 insertions(+)
diff --git a/libvlc/jni/Android.mk b/libvlc/jni/Android.mk
index d59be7d..1782a3a 100644
--- a/libvlc/jni/Android.mk
+++ b/libvlc/jni/Android.mk
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES += libvlcjni-equalizer.c
LOCAL_SRC_FILES += libvlcjni-vlcobject.c
LOCAL_SRC_FILES += libvlcjni-media.c libvlcjni-medialist.c libvlcjni-mediadiscoverer.c
LOCAL_SRC_FILES += vout.c native_crash_handler.c thumbnailer.c
+LOCAL_SRC_FILES += std_logger.c
ifneq ($(APP_PLATFORM),android-21)
# compat functions not needed after android-21
LOCAL_SRC_FILES += compat/pthread-condattr.c compat/pthread-rwlocks.c
diff --git a/libvlc/jni/libvlcjni.c b/libvlc/jni/libvlcjni.c
index 3b8fe8e..e79b7f1 100644
--- a/libvlc/jni/libvlcjni.c
+++ b/libvlc/jni/libvlcjni.c
@@ -39,6 +39,7 @@
#include "vout.h"
#include "utils.h"
#include "native_crash_handler.h"
+#include "std_logger.h"
#define VOUT_ANDROID_SURFACE 0
#define VOUT_OPENGLES2 1
@@ -254,6 +255,10 @@ JNIEnv *jni_get_env(const char *name)
return env;
}
+#ifndef NDEBUG
+static std_logger *p_std_logger = NULL;
+#endif
+
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv* env = NULL;
@@ -271,6 +276,9 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved)
pthread_mutex_init(&vout_android_lock, NULL);
pthread_cond_init(&vout_android_surf_attached, NULL);
+#ifndef NDEBUG
+ p_std_logger = std_logger_Open("VLC-std");
+#endif
#define GET_CLASS(clazz, str, b_globlal) do { \
(clazz) = (*env)->FindClass(env, (str)); \
@@ -399,6 +407,10 @@ void JNI_OnUnload(JavaVM* vm, void* reserved)
(*env)->DeleteGlobalRef(env, fields.Media.clazz);
pthread_key_delete(jni_env_key);
+
+#ifndef NDEBUG
+ std_logger_Close(p_std_logger);
+#endif
}
void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
diff --git a/libvlc/jni/std_logger.c b/libvlc/jni/std_logger.c
new file mode 100644
index 0000000..c6bf3b8
--- /dev/null
+++ b/libvlc/jni/std_logger.c
@@ -0,0 +1,187 @@
+/*****************************************************************************
+ * std_logger.c
+ *****************************************************************************
+ * Copyright © 2015 VLC authors, VideoLAN and VideoLabs
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <android/log.h>
+
+#include "std_logger.h"
+
+struct std_logger
+{
+ const char *TAG;
+ int stop_pipe[2];
+ int stdout_pipe[2];
+ int stderr_pipe[2];
+ int old_stdout, old_stderr;
+
+ pthread_t thread;
+};
+
+static ssize_t
+std_logger_Print(std_logger *sys, int fd, int prio)
+{
+ char buf[1024 + 1];
+ ssize_t ret;
+
+ ret = read(fd, buf, 1024);
+ if (ret <= 0)
+ return ret;
+
+ buf[ret] = '\0';
+ __android_log_print(prio, sys->TAG, "%s", buf);
+
+ return ret;
+}
+
+static void *
+std_logger_Thread(void *arg)
+{
+ std_logger *sys = arg;
+
+ while (true)
+ {
+ fd_set rfds;
+ int ret, nfds;
+
+ FD_ZERO(&rfds);
+
+ FD_SET(sys->stop_pipe[0], &rfds);
+ nfds = sys->stop_pipe[0];
+
+ FD_SET(sys->stdout_pipe[0], &rfds);
+ if (sys->stdout_pipe[0] > nfds)
+ nfds = sys->stdout_pipe[0];
+
+ FD_SET(sys->stderr_pipe[0], &rfds);
+ if (sys->stderr_pipe[0] > nfds)
+ nfds = sys->stderr_pipe[0];
+
+ ret = select(nfds + 1, &rfds, NULL, NULL, NULL);
+
+ if (ret == -1)
+ break;
+ else if (ret == 0)
+ continue;
+
+ if (FD_ISSET(sys->stop_pipe[0], &rfds))
+ break;
+
+ if (FD_ISSET(sys->stdout_pipe[0], &rfds)
+ && std_logger_Print(sys, sys->stdout_pipe[0], ANDROID_LOG_DEBUG) <= 0)
+ break;
+
+ if (FD_ISSET(sys->stderr_pipe[0], &rfds)
+ && std_logger_Print(sys, sys->stderr_pipe[0], ANDROID_LOG_ERROR) <= 0)
+ break;
+ }
+ return NULL;
+}
+
+static void
+ClosePipe(int *pipe)
+{
+ if (pipe[0] != -1)
+ {
+ close(pipe[0]);
+ pipe[0] = -1;
+ }
+ if (pipe[1] != -1)
+ {
+ close(pipe[1]);
+ pipe[1] = -1;
+ }
+}
+
+std_logger *
+std_logger_Open(const char *TAG)
+{
+ std_logger *sys = NULL;
+
+ sys = calloc(1, sizeof (std_logger));
+ if (!sys)
+ return NULL;
+
+ sys->TAG = TAG;
+ sys->stop_pipe[0] = sys->stop_pipe[1] =
+ sys->stdout_pipe[0] = sys->stdout_pipe[1] =
+ sys->old_stdout = sys->old_stderr = -1;
+
+ /* save the old stdout/stderr fd to restore it when logged is closed */
+ sys->old_stdout = dup(STDOUT_FILENO);
+ sys->old_stderr = dup(STDERR_FILENO);
+ if (sys->old_stdout == -1 || sys->old_stderr == -1)
+ goto bailout;
+
+ /* duplicate stdout */
+ if (pipe(sys->stdout_pipe) == -1)
+ goto bailout;
+ if (dup2(sys->stdout_pipe[1], STDOUT_FILENO) == -1)
+ goto bailout;
+
+ /* duplicate stderr */
+ if (pipe(sys->stderr_pipe) == -1)
+ goto bailout;
+ if (dup2(sys->stderr_pipe[1], STDERR_FILENO) == -1)
+ goto bailout;
+
+ /* pipe to signal the thread to stop */
+ if (pipe(sys->stop_pipe) == -1)
+ goto bailout;
+
+ if (pthread_create(&sys->thread, NULL, std_logger_Thread, sys))
+ {
+ ClosePipe(sys->stop_pipe);
+ goto bailout;
+ }
+
+ return sys;
+bailout:
+ std_logger_Close(sys);
+ return NULL;
+}
+
+void
+std_logger_Close(std_logger *sys)
+{
+ if (sys->stop_pipe[1] != -1)
+ {
+ write(sys->stop_pipe[1], '\0', 1);
+ close(sys->stop_pipe[1]);
+ sys->stop_pipe[1] = -1;
+ pthread_join(sys->thread, NULL);
+ }
+ ClosePipe(sys->stop_pipe);
+ ClosePipe(sys->stdout_pipe);
+ ClosePipe(sys->stderr_pipe);
+
+ if (sys->old_stdout != -1 && sys->old_stderr != -1) {
+ dup2(sys->old_stdout, STDOUT_FILENO);
+ dup2(sys->old_stderr, STDERR_FILENO);
+ close(sys->old_stdout);
+ close(sys->old_stderr);
+ sys->old_stdout = sys->old_stderr = -1;
+ }
+ free(sys);
+}
diff --git a/libvlc/jni/std_logger.h b/libvlc/jni/std_logger.h
new file mode 100644
index 0000000..ae9f47d
--- /dev/null
+++ b/libvlc/jni/std_logger.h
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * std_logger.h
+ *****************************************************************************
+ * Copyright © 2015 VLC authors, VideoLAN and VideoLabs
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef STD_LOGGER_H
+#define STD_LOGGER_H
+
+/* By default, stdout/stderr are deactivated, i.e. they are opened on
+ * /dev/null. std_logger_Open will duplicate stdout and stderr fd on a write
+ * end of a pipe. A thread will be created and will print the read end of the
+ * pipe. */
+
+typedef struct std_logger std_logger;
+
+std_logger *std_logger_Open(const char *TAG);
+void std_logger_Close(std_logger *sys);
+
+#endif // STD_LOGGER_H
More information about the Android
mailing list