MediaProcessors
audio_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 "audio_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 
43  "planar_signed_16b",
44  "interleaved_signed_16b",
45  NULL
46 };
47 
49 {
50  return (audio_settings_enc_ctx_t*)calloc(1, sizeof(
52 }
53 
55  audio_settings_enc_ctx_t **ref_audio_settings_enc_ctx)
56 {
57  audio_settings_enc_ctx_t *audio_settings_enc_ctx= NULL;
58 
59  if(ref_audio_settings_enc_ctx== NULL)
60  return;
61 
62  if((audio_settings_enc_ctx= *ref_audio_settings_enc_ctx)!= NULL) {
63 
64  free(audio_settings_enc_ctx);
65  *ref_audio_settings_enc_ctx= NULL;
66  }
67 }
68 
70  volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx)
71 {
72  LOG_CTX_INIT(NULL);
73 
74  /* Check arguments */
75  CHECK_DO(audio_settings_enc_ctx!= NULL, return STAT_ERROR);
76 
77  audio_settings_enc_ctx->bit_rate_output= 64000;
78  audio_settings_enc_ctx->sample_rate_output= 44100;
79 
80  return STAT_SUCCESS;
81 }
82 
84  volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx)
85 {
86  // Reserved for future use
87  // Release here heap-allocated members of the structure.
88 }
89 
91  const audio_settings_enc_ctx_t *audio_settings_enc_ctx_src,
92  audio_settings_enc_ctx_t *audio_settings_enc_ctx_dst)
93 {
94  LOG_CTX_INIT(NULL);
95 
96  /* Check arguments */
97  CHECK_DO(audio_settings_enc_ctx_src!= NULL, return STAT_ERROR);
98  CHECK_DO(audio_settings_enc_ctx_dst!= NULL, return STAT_ERROR);
99 
100  /* Copy simple variable values */
101  memcpy(audio_settings_enc_ctx_dst, audio_settings_enc_ctx_src,
102  sizeof(audio_settings_enc_ctx_t));
103 
104  // Future use: duplicate heap-allocated variables...
105 
106  return STAT_SUCCESS;
107 }
108 
110  volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx,
111  const char *str, log_ctx_t *log_ctx)
112 {
113  int end_code= STAT_ERROR;
114  int flag_is_query= 0; // 0-> JSON / 1->query string
115  cJSON *cjson_rest= NULL, *cjson_aux= NULL;
116  char *bit_rate_output_str= NULL, *sample_rate_output_str= NULL;
117  LOG_CTX_INIT(log_ctx);
118 
119  /* Check arguments */
120  CHECK_DO(audio_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  audio_settings_enc_ctx->bit_rate_output= atoll(bit_rate_output_str);
136 
137  /* 'sample_rate_output' */
138  sample_rate_output_str= uri_parser_query_str_get_value(
139  "sample_rate_output", str);
140  if(sample_rate_output_str!= NULL)
141  audio_settings_enc_ctx->sample_rate_output=
142  atoll(sample_rate_output_str);
143 
144  } else {
145 
146  /* In the case string format is JSON-REST, parse to cJSON structure */
147  cjson_rest= cJSON_Parse(str);
148  CHECK_DO(cjson_rest!= NULL, goto end);
149 
150  /* 'bit_rate_output' */
151  cjson_aux= cJSON_GetObjectItem(cjson_rest, "bit_rate_output");
152  if(cjson_aux!= NULL)
153  audio_settings_enc_ctx->bit_rate_output= cjson_aux->valuedouble;
154 
155  /* 'sample_rate_output' */
156  cjson_aux= cJSON_GetObjectItem(cjson_rest, "sample_rate_output");
157  if(cjson_aux!= NULL)
158  audio_settings_enc_ctx->sample_rate_output= cjson_aux->valuedouble;
159 
160  }
161 
162  end_code= STAT_SUCCESS;
163 end:
164  if(cjson_rest!= NULL)
165  cJSON_Delete(cjson_rest);
166  if(bit_rate_output_str!= NULL)
167  free(bit_rate_output_str);
168  if(sample_rate_output_str!= NULL)
169  free(sample_rate_output_str);
170  return end_code;
171 }
172 
174  volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx,
175  cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
176 {
177  int end_code= STAT_ERROR;
178  cJSON *cjson_rest= NULL, *cjson_aux= NULL;
179  LOG_CTX_INIT(log_ctx);
180 
181  CHECK_DO(audio_settings_enc_ctx!= NULL, goto end);
182  CHECK_DO(ref_cjson_rest!= NULL, goto end);
183 
184  *ref_cjson_rest= NULL;
185 
186  /* Create cJSON tree-root object */
187  cjson_rest= cJSON_CreateObject();
188  CHECK_DO(cjson_rest!= NULL, goto end);
189 
190  /* JSON string to be returned:
191  * {
192  * "bit_rate_output":number,
193  * "sample_rate_output":number
194  * }
195  */
196 
197  /* 'bit_rate_output' */
198  cjson_aux= cJSON_CreateNumber((double)
199  audio_settings_enc_ctx->bit_rate_output);
200  CHECK_DO(cjson_aux!= NULL, goto end);
201  cJSON_AddItemToObject(cjson_rest, "bit_rate_output", cjson_aux);
202 
203  /* 'sample_rate_output' */
204  cjson_aux= cJSON_CreateNumber((double)
205  audio_settings_enc_ctx->sample_rate_output);
206  CHECK_DO(cjson_aux!= NULL, goto end);
207  cJSON_AddItemToObject(cjson_rest, "sample_rate_output", cjson_aux);
208 
209  *ref_cjson_rest= cjson_rest;
210  cjson_rest= NULL;
211  end_code= STAT_SUCCESS;
212 end:
213  if(cjson_rest!= NULL)
214  cJSON_Delete(cjson_rest);
215  return end_code;
216 }
217 
219 {
220  return (audio_settings_dec_ctx_t*)calloc(1, sizeof(
222 }
223 
225  audio_settings_dec_ctx_t **ref_audio_settings_dec_ctx)
226 {
227  audio_settings_dec_ctx_t *audio_settings_dec_ctx= NULL;
228 
229  if(ref_audio_settings_dec_ctx== NULL)
230  return;
231 
232  if((audio_settings_dec_ctx= *ref_audio_settings_dec_ctx)!= NULL) {
233 
235  audio_settings_dec_ctx);
236 
237  free(audio_settings_dec_ctx);
238  *ref_audio_settings_dec_ctx= NULL;
239  }
240 }
241 
243  volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx)
244 {
245  LOG_CTX_INIT(NULL);
246 
247  /* Check arguments */
248  CHECK_DO(audio_settings_dec_ctx!= NULL, return STAT_ERROR);
249 
250  audio_settings_dec_ctx->samples_format_output= strdup(
251  "interleaved_signed_16b");
252 
253  return STAT_SUCCESS;
254 }
255 
257  volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx)
258 {
259  LOG_CTX_INIT(NULL);
260 
261  /* Check arguments */
262  CHECK_DO(audio_settings_dec_ctx!= NULL, return);
263 
264  if(audio_settings_dec_ctx->samples_format_output!= NULL) {
265  free(audio_settings_dec_ctx->samples_format_output);
266  audio_settings_dec_ctx->samples_format_output= NULL;
267  }
268 
269  // Reserved for future use
270  // Release here future heap-allocated members of the structure...
271 
272  return;
273 }
274 
276  const audio_settings_dec_ctx_t *audio_settings_dec_ctx_src,
277  audio_settings_dec_ctx_t *audio_settings_dec_ctx_dst)
278 {
279  LOG_CTX_INIT(NULL);
280 
281  /* Check arguments */
282  CHECK_DO(audio_settings_dec_ctx_src!= NULL, return STAT_ERROR);
283  CHECK_DO(audio_settings_dec_ctx_dst!= NULL, return STAT_ERROR);
284 
285  if(audio_settings_dec_ctx_src->samples_format_output!= NULL &&
286  strlen(audio_settings_dec_ctx_src->samples_format_output)> 0) {
287  audio_settings_dec_ctx_dst->samples_format_output= strdup(
288  audio_settings_dec_ctx_src->samples_format_output);
289  ASSERT(audio_settings_dec_ctx_dst->samples_format_output!= NULL);
290  }
291 
292  // Reserved for future use
293  // Copy values of simple variables, duplicate heap-allocated variables.
294 
295  return STAT_SUCCESS;
296 }
297 
299  volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx,
300  const char *str, log_ctx_t *log_ctx)
301 {
302  int end_code= STAT_ERROR;
303  int flag_is_query= 0; // 0-> JSON / 1->query string
304  cJSON *cjson_rest= NULL, *cjson_aux= NULL;
305  char *samples_format_output_str= NULL;
306  LOG_CTX_INIT(log_ctx);
307 
308  /* Check arguments */
309  CHECK_DO(audio_settings_dec_ctx!= NULL, return STAT_ERROR);
310  CHECK_DO(str!= NULL, return STAT_EINVAL);
311 
312  /* Guess string representation format (JSON-REST or Query) */
313  //LOGV("'%s'\n", str); //comment-me
314  flag_is_query= (str[0]=='{' && str[strlen(str)-1]=='}')? 0: 1;
315 
316  /* **** Parse RESTful string to get settings parameters **** */
317 
318  if(flag_is_query== 1) {
319 
320  /* 'samples_format_output' */
321  samples_format_output_str= uri_parser_query_str_get_value(
322  "samples_format_output", str);
323  if(samples_format_output_str!= NULL) {
324  const char *fmt;
325  int i, flag_supported;
326 
327  /* Sanity check */
328  CHECK_DO(strlen(samples_format_output_str)> 0,
329  end_code= STAT_EINVAL; goto end);
330 
331  /* Check if format is supported */
332  for(i= 0, flag_supported= 0;
334  i++) {
335  if(strncmp(samples_format_output_str, fmt, strlen(fmt))== 0) {
336  flag_supported= 1;
337  break;
338  }
339  }
340  if(flag_supported== 0) { // Format specified not supported
341  end_code= STAT_EINVAL;
342  goto end;
343  }
344 
345  if(audio_settings_dec_ctx->samples_format_output!= NULL)
346  free(audio_settings_dec_ctx->samples_format_output);
347  audio_settings_dec_ctx->samples_format_output= strdup(
348  samples_format_output_str);
349  }
350 
351  } else {
352 
353  /* In the case string format is JSON-REST, parse to cJSON structure */
354  cjson_rest= cJSON_Parse(str);
355  CHECK_DO(cjson_rest!= NULL, goto end);
356 
357  /* 'samples_format_output' */
358  cjson_aux= cJSON_GetObjectItem(cjson_rest, "samples_format_output");
359  if(cjson_aux!= NULL) {
360  const char *fmt;
361  int i, flag_supported;
362 
363  /* Sanity check */
364  CHECK_DO(cjson_aux->valuestring!= NULL &&
365  strlen(cjson_aux->valuestring)> 0,
366  end_code= STAT_EINVAL; goto end);
367 
368  /* Check if format is supported */
369  for(i= 0, flag_supported= 0;
371  i++) {
372  if(strncmp(cjson_aux->valuestring, fmt, strlen(fmt))== 0) {
373  flag_supported= 1;
374  break;
375  }
376  }
377  if(flag_supported== 0) { // Format specified not supported
378  end_code= STAT_EINVAL;
379  goto end;
380  }
381 
382  if(audio_settings_dec_ctx->samples_format_output!= NULL)
383  free(audio_settings_dec_ctx->samples_format_output);
384  audio_settings_dec_ctx->samples_format_output= strdup(
385  cjson_aux->valuestring);
386  }
387 
388  }
389 
390  end_code= STAT_SUCCESS;
391 end:
392  if(cjson_rest!= NULL)
393  cJSON_Delete(cjson_rest);
394  if(samples_format_output_str!= NULL)
395  free(samples_format_output_str);
396  return end_code;
397 }
398 
400  volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx,
401  cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
402 {
403  int end_code= STAT_ERROR;
404  cJSON *cjson_rest= NULL;
405  LOG_CTX_INIT(log_ctx);
406 
407  CHECK_DO(audio_settings_dec_ctx!= NULL, goto end);
408  CHECK_DO(ref_cjson_rest!= NULL, goto end);
409 
410  *ref_cjson_rest= NULL;
411 
412  /* Create cJSON tree-root object */
413  cjson_rest= cJSON_CreateObject();
414  CHECK_DO(cjson_rest!= NULL, goto end);
415 
416  /* JSON string to be returned:
417  * {
418  * //Reserved for future use: add settings to the REST string
419  * // e.g.: "var1_name":number, ...
420  * }
421  */
422 
423  /* Reserved for future use
424  *
425  * Example: If 'var1' is a number value:
426  *
427  * *cjson_aux= NULL;
428  * ...
429  * cjson_aux= cJSON_CreateNumber((double)audio_settings_dec_ctx->var1);
430  * CHECK_DO(cjson_aux!= NULL, goto end);
431  * cJSON_AddItemToObject(cjson_rest, "var1_name", cjson_aux);
432  */
433 
434  *ref_cjson_rest= cjson_rest;
435  cjson_rest= NULL;
436  end_code= STAT_SUCCESS;
437 end:
438  if(cjson_rest!= NULL)
439  cJSON_Delete(cjson_rest);
440  return end_code;
441 }
int audio_settings_enc_ctx_restful_get(volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx, cJSON **ref_cjson_rest, log_ctx_t *log_ctx)
audio_settings_enc_ctx_t * audio_settings_enc_ctx_allocate()
void audio_settings_enc_ctx_release(audio_settings_enc_ctx_t **ref_audio_settings_enc_ctx)
int audio_settings_dec_ctx_init(volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx)
int audio_settings_enc_ctx_init(volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx)
int audio_settings_enc_ctx_restful_put(volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx, const char *str, log_ctx_t *log_ctx)
void audio_settings_dec_ctx_release(audio_settings_dec_ctx_t **ref_audio_settings_dec_ctx)
int audio_settings_dec_ctx_cpy(const audio_settings_dec_ctx_t *audio_settings_dec_ctx_src, audio_settings_dec_ctx_t *audio_settings_dec_ctx_dst)
#define CHECK_DO(COND, ACTION)
Definition: check_utils.h:57
int audio_settings_enc_ctx_cpy(const audio_settings_enc_ctx_t *audio_settings_enc_ctx_src, audio_settings_enc_ctx_t *audio_settings_enc_ctx_dst)
audio_settings_dec_ctx_t * audio_settings_dec_ctx_allocate()
void audio_settings_dec_ctx_deinit(volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx)
void audio_settings_enc_ctx_deinit(volatile audio_settings_enc_ctx_t *audio_settings_enc_ctx)
Audio encoder and decoder generic settings.
static const char * supported_samples_format_oput_array_dec[]
#define ASSERT(COND)
Definition: check_utils.h:51
Definition: log.c:102
int audio_settings_dec_ctx_restful_put(volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx, const char *str, log_ctx_t *log_ctx)
int audio_settings_dec_ctx_restful_get(volatile audio_settings_dec_ctx_t *audio_settings_dec_ctx, cJSON **ref_cjson_rest, log_ctx_t *log_ctx)