mm-resource manager integration patch 31/224131/7 accepted/tizen/unified/20200212.125921 submit/tizen/20200211.042852
authorHyunsoo Park <hance.park@samsung.com>
Thu, 6 Feb 2020 11:04:59 +0000 (20:04 +0900)
committerHyunsoo Park <hance.park@samsung.com>
Tue, 11 Feb 2020 01:56:48 +0000 (10:56 +0900)
Change-Id: Ia0e0981953e9805f86b87729f1d0f7248eec76ba
Signed-off-by: Hyunsoo Park <hance.park@samsung.com>
configure.ac
packaging/libmm-wfd.spec
src/Makefile.am
src/include/mm_wfd_sink_attrs.h
src/include/mm_wfd_sink_priv.h
src/mm_wfd_sink_priv.c

index 3a6946a..8c73ab7 100644 (file)
@@ -103,6 +103,10 @@ PKG_CHECK_MODULES(CAPI_SYSTEM_INFO, capi-system-info)
 AC_SUBST(CAPI_SYSTEM_INFO_CFLAGS)
 AC_SUBST(CAPI_SYSTEM_INFO_LIBS)
 
+PKG_CHECK_MODULES(MM_RESOURCE_MANAGER, mm-resource-manager)
+AC_SUBST(MM_RESOURCE_MANAGER_CFLAGS)
+AC_SUBST(MM_RESOURCE_MANAGER_LIBS)
+
 AC_ARG_ENABLE(tests, AC_HELP_STRING([--enable-tests], [unittest build]),
      [
         case "${enableval}" in
index 6644f84..fd4b814 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-wfd
 Summary:    Multimedia Framework Wifi-Display Library
-Version:    0.3.1
+Version:    0.3.2
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
@@ -21,6 +21,7 @@ BuildRequires: pkgconfig(ecore-wl2)
 BuildRequires: pkgconfig(libtbm)
 BuildRequires: pkgconfig(libtzplatform-config)
 BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(mm-resource-manager)
 %if 0%{?gtests:1}
 BuildRequires:  pkgconfig(gmock)
 %endif
index 033f2df..c0aa245 100644 (file)
@@ -31,7 +31,7 @@ libmmfwfdsink_la_CFLAGS = -I$(srcdir)/include \
                        $(GST_VIDEO_CFLAGS) \
                        $(TZPLATFORM_CONFIG_CFLAGS) \
                        $(CAPI_SYSTEM_INFO_CFLAGS) \
-                       $(AUDIOSESSIONMGR_CFLAGS)
+                       $(MM_RESOURCE_MANAGER_CFLAGS)
 
 libmmfwfdsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
@@ -45,10 +45,10 @@ libmmfwfdsink_la_LIBADD = $(GST_LIBS) \
                        $(EVAS_LIBS) \
                        $(ECORE_WL2_LIBS) \
                        $(MMCOMMON_LIBS) \
-                       $(AUDIOSESSIONMGR_LIBS) \
                        $(TZPLATFORM_CONFIG_LIBS) \
                        $(CAPI_SYSTEM_INFO_LIBS) \
-                       $(GST_VIDEO_LIBS)
+                       $(GST_VIDEO_LIBS) \
+                       $(MM_RESOURCE_MANAGER_LIBS)
 
 libmmfwfdsink_la_CFLAGS += $(MMLOG_CFLAGS) -DMMF_LOG_OWNER=0x02000000 -DMMF_DEBUG_PREFIX=\"MMF-WFD-SINK\"
 libmmfwfdsink_la_LIBADD += $(MMLOG_LIBS)
index cfa5067..6b5a96a 100644 (file)
@@ -24,6 +24,7 @@
 #define __MM_WFD_ATTRS_H__
 
 #include <string.h>
+#include <stdlib.h>
 #include <glib.h>
 #include <mm_message.h>
 #include <mm_error.h>
index cafd401..5e7f92b 100644 (file)
@@ -32,6 +32,7 @@
 #include <mm_message.h>
 #include <mm_error.h>
 #include <mm_types.h>
+#include <mm_resource_manager.h>
 
 #include "mm_wfd_sink_ini.h"
 #include "mm_wfd_sink_attrs.h"
@@ -143,6 +144,12 @@ typedef enum {
        MM_WFD_SINK_RESOLUTION_MAX = 128,
 } MMWFDSinkResolution;
 
+typedef enum {
+       MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER,
+       MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY,
+       MM_WFD_SINK_RESOURCE_TYPE_MAX,
+} MMWFDSinkResourceType;
+
 typedef struct {
        gint codec;
        gint width;
@@ -252,6 +259,11 @@ typedef struct {
        guint coupled_sink_status;
        gchar *coupled_sink_address;
        gboolean is_coupled_sink_supported;
+
+       /* resource manager for H/W resources */
+       mm_resource_manager_h resource_manager;
+       mm_resource_manager_res_h hw_resource[MM_WFD_SINK_RESOURCE_TYPE_MAX];
+       gboolean interrupted_by_resource;
 } mm_wfd_sink_t;
 
 
index 960ab2e..41f8dea 100644 (file)
@@ -46,6 +46,116 @@ static gboolean _mm_wfd_sink_msg_callback(GstBus *bus, GstMessage *msg, gpointer
 /* util */
 static void __mm_wfd_sink_dump_pipeline_state(mm_wfd_sink_t *wfd_sink);
 
+static int
+__resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
+               void *user_data)
+{
+       mm_wfd_sink_t *wfdsink = NULL;
+       MMWFDSinkResourceType res_idx = MM_WFD_SINK_RESOURCE_TYPE_MAX;
+
+       wfd_sink_debug_fenter();
+
+       if (!user_data) {
+               wfd_sink_error("user_data is null");
+               return FALSE;
+       }
+
+       wfdsink = (mm_wfd_sink_t *)user_data;
+
+       wfdsink->interrupted_by_resource = TRUE;
+
+       wfd_sink_debug("resource is interrupted. resource would be released after destroying");
+
+       if (_mm_wfd_sink_disconnect(wfdsink) != MM_ERROR_NONE)
+               wfd_sink_error("failed to disconnect");
+
+       if (_mm_wfd_sink_unprepare(wfdsink) != MM_ERROR_NONE)
+               wfd_sink_error("failed to unprepare");
+
+       if (_mm_wfd_sink_destroy(wfdsink) != MM_ERROR_NONE)
+               wfd_sink_error("failed to destroy");
+
+       for (res_idx = MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MM_WFD_SINK_RESOURCE_TYPE_MAX; res_idx++) {
+               wfdsink->hw_resource[res_idx] = NULL;
+       }
+
+       wfd_sink_debug_fleave();
+       return TRUE; /* release all the resources */
+}
+
+static int __mm_wfd_sink_acquire_hw_resource (mm_wfd_sink_t* wfd_sink, MMWFDSinkResourceType type)
+{
+       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       mm_resource_manager_res_type_e rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
+
+       switch (type) {
+               case MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER:
+                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER;
+                       break;
+               case MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY:
+                       rm_res_type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY;
+                       break;
+               default:
+                       wfd_sink_error("invalid wfd sink resource type %d", type);
+                       return MM_ERROR_WFD_INTERNAL;
+       }
+
+       if (wfd_sink->hw_resource[type] != NULL) {
+               wfd_sink_debug("[%d type] resource was already acquired", type);
+               return MM_ERROR_NONE;
+       }
+
+       wfd_sink_debug("mark for acquire [%d type] resource", type);
+       rm_ret = mm_resource_manager_mark_for_acquire(wfd_sink->resource_manager,
+                       rm_res_type, MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &wfd_sink->hw_resource[type]);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               wfd_sink_error("failed to mark resource for acquire, ret(0x%x)", rm_ret);
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       rm_ret = mm_resource_manager_commit(wfd_sink->resource_manager);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               wfd_sink_error("failed to commit of resource, ret(0x%x)", rm_ret);
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       wfd_sink_debug_fleave();
+       return MM_ERROR_NONE;
+}
+
+static int __mm_wfd_sink_release_hw_resource(mm_wfd_sink_t *wfd_sink, MMWFDSinkResourceType type)
+{
+       int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE;
+
+       wfd_sink_debug_fenter();
+
+       if (wfd_sink->hw_resource[type] == NULL) {
+               wfd_sink_debug("there is no acquired [%d type] resource", type);
+               return MM_ERROR_NONE;
+       }
+
+       wfd_sink_debug("mark for release [%d type] resource", type);
+       rm_ret = mm_resource_manager_mark_for_release(wfd_sink->resource_manager, wfd_sink->hw_resource[type]);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               wfd_sink_error("failed to mark resource for release, ret(0x%x)", rm_ret);
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       wfd_sink->hw_resource[type] = NULL;
+
+       rm_ret = mm_resource_manager_commit(wfd_sink->resource_manager);
+       if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               wfd_sink_error("failed to commit of resource, ret(0x%x)", rm_ret);
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       wfd_sink_debug_fleave();
+       return MM_ERROR_NONE;
+}
+
 int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink, const char *ini_path)
 {
        int result = MM_ERROR_NONE;
@@ -67,6 +177,15 @@ int _mm_wfd_sink_create(mm_wfd_sink_t **wfd_sink, const char *ini_path)
                return MM_ERROR_WFD_NO_FREE_SPACE;
        }
 
+       /* initialize resource manager */
+       if (mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
+               __resource_release_cb, new_wfd_sink, &new_wfd_sink->resource_manager)
+               != MM_RESOURCE_MANAGER_ERROR_NONE) {
+               wfd_sink_error("failed to initialize resource manager");
+               result = MM_ERROR_WFD_INTERNAL;
+               goto fail_to_init;
+       }
+
        /* Initialize gstreamer related */
        new_wfd_sink->attrs = 0;
 
@@ -400,6 +519,16 @@ int _mm_wfd_sink_unprepare(mm_wfd_sink_t *wfd_sink)
        /* set state */
        __mm_wfd_sink_set_state(wfd_sink,  MM_WFD_SINK_STATE_NULL);
 
+       if (!wfd_sink->interrupted_by_resource) {
+               int rm_ret = MM_ERROR_NONE;
+               MMWFDSinkResourceType res_idx = MM_WFD_SINK_RESOURCE_TYPE_MAX;
+
+               for (res_idx = MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MM_WFD_SINK_RESOURCE_TYPE_MAX; res_idx++) {
+                       rm_ret = __mm_wfd_sink_release_hw_resource(wfd_sink, res_idx);
+                       if (rm_ret != MM_ERROR_NONE)
+                               wfd_sink_error("failed to release [%d] resources", res_idx);
+               }
+       }
        wfd_sink_debug_fleave();
 
        return result;
@@ -4343,6 +4472,16 @@ int __mm_wfd_sink_create_video_decodebin(mm_wfd_sink_t *wfd_sink)
                MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_H264_PARSE].gst,  "sink");
                MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_H264_PARSE].gst,  "src");
 
