multimedia/device/mpp/sample/hisi_rtsp_demo-master/rtsp_lib/test.c

309 lines
7.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*************************************************************************
> File Name: test.c
> Author: bxq
> Mail: 544177215@qq.com
> Created Time: Saturday, December 12, 2015 PM03:19:12 CST
************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include "comm.h"
#include "rtsp_demo.h"
#include <signal.h>
static int flag_run = 1;
static void sig_proc(int signo)
{
flag_run = 0;
}
static int get_next_video_frame (FILE *fp, uint8_t **buff, int *size)
{
uint8_t szbuf[1024];
int szlen = 0;
int ret;
if (!(*buff)) {
*buff = (uint8_t*)malloc(2*1024*1024);
if (!(*buff))
return -1;
}
*size = 0;
while ((ret = fread(szbuf + szlen, 1, sizeof(szbuf) - szlen, fp)) > 0) {
int i = 3;
szlen += ret;
while (i < szlen - 3 && !(szbuf[i] == 0 && szbuf[i+1] == 0 && (szbuf[i+2] == 1 || (szbuf[i+2] == 0 && szbuf[i+3] == 1)))) i++;
memcpy(*buff + *size, szbuf, i);
*size += i;
memmove(szbuf, szbuf + i, szlen - i);
szlen -= i;
if (szlen > 3) {
//printf("szlen %d\n", szlen);
fseek(fp, -szlen, SEEK_CUR);
break;
}
}
if (ret > 0)
return *size;
return 0;
}
static int get_next_audio_frame (FILE *fp, uint8_t **buff, int *size)
{
int ret;
#define AUDIO_FRAME_SIZE 320
if (!(*buff)) {
*buff = (uint8_t*)malloc(AUDIO_FRAME_SIZE);
if (!(*buff))
return -1;
}
ret = fread(*buff, 1, AUDIO_FRAME_SIZE, fp);
if (ret > 0) {
*size = ret;
return ret;
}
return 0;
}
#define MAX_SESSION_NUM 64
#define DEMO_CFG_FILE "demo.cfg"
struct demo_cfg
{
int session_count;
struct {
char path[64];
char video_file[64];
char audio_file[64];
} session_cfg[MAX_SESSION_NUM];
};
static int load_cfg(struct demo_cfg *cfg, const char *cfg_file)
{
//cfgline: path=%s video=%s audio=%s
FILE *fp = fopen(cfg_file, "r");
char line[256];
int count = 0;
if (!fp) {
fprintf(stderr, "open %s failed\n", cfg_file);
return -1;
}
memset(cfg, 0, sizeof(*cfg));
while (fgets(line, sizeof(line) - 1, fp)) {
const char *p;
memset(&cfg->session_cfg[count], 0, sizeof(cfg->session_cfg[count]));
if (line[0] == '#')
continue;
p = strstr(line, "path=");
if (!p)
continue;
if (sscanf(p, "path=%s", cfg->session_cfg[count].path) != 1)
continue;
if ((p = strstr(line, "video="))) {
if (sscanf(p, "video=%s", cfg->session_cfg[count].video_file) != 1) {
fprintf(stderr, "parse video file failed %s\n", p);
}
}
if ((p = strstr(line, "audio="))) {
if (sscanf(p, "audio=%s", cfg->session_cfg[count].audio_file) != 1) {
fprintf(stderr, "parse audio file failed %s\n", p);
}
}
if (strlen(cfg->session_cfg[count].video_file) || strlen(cfg->session_cfg[count].audio_file)) {
count ++;
} else {
fprintf(stderr, "parse line %s failed\n", line);
}
}
cfg->session_count = count;
/*
path=/live/chn0 video=BarbieGirl.h264 audio=BarbieGirl.alaw
path=/live/chn1 video=BarbieGirl.h264
path=/live/chn2 audio=BarbieGirl.alaw
*/
printf("cfg->session_count:%d\n",cfg->session_count);//3
fclose(fp);
return count;
}
int main(int argc, char *argv[])
{
const char *cfg_file = DEMO_CFG_FILE;
struct demo_cfg cfg;
FILE *fp[MAX_SESSION_NUM][2] = {{NULL}};
rtsp_demo_handle demo;
rtsp_session_handle session[MAX_SESSION_NUM] = {NULL};
int session_count = 0;
uint8_t *vbuf = NULL;
uint8_t *abuf = NULL;
uint64_t ts = 0;
int vsize = 0, asize = 0;
int ret, ch;
if (argc > 1)
cfg_file = argv[1];
ret = load_cfg(&cfg, cfg_file);
if (ret < 0) {
fprintf(stderr, "Usage: %s [CFG_FILE]\n", argv[0]);
getchar();
return 0;
}
//rtsp_demo usage:
//rtsp_new_demo
//rtsp_new_session <20>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>?
//rtsp_set_video
//rtsp_set_audio
//while(1){
// rtsp_tx_video
// rtsp_tx_audio
// rtsp_do_event
//}
//rtsp_del_session
//rtsp_del_demo
demo = rtsp_new_demo(8554);//rtsp sever socket
if (NULL == demo) {
printf("rtsp_new_demo failed\n");
return 0;
}
session_count = cfg.session_count;//3<><33>rtsp server session fp[ch][0] 64
for (ch = 0; ch < session_count; ch++) {
if (strlen(cfg.session_cfg[ch].video_file)) {
fp[ch][0] = fopen(cfg.session_cfg[ch].video_file, "rb");//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD>
if (!fp[ch][0]) {
fprintf(stderr, "open %s failed\n", cfg.session_cfg[ch].video_file);
}
}
//fp[ch][1] :<3A><>Ƶ<EFBFBD>ļ<EFBFBD><C4BC>ľ<EFBFBD><C4BE><EFBFBD>
if (strlen(cfg.session_cfg[ch].audio_file)) {
fp[ch][1] = fopen(cfg.session_cfg[ch].audio_file, "rb");
if (!fp[ch][1]) {
fprintf(stderr, "open %s failed\n", cfg.session_cfg[ch].audio_file);
}
}
if (fp[ch][0] == NULL && fp[ch][1] == NULL)
continue;
session[ch] = rtsp_new_session(demo, cfg.session_cfg[ch].path);//<2F><>Ӧrtsp session
if (NULL == session[ch]) {
printf("rtsp_new_session failed\n");
continue;
}
if (fp[ch][0]) {//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>Դ
rtsp_set_video(session[ch], RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
rtsp_sync_video_ts(session[ch], rtsp_get_reltime(), rtsp_get_ntptime());
}
if (fp[ch][1]) {//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>Դ
rtsp_set_audio(session[ch], RTSP_CODEC_ID_AUDIO_G711A, NULL, 0);
rtsp_sync_audio_ts(session[ch], rtsp_get_reltime(), rtsp_get_ntptime());
}
printf("==========> rtsp://127.0.0.1:8554%s for %s %s <===========\n", cfg.session_cfg[ch].path,
fp[ch][0] ? cfg.session_cfg[ch].video_file : "",
fp[ch][1] ? cfg.session_cfg[ch].audio_file : "");
}
ts = rtsp_get_reltime();
signal(SIGINT, sig_proc);
while (flag_run) {
uint8_t type = 0;
for (ch = 0; ch < session_count; ch++) {//3<><33>Դ
if (fp[ch][0]) {
read_video_again:
ret = get_next_video_frame(fp[ch][0], &vbuf, &vsize);
if (ret < 0) {
fprintf(stderr, "get_next_video_frame failed\n");
flag_run = 0;
break;
}
if (ret == 0) {
fseek(fp[ch][0], 0, SEEK_SET);
if (fp[ch][1])
fseek(fp[ch][1], 0, SEEK_SET);
goto read_video_again;
}
if (session[ch])//1Դsession <20><><EFBFBD><EFBFBD>
rtsp_tx_video(session[ch], vbuf, vsize, ts);//2rtsp_client_connect<63><74><EFBFBD><EFBFBD>
type = 0;
if (vbuf[0] == 0 && vbuf[1] == 0 && vbuf[2] == 1) {
type = vbuf[3] & 0x1f;
}
if (vbuf[0] == 0 && vbuf[1] == 0 && vbuf[2] == 0 && vbuf[3] == 1) {
type = vbuf[4] & 0x1f;
}
if (type != 5 && type != 1)
goto read_video_again;
}
if (fp[ch][1]) {
ret = get_next_audio_frame(fp[ch][1], &abuf, &asize);
if (ret < 0) {
fprintf(stderr, "get_next_audio_frame failed\n");
break;
}
if (ret == 0) {
fseek(fp[ch][1], 0, SEEK_SET);
if (fp[ch][0])
fseek(fp[ch][0], 0, SEEK_SET);
continue;
}
if (session[ch])
rtsp_tx_audio(session[ch], abuf, asize, ts);
}
}
do {
ret = rtsp_do_event(demo);//
if (ret > 0)
continue;
if (ret < 0)
break;
usleep(20000);
} while (rtsp_get_reltime() - ts < 1000000 / 25);
if (ret < 0)
break;
ts += 1000000 / 25;
printf(".");fflush(stdout);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>printf<74><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
}
free(vbuf);
free(abuf);
for (ch = 0; ch < session_count; ch++) {
if (fp[ch][0])
fclose(fp[ch][0]);
if (fp[ch][1])
fclose(fp[ch][1]);
if (session[ch])
rtsp_del_session(session[ch]);
}
rtsp_del_demo(demo);
printf("Exit.\n");
getchar();
return 0;
}