4 * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 /*=======================================================================================
24 ========================================================================================*/
25 #ifdef _MMCAMCORDER_RM_SUPPORT
29 #include <ri-module-api.h>
30 #include <resource_center.h>
31 #include "mm_camcorder_rm.h"
32 #include "mm_camcorder_internal.h"
34 static rm_cb_result __mmcamcorder_rm_callback(int handle, rm_callback_type event_src,
35 rm_device_request_s *info, void* cb_data)
37 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(cb_data);
38 int current_state = MM_CAMCORDER_STATE_NONE;
39 rm_cb_result cb_res = RM_CB_RESULT_OK;
41 mmf_return_val_if_fail((MMHandleType)hcamcorder, RM_CB_RESULT_OK);
43 current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
45 MMCAM_LOG_WARNING("current state %d (handle %p)", current_state, hcamcorder);
47 _MMCAMCORDER_LOCK_INTERRUPT(hcamcorder);
49 /* set RM event code for sending it to application */
50 hcamcorder->interrupt_code = event_src;
52 MMCAM_LOG_INFO("RM conflict callback : event code 0x%x", event_src);
54 case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
55 case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
56 __mmcamcorder_force_stop(hcamcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
62 _MMCAMCORDER_UNLOCK_INTERRUPT(hcamcorder);
67 int _mmcamcorder_rm_create(MMHandleType handle)
71 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
73 MMCAM_LOG_ERROR("Not initialized");
74 return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
76 memset(&hcamcorder->rci, 0x00, sizeof(rm_consumer_info));
77 mm_camcorder_get_attributes(handle, NULL,
78 MMCAM_CLIENT_PID, &hcamcorder->rci.app_pid,
80 aul_app_get_appid_bypid(hcamcorder->rci.app_pid, hcamcorder->rci.app_id, sizeof(hcamcorder->rci.app_id));
83 /* NULL should be passed for the rci parameter if the application does not have "visibility" */
84 if (hcamcorder->rm_handle == 0) {
85 ret = rm_register((rm_resource_cb)__mmcamcorder_rm_callback,
87 &(hcamcorder->rm_handle),
88 (hcamcorder->rci.app_id[0] != '\0') ? &hcamcorder->rci : NULL);
90 MMCAM_LOG_ERROR("rm_register fail ret = %d",ret);
91 return MM_ERROR_RESOURCE_INTERNAL;
97 int _mmcamcorder_rm_allocate(MMHandleType handle)
100 int preview_format = MM_PIXEL_FORMAT_NV12;
102 int qret_avail = 0; /* 0: not available, 1: available */
103 int resource_count = 0;
104 int display_surface_type = MM_DISPLAY_SURFACE_OVERLAY;
105 int camera_width = 0;
107 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
109 MMCAM_LOG_ERROR("Not initialized");
110 return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
113 MMCAM_LOG_INFO("app id : %s", hcamcorder->rci.app_id);
114 /* if the app_id is null,
115 In the multiview mode, the rc_get_capable_category_id returns the error(RI_CATEGORY_NOT_PERMITTED).
116 In the normal mode, it returns the category itself which is passed in the parameter. */
118 mm_camcorder_get_attributes(handle, NULL,
119 MMCAM_DISPLAY_SURFACE, &display_surface_type,
122 if (display_surface_type != MM_DISPLAY_SURFACE_NULL) {
123 mm_camcorder_get_attributes(handle, NULL,
124 MMCAM_CAMERA_FORMAT, &preview_format,
128 memset(&hcamcorder->request_resources, 0x0, sizeof(rm_category_request_s));
129 memset(&hcamcorder->returned_devices, 0x0, sizeof(rm_device_return_s));
131 if (preview_format == MM_PIXEL_FORMAT_ENCODED_H264) {
132 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
133 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_VIDEO_DECODER;
134 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_CATEGORY_VIDEO_DECODER);
135 MMCAM_LOG_INFO("request dec rsc - category 0x%x", RM_CATEGORY_VIDEO_DECODER);
138 } else if (preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG) {
139 mm_camcorder_get_attributes(handle, NULL,
140 MMCAM_CAMERA_WIDTH, &camera_width,
142 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
143 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_MJPEG_DECODER;
144 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, ri_get_jpeg_category_id("MJPEG", camera_width));
145 MMCAM_LOG_INFO("request dec rsc - category 0x%x, option width [%d]", RM_CATEGORY_MJPEG_DECODER, camera_width);
148 if (display_surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
149 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
150 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_SCALER;
151 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_CATEGORY_SCALER);
152 MMCAM_LOG_INFO("request scaler rsc - category 0x%x", RM_CATEGORY_SCALER);
156 hcamcorder->request_resources.request_num = resource_count;
158 if (resource_count > 0) {
159 qret = rm_query(hcamcorder->rm_handle, RM_QUERY_ALLOCATION, &(hcamcorder->request_resources), &qret_avail);
160 if (qret != RM_OK || qret_avail != 1) {
161 MMCAM_LOG_INFO("rm query failed. retry with sub devices");
163 memset(&hcamcorder->request_resources, 0x0, sizeof(rm_category_request_s));
164 memset(&hcamcorder->returned_devices, 0x0, sizeof(rm_device_return_s));
166 if (preview_format == MM_PIXEL_FORMAT_ENCODED_H264) {
167 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
168 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_VIDEO_DECODER_SUB;
169 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_DEVICE_OPT_SUB);
170 MMCAM_LOG_INFO("request dec rsc - category 0x%x", RM_CATEGORY_VIDEO_DECODER_SUB);
172 } else if (preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG) {
173 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
174 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_MJPEG_DECODER;
175 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, ri_get_jpeg_category_id("MJPEG", camera_width));
176 MMCAM_LOG_INFO("request dec rsc - category 0x%x", RM_CATEGORY_MJPEG_DECODER);
179 if ((display_surface_type == MM_DISPLAY_SURFACE_OVERLAY) &&
180 (preview_format == MM_PIXEL_FORMAT_ENCODED_H264 || preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG)) {
181 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
182 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_SCALER_SUB;
183 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_DEVICE_OPT_SUB);
184 MMCAM_LOG_INFO("request scaler rsc - category 0x%x", RM_CATEGORY_SCALER_SUB);
191 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
192 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_CAMERA;
193 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_CATEGORY_CAMERA);
195 hcamcorder->request_resources.request_num = resource_count + 1;
196 MMCAM_LOG_INFO("request camera rsc - category 0x%x", RM_CATEGORY_CAMERA);
198 iret = rm_allocate_resources(hcamcorder->rm_handle, &(hcamcorder->request_resources), &hcamcorder->returned_devices);
200 MMCAM_LOG_ERROR("Resource allocation request failed ret = %d",iret);
201 return MM_ERROR_RESOURCE_INTERNAL;
204 return MM_ERROR_NONE;
208 int _mmcamcorder_rm_deallocate(MMHandleType handle)
212 rm_device_request_s requested;
214 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
215 rm_device_return_s *r_devices;
217 if (!hcamcorder->rm_handle) {
218 MMCAM_LOG_ERROR("Resource is not initialized ");
219 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
222 r_devices = &hcamcorder->returned_devices;
224 if (r_devices->allocated_num > 0) {
225 memset(&requested, 0x0, sizeof(rm_device_request_s));
226 requested.request_num = r_devices->allocated_num;
227 for (idx = 0; idx < requested.request_num; idx++)
228 requested.device_id[idx] = r_devices->device_id[idx];
230 rm_ret = rm_deallocate_resources(hcamcorder->rm_handle, &requested);
232 MMCAM_LOG_ERROR("Resource deallocation request failed ");
235 for (idx = 0; idx < r_devices->allocated_num; idx++) {
236 if (r_devices->device_node[idx]) {
237 free(r_devices->device_node[idx]);
238 r_devices->device_node[idx] = NULL;
240 if (r_devices->omx_comp_name[idx]) {
241 free(r_devices->omx_comp_name[idx]);
242 r_devices->omx_comp_name[idx] = NULL;
246 return MM_ERROR_NONE;
249 int _mmcamcorder_rm_release(MMHandleType handle)
253 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
255 if (!hcamcorder->rm_handle) {
256 MMCAM_LOG_ERROR("Resource is not initialized ");
257 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
261 rm_ret = rm_unregister(hcamcorder->rm_handle);
263 MMCAM_LOG_ERROR("rm_unregister() failed");
264 hcamcorder->rm_handle = 0;
266 return MM_ERROR_NONE;
269 #endif /* _MMCAMCORDER_RM_SUPPORT*/