26 #include <UnitTest++/UnitTest++.h> 32 #include <sys/types.h> 36 #include <libcjson/cJSON.h> 37 #include <libmediaprocsutils/log.h> 38 #include <libmediaprocsutils/stat_codes.h> 39 #include <libmediaprocsutils/check_utils.h> 40 #include <libmediaprocsutils/schedule.h> 41 #include <libmediaprocs/proc_if.h> 42 #include <libmediaprocs/procs.h> 43 #include <libmediaprocsmuxers/live555_rtsp.h> 48 #define FRAME_SIZE 2048 51 volatile int flag_exit;
58 static void* consumer_thr(
void *t)
60 int i, ret_code, elem_strem_id_step= -1, elem_strem_id_alt= -1;
61 int elementary_streams_cnt= 0;
65 cJSON *cjson_rest= NULL, *cjson_es_array= NULL, *cjson_aux= NULL;
79 ret_code= STAT_EAGAIN;
80 while(ret_code!= STAT_SUCCESS && thr_ctx->flag_exit== 0) {
83 thr_ctx->dmux_proc_id, &proc_frame_ctx);
85 if(thr_ctx->flag_exit!= 0) {
89 if(ret_code!= STAT_SUCCESS || proc_frame_ctx== NULL) {
95 ret_code=
procs_opt(thr_ctx->procs_ctx,
"PROCS_ID_GET",
96 thr_ctx->dmux_proc_id, &rest_str);
97 if(ret_code!= STAT_SUCCESS || rest_str== NULL) {
101 if((cjson_rest= cJSON_Parse(rest_str))== NULL) {
106 if((cjson_es_array= cJSON_GetObjectItem(cjson_rest,
107 "elementary_streams"))== NULL) {
112 elementary_streams_cnt= cJSON_GetArraySize(cjson_es_array);
113 for(i= 0; i< elementary_streams_cnt; i++) {
114 cJSON *cjson_es= cJSON_GetArrayItem(cjson_es_array, i);
115 if(cjson_es!= NULL) {
116 int elementary_stream_id;
120 cjson_aux= cJSON_GetObjectItem(cjson_es,
121 "elementary_stream_id");
122 if(cjson_aux== NULL) {
126 elementary_stream_id= cjson_aux->valueint;
129 cjson_aux= cJSON_GetObjectItem(cjson_es,
"sdp_mimetype");
130 if(cjson_aux== NULL) {
134 mime= cjson_aux->valuestring;
135 if(mime!= NULL && strcasecmp(
"application/step-data",
137 elem_strem_id_step= elementary_stream_id;
138 else if(mime!= NULL && strcasecmp(
"application/alternate-data",
140 elem_strem_id_alt= elementary_stream_id;
143 free(rest_str); rest_str= NULL;
144 cJSON_Delete(cjson_rest); cjson_rest= NULL;
145 if(elem_strem_id_alt< 0 || elem_strem_id_alt< 0) {
150 while(thr_ctx->flag_exit== 0) {
155 thr_ctx->dmux_proc_id, &proc_frame_ctx);
156 CHECK(ret_code== STAT_SUCCESS || ret_code== STAT_EAGAIN ||
157 ret_code== STAT_ENOTFOUND);
160 if(proc_frame_ctx!= NULL) {
162 const uint8_t *data_buf= proc_frame_ctx->
p_data[0];
163 int frame_size= (int)proc_frame_ctx->
width[0];
164 printf(
"Got frame!\n"); fflush(stdout);
167 CHECK(frame_size== FRAME_SIZE);
176 if(proc_frame_ctx->
es_id== elem_strem_id_step) {
178 for(i= 0, val_32b= 0; i< frame_size; i+= 4, val_32b++) {
179 CHECK(data_buf[i+0]== (((uint32_t)val_32b>>24)& 0xFF));
180 CHECK(data_buf[i+1]== (((uint32_t)val_32b>>16)& 0xFF));
181 CHECK(data_buf[i+2]== (((uint32_t)val_32b>> 8)& 0xFF));
182 CHECK(data_buf[i+3]== (((uint32_t)val_32b>> 0)& 0xFF));
184 }
else if(proc_frame_ctx->
es_id== elem_strem_id_alt) {
186 for(i= 0; i< frame_size; i++)
187 CHECK(data_buf[i]== (i&1? 0xFF: 0));
201 const char *proc_settings,
int *ref_proc_id)
204 char *rest_str= NULL;
205 cJSON *cjson_rest= NULL, *cjson_aux= NULL;
207 ret_code=
procs_opt(procs_ctx,
"PROCS_POST", proc_name, proc_settings,
209 if(ret_code!= STAT_SUCCESS || rest_str== NULL) {
213 if((cjson_rest= cJSON_Parse(rest_str))== NULL) {
217 if((cjson_aux= cJSON_GetObjectItem(cjson_rest,
"proc_id"))== NULL) {
221 if((*ref_proc_id= cjson_aux->valuedouble)< 0) {
225 free(rest_str); rest_str= NULL;
226 cJSON_Delete(cjson_rest); cjson_rest= NULL;
229 TEST(UTESTS_LIVE555_RTSP_SERVER)
231 pthread_t consumer_thread;
232 int i, ret_code, mux_proc_id= -1, dmux_proc_id= -1,
233 elem_strem_id_step= -1, elem_strem_id_alt= -1;
235 char *rest_str= NULL;
236 cJSON *cjson_rest= NULL, *cjson_aux= NULL, *cjson_aux2= NULL;
239 uint8_t data_buf_template1[FRAME_SIZE];
240 uint8_t data_buf_template2[FRAME_SIZE];
248 if(ret_code!= STAT_SUCCESS) {
256 if(ret_code!= STAT_SUCCESS) {
262 if(ret_code!= STAT_SUCCESS) {
269 if(procs_ctx== NULL) {
275 procs_post(procs_ctx,
"live555_rtsp_mux",
"rtsp_port=8554",
279 ret_code=
procs_opt(procs_ctx,
"PROCS_ID_ES_MUX_REGISTER", mux_proc_id,
280 "sdp_mimetype=application/step-data", &rest_str);
281 if(ret_code!= STAT_SUCCESS || rest_str== NULL) {
282 fprintf(stderr,
"Error at line: %d\n", __LINE__);
285 if((cjson_rest= cJSON_Parse(rest_str))== NULL) {
286 fprintf(stderr,
"Error at line: %d\n", __LINE__);
289 if((cjson_aux= cJSON_GetObjectItem(cjson_rest,
290 "elementary_stream_id"))== NULL) {
291 fprintf(stderr,
"Error at line: %d\n", __LINE__);
294 if((elem_strem_id_step= cjson_aux->valuedouble)< 0) {
295 fprintf(stderr,
"Error at line: %d\n", __LINE__);
298 free(rest_str); rest_str= NULL;
299 cJSON_Delete(cjson_rest); cjson_rest= NULL;
302 ret_code=
procs_opt(procs_ctx,
"PROCS_ID_ES_MUX_REGISTER", mux_proc_id,
303 "sdp_mimetype=application/alternate-data", &rest_str);
304 if(ret_code!= STAT_SUCCESS || rest_str== NULL) {
305 fprintf(stderr,
"Error at line: %d\n", __LINE__);
308 if((cjson_rest= cJSON_Parse(rest_str))== NULL) {
309 fprintf(stderr,
"Error at line: %d\n", __LINE__);
312 if((cjson_aux= cJSON_GetObjectItem(cjson_rest,
313 "elementary_stream_id"))== NULL) {
314 fprintf(stderr,
"Error at line: %d\n", __LINE__);
317 if((elem_strem_id_alt= cjson_aux->valuedouble)< 0) {
318 fprintf(stderr,
"Error at line: %d\n", __LINE__);
321 free(rest_str); rest_str= NULL;
322 cJSON_Delete(cjson_rest); cjson_rest= NULL;
326 "rtsp_url=rtsp://127.0.0.1:8554/session", &dmux_proc_id);
329 thr_ctx.flag_exit= 0;
330 thr_ctx.procs_ctx= procs_ctx;
331 thr_ctx.dmux_proc_id= dmux_proc_id;
332 thr_ctx.proc_frame_ctx_template1= &proc_frame_ctx_template1;
333 thr_ctx.proc_frame_ctx_template2= &proc_frame_ctx_template2;
334 ret_code= pthread_create(&consumer_thread, NULL, consumer_thr,
347 proc_frame_ctx_template1.
data= data_buf_template1;
348 proc_frame_ctx_template1.
p_data[0]= data_buf_template1;
349 proc_frame_ctx_template1.
linesize[0]= FRAME_SIZE;
350 proc_frame_ctx_template1.
width[0]= FRAME_SIZE;
351 proc_frame_ctx_template1.
height[0]= 1;
352 proc_frame_ctx_template1.
pts= 0;
353 proc_frame_ctx_template1.
es_id= elem_strem_id_step;
354 for(
int i= 0, val_32b= 0; i< FRAME_SIZE; i+= 4, val_32b++) {
355 data_buf_template1[i+ 0]= ((uint32_t)val_32b>> 24)& 0xFF;
356 data_buf_template1[i+ 1]= ((uint32_t)val_32b>> 16)& 0xFF;
357 data_buf_template1[i+ 2]= ((uint32_t)val_32b>> 8)& 0xFF;
358 data_buf_template1[i+ 3]= ((uint32_t)val_32b>> 0)& 0xFF;
362 proc_frame_ctx_template2.
data= data_buf_template2;
363 proc_frame_ctx_template2.
p_data[0]= data_buf_template2;
364 proc_frame_ctx_template2.
linesize[0]= FRAME_SIZE;
365 proc_frame_ctx_template2.
width[0]= FRAME_SIZE;
366 proc_frame_ctx_template2.
height[0]= 1;
367 proc_frame_ctx_template2.
pts= 0;
368 proc_frame_ctx_template2.
es_id= elem_strem_id_alt;
369 for(
int i= 0; i< FRAME_SIZE; i++)
370 data_buf_template2[i]= i&1? 0xFF: 0;
373 for(i= 0; i< 10; i++) {
376 &proc_frame_ctx_template1)== STAT_SUCCESS);
378 &proc_frame_ctx_template2)== STAT_SUCCESS);
383 thr_ctx.flag_exit= 1;
386 ret_code=
procs_opt(procs_ctx,
"PROCS_ID_DELETE", dmux_proc_id);
387 CHECK(ret_code== STAT_SUCCESS);
392 for(i= 0; i< 10; i++) {
395 &proc_frame_ctx_template1)== STAT_SUCCESS);
397 &proc_frame_ctx_template2)== STAT_SUCCESS);
402 ret_code=
procs_opt(procs_ctx,
"PROCS_ID_PUT", mux_proc_id,
403 "rtsp_streaming_session_name=session2&rtsp_port=1999");
404 if(ret_code!= STAT_SUCCESS) {
410 ret_code=
procs_opt(procs_ctx,
"PROCS_ID_GET", mux_proc_id, &rest_str);
411 if(ret_code!= STAT_SUCCESS || rest_str== NULL) {
412 fprintf(stderr,
"Error at line: %d\n", __LINE__);
415 if((cjson_rest= cJSON_Parse(rest_str))== NULL) {
416 fprintf(stderr,
"Error at line: %d\n", __LINE__);
419 if((cjson_aux= cJSON_GetObjectItem(cjson_rest,
"settings"))== NULL) {
420 fprintf(stderr,
"Error at line: %d\n", __LINE__);
423 if((cjson_aux2= cJSON_GetObjectItem(cjson_aux,
424 "rtsp_streaming_session_name"))== NULL) {
425 fprintf(stderr,
"Error at line: %d\n", __LINE__);
428 CHECK(strcmp(cjson_aux2->valuestring,
"session2")== 0);
429 if((cjson_aux2= cJSON_GetObjectItem(cjson_aux,
430 "rtsp_port"))== NULL) {
431 fprintf(stderr,
"Error at line: %d\n", __LINE__);
434 CHECK(cjson_aux2->valueint== 1999);
435 free(rest_str); rest_str= NULL;
436 cJSON_Delete(cjson_rest); cjson_rest= NULL;
439 ret_code=
procs_opt(procs_ctx,
"PROCS_ID_DELETE", mux_proc_id);
440 CHECK(ret_code== STAT_SUCCESS);
441 pthread_join(consumer_thread, NULL);
size_t width[PROC_FRAME_NUM_DATA_POINTERS]
void proc_frame_ctx_release(proc_frame_ctx_t **ref_proc_frame_ctx)
int linesize[PROC_FRAME_NUM_DATA_POINTERS]
struct thr_ctx_s thr_ctx_t
SUITE(UTESTS_LIVE555_RTSP)
int procs_opt(procs_ctx_t *procs_ctx, const char *tag,...)
int procs_module_open(log_ctx_t *log_ctx)
int procs_module_opt(const char *tag,...)
int procs_recv_frame(procs_ctx_t *procs_ctx, int proc_id, proc_frame_ctx_t **ref_proc_frame_ctx)
void procs_module_close()
const proc_if_t proc_if_live555_rtsp_mux
int procs_send_frame(procs_ctx_t *procs_ctx, int proc_id, const proc_frame_ctx_t *proc_frame_ctx)
const proc_if_t proc_if_live555_rtsp_dmux
size_t height[PROC_FRAME_NUM_DATA_POINTERS]
void procs_close(procs_ctx_t **ref_procs_ctx)
const uint8_t * p_data[PROC_FRAME_NUM_DATA_POINTERS]
procs_ctx_t * procs_open(log_ctx_t *log_ctx, size_t max_procs_num, const char *prefix_name, const char *procs_href)
static void procs_post(procs_ctx_t *procs_ctx, const char *proc_name, const char *proc_settings, int *ref_proc_id)