Commit d2469972 authored by Thibault Saunier's avatar Thibault Saunier Committed by Thibault Saunier

Pass our C files to gst-indent

parent 42285ae1
Pipeline #33072 passed with stage
in 1 minute and 50 seconds
......@@ -3,14 +3,12 @@
static GMainLoop *loop;
static gboolean
my_bus_callback (GstBus *bus,
GstMessage *message,
gpointer data)
my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
{
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR: {
case GST_MESSAGE_ERROR:{
GError *err;
gchar *debug;
......@@ -39,8 +37,7 @@ my_bus_callback (GstBus *bus,
}
gint
main (gint argc,
gchar *argv[])
main (gint argc, gchar * argv[])
{
GstElement *pipeline;
GstBus *bus;
......
#include <gst/gst.h>
static void
link_to_multiplexer (GstPad *tolink_pad,
GstElement *mux)
link_to_multiplexer (GstPad * tolink_pad, GstElement * mux)
{
GstPad *pad;
gchar *srcname, *sinkname;
......@@ -19,9 +18,9 @@ link_to_multiplexer (GstPad *tolink_pad,
}
static void
some_function (GstElement *tee)
some_function (GstElement * tee)
{
GstPad * pad;
GstPad *pad;
gchar *name;
pad = gst_element_get_request_pad (tee, "src%d");
......
......@@ -6,26 +6,34 @@
/*
* Java Bindings
*/
static jstring gst_native_get_gstreamer_info (JNIEnv* env, jobject thiz) {
char *version_utf8 = gst_version_string();
jstring *version_jstring = (*env)->NewStringUTF(env, version_utf8);
static jstring
gst_native_get_gstreamer_info (JNIEnv * env, jobject thiz)
{
char *version_utf8 = gst_version_string ();
jstring *version_jstring = (*env)->NewStringUTF (env, version_utf8);
g_free (version_utf8);
return version_jstring;
}
static JNINativeMethod native_methods[] = {
{ "nativeGetGStreamerInfo", "()Ljava/lang/String;", (void *) gst_native_get_gstreamer_info}
{"nativeGetGStreamerInfo", "()Ljava/lang/String;",
(void *) gst_native_get_gstreamer_info}
};
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
jint
JNI_OnLoad (JavaVM * vm, void *reserved)
{
JNIEnv *env = NULL;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print (ANDROID_LOG_ERROR, "tutorial-1", "Could not retrieve JNIEnv");
if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print (ANDROID_LOG_ERROR, "tutorial-1",
"Could not retrieve JNIEnv");
return 0;
}
jclass klass = (*env)->FindClass (env, "org/freedesktop/gstreamer/tutorials/tutorial_1/Tutorial1");
(*env)->RegisterNatives (env, klass, native_methods, G_N_ELEMENTS(native_methods));
jclass klass = (*env)->FindClass (env,
"org/freedesktop/gstreamer/tutorials/tutorial_1/Tutorial1");
(*env)->RegisterNatives (env, klass, native_methods,
G_N_ELEMENTS (native_methods));
return JNI_VERSION_1_4;
}
......@@ -20,12 +20,13 @@ GST_DEBUG_CATEGORY_STATIC (debug_category);
#endif
/* Structure to contain all our information, so we can pass it to callbacks */
typedef struct _CustomData {
jobject app; /* Application instance, used to call its methods. A global reference is kept. */
GstElement *pipeline; /* The running pipeline */
GMainContext *context; /* GLib context used to run the main loop */
GMainLoop *main_loop; /* GLib main loop */
gboolean initialized; /* To avoid informing the UI multiple times about the initialization */
typedef struct _CustomData
{
jobject app; /* Application instance, used to call its methods. A global reference is kept. */
GstElement *pipeline; /* The running pipeline */
GMainContext *context; /* GLib context used to run the main loop */
GMainLoop *main_loop; /* GLib main loop */
gboolean initialized; /* To avoid informing the UI multiple times about the initialization */
} CustomData;
/* These global variables cache values which are not changing during execution */
......@@ -41,7 +42,9 @@ static jmethodID on_gstreamer_initialized_method_id;
*/
/* Register this thread with the VM */
static JNIEnv *attach_current_thread (void) {
static JNIEnv *
attach_current_thread (void)
{
JNIEnv *env;
JavaVMAttachArgs args;
......@@ -59,13 +62,17 @@ static JNIEnv *attach_current_thread (void) {
}
/* Unregister this thread from the VM */
static void detach_current_thread (void *env) {
static void
detach_current_thread (void *env)
{
GST_DEBUG ("Detaching thread %p", g_thread_self ());
(*java_vm)->DetachCurrentThread (java_vm);
}
/* Retrieve the JNI environment for this thread */
static JNIEnv *get_jni_env (void) {
static JNIEnv *
get_jni_env (void)
{
JNIEnv *env;
if ((env = pthread_getspecific (current_jni_env)) == NULL) {
......@@ -77,10 +84,12 @@ static JNIEnv *get_jni_env (void) {
}
/* Change the content of the UI's TextView */
static void set_ui_message (const gchar *message, CustomData *data) {
static void
set_ui_message (const gchar * message, CustomData * data)
{
JNIEnv *env = get_jni_env ();
GST_DEBUG ("Setting message to: %s", message);
jstring jmessage = (*env)->NewStringUTF(env, message);
jstring jmessage = (*env)->NewStringUTF (env, message);
(*env)->CallVoidMethod (env, data->app, set_message_method_id, jmessage);
if ((*env)->ExceptionCheck (env)) {
GST_ERROR ("Failed to call Java method");
......@@ -90,13 +99,17 @@ static void set_ui_message (const gchar *message, CustomData *data) {
}
/* Retrieve errors from the bus and show them on the UI */
static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
static void
error_cb (GstBus * bus, GstMessage * msg, CustomData * data)
{
GError *err;
gchar *debug_info;
gchar *message_string;
gst_message_parse_error (msg, &err, &debug_info);
message_string = g_strdup_printf ("Error received from element %s: %s", GST_OBJECT_NAME (msg->src), err->message);
message_string =
g_strdup_printf ("Error received from element %s: %s",
GST_OBJECT_NAME (msg->src), err->message);
g_clear_error (&err);
g_free (debug_info);
set_ui_message (message_string, data);
......@@ -105,23 +118,29 @@ static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
}
/* Notify UI about pipeline state changes */
static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
static void
state_changed_cb (GstBus * bus, GstMessage * msg, CustomData * data)
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
/* Only pay attention to messages coming from the pipeline, not its children */
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) {
gchar *message = g_strdup_printf("State changed to %s", gst_element_state_get_name(new_state));
set_ui_message(message, data);
gchar *message = g_strdup_printf ("State changed to %s",
gst_element_state_get_name (new_state));
set_ui_message (message, data);
g_free (message);
}
}
/* Check if all conditions are met to report GStreamer as initialized.
* These conditions will change depending on the application */
static void check_initialization_complete (CustomData *data) {
static void
check_initialization_complete (CustomData * data)
{
JNIEnv *env = get_jni_env ();
if (!data->initialized && data->main_loop) {
GST_DEBUG ("Initialization complete, notifying application. main_loop:%p", data->main_loop);
GST_DEBUG ("Initialization complete, notifying application. main_loop:%p",
data->main_loop);
(*env)->CallVoidMethod (env, data->app, on_gstreamer_initialized_method_id);
if ((*env)->ExceptionCheck (env)) {
GST_ERROR ("Failed to call Java method");
......@@ -132,10 +151,12 @@ static void check_initialization_complete (CustomData *data) {
}
/* Main method for the native code. This is executed on its own thread. */
static void *app_function (void *userdata) {
static void *
app_function (void *userdata)
{
JavaVMAttachArgs args;
GstBus *bus;
CustomData *data = (CustomData *)userdata;
CustomData *data = (CustomData *) userdata;
GSource *bus_source;
GError *error = NULL;
......@@ -143,14 +164,17 @@ static void *app_function (void *userdata) {
/* Create our own GLib Main Context and make it the default one */
data->context = g_main_context_new ();
g_main_context_push_thread_default(data->context);
g_main_context_push_thread_default (data->context);
/* Build pipeline */
data->pipeline = gst_parse_launch("audiotestsrc ! audioconvert ! audioresample ! autoaudiosink", &error);
data->pipeline =
gst_parse_launch
("audiotestsrc ! audioconvert ! audioresample ! autoaudiosink", &error);
if (error) {
gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message);
gchar *message =
g_strdup_printf ("Unable to build pipeline: %s", error->message);
g_clear_error (&error);
set_ui_message(message, data);
set_ui_message (message, data);
g_free (message);
return NULL;
}
......@@ -158,11 +182,14 @@ static void *app_function (void *userdata) {
/* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
bus = gst_element_get_bus (data->pipeline);
bus_source = gst_bus_create_watch (bus);
g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL);
g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func,
NULL, NULL);
g_source_attach (bus_source, data->context);
g_source_unref (bus_source);
g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, data);
g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, data);
g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
data);
g_signal_connect (G_OBJECT (bus), "message::state-changed",
(GCallback) state_changed_cb, data);
gst_object_unref (bus);
/* Create a GLib Main Loop and set it to run */
......@@ -175,7 +202,7 @@ static void *app_function (void *userdata) {
data->main_loop = NULL;
/* Free resources */
g_main_context_pop_thread_default(data->context);
g_main_context_pop_thread_default (data->context);
g_main_context_unref (data->context);
gst_element_set_state (data->pipeline, GST_STATE_NULL);
gst_object_unref (data->pipeline);
......@@ -188,11 +215,14 @@ static void *app_function (void *userdata) {
*/
/* Instruct the native code to create its internal data structure, pipeline and thread */
static void gst_native_init (JNIEnv* env, jobject thiz) {
static void
gst_native_init (JNIEnv * env, jobject thiz)
{
CustomData *data = g_new0 (CustomData, 1);
SET_CUSTOM_DATA (env, thiz, custom_data_field_id, data);
GST_DEBUG_CATEGORY_INIT (debug_category, "tutorial-2", 0, "Android tutorial 2");
gst_debug_set_threshold_for_name("tutorial-2", GST_LEVEL_DEBUG);
GST_DEBUG_CATEGORY_INIT (debug_category, "tutorial-2", 0,
"Android tutorial 2");
gst_debug_set_threshold_for_name ("tutorial-2", GST_LEVEL_DEBUG);
GST_DEBUG ("Created CustomData at %p", data);
data->app = (*env)->NewGlobalRef (env, thiz);
GST_DEBUG ("Created GlobalRef for app object at %p", data->app);
......@@ -200,9 +230,12 @@ static void gst_native_init (JNIEnv* env, jobject thiz) {
}
/* Quit the main loop, remove the native thread and free resources */
static void gst_native_finalize (JNIEnv* env, jobject thiz) {
static void
gst_native_finalize (JNIEnv * env, jobject thiz)
{
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
if (!data) return;
if (!data)
return;
GST_DEBUG ("Quitting main loop...");
g_main_loop_quit (data->main_loop);
GST_DEBUG ("Waiting for thread to finish...");
......@@ -216,32 +249,45 @@ static void gst_native_finalize (JNIEnv* env, jobject thiz) {
}
/* Set pipeline to PLAYING state */
static void gst_native_play (JNIEnv* env, jobject thiz) {
static void
gst_native_play (JNIEnv * env, jobject thiz)
{
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
if (!data) return;
if (!data)
return;
GST_DEBUG ("Setting state to PLAYING");
gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
}
/* Set pipeline to PAUSED state */
static void gst_native_pause (JNIEnv* env, jobject thiz) {
static void
gst_native_pause (JNIEnv * env, jobject thiz)
{
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
if (!data) return;
if (!data)
return;
GST_DEBUG ("Setting state to PAUSED");
gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
}
/* Static class initializer: retrieve method and field IDs */
static jboolean gst_native_class_init (JNIEnv* env, jclass klass) {
custom_data_field_id = (*env)->GetFieldID (env, klass, "native_custom_data", "J");
set_message_method_id = (*env)->GetMethodID (env, klass, "setMessage", "(Ljava/lang/String;)V");
on_gstreamer_initialized_method_id = (*env)->GetMethodID (env, klass, "onGStreamerInitialized", "()V");
if (!custom_data_field_id || !set_message_method_id || !on_gstreamer_initialized_method_id) {
static jboolean
gst_native_class_init (JNIEnv * env, jclass klass)
{
custom_data_field_id =
(*env)->GetFieldID (env, klass, "native_custom_data", "J");
set_message_method_id =
(*env)->GetMethodID (env, klass, "setMessage", "(Ljava/lang/String;)V");
on_gstreamer_initialized_method_id =
(*env)->GetMethodID (env, klass, "onGStreamerInitialized", "()V");
if (!custom_data_field_id || !set_message_method_id
|| !on_gstreamer_initialized_method_id) {
/* We emit this message through the Android log instead of the GStreamer log because the later
* has not been initialized yet.
*/
__android_log_print (ANDROID_LOG_ERROR, "tutorial-2", "The calling class does not implement all necessary interface methods");
__android_log_print (ANDROID_LOG_ERROR, "tutorial-2",
"The calling class does not implement all necessary interface methods");
return JNI_FALSE;
}
return JNI_TRUE;
......@@ -249,25 +295,30 @@ static jboolean gst_native_class_init (JNIEnv* env, jclass klass) {
/* List of implemented native methods */
static JNINativeMethod native_methods[] = {
{ "nativeInit", "()V", (void *) gst_native_init},
{ "nativeFinalize", "()V", (void *) gst_native_finalize},
{ "nativePlay", "()V", (void *) gst_native_play},
{ "nativePause", "()V", (void *) gst_native_pause},
{ "nativeClassInit", "()Z", (void *) gst_native_class_init}
{"nativeInit", "()V", (void *) gst_native_init},
{"nativeFinalize", "()V", (void *) gst_native_finalize},
{"nativePlay", "()V", (void *) gst_native_play},
{"nativePause", "()V", (void *) gst_native_pause},
{"nativeClassInit", "()Z", (void *) gst_native_class_init}
};
/* Library initializer */
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
jint
JNI_OnLoad (JavaVM * vm, void *reserved)
{
JNIEnv *env = NULL;
java_vm = vm;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print (ANDROID_LOG_ERROR, "tutorial-2", "Could not retrieve JNIEnv");
if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print (ANDROID_LOG_ERROR, "tutorial-2",
"Could not retrieve JNIEnv");
return 0;
}
jclass klass = (*env)->FindClass (env, "org/freedesktop/gstreamer/tutorials/tutorial_2/Tutorial2");
(*env)->RegisterNatives (env, klass, native_methods, G_N_ELEMENTS(native_methods));
jclass klass = (*env)->FindClass (env,
"org/freedesktop/gstreamer/tutorials/tutorial_2/Tutorial2");
(*env)->RegisterNatives (env, klass, native_methods,
G_N_ELEMENTS (native_methods));
pthread_key_create (&current_jni_env, detach_current_thread);
......
......@@ -24,13 +24,14 @@ GST_DEBUG_CATEGORY_STATIC (debug_category);
#endif
/* Structure to contain all our information, so we can pass it to callbacks */
typedef struct _CustomData {
jobject app; /* Application instance, used to call its methods. A global reference is kept. */
GstElement *pipeline; /* The running pipeline */
GMainContext *context; /* GLib context used to run the main loop */
GMainLoop *main_loop; /* GLib main loop */
gboolean initialized; /* To avoid informing the UI multiple times about the initialization */
GstElement *video_sink; /* The video sink element which receives XOverlay commands */
typedef struct _CustomData
{
jobject app; /* Application instance, used to call its methods. A global reference is kept. */
GstElement *pipeline; /* The running pipeline */
GMainContext *context; /* GLib context used to run the main loop */
GMainLoop *main_loop; /* GLib main loop */
gboolean initialized; /* To avoid informing the UI multiple times about the initialization */
GstElement *video_sink; /* The video sink element which receives XOverlay commands */
ANativeWindow *native_window; /* The Android native window where video will be rendered */
} CustomData;
......@@ -47,7 +48,9 @@ static jmethodID on_gstreamer_initialized_method_id;
*/
/* Register this thread with the VM */
static JNIEnv *attach_current_thread (void) {
static JNIEnv *
attach_current_thread (void)
{
JNIEnv *env;
JavaVMAttachArgs args;
......@@ -65,13 +68,17 @@ static JNIEnv *attach_current_thread (void) {
}
/* Unregister this thread from the VM */
static void detach_current_thread (void *env) {
static void
detach_current_thread (void *env)
{
GST_DEBUG ("Detaching thread %p", g_thread_self ());
(*java_vm)->DetachCurrentThread (java_vm);
}
/* Retrieve the JNI environment for this thread */
static JNIEnv *get_jni_env (void) {
static JNIEnv *
get_jni_env (void)
{
JNIEnv *env;
if ((env = pthread_getspecific (current_jni_env)) == NULL) {
......@@ -83,10 +90,12 @@ static JNIEnv *get_jni_env (void) {
}
/* Change the content of the UI's TextView */
static void set_ui_message (const gchar *message, CustomData *data) {
static void
set_ui_message (const gchar * message, CustomData * data)
{
JNIEnv *env = get_jni_env ();
GST_DEBUG ("Setting message to: %s", message);
jstring jmessage = (*env)->NewStringUTF(env, message);
jstring jmessage = (*env)->NewStringUTF (env, message);
(*env)->CallVoidMethod (env, data->app, set_message_method_id, jmessage);
if ((*env)->ExceptionCheck (env)) {
GST_ERROR ("Failed to call Java method");
......@@ -96,13 +105,17 @@ static void set_ui_message (const gchar *message, CustomData *data) {
}
/* Retrieve errors from the bus and show them on the UI */
static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
static void
error_cb (GstBus * bus, GstMessage * msg, CustomData * data)
{
GError *err;
gchar *debug_info;
gchar *message_string;
gst_message_parse_error (msg, &err, &debug_info);
message_string = g_strdup_printf ("Error received from element %s: %s", GST_OBJECT_NAME (msg->src), err->message);
message_string =
g_strdup_printf ("Error received from element %s: %s",
GST_OBJECT_NAME (msg->src), err->message);
g_clear_error (&err);
g_free (debug_info);
set_ui_message (message_string, data);
......@@ -111,26 +124,34 @@ static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
}
/* Notify UI about pipeline state changes */
static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
static void
state_changed_cb (GstBus * bus, GstMessage * msg, CustomData * data)
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
/* Only pay attention to messages coming from the pipeline, not its children */
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipeline)) {
gchar *message = g_strdup_printf("State changed to %s", gst_element_state_get_name(new_state));
set_ui_message(message, data);
gchar *message = g_strdup_printf ("State changed to %s",
gst_element_state_get_name (new_state));
set_ui_message (message, data);
g_free (message);
}
}
/* Check if all conditions are met to report GStreamer as initialized.
* These conditions will change depending on the application */
static void check_initialization_complete (CustomData *data) {
static void
check_initialization_complete (CustomData * data)
{
JNIEnv *env = get_jni_env ();
if (!data->initialized && data->native_window && data->main_loop) {
GST_DEBUG ("Initialization complete, notifying application. native_window:%p main_loop:%p", data->native_window, data->main_loop);
GST_DEBUG
("Initialization complete, notifying application. native_window:%p main_loop:%p",
data->native_window, data->main_loop);
/* The main loop is running and we received a native window, inform the sink about it */
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (data->video_sink), (guintptr)data->native_window);
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (data->video_sink),
(guintptr) data->native_window);
(*env)->CallVoidMethod (env, data->app, on_gstreamer_initialized_method_id);
if ((*env)->ExceptionCheck (env)) {
......@@ -142,10 +163,12 @@ static void check_initialization_complete (CustomData *data) {
}
/* Main method for the native code. This is executed on its own thread. */
static void *app_function (void *userdata) {
static void *
app_function (void *userdata)
{
JavaVMAttachArgs args;
GstBus *bus;
CustomData *data = (CustomData *)userdata;
CustomData *data = (CustomData *) userdata;
GSource *bus_source;
GError *error = NULL;
......@@ -153,22 +176,27 @@ static void *app_function (void *userdata) {
/* Create our own GLib Main Context and make it the default one */
data->context = g_main_context_new ();
g_main_context_push_thread_default(data->context);
g_main_context_push_thread_default (data->context);
/* Build pipeline */
data->pipeline = gst_parse_launch("videotestsrc ! warptv ! videoconvert ! autovideosink", &error);
data->pipeline =
gst_parse_launch ("videotestsrc ! warptv ! videoconvert ! autovideosink",
&error);
if (error) {
gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message);
gchar *message =
g_strdup_printf ("Unable to build pipeline: %s", error->message);
g_clear_error (&error);
set_ui_message(message, data);
set_ui_message (message, data);
g_free (message);
return NULL;
}
/* Set the pipeline to READY, so it can already accept a window handle, if we have one */
gst_element_set_state(data->pipeline, GST_STATE_READY);
gst_element_set_state (data->pipeline, GST_STATE_READY);
data->video_sink = gst_bin_get_by_interface(GST_BIN(data->pipeline), GST_TYPE_VIDEO_OVERLAY);
data->video_sink =
gst_bin_get_by_interface (GST_BIN (data->pipeline),
GST_TYPE_VIDEO_OVERLAY);
if (!data->video_sink) {
GST_ERROR ("Could not retrieve video sink");
return NULL;
......@@ -177,11 +205,14 @@ static void *app_function (void *userdata) {
/* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
bus = gst_element_get_bus (data->pipeline);
bus_source = gst_bus_create_watch (bus);
g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL);
g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func,
NULL, NULL);
g_source_attach (bus_source, data->context);
g_source_unref (bus_source);
g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, data);
g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, data);
g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
data);
g_signal_connect (G_OBJECT (bus), "message::state-changed",
(GCallback) state_changed_cb, data);
gst_object_unref (bus);
/* Create a GLib Main Loop and set it to run */
......@@ -194,7 +225,7 @@ static void *app_function (void *userdata) {
data->main_loop = NULL;
/* Free resources */
g_main_context_pop_thread_default(data->context);
g_main_context_pop_thread_default (data->context);
g_main_context_unref (data->context);
gst_element_set_state (data->pipeline, GST_STATE_NULL);
gst_object_unref (data->video_sink);
......@@ -208,11 +239,14 @@ static void *app_function (void *userdata) {
*/
/* Instruct the native code to create its internal data structure, pipeline and thread */
static void gst_native_init (JNIEnv* env, jobject thiz) {
static void
gst_native_init (JNIEnv * env, jobject thiz)
{
CustomData *data = g_new0 (CustomData, 1);
SET_CUSTOM_DATA (env, thiz, custom_data_field_id, data);
GST_DEBUG_CATEGORY_INIT (debug_category, "tutorial-3", 0, "Android tutorial 3");
gst_debug_set_threshold_for_name("tutorial-3", GST_LEVEL_DEBUG);
GST_DEBUG_CATEGORY_INIT (debug_category, "tutorial-3", 0,
"Android tutorial 3");
gst_debug_set_threshold_for_name ("tutorial-3", GST_LEVEL_DEBUG);
GST_DEBUG ("Created CustomData at %p", data);
data->app = (*env)->NewGlobalRef (env, thiz);
GST_DEBUG ("Created GlobalRef for app object at %p", data->app);
......@@ -220,9 +254,12 @@ static void gst_native_init (JNIEnv* env, jobject thiz) {
}
/* Quit the main loop, remove the native thread and free resources */
static void gst_native_finalize (JNIEnv* env, jobject thiz) {
static void
gst_native_finalize (JNIEnv * env, jobject thiz)
{
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
if (!data) return;
if (!data)
return;
GST_DEBUG ("Quitting main loop...");
g_main_loop_quit (data->main_loop);
GST_DEBUG ("Waiting for thread to finish...");
......@@ -236,50 +273,68 @@ static void gst_native_finalize (JNIEnv* env, jobject thiz) {
}
/* Set pipeline to PLAYING state */
static void gst_native_play (JNIEnv* env, jobject thiz) {
static void
gst_native_play (JNIEnv * env, jobject thiz)
{
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
if (!data) return;
if (!data)
return;
GST_DEBUG ("Setting state to PLAYING");
gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
}
/* Set pipeline to PAUSED state */
static void gst_native_pause (JNIEnv* env, jobject thiz) {
static void
gst_native_pause (JNIEnv * env, jobject thiz)
{
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
if (!data) return;
if (!data)
return;
GST_DEBUG ("Setting state to PAUSED");
gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
}
/* Static class initializer: retrieve method and field IDs */
static jboolean gst_native_class_init (JNIEnv* env, jclass klass) {
custom_data_field_id = (*env)->GetFieldID (env, klass, "native_custom_data", "J");
set_message_method_id = (*env)->GetMethodID (env, klass, "setMessage", "(Ljava/lang/String;)V");
on_gstreamer_initialized_method_id = (*env)->GetMethodID (env, klass, "onGStreamerInitialized", "()V");
if (!custom_data_field_id || !set_message_method_id || !on_gstreamer_initialized_method_id) {
static jboolean
gst_native_class_init (JNIEnv * env, jclass klass)
{
custom_data_field_id =
(*env)->GetFieldID (env, klass, "native_custom_data", "J");
set_message_method_id =
(*env)->GetMethodID (env, klass, "setMessage", "(Ljava/lang/String;)V");
on_gstreamer_initialized_method_id =
(*env)->GetMethodID (env, klass, "onGStreamerInitialized", "()V");
if (!custom_data_field_id || !set_message_method_id
|| !on_gstreamer_initialized_method_id) {
/* We emit this message through the Android log instead of the GStreamer log because the later
* has not been initialized yet.