Live555 直播源 以及MediaSubsession
- /*
- * H264DeviceSource.hh
- *
- * Created on: 2014年7月19日
- * Author: zjzhang
- */
- #ifndef H264DEVICESOURCE_HH_
- #define H264DEVICESOURCE_HH_
- #include<DeviceSource.hh>
- class H264DeviceSource: public DeviceSource {
- public:
- 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);
- protected:
- H264DeviceSource(UsageEnvironment& env,u_int8_t index,u_int width,u_int height,u_int fps,u_int kbps);
- virtual ~H264DeviceSource();
- private:
- virtual void doGetNextFrame();
- virtual unsigned maxFrameSize() const;
- int fHeight;
- int fWidth;
- void *fH264Encoder;
- u_int8_t * fBuffer;
- u_int fBufferSize;
- };
- #endif /* H264DEVICESOURCE_HH_ */
- /*
- * H264DeviceSource.cpp
- *
- * Created on: 2014年7月19日
- * Author: zjzhang
- */
- #include "H264DeviceSource.hh"
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "H264Stream.h"
- #ifdef __cplusplus
- }
- #endif
- DeviceSource*
- H264DeviceSource::createNew(UsageEnvironment& env, u_int8_t index, u_int width,
- u_int height, u_int fps, u_int kbps) {
- return new H264DeviceSource(env, index, width, height, fps, kbps);
- }
- H264DeviceSource::H264DeviceSource(UsageEnvironment& env, u_int8_t index,
- u_int width, u_int height, u_int fps, u_int kbps) :
- DeviceSource(env, DeviceParameters()) {
- openCamera(1);
- getFrame(1);
- fHeight = getHeight(1);
- fWidth = getWidth(1);
- openH264Encoder(fWidth, fHeight, fps, kbps, &fH264Encoder);
- fBufferSize = fHeight * fWidth * 3 / 2;
- fBuffer = new uint8_t[fBufferSize];
- }
- H264DeviceSource::~H264DeviceSource() {
- // TODO Auto-generated destructor stub
- delete[] fBuffer;
- closeH264Encoder(fH264Encoder);
- closeCamera(1);
- }
- unsigned H264DeviceSource::maxFrameSize() const {
- // By default, this source has no maximum frame size.
- return 4096;
- }
- void H264DeviceSource::doGetNextFrame() {
- if (!isCurrentlyAwaitingData())
- return; // we're not ready for the data yet
- unsigned char * rgbBuffer = getFrame(1);
- ConvertRGB2YUV(fWidth, fHeight, rgbBuffer, fBuffer);
- int newFrameSize = encodeFrame(fH264Encoder, fBuffer, fBufferSize);
- // Deliver the data here:
- if (newFrameSize < 0) {
- handleClosure();
- return;
- }
- if (newFrameSize > fMaxSize) {
- fFrameSize = fMaxSize;
- fNumTruncatedBytes = newFrameSize - fMaxSize;
- } else {
- fFrameSize = newFrameSize;
- }
- if (fFrameSize > 0) {
- int result = 0;
- int p = 0;
- do {
- unsigned long len = 0;
- result = getNextPacket(fH264Encoder, fBuffer + p, &len);
- p += len;
- } while (result > 0);
- }
- gettimeofday(&fPresentationTime, NULL); // If you have a more accurate time - e.g., from an encoder - then use that instead.
- // If the device is *not* a 'live source' (e.g., it comes instead from a file or buffer), then set "fDurationInMicroseconds" here.
- memmove(fTo, fBuffer, fFrameSize);
- FramedSource::afterGetting(this);
- }
- #ifndef _DEVIC_SERVER_MEDIA_SUBSESSION_HH
- #define _DEVICE_SERVER_MEDIA_SUBSESSION_HH
- #ifndef _ON_DEMAND_SERVER_MEDIA_SUBSESSION_HH
- #include "OnDemandServerMediaSubsession.hh"
- #endif
- class DeviceSource;
- class DeviceServerMediaSubsession: public OnDemandServerMediaSubsession {
- public:
- static DeviceServerMediaSubsession*
- createNew(UsageEnvironment& env,
- Boolean reuseFirstSource);
- // Used to implement "getAuxSDPLine()":
- void checkForAuxSDPLine1();
- void afterPlayingDummy1();
- protected: // we're a virtual base class
- DeviceServerMediaSubsession(UsageEnvironment& env,
- Boolean reuseFirstSource);
- virtual ~DeviceServerMediaSubsession();
- void setDoneFlag() { fDoneFlag = ~0; }
- protected: // redefined virtual functions
- virtual char const* getAuxSDPLine(RTPSink* rtpSink,
- FramedSource* inputSource);
- virtual FramedSource* createNewStreamSource(unsigned clientSessionId,
- unsigned& estBitrate);
- virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock,
- unsigned char rtpPayloadTypeIfDynamic,
- FramedSource* inputSource);
- private:
- char* fAuxSDPLine;
- char fDoneFlag; // used when setting up "fAuxSDPLine"
- RTPSink* fDummyRTPSink; // ditto
- };
- #endif
- #include "DeviceServerMediaSubsession.hh"
- #include "H264VideoRTPSink.hh"
- #include "DeviceSource.hh"
- #include "H264VideoStreamFramer.hh"
- #include "H264DeviceSource.hh"
- DeviceServerMediaSubsession*
- DeviceServerMediaSubsession::createNew(UsageEnvironment& env,
- Boolean reuseFirstSource) {
- return new DeviceServerMediaSubsession(env, reuseFirstSource);
- }
- DeviceServerMediaSubsession::DeviceServerMediaSubsession(UsageEnvironment& env,
- Boolean reuseFirstSource) :
- OnDemandServerMediaSubsession(env, reuseFirstSource) {
- }
- DeviceServerMediaSubsession::~DeviceServerMediaSubsession() {
- }
- FramedSource* DeviceServerMediaSubsession::createNewStreamSource(
- unsigned /*clientSessionId*/, unsigned& estBitrate) {
- DeviceSource* source = H264DeviceSource::createNew(envir());
- return H264VideoStreamFramer::createNew(envir(), source);
- }
- RTPSink* DeviceServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock,
- unsigned char rtpPayloadTypeIfDynamic, FramedSource* /*inputSource*/) {
- return H264VideoRTPSink::createNew(envir(), rtpGroupsock,
- rtpPayloadTypeIfDynamic);
- }
- static void afterPlayingDummy(void* clientData) {
- DeviceServerMediaSubsession* subsess =
- (DeviceServerMediaSubsession*) clientData;
- subsess->afterPlayingDummy1();
- }
- void DeviceServerMediaSubsession::afterPlayingDummy1() {
- // Unschedule any pending 'checking' task:
- envir().taskScheduler().unscheduleDelayedTask(nextTask());
- // Signal the event loop that we're done:
- setDoneFlag();
- }
- static void checkForAuxSDPLine(void* clientData) {
- DeviceServerMediaSubsession* subsess =
- (DeviceServerMediaSubsession*) clientData;
- subsess->checkForAuxSDPLine1();
- }
- void DeviceServerMediaSubsession::checkForAuxSDPLine1() {
- char const* dasl;
- if (fAuxSDPLine != NULL) {
- // Signal the event loop that we're done:
- setDoneFlag();
- } else if (fDummyRTPSink != NULL
- && (dasl = fDummyRTPSink->auxSDPLine()) != NULL) {
- fAuxSDPLine = strDup(dasl);
- fDummyRTPSink = NULL;
- // Signal the event loop that we're done:
- setDoneFlag();
- } else if (!fDoneFlag) {
- // try again after a brief delay:
- int uSecsToDelay = 100000; // 100 ms
- nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecsToDelay,
- (TaskFunc*) checkForAuxSDPLine, this);
- }
- }
- char const* DeviceServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,
- FramedSource* inputSource) {
- if (fAuxSDPLine != NULL)
- return fAuxSDPLine; // it's already been set up (for a previous client)
- if (fDummyRTPSink == NULL) { // we're not already setting it up for another, concurrent stream
- // Note: For H264 video files, the 'config' information ("profile-level-id" and "sprop-parameter-sets") isn't known
- // until we start reading the file. This means that "rtpSink"s "auxSDPLine()" will be NULL initially,
- // and we need to start reading data from our file until this changes.
- fDummyRTPSink = rtpSink;
- // Start reading the file:
- fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
- // Check whether the sink's 'auxSDPLine()' is ready:
- checkForAuxSDPLine(this);
- }
- envir().taskScheduler().doEventLoop(&fDoneFlag);
- return fAuxSDPLine;
- }
Live555 直播源 以及MediaSubsession的更多相关文章
- 基于vitamio的网络电视直播源码
这个项目是基于vitamio的网络电视直播源码,也是一个使用了vitamio的基于安卓的网络直播项目源码,可能现在网上已经有很多类似这样的视频播放应用了,不过这个还是相对来说比较完整的,希望这个案例能 ...
- 直播源格式转换教程——rtmp/rtsp/http/m3u8!!
之前寻找直播源,发现好多rtmp开头的,或者是rtsp开头的,但是ATV里面的个人链接是支持m3u8格式的.怎么办?小编发现了几个规律,网友可作参考.现在流行的直播地址差不多就这几种需要说明的是并不是 ...
- [转载]Fiddler为所欲为第四篇 直播源抓取与接口分析 [四]
今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析.(怎么样,是不是感觉和OD很像~~~)今天的教程我们以[麻花影视]为例,当然,其他APP的逻辑也是一样,通用的哦~ 首先需要做好准备 ...
- 【视频开发】【Live555】摄像头采集,264编码,live555直播
加入 摄像头采集和264编码,再使用live555直播 1.摄像头采集和264编码 将x264改成编码一帧的接口,码流不写入文件而是直接写入内存中(int Encode_frame 函数中). /* ...
- PotPlayer直播源分享
添加直播源方法: 央视CCTV1综合HD-1,rtsp://113.136.42.45:554/PLTV/88888888/224/3221226087/10000100000000060000000 ...
- 带货直播源码开发采用MySQL有什么优越性
MySQL是世界上最流行的开源关系数据库,带货直播源码使用MySQL,可实现分钟级别的数据库部署和弹性扩展,不仅经济实惠,而且稳定可靠,易于运维.云数据库 MySQL 提供备份恢复.监控.容灾.快速扩 ...
- 视频直播源码开发中的流媒体协议:rtmp协议
一.概念与摘要 视频直播源码的RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和互动内容).RTMP提供了一套全双工的可靠的多路复用消息服务,类似 ...
- 如何抓取直播源及视频URL地址-疯狂URL(教程)
直播源介绍 首先,我们来快速了解一下什么是直播源,所谓的直播源,其实就说推流地址,推流地址可能你也不知道是什么,那么我再简单说一下,推流地址就是,当某个直播开播的时候,需要将自己的直播状态实时的展示给 ...
- android文件管理器源码、斗鱼直播源码、企业级erp源码等
Android精选源码 文件清理管理器 自定义水平带数字的进度条以及自定义圆形带数字的进度条 利用sectionedRecyclerViewAdapter实现分组列表的recyclerView源码 流 ...
随机推荐
- Querying CRM data with LINQ
http://www.powerxrm.com/querying-crm-data-with-linq/ 如果不喜欢看SDK中的示例,这篇里面讲的非常详细,值得一看.
- BI Publisher(rtf)模板开发语法大全
Rtf模板开发例如背景,纹理分栏等等功能都能用word工具实现不再具体总结大家可以参考word教程..... 一.组 定义一个组的目的是告诉XMLPublisher对重复的数据行进行循环显示,也就 ...
- 详解EBS接口开发之采购订单导入
采购订单常用标准表简介 1.1 常用标准表 如下表中列出了与采购订单导入相关的表和说明: 表名 说明 其他信息 po.po_headers_all 采购订单头 采购订单号,采购类型,供应商,地点, ...
- UIKit中ImageView动画堆叠显示的微调整
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 网上看到一个PackingList项目(如果需要源代码可以Q我 ...
- XML之DOM解析模型
<?xml version= "1.0" encoding = "UTF-8"> <articles> <article cate ...
- Dynamics CRM2015 Update1 新功能之表单增强功能
CRM2015 Update 1发布后,系统的界面的变化很大,仔细观察后会发现表单窗体也有些不同了,在CRM2015 Update1的官方介绍中对此变化的解释是起用了新的窗体呈现引擎,让界面更好看加载 ...
- 验证码程序Demo
小伙伴都有这样的经历,册各种网站,总是输不对验证码,双十一那天狂买的小伙伴是不是对输入验证码有着不一样的感触呢,以前觉得验证码真是个麻烦鬼,一个不小心,一个眼拙,哎呦,没有输入正确,又是一阵子大眼瞪小 ...
- memcached实战系列(三)memcached命令使用
memcached命令的使用,在这里我们最好了解一下命令的含义,对命令有一个大致的了解,在了解的基础上进行使用.这里的命名是常用的crud命令的演示. 1.1.1. memcached命令的格式 标准 ...
- 使用github搭建网站
http://blog.csdn.net/pipisorry/article/details/51707366 使用github建站 github设计了Pages功能,允许用户自定义项目首页,用来替代 ...
- 3.Lucene3.x API分析,Director 索引操作目录,Document,分词器
1 Lucene卡发包结构分析 包名 功能 org.apache.lucene.analysis Analysis提供自带的各种Analyzer org.apache.lucene.colla ...