Chinaunix首页 | 论坛 | 博客
  • 博客访问: 287758
  • 博文数量: 182
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1292
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-06 19:02
个人简介

让一切的准备都完美演出,让所有的努力都美好落幕

文章分类

全部博文(182)

文章存档

2016年(60)

2015年(122)

我的朋友

分类: LINUX

2016-05-01 14:45:27

live555提供的示例程序mediaServer是一个基于文件播放的rtsp server。
有朋友问如果改造成一个实时的视频流。

从代码可以看出,当收到rtsp 的命令时,会执行DynamicRTSPServer::lookupServerMediaSession()。
session不存在时,会createNewSMS生成一个新的。
在createNewSMS中会调用 sms->addSubsession(AMRAudioFileServerMediaSubsession::createNew(env, fileName, reuseSource));
(假设我们的视频源是mpeg4-es)
再跟踪代码,发现createNew是给变量fFileName赋值,把文件名保存起来。

再下去,就是rtsp的播放准备播放命令了,很明显,需要一个视频源,这时程序会调用MPEG4VideoFileServerMediaSubsession::createNewStreamSource
在这里ByteStreamFileSource::createNew(envir(), fFileName);

接下去就简单了,每次doGetNextFrame,会fread,当然,如果异步的话,会交给TaskScheduler去做:
void ByteStreamFileSource::doGetNextFrame() {
  if (feof(fFid) || ferror(fFid)) {
    handleClosure(this);
    return;
  }

#ifdef READ_FROM_FILES_SYNCHRONOUSLY
  doReadFromFile();
#else
  if (!fHaveStartedReading) {
    // Await readable data from the file:
    envir().taskScheduler().turnOnBackgroundReadHandling(fileno(fFid),
           (TaskScheduler::BackgroundHandlerProc*)&fileReadableHandler, this);
    fHaveStartedReading = True;
  }
#endif
}

//**************
以上是读文件的方式。如果换成实时视频流,有两种方案:一是参考spook,读v4l2驱动得视频数据,读数据后就发送。另一种方法,是从内存中读到视频数据(来源可能是文件,也可能从远程通过socket得到,也可以从驱动读出,得到数据放到内存中)。如果对live Media Server做最小改动的话,就是参考ByteStreamFileSource,再写一个Source。
当然,想偷懒的话也简单:doReadFromFile时,从fread读文件,改成读内存缓冲就行了。注意一定要加锁。

以上只是理论,等放长假找个时间写出来试试。
阅读(2442) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~