mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[fix] fix h264 rtp packet parse
This commit is contained in:
@@ -2,7 +2,13 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
RtpPacket::RtpPacket() {}
|
||||
static FILE *file_1_ = nullptr;
|
||||
static FILE *file_2_ = nullptr;
|
||||
|
||||
RtpPacket::RtpPacket() {
|
||||
if (file_1_ == nullptr) file_1_ = fopen("file_1_.h264", "w+b");
|
||||
if (file_2_ == nullptr) file_2_ = fopen("file_2_.h264", "w+b");
|
||||
}
|
||||
|
||||
RtpPacket::RtpPacket(size_t size) : buffer_(size) {}
|
||||
|
||||
@@ -14,19 +20,32 @@ RtpPacket &RtpPacket::operator=(const RtpPacket &rtp_packet) = default;
|
||||
|
||||
RtpPacket &RtpPacket::operator=(RtpPacket &&rtp_packet) = default;
|
||||
|
||||
RtpPacket::~RtpPacket() = default;
|
||||
RtpPacket::~RtpPacket() {
|
||||
// if (file_1_ != nullptr) {
|
||||
// fclose(file_1_);
|
||||
// file_1_ = nullptr;
|
||||
// }
|
||||
// if (file_2_ != nullptr) {
|
||||
// fclose(file_2_);
|
||||
// file_2_ = nullptr;
|
||||
// }
|
||||
}
|
||||
|
||||
bool RtpPacket::Build(const uint8_t *buffer, uint32_t size) {
|
||||
fwrite((unsigned char *)buffer, 1, size, file_1_);
|
||||
if (!Parse(buffer, size)) {
|
||||
LOG_WARN("RtpPacket::Build: parse failed");
|
||||
return false;
|
||||
}
|
||||
buffer_.SetData(buffer, size);
|
||||
fwrite((unsigned char *)Payload(), 1, PayloadSize(), file_2_);
|
||||
size_ = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
||||
payload_offset_ = 0;
|
||||
|
||||
if (size < kFixedHeaderSize) {
|
||||
LOG_WARN("RtpPacket::Parse: size is too small");
|
||||
return false;
|
||||
@@ -45,7 +64,7 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
||||
LOG_WARN("RtpPacket::Parse: csrc count is too large");
|
||||
return false;
|
||||
}
|
||||
payload_offset_++;
|
||||
payload_offset_ += 1;
|
||||
|
||||
// 2nd byte
|
||||
marker_ = (buffer[payload_offset_] >> 7) & 0x01;
|
||||
@@ -99,18 +118,21 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
||||
(buffer[payload_offset_] << 8) | buffer[payload_offset_ + 1];
|
||||
extension_len_ =
|
||||
(buffer[payload_offset_ + 2] << 8) | buffer[payload_offset_ + 3];
|
||||
payload_offset_ += 4;
|
||||
|
||||
if (payload_offset_ + extension_len_ > size) {
|
||||
if (payload_offset_ + extension_len_ * 4 > size) {
|
||||
LOG_WARN("RtpPacket::Parse: extension len is too large");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t offset = payload_offset_ + 4;
|
||||
while (offset < size && extension_len_ > 0) {
|
||||
size_t offset = payload_offset_;
|
||||
size_t total_ext_len = extension_len_ * 4;
|
||||
while (offset < payload_offset_ + total_ext_len) {
|
||||
uint8_t id = buffer[offset] >> 4;
|
||||
uint8_t len = (buffer[offset] & 0x0F) + 1;
|
||||
if (offset + 1 + len > size) {
|
||||
break;
|
||||
if (offset + 1 + len > payload_offset_ + total_ext_len) {
|
||||
LOG_WARN("RtpPacket::Parse: extension data is too large");
|
||||
return false;
|
||||
}
|
||||
Extension extension;
|
||||
extension.id = id;
|
||||
@@ -119,7 +141,7 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
||||
extensions_.push_back(extension);
|
||||
offset += 1 + len;
|
||||
}
|
||||
payload_offset_ += extension_len_;
|
||||
payload_offset_ += total_ext_len;
|
||||
}
|
||||
|
||||
if (has_padding_ && payload_offset_ < size) {
|
||||
@@ -137,6 +159,7 @@ bool RtpPacket::Parse(const uint8_t *buffer, uint32_t size) {
|
||||
LOG_WARN("RtpPacket::Parse: payload size is too large");
|
||||
return false;
|
||||
}
|
||||
|
||||
payload_size_ = size - payload_offset_ - padding_size_;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -269,6 +269,10 @@ class RtpPacket {
|
||||
bool has_padding() const { return buffer_[0] & 0x20; }
|
||||
size_t padding_size() const { return padding_size_; }
|
||||
size_t size() const { return size_; }
|
||||
void add_offset_to_payload(size_t offset) {
|
||||
payload_offset_ += offset;
|
||||
payload_size_ -= offset;
|
||||
}
|
||||
|
||||
private:
|
||||
// Common header
|
||||
|
||||
@@ -5,16 +5,30 @@ RtpPacketH264::RtpPacketH264() {}
|
||||
RtpPacketH264::~RtpPacketH264() {}
|
||||
|
||||
bool RtpPacketH264::GetFrameHeaderInfo() {
|
||||
if (fu_info_got_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t* frame_buffer = Payload();
|
||||
|
||||
fu_indicator_.forbidden_bit = (frame_buffer[0] >> 7) & 0x01;
|
||||
fu_indicator_.nal_reference_idc = (frame_buffer[0] >> 5) & 0x03;
|
||||
fu_indicator_.nal_unit_type = frame_buffer[0] & 0x1F;
|
||||
|
||||
fu_header_.start = (frame_buffer[1] >> 7) & 0x01;
|
||||
fu_header_.end = (frame_buffer[1] >> 6) & 0x01;
|
||||
fu_header_.remain_bit = (frame_buffer[1] >> 5) & 0x01;
|
||||
fu_header_.nal_unit_type = frame_buffer[1] & 0x1F;
|
||||
if (rtp::NAL_UNIT_TYPE::NALU == fu_indicator_.nal_unit_type) {
|
||||
add_offset_to_payload(1);
|
||||
LOG_ERROR("2 [{} {} {}]", (int)fu_indicator_.forbidden_bit,
|
||||
(int)fu_indicator_.nal_reference_idc,
|
||||
(int)fu_indicator_.nal_unit_type);
|
||||
} else if (rtp::NAL_UNIT_TYPE::FU_A == fu_indicator_.nal_unit_type) {
|
||||
fu_header_.start = (frame_buffer[1] >> 7) & 0x01;
|
||||
fu_header_.end = (frame_buffer[1] >> 6) & 0x01;
|
||||
fu_header_.remain_bit = (frame_buffer[1] >> 5) & 0x01;
|
||||
fu_header_.nal_unit_type = frame_buffer[1] & 0x1F;
|
||||
add_offset_to_payload(2);
|
||||
}
|
||||
|
||||
fu_info_got_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -26,6 +26,7 @@ class RtpPacketH264 : public RtpPacket {
|
||||
private:
|
||||
rtp::FU_INDICATOR fu_indicator_;
|
||||
rtp::FU_HEADER fu_header_;
|
||||
bool fu_info_got_ = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user