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 #define PROCESS_NAME_PATH_MAX 200
36 static rm_cb_result __mmcamcorder_rm_callback(int handle, rm_callback_type event_src,
37 rm_device_request_s *info, void* cb_data)
39 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(cb_data);
40 int current_state = MM_CAMCORDER_STATE_NONE;
41 rm_cb_result cb_res = RM_CB_RESULT_OK;
43 mmf_return_val_if_fail((MMHandleType)hcamcorder, RM_CB_RESULT_OK);
45 current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
47 MMCAM_LOG_WARNING("current state %d (handle %p)", current_state, hcamcorder);
49 _MMCAMCORDER_LOCK_INTERRUPT(hcamcorder);
51 /* set RM event code for sending it to application */
52 hcamcorder->interrupt_code = event_src;
54 MMCAM_LOG_INFO("RM conflict callback : event code 0x%x", event_src);
56 case RM_CALLBACK_TYPE_RESOURCE_CONFLICT:
57 case RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD:
58 __mmcamcorder_force_stop(hcamcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
64 _MMCAMCORDER_UNLOCK_INTERRUPT(hcamcorder);
69 void _mmcamcorder_get_appid_bypid(int pid, char *name, size_t size)
72 char buf[PROCESS_NAME_PATH_MAX];
74 unsigned int buf_pos = 0;
75 unsigned int ret_pos = 0;
79 mmf_return_if_fail(name);
85 length = snprintf(buf, sizeof(buf), "/proc/%d/cmdline", (int)pid);
86 if (length >= (int)sizeof(buf))
89 cmdline = fopen(buf, "r");
90 if (NULL == cmdline) {
91 MMCAM_LOG_ERROR("File[%s] open failed", buf);
95 read = fgets(buf, sizeof(buf), cmdline);
99 MMCAM_LOG_ERROR("File read failed");
103 for (buf_pos = 0; buf_pos < sizeof(buf); buf_pos++) {
104 switch(buf[buf_pos]) {
106 name[ret_pos] = '\0';
113 name[ret_pos] = buf[buf_pos];
123 int _mmcamcorder_rm_create(MMHandleType handle)
127 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
129 MMCAM_LOG_ERROR("Not initialized");
130 return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
132 memset(&hcamcorder->rci, 0x00, sizeof(rm_consumer_info));
133 mm_camcorder_get_attributes(handle, NULL,
134 MMCAM_CLIENT_PID, &hcamcorder->rci.app_pid,
136 _mmcamcorder_get_appid_bypid(hcamcorder->rci.app_pid, hcamcorder->rci.app_id, sizeof(hcamcorder->rci.app_id));
139 /* NULL should be passed for the rci parameter if the application does not have "visibility" */
140 if (hcamcorder->rm_handle == 0) {
141 ret = rm_register((rm_resource_cb)__mmcamcorder_rm_callback,
143 &(hcamcorder->rm_handle),
144 (hcamcorder->rci.app_id[0] != '\0') ? &hcamcorder->rci : NULL);
146 MMCAM_LOG_ERROR("rm_register fail ret = %d",ret);
147 return MM_ERROR_RESOURCE_INTERNAL;
150 return MM_ERROR_NONE;
153 int _mmcamcorder_rm_allocate(MMHandleType handle)
156 int preview_format = MM_PIXEL_FORMAT_NV12;
158 int qret_avail = 0; /* 0: not available, 1: available */
159 int resource_count = 0;
160 int display_surface_type = MM_DISPLAY_SURFACE_OVERLAY;
161 int camera_width = 0;
163 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
165 MMCAM_LOG_ERROR("Not initialized");
166 return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
169 MMCAM_LOG_INFO("app id : %s", hcamcorder->rci.app_id);
170 /* if the app_id is null,
171 In the multiview mode, the rc_get_capable_category_id returns the error(RI_CATEGORY_NOT_PERMITTED).
172 In the normal mode, it returns the category itself which is passed in the parameter. */
174 mm_camcorder_get_attributes(handle, NULL,
175 MMCAM_DISPLAY_SURFACE, &display_surface_type,
178 if (display_surface_type != MM_DISPLAY_SURFACE_NULL) {
179 mm_camcorder_get_attributes(handle, NULL,
180 MMCAM_CAMERA_FORMAT, &preview_format,
184 memset(&hcamcorder->request_resources, 0x0, sizeof(rm_category_request_s));
185 memset(&hcamcorder->returned_devices, 0x0, sizeof(rm_device_return_s));
187 if (preview_format == MM_PIXEL_FORMAT_ENCODED_H264) {
188 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
189 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_VIDEO_DECODER;
190 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_CATEGORY_VIDEO_DECODER);
191 MMCAM_LOG_INFO("request dec rsc - category 0x%x", RM_CATEGORY_VIDEO_DECODER);
194 } else if (preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG) {
195 mm_camcorder_get_attributes(handle, NULL,
196 MMCAM_CAMERA_WIDTH, &camera_width,
198 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
199 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_MJPEG_DECODER;
200 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));
201 MMCAM_LOG_INFO("request dec rsc - category 0x%x, option width [%d]", RM_CATEGORY_MJPEG_DECODER, camera_width);
204 if (display_surface_type == MM_DISPLAY_SURFACE_OVERLAY) {
205 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
206 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_SCALER;
207 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_CATEGORY_SCALER);
208 MMCAM_LOG_INFO("request scaler rsc - category 0x%x", RM_CATEGORY_SCALER);
212 hcamcorder->request_resources.request_num = resource_count;
214 if (resource_count > 0) {
215 qret = rm_query(hcamcorder->rm_handle, RM_QUERY_ALLOCATION, &(hcamcorder->request_resources), &qret_avail);
216 if (qret != RM_OK || qret_avail != 1) {
217 MMCAM_LOG_INFO("rm query failed. retry with sub devices");
219 memset(&hcamcorder->request_resources, 0x0, sizeof(rm_category_request_s));
220 memset(&hcamcorder->returned_devices, 0x0, sizeof(rm_device_return_s));
222 if (preview_format == MM_PIXEL_FORMAT_ENCODED_H264) {
223 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
224 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_VIDEO_DECODER_SUB;
225 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_DEVICE_OPT_SUB);
226 MMCAM_LOG_INFO("request dec rsc - category 0x%x", RM_CATEGORY_VIDEO_DECODER_SUB);
228 } else if (preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG) {
229 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
230 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_MJPEG_DECODER;
231 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));
232 MMCAM_LOG_INFO("request dec rsc - category 0x%x", RM_CATEGORY_MJPEG_DECODER);
235 if ((display_surface_type == MM_DISPLAY_SURFACE_OVERLAY) &&
236 (preview_format == MM_PIXEL_FORMAT_ENCODED_H264 || preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG)) {
237 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
238 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_SCALER_SUB;
239 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_DEVICE_OPT_SUB);
240 MMCAM_LOG_INFO("request scaler rsc - category 0x%x", RM_CATEGORY_SCALER_SUB);
247 hcamcorder->request_resources.state[resource_count] = RM_STATE_EXCLUSIVE;
248 hcamcorder->request_resources.category_id[resource_count] = RM_CATEGORY_CAMERA;
249 hcamcorder->request_resources.category_option[resource_count] = rc_get_capable_category_id(hcamcorder->rm_handle, hcamcorder->rci.app_id, RM_CATEGORY_CAMERA);
251 hcamcorder->request_resources.request_num = resource_count + 1;
252 MMCAM_LOG_INFO("request camera rsc - category 0x%x", RM_CATEGORY_CAMERA);
254 iret = rm_allocate_resources(hcamcorder->rm_handle, &(hcamcorder->request_resources), &hcamcorder->returned_devices);
256 MMCAM_LOG_ERROR("Resource allocation request failed ret = %d",iret);
257 return MM_ERROR_RESOURCE_INTERNAL;
260 return MM_ERROR_NONE;
264 int _mmcamcorder_rm_deallocate(MMHandleType handle)
268 rm_device_request_s requested;
270 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
271 rm_device_return_s *r_devices;
273 if (!hcamcorder->rm_handle) {
274 MMCAM_LOG_ERROR("Resource is not initialized ");
275 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
278 r_devices = &hcamcorder->returned_devices;
280 if (r_devices->allocated_num > 0) {
281 memset(&requested, 0x0, sizeof(rm_device_request_s));
282 requested.request_num = r_devices->allocated_num;
283 for (idx = 0; idx < requested.request_num; idx++)
284 requested.device_id[idx] = r_devices->device_id[idx];
286 rm_ret = rm_deallocate_resources(hcamcorder->rm_handle, &requested);
288 MMCAM_LOG_ERROR("Resource deallocation request failed ");
291 for (idx = 0; idx < r_devices->allocated_num; idx++) {
292 if (r_devices->device_node[idx]) {
293 free(r_devices->device_node[idx]);
294 r_devices->device_node[idx] = NULL;
296 if (r_devices->omx_comp_name[idx]) {
297 free(r_devices->omx_comp_name[idx]);
298 r_devices->omx_comp_name[idx] = NULL;
302 return MM_ERROR_NONE;
305 int _mmcamcorder_rm_release(MMHandleType handle)
309 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
311 if (!hcamcorder->rm_handle) {
312 MMCAM_LOG_ERROR("Resource is not initialized ");
313 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
317 rm_ret = rm_unregister(hcamcorder->rm_handle);
319 MMCAM_LOG_ERROR("rm_unregister() failed");
320 hcamcorder->rm_handle = 0;
322 return MM_ERROR_NONE;
325 #endif /* _MMCAMCORDER_RM_SUPPORT*/