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:
parent
326713fbed
commit
749b7bdb2a
5 changed files with 48 additions and 34 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue