1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

refine hls, support time jitter detect and correct

This commit is contained in:
winlin 2013-11-26 11:48:18 +08:00
parent 326713fbed
commit 749b7bdb2a
5 changed files with 48 additions and 34 deletions

View file

@ -109,7 +109,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_HLS_METADATA 600 #define ERROR_HLS_METADATA 600
#define ERROR_HLS_DECODE_ERROR 601 #define ERROR_HLS_DECODE_ERROR 601
#define ERROR_HLS_BUSY 602 //#define ERROR_HLS_BUSY 602
#define ERROR_HLS_OPEN_FAILED 603 #define ERROR_HLS_OPEN_FAILED 603
#define ERROR_HLS_WRITE_FAILED 604 #define ERROR_HLS_WRITE_FAILED 604
#define ERROR_HLS_AAC_FRAME_LENGTH 605 #define ERROR_HLS_AAC_FRAME_LENGTH 605

View file

@ -34,6 +34,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_amf0.hpp> #include <srs_core_amf0.hpp>
#include <srs_core_protocol.hpp> #include <srs_core_protocol.hpp>
#include <srs_core_config.hpp> #include <srs_core_config.hpp>
#include <srs_core_source.hpp>
#include <srs_core_autofree.hpp>
SrsHLS::SrsHLS() SrsHLS::SrsHLS()
{ {
@ -56,10 +58,10 @@ int SrsHLS::on_publish(std::string _vhost)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// TODO: check config.
if (muxer) { if (muxer) {
ret = ERROR_HLS_BUSY; hls_enabled = true;
srs_error("hls is busy, something error, " srs_trace("hls is reopen, continue streaming HLS, vhost=%s", _vhost.c_str());
"vhost=%s, ret=%d", _vhost.c_str(), ret);
return ret; return ret;
} }
@ -96,8 +98,8 @@ int SrsHLS::on_publish(std::string _vhost)
void SrsHLS::on_unpublish() void SrsHLS::on_unpublish()
{ {
hls_enabled = false; hls_enabled = false;
muxer->close(); //muxer->close();
srs_freep(muxer); //srs_freep(muxer);
} }
int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata) int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
@ -152,10 +154,12 @@ int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
return ret; return ret;
} }
int SrsHLS::on_audio(SrsCommonMessage* audio) int SrsHLS::on_audio(SrsSharedPtrMessage* audio)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsAutoFree(SrsSharedPtrMessage, audio, false);
sample->clear(); sample->clear();
if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) { if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {
return ret; return ret;
@ -175,20 +179,23 @@ int SrsHLS::on_audio(SrsCommonMessage* audio)
return ret; return ret;
} }
u_int32_t timestamp = audio->header.timestamp; if ((ret = jitter->correct(audio, 0, 0)) != ERROR_SUCCESS) {
// TODO: correct the timestamp. return ret;
}
if ((ret = muxer->write_audio(timestamp, codec, sample)) != ERROR_SUCCESS) { if ((ret = muxer->write_audio(audio->header.timestamp, codec, sample)) != ERROR_SUCCESS) {
return ret; return ret;
} }
return ret; return ret;
} }
int SrsHLS::on_video(SrsCommonMessage* video) int SrsHLS::on_video(SrsSharedPtrMessage* video)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
SrsAutoFree(SrsSharedPtrMessage, video, false);
sample->clear(); sample->clear();
if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) { if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) {
return ret; return ret;
@ -208,10 +215,11 @@ int SrsHLS::on_video(SrsCommonMessage* video)
return ret; return ret;
} }
u_int32_t timestamp = video->header.timestamp; if ((ret = jitter->correct(video, 0, 0)) != ERROR_SUCCESS) {
// TODO: correct the timestamp. return ret;
}
if ((ret = muxer->write_video(timestamp, codec, sample)) != ERROR_SUCCESS) { if ((ret = muxer->write_video(video->header.timestamp, codec, sample)) != ERROR_SUCCESS) {
return ret; return ret;
} }

View file

@ -32,7 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string> #include <string>
class SrsOnMetaDataPacket; class SrsOnMetaDataPacket;
class SrsCommonMessage; class SrsSharedPtrMessage;
class SrsCodecSample; class SrsCodecSample;
class SrsCodecBuffer; class SrsCodecBuffer;
class SrsMpegtsFrame; class SrsMpegtsFrame;
@ -56,8 +56,8 @@ public:
virtual int on_publish(std::string _vhost); virtual int on_publish(std::string _vhost);
virtual void on_unpublish(); virtual void on_unpublish();
virtual int on_meta_data(SrsOnMetaDataPacket* metadata); virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
virtual int on_audio(SrsCommonMessage* audio); virtual int on_audio(SrsSharedPtrMessage* audio);
virtual int on_video(SrsCommonMessage* video); virtual int on_video(SrsSharedPtrMessage* video);
}; };
class SrsTSMuxer class SrsTSMuxer