+               if (!g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "sprddec_h264") ||
+                       !g_strcmp0(wfd_sink->ini.name_of_video_h264_decoder, "omxdec_h264")) {
+                       /* acquire HW resource */
+                       wfd_sink_error("wfd_sink->ini.name_of_video_h264_decoder1 :: %s", wfd_sink->ini.name_of_video_h264_decoder);
+                       if (__mm_wfd_sink_acquire_hw_resource(wfd_sink, MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER) != MM_ERROR_NONE) {
+                               wfd_sink_error("failed to acquire video decoder resource");
+                               goto CREATE_ERROR;
+                       }
+               }
+
                /* create dec */
                MMWFDSINK_CREATE_ELEMENT(v_decodebin, WFD_SINK_V_D_H264_DEC, wfd_sink->ini.name_of_video_h264_decoder, "video_h264_dec", FALSE);
                MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_decodebin[WFD_SINK_V_D_H264_DEC].gst,  "sink");
@@ -4576,8 +4715,8 @@ int __mm_wfd_sink_create_video_sinkbin(mm_wfd_sink_t *wfd_sink)
 
        /* create sink */
        mm_attrs_get_int_by_name(wfd_sink->attrs, "display_surface_type", &surface_type);
-
-       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
+       if (surface_type == MM_DISPLAY_SURFACE_OVERLAY &&
+               (__mm_wfd_sink_acquire_hw_resource(wfd_sink, MM_WFD_SINK_RESOURCE_TYPE_VIDEO_OVERLAY) == MM_ERROR_NONE)) {
                MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_sink, "video_sink", TRUE);
        } else if (surface_type == MM_DISPLAY_SURFACE_EVAS) {
                MMWFDSINK_CREATE_ELEMENT(v_sinkbin, WFD_SINK_V_S_SINK, wfd_sink->ini.name_of_video_evas_sink, "video_sink", TRUE);
@@ -4586,6 +4725,8 @@ int __mm_wfd_sink_create_video_sinkbin(mm_wfd_sink_t *wfd_sink)
                goto CREATE_ERROR;
        }
 
+       wfd_sink->interrupted_by_resource = FALSE;
+
        MMWFDSINK_PAD_PROBE(wfd_sink, NULL, v_sinkbin[WFD_SINK_V_S_SINK].gst,  "sink");
        if (v_sinkbin[WFD_SINK_V_S_SINK].gst) {
                if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videosink(wfd_sink, v_sinkbin[WFD_SINK_V_S_SINK].gst)) {