MediaProcessors
video_settings.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Rafael Antoniello
3  *
4  * This file is part of MediaProcessors.
5  *
6  * MediaProcessors is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * MediaProcessors is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with MediaProcessors. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
25 #include "video_settings.h"
26 
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 
31 #include <libcjson/cJSON.h>
32 #include <libmediaprocsutils/uri_parser.h>
33 #include <libmediaprocsutils/log.h>
34 #include <libmediaprocsutils/stat_codes.h>
35 #include <libmediaprocsutils/check_utils.h>
36 #include <libmediaprocs/proc_if.h>
37 
39 {
40  return (video_settings_enc_ctx_t*)calloc(1, sizeof(
42 }
43 
45  video_settings_enc_ctx_t **ref_video_settings_enc_ctx)
46 {
47  video_settings_enc_ctx_t *video_settings_enc_ctx= NULL;
48 
49  if(ref_video_settings_enc_ctx== NULL)
50  return;
51 
52  if((video_settings_enc_ctx= *ref_video_settings_enc_ctx)!= NULL) {
53 
55  video_settings_enc_ctx);
56 
57  free(video_settings_enc_ctx);
58  *ref_video_settings_enc_ctx= NULL;
59  }
60 }
61 
63  volatile video_settings_enc_ctx_t *video_settings_enc_ctx)
64 {
65  LOG_CTX_INIT(NULL);
66 
67  /* Check arguments */
68  CHECK_DO(video_settings_enc_ctx!= NULL, return STAT_ERROR);
69 
70  video_settings_enc_ctx->bit_rate_output= 300*1024;
71  video_settings_enc_ctx->frame_rate_output= 15;
72  video_settings_enc_ctx->width_output= 352;
73  video_settings_enc_ctx->height_output= 288;
74  video_settings_enc_ctx->gop_size= 15;
75  memset((void*)video_settings_enc_ctx->conf_preset, 0,
76  sizeof(video_settings_enc_ctx->conf_preset));
77  return STAT_SUCCESS;
78 }
79 
81  volatile video_settings_enc_ctx_t *video_settings_enc_ctx)
82 {
83  // Reserved for future use
84  // Release here heap-allocated members of the structure.
85 }
86 
88  const video_settings_enc_ctx_t *video_settings_enc_ctx_src,
89  video_settings_enc_ctx_t *video_settings_enc_ctx_dst)
90 {
91  LOG_CTX_INIT(NULL);
92 
93  /* Check arguments */
94  CHECK_DO(video_settings_enc_ctx_src!= NULL, return STAT_ERROR);
95  CHECK_DO(video_settings_enc_ctx_dst!= NULL, return STAT_ERROR);
96 
97  /* Copy simple variable values */
98  memcpy(video_settings_enc_ctx_dst, video_settings_enc_ctx_src,
99  sizeof(video_settings_enc_ctx_t));
100 
101  // Future use: duplicate heap-allocated variables...
102 
103  return STAT_SUCCESS;
104 }
105 
107  volatile video_settings_enc_ctx_t *video_settings_enc_ctx,
108  const char *str, log_ctx_t *log_ctx)
109 {
110  int end_code= STAT_ERROR;
111  int flag_is_query= 0; // 0-> JSON / 1->query string
112  cJSON *cjson_rest= NULL, *cjson_aux= NULL;
113  char *bit_rate_output_str= NULL, *frame_rate_output_str= NULL,
114  *width_output_str= NULL, *height_output_str= NULL,
115  *gop_size_str= NULL, *sample_fmt_input_str= NULL,
116  *profile_str= NULL, *conf_preset_str= NULL;
117  LOG_CTX_INIT(log_ctx);
118 
119  /* Check arguments */
120  CHECK_DO(video_settings_enc_ctx!= NULL, return STAT_ERROR);
121  CHECK_DO(str!= NULL, return STAT_EINVAL);
122 
123  /* Guess string representation format (JSON-REST or Query) */
124  //LOGV("'%s'\n", str); //comment-me
125  flag_is_query= (str[0]=='{' && str[strlen(str)-1]=='}')? 0: 1;
126 
127  /* **** Parse RESTful string to get settings parameters **** */
128 
129  if(flag_is_query== 1) {
130 
131  /* 'bit_rate_output' */
132  bit_rate_output_str= uri_parser_query_str_get_value("bit_rate_output",
133  str);
134  if(bit_rate_output_str!= NULL)
135  video_settings_enc_ctx->bit_rate_output= atoll(bit_rate_output_str);
136 
137  /* 'frame_rate_output' */
138  frame_rate_output_str= uri_parser_query_str_get_value(
139  "frame_rate_output", str);
140  if(frame_rate_output_str!= NULL)
141  video_settings_enc_ctx->frame_rate_output=
142  atoll(frame_rate_output_str);
143 
144  /* 'width_output' */
145  width_output_str= uri_parser_query_str_get_value("width_output", str);
146  if(width_output_str!= NULL)
147  video_settings_enc_ctx->width_output= atoll(width_output_str);
148 
149  /* 'height_output' */
150  height_output_str= uri_parser_query_str_get_value("height_output", str);
151  if(height_output_str!= NULL)
152  video_settings_enc_ctx->height_output= atoll(height_output_str);
153 
154  /* 'gop_size' */
155  gop_size_str= uri_parser_query_str_get_value("gop_size", str);
156  if(gop_size_str!= NULL)
157  video_settings_enc_ctx->gop_size= atoll(gop_size_str);
158 
159  /* 'conf_preset' */
160  conf_preset_str= uri_parser_query_str_get_value("conf_preset", str);
161  if(conf_preset_str!= NULL) {
162  CHECK_DO(strlen(conf_preset_str)<
163  (sizeof(video_settings_enc_ctx->conf_preset)- 1),
164  end_code= STAT_EINVAL; goto end);
165  memcpy((void*)video_settings_enc_ctx->conf_preset, conf_preset_str,
166  strlen(conf_preset_str));
167  video_settings_enc_ctx->conf_preset[strlen(conf_preset_str)]= 0;
168  }
169 
170  } else {
171 
172  /* In the case string format is JSON-REST, parse to cJSON structure */
173  cjson_rest= cJSON_Parse(str);
174  CHECK_DO(cjson_rest!= NULL, goto end);
175 
176  /* 'bit_rate_output' */
177  cjson_aux= cJSON_GetObjectItem(cjson_rest, "bit_rate_output");
178  if(cjson_aux!= NULL)
179  video_settings_enc_ctx->bit_rate_output= cjson_aux->valuedouble;
180 
181  /* 'frame_rate_output' */
182  cjson_aux= cJSON_GetObjectItem(cjson_rest, "frame_rate_output");
183  if(cjson_aux!= NULL)
184  video_settings_enc_ctx->frame_rate_output= cjson_aux->valuedouble;
185 
186  /* 'width_output' */
187  cjson_aux= cJSON_GetObjectItem(cjson_rest, "width_output");
188  if(cjson_aux!= NULL)
189  video_settings_enc_ctx->width_output= cjson_aux->valuedouble;
190 
191  /* 'height_output' */
192  cjson_aux= cJSON_GetObjectItem(cjson_rest, "height_output");
193  if(cjson_aux!= NULL)
194  video_settings_enc_ctx->height_output= cjson_aux->valuedouble;
195 
196  /* 'gop_size' */
197  cjson_aux= cJSON_GetObjectItem(cjson_rest, "gop_size");
198  if(cjson_aux!= NULL)
199  video_settings_enc_ctx->gop_size= cjson_aux->valuedouble;
200 
201  /* 'conf_preset' */
202  cjson_aux= cJSON_GetObjectItem(cjson_rest, "conf_preset");
203  if(cjson_aux!= NULL && cjson_aux->valuestring!= NULL) {
204  CHECK_DO(strlen(cjson_aux->valuestring)<
205  (sizeof(video_settings_enc_ctx->conf_preset)- 1),
206  end_code= STAT_EINVAL; goto end);
207  memcpy((void*)video_settings_enc_ctx->conf_preset,
208  cjson_aux->valuestring, strlen(cjson_aux->valuestring));
209  video_settings_enc_ctx->conf_preset
210  [strlen(cjson_aux->valuestring)]= 0;
211  }
212  }
213 
214  end_code= STAT_SUCCESS;
215 end:
216  if(cjson_rest!= NULL)
217  cJSON_Delete(cjson_rest);
218  if(bit_rate_output_str!= NULL)
219  free(bit_rate_output_str);
220  if(frame_rate_output_str!= NULL)
221  free(frame_rate_output_str);
222  if(width_output_str!= NULL)
223  free(width_output_str);
224  if(height_output_str!= NULL)
225  free(height_output_str);
226  if(gop_size_str!= NULL)
227  free(gop_size_str);
228  if(sample_fmt_input_str!= NULL)
229  free(sample_fmt_input_str);
230  if(profile_str!= NULL)
231  free(profile_str);
232  if(conf_preset_str!= NULL)
233  free(conf_preset_str);
234  return end_code;
235 }
236 
238  volatile video_settings_enc_ctx_t *video_settings_enc_ctx,
239  cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
240 {
241  int end_code= STAT_ERROR;
242  cJSON *cjson_rest= NULL, *cjson_aux= NULL;
243  LOG_CTX_INIT(log_ctx);
244 
245  CHECK_DO(video_settings_enc_ctx!= NULL, goto end);
246  CHECK_DO(ref_cjson_rest!= NULL, goto end);
247 
248  *ref_cjson_rest= NULL;
249 
250  /* Create cJSON tree-root object */
251  cjson_rest= cJSON_CreateObject();
252  CHECK_DO(cjson_rest!= NULL, goto end);
253 
254  /* JSON string to be returned:
255  * {
256  * "bit_rate_output":number,
257  * "frame_rate_output":number,
258  * "width_output":number,
259  * "height_output":number,
260  * "gop_size":number,
261  * "conf_preset":string
262  * }
263  */
264 
265  /* 'bit_rate_output' */
266  cjson_aux= cJSON_CreateNumber((double)
267  video_settings_enc_ctx->bit_rate_output);
268  CHECK_DO(cjson_aux!= NULL, goto end);
269  cJSON_AddItemToObject(cjson_rest, "bit_rate_output", cjson_aux);
270 
271  /* 'frame_rate_output' */
272  cjson_aux= cJSON_CreateNumber((double)
273  video_settings_enc_ctx->frame_rate_output);
274  CHECK_DO(cjson_aux!= NULL, goto end);
275  cJSON_AddItemToObject(cjson_rest, "frame_rate_output", cjson_aux);
276 
277  /* 'width_output' */
278  cjson_aux= cJSON_CreateNumber((double)video_settings_enc_ctx->width_output);
279  CHECK_DO(cjson_aux!= NULL, goto end);
280  cJSON_AddItemToObject(cjson_rest, "width_output", cjson_aux);
281 
282  /* 'height_output' */
283  cjson_aux= cJSON_CreateNumber((double)
284  video_settings_enc_ctx->height_output);
285  CHECK_DO(cjson_aux!= NULL, goto end);
286  cJSON_AddItemToObject(cjson_rest, "height_output", cjson_aux);
287 
288  /* 'gop_size' */
289  cjson_aux= cJSON_CreateNumber((double)video_settings_enc_ctx->gop_size);
290  CHECK_DO(cjson_aux!= NULL, goto end);
291  cJSON_AddItemToObject(cjson_rest, "gop_size", cjson_aux);
292 
293  /* 'conf_preset' */
294  if(video_settings_enc_ctx->conf_preset!= NULL &&
295  strlen((const char*)video_settings_enc_ctx->conf_preset)> 0) {
296  cjson_aux= cJSON_CreateString((const char*)
297  video_settings_enc_ctx->conf_preset);
298  } else {
299  cjson_aux= cJSON_CreateNull();
300  }
301  CHECK_DO(cjson_aux!= NULL, goto end);
302  cJSON_AddItemToObject(cjson_rest, "conf_preset", cjson_aux);
303 
304  *ref_cjson_rest= cjson_rest;
305  cjson_rest= NULL;
306  end_code= STAT_SUCCESS;
307 end:
308  if(cjson_rest!= NULL)
309  cJSON_Delete(cjson_rest);
310  return end_code;
311 }
312 
314 {
315  return (video_settings_dec_ctx_t*)calloc(1, sizeof(
317 }
318 
320  video_settings_dec_ctx_t **ref_video_settings_dec_ctx)
321 {
322  video_settings_dec_ctx_t *video_settings_dec_ctx= NULL;
323 
324  if(ref_video_settings_dec_ctx== NULL)
325  return;
326 
327  if((video_settings_dec_ctx= *ref_video_settings_dec_ctx)!= NULL) {
328 
329  free(video_settings_dec_ctx);
330  *ref_video_settings_dec_ctx= NULL;
331  }
332 }
333 
335  volatile video_settings_dec_ctx_t *video_settings_dec_ctx)
336 {
337  LOG_CTX_INIT(NULL);
338 
339  /* Check arguments */
340  CHECK_DO(video_settings_dec_ctx!= NULL, return STAT_ERROR);
341 
342  // Reserved for future use
343  // Initialize here structure members, for example:
344  // video_settings_dec_ctx->varX= valueX;
345 
346  return STAT_SUCCESS;
347 }
348 
350  volatile video_settings_dec_ctx_t *video_settings_dec_ctx)
351 {
352  // Reserved for future use
353  // Release here heap-allocated members of the structure.
354 }
355 
357  const video_settings_dec_ctx_t *video_settings_dec_ctx_src,
358  video_settings_dec_ctx_t *video_settings_dec_ctx_dst)
359 {
360  LOG_CTX_INIT(NULL);
361 
362  /* Check arguments */
363  CHECK_DO(video_settings_dec_ctx_src!= NULL, return STAT_ERROR);
364  CHECK_DO(video_settings_dec_ctx_dst!= NULL, return STAT_ERROR);
365 
366  // Reserved for future use
367  // Copy values of simple variables, duplicate heap-allocated variables.
368 
369  return STAT_SUCCESS;
370 }
371 
373  volatile video_settings_dec_ctx_t *video_settings_dec_ctx,
374  const char *str, log_ctx_t *log_ctx)
375 {
376  int end_code= STAT_ERROR;
377  int flag_is_query= 0; // 0-> JSON / 1->query string
378  cJSON *cjson_rest= NULL;
379  LOG_CTX_INIT(log_ctx);
380 
381  /* Check arguments */
382  CHECK_DO(video_settings_dec_ctx!= NULL, return STAT_ERROR);
383  CHECK_DO(str!= NULL, return STAT_EINVAL);
384 
385  /* Guess string representation format (JSON-REST or Query) */
386  //LOGV("'%s'\n", str); //comment-me
387  flag_is_query= (str[0]=='{' && str[strlen(str)-1]=='}')? 0: 1;
388 
389  /* **** Parse RESTful string to get settings parameters **** */
390 
391  if(flag_is_query== 1) {
392 
393  /* Reserved for future use
394  *
395  * Example: If 'var1' is a number value passed as query-string
396  * '...var1_name=number&...':
397  *
398  * char *var1_str= NULL;
399  * ...
400  * var1_str= uri_parser_query_str_get_value("var1_name", str);
401  * if(var1_str!= NULL)
402  * video_settings_dec_ctx->var1= atoll(var1_str);
403  * ...
404  * if(var1_str!= NULL)
405  * free(var1_str);
406  */
407 
408  } else {
409 
410  /* In the case string format is JSON-REST, parse to cJSON structure */
411  cjson_rest= cJSON_Parse(str);
412  CHECK_DO(cjson_rest!= NULL, goto end);
413 
414  /* Reserved for future use
415  *
416  * Example: If 'var1' is a number value passed as JSON-string
417  * '{..., "var1_name":number, ...}':
418  *
419  * *cjson_aux= NULL;
420  * ...
421  * cjson_aux= cJSON_GetObjectItem(cjson_rest, "var1_name");
422  * if(cjson_aux!= NULL)
423  * video_settings_dec_ctx->var1= cjson_aux->valuedouble;
424  */
425  }
426 
427  end_code= STAT_SUCCESS;
428 end:
429  if(cjson_rest!= NULL)
430  cJSON_Delete(cjson_rest);
431  return end_code;
432 }
433 
435  volatile video_settings_dec_ctx_t *video_settings_dec_ctx,
436  cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
437 {
438  int end_code= STAT_ERROR;
439  cJSON *cjson_rest= NULL;
440  LOG_CTX_INIT(log_ctx);
441 
442  CHECK_DO(video_settings_dec_ctx!= NULL, goto end);
443  CHECK_DO(ref_cjson_rest!= NULL, goto end);
444 
445  *ref_cjson_rest= NULL;
446 
447  /* Create cJSON tree-root object */
448  cjson_rest= cJSON_CreateObject();
449  CHECK_DO(cjson_rest!= NULL, goto end);
450 
451  /* JSON string to be returned:
452  * {
453  * //Reserved for future use: add settings to the REST string
454  * // e.g.: "var1_name":number, ...
455  * }
456  */
457 
458  /* Reserved for future use
459  *
460  * Example: If 'var1' is a number value:
461  *
462  * *cjson_aux= NULL;
463  * ...
464  * cjson_aux= cJSON_CreateNumber((double)video_settings_dec_ctx->var1);
465  * CHECK_DO(cjson_aux!= NULL, goto end);
466  * cJSON_AddItemToObject(cjson_rest, "var1_name", cjson_aux);
467  */
468 
469  *ref_cjson_rest= cjson_rest;
470  cjson_rest= NULL;
471  end_code= STAT_SUCCESS;
472 end:
473  if(cjson_rest!= NULL)
474  cJSON_Delete(cjson_rest);
475  return end_code;
476 }
int video_settings_enc_ctx_init(volatile video_settings_enc_ctx_t *video_settings_enc_ctx)
int video_settings_dec_ctx_restful_get(volatile video_settings_dec_ctx_t *video_settings_dec_ctx, cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
Video encoder and decoder generic settings.
int video_settings_dec_ctx_init(volatile video_settings_dec_ctx_t *video_settings_dec_ctx)
int video_settings_enc_ctx_restful_put(volatile video_settings_enc_ctx_t *video_settings_enc_ctx, const char *str, log_ctx_t *log_ctx)
void video_settings_dec_ctx_release(video_settings_dec_ctx_t **ref_video_settings_dec_ctx)
video_settings_dec_ctx_t * video_settings_dec_ctx_allocate()
void video_settings_enc_ctx_deinit(volatile video_settings_enc_ctx_t *video_settings_enc_ctx)
void video_settings_enc_ctx_release(video_settings_enc_ctx_t **ref_video_settings_enc_ctx)
#define CHECK_DO(COND, ACTION)
Definition: check_utils.h:57
int video_settings_enc_ctx_cpy(const video_settings_enc_ctx_t *video_settings_enc_ctx_src, video_settings_enc_ctx_t *video_settings_enc_ctx_dst)
int video_settings_enc_ctx_restful_get(volatile video_settings_enc_ctx_t *video_settings_enc_ctx, cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
int video_settings_dec_ctx_cpy(const video_settings_dec_ctx_t *video_settings_dec_ctx_src, video_settings_dec_ctx_t *video_settings_dec_ctx_dst)
video_settings_enc_ctx_t * video_settings_enc_ctx_allocate()
Definition: log.c:102
int video_settings_dec_ctx_restful_put(volatile video_settings_dec_ctx_t *video_settings_dec_ctx, const char *str, log_ctx_t *log_ctx)
void video_settings_dec_ctx_deinit(volatile video_settings_dec_ctx_t *video_settings_dec_ctx)