目录

一 关键类

二 推流缓冲


webrtc拉流篇,可参考

https://mp.csdn.net/mp_blog/creation/editor/122743325

RTMP采用的封装格式是FLV。所以在指定输出流媒体的时候须要指定其封装格式为“flv”。同理,其余流媒体协议也须要指定其封装格式。例如采用UDP推送流媒体的时候,能够指定其封装格式为“mpegts”。

一 关键类

环形缓冲,聚合了_RingStorage

template<typename T>

class RingBuffer : public enable_shared_from_this<RingBuffer<T> > {

public:

typedef std::shared_ptr<RingBuffer> Ptr;

typedef _RingReader<T> RingReader;

typedef _RingStorage<T> RingStorage;

typedef _RingReaderDispatcher<T> RingReaderDispatcher;

typedef function<void(int size)> onReaderChanged;

RingBuffer(int max_size = 1024, const onReaderChanged &cb = nullptr) {

_on_reader_changed = cb;

_storage = std::make_shared<RingStorage>(max_size);

}

~RingBuffer() {}

void write(T in, bool is_key = true) {

if (_delegate) {

_delegate->onWrite(std::move(in), is_key);

return;

}

LOCK_GUARD(_mtx_map);

for (auto &pr : _dispatcher_map) {

auto &second = pr.second;

//切换线程后触发onRead事件

pr.first->async([second, in, is_key]() {

second->write(std::move(const_cast<T &>(in)), is_key);

}, false);

}

_storage->write(std::move(in), is_key);

}

int readerCount() {

return _total_count;

}

void clearCache(){

LOCK_GUARD(_mtx_map);

_storage->clearCache();

for (auto &pr : _dispatcher_map) {

auto &second = pr.second;

//切换线程后清空缓存

pr.first->async([second]() {

second->clearCache();

}, false);

}

}

private:

struct HashOfPtr {

std::size_t operator()(const EventPoller::Ptr &key) const {

return (std::size_t) key.get();

}

};

private:

mutex _mtx_map;

atomic_int _total_count {0};

typename RingStorage::Ptr _storage;

typename RingDelegate<T>::Ptr _delegate;

onReaderChanged _on_reader_changed;

unordered_map<EventPoller::Ptr, typename RingReaderDispatcher::Ptr, HashOfPtr> _dispatcher_map;

};

存放ffmpeg rtmp推流,demuxer,解码,重新编码后的rtppacket数据

template<typename T>

class _RingStorage {

public:

typedef std::shared_ptr<_RingStorage> Ptr;

_RingStorage(int max_size) {

//gop缓存个数不能小于32

if(max_size < RING_MIN_SIZE){

max_size = RING_MIN_SIZE;

}

_max_size = max_size;

}

~_RingStorage() {}

/**

* 写入环形缓存数据

* @param in 数据

* @param is_key 是否为关键帧

* @return 是否触发重置环形缓存大小

*/

void write(T in, bool is_key = true) {

if (is_key) {

//遇到I帧,那么移除老数据

_size = 0;

_have_idr = true;

_data_cache.clear();

}

if (!_have_idr) {

//缓存中没有关键帧,那么gop缓存无效

return;

}

_data_cache.emplace_back(std::make_pair(is_key, std::move(in)));

if (++_size > _max_size) {

//GOP缓存溢出,清空关老数据

_size = 0;

_have_idr = false;

_data_cache.clear();

}

}

Ptr clone() const {

Ptr ret(new _RingStorage());

ret->_size = _size;

ret->_have_idr = _have_idr;

ret->_max_size = _max_size;

ret->_data_cache = _data_cache;

return ret;

}

const List<pair<bool, T> > &getCache() const {

return _data_cache;

}

void clearCache(){

_size = 0;

_data_cache.clear();

}

private:

_RingStorage() = default;

private:

bool _have_idr = false;

int _size = 0;

int _max_size;

List<pair<bool, T> > _data_cache;

};

webrtc从此处reader

template<typename T>

