From 98d0bc27f951a55232f9393280dfcf049344b365 Mon Sep 17 00:00:00 2001 From: baiyfcu Date: Sun, 26 Apr 2020 17:40:34 +0800 Subject: [PATCH 1/2] =?UTF-8?q?mk=5Fplayer=20api=20=E5=A2=9E=E5=8A=A0seek?= =?UTF-8?q?=E5=92=8C=E8=8E=B7=E5=8F=96=E8=BF=9B=E5=BA=A6=E4=BB=A5=E7=9B=B8?= =?UTF-8?q?=E5=AF=B9=E5=BC=80=E5=A7=8B=E6=97=B6=E9=97=B4=E7=9A=84=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=BB=A5=E9=80=82=E5=BA=94=E6=8C=89=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E8=BD=B4=E6=96=B9=E5=BC=8F=E5=9B=9E=E6=94=BE=E7=9A=84=E9=9C=80?= =?UTF-8?q?=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/include/mk_player.h | 14 +++++++++++++- api/source/mk_player.cpp | 18 ++++++++++++++++++ src/Common/Stamp.cpp | 7 ++++++- src/Common/Stamp.h | 3 +++ src/Player/PlayerBase.h | 25 +++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/api/include/mk_player.h b/api/include/mk_player.h index d93414e2..bd980891 100755 --- a/api/include/mk_player.h +++ b/api/include/mk_player.h @@ -80,6 +80,13 @@ API_EXPORT void API_CALL mk_player_pause(mk_player ctx, int pause); */ API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress); +/** + * 设置点播进度条 + * @param ctx 对象指针 + * @param seekPos 取值范围 相对于开始时间增量 单位秒 + */ +API_EXPORT void API_CALL mk_player_seektoByPos(mk_player ctx, int seekPos); + /** * 设置播放器开启播放结果回调函数 * @param ctx 播放器指针 @@ -155,10 +162,15 @@ API_EXPORT int API_CALL mk_player_audio_channel(mk_player ctx); API_EXPORT float API_CALL mk_player_duration(mk_player ctx); /** - * 获取点播播放进度,取值范围未 0.0~1.0 + * 获取点播播放进度,取值范围 0.0~1.0 */ API_EXPORT float API_CALL mk_player_progress(mk_player ctx); +/** + * 获取点播播放进度位置,取值范围 相对于开始时间增量 单位秒 + */ +API_EXPORT int API_CALL mk_player_progress_pos(mk_player ctx); + /** * 获取丢包率,rtsp时有效 * @param ctx 对象指针 diff --git a/api/source/mk_player.cpp b/api/source/mk_player.cpp index b2a01bcd..7db8bc69 100755 --- a/api/source/mk_player.cpp +++ b/api/source/mk_player.cpp @@ -62,6 +62,16 @@ API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) { }); } + +API_EXPORT void API_CALL mk_player_seektoByPos(mk_player ctx, int seekPos) +{ + MediaPlayer::Ptr& player = *((MediaPlayer::Ptr*)ctx); + player->getPoller()->async([seekPos, player]() { + //切换线程后再操作 + player->seekTo((uint32_t)seekPos); + }); +} + static void mk_player_set_on_event(mk_player ctx, on_mk_play_event cb, void *user_data, int type) { assert(ctx && cb); MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); @@ -169,6 +179,14 @@ API_EXPORT float API_CALL mk_player_progress(mk_player ctx) { return player->getProgress(); } + +API_EXPORT int API_CALL mk_player_progress_pos(mk_player ctx) +{ + assert(ctx); + MediaPlayer::Ptr& player = *((MediaPlayer::Ptr*)ctx); + return player->getProgressPos(); +} + API_EXPORT float API_CALL mk_player_loss_rate(mk_player ctx, int track_type) { assert(ctx); MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); diff --git a/src/Common/Stamp.cpp b/src/Common/Stamp.cpp index e184dcdb..7ed1474f 100644 --- a/src/Common/Stamp.cpp +++ b/src/Common/Stamp.cpp @@ -52,7 +52,10 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, //这是点播 dts_out = dts; pts_out = pts; - _relativeStamp = dts_out; + _last_dts = dts; + if (_dts_base == -1) + _dts_base = dts; + _relativeStamp = _npt_base + dts - _dts_base; return; } @@ -84,6 +87,8 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, } void Stamp::setRelativeStamp(int64_t relativeStamp) { + _dts_base = _last_dts; + _npt_base = relativeStamp; _relativeStamp = relativeStamp; } diff --git a/src/Common/Stamp.h b/src/Common/Stamp.h index 9e49f393..5d3897bf 100644 --- a/src/Common/Stamp.h +++ b/src/Common/Stamp.h @@ -71,6 +71,9 @@ private: int64_t _last_dts = -1; SmoothTicker _ticker; bool _playback = false; + + int64_t _dts_base = 0; + int64_t _npt_base = 0; }; diff --git a/src/Player/PlayerBase.h b/src/Player/PlayerBase.h index e38d723e..656211f2 100644 --- a/src/Player/PlayerBase.h +++ b/src/Player/PlayerBase.h @@ -93,12 +93,24 @@ public: */ virtual float getProgress() const { return 0;} + /** + * 获取播放进度pos,取值 相对开始时间增量 单位秒 + * @return + */ + virtual uint32_t getProgressPos() const { return 0; } + /** * 拖动进度条 * @param fProgress 进度,取值 0.0 ~ 1.0 */ virtual void seekTo(float fProgress) {} + /** + * 拖动进度条 + * @param seekPos 进度,取值 相对于开始时间的增量 单位秒 + */ + virtual void seekTo(uint32_t seekPos) {} + /** * 设置一个MediaSource,直接生产rtsp/rtmp代理 * @param src @@ -174,6 +186,12 @@ public: } return Parent::getProgress(); } + uint32_t getProgressPos() const override { + if (_delegate) { + return _delegate->getProgressPos(); + } + return Parent::getProgressPos(); + } void seekTo(float fProgress) override{ if (_delegate) { return _delegate->seekTo(fProgress); @@ -181,6 +199,13 @@ public: return Parent::seekTo(fProgress); } + void seekTo(uint32_t seekPos) override { + if (_delegate) { + return _delegate->seekTo(seekPos); + } + return Parent::seekTo(seekPos); + } + void setMediaSouce(const MediaSource::Ptr & src) override { if (_delegate) { _delegate->setMediaSouce(src); From 05a65d4961e99486ec58c210b6f157f9298c8d0f Mon Sep 17 00:00:00 2001 From: baiyfcu Date: Wed, 17 Jun 2020 15:51:02 +0800 Subject: [PATCH 2/2] merge stamp --- src/Common/Stamp.cpp | 54 ++++++++++++++++++++++++++++++++++++-------- src/Common/Stamp.h | 23 +++++++++++++------ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/Common/Stamp.cpp b/src/Common/Stamp.cpp index 0bbaf958..e5fd631c 100644 --- a/src/Common/Stamp.cpp +++ b/src/Common/Stamp.cpp @@ -42,7 +42,48 @@ void Stamp::setPlayBack(bool playback) { _playback = playback; } +void Stamp::syncTo(Stamp &other){ + _sync_master = &other; + _sync_finished = false; +} + void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp) { + revise_l(dts,pts,dts_out,pts_out,modifyStamp); + if(_sync_finished || modifyStamp || _playback){ + //自动生成时间戳或回放或同步完毕 + if(dts_out < 0) { dts_out = 0; } + if(pts_out < 0) { pts_out = 0; } + return; + } + + if(_sync_master && _sync_master->_last_dts){ + //音视频dts当前时间差 + int64_t dts_diff = _last_dts - _sync_master->_last_dts; + if(ABS(dts_diff) < 5000){ + //如果绝对时间戳小于5秒,那么说明他们的起始时间戳是一致的,那么强制同步 + _last_relativeStamp = _relativeStamp; + _relativeStamp = _sync_master->_relativeStamp + dts_diff; + } + //下次不用再强制同步 + _sync_master = nullptr; + } + + if (dts_out < 0 || dts_out < _last_relativeStamp) { + //相对时间戳小于0,或者小于上次的时间戳, + //那么说明是同步时间戳导致的,在这个过渡期内,我们一直返回上次的结果(目的是为了防止时间戳回退) + pts_out = _last_relativeStamp + (pts_out - dts_out); + dts_out = _last_relativeStamp; + } else if(!_sync_master){ + //音视频同步过渡期完毕 + _sync_finished = true; + } + + if(pts_out < 0){ + pts_out = dts_out; + } +} + +void Stamp::revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp) { if(!pts){ //没有播放时间戳,使其赋值为解码时间戳 pts = dts; @@ -52,10 +93,8 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, //这是点播 dts_out = dts; pts_out = pts; + _relativeStamp = dts_out; _last_dts = dts; - if (_dts_base == -1) - _dts_base = dts; - _relativeStamp = _npt_base + dts - _dts_base; return; } @@ -65,6 +104,7 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, if(_last_dts != dts){ //时间戳发生变更 if(modifyStamp){ + //内部自己生产时间戳 _relativeStamp = _ticker.elapsedTime(); }else{ _relativeStamp += deltaStamp(dts); @@ -80,15 +120,9 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out, } pts_out = dts_out + pts_dts_diff; - if(pts_out < 0){ - //时间戳不能小于0 - pts_out = 0; - } } void Stamp::setRelativeStamp(int64_t relativeStamp) { - _dts_base = _last_dts; - _npt_base = relativeStamp; _relativeStamp = relativeStamp; } @@ -141,7 +175,7 @@ bool DtsGenerator::getDts_l(uint32_t pts, uint32_t &dts){ //已经出现多次非B帧的情况,那么我们就能知道P帧间B帧的个数 _sorter_max_size = _frames_since_last_max_pts; //我们记录P帧间时间间隔(也就是多个B帧时间戳增量累计) - _dts_pts_offset = (pts - _last_max_pts) / 2; + _dts_pts_offset = (pts - _last_max_pts); } //遇到P帧或关键帧,连续B帧计数清零 _frames_since_last_max_pts = 0; diff --git a/src/Common/Stamp.h b/src/Common/Stamp.h index 5d3897bf..cf374277 100644 --- a/src/Common/Stamp.h +++ b/src/Common/Stamp.h @@ -32,6 +32,7 @@ public: private: int64_t _last_stamp = 0; }; + //该类解决时间戳回环、回退问题 //计算相对时间戳或者产生平滑时间戳 class Stamp : public DeltaStamp{ @@ -66,17 +67,27 @@ public: * @param playback 是否为回放模式 */ void setPlayBack(bool playback = true); + + /** + * 音视频同步用,音频应该同步于视频(只修改音频时间戳) + * 因为音频时间戳修改后不影响播放速度 + */ + void syncTo(Stamp &other); + +private: + void revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,bool modifyStamp = false); private: int64_t _relativeStamp = 0; - int64_t _last_dts = -1; + int64_t _last_relativeStamp = 0; + int64_t _last_dts = 0; SmoothTicker _ticker; bool _playback = false; - - int64_t _dts_base = 0; - int64_t _npt_base = 0; + Stamp *_sync_master = nullptr; + bool _sync_finished = true; }; - +//dts生成器, +//pts排序后就是dts class DtsGenerator{ public: DtsGenerator() = default; @@ -93,8 +104,6 @@ private: int _sorter_max_size = 0; int _count_sorter_max_size = 0; set _pts_sorter; - - }; }//namespace mediakit