+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;
+}
+