From da72caf8b9e4b5a3fb5b944ad9f869bab37228f9 Mon Sep 17 00:00:00 2001 From: HuyaJohn Date: Wed, 11 Mar 2020 04:21:44 -0700 Subject: [PATCH] h264 packet done, chrome play well --- trunk/src/app/srs_app_rtc_conn.cpp | 129 ++++++++----- trunk/src/app/srs_app_rtp.cpp | 274 ++++------------------------ trunk/src/app/srs_app_rtp.hpp | 21 ++- trunk/src/app/srs_app_utility.cpp | 34 ++++ trunk/src/app/srs_app_utility.hpp | 4 + trunk/src/kernel/srs_kernel_flv.cpp | 4 +- 6 files changed, 169 insertions(+), 297 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index af9fad322..a92a2b5f8 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -30,6 +30,8 @@ using namespace std; #include #include +#include +#include #include @@ -41,7 +43,9 @@ using namespace std; #include #include #include +#include #include +#include #include #include #include @@ -77,42 +81,6 @@ static string gen_random_str(int len) const int SRTP_MASTER_KEY_KEY_LEN = 16; const int SRTP_MASTER_KEY_SALT_LEN = 14; -static string dump_string_hex(const char* buf, const int nb_buf, const int& max_len); -static string dump_string_hex(const std::string& str, const int& max_len = 128) -{ - return dump_string_hex(str.c_str(), str.size(), max_len); -} - -static string dump_string_hex(const char* buf, const int nb_buf, const int& max_len = 128) -{ - string ret; - ret.reserve(max_len * 4); - - char tmp_buf[1024*16]; - tmp_buf[0] = '\n'; - int len = 1; - - for (int i = 0; i < nb_buf && i < max_len; ++i) { - //int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "(%03d)%02X ", i, (uint8_t)buf[i]); - int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "%02X ", (uint8_t)buf[i]); - if (nb <= 0) - break; - - len += nb; - - if (i % 48 == 47) { - tmp_buf[len++] = '\n'; - ret.append(tmp_buf, len); - len = 0; - } - } - tmp_buf[len] = '\0'; - ret.append(tmp_buf, len); - - return ret; - -} - SrsCandidate::SrsCandidate() { } @@ -654,14 +622,10 @@ srs_error_t SrsRtcSenderThread::cycle() SrsSharedPtrMessage* msg = msgs.msgs[i]; for (int i = 0; i < msg->nb_rtp_fragments; ++i) { - srs_trace("rtp fragment size=%d, payload=%s", msg->rtp_fragments[i].size, - dump_string_hex(msg->rtp_fragments[i].bytes, msg->rtp_fragments[i].size, 1460).c_str()); - SrsBuffer stream(msg->rtp_fragments[i].bytes + 2, 2); - static uint16_t seq = 0; - stream.write_2bytes(++seq); - - srs_trace("seq=%u", seq); + uint16_t seq = stream.read_2bytes(); + srs_trace("rtp fragment size=%d, seq=%u, payload=%s", msg->rtp_fragments[i].size, seq, + dump_string_hex(msg->rtp_fragments[i].bytes, msg->rtp_fragments[i].size, 1460).c_str()); if (rtc_session->dtls_session) { char rtp_send_protected_buf[1500]; @@ -670,6 +634,8 @@ srs_error_t SrsRtcSenderThread::cycle() ukt.sendto(rtp_send_protected_buf, rtp_send_protected_len, 0); } } + + srs_freep(msg); } srs_usleep(16000); @@ -778,27 +744,40 @@ srs_error_t SrsRtcSession::on_rtp_or_rtcp(SrsUdpRemuxSocket* udp_remux_socket) return srs_error_wrap(err, "recv unexpect rtp/rtcp packet before dtls done"); } + uint8_t payload_type = udp_remux_socket->data()[1] & 0x7F; + char srtp_unprotect_buf[1460]; int nb_srtp_unprotect_buf = udp_remux_socket->size(); if (dtls_session->srtp_receiver_unprotect(srtp_unprotect_buf, udp_remux_socket->data(), nb_srtp_unprotect_buf) != srs_success) { - return srs_error_wrap(err, "srtp receiver unprotect failed"); + return srs_error_wrap(err, "srtp receiver unprotect failed, payload_type=%u", payload_type); } //srs_trace("srtp unprotect success, %s", dump_string_hex(srtp_unprotect_buf, nb_srtp_unprotect_buf, nb_srtp_unprotect_buf).c_str()); SrsBuffer* stream = new SrsBuffer(srtp_unprotect_buf, nb_srtp_unprotect_buf); + SrsAutoFree(SrsBuffer, stream); uint8_t first = stream->read_1bytes(); uint8_t second = stream->read_1bytes(); - bool marker = (second & 0x80) == 0x80; - uint8_t payload_type = second &0x7F; + + bool padding = (first & 0x20); + bool ext = (first & 0x10); + uint8_t cc = (first & 0x0F); + + bool marker = (second & 0x80); uint16_t sequence = stream->read_2bytes(); uint32_t timestamp = stream->read_4bytes(); uint32_t ssrc = stream->read_4bytes(); - srs_trace("sequence=%u, timestamp=%u, ssrc=%u, marker=%d, payload_type=%u", sequence, timestamp, ssrc, marker, payload_type); + srs_trace("sequence=%u, timestamp=%u, ssrc=%u, padding=%d, ext=%d, cc=%u, marker=%d, payload_type=%u", + sequence, timestamp, ssrc, padding, ext, cc, marker, payload_type); - if (first & 0x10) { + for (uint8_t i = 0; i < cc; ++i) { + uint32_t csrc = 0; + csrc = stream->read_4bytes(); + } + + if (ext) { uint16_t extern_profile = stream->read_2bytes(); uint16_t extern_length = stream->read_2bytes(); @@ -807,6 +786,58 @@ srs_error_t SrsRtcSession::on_rtp_or_rtcp(SrsUdpRemuxSocket* udp_remux_socket) stream->read_string(extern_length * 4); } + if (payload_type == 102) { + static uint32_t pre_seq = 0; + uint32_t seq = sequence; + + srs_assert(pre_seq == 0 || (pre_seq + 1 == seq)); + + pre_seq = seq; + + static uint8_t start_code[4] = {0x00, 0x00, 0x00, 0x01}; + static int fd = -1; + if (fd < 0) { + fd = open("rtc.264", O_CREAT|O_TRUNC|O_RDWR, 0664); + } + + const uint8_t* p = (const uint8_t*)stream->data() + stream->pos(); + int len = stream->left(); + uint8_t header = p[0]; + uint8_t nal_type = header & kNalTypeMask; + + srs_trace("nal_type=%u, seq=%u, rtp payload, %s", nal_type, sequence, dump_string_hex(stream->data() + stream->pos(), stream->left(), stream->left()).c_str()); + + if (nal_type >=1 && nal_type <= 23) { + srs_trace("single nalu"); + write(fd, start_code, sizeof(start_code)); + write(fd, p, len); + } else if (nal_type == kFuA) { + srs_trace("FuA"); + if (p[1] & 0x80) { + uint8_t nal_type = ((p[0] & (~kNalTypeMask)) | (p[1] & kNalTypeMask)); + write(fd, start_code, sizeof(start_code)); + write(fd, &nal_type, 1); + write(fd, p + 2, len - 2); + } else { + write(fd, p + 2, len - 2); + } + } else if (nal_type == kStapA) { + srs_trace("StapA"); + int pos = 1; + while (pos < len) { + int nal_len = p[pos] << 8 | p[pos + 1]; + srs_trace("nal_len=%d", nal_len); + write(fd, start_code, sizeof(start_code)); + write(fd, p + pos + 2, nal_len); + pos += nal_len + 2; + } + srs_assert(pos == len); + } else { + srs_assert(false); + } + } + + // XXX:send h264 back to client, for debug if (payload_type == 102) { char rtp_send_protected_buf[1500]; int rtp_send_protected_len = nb_srtp_unprotect_buf; @@ -816,8 +847,6 @@ srs_error_t SrsRtcSession::on_rtp_or_rtcp(SrsUdpRemuxSocket* udp_remux_socket) udp_remux_socket->sendto(rtp_send_protected_buf, rtp_send_protected_len, 0); } - srs_trace("rtp payload, %s", dump_string_hex(stream->data() + stream->pos(), stream->left(), stream->left()).c_str()); - return err; } diff --git a/trunk/src/app/srs_app_rtp.cpp b/trunk/src/app/srs_app_rtp.cpp index 3a00d3d34..dafdbd0b8 100644 --- a/trunk/src/app/srs_app_rtp.cpp +++ b/trunk/src/app/srs_app_rtp.cpp @@ -50,42 +50,6 @@ using namespace std; #include #include -static string dump_string_hex(const char* buf, const int nb_buf, const int& max_len); -static string dump_string_hex(const std::string& str, const int& max_len = 128) -{ - return dump_string_hex(str.c_str(), str.size(), max_len); -} - -static string dump_string_hex(const char* buf, const int nb_buf, const int& max_len = 128) -{ - string ret; - ret.reserve(max_len * 4); - - char tmp_buf[1024*16]; - tmp_buf[0] = '\n'; - int len = 1; - - for (int i = 0; i < nb_buf && i < max_len; ++i) { - //int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "(%03d)%02X ", i, (uint8_t)buf[i]); - int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "%02X ", (uint8_t)buf[i]); - if (nb <= 0) - break; - - len += nb; - - if (i % 48 == 47) { - tmp_buf[len++] = '\n'; - ret.append(tmp_buf, len); - len = 0; - } - } - tmp_buf[len] = '\0'; - ret.append(tmp_buf, len); - - return ret; -} - - SrsRtpMuxer::SrsRtpMuxer() { sequence = 0; @@ -95,182 +59,6 @@ SrsRtpMuxer::~SrsRtpMuxer() { } -#if 0 -srs_error_t SrsRtpMuxer::frame_to_packet(SrsSharedPtrMessage* shared_frame, SrsFormat* format) -{ - srs_error_t err = srs_success; - - int nb_samples = format->video->nb_samples; - SrsSample* samples = format->video->samples; - - SrsSample* rtp_fragment_samples = new SrsSample[2000]; - int rtp_fragment_samples_index = 0; - - static int debug_fd = -1; - static uint8_t start_code[4] = {0x00, 0x00, 0x00, 0x01}; - if (debug_fd < 0) { - debug_fd = open("./raw.264", O_CREAT|O_TRUNC|O_RDWR, 0664); - } - - SrsSample sps_pps_samples[2]; - if (format->is_avc_sequence_header()) { - sps_pps_samples[0].bytes = format->vcodec->sequenceParameterSetNALUnit.data(); - sps_pps_samples[0].size = format->vcodec->sequenceParameterSetNALUnit.size(); - sps_pps_samples[1].bytes = format->vcodec->pictureParameterSetNALUnit.data(); - sps_pps_samples[1].size = format->vcodec->pictureParameterSetNALUnit.size(); - - nb_samples = 2; - samples = sps_pps_samples; - - { - char* buf = new char[1460]; - SrsBuffer* stream = new SrsBuffer(buf, 1460); - SrsAutoFree(SrsBuffer, stream); - // write rtp header first - stream->write_1bytes(0x80); - stream->write_1bytes(102); - - stream->write_2bytes(sequence++); - stream->write_4bytes((int32_t)shared_frame->timestamp * 90); - stream->write_4bytes((int32_t)3233846889); - - stream->write_1bytes(24/*STAP-A*/); - // AUD - stream->write_2bytes(2); - stream->write_1bytes(0x09); - stream->write_1bytes(0x10); - - stream->write_2bytes(sps_pps_samples[0].size); - stream->write_bytes(sps_pps_samples[0].bytes, sps_pps_samples[0].size); - stream->write_2bytes(sps_pps_samples[1].size); - stream->write_bytes(sps_pps_samples[1].bytes, sps_pps_samples[1].size); - - if (debug_fd >= 0) { - write(debug_fd, start_code, sizeof(start_code)); - write(debug_fd, sps_pps_samples[0].bytes, sps_pps_samples[0].size); - write(debug_fd, start_code, sizeof(start_code)); - write(debug_fd, sps_pps_samples[1].bytes, sps_pps_samples[1].size); - } - - rtp_fragment_samples[rtp_fragment_samples_index].bytes = stream->data(); - rtp_fragment_samples[rtp_fragment_samples_index].size = stream->pos(); - - ++rtp_fragment_samples_index; - } - shared_frame->set_rtp_fragments(rtp_fragment_samples, rtp_fragment_samples_index); - - return err; - } - - for (int i = 0; i < nb_samples; ++i) { - SrsSample sample = samples[i]; - - srs_trace("nal size=%d, dump=%s", sample.size, dump_string_hex(sample.bytes, sample.size, sample.size).c_str()); - - if ((sample.bytes[0] & 0x1F) == 0x06) { - srs_trace("ignore SEI"); - continue; - } - - if (debug_fd >= 0) { - write(debug_fd, start_code, sizeof(start_code)); - write(debug_fd, sample.bytes, sample.size); - } - - static int max_packet_size = 900; - if (sample.size <= max_packet_size) { - char* buf = new char[1460]; - SrsBuffer* stream = new SrsBuffer(buf, 1460); - SrsAutoFree(SrsBuffer, stream); - // write rtp header first - stream->write_1bytes(0x80); - if ((sample.bytes[0] & 0x1F) <= 5) { - stream->write_1bytes((1 << 7) | 102); - } else { - stream->write_1bytes(102); - } - - stream->write_2bytes(sequence++); - stream->write_4bytes((int32_t)shared_frame->timestamp * 90); - stream->write_4bytes((int32_t)3233846889); - -#if 0 // single nalu - stream->write_bytes(sample.bytes, sample.size); -#else - stream->write_1bytes((sample.bytes[0] & 0xE0) | 24/*STAP-A*/); - stream->write_2bytes(sample.size); - stream->write_bytes(sample.bytes, sample.size); -#endif - - rtp_fragment_samples[rtp_fragment_samples_index].bytes = stream->data(); - rtp_fragment_samples[rtp_fragment_samples_index].size = stream->pos(); - - ++rtp_fragment_samples_index; - } else { - int num_of_packet = (sample.size + max_packet_size) / max_packet_size; - char* p = sample.bytes + 1; - int left_bytes = sample.size - 1; - for (int n = 0; n < num_of_packet; ++n) { - char* buf = new char[1460]; - SrsBuffer* stream = new SrsBuffer(buf, 1460); - SrsAutoFree(SrsBuffer, stream); - // write rtp header first - stream->write_1bytes(0x80); - if ((sample.bytes[0] & 0x1F) <= 5) { - stream->write_1bytes((1 << 7) | 102); - } else { - stream->write_1bytes(102); - } - - stream->write_2bytes(sequence++); - stream->write_4bytes((int32_t)shared_frame->timestamp * 90); - stream->write_4bytes((int32_t)3233846889); - - stream->write_1bytes((sample.bytes[0] & 0xE0) | 28); - if (n == 0) { - stream->write_1bytes(0x80 | (sample.bytes[0] & 0x1F)); - } else if (n == num_of_packet - 1) { - stream->write_1bytes(0x40 | (sample.bytes[0] & 0x1F)); - } else { - stream->write_1bytes(0x00 | (sample.bytes[0] & 0x1F)); - } - - int len = left_bytes > max_packet_size ? max_packet_size : left_bytes; - stream->write_bytes(p, len); - left_bytes -= len; - p += len; - - rtp_fragment_samples[rtp_fragment_samples_index].bytes = stream->data(); - rtp_fragment_samples[rtp_fragment_samples_index].size = stream->pos(); - - ++rtp_fragment_samples_index; - - } - } - } - shared_frame->set_rtp_fragments(rtp_fragment_samples, rtp_fragment_samples_index); - - return err; -} -#endif - -const int max_payload_size = 1200; -const int kRtpPacketSize = 1500; - -const uint8_t kMarker = 0x80; -const uint8_t kH264PayloadType = 102; - -const uint8_t kNalTypeMask = 0x1F; - -const uint8_t kIdr = 5; -const uint8_t kStapA = 24; -const uint8_t kFua = 28; - -const uint8_t kStart = 0x80; -const uint8_t kEnd = 0x40; - -const uint32_t kVideoSSRC = 3233846889; - srs_error_t SrsRtpMuxer::frame_to_packet(SrsSharedPtrMessage* shared_frame, SrsFormat* format) { srs_error_t err = srs_success; @@ -280,11 +68,13 @@ srs_error_t SrsRtpMuxer::frame_to_packet(SrsSharedPtrMessage* shared_frame, SrsF pps.assign(format->vcodec->pictureParameterSetNALUnit.data(), format->vcodec->pictureParameterSetNALUnit.size()); } + vector rtp_packet_vec; + for (int i = 0; i < format->video->nb_samples; ++i) { SrsSample sample = format->video->samples[i]; uint8_t header = sample.bytes[0]; - uint8_t nal_type = header & 0x1F; + uint8_t nal_type = header & kNalTypeMask; if (nal_type == 0x06) { srs_trace("ignore SEI"); @@ -292,9 +82,9 @@ srs_error_t SrsRtpMuxer::frame_to_packet(SrsSharedPtrMessage* shared_frame, SrsF } if (sample.size <= max_payload_size) { - packet_single_nalu(shared_frame, format, &sample); + packet_single_nalu(shared_frame, format, &sample, rtp_packet_vec); } else { - packet_fu_a(shared_frame, format, &sample); + packet_fu_a(shared_frame, format, &sample, rtp_packet_vec); } srs_trace("nal size=%d, nal=%s", sample.size, dump_string_hex(sample.bytes, sample.size, sample.size).c_str()); @@ -303,15 +93,20 @@ srs_error_t SrsRtpMuxer::frame_to_packet(SrsSharedPtrMessage* shared_frame, SrsF } } + SrsSample* rtp_samples = new SrsSample[rtp_packet_vec.size()]; + for (int i = 0; i < rtp_packet_vec.size(); ++i) { + rtp_samples[i] = rtp_packet_vec[i]; + } + + shared_frame->set_rtp_fragments(rtp_samples, rtp_packet_vec.size()); + return err; } -srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample) +srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, vector& rtp_packet_vec) { srs_error_t err = srs_success; - vector rtp_packet_vec; - char* p = sample->bytes + 1; int nb_left = sample->size - 1; uint8_t header = sample->bytes[0]; @@ -325,7 +120,7 @@ srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsForma int avg_packet_size = sample->size / num_of_packet; for (int i = 0; i < num_of_packet; ++i) { char* buf = new char[kRtpPacketSize]; - SrsBuffer* stream = new SrsBuffer(buf, 1460); + SrsBuffer* stream = new SrsBuffer(buf, kRtpPacketSize); SrsAutoFree(SrsBuffer, stream); int packet_size = min(nb_left, max_payload_size); @@ -333,8 +128,13 @@ srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsForma // v=2,p=0,x=0,cc=0 stream->write_1bytes(0x80); // marker payloadtype - stream->write_1bytes(kMarker | kH264PayloadType); - // sequenct + if (i == num_of_packet - 1) { + stream->write_1bytes(kMarker | kH264PayloadType); + } else { + stream->write_1bytes(kH264PayloadType); + } + // sequence + srs_trace("sequence=%u", sequence); stream->write_2bytes(sequence++); // timestamp stream->write_4bytes(int32_t(shared_frame->timestamp * 90)); @@ -342,11 +142,11 @@ srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsForma stream->write_4bytes(int32_t(kVideoSSRC)); // fu-indicate - uint8_t fu_indicate = kFua; - fu_indicate |= (nal_type & (~kNalTypeMask)); + uint8_t fu_indicate = kFuA; + fu_indicate |= (header & (~kNalTypeMask)); stream->write_1bytes(fu_indicate); - uint8_t fu_header = nal_type & kNalTypeMask; + uint8_t fu_header = nal_type; if (i == 0) fu_header |= kStart; if (i == num_of_packet - 1) @@ -355,7 +155,7 @@ srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsForma stream->write_bytes(p, packet_size); p += packet_size; - nb_left -= max_payload_size; + nb_left -= packet_size; SrsSample rtp_packet; @@ -364,26 +164,17 @@ srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsForma rtp_packet_vec.push_back(rtp_packet); } - - SrsSample* rtp_samples = new SrsSample[rtp_packet_vec.size()]; - for (int i = 0; i < rtp_packet_vec.size(); ++i) { - rtp_samples[i] = rtp_packet_vec[i]; - } - - shared_frame->set_rtp_fragments(rtp_samples, rtp_packet_vec.size()); } -srs_error_t SrsRtpMuxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample) +srs_error_t SrsRtpMuxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, vector& rtp_packet_vec) { srs_error_t err = srs_success; - vector rtp_packet_vec; - uint8_t header = sample->bytes[0]; uint8_t nal_type = header & kNalTypeMask; char* buf = new char[kRtpPacketSize]; - SrsBuffer* stream = new SrsBuffer(buf, 1460); + SrsBuffer* stream = new SrsBuffer(buf, kRtpPacketSize); SrsAutoFree(SrsBuffer, stream); if (nal_type == kIdr) { @@ -395,6 +186,7 @@ srs_error_t SrsRtpMuxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, S // marker payloadtype stream->write_1bytes(kMarker | kH264PayloadType); // sequenct + srs_trace("sequence=%u", sequence); stream->write_2bytes(sequence++); // timestamp stream->write_4bytes(int32_t(shared_frame->timestamp * 90)); @@ -407,12 +199,7 @@ srs_error_t SrsRtpMuxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, S rtp_packet.bytes = stream->data(); rtp_packet.size = stream->pos(); - SrsSample* rtp_samples = new SrsSample[rtp_packet_vec.size()]; - for (int i = 0; i < rtp_packet_vec.size(); ++i) { - rtp_samples[i] = rtp_packet_vec[i]; - } - - shared_frame->set_rtp_fragments(rtp_samples, rtp_packet_vec.size()); + rtp_packet_vec.push_back(rtp_packet); return err; } @@ -425,7 +212,7 @@ srs_error_t SrsRtpMuxer::packet_stap_a(const string &sps, const string& pps, Srs uint8_t nal_type = header & kNalTypeMask; char* buf = new char[kRtpPacketSize]; - SrsBuffer* stream = new SrsBuffer(buf, 1460); + SrsBuffer* stream = new SrsBuffer(buf, kRtpPacketSize); SrsAutoFree(SrsBuffer, stream); // v=2,p=0,x=0,cc=0 @@ -433,6 +220,7 @@ srs_error_t SrsRtpMuxer::packet_stap_a(const string &sps, const string& pps, Srs // marker payloadtype stream->write_1bytes(kMarker | kH264PayloadType); // sequenct + srs_trace("sequence=%u", sequence); stream->write_2bytes(sequence++); // timestamp stream->write_4bytes(int32_t(shared_frame->timestamp * 90)); diff --git a/trunk/src/app/srs_app_rtp.hpp b/trunk/src/app/srs_app_rtp.hpp index 1d0f510dd..9000fd830 100644 --- a/trunk/src/app/srs_app_rtp.hpp +++ b/trunk/src/app/srs_app_rtp.hpp @@ -36,6 +36,23 @@ class SrsSharedPtrMessage; class SrsRequest; class SrsOriginHub; +const int max_payload_size = 1200; +const int kRtpPacketSize = 1500; + +const uint8_t kMarker = 0x80; +const uint8_t kH264PayloadType = 102; + +const uint8_t kNalTypeMask = 0x1F; + +const uint8_t kIdr = 5; +const uint8_t kStapA = 24; +const uint8_t kFuA = 28; + +const uint8_t kStart = 0x80; +const uint8_t kEnd = 0x40; + +const uint32_t kVideoSSRC = 3233846889; + class SrsRtpMuxer { private: @@ -48,8 +65,8 @@ public: public: srs_error_t frame_to_packet(SrsSharedPtrMessage* shared_video, SrsFormat* format); private: - srs_error_t packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample); - srs_error_t packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample); + srs_error_t packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, std::vector& rtp_packet_vec); + srs_error_t packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, std::vector& rtp_packet_vec); srs_error_t packet_stap_a(const std::string &sps, const std::string& pps, SrsSharedPtrMessage* shared_frame, std::vector& rtp_packet_vec); }; diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index 04ece7184..66ae11269 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -1193,3 +1193,37 @@ void srs_api_dump_summaries(SrsJsonObject* obj) sys->set("conn_srs", SrsJsonAny::integer(nrs->nb_conn_srs)); } +string dump_string_hex(const std::string& str, const int& max_len) +{ + return dump_string_hex(str.c_str(), str.size(), max_len); +} + +string dump_string_hex(const char* buf, const int nb_buf, const int& max_len) +{ + string ret; + ret.reserve(max_len * 4); + + char tmp_buf[1024*16]; + tmp_buf[0] = '\n'; + int len = 1; + + for (int i = 0; i < nb_buf && i < max_len; ++i) { + //int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "(%03d)%02X ", i, (uint8_t)buf[i]); + int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "%02X ", (uint8_t)buf[i]); + if (nb <= 0) + break; + + len += nb; + + if (i % 48 == 47) { + tmp_buf[len++] = '\n'; + ret.append(tmp_buf, len); + len = 0; + } + } + tmp_buf[len] = '\0'; + ret.append(tmp_buf, len); + + return ret; + +} diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index be7cbced6..77d28f802 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -649,5 +650,8 @@ extern bool srs_is_boolean(std::string str); // Dump summaries for /api/v1/summaries. extern void srs_api_dump_summaries(SrsJsonObject* obj); +extern std::string dump_string_hex(const std::string& str, const int& max_len = INT_MAX); +extern std::string dump_string_hex(const char* buf, const int nb_buf, const int& max_len = INT_MAX); + #endif diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index aa0d3a7ec..f2f773049 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -216,10 +216,10 @@ SrsSharedPtrMessage::SrsSharedPtrPayload::~SrsSharedPtrPayload() srs_freepa(payload); for (int i = 0; i < nb_rtp_fragments; ++i) { - srs_freep(rtp_fragments[i].bytes); + srs_freepa(rtp_fragments[i].bytes); } - if (nb_rtp_fragments) { + if (rtp_fragments != NULL && nb_rtp_fragments > 0) { srs_freepa(rtp_fragments); } }