1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-14 20:31:56 +00:00

merge from 2.0.159

This commit is contained in:
winlin 2015-04-09 12:35:53 +08:00
commit 71e1602458
9 changed files with 91 additions and 29 deletions

View file

@ -566,6 +566,7 @@ Supported operating systems and hardware:
### SRS 2.0 history
* v2.0, 2015-04-08, for [#375](https://github.com/winlinvip/simple-rtmp-server/issues/375), fix hls bug, keep cc continous between ts files. 2.0.159.
* v2.0, 2015-04-04, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite annexb mux for ts, refer to apple sample. 2.0.157.
* v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156.
* v2.0, 2015-04-03, for [#372](https://github.com/winlinvip/simple-rtmp-server/issues/372), support transform vhost of edge 2.0.155.

View file

@ -127,6 +127,12 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
return ret;
}
if (!srs_utils_flv_tag_is_ok(type)) {
srs_human_trace("ignore invalid flv tag=%d, dts=%d, %d bytes", type, timestamp, size);
free(data);
continue;
}
if ((ret = srs_human_print_rtmp_packet(type, timestamp, data, size)) != 0) {
srs_human_trace("print packet failed. ret=%d", ret);
return ret;

View file

@ -3093,7 +3093,7 @@ bool SrsConfig::get_log_tank_file()
SrsConfDirective* conf = root->get("srs_log_tank");
if (!conf || conf->arg0().empty()) {
return false;
return true;
}
return conf->arg0() != SRS_CONF_DEFAULT_LOG_TANK_CONSOLE;

View file

@ -138,14 +138,14 @@ string SrsHlsCacheWriter::cache()
return data;
}
SrsHlsSegment::SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac, SrsCodecVideo vc)
SrsHlsSegment::SrsHlsSegment(SrsTsContext* c, bool write_cache, bool write_file, SrsCodecAudio ac, SrsCodecVideo vc)
{
duration = 0;
sequence_no = 0;
segment_start_dts = 0;
is_sequence_header = false;
writer = new SrsHlsCacheWriter(write_cache, write_file);
muxer = new SrsTSMuxer(writer, ac, vc);
muxer = new SrsTSMuxer(writer, c, ac, vc);
}
SrsHlsSegment::~SrsHlsSegment()
@ -236,6 +236,7 @@ SrsHlsMuxer::SrsHlsMuxer()
should_write_cache = false;
should_write_file = true;
async = new SrsDvrAsyncCallThread();
context = new SrsTsContext();
}
SrsHlsMuxer::~SrsHlsMuxer()
@ -250,6 +251,7 @@ SrsHlsMuxer::~SrsHlsMuxer()
srs_freep(current);
srs_freep(req);
srs_freep(async);
srs_freep(context);
}
int SrsHlsMuxer::sequence_no()
@ -269,11 +271,21 @@ double SrsHlsMuxer::duration()
double SrsHlsMuxer::deviation()
{
// no floor, no deviation.
if (!hls_ts_floor) {
return 0;
}
return hls_fragment_deviation;
}
int SrsHlsMuxer::absolute_deviation()
{
// no floor, no deviation.
if (!hls_ts_floor) {
return 0;
}
// accept the floor ts for the first piece.
int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment));
return (int)(accept_floor_ts - (floor_ts - 1));
@ -391,7 +403,7 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
}
// new segment.
current = new SrsHlsSegment(should_write_cache, should_write_file, default_acodec, default_vcodec);
current = new SrsHlsSegment(context, should_write_cache, should_write_file, default_acodec, default_vcodec);
current->sequence_no = _sequence_no++;
current->segment_start_dts = segment_start_dts;

View file

@ -56,6 +56,7 @@ class SrsTsAacJitter;
class SrsTsCache;
class SrsHlsSegment;
class SrsTsCache;
class SrsTsContext;
/**
* the handler for hls event.
@ -145,7 +146,7 @@ public:
// whether current segement is sequence header.
bool is_sequence_header;
public:
SrsHlsSegment(bool write_cache, bool write_file, SrsCodecAudio ac, SrsCodecVideo vc);
SrsHlsSegment(SrsTsContext* c, bool write_cache, bool write_file, SrsCodecAudio ac, SrsCodecVideo vc);
virtual ~SrsHlsSegment();
public:
/**
@ -229,6 +230,11 @@ private:
* @see https://github.com/winlinvip/simple-rtmp-server/issues/301
*/
SrsCodecAudio acodec;
/**
* the ts context, to keep cc continous between ts.
* @see https://github.com/winlinvip/simple-rtmp-server/issues/375
*/
SrsTsContext* context;
public:
SrsHlsMuxer();
virtual ~SrsHlsMuxer();

