Release resources after finishing change of gst state to NULL 75/234575/2
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 27 May 2020 04:23:50 +0000 (13:23 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 28 May 2020 05:43:44 +0000 (14:43 +0900)
[Version] 0.1.45
[Issue Type] Bug fix

Change-Id: I021849c35725ac757218ec2071491168d579625a
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/media_streamer_priv.h
packaging/capi-media-streamer.spec
src/media_streamer_gst.c
src/media_streamer_priv.c

index 4fcece7..cb2355c 100644 (file)
@@ -160,8 +160,6 @@ int ms_create(media_streamer_s *ms_streamer);
  */
 int ms_set_state(media_streamer_s *ms_streamer, media_streamer_state_e state);
 
-int ms_release_resources(media_streamer_s *ms_streamer);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 46f6ffb..27bf58a 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-streamer
 Summary:    A Media Streamer API
-Version:    0.1.44
+Version:    0.1.45
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 1bd258e..4eadf70 100644 (file)
@@ -1996,7 +1996,7 @@ static int __ms_gstreamer_init(media_streamer_s *ms_streamer)
                return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
        }
 
-       /* get argc(number of command line option), argc is always one widthout option */
+       /* get argc(number of command line option), argc is always one without option */
        *argc = 1;
        if (ms_streamer->ini.gst_args)
                (*argc) += g_strv_length(ms_streamer->ini.gst_args); /* default is "--gst-debug = 2 */
