change appid acquisition method due to AMD latency
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_rm.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyuntae Kim <ht1211.kim@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22  /*=======================================================================================
23 |  INCLUDE FILES                                                                        |
24 ========================================================================================*/
25 #ifdef _MMCAMCORDER_RM_SUPPORT
26 #include <aul.h>
27 #include <rm_api.h>
28 #include <ri-api.h>
29 #include <ri-module-api.h>
30 #include <resource_center.h>
31 #include "mm_camcorder_rm.h"
32 #include "mm_camcorder_internal.h"
33
34 #define PROCESS_NAME_PATH_MAX   200
35
36 static rm_cb_result __mmcamcorder_rm_callback(int handle, rm_callback_type event_src,
37         rm_device_request_s *info, void* cb_data)
38 {
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;
42
43         mmf_return_val_if_fail((MMHandleType)hcamcorder, RM_CB_RESULT_OK);
44
45         current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
46
47         MMCAM_LOG_WARNING("current state %d (handle %p)", current_state, hcamcorder);
48
49         _MMCAMCORDER_LOCK_INTERRUPT(hcamcorder);
50
51         /* set RM event code for sending it to application */
52         hcamcorder->interrupt_code = event_src;
53
54         MMCAM_LOG_INFO("RM conflict callback : event code 0x%x", event_src);
55         switch (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);
59                 break;
60         default:
61                 break;
62         }
63
64         _MMCAMCORDER_UNLOCK_INTERRUPT(hcamcorder);
65
66         return cb_res;
67 }
68
69 void _mmcamcorder_get_appid_bypid(int pid, char *name, size_t size)
70 {
71         FILE *cmdline;
72         char buf[PROCESS_NAME_PATH_MAX];
73         int length;
74         unsigned int buf_pos = 0;
75         unsigned int ret_pos = 0;
76         char *read = NULL;
77
78
79         mmf_return_if_fail(name);
80
81         if (size > 0u) {
82                 name[0] = 0;
83         }
84
85         length = snprintf(buf, sizeof(buf), "/proc/%d/cmdline", (int)pid);
86         if (length >= (int)sizeof(buf))
87                 return;
88
89         cmdline = fopen(buf, "r");
90         if (NULL == cmdline) {
91                 MMCAM_LOG_ERROR("File[%s] open failed", buf);
92                 return;
93         }
94
95         read = fgets(buf, sizeof(buf), cmdline);
96         fclose(cmdline);
97
98         if (NULL == read) {
99                 MMCAM_LOG_ERROR("File read failed");
100                 return;
101         }
102
103         for (buf_pos = 0; buf_pos < sizeof(buf); buf_pos++) {
104                 switch(buf[buf_pos]) {
105                         case '\0':
106                                 name[ret_pos] = '\0';
107                                 return;
108                         case '/':
109                                 ret_pos = 0;
110                                 break;
111                         default:
112                                 if (ret_pos < size)
113                                         name[ret_pos] = buf[buf_pos];
114
115                                 ret_pos++;
116                                 break;
117                 }
118         }
119
120 }
121
122
123 int _mmcamcorder_rm_create(MMHandleType handle)
124 {
125         int ret = RM_OK;
126
127         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
128         if (!hcamcorder) {
129                 MMCAM_LOG_ERROR("Not initialized");
130                 return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
131         }
132         memset(&hcamcorder->rci, 0x00, sizeof(rm_consumer_info));
133         mm_camcorder_get_attributes(handle, NULL,
134                 MMCAM_CLIENT_PID, &hcamcorder->rci.app_pid,
135                 NULL);
136         _mmcamcorder_get_appid_bypid(hcamcorder->rci.app_pid, hcamcorder->rci.app_id, sizeof(hcamcorder->rci.app_id));
137
138         /* RM register */
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,
142                         (void*)hcamcorder,
143                         &(hcamcorder->rm_handle),
144                         (hcamcorder->rci.app_id[0] != '\0') ? &hcamcorder->rci : NULL);
145                 if (ret != RM_OK) {
146                         MMCAM_LOG_ERROR("rm_register fail ret = %d",ret);
147                         return MM_ERROR_RESOURCE_INTERNAL;
148                 }
149         }
150         return MM_ERROR_NONE;
151 }
152
153 int _mmcamcorder_rm_allocate(MMHandleType handle)
154 {
155         int iret = RM_OK;
156         int preview_format = MM_PIXEL_FORMAT_NV12;
157         int qret = RM_OK;
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;
162
163         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
164         if (!hcamcorder) {
165                 MMCAM_LOG_ERROR("Not initialized");
166                 return MM_ERROR_CAMCORDER_NOT_INITIALIZED;
167         }
168
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. */
173
174         mm_camcorder_get_attributes(handle, NULL,
175                 MMCAM_DISPLAY_SURFACE, &display_surface_type,
176                 NULL);
177
178         if (display_surface_type != MM_DISPLAY_SURFACE_NULL) {
179                 mm_camcorder_get_attributes(handle, NULL,
180                         MMCAM_CAMERA_FORMAT, &preview_format,
181                         NULL);
182
183                 resource_count = 0;
184                 memset(&hcamcorder->request_resources, 0x0, sizeof(rm_category_request_s));
185                 memset(&hcamcorder->returned_devices, 0x0, sizeof(rm_device_return_s));
186
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);
192
193                         resource_count++;
194                 } else if (preview_format == MM_PIXEL_FORMAT_ENCODED_MJPEG) {
195                         mm_camcorder_get_attributes(handle, NULL,
196                                 MMCAM_CAMERA_WIDTH, &camera_width,
197                                 NULL);
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);
202                         resource_count++;
203                 }
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);
209                         resource_count++;
210                 }
211
212                 hcamcorder->request_resources.request_num = resource_count;
213
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");
218                                 resource_count = 0;
219                                 memset(&hcamcorder->request_resources, 0x0, sizeof(rm_category_request_s));
220                                 memset(&hcamcorder->returned_devices, 0x0, sizeof(rm_device_return_s));
221
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);
227                                         resource_count++;
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);
233                                         resource_count++;
234                                 }
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);
241                                         resource_count++;
242                                 }
243                         }
244                 }
245         }
246
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);
250
251         hcamcorder->request_resources.request_num = resource_count + 1;
252         MMCAM_LOG_INFO("request camera rsc - category 0x%x", RM_CATEGORY_CAMERA);
253
254         iret = rm_allocate_resources(hcamcorder->rm_handle, &(hcamcorder->request_resources), &hcamcorder->returned_devices);
255         if (iret != RM_OK) {
256                 MMCAM_LOG_ERROR("Resource allocation request failed ret = %d",iret);
257                 return MM_ERROR_RESOURCE_INTERNAL;
258         }
259
260         return MM_ERROR_NONE;
261 }
262
263
264 int _mmcamcorder_rm_deallocate(MMHandleType handle)
265 {
266         int rm_ret = RM_OK;
267         int idx = 0;
268         rm_device_request_s requested;
269
270         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
271         rm_device_return_s *r_devices;
272
273         if (!hcamcorder->rm_handle) {
274                 MMCAM_LOG_ERROR("Resource is not initialized ");
275                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
276         }
277
278         r_devices = &hcamcorder->returned_devices;
279
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];
285
286                 rm_ret = rm_deallocate_resources(hcamcorder->rm_handle, &requested);
287                 if (rm_ret != RM_OK)
288                         MMCAM_LOG_ERROR("Resource deallocation request failed ");
289         }
290
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;
295                 }
296                 if (r_devices->omx_comp_name[idx]) {
297                         free(r_devices->omx_comp_name[idx]);
298                         r_devices->omx_comp_name[idx] = NULL;
299                 }
300         }
301
302         return MM_ERROR_NONE;
303 }
304
305 int _mmcamcorder_rm_release(MMHandleType handle)
306 {
307         int rm_ret = RM_OK;
308
309         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
310
311         if (!hcamcorder->rm_handle) {
312                 MMCAM_LOG_ERROR("Resource is not initialized ");
313                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
314         }
315
316         /* unregister RM */
317         rm_ret = rm_unregister(hcamcorder->rm_handle);
318         if (rm_ret != RM_OK)
319                 MMCAM_LOG_ERROR("rm_unregister() failed");
320         hcamcorder->rm_handle = 0;
321
322         return MM_ERROR_NONE;
323 }
324
325 #endif /* _MMCAMCORDER_RM_SUPPORT*/
326