testOnDemandRTSPServer
首先启动使用环境,
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
然后创建rtsp服务器实例
RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
if (rtspServer == NULL) {
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
}
// Set up each of the possible streams that can be served by the
// RTSP server. Each such stream is implemented using a
// "ServerMediaSession" object, plus one or more
// "ServerMediaSubsession" objects for each audio/video substream.
然后启动每一种rtsp服务器支持的流媒体服务,每种流媒体都使用媒体服务会话(ServerMediaSession)对象,
而每个媒体服务会话都包含一个或多个子会话(视频或音频)。
如果流媒体类型是h264,在testOnDemandRTSPServer中,是从文件读取流媒体,其流程为
char const* streamName = "h264ESVideoTest";
char const* inputFileName = "out.h264";
ServerMediaSession* sms
= ServerMediaSession::createNew(*env, streamName, streamName,
descriptionString);
sms->addSubsession(H264VideoFileServerMediaSubsession
::createNew(*env, inputFileName, reuseFirstSource));
rtspServer->addServerMediaSession(sms);
即首先创建一个媒体服务会话,然后给该媒体服务会话添加视频子会话,而视频子会话是
h264文件媒体服务子会话,用H264VideoFileServerMediaSubsession表示。
然后将媒体服务会话添加到rtsp服务进程中。
而要想从内存读取流媒体,关键就是要修改视频子会话,将视频子会话从读取文件改为读取内存。
原本的H264VideoFileServerMediaSubsession继承关系是
class H264VideoFileServerMediaSubsession: public FileServerMediaSubsession
class FileServerMediaSubsession: public OnDemandServerMediaSubsession
从类的名字即可看出是从文件读取视频流还是从内存读取视频流基类都应该是OnDemandServerMediaSubsession。
FileServerMediaSubsession是一个纯虚类。
那么H264VideoFileServerMediaSubsession中决定从文件读取视频流的函数是哪个呢?
FramedSource* H264VideoFileServerMediaSubsession::createNewStreamSource(unsigned /*clientSessionId*/, unsigned& estBitrate) {
estBitrate = 500; // kbps, estimate
// Create the video source:
ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(envir(), fFileName);
if (fileSource == NULL) return NULL;
fFileSize = fileSource->fileSize();
// Create a framer for the Video Elementary Stream:
return H264VideoStreamFramer::createNew(envir(), fileSource);
}
由此可见关键函数是createNewStreamSource。
因而可以创建类H264VideoMemoryBufferServerMediaSubsession
继承关系为
class H264VideoMemoryBufferServerMediaSubsession: public MemoryBufferServerMediaSubsession
class MemoryBufferServerMediaSubsession: public OnDemandServerMediaSubsession
两个类与class H264VideoFileServerMediaSubsession: public FileServerMediaSubsession相比,仅将从文件读改为内存读
关键在于将函数
FramedSource* H264VideoMemoryBufferServerMediaSubsession::createNewStreamSource(unsigned /*clientSessionId*/, unsigned& estBitrate) {
estBitrate = 500; // kbps, estimate
改为读内存,而与类ByteStreamFileSource相对应,live555定义了类 ByteStreamMemoryBufferSource。
这两个类在参数传递方面有所不同,主要是文件的表示形式与内存的表示形式不同,给定文件名,那么文件的大小就是一定的,所以传文件
只需触按文件名即可,而传内存既要有内存地址又要有内存大小。
那么传递给类H264VideoMemoryBufferServerMediaSubsession,MemoryBufferServerMediaSubsession的参数要多一个内存大小。
这样做编译是成功了,但是运行效果不对,尝试只发送一帧视频,VLC提示错误。