mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-30 16:27:36 +08:00
修复某些场景下rtmp定位关键帧不准确的bug
This commit is contained in:
parent
51ae8d4083
commit
0878f776b3
@ -29,17 +29,16 @@ static string getAacCfg(const RtmpPacket &thiz) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) {
|
void AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
||||||
if (pkt->isCfgFrame()) {
|
if (pkt->isCfgFrame()) {
|
||||||
_aac_cfg = getAacCfg(*pkt);
|
_aac_cfg = getAacCfg(*pkt);
|
||||||
onGetAAC(nullptr, 0, 0);
|
onGetAAC(nullptr, 0, 0);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_aac_cfg.empty()) {
|
if (!_aac_cfg.empty()) {
|
||||||
onGetAAC(pkt->buffer.data() + 2, pkt->buffer.size() - 2, pkt->time_stamp);
|
onGetAAC(pkt->buffer.data() + 2, pkt->buffer.size() - 2, pkt->time_stamp);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) {
|
void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) {
|
||||||
@ -112,7 +111,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||||
rtmpPkt->time_stamp = frame->dts();
|
rtmpPkt->time_stamp = frame->dts();
|
||||||
rtmpPkt->type_id = MSG_AUDIO;
|
rtmpPkt->type_id = MSG_AUDIO;
|
||||||
RtmpCodec::inputRtmp(rtmpPkt, false);
|
RtmpCodec::inputRtmp(rtmpPkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +132,7 @@ void AACRtmpEncoder::makeAudioConfigPkt() {
|
|||||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||||
rtmpPkt->time_stamp = 0;
|
rtmpPkt->time_stamp = 0;
|
||||||
rtmpPkt->type_id = MSG_AUDIO;
|
rtmpPkt->type_id = MSG_AUDIO;
|
||||||
RtmpCodec::inputRtmp(rtmpPkt, false);
|
RtmpCodec::inputRtmp(rtmpPkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -28,10 +28,9 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 输入Rtmp并解码
|
* 输入Rtmp并解码
|
||||||
* @param Rtmp Rtmp数据包
|
* @param rtmp Rtmp数据包
|
||||||
* @param key_pos 此参数内部强制转换为false,请忽略之
|
|
||||||
*/
|
*/
|
||||||
bool inputRtmp(const RtmpPacket::Ptr &Rtmp, bool key_pos = false) override;
|
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
CodecId getCodecId() const override{
|
||||||
return CodecAAC;
|
return CodecAAC;
|
||||||
|
@ -29,7 +29,7 @@ void CommonRtmpDecoder::obtainFrame() {
|
|||||||
_frame->_prefix_size = 0;
|
_frame->_prefix_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp, bool) {
|
void CommonRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp) {
|
||||||
//拷贝负载
|
//拷贝负载
|
||||||
_frame->_buffer.assign(rtmp->buffer.data() + 1, rtmp->buffer.size() - 1);
|
_frame->_buffer.assign(rtmp->buffer.data() + 1, rtmp->buffer.size() - 1);
|
||||||
_frame->_dts = rtmp->time_stamp;
|
_frame->_dts = rtmp->time_stamp;
|
||||||
@ -37,7 +37,6 @@ bool CommonRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp, bool) {
|
|||||||
RtmpCodec::inputFrame(_frame);
|
RtmpCodec::inputFrame(_frame);
|
||||||
//创建下一帧
|
//创建下一帧
|
||||||
obtainFrame();
|
obtainFrame();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -61,7 +60,7 @@ void CommonRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
rtmp->stream_index = STREAM_MEDIA;
|
rtmp->stream_index = STREAM_MEDIA;
|
||||||
rtmp->time_stamp = frame->dts();
|
rtmp->time_stamp = frame->dts();
|
||||||
rtmp->type_id = MSG_AUDIO;
|
rtmp->type_id = MSG_AUDIO;
|
||||||
RtmpCodec::inputRtmp(rtmp, false);
|
RtmpCodec::inputRtmp(rtmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -39,9 +39,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 输入Rtmp并解码
|
* 输入Rtmp并解码
|
||||||
* @param rtmp Rtmp数据包
|
* @param rtmp Rtmp数据包
|
||||||
* @param key_pos 此参数内部强制转换为false,请忽略之
|
|
||||||
*/
|
*/
|
||||||
bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos = false) override;
|
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void obtainFrame();
|
void obtainFrame();
|
||||||
|
@ -23,10 +23,6 @@ H264Frame::Ptr H264RtmpDecoder::obtainFrame() {
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool H264RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) {
|
|
||||||
return decodeRtmp(rtmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回不带0x00 00 00 01头的sps
|
* 返回不带0x00 00 00 01头的sps
|
||||||
* @return
|
* @return
|
||||||
@ -90,14 +86,14 @@ static string getH264PPS(const RtmpPacket &thiz) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
|
void H264RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
||||||
if (pkt->isCfgFrame()) {
|
if (pkt->isCfgFrame()) {
|
||||||
//缓存sps pps,后续插入到I帧之前
|
//缓存sps pps,后续插入到I帧之前
|
||||||
_sps = getH264SPS(*pkt);
|
_sps = getH264SPS(*pkt);
|
||||||
_pps = getH264PPS(*pkt);
|
_pps = getH264PPS(*pkt);
|
||||||
onGetH264(_sps.data(), _sps.size(), pkt->time_stamp , pkt->time_stamp);
|
onGetH264(_sps.data(), _sps.size(), pkt->time_stamp , pkt->time_stamp);
|
||||||
onGetH264(_pps.data(), _pps.size(), pkt->time_stamp , pkt->time_stamp);
|
onGetH264(_pps.data(), _pps.size(), pkt->time_stamp , pkt->time_stamp);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkt->buffer.size() > 9) {
|
if (pkt->buffer.size() > 9) {
|
||||||
@ -119,7 +115,6 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
|
|||||||
iOffset += iFrameLen;
|
iOffset += iFrameLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pkt->isVideoKeyFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) {
|
inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) {
|
||||||
@ -191,7 +186,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(_lastPacket && _lastPacket->time_stamp != frame->dts()) {
|
if(_lastPacket && _lastPacket->time_stamp != frame->dts()) {
|
||||||
RtmpCodec::inputRtmp(_lastPacket, _lastPacket->isVideoKeyFrame());
|
RtmpCodec::inputRtmp(_lastPacket);
|
||||||
_lastPacket = nullptr;
|
_lastPacket = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +254,7 @@ void H264RtmpEncoder::makeVideoConfigPkt() {
|
|||||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||||
rtmpPkt->time_stamp = 0;
|
rtmpPkt->time_stamp = 0;
|
||||||
rtmpPkt->type_id = MSG_VIDEO;
|
rtmpPkt->type_id = MSG_VIDEO;
|
||||||
RtmpCodec::inputRtmp(rtmpPkt, false);
|
RtmpCodec::inputRtmp(rtmpPkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
@ -32,17 +32,17 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 输入264 Rtmp包
|
* 输入264 Rtmp包
|
||||||
* @param rtmp Rtmp包
|
* @param rtmp Rtmp包
|
||||||
* @param key_pos 此参数忽略之
|
|
||||||
*/
|
*/
|
||||||
bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos = true) override;
|
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
CodecId getCodecId() const override{
|
||||||
return CodecH264;
|
return CodecH264;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool decodeRtmp(const RtmpPacket::Ptr &Rtmp);
|
|
||||||
void onGetH264(const char *pcData, int iLen, uint32_t dts,uint32_t pts);
|
void onGetH264(const char *pcData, int iLen, uint32_t dts,uint32_t pts);
|
||||||
H264Frame::Ptr obtainFrame();
|
H264Frame::Ptr obtainFrame();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
H264Frame::Ptr _h264frame;
|
H264Frame::Ptr _h264frame;
|
||||||
string _sps;
|
string _sps;
|
||||||
|
@ -27,10 +27,6 @@ H265Frame::Ptr H265RtmpDecoder::obtainFrame() {
|
|||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool H265RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) {
|
|
||||||
return decodeRtmp(rtmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_MP4
|
#ifdef ENABLE_MP4
|
||||||
/**
|
/**
|
||||||
* 返回不带0x00 00 00 01头的sps
|
* 返回不带0x00 00 00 01头的sps
|
||||||
@ -65,7 +61,7 @@ static bool getH265ConfigFrame(const RtmpPacket &thiz,string &frame) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool H265RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
|
void H265RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
||||||
if (pkt->isCfgFrame()) {
|
if (pkt->isCfgFrame()) {
|
||||||
#ifdef ENABLE_MP4
|
#ifdef ENABLE_MP4
|
||||||
string config;
|
string config;
|
||||||
@ -75,7 +71,7 @@ bool H265RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
|
|||||||
#else
|
#else
|
||||||
WarnL << "请开启MP4相关功能并使能\"ENABLE_MP4\",否则对H265-RTMP支持不完善";
|
WarnL << "请开启MP4相关功能并使能\"ENABLE_MP4\",否则对H265-RTMP支持不完善";
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkt->buffer.size() > 9) {
|
if (pkt->buffer.size() > 9) {
|
||||||
@ -97,7 +93,6 @@ bool H265RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
|
|||||||
iOffset += iFrameLen;
|
iOffset += iFrameLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pkt->isVideoKeyFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void H265RtmpDecoder::onGetH265(const char* pcData, int iLen, uint32_t dts,uint32_t pts) {
|
inline void H265RtmpDecoder::onGetH265(const char* pcData, int iLen, uint32_t dts,uint32_t pts) {
|
||||||
@ -177,7 +172,7 @@ void H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(_lastPacket && _lastPacket->time_stamp != frame->dts()) {
|
if(_lastPacket && _lastPacket->time_stamp != frame->dts()) {
|
||||||
RtmpCodec::inputRtmp(_lastPacket, _lastPacket->isVideoKeyFrame());
|
RtmpCodec::inputRtmp(_lastPacket);
|
||||||
_lastPacket = nullptr;
|
_lastPacket = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +237,7 @@ void H265RtmpEncoder::makeVideoConfigPkt() {
|
|||||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||||
rtmpPkt->time_stamp = 0;
|
rtmpPkt->time_stamp = 0;
|
||||||
rtmpPkt->type_id = MSG_VIDEO;
|
rtmpPkt->type_id = MSG_VIDEO;
|
||||||
RtmpCodec::inputRtmp(rtmpPkt, false);
|
RtmpCodec::inputRtmp(rtmpPkt);
|
||||||
#else
|
#else
|
||||||
WarnL << "请开启MP4相关功能并使能\"ENABLE_MP4\",否则对H265-RTMP支持不完善";
|
WarnL << "请开启MP4相关功能并使能\"ENABLE_MP4\",否则对H265-RTMP支持不完善";
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,17 +32,17 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 输入265 Rtmp包
|
* 输入265 Rtmp包
|
||||||
* @param rtmp Rtmp包
|
* @param rtmp Rtmp包
|
||||||
* @param key_pos 此参数忽略之
|
|
||||||
*/
|
*/
|
||||||
bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos = true) override;
|
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
CodecId getCodecId() const override{
|
||||||
return CodecH265;
|
return CodecH265;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool decodeRtmp(const RtmpPacket::Ptr &Rtmp);
|
|
||||||
void onGetH265(const char *pcData, int iLen, uint32_t dts,uint32_t pts);
|
void onGetH265(const char *pcData, int iLen, uint32_t dts,uint32_t pts);
|
||||||
H265Frame::Ptr obtainFrame();
|
H265Frame::Ptr obtainFrame();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
H265Frame::Ptr _h265frame;
|
H265Frame::Ptr _h265frame;
|
||||||
};
|
};
|
||||||
|
@ -45,14 +45,11 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 输入rtmp包
|
* 输入rtmp包
|
||||||
* @param rtmp rtmp包
|
* @param rtmp rtmp包
|
||||||
* @param key_pos 是否为关键帧
|
|
||||||
* @return 是否为关键帧
|
|
||||||
*/
|
*/
|
||||||
virtual bool inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) {
|
virtual void inputRtmp(const RtmpPacket::Ptr &rtmp) {
|
||||||
if (_rtmpRing) {
|
if (_rtmpRing) {
|
||||||
_rtmpRing->write(rtmp, key_pos);
|
_rtmpRing->write(rtmp, rtmp->isVideoKeyFrame());
|
||||||
}
|
}
|
||||||
return key_pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -65,34 +65,32 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
||||||
switch (pkt->type_id) {
|
switch (pkt->type_id) {
|
||||||
case MSG_VIDEO: {
|
case MSG_VIDEO: {
|
||||||
if(!_try_get_video_track){
|
if (!_try_get_video_track) {
|
||||||
_try_get_video_track = true;
|
_try_get_video_track = true;
|
||||||
auto codec = AMFValue(pkt->getMediaType());
|
auto codec = AMFValue(pkt->getMediaType());
|
||||||
makeVideoTrack(codec);
|
makeVideoTrack(codec);
|
||||||
}
|
}
|
||||||
if(_video_rtmp_decoder){
|
if (_video_rtmp_decoder) {
|
||||||
return _video_rtmp_decoder->inputRtmp(pkt, true);
|
_video_rtmp_decoder->inputRtmp(pkt);
|
||||||
}
|
}
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MSG_AUDIO: {
|
case MSG_AUDIO: {
|
||||||
if(!_try_get_audio_track) {
|
if (!_try_get_audio_track) {
|
||||||
_try_get_audio_track = true;
|
_try_get_audio_track = true;
|
||||||
auto codec = AMFValue(pkt->getMediaType());
|
auto codec = AMFValue(pkt->getMediaType());
|
||||||
makeAudioTrack(codec, pkt->getAudioSampleRate(), pkt->getAudioChannel(), pkt->getAudioSampleBit());
|
makeAudioTrack(codec, pkt->getAudioSampleRate(), pkt->getAudioChannel(), pkt->getAudioSampleBit());
|
||||||
}
|
}
|
||||||
if(_audio_rtmp_decoder){
|
if (_audio_rtmp_decoder) {
|
||||||
_audio_rtmp_decoder->inputRtmp(pkt, false);
|
_audio_rtmp_decoder->inputRtmp(pkt);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default : break;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 开始解复用
|
* 开始解复用
|
||||||
* @param pkt rtmp包
|
* @param pkt rtmp包
|
||||||
* @return true 代表是i帧
|
|
||||||
*/
|
*/
|
||||||
bool inputRtmp(const RtmpPacket::Ptr &pkt);
|
void inputRtmp(const RtmpPacket::Ptr &pkt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void makeVideoTrack(const AMFValue &val);
|
void makeVideoTrack(const AMFValue &val);
|
||||||
|
@ -117,9 +117,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 输入rtmp包
|
* 输入rtmp包
|
||||||
* @param pkt rtmp包
|
* @param pkt rtmp包
|
||||||
* @param key 是否为关键帧
|
|
||||||
*/
|
*/
|
||||||
void onWrite(const RtmpPacket::Ptr &pkt, bool key = true) override {
|
void onWrite(const RtmpPacket::Ptr &pkt, bool = true) override {
|
||||||
//保存当前时间戳
|
//保存当前时间戳
|
||||||
switch (pkt->type_id) {
|
switch (pkt->type_id) {
|
||||||
case MSG_VIDEO : _track_stamps[TrackVideo] = pkt->time_stamp, _have_video = true; break;
|
case MSG_VIDEO : _track_stamps[TrackVideo] = pkt->time_stamp, _have_video = true; break;
|
||||||
@ -152,7 +151,7 @@ public:
|
|||||||
regist();
|
regist();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PacketCache<RtmpPacket>::inputPacket(pkt->type_id == MSG_VIDEO, pkt, key);
|
PacketCache<RtmpPacket>::inputPacket(pkt->type_id == MSG_VIDEO, pkt, pkt->isVideoKeyFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,15 +60,12 @@ public:
|
|||||||
/**
|
/**
|
||||||
* 输入rtmp并解析
|
* 输入rtmp并解析
|
||||||
*/
|
*/
|
||||||
void onWrite(const RtmpPacket::Ptr &pkt,bool key_pos = true) override {
|
void onWrite(const RtmpPacket::Ptr &pkt, bool = true) override {
|
||||||
if (_all_track_ready && !_muxer->isEnabled()) {
|
if (!_all_track_ready || _muxer->isEnabled()) {
|
||||||
//获取到所有Track后,并且未开启转协议,那么不需要解复用rtmp
|
//未获取到所有Track后,或者开启转协议,那么需要解复用rtmp
|
||||||
key_pos = pkt->isVideoKeyFrame();
|
_demuxer->inputRtmp(pkt);
|
||||||
} else {
|
|
||||||
//需要解复用rtmp
|
|
||||||
key_pos = _demuxer->inputRtmp(pkt);
|
|
||||||
}
|
}
|
||||||
RtmpMediaSource::onWrite(pkt, key_pos);
|
RtmpMediaSource::onWrite(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user