emotion gstreamer1: Use refcounting instead of in/out variable counting

This commit is contained in:
Sebastian Dröge 2014-01-12 19:18:37 +01:00
parent 85b17ff7c1
commit 01389b1d00
3 changed files with 35 additions and 32 deletions

View File

@ -48,9 +48,7 @@ emotion_gstreamer_message_alloc(Emotion_Gstreamer *ev,
send = malloc(sizeof (Emotion_Gstreamer_Message)); send = malloc(sizeof (Emotion_Gstreamer_Message));
if (!send) return NULL; if (!send) return NULL;
ev->out++; send->ev = emotion_gstreamer_ref(ev);
send->ev = ev;
send->msg = gst_message_ref(msg); send->msg = gst_message_ref(msg);
return send; return send;
@ -59,13 +57,7 @@ emotion_gstreamer_message_alloc(Emotion_Gstreamer *ev,
void void
emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send) emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send)
{ {
send->ev->in++; emotion_gstreamer_unref(send->ev);
if (send->ev->in == send->ev->out
&& send->ev->threads == NULL
&& send->ev->shutdown)
send->ev->api->del(send->ev);
gst_message_unref(send->msg); gst_message_unref(send->msg);
free(send); free(send);
} }

View File

@ -71,6 +71,13 @@ emotion_visualization_element_name_get(Emotion_Vis visualisation)
} }
} }
Emotion_Gstreamer *
emotion_gstreamer_ref(Emotion_Gstreamer *ev)
{
g_atomic_int_inc (&ev->ref_count);
return ev;
}
static void static void
em_cleanup(Emotion_Gstreamer *ev) em_cleanup(Emotion_Gstreamer *ev)
{ {
@ -91,6 +98,17 @@ em_cleanup(Emotion_Gstreamer *ev)
} }
} }
void
emotion_gstreamer_unref(Emotion_Gstreamer *ev)
{
if (g_atomic_int_dec_and_test(&ev->ref_count))
{
em_cleanup(ev);
free(ev);
}
}
static void static void
em_del(void *video) em_del(void *video)
{ {
@ -103,19 +121,11 @@ em_del(void *video)
EINA_LIST_FREE(ev->threads, t) EINA_LIST_FREE(ev->threads, t)
ecore_thread_cancel(t); ecore_thread_cancel(t);
ev->shutdown = EINA_TRUE;
return;
} }
if (ev->in != ev->out) ev->shutdown = EINA_TRUE;
{
ev->shutdown = EINA_TRUE;
return;
}
em_cleanup(ev); emotion_gstreamer_unref(ev);
free(ev);
} }
static Eina_Bool static Eina_Bool
@ -1024,6 +1034,8 @@ em_add(const Emotion_Engine *api,
ev->api = api; ev->api = api;
ev->obj = obj; ev->obj = obj;
ev->ref_count = 1;
/* Default values */ /* Default values */
ev->vis = EMOTION_VIS_NONE; ev->vis = EMOTION_VIS_NONE;
@ -1365,8 +1377,8 @@ _bus_main_handler(void *data)
ev); ev);
gst_tag_list_free(new_tags); gst_tag_list_free(new_tags);
} }
break;
} }
break;
case GST_MESSAGE_ASYNC_DONE: case GST_MESSAGE_ASYNC_DONE:
_emotion_seek_done(ev->obj); _emotion_seek_done(ev->obj);
break; break;
@ -1603,8 +1615,7 @@ _emotion_gstreamer_cancel(void *data, Ecore_Thread *thread)
if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT")); if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT"));
} }
if (ev->in == ev->out && ev->shutdown) emotion_gstreamer_unref(ev);
ev->api->del(ev);
} }
static void static void
@ -1626,10 +1637,8 @@ _emotion_gstreamer_end(void *data, Ecore_Thread *thread)
if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT")); if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT"));
} }
if (ev->in == ev->out && ev->shutdown) _emotion_gstreamer_video_pipeline_parse(data, EINA_TRUE);
ev->api->del(ev); emotion_gstreamer_unref(ev);
else
_emotion_gstreamer_video_pipeline_parse(data, EINA_TRUE);
} }
static GstElement * static GstElement *
@ -1676,7 +1685,7 @@ _create_pipeline (Emotion_Gstreamer *ev,
ecore_thread_run(_emotion_gstreamer_pause, ecore_thread_run(_emotion_gstreamer_pause,
_emotion_gstreamer_end, _emotion_gstreamer_end,
_emotion_gstreamer_cancel, _emotion_gstreamer_cancel,
ev)); emotion_gstreamer_ref(ev)));
/** NOTE: you need to set: GST_DEBUG_DUMP_DOT_DIR=/tmp EMOTION_ENGINE=gstreamer to save the $EMOTION_GSTREAMER_DOT file in '/tmp' */ /** NOTE: you need to set: GST_DEBUG_DUMP_DOT_DIR=/tmp EMOTION_ENGINE=gstreamer to save the $EMOTION_GSTREAMER_DOT file in '/tmp' */
/** then call dot -Tpng -oemotion_pipeline.png /tmp/$TIMESTAMP-$EMOTION_GSTREAMER_DOT.dot */ /** then call dot -Tpng -oemotion_pipeline.png /tmp/$TIMESTAMP-$EMOTION_GSTREAMER_DOT.dot */

View File

@ -49,6 +49,8 @@ struct _Emotion_Gstreamer
{ {
const Emotion_Engine *api; const Emotion_Engine *api;
volatile int ref_count;
/* Gstreamer elements */ /* Gstreamer elements */
GstElement *pipeline; GstElement *pipeline;
GstElement *vsink; GstElement *vsink;
@ -64,9 +66,6 @@ struct _Emotion_Gstreamer
Emotion_Gstreamer_Metadata *metadata; Emotion_Gstreamer_Metadata *metadata;
int in;
int out;
Emotion_Vis vis; Emotion_Vis vis;
Eina_Bool play : 1; Eina_Bool play : 1;
@ -74,7 +73,7 @@ struct _Emotion_Gstreamer
Eina_Bool audio_mute : 1; Eina_Bool audio_mute : 1;
Eina_Bool play_started : 1; Eina_Bool play_started : 1;
Eina_Bool pipeline_parsed : 1; Eina_Bool pipeline_parsed : 1;
Eina_Bool shutdown : 1; Eina_Bool shutdown : 1;
}; };
struct _EmotionVideoSink { struct _EmotionVideoSink {
@ -204,6 +203,9 @@ Emotion_Gstreamer_Message *emotion_gstreamer_message_alloc(Emotion_Gstreamer *ev
GstMessage *msg); GstMessage *msg);
void emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send); void emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send);
Emotion_Gstreamer * emotion_gstreamer_ref (Emotion_Gstreamer *ev);
void emotion_gstreamer_unref (Emotion_Gstreamer *ev);
typedef struct _ColorSpace_Format_Convertion ColorSpace_Format_Convertion; typedef struct _ColorSpace_Format_Convertion ColorSpace_Format_Convertion;
struct _ColorSpace_Format_Convertion struct _ColorSpace_Format_Convertion