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:
parent
62b7204514
commit
f32aab3d92
175 changed files with 15529 additions and 15935 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue