C lib加上tag區分
This commit is contained in:
@@ -35,6 +35,7 @@ typedef struct _CustomData {
|
||||
GstState state; /* Current pipeline state */
|
||||
GstState target_state; /* Desired pipeline state, to be set once buffering is complete */
|
||||
gboolean is_live; /* Live streams do not use buffering */
|
||||
gchar * tag;
|
||||
} CustomData;
|
||||
|
||||
/* playbin2 flags */
|
||||
@@ -94,7 +95,7 @@ static JNIEnv *get_jni_env(void) {
|
||||
/* Change the content of the UI's TextView */
|
||||
static void set_ui_message(const gchar *message, CustomData *data) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
GST_DEBUG ("Setting message to: %s", message);
|
||||
//GST_DEBUG ("Setting message to: %s", message);
|
||||
jstring jmessage = (*env)->NewStringUTF(env, message);
|
||||
(*env)->CallVoidMethod(env, data->app, set_message_method_id, jmessage);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
@@ -125,8 +126,9 @@ static void error_cb(GstBus *bus, GstMessage *msg, CustomData *data) {
|
||||
/* Called when the End Of the Stream is reached. Just move to the beginning of the media and pause. */
|
||||
static void eos_cb(GstBus *bus, GstMessage *msg, CustomData *data) {
|
||||
data->target_state = GST_STATE_PAUSED;
|
||||
data->is_live |= (gst_element_set_state(data->pipeline,
|
||||
GST_STATE_PAUSED) == GST_STATE_CHANGE_NO_PREROLL);
|
||||
GstStateChangeReturn status = gst_element_set_state(data->pipeline,GST_STATE_PAUSED);
|
||||
data->is_live |= (status == GST_STATE_CHANGE_NO_PREROLL);
|
||||
GST_DEBUG ("eos_cb, %s", data->is_live ? "true" : "false");
|
||||
}
|
||||
|
||||
/* Called when buffering messages are received. We inform the UI about the current buffering level and
|
||||
@@ -321,16 +323,16 @@ static void gst_native_finalize(JNIEnv *env, jobject thiz) {
|
||||
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
|
||||
if (!data)
|
||||
return;
|
||||
GST_DEBUG ("Quitting main loop...");
|
||||
GST_DEBUG ("[%s]Quitting main loop...", data->tag);
|
||||
g_main_loop_quit(data->main_loop);
|
||||
GST_DEBUG ("Waiting for thread to finish...");
|
||||
GST_DEBUG ("[%s]Waiting for thread to finish...", data->tag);
|
||||
pthread_join(gst_app_thread, NULL);
|
||||
GST_DEBUG ("Deleting GlobalRef for app object at %p", data->app);
|
||||
GST_DEBUG ("[%s]Deleting GlobalRef for app object at %p", data->tag, data->app);
|
||||
(*env)->DeleteGlobalRef(env, data->app);
|
||||
GST_DEBUG ("Freeing CustomData at %p", data);
|
||||
GST_DEBUG ("[%s]Freeing CustomData at %p", data->tag, data);
|
||||
g_free(data);
|
||||
SET_CUSTOM_DATA (env, thiz, custom_data_field_id, NULL);
|
||||
GST_DEBUG ("Done finalizing");
|
||||
GST_DEBUG ("[%s]Done finalizing", data->tag);
|
||||
}
|
||||
|
||||
/* Set playbin2's URI */
|
||||
@@ -345,7 +347,21 @@ void gst_native_set_uri(JNIEnv *env, jobject thiz, jstring uri) {
|
||||
g_object_set(data->pipeline, "uri", char_uri, NULL);
|
||||
(*env)->ReleaseStringUTFChars(env, uri, char_uri);
|
||||
g_object_set(data->pipeline, "latency", 250, NULL);
|
||||
data->is_live = (gst_element_set_state(data->pipeline, data->target_state) == GST_STATE_CHANGE_NO_PREROLL);
|
||||
GstStateChangeReturn status = gst_element_set_state(data->pipeline, data->target_state);
|
||||
data->is_live = (status == GST_STATE_CHANGE_NO_PREROLL);
|
||||
GST_DEBUG ("[%s]gst_native_set_uri, %s", data->tag, data->is_live ? "true" : "false");
|
||||
}
|
||||
|
||||
|
||||
/* Set name */
|
||||
void gst_native_set_tag(JNIEnv *env, jobject thiz, jstring tag) {
|
||||
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
|
||||
if (!data || !data->pipeline)
|
||||
return;
|
||||
const gchar *char_tag = (*env)->GetStringUTFChars(env, tag, NULL);
|
||||
GST_DEBUG ("Setting TAG to %s", char_tag);
|
||||
data->tag = g_strdup (char_tag);
|
||||
(*env)->ReleaseStringUTFChars(env, tag, char_tag);
|
||||
}
|
||||
|
||||
/* Set pipeline to PLAYING state */
|
||||
@@ -353,9 +369,12 @@ static void gst_native_play(JNIEnv *env, jobject thiz) {
|
||||
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
|
||||
if (!data)
|
||||
return;
|
||||
GST_DEBUG ("Setting state to PLAYING");
|
||||
data->is_live = (gst_element_set_state(data->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_NO_PREROLL);
|
||||
//GST_DEBUG ("Setting state to PLAYING");
|
||||
|
||||
GstStateChangeReturn status = gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
|
||||
data->is_live = (status == GST_STATE_CHANGE_ASYNC);
|
||||
data->target_state = GST_STATE_PLAYING;
|
||||
GST_DEBUG ("[%s]Setting state to PLAYING, %s", data->tag, data->is_live ? "true" : "false");
|
||||
}
|
||||
|
||||
/* Set pipeline to PAUSED state */
|
||||
@@ -363,9 +382,11 @@ static void gst_native_pause(JNIEnv *env, jobject thiz) {
|
||||
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
|
||||
if (!data)
|
||||
return;
|
||||
GST_DEBUG ("Setting state to PAUSED");
|
||||
data->is_live = (gst_element_set_state(data->pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_NO_PREROLL);
|
||||
//GST_DEBUG ("Setting state to PAUSED");
|
||||
GstStateChangeReturn status = gst_element_set_state(data->pipeline, GST_STATE_PAUSED);
|
||||
data->is_live = (status == GST_STATE_CHANGE_ASYNC);
|
||||
data->target_state = GST_STATE_PAUSED;
|
||||
GST_DEBUG ("[%s]Setting state to PAUSED, %s", data->tag, data->is_live ? "true" : "false");
|
||||
}
|
||||
|
||||
/* Static class initializer: retrieve method and field IDs */
|
||||
@@ -392,20 +413,18 @@ static void gst_native_surface_init(JNIEnv *env, jobject thiz, jobject surface)
|
||||
if (!data)
|
||||
return;
|
||||
ANativeWindow *new_native_window = ANativeWindow_fromSurface(env, surface);
|
||||
GST_DEBUG ("Received surface %p (native window %p)", surface,
|
||||
new_native_window);
|
||||
GST_DEBUG ("[%s]Received surface %p (native window %p)", data->tag, surface, new_native_window);
|
||||
|
||||
if (data->native_window) {
|
||||
ANativeWindow_release(data->native_window);
|
||||
if (data->native_window == new_native_window) {
|
||||
GST_DEBUG ("New native window is the same as the previous one %p",
|
||||
data->native_window);
|
||||
GST_DEBUG ("[%s]New native window is the same as the previous one %p", data->tag, data->native_window);
|
||||
if (data->pipeline) {
|
||||
gst_video_overlay_expose(GST_VIDEO_OVERLAY (data->pipeline));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
GST_DEBUG ("Released previous native window %p", data->native_window);
|
||||
GST_DEBUG ("[%s]Released previous native window %p", data->tag, data->native_window);
|
||||
data->initialized = FALSE;
|
||||
}
|
||||
}
|
||||
@@ -418,7 +437,7 @@ static void gst_native_surface_finalize(JNIEnv *env, jobject thiz) {
|
||||
CustomData *data = GET_CUSTOM_DATA (env, thiz, custom_data_field_id);
|
||||
if (!data)
|
||||
return;
|
||||
GST_DEBUG ("Releasing Native Window %p", data->native_window);
|
||||
GST_DEBUG ("[%s]Releasing Native Window %p", data->tag, data->native_window);
|
||||
|
||||
if (data->pipeline) {
|
||||
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY (data->pipeline),
|
||||
@@ -436,6 +455,7 @@ static JNINativeMethod native_methods[] = {
|
||||
{"nativeInit", "()V", (void *) gst_native_init},
|
||||
{"nativeFinalize", "()V", (void *) gst_native_finalize},
|
||||
{"nativeSetUri", "(Ljava/lang/String;)V", (void *) gst_native_set_uri},
|
||||
{"nativeSetTag", "(Ljava/lang/String;)V", (void *) gst_native_set_tag},
|
||||
{"nativePlay", "()V", (void *) gst_native_play},
|
||||
{"nativePause", "()V", (void *) gst_native_pause},
|
||||
{"nativeSurfaceInit", "(Ljava/lang/Object;)V",
|
||||
|
||||
@@ -13,7 +13,9 @@ import org.freedesktop.gstreamer.GStreamer;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
public class GstLibrary implements Closeable {
|
||||
public class GstLibrary implements Closeable, SurfaceHolder.Callback {
|
||||
|
||||
private static final String TAG = "GStreamer";//GstLibrary.class.getSimpleName();
|
||||
|
||||
final Context mAppContext;
|
||||
|
||||
@@ -21,6 +23,8 @@ public class GstLibrary implements Closeable {
|
||||
|
||||
private String rtspUrl;
|
||||
|
||||
private String tag = "";
|
||||
|
||||
public GstLibrary(Context context) {
|
||||
this.mAppContext = context.getApplicationContext();
|
||||
|
||||
@@ -38,6 +42,7 @@ public class GstLibrary implements Closeable {
|
||||
private native void nativeInit(); // Initialize native code, build pipeline, etc
|
||||
private native void nativeFinalize(); // Destroy pipeline and shutdown native code
|
||||
private native void nativeSetUri(String uri); // Set the URI of the media to play
|
||||
private native void nativeSetTag(String tag); // Set the URI of the media to play
|
||||
private native void nativePlay(); // Set pipeline to PLAYING
|
||||
private native void nativePause(); // Set pipeline to PAUSED
|
||||
private static native boolean nativeClassInit(); // Initialize native class: cache Method IDs for callbacks
|
||||
@@ -59,6 +64,11 @@ public class GstLibrary implements Closeable {
|
||||
this.rtspUrl = rtspUrl;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
nativeSetTag(tag);
|
||||
}
|
||||
|
||||
public void releaseSurface() {
|
||||
nativeSurfaceFinalize();
|
||||
}
|
||||
@@ -68,7 +78,7 @@ public class GstLibrary implements Closeable {
|
||||
}
|
||||
|
||||
public void setSurfaceHolder(SurfaceHolder holder) {
|
||||
nativeSurfaceInit(holder.getSurface());
|
||||
holder.addCallback(this);
|
||||
}
|
||||
|
||||
// Called from native code. This sets the content of the TextView from the UI thread.
|
||||
@@ -108,7 +118,7 @@ public class GstLibrary implements Closeable {
|
||||
// Called from native code when the size of the media changes or is first detected.
|
||||
// Inform the video surface about the new size and recalculate the layout.
|
||||
private void onMediaSizeChanged (int width, int height) {
|
||||
Log.i ("GStreamer", "Media size changed to " + width + "x" + height);
|
||||
Log.i (TAG + "+" + tag, String.format("Media size changed to %d x %d", width, height));
|
||||
/*mainHandler.post(() -> {
|
||||
surfaceView.media_width = width;
|
||||
surfaceView.media_height = height;
|
||||
@@ -130,4 +140,22 @@ public class GstLibrary implements Closeable {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
Log.d(TAG + "+" + tag, "Surface created: " + holder.getSurface());
|
||||
nativeSurfaceInit(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
Log.d(TAG + "+" + tag, String.format("Surface changed, format: %d, width: %d, height: %d", format, width, height));
|
||||
/*setSurfaceHolder(holder);*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
Log.d(TAG + "+" + tag, "Surface destroyed");
|
||||
releaseSurface();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user