class _RingReader {

public:

typedef std::shared_ptr<_RingReader> Ptr;

friend class _RingReaderDispatcher<T>;

_RingReader(const std::shared_ptr<_RingStorage<T> > &storage, bool use_cache) {

_storage = storage;

_use_cache = use_cache;

}

~_RingReader() {}

void setReadCB(const function<void(const T &)> &cb) {

if (!cb) {

_read_cb = [](const T &) {};

} else {

_read_cb = cb;

flushGop();

}

}

void setDetachCB(const function<void()> &cb) {

if (!cb) {

_detach_cb = []() {};

} else {

_detach_cb = cb;

}

}

private:

void onRead(const T &data, bool is_key) {

_read_cb(data);

}

void onDetach() const {

_detach_cb();

}

void flushGop() {

if (!_use_cache) {

return;

}

_storage->getCache().for_each([&](const pair<bool, T> &pr) {

onRead(pr.second, pr.first);

});

}

private:

bool _use_cache;

shared_ptr<_RingStorage<T> > _storage;

function<void(void)> _detach_cb = []() {};

function<void(const T &)> _read_cb = [](const T &) {};

};

二 推流缓冲

void EventPoller::runLoop(bool blocked,bool regist_self)

bool Socket::attachEvent(const SockFD::Ptr &sock, bool is_udp) /lambda表达式

ssize_t Socket::onRead(const SockFD::Ptr &sock, bool is_udp) noexcept

void TcpServer::onAcceptConnection(const Socket::Ptr &sock) /lambda表达式

void RtmpSession::onRecv(const Buffer::Ptr &buf)

void RtmpProtocol::onParseRtmp(const char *data, size_t size)

void HttpRequestSplitter::input(const char *data,size_t len)

const char *RtmpProtocol::onSearchPacketTail(const char *data,size_t len)

const char* RtmpProtocol::handle_C2(const char *data, size_t len)

const char* RtmpProtocol::handle_rtmp(const char *data, size_t len)

void RtmpProtocol::handle_chunk(RtmpPacket::Ptr packet)

void RtmpSession::onRtmpChunk(RtmpPacket::Ptr packet)

void onWrite(RtmpPacket::Ptr pkt, bool = true) override

void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt)

void H264RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt)

inline void H264RtmpDecoder::onGetH264(const char* data, size_t len, uint32_t dts, uint32_t pts)

bool FrameDispatcher :: inputFrame(const Frame::Ptr &frame) override

bool H264Track::inputFrame(const Frame::Ptr &frame)

bool H264Track::inputFrame_l(const Frame::Ptr &frame)

bool FrameWriterInterfaceHelper::inputFrame(const Frame::Ptr &frame) override

bool MediaSink::addTrack(const Track::Ptr &track_in)/lambda表达式

bool MultiMediaSourceMuxer::onTrackFrame(const Frame::Ptr &frame_in)

bool RtspMediaSourceMuxer::inputFrame(const Frame::Ptr &frame) override

bool RtspMuxer::inputFrame(const Frame::Ptr &frame)

bool H264RtpEncoder::inputFrame(const Frame::Ptr &frame)

bool H264RtpEncoder::inputFrame_l(const Frame::Ptr &frame, bool is_mark)

void H264RtpEncoder::packRtp(const char *ptr, size_t len, uint32_t pts, bool is_mark, bool gop_pos)

void H264RtpEncoder::packRtpFu(const char *ptr, size_t len, uint32_t pts, bool is_mark, bool gop_pos)

bool RtpRing::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos)

void RingBuffer::write(T in, bool is_key = true)

ringbuffer超过maxsize 512之后,推流数据未被拉流的话,会清空。推流和拉流过程是独立进行,比如只ffmepg推流,webrtc不拉流,播放放。