View file

@ -45,10 +45,13 @@ SrsRtmpJitter::~SrsRtmpJitter()
{ {
} }
int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int audio_sample_rate, int video_frame_rate) int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
int audio_sample_rate = tba;
int video_frame_rate = tbv;
/** /**
* we use a very simple time jitter detect/correct algorithm: * we use a very simple time jitter detect/correct algorithm:
* 1. delta: ensure the delta is positive and valid, * 1. delta: ensure the delta is positive and valid,
@ -117,11 +120,12 @@ int SrsConsumer::get_time()
return jitter->get_time(); return jitter->get_time();
} }
int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, int audio_sample_rate, int video_frame_rate) int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, int tba, int tbv)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = jitter->correct(msg, audio_sample_rate, video_frame_rate)) != ERROR_SUCCESS) { if ((ret = jitter->correct(msg, tba, tbv)) != ERROR_SUCCESS) {
srs_freep(msg);
return ret; return ret;
} }
@ -351,11 +355,6 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = hls->on_audio(audio)) != ERROR_SUCCESS) {
srs_error("hls process audio message failed. ret=%d", ret);
return ret;
}
SrsSharedPtrMessage* msg = new SrsSharedPtrMessage(); SrsSharedPtrMessage* msg = new SrsSharedPtrMessage();
SrsAutoFree(SrsSharedPtrMessage, msg, false); SrsAutoFree(SrsSharedPtrMessage, msg, false);
if ((ret = msg->initialize(audio, (char*)audio->payload, audio->size)) != ERROR_SUCCESS) { if ((ret = msg->initialize(audio, (char*)audio->payload, audio->size)) != ERROR_SUCCESS) {
@ -364,6 +363,11 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
} }
srs_verbose("initialize shared ptr audio success."); srs_verbose("initialize shared ptr audio success.");
if ((ret = hls->on_audio(msg->copy())) != ERROR_SUCCESS) {
srs_error("hls process audio message failed. ret=%d", ret);
return ret;
}
// detach the original audio // detach the original audio
audio->payload = NULL; audio->payload = NULL;
audio->size = 0; audio->size = 0;
@ -401,11 +405,6 @@ int SrsSource::on_video(SrsCommonMessage* video)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
if ((ret = hls->on_video(video)) != ERROR_SUCCESS) {
srs_error("hls process video message failed. ret=%d", ret);
return ret;
}
SrsSharedPtrMessage* msg = new SrsSharedPtrMessage(); SrsSharedPtrMessage* msg = new SrsSharedPtrMessage();
SrsAutoFree(SrsSharedPtrMessage, msg, false); SrsAutoFree(SrsSharedPtrMessage, msg, false);
if ((ret = msg->initialize(video, (char*)video->payload, video->size)) != ERROR_SUCCESS) { if ((ret = msg->initialize(video, (char*)video->payload, video->size)) != ERROR_SUCCESS) {
@ -414,6 +413,11 @@ int SrsSource::on_video(SrsCommonMessage* video)
} }
srs_verbose("initialize shared ptr video success."); srs_verbose("initialize shared ptr video success.");
if ((ret = hls->on_video(msg->copy())) != ERROR_SUCCESS) {
srs_error("hls process video message failed. ret=%d", ret);
return ret;
}
// detach the original audio // detach the original audio
video->payload = NULL; video->payload = NULL;
video->size = 0; video->size = 0;

View file

@ -56,7 +56,7 @@ public:
/** /**
* detect the time jitter and correct it. * detect the time jitter and correct it.
*/ */
virtual int correct(SrsSharedPtrMessage* msg, int audio_sample_rate, int video_frame_rate); virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv);
/** /**
* get current client time, the last packet time. * get current client time, the last packet time.
*/ */
@ -83,10 +83,12 @@ public:
virtual int get_time(); virtual int get_time();
/** /**
* enqueue an shared ptr message. * enqueue an shared ptr message.
* @param audio_sample_rate used to calc the audio time delta if time-jitter detected. * @param tba timebase of audio.
* @param video_frame_rate used to calc the video time delta if time-jitter detected. * used to calc the audio time delta if time-jitter detected.
* @param tbv timebase of video.
* used to calc the video time delta if time-jitter detected.
*/ */
virtual int enqueue(SrsSharedPtrMessage* msg, int audio_sample_rate, int video_frame_rate); virtual int enqueue(SrsSharedPtrMessage* msg, int tba, int tbv);
/** /**
* get packets in consumer queue. * get packets in consumer queue.
* @pmsgs SrsMessages*[], output the prt array. * @pmsgs SrsMessages*[], output the prt array.