srs gop缓冲

来源:互联网 发布:ios程序员烂大街 编辑:程序博客网 时间:2024/05/16 12:59

源码在 src/app/srs_app_source.cpp中

*** cache a gop of video/audio data,* delivery at the connect of flash player,* to enable it to fast startup.*/class SrsGopCache{private:    /**    * if disabled the gop cache,    * the client will wait for the next keyframe for h264,    * and will be black-screen.    */    bool enable_gop_cache;    /**    * the video frame count, avoid cache for pure audio stream.    */    int cached_video_count;    /**    * when user disabled video when publishing, and gop cache enalbed,    * we will cache the audio/video for we already got video, but we never    * know when to clear the gop cache, for there is no video in future,    * so we must guess whether user disabled the video.    * when we got some audios after laster video, for instance, 600 audio packets,    * about 3s(26ms per packet) 115 audio packets, clear gop cache.    *     * @remark, it is ok for performance, for when we clear the gop cache,    *       gop cache is disabled for pure audio stream.    * @see: https://github.com/ossrs/srs/issues/124    */    int audio_after_last_video_count;    /**    * cached gop.    */    std::vector<SrsSharedPtrMessage*> gop_cache;public:    SrsGopCache();    virtual ~SrsGopCache();public:    /**     * cleanup when system quit.     */    virtual void dispose();    /**    * to enable or disable the gop cache.    */    virtual void set(bool v);    virtual bool enabled();    /**    * only for h264 codec    * 1. cache the gop when got h264 video packet.    * 2. clear gop when got keyframe.    * @param shared_msg, directly ptr, copy it if need to save it.    */    virtual int cache(SrsSharedPtrMessage* shared_msg);    /**    * clear the gop cache.    */    virtual void clear();    /**    * dump the cached gop to consumer.    */    virtual int dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm);    /**    * used for atc to get the time of gop cache,    * the atc will adjust the sequence header timestamp to gop cache.    */    virtual bool empty();    /**    * get the start time of gop cache, in ms.    * @return 0 if no packets.    */    virtual int64_t start_time();    /**    * whether current stream is pure audio,    * when no video in gop cache, the stream is pure audio right now.    */    virtual bool pure_audio();};

SrsGopCache::SrsGopCache(){    cached_video_count = 0;    enable_gop_cache = true;    audio_after_last_video_count = 0;}SrsGopCache::~SrsGopCache(){    clear();}void SrsGopCache::dispose(){    clear();}void SrsGopCache::set(bool v){    enable_gop_cache = v;        if (!v) {        srs_info("disable gop cache, clear %d packets.", (int)gop_cache.size());        clear();        return;    }        srs_info("enable gop cache");}bool SrsGopCache::enabled(){    return enable_gop_cache;}int SrsGopCache::cache(SrsSharedPtrMessage* shared_msg){    int ret = ERROR_SUCCESS;        if (!enable_gop_cache) {        srs_verbose("gop cache is disabled.");        return ret;    }    // the gop cache know when to gop it.    SrsSharedPtrMessage* msg = shared_msg;        // got video, update the video count if acceptable    if (msg->is_video()) {        // drop video when not h.264        if (!SrsFlvVideo::h264(msg->payload, msg->size)) {            srs_info("gop cache drop video for none h.264");            return ret;        }                cached_video_count++;        audio_after_last_video_count = 0;    }        // no acceptable video or pure audio, disable the cache.    if (pure_audio()) {        srs_verbose("ignore any frame util got a h264 video frame.");        return ret;    }        // ok, gop cache enabled, and got an audio.    if (msg->is_audio()) {        audio_after_last_video_count++;    }        // clear gop cache when pure audio count overflow    if (audio_after_last_video_count > SRS_PURE_AUDIO_GUESS_COUNT) {        srs_warn("clear gop cache for guess pure audio overflow");        clear();        return ret;    }        // clear gop cache when got key frame  //获得下个关键帧时会清空该gop    if (msg->is_video() && SrsFlvVideo::keyframe(msg->payload, msg->size)) {        srs_info("clear gop cache when got keyframe. vcount=%d, count=%d",            cached_video_count, (int)gop_cache.size());                    clear();                // curent msg is video frame, so we set to 1.        cached_video_count = 1;    }        // cache the frame.    gop_cache.push_back(msg->copy());        return ret;}void SrsGopCache::clear(){    std::vector<SrsSharedPtrMessage*>::iterator it;    for (it = gop_cache.begin(); it != gop_cache.end(); ++it) {        SrsSharedPtrMessage* msg = *it;        srs_freep(msg);    }    gop_cache.clear();    cached_video_count = 0;    audio_after_last_video_count = 0;}    int SrsGopCache::dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm){    int ret = ERROR_SUCCESS;        std::vector<SrsSharedPtrMessage*>::iterator it;    for (it = gop_cache.begin(); it != gop_cache.end(); ++it) {        SrsSharedPtrMessage* msg = *it;        if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) {            srs_error("dispatch cached gop failed. ret=%d", ret);            return ret;        }    }    srs_trace("dispatch cached gop success. count=%d, duration=%d", (int)gop_cache.size(), consumer->get_time());        return ret;}bool SrsGopCache::empty(){    return gop_cache.empty();}int64_t SrsGopCache::start_time(){    if (empty()) {        return 0;    }        SrsSharedPtrMessage* msg = gop_cache[0];    srs_assert(msg);        return msg->timestamp;}bool SrsGopCache::pure_audio(){    return cached_video_count == 0;}

断点调试 数据Gop缓冲过程


0 0
原创粉丝点击