/****************************************************************************************
* 文 件 名 : rtsp_hisi.c
* 项目名称 : rtsp
* 模 块 名 : rtsp
* 功 能 : 流数据转发
* 操作系统 : arm-LINUX
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 编 码 : fanxl '2017-08-15
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Copyright 2017 ZFDX Corporation All Rights Reserved.
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
***************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#include <signal.h>
#include <sys/sem.h>
#include "zfcommon.h"
#include "zfcommon_def.h"
#include "zfdxlog.h"
#include "sample_comm.h"
#include "hi_comm_rc.h"
#include "rtsp_def.h"
#include "rtsp.h"
#include "rtsp_hisi.h"
#define RS 0
#define WS 1
#define SEM_NUM 2
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
static int ms_lSmid[MAX_STREAM_NUM];
static VENC_STREAM_S ms_stStream[MAX_STREAM_NUM]; /*流数据缓存指针*/
static int ms_bState[MAX_STREAM_NUM]; /*流数据状态 0 可写 1 可读*/
/* (live)流处理表驱动 */
typedef struct
{
unsigned lClientID; /* 连接的客户端编号 */
int bStatue; /*状态*/
int bReadCommitted; /*数据读提交 0:未完成读 1:完成读数据*/
void * pSource;
SendDataProc pfnMessageProc; /* 处理函数 */
}ST_LiveTableDriven;
/*表*/
static ST_LiveTableDriven astTableDriven[MAX_STREAM_NUM][MAX_CLIENT_NUM];
//static pthread_mutex_t mutexQueue; /* 互斥锁*/
//static pthread_cond_t condQueue; /* 条件变量*/
static int bQueueEmptyBefore = FALSE;
//static ST_PacketQueue sendQueue;
/* ========================================================================== */
int set_sem_value(int sem_id, int sum_num, int init_value)
{
union semun sem_union;
sem_union.val = init_value;
if (semctl(sem_id, sum_num, SETVAL, sem_union) == -1)
{
perror("Initialize semaphore set_sem_value.\n");
return -1;
}
return 0;
}
/* ========================================================================== */
int init_semaphore()
{
HI_S32 s32SemId;
HI_S32 s32Ret;
// 创建信号灯集(拥有2个信号灯 : 0号代表读资源 1号代表写资源)
s32SemId = semget(0, SEM_NUM, 0666 | IPC_CREAT);
if (s32SemId < 0)
{
printf("create semaphore failed with sem_id[%d] !!\n", s32SemId);
return -1;
}
// 设置信号灯集中信号灯的值
s32Ret = set_sem_value(s32SemId, RS, 0);//ID,NUM,VALUE
if (s32Ret != 0)
{ printf("sem_id=%d set_sem_value RS failed with %d !!\n", s32SemId, s32Ret);
return -1;
}
s32Ret = set_sem_value(s32SemId, WS, 0);
if (s32Ret != 0)
{ printf("sem_id=%d set_sem_value WS failed with %d !!\n", s32SemId, s32Ret);
return -1;
}
return s32SemId;
}
/* ========================================================================== */
int del_semaphore(int sem_id)
{
union semun sem_union;
if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)
{
perror("Delete semaphore.\n");
return -1;
}
/*
IPC_RMID:
Immediately remove the semaphore set, awakening all processes blocked in
semop(2) calls on the set (with an error return and errno set to EIDRM).
The effective user ID of the calling process must match the creator or owner
of the semaphore set, or the caller must be privileged.
The argument semnum is ignored.
int semctl(int semid,int semnum,int cmd, ...);
*/
#if 0
if (semctl(sem_id, WS, IPC_RMID, sem_union) == -1)
{
perror("Delete semaphore WS.\n");
return -1;
}
#endif
return 0;
}
/* ========================================================================== */
#if 0
struct timespec
{
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif
int sem_p(int sem_id, int sem_num)
{
struct sembuf sem_b;
sem_b.sem_num = sem_num;
sem_b.sem_op = -1;
//sem_b.sem_flg = SEM_UNDO;
sem_b.sem_flg = 0; //阻塞方式
#if 1
if (semop(sem_id, &sem_b, 1) == -1)
{
perror("P operation.\n");
return -1;
}
#endif
// HI_S32 s32Ret;
// struct timespec timeout;
// timeout.tv_sec = 0;
// timeout.tv_nsec = 300000000; //300ms
//
// if (semtimedop(sem_id, &sem_b, 1, &timeout) == -1)
// {
// if (errno == EAGAIN)
// {
// perror("semtimedop timeout.\n");
// // 设置信号灯集中信号灯的值
// //s32Ret = set_sem_value(s32SemId, RS, 0);//ID,NUM,VALUE
// if ((s32Ret = set_sem_value(sem_id, RS, 0)) != 0)
// { printf("sem_id=%d set_sem_value RS failed with %d !!\n", sem_id, s32Ret);
// return -1;
// }
//
// //s32Ret = set_sem_value(s32SemId, WS, 1);
// if ((s32Ret = set_sem_value(sem_id, WS, 1)) != 0)
// { printf("sem_id=%d set_sem_value WS failed with %d !!\n", sem_id, s32Ret);
// return -1;
// }
// }
// else
// {
// perror("P operation.\n");
// return -1;
// }
// }
return 0;
}
/* ========================================================================== */
int sem_v(int sem_id, int sem_num)
{
struct sembuf sem_b;
sem_b.sem_num = sem_num;
sem_b.sem_op = 1;
//sem_b.sem_flg = SEM_UNDO;
sem_b.sem_flg = 0; //阻塞方式
if (semop(sem_id, &sem_b, 1) == -1)
{
perror("V operation.\n");
return -1;
}
return 0;
}
HI_S32 rtsp_hisi_init()
{
HI_S32 s32Ret;
int i,j;
s32Ret = HI_MPI_SYS_Init();
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_SYS_Init failed!\n");
return HI_FAILURE;
}
/*流处理表初始化*/
for (i = 0; i < MAX_STREAM_NUM; i++)
{
for (j = 0; j < MAX_CLIENT_NUM; j++)
{
astTableDriven[i][j].bStatue = 0;
astTableDriven[i][j].bReadCommitted = 0;
astTableDriven[i][j].lClientID = 0;
astTableDriven[i][j].pSource = NULL;
astTableDriven[i][j].pfnMessageProc = NULL;
}
ms_bState[i] = 0;
memset(&ms_stStream[i], 0, sizeof(VENC_STREAM_S));
ms_lSmid[i] = init_semaphore();
if (ms_lSmid[i] < 0)
{
printf("creat sem is err!\n");
}
}
// /* 初始化发送队列 */
// s32Ret = bsponc_queueInit(&sendQueue, 20);
// if (s32Ret < 0)
// {
// printf("初始化发送队列失败");
// }
// /* 初始化队列互斥器与变量变量 */
// s32Ret = pthread_mutex_init(&mutexQueue, NULL);
// if (s32Ret < 0)
// {
// printf("队列互斥器创建失败");
// }
return s32Ret;
}
void rtsp_hisi_relase()
{
int i;
HI_S32 s32Ret;
for (i = 0; i < MAX_STREAM_NUM; i++)
{
if (ms_stStream[i].u32PackCount != 0)
{
s32Ret = rtsp_relase_stream(i, &(ms_stStream[i]));
if (HI_SUCCESS != s32Ret)
{
free(ms_stStream[i].pstPack);
ms_stStream[i].pstPack = NULL;
memset(&ms_stStream[i], 0, sizeof(VENC_STREAM_S));
printf("[rtsp] rtsp_relase_stream failed with %#x!\n", s32Ret);
}
}
if ((s32Ret = del_semaphore(ms_lSmid[i])) != 0)
{
printf("semaphore delete failed with %d!!\n", s32Ret);
}
}
}
/*注册流处理*/
void rtsp_source_register(int lChn, unsigned lClientId, void * pSource, SendDataProc pFuction)
{
int i;
for
评论23