/** 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 stubdelete[] 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 yetunsigned 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 classDeviceServerMediaSubsession(UsageEnvironment& env,Boolean reuseFirstSource);virtual ~DeviceServerMediaSubsession();void setDoneFlag() { fDoneFlag = ~0; }protected: // redefined virtual functionsvirtual 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 msnextTask() = 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相关推荐

  1. vlc 调用live555的源码分析--vlc v2.1.1版本

    VLC调用Live555源码解析 以前在看live555的源码和例子的时,发现live555的例子都是回调,这样我们根本无法判断命令是否发送成功,也无法判断发送是否超时:网上搜索,也没有看到有用的资料 ...

  2. 加油站会员管理系统源码php_分享一下:关于一对一直播源码的重要组成部分

    随着传统直播的普及,"直播"是开发热潮的来临,一对一直播俨然成为了直播行业又一次火爆的应用领域.和传统的直播搭建形式相同,一对一直播源码开发也要通过一套功能全面的一对一直播源码来完 ...

  3. 直播源码和短视频源码,相亲相爱的一家人

    直播源码和短视频源码,相亲相爱的一家人 从直播的百播大战,到如今的趋于稳定:从短视频的兴起,到如今的竞争发展.直播和短视频两条线,开始相交,直播里面添加短视频功能,短视频里面也添加了直播. 在直播里面 ...

  4. 简单三步搭建一对一直播源码系统

    随着一对一直播源码的火热,手机直播开发便获得越来越多的人讨论,甚至有人说一对一直播开发只需要三个步骤!这对很多人来讲是很不可思议的.接下来小编具体分析一下. 首先,一对一直播源码开发分三步确实可以搭建 ...

  5. 超级直播sop直播源.zip_超级直播app壳 打造自己的直播app

    本公众号下载软件相关内容来自网友分享,非本公众号制作,如有侵权请联系作者,24小时内删除. ⚠️直播软件具有时效性,只能保证在发布当日可以正常使用,如果出现无法打开或无节目,属于正常情况,请谅解. 超 ...

  6. m3u直播源_教你创建电视直播源

    随着网络的日益普及,网上观看影视的人也越来越多,方法也五花八门.例如:直接上视频网站上看,或者是手机上安装相应的应用看,高清节目还可以下载后播放. 其实现在不少的播放器也支持网络影视内容,例如:Kod ...

  7. 地址栏地址 获取_直播源获取工具,支持斗鱼、虎牙、B站、企鹅电竞、YY、抖音、西瓜直播!...

    喜欢看直播打游戏的朋友肯定会关注几个自己喜欢的主播,看他们打游戏同时也能get一些技能. 但是有时候在手机上看不过瘾想在电脑上看,每次都要进行登录进去看非常麻烦. 那么今天给大家准备了一个获取直播源的 ...

  8. 直播源码中有哪些网络协议需要注意?

    在当今的直播平台中,对直播源码越来越注重.那么直播源码中有哪些网络协议需要注意的呢? 1.TCP:TCP为点对点的协议,虽然能保证了数据传输的可靠性,但是对服务器资源耗费较大,在数据流大的场合难以保证 ...

  9. easyvision视觉软件 源码_一对一直播源码都有哪些独具一格的优势?

    视频在线观看直播行业发展趋势稳定,一对一直播源码越来越受到大家的欢迎,它拥有着独特的优势,丰富多彩的玩法运用和普遍的主要用途,一对一直播源码有哪些优势呢? 1.一对一直播源码别具特色的语音通话.网红是 ...

最新文章

  1. TabHost布局及新浪式TabHost布局
  2. MIT、CMU 美国计算机专业最牛20名学校大点评
  3. Python剑指offer:和为s的连续整数序列
  4. java 获取系统当前时间
  5. 复制中含有非法字符导致的错误
  6. Android Studio 超级简单的打包生成apk
  7. md5不是对称密码算法_密码学中的消息摘要算法5(MD5)
  8. 九章算法 | Facebook 面试题 : Backpack VI 背包算法
  9. 小米10之后摩托罗拉Edge+也要用一亿像素相机,还有3.5耳机孔
  10. 开源 非开源_打破开源中的怪胎刻板印象
  11. DataTrigger
  12. vant部署_记录mpvue+vant-weapp的使用(一):安装配置使用,引入vant-weapp
  13. python实现判断一个字符串是否是合法IP地址
  14. centos6.8 hugepage设置
  15. 大数据之Hadoop图解概述
  16. Packet Tracer 5.0建构CCNA实验攻略——帧中继Frame Relay
  17. 深度学习在羚珑中的探索 -- 模板风格分类识别
  18. JVM上篇(13):GC分类器
  19. 如何读群晖硬盘_如何优雅无损的更换群晖硬盘
  20. 微信团队分享:视频图像的超分辨率技术原理和应用场景

热门文章

  1. 配置zabbix监控nginx状态,监控华为路由器
  2. java rtmp服务器_RTMP服务器安装
  3. js时间format
  4. 重磅!2022年QS世界大学学科排名出炉!
  5. caj能转成pdf格式吗?这三个方法建议收藏!
  6. BUUCTF misc 专题(18)小明的保险箱
  7. pc网站的一些自适应的方案
  8. 什么是带内管理 带外管理
  9. 解神者x2服务器维护,解神者X2服务器维护中 登不上与连网失败解决攻略[多图]...
  10. 安全架构-SQL注入原理及防范