/* 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;
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;
/* 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;
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");
/* 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);
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)) {