@@ -2243,9 +2243,8 @@ int ms_pipeline_unprepare(media_streamer_s *ms_streamer)
                ms_error("Failed to unprepare pipeline");
 
        if (!ms_streamer->is_interrupted) {
+               /* FIXME: it seems possible to move codes below to ms_set_state(), need to check the history. */
                /* Unprepare resources in case of failure */
-               ms_release_resources(ms_streamer);
-
                if (ms_streamer->video_decoder_resource != NULL) {
                        ret = mm_resource_manager_mark_for_release(ms_streamer->resource_manager,
                                        ms_streamer->video_decoder_resource);
index 0791f5b..0fabbb9 100644 (file)
 
 #define GST_TIME_TO_MSEC(t) (t == GST_CLOCK_TIME_NONE ? t : (int)(((GstClockTime)(t)) / GST_MSECOND))
 
-static int __ms_change_resources_state(media_streamer_s *ms_streamer, media_streamer_state_e state);
 static int __ms_change_dpm_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state);
 static gboolean __ms_resource_node_find(gpointer key, gpointer value, gpointer user_data);
 static int __ms_resource_release_cb(mm_resource_manager_h rm,
                mm_resource_manager_res_h resource_h, void *user_data);
+static int __ms_acquire_resources(media_streamer_s *ms_streamer);
+static int __ms_release_resources(media_streamer_s *ms_streamer);
 
 int ms_set_state(media_streamer_s *ms_streamer, media_streamer_state_e state)
 {
@@ -40,37 +41,48 @@ int ms_set_state(media_streamer_s *ms_streamer, media_streamer_state_e state)
        if (!ms_streamer->is_interrupted) {
                ret = __ms_change_dpm_policy_state(ms_streamer, state);
                if (MEDIA_STREAMER_ERROR_NONE != ret) {
-                       ms_error("Failed to change policy state for streamer %p", ms_streamer);
-                       return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
-               }
-               ret = __ms_change_resources_state(ms_streamer, state);
-               if (MEDIA_STREAMER_ERROR_NONE != ret) {
-                       ms_error("Failed to change resources state for streamer %p", ms_streamer);
+                       ms_error("Failed to change DPM policy state for streamer %p", ms_streamer);
                        return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
                }
        }
 
        switch (state) {
        case MEDIA_STREAMER_STATE_NONE:
-               /*
-                * Media streamer must be in IDLE state
-                * Unlink and destroy all bins and elements.
-                */
+               /* Media streamer must be in IDLE state
+                * Unlink and destroy all bins and elements. */
                ret = ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
-               ms_streamer->pend_state = 0;
+               ms_streamer->pend_state = MEDIA_STREAMER_STATE_NONE;
                ms_streamer->state = state;
                break;
-       case MEDIA_STREAMER_STATE_IDLE:
-               /*
-                * Unlink all gst_elements, set pipeline into state NULL
-                */
+       case MEDIA_STREAMER_STATE_IDLE: {
+               media_streamer_state_e prev_pend_state = ms_streamer->pend_state;
+               /* Unlink all gst_elements, set pipeline into state NULL. */
                ret = ms_element_set_state(ms_streamer->pipeline, GST_STATE_NULL);
                ms_bin_foreach_elements(GST_BIN(ms_streamer->sink_bin), ms_element_unlock_state, ms_streamer);
+
+               /* Release resources, use ms_pipeline_get_state() to ensure the state change finish. */
+               ms_pipeline_get_state(ms_streamer);
+               if (!ms_streamer->is_interrupted &&
+                       (prev_pend_state == MEDIA_STREAMER_STATE_READY ||
+                       prev_pend_state == MEDIA_STREAMER_STATE_PAUSED ||
+                       prev_pend_state == MEDIA_STREAMER_STATE_PLAYING)) {
+                       ret = __ms_release_resources(ms_streamer);
+               }
                ms_streamer->pend_state = MEDIA_STREAMER_STATE_IDLE;
                ms_streamer->state = state;
-
                break;
+       }
        case MEDIA_STREAMER_STATE_READY:
+               /* Acquire resources */
+               if (!ms_streamer->is_interrupted &&
+                       ms_streamer->pend_state == MEDIA_STREAMER_STATE_IDLE) {
+                       ret = __ms_acquire_resources(ms_streamer);
+                       if (MEDIA_STREAMER_ERROR_NONE != ret) {
+                               ms_error("Failed to change resources state for streamer %p", ms_streamer);
+                               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+                       }
+               }
+
                ret = ms_element_set_state(ms_streamer->pipeline, GST_STATE_PAUSED);
                ms_streamer->pend_state = MEDIA_STREAMER_STATE_READY;
                break;
@@ -233,7 +245,7 @@ int ms_destroy(media_streamer_s *ms_streamer)
        return ret;
 }
 
-int ms_acquire_resources(media_streamer_s *ms_streamer)
+static int __ms_acquire_resources(media_streamer_s *ms_streamer)
 {
        int ret = MEDIA_STREAMER_ERROR_NONE;
 
@@ -273,7 +285,7 @@ int ms_acquire_resources(media_streamer_s *ms_streamer)
        return MEDIA_STREAMER_ERROR_NONE;
 }
 
-int ms_release_resources(media_streamer_s *ms_streamer)
+static int __ms_release_resources(media_streamer_s *ms_streamer)
 {
        int ret = MEDIA_STREAMER_ERROR_NONE;
 
@@ -312,53 +324,6 @@ int ms_release_resources(media_streamer_s *ms_streamer)
        return MEDIA_STREAMER_ERROR_NONE;
 }
 
-static int __ms_change_resources_state(media_streamer_s *ms_streamer, media_streamer_state_e state)
-{
-       int ret = MEDIA_STREAMER_ERROR_NONE;
-
-       ms_debug_fenter();
-
-       ms_retvm_if(ms_streamer == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "ms_streamer is NULL");
-
-       /* According to state graph we need to handle only this two states
-        * and different transitions into them */
-       if (state == MEDIA_STREAMER_STATE_IDLE) {
-               switch (ms_streamer->pend_state) {
-               case MEDIA_STREAMER_STATE_READY:
-               case MEDIA_STREAMER_STATE_PAUSED:
-               case MEDIA_STREAMER_STATE_PLAYING:
-                       /* After unprepare function call */
-                       ret = ms_release_resources(ms_streamer);
-                       break;
-               case MEDIA_STREAMER_STATE_NONE:
-               case MEDIA_STREAMER_STATE_IDLE:
-                       /* We do not considering double unprepare */
-               case MEDIA_STREAMER_STATE_SEEKING:
-               default:
-                       break;
-               }
-       } else if (state == MEDIA_STREAMER_STATE_READY) {
-               switch (ms_streamer->pend_state) {
-               case MEDIA_STREAMER_STATE_IDLE:
-                       /* After prepare function */
-                       ret = ms_acquire_resources(ms_streamer);
-                       break;
-               case MEDIA_STREAMER_STATE_PAUSED:
-               case MEDIA_STREAMER_STATE_PLAYING:
-               case MEDIA_STREAMER_STATE_NONE:
-               case MEDIA_STREAMER_STATE_SEEKING:
-               default:
-                       break;
-               }
-       } else {
-               ms_debug("Ignoring state for resource managements");
-       }
-
-       ms_debug_fleave();
-
-       return ret;
-}
-
 //LCOV_EXCL_START
 static gboolean __ms_resource_node_find(gpointer key, gpointer value, gpointer user_data)
 {