1. /*
  2. * H264DeviceSource.hh
  3. *
  4. * Created on: 2014年7月19日
  5. * Author: zjzhang
  6. */
  7.  
  8. #ifndef H264DEVICESOURCE_HH_
  9. #define H264DEVICESOURCE_HH_
  10. #include<DeviceSource.hh>
  11.  
  12. class H264DeviceSource: public DeviceSource {
  13. public:
  14. static DeviceSource* createNew(UsageEnvironment& env,u_int8_t index=1,u_int width=352,u_int height=288,u_int fps=15,u_int kbps=100);
  15. protected:
  16. H264DeviceSource(UsageEnvironment& env,u_int8_t index,u_int width,u_int height,u_int fps,u_int kbps);
  17. virtual ~H264DeviceSource();
  18. private:
  19. virtual void doGetNextFrame();
  20. virtual unsigned maxFrameSize() const;
  21. int fHeight;
  22. int fWidth;
  23. void *fH264Encoder;
  24. u_int8_t * fBuffer;
  25. u_int fBufferSize;
  26. };
  27.  
  28. #endif /* H264DEVICESOURCE_HH_ */
  1. /*
  2. * H264DeviceSource.cpp
  3. *
  4. * Created on: 2014年7月19日
  5. * Author: zjzhang
  6. */
  7.  
  8. #include "H264DeviceSource.hh"
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. #include "H264Stream.h"
  13. #ifdef __cplusplus
  14. }
  15. #endif
  16. DeviceSource*
  17. H264DeviceSource::createNew(UsageEnvironment& env, u_int8_t index, u_int width,
  18. u_int height, u_int fps, u_int kbps) {
  19. return new H264DeviceSource(env, index, width, height, fps, kbps);
  20. }
  21.  
  22. H264DeviceSource::H264DeviceSource(UsageEnvironment& env, u_int8_t index,
  23. u_int width, u_int height, u_int fps, u_int kbps) :
  24. DeviceSource(env, DeviceParameters()) {
  25. openCamera(1);
  26. getFrame(1);
  27. fHeight = getHeight(1);
  28. fWidth = getWidth(1);
  29. openH264Encoder(fWidth, fHeight, fps, kbps, &fH264Encoder);
  30. fBufferSize = fHeight * fWidth * 3 / 2;
  31. fBuffer = new uint8_t[fBufferSize];
  32.  
  33. }
  34.  
  35. H264DeviceSource::~H264DeviceSource() {
  36. // TODO Auto-generated destructor stub
  37.  
  38. delete[] fBuffer;
  39. closeH264Encoder(fH264Encoder);
  40. closeCamera(1);
  41. }
  42. unsigned H264DeviceSource::maxFrameSize() const {
  43. // By default, this source has no maximum frame size.
  44. return 4096;
  45. }
  46. void H264DeviceSource::doGetNextFrame() {
  47. if (!isCurrentlyAwaitingData())
  48. return; // we're not ready for the data yet
  49.  
  50. unsigned char * rgbBuffer = getFrame(1);
  51. ConvertRGB2YUV(fWidth, fHeight, rgbBuffer, fBuffer);
  52. int newFrameSize = encodeFrame(fH264Encoder, fBuffer, fBufferSize);
  53.  
  54. // Deliver the data here:
  55. if (newFrameSize < 0) {
  56. handleClosure();
  57. return;
  58. }
  59. if (newFrameSize > fMaxSize) {
  60. fFrameSize = fMaxSize;
  61. fNumTruncatedBytes = newFrameSize - fMaxSize;
  62. } else {
  63. fFrameSize = newFrameSize;
  64. }
  65. if (fFrameSize > 0) {
  66. int result = 0;
  67. int p = 0;
  68. do {
  69. unsigned long len = 0;
  70. result = getNextPacket(fH264Encoder, fBuffer + p, &len);
  71. p += len;
  72. } while (result > 0);
  73. }
  74.  
  75. gettimeofday(&fPresentationTime, NULL); // If you have a more accurate time - e.g., from an encoder - then use that instead.
  76. // If the device is *not* a 'live source' (e.g., it comes instead from a file or buffer), then set "fDurationInMicroseconds" here.
  77. memmove(fTo, fBuffer, fFrameSize);
  78.  
  79. FramedSource::afterGetting(this);
  80. }

  1. #ifndef _DEVIC_SERVER_MEDIA_SUBSESSION_HH
  2. #define _DEVICE_SERVER_MEDIA_SUBSESSION_HH
  3.  
  4. #ifndef _ON_DEMAND_SERVER_MEDIA_SUBSESSION_HH
  5. #include "OnDemandServerMediaSubsession.hh"
  6. #endif
  7. class DeviceSource;
  8. class DeviceServerMediaSubsession: public OnDemandServerMediaSubsession {
  9. public:
  10. static DeviceServerMediaSubsession*
  11. createNew(UsageEnvironment& env,
  12. Boolean reuseFirstSource);
  13.  
  14. // Used to implement "getAuxSDPLine()":
  15. void checkForAuxSDPLine1();
  16. void afterPlayingDummy1();
  17. protected: // we're a virtual base class
  18. DeviceServerMediaSubsession(UsageEnvironment& env,
  19. Boolean reuseFirstSource);
  20. virtual ~DeviceServerMediaSubsession();
  21.  
  22. void setDoneFlag() { fDoneFlag = ~0; }
  23.  
  24. protected: // redefined virtual functions
  25. virtual char const* getAuxSDPLine(RTPSink* rtpSink,
  26. FramedSource* inputSource);
  27. virtual FramedSource* createNewStreamSource(unsigned clientSessionId,
  28. unsigned& estBitrate);
  29. virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock,
  30. unsigned char rtpPayloadTypeIfDynamic,
  31. FramedSource* inputSource);
  32.  
  33. private:
  34. char* fAuxSDPLine;
  35. char fDoneFlag; // used when setting up "fAuxSDPLine"
  36. RTPSink* fDummyRTPSink; // ditto
  37. };
  38.  
  39. #endif
  1. #include "DeviceServerMediaSubsession.hh"
  2. #include "H264VideoRTPSink.hh"
  3. #include "DeviceSource.hh"
  4. #include "H264VideoStreamFramer.hh"
  5. #include "H264DeviceSource.hh"
  6.  
  7. DeviceServerMediaSubsession*
  8. DeviceServerMediaSubsession::createNew(UsageEnvironment& env,
  9. Boolean reuseFirstSource) {
  10. return new DeviceServerMediaSubsession(env, reuseFirstSource);
  11. }
  12. DeviceServerMediaSubsession::DeviceServerMediaSubsession(UsageEnvironment& env,
  13. Boolean reuseFirstSource) :
  14. OnDemandServerMediaSubsession(env, reuseFirstSource) {
  15. }
  16.  
  17. DeviceServerMediaSubsession::~DeviceServerMediaSubsession() {
  18. }
  19.  
  20. FramedSource* DeviceServerMediaSubsession::createNewStreamSource(
  21. unsigned /*clientSessionId*/, unsigned& estBitrate) {
  22. DeviceSource* source = H264DeviceSource::createNew(envir());
  23. return H264VideoStreamFramer::createNew(envir(), source);
  24. }
  25.  
  26. RTPSink* DeviceServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock,
  27. unsigned char rtpPayloadTypeIfDynamic, FramedSource* /*inputSource*/) {
  28. return H264VideoRTPSink::createNew(envir(), rtpGroupsock,
  29. rtpPayloadTypeIfDynamic);
  30. }
  31.  
  32. static void afterPlayingDummy(void* clientData) {
  33. DeviceServerMediaSubsession* subsess =
  34. (DeviceServerMediaSubsession*) clientData;
  35. subsess->afterPlayingDummy1();
  36. }
  37.  
  38. void DeviceServerMediaSubsession::afterPlayingDummy1() {
  39. // Unschedule any pending 'checking' task:
  40. envir().taskScheduler().unscheduleDelayedTask(nextTask());
  41. // Signal the event loop that we're done:
  42. setDoneFlag();
  43. }
  44.  
  45. static void checkForAuxSDPLine(void* clientData) {
  46. DeviceServerMediaSubsession* subsess =
  47. (DeviceServerMediaSubsession*) clientData;
  48. subsess->checkForAuxSDPLine1();
  49. }
  50.  
  51. void DeviceServerMediaSubsession::checkForAuxSDPLine1() {
  52. char const* dasl;
  53.  
  54. if (fAuxSDPLine != NULL) {
  55. // Signal the event loop that we're done:
  56. setDoneFlag();
  57. } else if (fDummyRTPSink != NULL
  58. && (dasl = fDummyRTPSink->auxSDPLine()) != NULL) {
  59. fAuxSDPLine = strDup(dasl);
  60. fDummyRTPSink = NULL;
  61.  
  62. // Signal the event loop that we're done:
  63. setDoneFlag();
  64. } else if (!fDoneFlag) {
  65. // try again after a brief delay:
  66. int uSecsToDelay = 100000; // 100 ms
  67. nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecsToDelay,
  68. (TaskFunc*) checkForAuxSDPLine, this);
  69. }
  70. }
  71. char const* DeviceServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,
  72. FramedSource* inputSource) {
  73.  
  74. if (fAuxSDPLine != NULL)
  75. return fAuxSDPLine; // it's already been set up (for a previous client)
  76.  
  77. if (fDummyRTPSink == NULL) { // we're not already setting it up for another, concurrent stream
  78. // Note: For H264 video files, the 'config' information ("profile-level-id" and "sprop-parameter-sets") isn't known
  79. // until we start reading the file. This means that "rtpSink"s "auxSDPLine()" will be NULL initially,
  80. // and we need to start reading data from our file until this changes.
  81. fDummyRTPSink = rtpSink;
  82.  
  83. // Start reading the file:
  84. fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
  85.  
  86. // Check whether the sink's 'auxSDPLine()' is ready:
  87. checkForAuxSDPLine(this);
  88. }
  89.  
  90. envir().taskScheduler().doEventLoop(&fDoneFlag);
  91.  
  92. return fAuxSDPLine;
  93. }

