MediaProcessors
ffmpeg_lhe.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_lhe.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 "ffmpeg_video.h"
41 #include "proc_frame_2_ffmpeg.h"
42 #include "video_settings.h"
43 
44 /* **** Definitions **** */
45 
57 
61 typedef struct ffmpeg_mlhe_enc_ctx_s {
67  struct ffmpeg_video_enc_ctx_s ffmpeg_video_enc_ctx;
72  volatile struct ffmpeg_mlhe_enc_settings_ctx_s ffmpeg_mlhe_enc_settings_ctx;
74 
84  struct video_settings_dec_ctx_s video_settings_dec_ctx;
86 
90 typedef struct ffmpeg_mlhe_dec_ctx_s {
96  struct ffmpeg_video_dec_ctx_s ffmpeg_video_dec_ctx;
101  volatile struct ffmpeg_mlhe_dec_settings_ctx_s ffmpeg_mlhe_dec_settings_ctx;
103 
104 /* **** Prototypes **** */
105 
106 /* **** Encoder **** */
107 
108 static proc_ctx_t* ffmpeg_mlhe_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_mlhe_enc_close(proc_ctx_t **ref_proc_ctx);
111 static int ffmpeg_mlhe_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_mlhe_enc_rest_put(proc_ctx_t *proc_ctx, const char *str);
114 static int ffmpeg_mlhe_enc_rest_get(proc_ctx_t *proc_ctx,
115  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse);
116 
118  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx,
119  log_ctx_t *log_ctx);
121  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx,
122  log_ctx_t *log_ctx);
123 
124 /* **** Decoder **** */
125 
126 static proc_ctx_t* ffmpeg_mlhe_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_mlhe_dec_close(proc_ctx_t **ref_proc_ctx);
129 static int ffmpeg_mlhe_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_mlhe_dec_rest_put(proc_ctx_t *proc_ctx, const char *str);
133 static int ffmpeg_mlhe_dec_rest_get(proc_ctx_t *proc_ctx,
134  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse);
135 
137  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx,
138  log_ctx_t *log_ctx);
140  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx,
141  log_ctx_t *log_ctx);
142 
143 /* **** Implementations **** */
144 
146 {
147  "ffmpeg_mlhe_enc", "encoder", "video/mlhe",
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_mlhe_dec", "decoder", "video/mlhe",
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 
190  const char *settings_str, log_ctx_t *log_ctx, va_list arg)
191 {
192  int ret_code, end_code= STAT_ERROR;
193  ffmpeg_mlhe_enc_ctx_t *ffmpeg_mlhe_enc_ctx= NULL;
194  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx=
195  NULL; // Do not release
196  ffmpeg_video_enc_ctx_t *ffmpeg_video_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_mlhe_enc_ctx= (ffmpeg_mlhe_enc_ctx_t*)calloc(1, sizeof(
209  CHECK_DO(ffmpeg_mlhe_enc_ctx!= NULL, goto end);
210 
211  /* Get settings structure */
212  ffmpeg_mlhe_enc_settings_ctx=
213  &ffmpeg_mlhe_enc_ctx->ffmpeg_mlhe_enc_settings_ctx;
214 
215  /* Initialize settings to defaults */
216  ret_code= ffmpeg_mlhe_enc_settings_ctx_init(ffmpeg_mlhe_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_mlhe_enc_rest_put((proc_ctx_t*)ffmpeg_mlhe_enc_ctx,
222  settings_str);
223  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
224 
225  /* Get generic video encoder and settings context structures */
226  ffmpeg_video_enc_ctx= &ffmpeg_mlhe_enc_ctx->ffmpeg_video_enc_ctx;
227  video_settings_enc_ctx= (volatile video_settings_enc_ctx_t*)
228  ffmpeg_mlhe_enc_settings_ctx;
229 
230  /* Initialize FFMPEG's generic video encoder context */
231  ret_code= ffmpeg_video_enc_ctx_init(ffmpeg_video_enc_ctx,
232  (int)AV_CODEC_ID_MLHE,
233  (const video_settings_enc_ctx_t*)video_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_mlhe_enc_close((proc_ctx_t**)&ffmpeg_mlhe_enc_ctx);
241  return (proc_ctx_t*)ffmpeg_mlhe_enc_ctx;
242 }
243 
248 static void ffmpeg_mlhe_enc_close(proc_ctx_t **ref_proc_ctx)
249 {
250  ffmpeg_mlhe_enc_ctx_t *ffmpeg_mlhe_enc_ctx= NULL;
251 
252  if(ref_proc_ctx== NULL)
253  return;
254 
255  if((ffmpeg_mlhe_enc_ctx= (ffmpeg_mlhe_enc_ctx_t*)*ref_proc_ctx)!=
256  NULL) {
257  LOG_CTX_INIT(((proc_ctx_t*)ffmpeg_mlhe_enc_ctx)->log_ctx);
258 
259  /* De-initialize FFMPEG's generic video encoder context */
261  LOG_CTX_GET());
262 
263  /* Release settings */
265  &ffmpeg_mlhe_enc_ctx->ffmpeg_mlhe_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_mlhe_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_mlhe_enc_ctx_t *ffmpeg_mlhe_enc_ctx= NULL; // Do not release
285  ffmpeg_video_enc_ctx_t *ffmpeg_video_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 video encoder context */
298  ffmpeg_mlhe_enc_ctx= (ffmpeg_mlhe_enc_ctx_t*)proc_ctx;
299  ffmpeg_video_enc_ctx= &ffmpeg_mlhe_enc_ctx->ffmpeg_video_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_video_enc_frame(ffmpeg_video_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_mlhe_enc_rest_put(proc_ctx_t *proc_ctx, const char *str)
327 {
328  int ret_code;
329  ffmpeg_mlhe_enc_ctx_t *ffmpeg_mlhe_enc_ctx= NULL;
330  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_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 video encoder settings contexts */
341  ffmpeg_mlhe_enc_ctx= (ffmpeg_mlhe_enc_ctx_t*)proc_ctx;
342  ffmpeg_mlhe_enc_settings_ctx=
343  &ffmpeg_mlhe_enc_ctx->ffmpeg_mlhe_enc_settings_ctx;
344  video_settings_enc_ctx=
345  &ffmpeg_mlhe_enc_settings_ctx->video_settings_enc_ctx;
346 
347  /* PUT generic video encoder settings */
348  ret_code= video_settings_enc_ctx_restful_put(video_settings_enc_ctx, str,
349  LOG_CTX_GET());
350  if(ret_code!= STAT_SUCCESS)
351  return ret_code;
352 
353  /* PUT specific MLHE video encoder settings */
354  // Reserved for future use
355 
356  /* Finally that we have new settings parsed, reset FFMPEG processor */
358  (volatile void*)video_settings_enc_ctx, 1/*Signal is an encoder*/,
359  LOG_CTX_GET());
360 
361  return STAT_SUCCESS;
362 }
363 
369  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
370 {
371  int ret_code, end_code= STAT_ERROR;
372  ffmpeg_mlhe_enc_ctx_t *ffmpeg_mlhe_enc_ctx= NULL;
373  ffmpeg_video_enc_ctx_t *ffmpeg_video_enc_ctx= NULL;
374  AVCodecContext *avcodecctx= NULL;
375  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx= NULL;
377  cJSON *cjson_rest= NULL, *cjson_settings= NULL;
378  //cJSON *cjson_aux= NULL; // Do not release // Reserved for future use
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  * ... // Reserved for future use
401  * }
402  */
403 
404  /* Get FFmpeg video encoder settings contexts */
405  ffmpeg_mlhe_enc_ctx= (ffmpeg_mlhe_enc_ctx_t*)proc_ctx;
406  ffmpeg_mlhe_enc_settings_ctx=
407  &ffmpeg_mlhe_enc_ctx->ffmpeg_mlhe_enc_settings_ctx;
408  video_settings_enc_ctx=
409  &ffmpeg_mlhe_enc_settings_ctx->video_settings_enc_ctx;
410 
411  /* GET generic video encoder settings */
412  ret_code= video_settings_enc_ctx_restful_get(video_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 MLHE video 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_video_enc_ctx= &ffmpeg_mlhe_enc_ctx->ffmpeg_video_enc_ctx;
426  avcodecctx= ffmpeg_video_enc_ctx->avcodecctx;
427  CHECK_DO(avcodecctx!= NULL, goto end);
428 
429  // Reserved for future use
430  /* Example:
431  * cjson_aux= cJSON_CreateNumber((double)avcodecctx->var1);
432  * CHECK_DO(cjson_aux!= NULL, goto end);
433  * cJSON_AddItemToObject(cjson_rest, "var1_name", cjson_aux);
434  */
435 
436  // Reserved for future use: set other data values here...
437 
438  /* Format response to be returned */
439  switch(rest_fmt) {
441  /* Print cJSON structure data to char string */
442  *ref_reponse= (void*)CJSON_PRINT(cjson_rest);
443  CHECK_DO(*ref_reponse!= NULL && strlen((char*)*ref_reponse)> 0,
444  goto end);
445  break;
447  *ref_reponse= (void*)cjson_rest;
448  cjson_rest= NULL; // Avoid double referencing
449  break;
450  default:
451  LOGE("Unknown format requested for processor REST\n");
452  goto end;
453  }
454 
455  end_code= STAT_SUCCESS;
456 end:
457  if(cjson_settings!= NULL)
458  cJSON_Delete(cjson_settings);
459  if(cjson_rest!= NULL)
460  cJSON_Delete(cjson_rest);
461  return end_code;
462 }
463 
472  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx,
473  log_ctx_t *log_ctx)
474 {
475  int ret_code;
477  LOG_CTX_INIT(log_ctx);
478 
479  /* Check arguments */
480  CHECK_DO(ffmpeg_mlhe_enc_settings_ctx!= NULL, return STAT_ERROR);
481 
482  video_settings_enc_ctx=
483  &ffmpeg_mlhe_enc_settings_ctx->video_settings_enc_ctx;
484 
485  /* Initialize generic video encoder settings */
486  ret_code= video_settings_enc_ctx_init(video_settings_enc_ctx);
487  if(ret_code!= STAT_SUCCESS)
488  return ret_code;
489 
490  /* Initialize specific MLHE video encoder settings */
491  // Reserved for future use
492 
493  return STAT_SUCCESS;
494 }
495 
502  volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx,
503  log_ctx_t *log_ctx)
504 {
506  LOG_CTX_INIT(log_ctx);
507 
508  /* Check arguments */
509  CHECK_DO(ffmpeg_mlhe_enc_settings_ctx!= NULL, return);
510 
511  video_settings_enc_ctx=
512  &ffmpeg_mlhe_enc_settings_ctx->video_settings_enc_ctx;
513 
514  /* Release (heap-allocated) generic video encoder settings */
515  video_settings_enc_ctx_deinit(video_settings_enc_ctx);
516 
517  /* Release specific MLHE video encoder settings */
518  // Reserved for future use
519 }
520 
526  const char *settings_str, log_ctx_t *log_ctx, va_list arg)
527 {
528  int ret_code, end_code= STAT_ERROR;
529  ffmpeg_mlhe_dec_ctx_t *ffmpeg_mlhe_dec_ctx= NULL;
530  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx=
531  NULL; // Do not release
532  ffmpeg_video_dec_ctx_t *ffmpeg_video_dec_ctx= NULL; // Do not release
534  NULL; // Do not release
535  LOG_CTX_INIT(log_ctx);
536 
537  /* Check arguments */
538  CHECK_DO(proc_if!= NULL, return NULL);
539  CHECK_DO(settings_str!= NULL, return NULL);
540  // Note: 'log_ctx' is allowed to be NULL
541 
542  /* Allocate context structure */
543  ffmpeg_mlhe_dec_ctx= (ffmpeg_mlhe_dec_ctx_t*)calloc(1, sizeof(
545  CHECK_DO(ffmpeg_mlhe_dec_ctx!= NULL, goto end);
546 
547  /* Get settings structure */
548  ffmpeg_mlhe_dec_settings_ctx=
549  &ffmpeg_mlhe_dec_ctx->ffmpeg_mlhe_dec_settings_ctx;
550 
551  /* Initialize settings to defaults */
552  ret_code= ffmpeg_mlhe_dec_settings_ctx_init(ffmpeg_mlhe_dec_settings_ctx,
553  LOG_CTX_GET());
554  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
555 
556  /* Parse and put given settings */
557  ret_code= ffmpeg_mlhe_dec_rest_put((proc_ctx_t*)ffmpeg_mlhe_dec_ctx,
558  settings_str);
559  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
560 
561  /* Get generic video decoder and settings context structures */
562  ffmpeg_video_dec_ctx= &ffmpeg_mlhe_dec_ctx->ffmpeg_video_dec_ctx;
563  video_settings_dec_ctx= (volatile video_settings_dec_ctx_t*)
564  ffmpeg_mlhe_dec_settings_ctx;
565 
566  /* Initialize FFMPEG's generic video decoder context */
567  ret_code= ffmpeg_video_dec_ctx_init(ffmpeg_video_dec_ctx,
568  (int)AV_CODEC_ID_MLHE,
569  (const video_settings_dec_ctx_t*)video_settings_dec_ctx,
570  LOG_CTX_GET());
571  CHECK_DO(ret_code== STAT_SUCCESS, goto end);
572 
573  end_code= STAT_SUCCESS;
574  end:
575  if(end_code!= STAT_SUCCESS)
576  ffmpeg_mlhe_dec_close((proc_ctx_t**)&ffmpeg_mlhe_dec_ctx);
577  return (proc_ctx_t*)ffmpeg_mlhe_dec_ctx;
578 }
579 
584 static void ffmpeg_mlhe_dec_close(proc_ctx_t **ref_proc_ctx)
585 {
586  ffmpeg_mlhe_dec_ctx_t *ffmpeg_mlhe_dec_ctx= NULL;
587 
588  if(ref_proc_ctx== NULL)
589  return;
590 
591  if((ffmpeg_mlhe_dec_ctx= (ffmpeg_mlhe_dec_ctx_t*)*ref_proc_ctx)!= NULL) {
592  LOG_CTX_INIT(((proc_ctx_t*)ffmpeg_mlhe_dec_ctx)->log_ctx);
593 
594  /* De-initialize FFMPEG's generic video decoder context */
596  LOG_CTX_GET());
597 
598  /* Release settings */
600  &ffmpeg_mlhe_dec_ctx->ffmpeg_mlhe_dec_settings_ctx,
601  LOG_CTX_GET());
602 
603  // Reserved for future use: release other new variables here...
604 
605  /* Release context structure */
606  free(ffmpeg_mlhe_dec_ctx);
607  *ref_proc_ctx= NULL;
608  }
609 }
610 
616  fifo_ctx_t* iput_fifo_ctx, fifo_ctx_t* oput_fifo_ctx)
617 {
618  int ret_code, end_code= STAT_ERROR;
619  ffmpeg_mlhe_dec_ctx_t *ffmpeg_mlhe_dec_ctx= NULL; // Do not release
620  ffmpeg_video_dec_ctx_t *ffmpeg_video_dec_ctx= NULL; // Do not release
621  AVPacket *avpacket_iput= NULL;
622  size_t fifo_elem_size= 0;
623  LOG_CTX_INIT(NULL);
624 
625  /* Check arguments */
626  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
627  CHECK_DO(iput_fifo_ctx!= NULL, return STAT_ERROR);
628  CHECK_DO(oput_fifo_ctx!= NULL, return STAT_ERROR);
629 
630  LOG_CTX_SET(proc_ctx->log_ctx);
631 
632  /* Get FFmpeg video decoder context */
633  ffmpeg_mlhe_dec_ctx= (ffmpeg_mlhe_dec_ctx_t*)proc_ctx;
634  ffmpeg_video_dec_ctx= &ffmpeg_mlhe_dec_ctx->ffmpeg_video_dec_ctx;
635 
636  /* Get input packet from FIFO buffer */
637  ret_code= fifo_get(iput_fifo_ctx, (void**)&avpacket_iput, &fifo_elem_size);
638  CHECK_DO(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN, goto end);
639  if(ret_code== STAT_EAGAIN) {
640  /* This means FIFO was unblocked, just go out with EOF status */
641  end_code= STAT_EOF;
642  goto end;
643  }
644 
645  /* Decode frame */
646  ret_code= ffmpeg_video_dec_frame(ffmpeg_video_dec_ctx, avpacket_iput,
647  oput_fifo_ctx, LOG_CTX_GET());
648  CHECK_DO(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN, goto end);
649 
650  end_code= STAT_SUCCESS;
651 end:
652  if(avpacket_iput!= NULL)
653  avpacket_release((void**)&avpacket_iput);
654  return end_code;
655 }
656 
661 static int ffmpeg_mlhe_dec_rest_put(proc_ctx_t *proc_ctx, const char *str)
662 {
663  int ret_code;
664  ffmpeg_mlhe_dec_ctx_t *ffmpeg_mlhe_dec_ctx= NULL;
665  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx= NULL;
667  LOG_CTX_INIT(NULL);
668 
669  /* Check arguments */
670  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
671  CHECK_DO(str!= NULL, return STAT_ERROR);
672 
673  LOG_CTX_SET(proc_ctx->log_ctx);
674 
675  /* Get FFmpeg video decoder settings contexts */
676  ffmpeg_mlhe_dec_ctx= (ffmpeg_mlhe_dec_ctx_t*)proc_ctx;
677  ffmpeg_mlhe_dec_settings_ctx=
678  &ffmpeg_mlhe_dec_ctx->ffmpeg_mlhe_dec_settings_ctx;
679  video_settings_dec_ctx=
680  &ffmpeg_mlhe_dec_settings_ctx->video_settings_dec_ctx;
681 
682  /* PUT generic video decoder settings */
683  ret_code= video_settings_dec_ctx_restful_put(video_settings_dec_ctx, str,
684  LOG_CTX_GET());
685  if(ret_code!= STAT_SUCCESS)
686  return ret_code;
687 
688  /* PUT specific MLHE video decoder settings */
689  // Reserved for future use
690 
691  /* Finally that we have new settings parsed, reset FFMPEG processor */
693  (volatile void*)video_settings_dec_ctx, 0/*Signal is an decoder*/,
694  LOG_CTX_GET());
695 
696  return STAT_SUCCESS;
697 }
698 
704  const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
705 {
706  int ret_code, end_code= STAT_ERROR;
707  ffmpeg_mlhe_dec_ctx_t *ffmpeg_mlhe_dec_ctx= NULL;
708  ffmpeg_video_dec_ctx_t *ffmpeg_video_dec_ctx= NULL;
709  AVCodecContext *avcodecctx= NULL;
710  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx= NULL;
712  cJSON *cjson_rest= NULL, *cjson_settings= NULL;
713  //cJSON *cjson_aux= NULL; // Do not release // Future use
714  LOG_CTX_INIT(NULL);
715 
716  /* Check arguments */
717  CHECK_DO(proc_ctx!= NULL, return STAT_ERROR);
718  CHECK_DO(rest_fmt< PROC_IF_REST_FMT_ENUM_MAX, return STAT_ERROR);
719  CHECK_DO(ref_reponse!= NULL, return STAT_ERROR);
720 
721  LOG_CTX_SET(proc_ctx->log_ctx);
722 
723  *ref_reponse= NULL;
724 
725  /* Create cJSON tree root object */
726  cjson_rest= cJSON_CreateObject();
727  CHECK_DO(cjson_rest!= NULL, goto end);
728 
729  /* JSON string to be returned:
730  * {
731  * "settings":
732  * {
733  * ...
734  * },
735  * ... // reserved for future use
736  * }
737  */
738 
739  /* Get FFmpeg video decoder settings contexts */
740  ffmpeg_mlhe_dec_ctx= (ffmpeg_mlhe_dec_ctx_t*)proc_ctx;
741  ffmpeg_mlhe_dec_settings_ctx=
742  &ffmpeg_mlhe_dec_ctx->ffmpeg_mlhe_dec_settings_ctx;
743  video_settings_dec_ctx=
744  &ffmpeg_mlhe_dec_settings_ctx->video_settings_dec_ctx;
745 
746  /* GET generic video decoder settings */
747  ret_code= video_settings_dec_ctx_restful_get(video_settings_dec_ctx,
748  &cjson_settings, LOG_CTX_GET());
749  CHECK_DO(ret_code== STAT_SUCCESS && cjson_settings!= NULL, goto end);
750 
751  /* GET specific MLHE video decoder settings */
752  // Reserved for future use: attach to 'cjson_settings' (should be != NULL)
753 
754  /* Attach settings object to REST response */
755  cJSON_AddItemToObject(cjson_rest, "settings", cjson_settings);
756  cjson_settings= NULL; // Attached; avoid double referencing
757 
758  /* **** Attach data to REST response **** */
759 
760  ffmpeg_video_dec_ctx= &ffmpeg_mlhe_dec_ctx->ffmpeg_video_dec_ctx;
761  avcodecctx= ffmpeg_video_dec_ctx->avcodecctx;
762  CHECK_DO(avcodecctx!= NULL, goto end);
763 
764  // Reserved for future use
765  /* Example:
766  * cjson_aux= cJSON_CreateNumber((double)avcodecctx->var1);
767  * CHECK_DO(cjson_aux!= NULL, goto end);
768  * cJSON_AddItemToObject(cjson_rest, "var1_name", cjson_aux);
769  */
770 
771  /* Format response to be returned */
772  switch(rest_fmt) {
774  /* Print cJSON structure data to char string */
775  *ref_reponse= (void*)CJSON_PRINT(cjson_rest);
776  CHECK_DO(*ref_reponse!= NULL && strlen((char*)*ref_reponse)> 0,
777  goto end);
778  break;
780  *ref_reponse= (void*)cjson_rest;
781  cjson_rest= NULL; // Avoid double referencing
782  break;
783  default:
784  LOGE("Unknown format requested for processor REST\n");
785  goto end;
786  }
787 
788  end_code= STAT_SUCCESS;
789 end:
790  if(cjson_settings!= NULL)
791  cJSON_Delete(cjson_settings);
792  if(cjson_rest!= NULL)
793  cJSON_Delete(cjson_rest);
794  return end_code;
795 }
796 
805  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx,
806  log_ctx_t *log_ctx)
807 {
808  int ret_code;
810  LOG_CTX_INIT(log_ctx);
811 
812  /* Check arguments */
813  CHECK_DO(ffmpeg_mlhe_dec_settings_ctx!= NULL, return STAT_ERROR);
814 
815  video_settings_dec_ctx=
816  &ffmpeg_mlhe_dec_settings_ctx->video_settings_dec_ctx;
817 
818  /* Initialize generic video decoder settings */
819  ret_code= video_settings_dec_ctx_init(video_settings_dec_ctx);
820  if(ret_code!= STAT_SUCCESS)
821  return ret_code;
822 
823  /* Initialize specific MLHE video decoder settings */
824  // Reserved for future use
825 
826  return STAT_SUCCESS;
827 }
828 
835  volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx,
836  log_ctx_t *log_ctx)
837 {
839  LOG_CTX_INIT(log_ctx);
840 
841  /* Check arguments */
842  CHECK_DO(ffmpeg_mlhe_dec_settings_ctx!= NULL, return);
843 
844  video_settings_dec_ctx=
845  &ffmpeg_mlhe_dec_settings_ctx->video_settings_dec_ctx;
846 
847  /* Release (heap-allocated) generic video decoder settings */
848  video_settings_dec_ctx_deinit(video_settings_dec_ctx);
849 
850  /* Release specific MLHE video decoder settings */
851  // Reserved for future use
852 }
static int ffmpeg_mlhe_enc_rest_get(proc_ctx_t *proc_ctx, const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
Definition: ffmpeg_lhe.c:368
static proc_ctx_t * ffmpeg_mlhe_enc_open(const proc_if_t *proc_if, const char *settings_str, log_ctx_t *log_ctx, va_list arg)
Definition: ffmpeg_lhe.c:189
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
static int ffmpeg_mlhe_dec_rest_get(proc_ctx_t *proc_ctx, const proc_if_rest_fmt_t rest_fmt, void **ref_reponse)
Definition: ffmpeg_lhe.c:703
#define CJSON_PRINT(CJSON_PTR)
Definition: proc.h:70
Facilities to convert processor&#39;s input/output frame to FFmpeg&#39;s formats and vice versa...
proc_frame_ctx_t * avframe_2_proc_frame_ctx(const void *avframe_arg)
static int ffmpeg_mlhe_enc_process_frame(proc_ctx_t *proc_ctx, fifo_ctx_t *iput_fifo_ctx, fifo_ctx_t *oput_fifo_ctx)
Definition: ffmpeg_lhe.c:280
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)
void ffmpeg_video_reset_on_new_settings(proc_ctx_t *proc_ctx, volatile void *video_settings_opaque, int flag_is_encoder, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:496
static int ffmpeg_mlhe_enc_rest_put(proc_ctx_t *proc_ctx, const char *str)
Definition: ffmpeg_lhe.c:326
struct video_settings_dec_ctx_s video_settings_dec_ctx
Definition: ffmpeg_lhe.c:84
Video encoder and decoder generic settings.
struct ffmpeg_video_dec_ctx_s ffmpeg_video_dec_ctx
Definition: ffmpeg_lhe.c:96
int ffmpeg_video_enc_frame(ffmpeg_video_enc_ctx_t *ffmpeg_video_enc_ctx, AVFrame *avframe_iput, fifo_ctx_t *oput_fifo_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:186
int video_settings_dec_ctx_init(volatile video_settings_dec_ctx_t *video_settings_dec_ctx)
struct video_settings_enc_ctx_s video_settings_enc_ctx
Definition: ffmpeg_lhe.c:55
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)
static int ffmpeg_mlhe_enc_settings_ctx_init(volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_lhe.c:471
Generic processor module context (see type proc_ctx_t) extension for video encoders and decoders...
struct ffmpeg_mlhe_enc_ctx_s ffmpeg_mlhe_enc_ctx_t
const proc_if_t proc_if_ffmpeg_mlhe_enc
Definition: ffmpeg_lhe.c:145
volatile struct ffmpeg_mlhe_dec_settings_ctx_s ffmpeg_mlhe_dec_settings_ctx
Definition: ffmpeg_lhe.c:101
static void ffmpeg_mlhe_enc_close(proc_ctx_t **ref_proc_ctx)
Definition: ffmpeg_lhe.c:248
static void ffmpeg_mlhe_dec_close(proc_ctx_t **ref_proc_ctx)
Definition: ffmpeg_lhe.c:584
void video_settings_enc_ctx_deinit(volatile video_settings_enc_ctx_t *video_settings_enc_ctx)
struct ffmpeg_video_enc_ctx_s ffmpeg_video_enc_ctx
Definition: ffmpeg_lhe.c:67
void avpacket_release(void **ref_avpacket)
int ffmpeg_video_dec_frame(ffmpeg_video_dec_ctx_t *ffmpeg_video_dec_ctx, AVPacket *avpacket_iput, fifo_ctx_t *oput_fifo_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:413
AVCodecContext * avcodecctx
Definition: ffmpeg_video.h:63
void ffmpeg_video_dec_ctx_deinit(ffmpeg_video_dec_ctx_t *ffmpeg_video_dec_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:403
static void ffmpeg_mlhe_enc_settings_ctx_deinit(volatile ffmpeg_mlhe_enc_settings_ctx_t *ffmpeg_mlhe_enc_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_lhe.c:501
#define CHECK_DO(COND, ACTION)
Definition: check_utils.h:57
Character string response.
Definition: proc_if.h:158
FFmpeg LHE/MLHE video encoder and decoder wrappers.
enum proc_if_rest_fmt_enum proc_if_rest_fmt_t
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)
static int ffmpeg_mlhe_dec_settings_ctx_init(volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_lhe.c:804
struct ffmpeg_mlhe_dec_settings_ctx_s ffmpeg_mlhe_dec_settings_ctx_t
proc_frame_ctx_t * avpacket_2_proc_frame_ctx(const void *avpacket_arg)
cJSON structure response
Definition: proc_if.h:159
static int ffmpeg_mlhe_dec_process_frame(proc_ctx_t *proc_ctx, fifo_ctx_t *iput_fifo_ctx, fifo_ctx_t *oput_fifo_ctx)
Definition: ffmpeg_lhe.c:615
static void ffmpeg_mlhe_dec_settings_ctx_deinit(volatile ffmpeg_mlhe_dec_settings_ctx_t *ffmpeg_mlhe_dec_settings_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_lhe.c:834
int ffmpeg_video_enc_ctx_init(ffmpeg_video_enc_ctx_t *ffmpeg_video_enc_ctx, int avcodecid, const video_settings_enc_ctx_t *video_settings_enc_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:53
volatile struct ffmpeg_mlhe_enc_settings_ctx_s ffmpeg_mlhe_enc_settings_ctx
Definition: ffmpeg_lhe.c:72
struct ffmpeg_mlhe_enc_settings_ctx_s ffmpeg_mlhe_enc_settings_ctx_t
void * proc_frame_ctx_2_avpacket(const proc_frame_ctx_t *proc_frame_ctx)
AVCodecContext * avcodecctx
Definition: ffmpeg_video.h:110
static proc_ctx_t * ffmpeg_mlhe_dec_open(const proc_if_t *proc_if, const char *settings_str, log_ctx_t *log_ctx, va_list arg)
Definition: ffmpeg_lhe.c:525
void * proc_frame_ctx_2_avframe(const proc_frame_ctx_t *proc_frame_ctx)
Definition: log.c:102
struct ffmpeg_mlhe_dec_ctx_s ffmpeg_mlhe_dec_ctx_t
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 ffmpeg_video_enc_ctx_deinit(ffmpeg_video_enc_ctx_t *ffmpeg_video_enc_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:163
void video_settings_dec_ctx_deinit(volatile video_settings_dec_ctx_t *video_settings_dec_ctx)
const proc_if_t proc_if_ffmpeg_mlhe_dec
Definition: ffmpeg_lhe.c:165
int ffmpeg_video_dec_ctx_init(ffmpeg_video_dec_ctx_t *ffmpeg_video_dec_ctx, int avcodecid, const video_settings_dec_ctx_t *video_settings_dec_ctx, log_ctx_t *log_ctx)
Definition: ffmpeg_video.c:348
log_ctx_t * log_ctx
Definition: proc.h:103
static int ffmpeg_mlhe_dec_rest_put(proc_ctx_t *proc_ctx, const char *str)
Definition: ffmpeg_lhe.c:661