live555直播实现-DM365 DVSDK+live555=RTSP server live

今天终于实现了live555+DM365 dvsdk encode例程的直播

主要参看前两篇博客--live555直播准备,在融合到DVSDK的时候主要做了如下几点改动

0.修改的writer线程,以前write线程作用是将视频数据保存为文件,这里修改成将视频数据赋给live555RTSP服务器

1.关于线程函数总定义参数部分改为全局变量,因为是要在C代码中掺杂上C++的类,为了C++中也可以使用这些参数,所以改为了全局变量

2.将线程中的envp参数通过构造函数传递给类函数

3.在H264FramedLiveSource类中添加void cleanup1()方法用于在类中运行关于encode部分的代码出错时清零线程用的,跟线程函数中的cleanup标号相同的作用

4.主要修改了doGetNextFrame()方法,将以前write线程函数中while循环中的代码放到此函数中,也就能够得到视频数据了,关于live555获取此数据的程序这样写

if( fFrameSize >  fMaxSize)
		{
	        	fNumTruncatedBytes = fFrameSize - fMaxSize;  
           	 	fFrameSize = fMaxSize;  
     		}  
   	 	else
		{  
        		fNumTruncatedBytes = 0;  
    		}  

		memmove(fTo, Buffer_getUserPtr(hOutBuf), fFrameSize);
		nextTask() = envir().taskScheduler().scheduleDelayedTask( 0,
			(TaskFunc*)FramedSource::afterGetting, this);


需要把DVSDK和live555融合在一起,编译出一个可执行文件

此处记录下出现的问题和解决方法:

问题一:C++代码(live555)和C代码(DVSDK)编译时怎样修改?

解决:参考当初DVSDK+JRTPLIB实现音视频同步时候的修改,还是遇到了下面当初没有遇到的问题

编译的时候没有问题,就是在连接的时候,出现undefined等,就是live555的静态连接库没有找到
理论上按照jrtplib时的方法,在Makefile中添加live555的四个动态链接库,但是问题并未解决,困扰一天

解决:最后终于找到原因,是因为Makefile中连接时候的命令如下所示:
arm_v5t_le-g++ -lpthread -lpng -ljpeg -lfreetype -lasound -lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment -o encode capture.o codecs.o main.o speech.o video.o writer.o ../ctrl.o ../uibuttons.o ../ui.o encode_config/linker.cmd
从连接命令可以看到,先写的调用库和输出,再写的.o输入,只需改为先输入再调用库再输出就好了如下所示:
arm_v5t_le-g++ capture.o codecs.o main.o speech.o video.o writer.o ../ctrl.o ../uibuttons.o ../ui.o encode_config/linker.cmd -lpthread -lpng -ljpeg -lfreetype -lasound -lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment -o encode
为什么C连接的时候和jrtplib的时候这种位置可以连接通过,live555就连接不到库呢?
待解决?

对应的Makefile修改如下:
0.显示编译连接命令
  VERBOSE = @   改为 VERBOSE =
1.添加live555的库
  #change by zjk
  LD_FLAGS += -lpthread -lpng -ljpeg -lfreetype -lasound -lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment
2.修改编译器
#change by zjk
COMPILE.c = $(VERBOSE) $(MVTOOL_PREFIX)g++ $(C_FLAGS) $(CPP_FLAGS) -c
3.修改连接器和连接输入输出文件交换位置
#change by zjk for live555
LINK.c = $(VERBOSE) $(MVTOOL_PREFIX)g++ 

#change by zjk
$(LINK.c) $^ $(LD_FLAGS) -o $@ 

问题二:刚开始把线程中申请bufer的函数放到类H264FramedLiveSource 的构造函数里面去了,当初想着,当初始化的时候顺便将这些buffer申请了,正好doGetNextFrame()函数中也需要这些参数,直接把变量的申请放到类里面了,这样正好不用在线程函数中定义变量并将变量传给类,参数太多也太麻烦
出现问题:第一次打开的时候是可以看到直播画面的,如果想再打开一个或者再打开一次就会程序停止并报错:  CMEMK Error: Failed to find a pool which fits 622080
CMEM Error: getPool: Failed to get a pool fitting a size 622080
Failed to allocate memory.
Error: Failed to allocate contiguous buffers
encode_live555: BufTab.c:430: BufTab_getBuf: Assertion `hBufTab' failed.
Aborted
解决:这是因为每次再打开一次或者打开多个客户端的时候会重新建一个H264FramedLiveSource 类的对象,而此时正好创建buffer的语句在构造函数中,相当于没打开一次就多创建一次buffer,又没有释放掉,导致内存泄露,进行代码更改:将在类中的变量定义变成全局变量,在构造函数创建buffer语句重新放到线程函数中,这样不管打开几次客户端,创建buffer代码只是创建了一次,就不会内存溢出了。
365内存不够可以使用其他方法,祥看CSDN博客:

但是不适合这个问题,因为那样治标不治本,而且标也没法治,将系统减小到64M,运行encode的时候提示capture创建失败

问题三:有2秒左右的延时
解决:将VLC播放器打开网络的地方,下面有个显示更多选项,选中后,将缓存更改为300ms,这样延时在1s左右

实现良好,心情大好
张纪宽
2014/08/05

2014/08/12:删掉了关于文件存储部分的代码,更改了关于内存申请部分的代码,删掉了关于264打包部分的代码(live中不需要进行打包),其余测试良好。
这个程序是live555直播,用的单播的形式,稳定性非常好。


测试:

运行./encode_live555 -v /home/test.264 -y 2     
     VLC :rtsp://172.18.168.62:8554/H264-live-unicast-zjk

如下图所示

PC端;

live555直播实现-DM365 DVSDK+live555=RTSP server live_第1张图片

手机端:

live555直播实现-DM365 DVSDK+live555=RTSP server live_第2张图片



缺点:
1.用的是单播的形式,这样的缺点是占用资源,当有两个客户端同时打开的时候会非常卡,甚至没有图像了,下次应该修改成广播的形式
2.只能在同一局域网使用,关于pc上运行可以用airJ无线点播,365运行不能的原因还未搞定


你可能感兴趣的:(server,RTSP,直播,Live555,DVSDK,DM365)