1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

h264 packet done, chrome play well

This commit is contained in:
HuyaJohn 2020-03-11 04:21:44 -07:00
parent e831f3254a
commit da72caf8b9
6 changed files with 169 additions and 297 deletions

View file

@ -30,6 +30,8 @@ using namespace std;
#include <arpa/inet.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sstream>
@ -41,7 +43,9 @@ using namespace std;
#include <srs_rtmp_stack.hpp>
#include <srs_rtmp_msg_array.hpp>
#include <srs_app_dtls.hpp>
#include <srs_app_utility.hpp>
#include <srs_app_config.hpp>
#include <srs_app_rtp.hpp>
#include <srs_app_source.hpp>
#include <srs_app_server.hpp>
#include <srs_service_utility.hpp>
@ -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;
}

View file

@ -50,42 +50,6 @@ using namespace std;
#include <srs_protocol_format.hpp>
#include <openssl/rand.h>
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<SrsSample> 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<SrsSample>& rtp_packet_vec)
{
srs_error_t err = srs_success;
vector<SrsSample> 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<SrsSample>& rtp_packet_vec)
{
srs_error_t err = srs_success;
vector<SrsSample> 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));

View file

@ -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<SrsSample>& rtp_packet_vec);
srs_error_t packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, std::vector<SrsSample>& rtp_packet_vec);
srs_error_t packet_stap_a(const std::string &sps, const std::string& pps, SrsSharedPtrMessage* shared_frame, std::vector<SrsSample>& rtp_packet_vec);
};

View file

@ -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;
}

View file

@ -30,6 +30,7 @@
#include <string>
#include <sstream>
#include <limits.h>
#include <arpa/inet.h>
#include <sys/resource.h>
@ -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

View file

@ -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);
}
}