Live555 直播源 以及MediaSubsession的更多相关文章

  1. 基于vitamio的网络电视直播源码

    这个项目是基于vitamio的网络电视直播源码,也是一个使用了vitamio的基于安卓的网络直播项目源码,可能现在网上已经有很多类似这样的视频播放应用了,不过这个还是相对来说比较完整的,希望这个案例能 ...

  2. 直播源格式转换教程——rtmp/rtsp/http/m3u8!!

    之前寻找直播源,发现好多rtmp开头的,或者是rtsp开头的,但是ATV里面的个人链接是支持m3u8格式的.怎么办?小编发现了几个规律,网友可作参考.现在流行的直播地址差不多就这几种需要说明的是并不是 ...

  3. [转载]Fiddler为所欲为第四篇 直播源抓取与接口分析 [四]

    今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析.(怎么样,是不是感觉和OD很像~~~)今天的教程我们以[麻花影视]为例,当然,其他APP的逻辑也是一样,通用的哦~ 首先需要做好准备 ...

  4. 【视频开发】【Live555】摄像头采集,264编码,live555直播

    加入 摄像头采集和264编码,再使用live555直播 1.摄像头采集和264编码 将x264改成编码一帧的接口,码流不写入文件而是直接写入内存中(int  Encode_frame 函数中). /* ...

  5. PotPlayer直播源分享

    添加直播源方法: 央视CCTV1综合HD-1,rtsp://113.136.42.45:554/PLTV/88888888/224/3221226087/10000100000000060000000 ...

  6. 带货直播源码开发采用MySQL有什么优越性

    MySQL是世界上最流行的开源关系数据库,带货直播源码使用MySQL,可实现分钟级别的数据库部署和弹性扩展,不仅经济实惠,而且稳定可靠,易于运维.云数据库 MySQL 提供备份恢复.监控.容灾.快速扩 ...

  7. 视频直播源码开发中的流媒体协议:rtmp协议

    一.概念与摘要 视频直播源码的RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和互动内容).RTMP提供了一套全双工的可靠的多路复用消息服务,类似 ...

  8. 如何抓取直播源及视频URL地址-疯狂URL(教程)

    直播源介绍 首先,我们来快速了解一下什么是直播源,所谓的直播源,其实就说推流地址,推流地址可能你也不知道是什么,那么我再简单说一下,推流地址就是,当某个直播开播的时候,需要将自己的直播状态实时的展示给 ...

  9. android文件管理器源码、斗鱼直播源码、企业级erp源码等

    Android精选源码 文件清理管理器 自定义水平带数字的进度条以及自定义圆形带数字的进度条 利用sectionedRecyclerViewAdapter实现分组列表的recyclerView源码 流 ...

随机推荐

  1. Querying CRM data with LINQ

    http://www.powerxrm.com/querying-crm-data-with-linq/ 如果不喜欢看SDK中的示例,这篇里面讲的非常详细,值得一看.

  2. BI Publisher(rtf)模板开发语法大全

    Rtf模板开发例如背景,纹理分栏等等功能都能用word工具实现不再具体总结大家可以参考word教程.....   一.组 定义一个组的目的是告诉XMLPublisher对重复的数据行进行循环显示,也就 ...

  3. 详解EBS接口开发之采购订单导入

    采购订单常用标准表简介 1.1   常用标准表 如下表中列出了与采购订单导入相关的表和说明: 表名 说明 其他信息 po.po_headers_all 采购订单头 采购订单号,采购类型,供应商,地点, ...

  4. UIKit中ImageView动画堆叠显示的微调整

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 网上看到一个PackingList项目(如果需要源代码可以Q我 ...

  5. XML之DOM解析模型

    <?xml version= "1.0" encoding = "UTF-8"> <articles> <article cate ...

  6. Dynamics CRM2015 Update1 新功能之表单增强功能

    CRM2015 Update 1发布后,系统的界面的变化很大,仔细观察后会发现表单窗体也有些不同了,在CRM2015 Update1的官方介绍中对此变化的解释是起用了新的窗体呈现引擎,让界面更好看加载 ...

  7. 验证码程序Demo

    小伙伴都有这样的经历,册各种网站,总是输不对验证码,双十一那天狂买的小伙伴是不是对输入验证码有着不一样的感触呢,以前觉得验证码真是个麻烦鬼,一个不小心,一个眼拙,哎呦,没有输入正确,又是一阵子大眼瞪小 ...

  8. memcached实战系列(三)memcached命令使用

    memcached命令的使用,在这里我们最好了解一下命令的含义,对命令有一个大致的了解,在了解的基础上进行使用.这里的命名是常用的crud命令的演示. 1.1.1. memcached命令的格式 标准 ...

  9. 使用github搭建网站

    http://blog.csdn.net/pipisorry/article/details/51707366 使用github建站 github设计了Pages功能,允许用户自定义项目首页,用来替代 ...

  10. 3.Lucene3.x API分析,Director 索引操作目录,Document,分词器

     1  Lucene卡发包结构分析 包名 功能 org.apache.lucene.analysis Analysis提供自带的各种Analyzer org.apache.lucene.colla ...