MediaProcessors
ffmpeg_mp3.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 "ffmpeg_mp3.h"
26 
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <pthread.h>
31 
32 #include <libcjson/cJSON.h>
33 #include <libavcodec/avcodec.h>
34 #include <libmediaprocsutils/log.h>
35 #include <libmediaprocsutils/stat_codes.h>
36 #include <libmediaprocsutils/check_utils.h>
37 #include <libmediaprocsutils/fifo.h>
38 #include <libmediaprocs/proc_if.h>
39 #include <libmediaprocs/proc.h>
40 #include "audio_settings.h"
41 #include "ffmpeg_audio.h"
42 #include "proc_frame_2_ffmpeg.h"
43 
44 /* **** Definitions **** */
45 
57 
61 typedef struct ffmpeg_mp3_enc_ctx_s {
67  struct ffmpeg_audio_enc_ctx_s ffmpeg_audio_enc_ctx;
72  volatile struct ffmpeg_mp3_enc_settings_ctx_s ffmpeg_mp3_enc_settings_ctx;
74 
84  struct audio_settings_dec_ctx_s audio_settings_dec_ctx;
86 
90 typedef struct ffmpeg_mp3_dec_ctx_s {
96  struct ffmpeg_audio_dec_ctx_s ffmpeg_audio_dec_ctx;
101  volatile struct ffmpeg_mp3_dec_settings_ctx_s ffmpeg_mp3_dec_settings_ctx;
103 
104 /* **** Prototypes **** */
105 
106 /* *** Encoder **** */
107 
108 static proc_ctx_t* ffmpeg_mp3_enc_open(const proc_if_t *proc_if,
109  const char *settings_str, log_ctx_t *log_ctx, va_list arg);
110 static void ffmpeg_mp3_enc_close(proc_ctx_t **ref_proc_ctx);
111 static int ffmpeg_mp3_enc_process_frame(proc_ctx_t *proc_ctx,
112  fifo_ctx_t *iput_fifo_ctx, fifo_ctx_t *oput_fifo_ctx);
113 static int ffmpeg_mp3_enc_rest_put(proc_ctx_t *proc_ctx, const char *str);
114 static int ffmpeg_mp3_enc_rest_get(proc_ctx_t *proc_ctx,
115  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse);
116 
118  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx,
119  log_ctx_t *log_ctx);
121  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx,
122  log_ctx_t *log_ctx);
123 
124 /* *** Decoder **** */
125 
126 static proc_ctx_t* ffmpeg_mp3_dec_open(const proc_if_t *proc_if,
127  const char *settings_str, log_ctx_t *log_ctx, va_list arg);
128 static void ffmpeg_mp3_dec_close(proc_ctx_t **ref_proc_ctx);
129 static int ffmpeg_mp3_dec_process_frame(proc_ctx_t *proc_ctx,
130  fifo_ctx_t* iput_fifo_ctx, fifo_ctx_t* oput_fifo_ctx);
131 
132 static int ffmpeg_mp3_dec_rest_put(proc_ctx_t *proc_ctx, const char *str);
133 static int ffmpeg_mp3_dec_rest_get(proc_ctx_t *proc_ctx,
134  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse);
135 
137  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx,
138  log_ctx_t *log_ctx);
140  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx,
141  log_ctx_t *log_ctx);
142 
143 /* **** Implementations **** */
144 
146 {
147  "ffmpeg_mp3_enc", "encoder", "audio/MPA",
148  (uint64_t)(PROC_FEATURE_BITRATE|PROC_FEATURE_REGISTER_PTS|
149  PROC_FEATURE_LATENCY),
152  proc_send_frame_default1,
153  NULL, // no 'send-no-dup'
154  proc_recv_frame_default1,
155  NULL, // no specific unblock function extension
159  NULL, // no extra options
163 };
164 
166 {
167  "ffmpeg_mp3_dec", "decoder", "audio/MPA",
168  (uint64_t)(PROC_FEATURE_BITRATE|PROC_FEATURE_REGISTER_PTS|
169  PROC_FEATURE_LATENCY),
172  proc_send_frame_default1,
173  NULL, // no 'send-no-dup'
174  proc_recv_frame_default1,
175  NULL, // no specific unblock function extension
179  NULL, // no extra options
183 };
184 
189 static proc_ctx_t* ffmpeg_mp3_enc_open(const proc_if_t *proc_if,
190  const char *settings_str, log_ctx_t *log_ctx, va_list arg)
191 {
192  int ret_code, end_code= STAT_ERROR;
193  ffmpeg_mp3_enc_ctx_t *ffmpeg_mp3_enc_ctx= NULL;
194  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx=
195  NULL; // Do not release
196  ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx= NULL; // Do not release
198  NULL; // Do not release
199  LOG_CTX_INIT(log_ctx);
200 
201  /* Check arguments */
202  CHECK_DO(proc_if!= NULL, return NULL);
203  CHECK_DO(settings_str!= NULL, return NULL);
204  // Note: 'log_ctx' is allowed to be NULL
205 
206  /* Allocate context structure */
207  ffmpeg_mp3_enc_ctx= (ffmpeg_mp3_enc_ctx_t*)calloc(1, sizeof(
209  CHECK_DO(ffmpeg_mp3_enc_ctx!= NULL, goto end);
210 
211  /* Get settings structure */
212  ffmpeg_mp3_enc_settings_ctx=
213  &ffmpeg_mp3_enc_ctx->ffmpeg_mp3_enc_settings_ctx;
214 
215  /* Initialize settings to defaults */
216  ret_code= ffmpeg_mp3_enc_settings_ctx_init(ffmpeg_mp3_enc_settings_ctx,
217  LOG_CTX_GET());
218  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
219 
220  /* Parse and put given settings */
221  ret_code= ffmpeg_mp3_enc_rest_put((proc_ctx_t*)ffmpeg_mp3_enc_ctx,
222  settings_str);
223  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
224 
225  /* Get generic audio encoder and settings context structures */
226  ffmpeg_audio_enc_ctx= &ffmpeg_mp3_enc_ctx->ffmpeg_audio_enc_ctx;
227  audio_settings_enc_ctx= (volatile audio_settings_enc_ctx_t*)
228  ffmpeg_mp3_enc_settings_ctx;
229 
230  /* Initialize FFMPEG's generic audio encoder context */
231  ret_code= ffmpeg_audio_enc_ctx_init(ffmpeg_audio_enc_ctx,
232  (int)AV_CODEC_ID_MP3,
233  (const audio_settings_enc_ctx_t*)audio_settings_enc_ctx,
234  LOG_CTX_GET());
235  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
236 
237  end_code= STAT_SUCCESS;
238  end:
239  if(end_code!= STAT_SUCCESS)
240  ffmpeg_mp3_enc_close((proc_ctx_t**)&ffmpeg_mp3_enc_ctx);
241  return (proc_ctx_t*)ffmpeg_mp3_enc_ctx;
242 }
243 
248 static void ffmpeg_mp3_enc_close(proc_ctx_t **ref_proc_ctx)
249 {
250  ffmpeg_mp3_enc_ctx_t *ffmpeg_mp3_enc_ctx= NULL;
251 
252  if(ref_proc_ctx== NULL)
253  return;
254 
255  if((ffmpeg_mp3_enc_ctx= (ffmpeg_mp3_enc_ctx_t*)*ref_proc_ctx)!=
256  NULL) {
257  LOG_CTX_INIT(((proc_ctx_t*)ffmpeg_mp3_enc_ctx)->log_ctx);
258 
259  /* De-initialize FFMPEG's generic audio encoder context */
261  LOG_CTX_GET());
262 
263  /* Release settings */
265  &ffmpeg_mp3_enc_ctx->ffmpeg_mp3_enc_settings_ctx,
266  LOG_CTX_GET());
267 
268  // Reserved for future use: release other new variables here...
269 
270  /* Release context structure */
271  free(ffmpeg_mp3_enc_ctx);
272  *ref_proc_ctx= NULL;
273  }
274 }
275 
281  fifo_ctx_t* iput_fifo_ctx, fifo_ctx_t* oput_fifo_ctx)
282 {
283  int ret_code, end_code= STAT_ERROR;
284  ffmpeg_mp3_enc_ctx_t *ffmpeg_mp3_enc_ctx= NULL; // Do not release
285  ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx= NULL; // Do not release
286  AVFrame *avframe_iput= NULL;
287  size_t fifo_elem_size= 0;
288  LOG_CTX_INIT(NULL);
289 
290  /* Check arguments */
291  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
292  CHECK_DO(iput_fifo_ctx!= NULL, return STAT_ERROR);
293  CHECK_DO(oput_fifo_ctx!= NULL, return STAT_ERROR);
294 
295  LOG_CTX_SET(proc_ctx->log_ctx);
296 
297  /* Get FFmpeg audio encoder context */
298  ffmpeg_mp3_enc_ctx= (ffmpeg_mp3_enc_ctx_t*)proc_ctx;
299  ffmpeg_audio_enc_ctx= &ffmpeg_mp3_enc_ctx->ffmpeg_audio_enc_ctx;
300 
301  /* Get input frame from FIFO buffer */
302  ret_code= fifo_get(iput_fifo_ctx, (void**)&avframe_iput, &fifo_elem_size);
303  CHECK_DO(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN, goto end);
304  if(ret_code== STAT_EAGAIN) {
305  /* This means FIFO was unblocked, just go out with EOF status */
306  end_code= STAT_EOF;
307  goto end;
308  }
309 
310  /* Encode frame */
311  ret_code= ffmpeg_audio_enc_frame(ffmpeg_audio_enc_ctx, avframe_iput,
312  oput_fifo_ctx, LOG_CTX_GET());
313  CHECK_DO(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN, goto end);
314 
315  end_code= STAT_SUCCESS;
316 end:
317  if(avframe_iput!= NULL)
318  av_frame_free(&avframe_iput);
319  return end_code;
320 }
321 
326 static int ffmpeg_mp3_enc_rest_put(proc_ctx_t *proc_ctx, const char *str)
327 {
328  int ret_code;
329  ffmpeg_mp3_enc_ctx_t *ffmpeg_mp3_enc_ctx= NULL;
330  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx= NULL;
332  LOG_CTX_INIT(NULL);
333 
334  /* Check arguments */
335  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
336  CHECK_DO(str!= NULL, return STAT_ERROR);
337 
338  LOG_CTX_SET(proc_ctx->log_ctx);
339 
340  /* Get FFmpeg audio encoder settings contexts */
341  ffmpeg_mp3_enc_ctx= (ffmpeg_mp3_enc_ctx_t*)proc_ctx;
342  ffmpeg_mp3_enc_settings_ctx=
343  &ffmpeg_mp3_enc_ctx->ffmpeg_mp3_enc_settings_ctx;
344  audio_settings_enc_ctx=
345  &ffmpeg_mp3_enc_settings_ctx->audio_settings_enc_ctx;
346 
347  /* PUT generic audio encoder settings */
348  ret_code= audio_settings_enc_ctx_restful_put(audio_settings_enc_ctx, str,
349  LOG_CTX_GET());
350  if(ret_code!= STAT_SUCCESS)
351  return ret_code;
352 
353  /* PUT specific mp3 audio encoder settings */
354  // Reserved for future use
355 
356  /* Finally that we have new settings parsed, reset FFMPEG processor */
358  (volatile void*)audio_settings_enc_ctx, 1/*Signal is an encoder*/,
359  LOG_CTX_GET());
360 
361  return STAT_SUCCESS;
362 }
363 
368 static int ffmpeg_mp3_enc_rest_get(proc_ctx_t *proc_ctx,
369  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
370 {
371  int ret_code, end_code= STAT_ERROR;
372  ffmpeg_mp3_enc_ctx_t *ffmpeg_mp3_enc_ctx= NULL;
373  ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx= NULL;
374  AVCodecContext *avcodecctx= NULL;
375  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx= NULL;
377  cJSON *cjson_rest= NULL, *cjson_settings= NULL;
378  cJSON *cjson_aux= NULL; // Do not release
379  LOG_CTX_INIT(NULL);
380 
381  /* Check arguments */
382  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
383  CHECK_DO(rest_fmt< PROC_IF_REST_FMT_ENUM_MAX, return STAT_ERROR);
384  CHECK_DO(ref_reponse!= NULL, return STAT_ERROR);
385 
386  LOG_CTX_SET(proc_ctx->log_ctx);
387 
388  *ref_reponse= NULL;
389 
390  /* Create cJSON tree root object */
391  cjson_rest= cJSON_CreateObject();
392  CHECK_DO(cjson_rest!= NULL, goto end);
393 
394  /* JSON string to be returned:
395  * {
396  * "settings":
397  * {
398  * ...
399  * },
400  * "expected_frame_size_iput":number
401  * }
402  */
403 
404  /* Get FFmpeg audio encoder settings contexts */
405  ffmpeg_mp3_enc_ctx= (ffmpeg_mp3_enc_ctx_t*)proc_ctx;
406  ffmpeg_mp3_enc_settings_ctx=
407  &ffmpeg_mp3_enc_ctx->ffmpeg_mp3_enc_settings_ctx;
408  audio_settings_enc_ctx=
409  &ffmpeg_mp3_enc_settings_ctx->audio_settings_enc_ctx;
410 
411  /* GET generic audio encoder settings */
412  ret_code= audio_settings_enc_ctx_restful_get(audio_settings_enc_ctx,
413  &cjson_settings, LOG_CTX_GET());
414  CHECK_DO(ret_code== STAT_SUCCESS && cjson_settings!= NULL, goto end);
415 
416  /* GET specific mp3 audio encoder settings */
417  // Reserved for future use: attach to 'cjson_settings' (should be != NULL)
418 
419  /* Attach settings object to REST response */
420  cJSON_AddItemToObject(cjson_rest, "settings", cjson_settings);
421  cjson_settings= NULL; // Attached; avoid double referencing
422 
423  /* **** Attach data to REST response **** */
424 
425  ffmpeg_audio_enc_ctx= &ffmpeg_mp3_enc_ctx->ffmpeg_audio_enc_ctx;
426  avcodecctx= ffmpeg_audio_enc_ctx->avcodecctx;
427  CHECK_DO(avcodecctx!= NULL, goto end);
428 
429  /* 'expected_frame_size_iput' */
430  cjson_aux= cJSON_CreateNumber((double)avcodecctx->frame_size);
431  CHECK_DO(cjson_aux!= NULL, goto end);
432  cJSON_AddItemToObject(cjson_rest, "expected_frame_size_iput", cjson_aux);
433 
434  // Reserved for future use: set other data values here...
435 
436  /* Format response to be returned */
437  switch(rest_fmt) {
439  /* Print cJSON structure data to char string */
440  *ref_reponse= (void*)CJSON_PRINT(cjson_rest);
441  CHECK_DO(*ref_reponse!= NULL && strlen((char*)*ref_reponse)> 0,
442  goto end);
443  break;
445  *ref_reponse= (void*)cjson_rest;
446  cjson_rest= NULL; // Avoid double referencing
447  break;
448  default:
449  LOGE("Unknown format requested for processor REST\n");
450  goto end;
451  }
452 
453  end_code= STAT_SUCCESS;
454 end:
455  if(cjson_settings!= NULL)
456  cJSON_Delete(cjson_settings);
457  if(cjson_rest!= NULL)
458  cJSON_Delete(cjson_rest);
459  return end_code;
460 }
461 
470  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx,
471  log_ctx_t *log_ctx)
472 {
473  int ret_code;
475  LOG_CTX_INIT(log_ctx);
476 
477  /* Check arguments */
478  CHECK_DO(ffmpeg_mp3_enc_settings_ctx!= NULL, return STAT_ERROR);
479 
480  audio_settings_enc_ctx=
481  &ffmpeg_mp3_enc_settings_ctx->audio_settings_enc_ctx;
482 
483  /* Initialize generic audio encoder settings */
484  ret_code= audio_settings_enc_ctx_init(audio_settings_enc_ctx);
485  if(ret_code!= STAT_SUCCESS)
486  return ret_code;
487 
488  /* Initialize specific MP3 audio encoder settings */
489  // Reserved for future use
490 
491  return STAT_SUCCESS;
492 }
493 
500  volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx,
501  log_ctx_t *log_ctx)
502 {
504  LOG_CTX_INIT(log_ctx);
505 
506  /* Check arguments */
507  CHECK_DO(ffmpeg_mp3_enc_settings_ctx!= NULL, return);
508 
509  audio_settings_enc_ctx=
510  &ffmpeg_mp3_enc_settings_ctx->audio_settings_enc_ctx;
511 
512  /* Release (heap-allocated) generic audio encoder settings */
513  audio_settings_enc_ctx_deinit(audio_settings_enc_ctx);
514 
515  /* Release specific MP3 audio encoder settings */
516  // Reserved for future use
517 }
518 
523 static proc_ctx_t* ffmpeg_mp3_dec_open(const proc_if_t *proc_if,
524  const char *settings_str, log_ctx_t *log_ctx, va_list arg)
525 {
526  int ret_code, end_code= STAT_ERROR;
527  ffmpeg_mp3_dec_ctx_t *ffmpeg_mp3_dec_ctx= NULL;
528  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx=
529  NULL; // Do not release
530  ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx= NULL; // Do not release
532  NULL; // Do not release
533  LOG_CTX_INIT(log_ctx);
534 
535  /* Check arguments */
536  CHECK_DO(proc_if!= NULL, return NULL);
537  CHECK_DO(settings_str!= NULL, return NULL);
538  // Note: 'log_ctx' is allowed to be NULL
539 
540  /* Allocate context structure */
541  ffmpeg_mp3_dec_ctx= (ffmpeg_mp3_dec_ctx_t*)calloc(1, sizeof(
543  CHECK_DO(ffmpeg_mp3_dec_ctx!= NULL, goto end);
544 
545  /* Get settings structure */
546  ffmpeg_mp3_dec_settings_ctx=
547  &ffmpeg_mp3_dec_ctx->ffmpeg_mp3_dec_settings_ctx;
548 
549  /* Initialize settings to defaults */
550  ret_code= ffmpeg_mp3_dec_settings_ctx_init(ffmpeg_mp3_dec_settings_ctx,
551  LOG_CTX_GET());
552  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
553 
554  /* Parse and put given settings */
555  ret_code= ffmpeg_mp3_dec_rest_put((proc_ctx_t*)ffmpeg_mp3_dec_ctx,
556  settings_str);
557  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
558 
559  /* Get generic audio decoder and settings context structures */
560  ffmpeg_audio_dec_ctx= &ffmpeg_mp3_dec_ctx->ffmpeg_audio_dec_ctx;
561  audio_settings_dec_ctx= (volatile audio_settings_dec_ctx_t*)
562  ffmpeg_mp3_dec_settings_ctx;
563 
564  /* Initialize FFMPEG's generic audio decoder context */
565  ret_code= ffmpeg_audio_dec_ctx_init(ffmpeg_audio_dec_ctx,
566  (int)AV_CODEC_ID_MP3,
567  (const audio_settings_dec_ctx_t*)audio_settings_dec_ctx,
568  LOG_CTX_GET());
569  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
570 
571  end_code= STAT_SUCCESS;
572  end:
573  if(end_code!= STAT_SUCCESS)
574  ffmpeg_mp3_dec_close((proc_ctx_t**)&ffmpeg_mp3_dec_ctx);
575  return (proc_ctx_t*)ffmpeg_mp3_dec_ctx;
576 }
577 
582 static void ffmpeg_mp3_dec_close(proc_ctx_t **ref_proc_ctx)
583 {
584  ffmpeg_mp3_dec_ctx_t *ffmpeg_mp3_dec_ctx= NULL;
585 
586  if(ref_proc_ctx== NULL)
587  return;
588 
589  if((ffmpeg_mp3_dec_ctx= (ffmpeg_mp3_dec_ctx_t*)*ref_proc_ctx)!= NULL) {
590  LOG_CTX_INIT(((proc_ctx_t*)ffmpeg_mp3_dec_ctx)->log_ctx);
591 
592  /* De-initialize FFMPEG's generic audio decoder context */
594  LOG_CTX_GET());
595 
596  /* Release settings */
598  &ffmpeg_mp3_dec_ctx->ffmpeg_mp3_dec_settings_ctx,
599  LOG_CTX_GET());
600 
601  // Reserved for future use: release other new variables here...
602 
603  /* Release context structure */
604  free(ffmpeg_mp3_dec_ctx);
605  *ref_proc_ctx= NULL;
606  }
607 }
608 
614  fifo_ctx_t* iput_fifo_ctx, fifo_ctx_t* oput_fifo_ctx)
615 {
616  int ret_code, end_code= STAT_ERROR;
617  ffmpeg_mp3_dec_ctx_t *ffmpeg_mp3_dec_ctx= NULL; // Do not release
618  ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx= NULL; // Do not release
619  AVPacket *avpacket_iput= NULL;
620  size_t fifo_elem_size= 0;
621  LOG_CTX_INIT(NULL);
622 
623  /* Check arguments */
624  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
625  CHECK_DO(iput_fifo_ctx!= NULL, return STAT_ERROR);
626  CHECK_DO(oput_fifo_ctx!= NULL, return STAT_ERROR);
627 
628  LOG_CTX_SET(proc_ctx->log_ctx);
629 
630  /* Get FFmpeg audio decoder context */
631  ffmpeg_mp3_dec_ctx= (ffmpeg_mp3_dec_ctx_t*)proc_ctx;
632  ffmpeg_audio_dec_ctx= &ffmpeg_mp3_dec_ctx->ffmpeg_audio_dec_ctx;
633 
634  /* Get input packet from FIFO buffer */
635  ret_code= fifo_get(iput_fifo_ctx, (void**)&avpacket_iput, &fifo_elem_size);
636  CHECK_DO(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN, goto end);
637  if(ret_code== STAT_EAGAIN) {
638  /* This means FIFO was unblocked, just go out with EOF status */
639  end_code= STAT_EOF;
640  goto end;
641  }
642 
643  /* Decode frame */
644  ret_code= ffmpeg_audio_dec_frame(ffmpeg_audio_dec_ctx, avpacket_iput,
645  oput_fifo_ctx, LOG_CTX_GET());
646  CHECK_DO(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN, goto end);
647 
648  end_code= STAT_SUCCESS;
649 end:
650  if(avpacket_iput!= NULL)
651  avpacket_release((void**)&avpacket_iput);
652  return end_code;
653 }
654 
659 static int ffmpeg_mp3_dec_rest_put(proc_ctx_t *proc_ctx, const char *str)
660 {
661  int ret_code;
662  ffmpeg_mp3_dec_ctx_t *ffmpeg_mp3_dec_ctx= NULL;
663  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx= NULL;
665  LOG_CTX_INIT(NULL);
666 
667  /* Check arguments */
668  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
669  CHECK_DO(str!= NULL, return STAT_ERROR);
670 
671  LOG_CTX_SET(proc_ctx->log_ctx);
672 
673  /* Get FFmpeg audio decoder settings contexts */
674  ffmpeg_mp3_dec_ctx= (ffmpeg_mp3_dec_ctx_t*)proc_ctx;
675  ffmpeg_mp3_dec_settings_ctx=
676  &ffmpeg_mp3_dec_ctx->ffmpeg_mp3_dec_settings_ctx;
677  audio_settings_dec_ctx=
678  &ffmpeg_mp3_dec_settings_ctx->audio_settings_dec_ctx;
679 
680  /* PUT generic audio decoder settings */
681  ret_code= audio_settings_dec_ctx_restful_put(audio_settings_dec_ctx, str,
682  LOG_CTX_GET());
683  if(ret_code!= STAT_SUCCESS)
684  return ret_code;
685 
686  /* PUT specific MP3 audio decoder settings */
687  // Reserved for future use
688 
689  /* Finally that we have new settings parsed, reset FFMPEG processor */
691  (volatile void*)audio_settings_dec_ctx, 0/*Signal is an decoder*/,
692  LOG_CTX_GET());
693 
694  return STAT_SUCCESS;
695 }
696 
701 static int ffmpeg_mp3_dec_rest_get(proc_ctx_t *proc_ctx,
702  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
703 {
704  int ret_code, end_code= STAT_ERROR;
705  ffmpeg_mp3_dec_ctx_t *ffmpeg_mp3_dec_ctx= NULL;
706  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx= NULL;
707  ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx= NULL;
708  AVCodecContext *avcodecctx= NULL;
710  cJSON *cjson_rest= NULL, *cjson_settings= NULL;
711  //cJSON *cjson_aux= NULL; // Do not release // Future use
712  LOG_CTX_INIT(NULL);
713 
714  /* Check arguments */
715  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
716  CHECK_DO(rest_fmt< PROC_IF_REST_FMT_ENUM_MAX, return STAT_ERROR);
717  CHECK_DO(ref_reponse!= NULL, return STAT_ERROR);
718 
719  LOG_CTX_SET(proc_ctx->log_ctx);
720 
721  *ref_reponse= NULL;
722 
723  /* Create cJSON tree root object */
724  cjson_rest= cJSON_CreateObject();
725  CHECK_DO(cjson_rest!= NULL, goto end);
726 
727  /* JSON string to be returned:
728  * {
729  * "settings":
730  * {
731  * ...
732  * },
733  * ... // reserved for future use
734  * }
735  */
736 
737  /* Get FFmpeg audio decoder settings contexts */
738  ffmpeg_mp3_dec_ctx= (ffmpeg_mp3_dec_ctx_t*)proc_ctx;
739  ffmpeg_mp3_dec_settings_ctx=
740  &ffmpeg_mp3_dec_ctx->ffmpeg_mp3_dec_settings_ctx;
741  audio_settings_dec_ctx=
742  &ffmpeg_mp3_dec_settings_ctx->audio_settings_dec_ctx;
743 
744  /* GET generic audio decoder settings */
745  ret_code= audio_settings_dec_ctx_restful_get(audio_settings_dec_ctx,
746  &cjson_settings, LOG_CTX_GET());
747  CHECK_DO(ret_code== STAT_SUCCESS && cjson_settings!= NULL, goto end);
748 
749  /* GET specific MP3 audio decoder settings */
750  // Reserved for future use: attach to 'cjson_settings' (should be != NULL)
751 
752  /* Attach settings object to REST response */
753  cJSON_AddItemToObject(cjson_rest, "settings", cjson_settings);
754  cjson_settings= NULL; // Attached; avoid double referencing
755 
756  /* **** Attach data to REST response **** */
757 
758  ffmpeg_audio_dec_ctx= &ffmpeg_mp3_dec_ctx->ffmpeg_audio_dec_ctx;
759  avcodecctx= ffmpeg_audio_dec_ctx->avcodecctx;
760  CHECK_DO(avcodecctx!= NULL, goto end);
761 
762  // Reserved for future use
763  /* Example:
764  * cjson_aux= cJSON_CreateNumber((double)avcodecctx->var1);
765  * CHECK_DO(cjson_aux!= NULL, goto end);
766  * cJSON_AddItemToObject(cjson_rest, "var1_name", cjson_aux);
767  */
768 
769  /* Format response to be returned */
770  switch(rest_fmt) {
772  /* Print cJSON structure data to char string */
773  *ref_reponse= (void*)CJSON_PRINT(cjson_rest);
774  CHECK_DO(*ref_reponse!= NULL && strlen((char*)*ref_reponse)> 0,
775  goto end);
776  break;
778  *ref_reponse= (void*)cjson_rest;
779  cjson_rest= NULL; // Avoid double referencing
780  break;
781  default:
782  LOGE("Unknown format requested for processor REST\n");
783  goto end;
784  }
785 
786  end_code= STAT_SUCCESS;
787 end:
788  if(cjson_settings!= NULL)
789  cJSON_Delete(cjson_settings);
790  if(cjson_rest!= NULL)
791  cJSON_Delete(cjson_rest);
792  return end_code;
793 }
794 
803  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx,
804  log_ctx_t *log_ctx)
805 {
806  int ret_code;
808  LOG_CTX_INIT(log_ctx);
809 
810  /* Check arguments */
811  CHECK_DO(ffmpeg_mp3_dec_settings_ctx!= NULL, return STAT_ERROR);
812 
813  audio_settings_dec_ctx=
814  &ffmpeg_mp3_dec_settings_ctx->audio_settings_dec_ctx;
815 
816  /* Initialize generic audio decoder settings */
817  ret_code= audio_settings_dec_ctx_init(audio_settings_dec_ctx);
818  if(ret_code!= STAT_SUCCESS)
819  return ret_code;
820 
821  /* Initialize specific MP3 audio decoder settings */
822  // Reserved for future use
823 
824  return STAT_SUCCESS;
825 }
826 
833  volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx,
834  log_ctx_t *log_ctx)
835 {
837  LOG_CTX_INIT(log_ctx);
838 
839  /* Check arguments */
840  CHECK_DO(ffmpeg_mp3_dec_settings_ctx!= NULL, return);
841 
842  audio_settings_dec_ctx=
843  &ffmpeg_mp3_dec_settings_ctx->audio_settings_dec_ctx;
844 
845  /* Release (heap-allocated) generic audio decoder settings */
846  audio_settings_dec_ctx_deinit(audio_settings_dec_ctx);
847 
848  /* Release specific mp3 audio decoder settings */
849  // Reserved for future use
850 }
void avframe_release(void **ref_avfame)
int fifo_get(fifo_ctx_t *fifo_ctx, void **ref_elem, size_t *ref_elem_size)
Definition: fifo.c:366
#define CJSON_PRINT(CJSON_PTR)
Definition: proc.h:70
AVCodecContext * avcodecctx
Definition: ffmpeg_audio.h:78
Facilities to convert processor&#39;s input/output frame to FFmpeg&#39;s formats and vice versa...
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)
proc_frame_ctx_t * avframe_2_proc_frame_ctx(const void *avframe_arg)
const proc_if_t proc_if_ffmpeg_mp3_dec
Definition: ffmpeg_mp3.c:165
static void ffmpeg_mp3_dec_settings_ctx_deinit(volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_mp3.c:832
void ffmpeg_audio_enc_ctx_deinit(ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:139
static int ffmpeg_mp3_enc_rest_put(proc_ctx_t *proc_ctx, const char *str)
Definition: ffmpeg_mp3.c:326
struct ffmpeg_audio_enc_ctx_s ffmpeg_audio_enc_ctx
Definition: ffmpeg_mp3.c:67
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)
static int ffmpeg_mp3_dec_rest_get(proc_ctx_t *proc_ctx, const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
Definition: ffmpeg_mp3.c:701
void ffmpeg_audio_dec_ctx_deinit(ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:301
static proc_ctx_t * ffmpeg_mp3_dec_open(const proc_if_t *proc_if, const char *settings_str, log_ctx_t *log_ctx, va_list arg)
Definition: ffmpeg_mp3.c:523
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)
struct audio_settings_enc_ctx_s audio_settings_enc_ctx
Definition: ffmpeg_mp3.c:55
int ffmpeg_audio_enc_frame(ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx, AVFrame *avframe_iput, fifo_ctx_t *oput_fifo_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:149
int ffmpeg_audio_dec_frame(ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx, AVPacket *avpacket_iput, fifo_ctx_t *oput_fifo_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:311
const proc_if_t proc_if_ffmpeg_mp3_enc
Definition: ffmpeg_mp3.c:145
Generic processor module context (see type proc_ctx_t) extension for audio encoders and decoders...
struct ffmpeg_audio_dec_ctx_s ffmpeg_audio_dec_ctx
Definition: ffmpeg_mp3.c:96
static void ffmpeg_mp3_enc_settings_ctx_deinit(volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_mp3.c:499
struct ffmpeg_mp3_dec_ctx_s ffmpeg_mp3_dec_ctx_t
static int ffmpeg_mp3_dec_process_frame(proc_ctx_t *proc_ctx, fifo_ctx_t *iput_fifo_ctx, fifo_ctx_t *oput_fifo_ctx)
Definition: ffmpeg_mp3.c:613
void avpacket_release(void **ref_avpacket)
volatile struct ffmpeg_mp3_dec_settings_ctx_s ffmpeg_mp3_dec_settings_ctx
Definition: ffmpeg_mp3.c:101
struct ffmpeg_mp3_enc_settings_ctx_s ffmpeg_mp3_enc_settings_ctx_t
void ffmpeg_audio_reset_on_new_settings(proc_ctx_t *proc_ctx, volatile void *audio_settings_opaque, int flag_is_encoder, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:392
struct ffmpeg_mp3_dec_settings_ctx_s ffmpeg_mp3_dec_settings_ctx_t
#define CHECK_DO(COND, ACTION)
Definition: check_utils.h:57
Character string response.
Definition: proc_if.h:158
static int ffmpeg_mp3_enc_rest_get(proc_ctx_t *proc_ctx, const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
Definition: ffmpeg_mp3.c:368
struct ffmpeg_mp3_enc_ctx_s ffmpeg_mp3_enc_ctx_t
enum proc_if_rest_fmt_enum proc_if_rest_fmt_t
static int ffmpeg_mp3_dec_settings_ctx_init(volatile ffmpeg_mp3_dec_settings_ctx_t *ffmpeg_mp3_dec_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_mp3.c:802
proc_frame_ctx_t * avpacket_2_proc_frame_ctx(const void *avpacket_arg)
cJSON structure response
Definition: proc_if.h:159
volatile struct ffmpeg_mp3_enc_settings_ctx_s ffmpeg_mp3_enc_settings_ctx
Definition: ffmpeg_mp3.c:72
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)
struct audio_settings_dec_ctx_s audio_settings_dec_ctx
Definition: ffmpeg_mp3.c:84
AVCodecContext * avcodecctx
Definition: ffmpeg_audio.h:59
Audio encoder and decoder generic settings.
void * proc_frame_ctx_2_avpacket(const proc_frame_ctx_t *proc_frame_ctx)
static int ffmpeg_mp3_enc_process_frame(proc_ctx_t *proc_ctx, fifo_ctx_t *iput_fifo_ctx, fifo_ctx_t *oput_fifo_ctx)
Definition: ffmpeg_mp3.c:280
static void ffmpeg_mp3_dec_close(proc_ctx_t **ref_proc_ctx)
Definition: ffmpeg_mp3.c:582
int ffmpeg_audio_enc_ctx_init(ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx, int avcodecid, const audio_settings_enc_ctx_t *audio_settings_enc_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:55
static proc_ctx_t * ffmpeg_mp3_enc_open(const proc_if_t *proc_if, const char *settings_str, log_ctx_t *log_ctx, va_list arg)
Definition: ffmpeg_mp3.c:189
int ffmpeg_audio_dec_ctx_init(ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx, int avcodecid, const audio_settings_dec_ctx_t *audio_settings_dec_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_audio.c:229
void * proc_frame_ctx_2_avframe(const proc_frame_ctx_t *proc_frame_ctx)
Definition: log.c:102
static void ffmpeg_mp3_enc_close(proc_ctx_t **ref_proc_ctx)
Definition: ffmpeg_mp3.c:248
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)
static int ffmpeg_mp3_dec_rest_put(proc_ctx_t *proc_ctx, const char *str)
Definition: ffmpeg_mp3.c:659
log_ctx_t * log_ctx
Definition: proc.h:103
static int ffmpeg_mp3_enc_settings_ctx_init(volatile ffmpeg_mp3_enc_settings_ctx_t *ffmpeg_mp3_enc_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_mp3.c:469
FFmpeg MP3 audio encoder and decoder wrappers.