ZLMediaKit接收ffmpeg rtmp推流相关推荐

  1. ffmpeg+rtmp推流/拉流(十)

    一.搭建rtmp服务器 1.下载nginx https://github.com/nginx/nginx/archive/release-1.19.6.zip2.下载nginx-rtmp-module ...

  2. ffmpeg rtmp推流

    本文实现ffmpeg本地文件rtmp推流 ffmpeg本地文件推流主要流程 ffmpeg视频格式转换示例 #include <iostream>extern "C" { ...

  3. 音视频开发---ffmpeg rtmp推流

    目录 推流介绍 FFmpeg推流 推流器函数流程图 代码 遗留问题 参考 推流介绍 推流是将输入视频数据推送至流媒体服务器, 输入视频数据可以是本地视频文件(avi,mp4,flv......),也可 ...

  4. ffmpeg rtmp推流代码示例

    rtmp推流,得有rtmp服务器,可以参考这篇博客搭建rtmp服务器  ===>>>ubuntu搭建rtmp服务器,如果自己有rtmp服务器,可以不用看. rtmp推流需要用flv格 ...

  5. ffmpeg rtmp 推流错误WriteN, RTMP send error 10053 10038

    利用ffmepg推264流到rtmp服务端出现错误WriteN, RTMP send error 10053,具体如下图所示. 图1推流到rtmp服务错误 原因是视频流缺少SPS,PPS信息,加上这两 ...

  6. LiveNVR视频平台接收无人机等移动终端RTMP推流后转成GB28181协议输出级联到GB28181视频平台的操作说明...

    1.需求介绍 目前很多移动终端设备(如无人机等)只支持RTMP推流输出,不支持GB28181协议.但是又有需要通过GB28181协议接入到视频平台的需求.比如有些大疆无人机产品不能直接注册国标平台,只 ...

  7. python利用ffmpeg进行rtmp推流直播

    思路: opencv读取视频 -> 将视频分割为帧 -> 将每一帧进行需求加工后 -> 将此帧写入pipe管道 -> 利用ffmpeg进行推流直播 pipe管道: 啥是pipe ...

  8. 【音视频】利用ffmpeg实现:音视频的提取,rtmp推流等

    目录 可列出电脑的设备 音频+桌面视频,存mp4 录声音  推流到服务器 音频+桌面视频,推流到服务器 音频+笔记本摄像头,推流到服务器 音频+笔记本摄像头,推流到服务器:通过wvp-pro代+AAC ...

  9. 最简单的基于FFmpeg的推流器(以推送RTMP为例)

    ===================================================== 最简单的基于FFmpeg的推流器系列文章列表: <最简单的基于FFmpeg的推流器(以 ...

最新文章

  1. 什么是REST?以及RESTful
  2. Apache与Tomcat联系及区别
  3. golang reflect Pointer 获取 传入的interface信息
  4. MFC之ComboBox控件用法
  5. 科普 | 5G基站功耗,到底有多可怕?
  6. Android -- 带你从源码角度领悟Dagger2入门到放弃(一)
  7. 电脑模拟器哪个好_电脑系统杀毒软件哪个好测评
  8. php 事件调度,MySQL的事件调度器使用介绍
  9. 整理LVS架构压力测试工作
  10. 修改删除idea快捷键
  11. CentOS7 安装 7-zip 压缩工具
  12. CKEDITOR富文本编辑器+AJAX+JQUERY+ListView综合应用
  13. 计算机日期的格式怎么写,在excel表格中怎么把日期格式改成文本格式(excle表格中改变日期格式)...
  14. thinkphp5 自定义分页样式
  15. 给你一个完整的社群鸭介绍
  16. IPQ8072A 如何通过AT指令跟SDX55交互
  17. 最新史上最大数据泄露,名为“Collection #1”的7.73亿数据!
  18. 系统重启后mipi屏幕黑屏的问题
  19. pq下垂控制单相逆变器matlab仿真,学习下垂控制的逆变器并联原理,如何实现仿真P1?-控制器/处理器-与非网...
  20. 深度学习在工业界的应用案例(二)

热门文章

  1. Android打气筒三种方式
  2. SnackBar介绍
  3. React 实现地区三级联动
  4. MES制造执行系统的工作协同方式
  5. Zbrush基础《二》
  6. python怎么计算分数_python如何进行分数计算
  7. 编程基础 二进制 解密
  8. 智慧停车之 IOT选型-电信物联网
  9. 变频器对电机绝缘的影响
  10. 引体向上 - 宽握/窄握引体向上动作图解