mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-28 13:04:07 +08:00
HLS TS 切片下载失败后清除该切片遗留的解复用输入缓存 (#4786)
在 HLS TS 切片下载失败后清除该切片遗留的解复用输入缓存,防止其与下一切片拼接导致错误的包或者损坏的包出现.
This commit is contained in:
@@ -153,6 +153,7 @@ void HlsPlayer::fetchSegment() {
|
||||
return;
|
||||
}
|
||||
if (err) {
|
||||
strong_self->onSegmentDownloadFailed(err);
|
||||
WarnL << "Download ts segment " << url << " failed:" << err;
|
||||
if (err.getErrCode() == Err_timeout) {
|
||||
strong_self->_timeout_multiple = MAX(strong_self->_timeout_multiple + 1, MAX_TIMEOUT_MULTIPLE);
|
||||
@@ -492,6 +493,14 @@ void HlsPlayerImp::onPacket(const char *data, size_t len) {
|
||||
_recvtotalbytes += HlsPlayer::getRecvTotalBytes();
|
||||
}
|
||||
|
||||
void HlsPlayerImp::onSegmentDownloadFailed(const toolkit::SockException &ex) {
|
||||
if (_decoder && ex) {
|
||||
// 失败切片的输入残片不能与下一切片拼接;这里只清输入缓存,不 flush 解码帧。
|
||||
// Input left by a failed segment must not join the next one; clear it without flushing decoded frames.
|
||||
_decoder->clearInputCache();
|
||||
}
|
||||
}
|
||||
|
||||
void HlsPlayerImp::addTrackCompleted() {
|
||||
PlayerImp<HlsPlayer, PlayerBase>::onPlayResult(SockException(Err_success, "play hls success"));
|
||||
}
|
||||
|
||||
@@ -90,6 +90,9 @@ protected:
|
||||
* [AUTO-TRANSLATED:159a6559]
|
||||
*/
|
||||
virtual void onPacket(const char *data, size_t len) = 0;
|
||||
// TS 切片下载失败通知;派生类可清理该切片遗留的输入状态。
|
||||
// Notify derived classes to clear input state left by a failed TS segment.
|
||||
virtual void onSegmentDownloadFailed(const toolkit::SockException &ex) {}
|
||||
|
||||
private:
|
||||
bool onParsed(bool is_m3u8_inner, int64_t sequence, const map<int, ts_segment> &ts_map) override;
|
||||
@@ -149,6 +152,7 @@ public:
|
||||
private:
|
||||
//// HlsPlayer override////
|
||||
void onPacket(const char *data, size_t len) override;
|
||||
void onSegmentDownloadFailed(const toolkit::SockException &ex) override;
|
||||
|
||||
private:
|
||||
//// PlayerBase override////
|
||||
|
||||
@@ -72,6 +72,10 @@ ssize_t DecoderImp::input(const uint8_t *data, size_t bytes){
|
||||
return _decoder->input(data, bytes);
|
||||
}
|
||||
|
||||
void DecoderImp::clearInputCache() {
|
||||
_decoder->clearInputCache();
|
||||
}
|
||||
|
||||
DecoderImp::DecoderImp(const Decoder::Ptr &decoder, MediaSinkInterface *sink){
|
||||
_decoder = decoder;
|
||||
_sink = sink;
|
||||
|
||||
@@ -25,6 +25,9 @@ public:
|
||||
using onStream = std::function<void(int stream, int codecid, const void *extra, size_t bytes, int finish)>;
|
||||
|
||||
virtual ssize_t input(const uint8_t *data, size_t bytes) = 0;
|
||||
// 清理未完成的输入缓存,但不 flush 已解析的帧。
|
||||
// Clear incomplete input cache without flushing parsed frames.
|
||||
virtual void clearInputCache() {}
|
||||
void setOnDecode(onDecode cb);
|
||||
void setOnStream(onStream cb);
|
||||
|
||||
@@ -45,6 +48,7 @@ public:
|
||||
|
||||
static Ptr createDecoder(Type type, MediaSinkInterface *sink);
|
||||
ssize_t input(const uint8_t *data, size_t bytes);
|
||||
void clearInputCache();
|
||||
void flush();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -146,6 +146,12 @@ ssize_t TSDecoder::input(const uint8_t *data, size_t bytes) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void TSDecoder::clearInputCache() {
|
||||
// 只清理未完成的 TS 输入缓存,不重置 libmpegts 或 flush 残留帧。
|
||||
// Clear only incomplete TS input; do not reset libmpegts or flush pending frames.
|
||||
_ts_segment.reset();
|
||||
}
|
||||
|
||||
#endif//defined(ENABLE_HLS)
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
TSDecoder();
|
||||
~TSDecoder();
|
||||
ssize_t input(const uint8_t* data, size_t bytes) override ;
|
||||
void clearInputCache() override;
|
||||
|
||||
private:
|
||||
TSSegment _ts_segment;
|
||||
|
||||
Reference in New Issue
Block a user