MediaProcessors
utests_proc.cpp
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 
26 #include <UnitTest++/UnitTest++.h>
27 
28 extern "C" {
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <string.h>
35 
36 #include <libmediaprocsutils/log.h>
37 #include <libmediaprocsutils/stat_codes.h>
38 #include <libmediaprocsutils/fifo.h>
39 #include <libmediaprocs/proc_if.h>
40 #include <libmediaprocs/proc.h>
41 }
42 
43 /* **** Define a very simple bypass processor **** */
44 
45 static proc_ctx_t* bypass_proc_open(const proc_if_t*, const char *settings_str,
46  log_ctx_t *log_ctx, va_list arg)
47 {
48  return (proc_ctx_t*)calloc(1, sizeof(proc_ctx_t));
49 }
50 
51 static void bypass_proc_close(proc_ctx_t **ref_proc_ctx)
52 {
53  proc_ctx_t *proc_ctx= NULL;
54 
55  if(ref_proc_ctx== NULL)
56  return;
57 
58  if((proc_ctx= *ref_proc_ctx)!= NULL) {
59  free(proc_ctx);
60  *ref_proc_ctx= NULL;
61  }
62 }
63 
64 static int bypass_proc_rest_put(proc_ctx_t*, const char *str)
65 {
66  return STAT_SUCCESS;
67 }
68 
69 static int bypass_proc_rest_get(proc_ctx_t*, const proc_if_rest_fmt_t rest_fmt,
70  void **ref_reponse)
71 {
72  return STAT_SUCCESS;
73 }
74 
75 static int bypass_proc_process_frame(proc_ctx_t *proc_ctx,
76  fifo_ctx_t *fifo_ctx_iput, fifo_ctx_t *fifo_ctx_oput)
77 {
78  int ret_code;
79  size_t fifo_elem_size= 0;
80  proc_frame_ctx_t *proc_frame_ctx= NULL;
81 
82  /* Just "bypass" frame from input to output */
83  ret_code= fifo_get(proc_ctx->fifo_ctx_array[PROC_IPUT],
84  (void**)&proc_frame_ctx, &fifo_elem_size);
85  CHECK(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN);
86  if(ret_code!= STAT_SUCCESS)
87  goto end;
88 
89  ret_code= fifo_put_dup(proc_ctx->fifo_ctx_array[PROC_OPUT],
90  proc_frame_ctx, sizeof(void*));
91  CHECK(ret_code== STAT_SUCCESS || ret_code== STAT_ENOMEM);
92 
93 end:
94  if(proc_frame_ctx!= NULL)
95  proc_frame_ctx_release(&proc_frame_ctx);
96  return STAT_SUCCESS;
97 }
98 
99 SUITE(UTESTS_PROC)
100 {
101  TEST(ALLOCATE_RELEASE_PROC)
102  {
103 #define FIFO_SIZE 2
104  int frame_idx, i, x, y, ret_code;
105  proc_ctx_t *proc_ctx= NULL;
106  const proc_if_t proc_if_bypass_proc= {
107  "bypass_processor", "encoder", "application/octet-stream",
108  (uint64_t)(PROC_FEATURE_BITRATE|PROC_FEATURE_REGISTER_PTS|
109  PROC_FEATURE_LATENCY),
110  bypass_proc_open,
111  bypass_proc_close,
112  proc_send_frame_default1,
113  NULL, // no 'send-no-dup'
114  proc_recv_frame_default1,
115  NULL, // no specific unblock function extension
116  bypass_proc_rest_put,
117  bypass_proc_rest_get,
118  bypass_proc_process_frame,
119  NULL,
120  (void*(*)(const proc_frame_ctx_t*))proc_frame_ctx_dup,
121  (void(*)(void**))proc_frame_ctx_release,
122  (proc_frame_ctx_t*(*)(const void*))proc_frame_ctx_dup
123  };
124  uint32_t fifo_ctx_maxsize[PROC_IO_NUM]= {FIFO_SIZE, FIFO_SIZE};
125  proc_frame_ctx_t *proc_frame_ctx= NULL;
126  uint8_t yuv_frame[48]= { // YUV4:2:0 simple data example
127  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // Y
128  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // Y
129  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // Y
130  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // Y
131  0x00, 0x01, 0x02, 0x03, // U
132  0x04, 0x05, 0x06, 0x07, // U
133  0x00, 0x01, 0x02, 0x03, // V
134  0x04, 0x05, 0x06, 0x07 // V
135  };
136  proc_frame_ctx_t proc_frame_ctx_yuv= {0};
137 
138  if(log_module_open()!= STAT_SUCCESS) {
139  printf("Could not initialize LOG module\n");
140  return;
141  }
142 
143  /* Initialize YUV frame structure */
144  proc_frame_ctx_yuv.data= yuv_frame;
145  proc_frame_ctx_yuv.p_data[0]= &yuv_frame[0]; // Y
146  proc_frame_ctx_yuv.p_data[1]= &yuv_frame[32]; // U
147  proc_frame_ctx_yuv.p_data[2]= &yuv_frame[40]; // V
148  proc_frame_ctx_yuv.linesize[0]= proc_frame_ctx_yuv.width[0]= 8;
149  proc_frame_ctx_yuv.linesize[1]= proc_frame_ctx_yuv.width[1]= 4;
150  proc_frame_ctx_yuv.linesize[2]= proc_frame_ctx_yuv.width[2]= 4;
151  proc_frame_ctx_yuv.height[0]= 4;
152  proc_frame_ctx_yuv.height[1]= proc_frame_ctx_yuv.height[2]= 2;
153  proc_frame_ctx_yuv.proc_sample_fmt= PROC_IF_FMT_UNDEF;
154  proc_frame_ctx_yuv.pts= -1;
155  proc_frame_ctx_yuv.dts= -1;
156 
157  /* Open processor */
158  proc_ctx= proc_open(&proc_if_bypass_proc, ""/*settings*/, 0/*index*/,
159  fifo_ctx_maxsize, NULL/*LOG*/, NULL);
160  CHECK(proc_ctx!= NULL);
161  if(proc_ctx== NULL)
162  return;
163 
164  /* Fill processor input FIFO with two equal YUV frames */
165  for(frame_idx= 0; frame_idx< FIFO_SIZE; frame_idx++) {
166  ret_code= proc_send_frame(proc_ctx, &proc_frame_ctx_yuv);
167  CHECK(ret_code== STAT_SUCCESS);
168  }
169 
170  /* Read previously pushed frames from processor (in this simple test
171  * the processor is just a "bypass").
172  */
173  for(frame_idx= 0; frame_idx< FIFO_SIZE; frame_idx++) {
174  if(proc_frame_ctx!= NULL)
175  proc_frame_ctx_release(&proc_frame_ctx);
176  ret_code= proc_recv_frame(proc_ctx, &proc_frame_ctx);
177  CHECK(ret_code== STAT_SUCCESS);
178  CHECK(proc_frame_ctx!= NULL);
179  if(proc_frame_ctx== NULL)
180  goto end;
181 
182  CHECK(proc_frame_ctx->proc_sample_fmt== PROC_IF_FMT_UNDEF);
183  CHECK(proc_frame_ctx->pts== -1);
184  CHECK(proc_frame_ctx->dts== -1);
185  for(i= 0; i< 3/*Num. of data planes*/; i++) {
186  for(y= 0; y< (int)proc_frame_ctx->height[i]; y++) {
187  for(x= 0; x< (int)proc_frame_ctx->width[i]; x++) {
188  int data_coord= x+ y* proc_frame_ctx->linesize[i];
189  uint8_t data_val= proc_frame_ctx->p_data[i][data_coord];
190  int expected_val= x+ y* proc_frame_ctx_yuv.width[i];
191  CHECK(data_val== expected_val);
192  //printf("0x%02x ", data_val); // comment-me
193  }
194  //printf("\n"); // comment-me
195  }
196  }
197  }
198 
199 end:
200  /* Close processor and release frame data if applicable */
201  proc_close(&proc_ctx);
202  proc_frame_ctx_release(&proc_frame_ctx);
203 
204  log_module_close();
205 #undef FIFO_SIZE
206  }
207 }
int fifo_get(fifo_ctx_t *fifo_ctx, void **ref_elem, size_t *ref_elem_size)
Definition: fifo.c:366
size_t width[PROC_FRAME_NUM_DATA_POINTERS]
Definition: proc_if.h:113
void proc_frame_ctx_release(proc_frame_ctx_t **ref_proc_frame_ctx)
Definition: proc_if.c:125
int linesize[PROC_FRAME_NUM_DATA_POINTERS]
Definition: proc_if.h:107
int fifo_put_dup(fifo_ctx_t *fifo_ctx, const void *elem, size_t elem_size)
Definition: fifo.c:355
SUITE(UTESTS_LIVE555_RTSP)
int proc_send_frame(proc_ctx_t *proc_ctx, const proc_frame_ctx_t *proc_frame_ctx)
Definition: proc.c:287
int proc_sample_fmt
Definition: proc_if.h:127
int64_t dts
Definition: proc_if.h:144
proc_ctx_t * proc_open(const proc_if_t *proc_if, const char *settings_str, int proc_instance_index, uint32_t fifo_ctx_maxsize[PROC_IO_NUM], log_ctx_t *log_ctx, va_list arg)
Definition: proc.c:87
enum proc_if_rest_fmt_enum proc_if_rest_fmt_t
fifo_ctx_t * fifo_ctx_array[PROC_IO_NUM]
Definition: proc.h:107
int proc_recv_frame(proc_ctx_t *proc_ctx, proc_frame_ctx_t **ref_proc_frame_ctx)
Definition: proc.c:323
Undefined format.
Definition: proc_if.h:54
proc_frame_ctx_t * proc_frame_ctx_dup(const proc_frame_ctx_t *proc_frame_ctx_arg)
Definition: proc_if.c:52
size_t height[PROC_FRAME_NUM_DATA_POINTERS]
Definition: proc_if.h:119
Definition: log.c:102
void proc_close(proc_ctx_t **ref_proc_ctx)
Definition: proc.c:208
const uint8_t * p_data[PROC_FRAME_NUM_DATA_POINTERS]
Definition: proc_if.h:94
uint8_t * data
Definition: proc_if.h:84
int64_t pts
Definition: proc_if.h:138