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

For #299, refine code.

This commit is contained in:
winlin 2017-03-25 17:21:39 +08:00
parent 62b7204514
commit f32aab3d92
175 changed files with 15529 additions and 15935 deletions

View file

@ -1,25 +1,25 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2017 SRS(ossrs)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 SRS(ossrs)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_app_mpegts_udp.hpp>
@ -70,33 +70,33 @@ SrsMpegtsQueue::~SrsMpegtsQueue()
int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg)
{
int ret = ERROR_SUCCESS;
// TODO: FIXME: use right way.
for (int i = 0; i < 10; i++) {
if (msgs.find(msg->timestamp) == msgs.end()) {
break;
}
// adjust the ts, add 1ms.
msg->timestamp += 1;
if (i >= 5) {
srs_warn("mpegts: free the msg for dts exists, dts=%"PRId64, msg->timestamp);
srs_freep(msg);
return ret;
}
}
if (msg->is_audio()) {
nb_audios++;
}
if (msg->is_video()) {
nb_videos++;
}
msgs[msg->timestamp] = msg;
return ret;
}
@ -106,23 +106,23 @@ SrsSharedPtrMessage* SrsMpegtsQueue::dequeue()
bool av_ok = nb_videos >= 2 && nb_audios >= 2;
// 100 videos about 30s, while 300 audios about 30s
bool av_overflow = nb_videos > 100 || nb_audios > 300;
if (av_ok || av_overflow) {
std::map<int64_t, SrsSharedPtrMessage*>::iterator it = msgs.begin();
SrsSharedPtrMessage* msg = it->second;
msgs.erase(it);
if (msg->is_audio()) {
nb_audios--;
}
if (msg->is_video()) {
nb_videos--;
}
return msg;
}
return NULL;
}
@ -147,7 +147,7 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c)
SrsMpegtsOverUdp::~SrsMpegtsOverUdp()
{
close();
srs_freep(buffer);
srs_freep(stream);
srs_freep(context);
@ -161,20 +161,20 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
{
std::string peer_ip = inet_ntoa(from->sin_addr);
int peer_port = ntohs(from->sin_port);
// append to buffer.
buffer->append(buf, nb_buf);
srs_info("udp: got %s:%d packet %d/%d bytes",
peer_ip.c_str(), peer_port, nb_buf, buffer->length());
peer_ip.c_str(), peer_port, nb_buf, buffer->length());
return on_udp_bytes(peer_ip, peer_port, buf, nb_buf);
}
int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
{
int ret = ERROR_SUCCESS;
// collect nMB data to parse in a time.
// TODO: FIXME: comment the following for release.
//if (buffer->length() < 3 * 1024 * 1024) return ret;
@ -204,26 +204,26 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
fr.close();
buffer->append(fbuf, nb_fbuf);
#endif
// find the sync byte of mpegts.
char* p = buffer->bytes();
for (int i = 0; i < buffer->length(); i++) {
if (p[i] != 0x47) {
continue;
}
if (i > 0) {
buffer->erase(i);
}
break;
}
// drop ts packet when size not modulus by 188
if (buffer->length() < SRS_TS_PACKET_SIZE) {
srs_warn("udp: wait %s:%d packet %d/%d bytes", host.c_str(), port, nb_buf, buffer->length());
return ret;
}
// use stream to parse ts packet.
int nb_packet = buffer->length() / SRS_TS_PACKET_SIZE;
for (int i = 0; i < nb_packet; i++) {
@ -231,7 +231,7 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
if ((ret = stream->initialize(p, SRS_TS_PACKET_SIZE)) != ERROR_SUCCESS) {
return ret;
}
// process each ts packet
if ((ret = context->decode(stream, this)) != ERROR_SUCCESS) {
srs_warn("mpegts: ignore parse ts packet failed. ret=%d", ret);
@ -240,28 +240,28 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
srs_info("mpegts: parse ts packet completed");
}
srs_info("mpegts: parse udp packet completed");
// erase consumed bytes
if (nb_packet > 0) {
buffer->erase(nb_packet * SRS_TS_PACKET_SIZE);
}
return ret;
}
int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
{
int ret = ERROR_SUCCESS;
pprint->elapse();
// about the bytes of msg, specified by elementary stream which indicates by PES_packet_data_byte and stream_id
// for example, when SrsTsStream of SrsTsChannel indicates stream_type is SrsTsStreamVideoMpeg4 and SrsTsStreamAudioMpeg4,
// the elementary stream can be mux in "2.11 Carriage of ISO/IEC 14496 data" in hls-mpeg-ts-iso13818-1.pdf, page 103
// @remark, the most popular stream_id is 0xe0 for h.264 over mpegts, which indicates the stream_id is video and
// @remark, the most popular stream_id is 0xe0 for h.264 over mpegts, which indicates the stream_id is video and
// stream_number is 0, where I guess the elementary is specified in annexb format(ISO_IEC_14496-10-AVC-2003.pdf, page 211).
// because when audio stream_number is 0, the elementary is ADTS(ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS).
// about the bytes of PES_packet_data_byte, defined in hls-mpeg-ts-iso13818-1.pdf, page 58
// PES_packet_data_byte "C PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream
// indicated by the packets stream_id or PID. When the elementary stream data conforms to ITU-T
@ -270,33 +270,33 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
// PES_packet_data_bytes, N, is specified by the PES_packet_length field. N shall be equal to the value indicated in the
// PES_packet_length minus the number of bytes between the last byte of the PES_packet_length field and the first
// PES_packet_data_byte.
//
//
// In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the
// PES_packet_data_byte field are user definable and will not be specified by ITU-T | ISO/IEC in the future.
// about the bytes of stream_id, define in hls-mpeg-ts-iso13818-1.pdf, page 49
// stream_id "C In Program Streams, the stream_id specifies the type and number of the elementary stream as defined by the
// stream_id Table 2-18. In Transport Streams, the stream_id may be set to any valid value which correctly describes the
// elementary stream type as defined in Table 2-18. In Transport Streams, the elementary stream type is specified in the
// Program Specific Information as specified in 2.4.4.
// about the stream_id table, define in Table 2-18 "C Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52.
//
//
// 110x xxxx
// ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
// 14496-3 audio stream number x xxxx
// ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio
//
//
// 1110 xxxx
// ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
// 14496-2 video stream number xxxx
// ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo
if (pprint->can_print()) {
srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" mpegts: got %s age=%d stream=%s, dts=%"PRId64", pts=%"PRId64", size=%d, us=%d, cc=%d, sid=%#x(%s-%d)",
(msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", pprint->age(), srs_ts_stream2string(msg->channel->stream).c_str(),
msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid,
msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());
(msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", pprint->age(), srs_ts_stream2string(msg->channel->stream).c_str(),
msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid,
msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number());
}
// When the audio SID is private stream 1, we use common audio.
@ -304,29 +304,29 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
if (msg->channel->apply == SrsTsPidApplyAudio && msg->sid == SrsTsPESStreamIdPrivateStream1) {
msg->sid = SrsTsPESStreamIdAudioCommon;
}
// when not audio/video, or not adts/annexb format, donot support.
if (msg->stream_number() != 0) {
ret = ERROR_STREAM_CASTER_TS_ES;
srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d",
msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret);
srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d",
msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret);
return ret;
}
// check supported codec
if (msg->channel->stream != SrsTsStreamVideoH264 && msg->channel->stream != SrsTsStreamAudioAAC) {
ret = ERROR_STREAM_CASTER_TS_CODEC;
srs_error("mpegts: unsupported stream codec=%d. ret=%d", msg->channel->stream, ret);
return ret;
}
// parse the stream.
SrsBuffer avs;
if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) {
srs_error("mpegts: initialize av stream failed. ret=%d", ret);
return ret;
}
// publish audio or video.
if (msg->channel->stream == SrsTsStreamVideoH264) {
return on_ts_video(msg, &avs);
@ -334,7 +334,7 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
if (msg->channel->stream == SrsTsStreamAudioAAC) {
return on_ts_audio(msg, &avs);
}
// TODO: FIXME: implements it.
return ret;
}
@ -342,12 +342,12 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg)
int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs)
{
int ret = ERROR_SUCCESS;
// ensure rtmp connected.
if ((ret = connect()) != ERROR_SUCCESS) {
return ret;
}
// ts tbn to flv tbn.
uint32_t dts = (uint32_t)(msg->dts / 90);
uint32_t pts = (uint32_t)(msg->dts / 90);
@ -369,39 +369,39 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs)
if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
continue;
}
// for sps
if (avc->is_sps(frame, frame_size)) {
std::string sps;
if ((ret = avc->sps_demux(frame, frame_size, sps)) != ERROR_SUCCESS) {
return ret;
}
if (h264_sps == sps) {
continue;
}
h264_sps_changed = true;
h264_sps = sps;
if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {
return ret;
}
continue;
}
// for pps
if (avc->is_pps(frame, frame_size)) {
std::string pps;
if ((ret = avc->pps_demux(frame, frame_size, pps)) != ERROR_SUCCESS) {
return ret;
}
if (h264_pps == pps) {
continue;
}
h264_pps_changed = true;
h264_pps = pps;
if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) {
return ret;
}
@ -456,11 +456,11 @@ int SrsMpegtsOverUdp::write_h264_sps_pps(uint32_t dts, uint32_t pts)
h264_sps_changed = false;
h264_pps_changed = false;
h264_sps_pps_sent = true;
return ret;
}
int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts)
int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts)
{
int ret = ERROR_SUCCESS;
@ -480,7 +480,7 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t
if (nal_unit_type == SrsAvcNaluTypeIDR) {
frame_type = SrsVideoAvcFrameTypeKeyFrame;
}
std::string ibp;
if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) {
return ret;
@ -501,12 +501,12 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t
int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs)
{
int ret = ERROR_SUCCESS;
// ensure rtmp connected.
if ((ret = connect()) != ERROR_SUCCESS) {
return ret;
}
// ts tbn to flv tbn.
uint32_t dts = (uint32_t)(msg->dts / 90);
@ -518,14 +518,14 @@ int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs)
if ((ret = aac->adts_demux(avs, &frame, &frame_size, codec)) != ERROR_SUCCESS) {
return ret;
}
// ignore invalid frame,
// * atleast 1bytes for aac to decode the data.
if (frame_size <= 0) {
continue;
}
srs_info("mpegts: demux aac frame size=%d, dts=%d", frame_size, dts);
// generate sh.
if (aac_specific_config.empty()) {
std::string sh;
@ -533,28 +533,28 @@ int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs)
return ret;
}
aac_specific_config = sh;
codec.aac_packet_type = 0;
if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), &codec, dts)) != ERROR_SUCCESS) {
return ret;
}
}
// audio raw data.
codec.aac_packet_type = 1;
if ((ret = write_audio_raw_frame(frame, frame_size, &codec, dts)) != ERROR_SUCCESS) {
return ret;
}
}
return ret;
}
int SrsMpegtsOverUdp::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts)
{
int ret = ERROR_SUCCESS;
char* data = NULL;
int size = 0;
if ((ret = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) {
@ -579,24 +579,24 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, uint32_t timestamp, char* dat
return ret;
}
srs_assert(msg);
// push msg to queue.
if ((ret = queue->push(msg)) != ERROR_SUCCESS) {
srs_error("mpegts: push msg to queue failed. ret=%d", ret);
return ret;
}
// for all ready msg, dequeue and send out.
for (;;) {
if ((msg = queue->dequeue()) == NULL) {
break;
}
if (pprint->can_print()) {
srs_trace("mpegts: send msg %s age=%d, dts=%"PRId64", size=%d",
msg->is_audio()? "A":msg->is_video()? "V":"N", pprint->age(), msg->timestamp, msg->size);
msg->is_audio()? "A":msg->is_video()? "V":"N", pprint->age(), msg->timestamp, msg->size);
}
// send out encoded msg.
if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) {
close();
@ -610,7 +610,7 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, uint32_t timestamp, char* dat
int SrsMpegtsOverUdp::connect()
{
int ret = ERROR_SUCCESS;
// Ignore when connected.
if (sdk) {
return ret;
@ -631,7 +631,7 @@ int SrsMpegtsOverUdp::connect()
srs_error("mpegts: publish failed. ret=%d", ret);
return ret;
}
return ret;
}