ZLMediaKit基础设施类 RingBuffer 相关

这几个类在推流流程中使用的,数据流转的基本设施类。

1,RingBuffer,_RingReaderDispatcher,_RingReader都有一个_RingStorage类型的共享变量。

2,RingBuffer本身并不保存数据,数据的保存是通过_RingStorage类变量进行保存。

3,_RingStorage其实保存的是数据的共享类型指针,通过一个deque保存。定义为deque<pair<bool, T> > _data_cache; 并设置最大记录数量。这里主要是缓存一个从当前I帧开始到下一个I帧来之间的完整的一个GOP吧。当有新的连接过来,将这些数据,一下子发送给客户端,达到一个秒开的效果。

4,RingBuffer构造函数中,创建一个RingStorage的共享指针变量。attach函数中,将会创建一RingReaderDispatcher类型的共享变量,并把RingStorage的共享指针变量,作为参数传递进去。并调用RingReaderDispatcher类型的attch方法,RingReaderDispatcher类型的attch方法中,,会创建一个_RingReader类型的共享变量,同样会传递RingStorage的共享指针变量,最后返回一个_RingReader类型的共享变量。也就是说,这几个类指向的RingStorage的共享指针变量,是同一个。

      外部类通过调用RingBuffer的 attch方法,得到一个_RingReader的共享指针,并对这个指针调用 setReadCB回调。当向RingBuffer写数据时,将会触发回调处理。一般是将接收的数据直接发送。因为连接建立的时候,已经设置连接为非阻塞,所以这里直接发送。也有不少项目是设置一个线程和一定大小的缓冲,先将数据缓存下来,然后线程从缓存中再依次读取发送,阻塞模式下需要这么去做,非阻塞将这些都交给了系统底层,不需要自己写代码去控制,代码量减少不少,需要注意的是,根据项目的实际发送数据码率,调用 setsockopt设置好发送缓冲大小,这个可以设置的稍微大一点,保证数据的发送。

 参考项目中的这些代码:

FlvMuxer::start

_ring_reader = media->getRing()->attach(poller);
    _ring_reader->setDetachCB([weakSelf](){
        auto strongSelf = weakSelf.lock();
        if(!strongSelf){
            return;
        }
        strongSelf->onDetach();
    });

HttpSession::checkLiveStreamFMP4

 _fmp4_reader = fmp4_src->getRing()->attach(getPoller());

_fmp4_reader->setReadCB([weak_self](const FMP4MediaSource::RingDataType &fmp4_list) {
            auto strong_self = weak_self.lock();
            if (!strong_self) {
                //本对象已经销毁
                return;
            }
            int i = 0;
            int size = fmp4_list->size();
            fmp4_list->for_each([&](const FMP4Packet::Ptr &ts) {
                strong_self->onWrite(ts, ++i == size);
            });
        });

RtspPusher::sendRecord

_ts_reader = ts_src->getRi_ts_reader->setReadCB([weak_self](const TSMediaSource::RingDataType &ts_list) {
            auto strong_self = weak_self.lock();
            if (!strong_self) {
                //本对象已经销毁
                return;
            }
            int i = 0;
            int size = ts_list->size();
            ts_list->for_each([&](const TSPacket::Ptr &ts) {
                strong_self->onWrite(ts, ++i == size);
            });
        });ng()->attach(getPoller());

RtspSession::handleReq_Play

_play_reader = play_src->getRing()->attach(getPoller(), useGOP);

_play_reader->setReadCB([weakSelf](const RtspMediaSource::RingDataType &pack) {
            auto strongSelf = weakSelf.lock();
            if (!strongSelf) {
                return;
            }
            if (strongSelf->_enable_send_rtp) {
                strongSelf->sendRtpPacket(pack);
            }
        });

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值