View file

@ -51,10 +51,10 @@ using namespace std;
// the mpegts header specifed the video/audio pid.
#define TS_PMT_NUMBER 1
#define TS_PMT_PID 0x100
#define TS_VIDEO_AVC_PID 0x101
#define TS_AUDIO_AAC_PID 0x102
#define TS_AUDIO_MP3_PID 0x103
#define TS_PMT_PID 0x1001
#define TS_VIDEO_AVC_PID 0x100
#define TS_AUDIO_AAC_PID 0x101
#define TS_AUDIO_MP3_PID 0x102
string srs_ts_stream2string(SrsTsStream stream)
{
@ -95,6 +95,7 @@ SrsTsMessage::SrsTsMessage(SrsTsChannel* c, SrsTsPacket* p)
continuity_counter = 0;
PES_packet_length = 0;
payload = new SrsSimpleBuffer();
is_discontinuity = false;
start_pts = 0;
write_pcr = false;
@ -192,6 +193,12 @@ SrsTsContext::~SrsTsContext()
pids.clear();
}
void SrsTsContext::reset()
{
vcodec = SrsCodecVideoReserved;
acodec = SrsCodecAudioReserved1;
}
SrsTsChannel* SrsTsContext::get(int pid)
{
if (pids.find(pid) == pids.end()) {
@ -251,7 +258,7 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsCodecVideo
int ret = ERROR_SUCCESS;
SrsTsStream vs, as;
int16_t video_pid, audio_pid;
int16_t video_pid = 0, audio_pid = 0;
switch (vc) {
case SrsCodecVideoAVC:
vs = SrsTsStreamVideoH264;
@ -401,9 +408,14 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p
write_pcr = true;
}
// it's ok to set pcr equals to dts,
// @see https://github.com/winlinvip/simple-rtmp-server/issues/311
int64_t pcr = write_pcr? msg->dts : -1;
// TODO: FIXME: finger it why use discontinuity of msg.
pkt = SrsTsPacket::create_pes_first(this,
pid, msg->sid, channel->continuity_counter++, msg->discontinuity,
write_pcr? msg->dts:-1, msg->dts, msg->pts, msg->payload->length()
pid, msg->sid, channel->continuity_counter++, msg->is_discontinuity,
pcr, msg->dts, msg->pts, msg->payload->length()
);
} else {
pkt = SrsTsPacket::create_pes_continue(this,
@ -419,7 +431,7 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p
int nb_buf = pkt->size();
srs_assert(nb_buf < SRS_TS_PACKET_SIZE);
int left = srs_min(end - p, SRS_TS_PACKET_SIZE - nb_buf);
int left = (int)srs_min(end - p, SRS_TS_PACKET_SIZE - nb_buf);
int nb_stuffings = SRS_TS_PACKET_SIZE - nb_buf - left;
if (nb_stuffings > 0) {
// set all bytes to stuffings.
@ -432,7 +444,7 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p
nb_buf = pkt->size();
srs_assert(nb_buf < SRS_TS_PACKET_SIZE);
left = srs_min(end - p, SRS_TS_PACKET_SIZE - nb_buf);
left = (int)srs_min(end - p, SRS_TS_PACKET_SIZE - nb_buf);
nb_stuffings = SRS_TS_PACKET_SIZE - nb_buf - left;
srs_assert(nb_stuffings == 0);
}
@ -703,13 +715,18 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number,
pmt->section_number = 0;
pmt->last_section_number = 0;
pmt->program_info_length = 0;
// use audio to carray pcr by default.
// for hls, there must be atleast one audio channel.
pmt->PCR_PID = apid;
pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid));
// if h.264 specified, use video to carry pcr.
if (vs == SrsTsStreamVideoH264) {
pmt->PCR_PID = vpid;
pmt->infos.push_back(new SrsTsPayloadPMTESInfo(vs, vpid));
} else {
pmt->PCR_PID = apid;
}
pmt->infos.push_back(new SrsTsPayloadPMTESInfo(as, apid));
pmt->CRC_32 = 0; // calc in encode.
return pkt;
}
@ -2604,10 +2621,10 @@ int SrsTsPayloadPMT::psi_encode(SrsStream* stream)
return ret;
}
SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac, SrsCodecVideo vc)
SrsTSMuxer::SrsTSMuxer(SrsFileWriter* w, SrsTsContext* c, SrsCodecAudio ac, SrsCodecVideo vc)
{
writer = w;
context = NULL;
context = c;
acodec = ac;
vcodec = vc;
@ -2625,10 +2642,9 @@ int SrsTSMuxer::open(string _path)
path = _path;
close();
// use context to write ts file.
srs_freep(context);
context = new SrsTsContext();
// reset the context for a new ts start.
context->reset();
if ((ret = writer->open(path)) != ERROR_SUCCESS) {
return ret;
@ -2677,7 +2693,6 @@ int SrsTSMuxer::write_video(SrsTsMessage* video)
void SrsTSMuxer::close()
{
srs_freep(context);
writer->close();
}
@ -2911,6 +2926,8 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
// 9, SI (SI slice)
// H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 105.
static u_int8_t aud_nalu_7[] = { 0x09, 0xf0};
// always append a aud nalu for each frame.
video->payload->append((const char*)fresh_nalu_header, 4);
video->payload->append((const char*)aud_nalu_7, 2);
@ -2973,6 +2990,7 @@ SrsTsEncoder::SrsTsEncoder()
codec = new SrsAvcAacCodec();
sample = new SrsCodecSample();
cache = new SrsTsCache();
context = new SrsTsContext();
muxer = NULL;
}
@ -2982,6 +3000,7 @@ SrsTsEncoder::~SrsTsEncoder()
srs_freep(sample);
srs_freep(cache);
srs_freep(muxer);
srs_freep(context);
}
int SrsTsEncoder::initialize(SrsFileWriter* fs)
@ -2999,7 +3018,7 @@ int SrsTsEncoder::initialize(SrsFileWriter* fs)
_fs = fs;
srs_freep(muxer);
muxer = new SrsTSMuxer(fs, SrsCodecAudioAAC, SrsCodecVideoAVC);
muxer = new SrsTSMuxer(fs, context, SrsCodecAudioAAC, SrsCodecVideoAVC);
if ((ret = muxer->open("")) != ERROR_SUCCESS) {
return ret;

View file

@ -47,6 +47,7 @@ class SrsTsAdaptationField;
class SrsTsPayload;
class SrsTsMessage;
class SrsTsPacket;
class SrsTsContext;
// Transport Stream packets are 188 bytes in length.
#define SRS_TS_PACKET_SIZE 188
@ -258,7 +259,7 @@ public:
// generally, the video IDR(I frame, the keyframe of h.264) carray the pcr info.
bool write_pcr;
// whether got discontinuity ts, for example, sequence header changed.
bool discontinuity;
bool is_discontinuity;
public:
// the timestamp in 90khz
int64_t dts;
@ -343,6 +344,11 @@ private:
public:
SrsTsContext();
virtual ~SrsTsContext();
public:
/**
* reset the context for a new ts segment start.
*/
virtual void reset();
// codec
public:
/**
@ -1533,7 +1539,7 @@ private:
SrsFileWriter* writer;
std::string path;
public:
SrsTSMuxer(SrsFileWriter* w, SrsCodecAudio ac, SrsCodecVideo vc);
SrsTSMuxer(SrsFileWriter* w, SrsTsContext* c, SrsCodecAudio ac, SrsCodecVideo vc);
virtual ~SrsTSMuxer();
public:
/**
@ -1608,6 +1614,7 @@ private:
SrsCodecSample* sample;
SrsTsCache* cache;
SrsTSMuxer* muxer;
SrsTsContext* context;
public:
SrsTsEncoder();
virtual ~SrsTsEncoder();

View file

@ -1973,6 +1973,11 @@ int srs_utils_parse_timestamp(
return ret;
}
srs_bool srs_utils_flv_tag_is_ok(char type)
{
return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT;
}
char srs_utils_flv_video_codec_id(char* data, int size)
{
@ -2324,7 +2329,7 @@ int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int
);
} else if (type == SRS_RTMP_TYPE_SCRIPT) {
srs_human_verbose("Data packet type=%s, time=%d, size=%d",
srs_human_flv_tag_type2string(type), timestamp, size);
srs_human_flv_tag_type2string(type), timestamp, size);
int nparsed = 0;
while (nparsed < size) {
int nb_parsed_this = 0;
@ -2332,7 +2337,7 @@ int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int
if (amf0 == NULL) {
break;
}
nparsed += nb_parsed_this;
char* amf0_str = NULL;

View file

@ -655,6 +655,12 @@ extern int srs_utils_parse_timestamp(
u_int32_t time, char type, char* data, int size,
u_int32_t* ppts
);
/**
* whether the flv tag specified by param type is ok.
* @return true when tag is video/audio/script-data; otherwise, false.
*/
extern srs_bool srs_utils_flv_tag_is_ok(char type);
/**
* get the CodecID of video tag.