mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
112 lines
3.7 KiB
C++
112 lines
3.7 KiB
C++
#include "obu_parser.h"
|
|
|
|
#include "byte_buffer.h"
|
|
#include "log.h"
|
|
|
|
constexpr int kAggregationHeaderSize = 1;
|
|
// when there are 3 or less OBU (fragments) in a packet, size of the last one
|
|
// can be omited.
|
|
constexpr int kMaxNumObusToOmitSize = 3;
|
|
constexpr uint8_t kObuSizePresentBit = 0b0'0000'010;
|
|
constexpr int kObuTypeSequenceHeader = 1;
|
|
constexpr int kObuTypeTemporalDelimiter = 2;
|
|
constexpr int kObuTypeTileList = 8;
|
|
constexpr int kObuTypePadding = 15;
|
|
|
|
const char* ObuTypeToString(OBU_TYPE type) {
|
|
switch (type) {
|
|
case OBU_SEQUENCE_HEADER:
|
|
return "OBU_SEQUENCE_HEADER";
|
|
case OBU_TEMPORAL_DELIMITER:
|
|
return "OBU_TEMPORAL_DELIMITER";
|
|
case OBU_FRAME_HEADER:
|
|
return "OBU_FRAME_HEADER";
|
|
case OBU_REDUNDANT_FRAME_HEADER:
|
|
return "OBU_REDUNDANT_FRAME_HEADER";
|
|
case OBU_FRAME:
|
|
return "OBU_FRAME";
|
|
case OBU_TILE_GROUP:
|
|
return "OBU_TILE_GROUP";
|
|
case OBU_METADATA:
|
|
return "OBU_METADATA";
|
|
case OBU_TILE_LIST:
|
|
return "OBU_TILE_LIST";
|
|
case OBU_PADDING:
|
|
return "OBU_PADDING";
|
|
default:
|
|
break;
|
|
}
|
|
return "<Invalid OBU Type>";
|
|
}
|
|
|
|
bool ObuHasExtension(uint8_t obu_header) { return obu_header & 0b0'0000'100; }
|
|
|
|
bool ObuHasSize(uint8_t obu_header) { return obu_header & kObuSizePresentBit; }
|
|
|
|
int ObuType(uint8_t obu_header) { return (obu_header & 0b0'1111'000) >> 3; }
|
|
|
|
std::vector<Obu> ParseObus(uint8_t* payload, int payload_size) {
|
|
std::vector<Obu> result;
|
|
ByteBufferReader payload_reader(reinterpret_cast<const char*>(payload),
|
|
payload_size);
|
|
while (payload_reader.Length() > 0) {
|
|
Obu obu;
|
|
payload_reader.ReadUInt8(&obu.header_);
|
|
LOG_ERROR("Get obu type = [{}]",
|
|
ObuTypeToString((OBU_TYPE)ObuType(obu.header_)))
|
|
obu.size_ = 1;
|
|
if (ObuHasExtension(obu.header_)) {
|
|
if (payload_reader.Length() == 0) {
|
|
LOG_ERROR(
|
|
"Malformed AV1 input: expected extension_header, no more bytes in "
|
|
"the buffer. Offset: {}",
|
|
(payload_size - payload_reader.Length()));
|
|
return {};
|
|
}
|
|
payload_reader.ReadUInt8(&obu.extension_header_);
|
|
++obu.size_;
|
|
}
|
|
if (!ObuHasSize(obu.header_)) {
|
|
obu.SetPayload(reinterpret_cast<const uint8_t*>(payload_reader.Data()),
|
|
payload_reader.Length());
|
|
payload_reader.Consume(payload_reader.Length());
|
|
LOG_ERROR("payload_reader.Length() = {}", payload_reader.Length());
|
|
} else {
|
|
uint64_t size = 0;
|
|
if (!payload_reader.ReadUVarint(&size) ||
|
|
size > payload_reader.Length()) {
|
|
LOG_ERROR(
|
|
"Malformed AV1 input: declared size {} is larger than remaining "
|
|
"buffer size {}",
|
|
size, payload_reader.Length());
|
|
return {};
|
|
}
|
|
obu.SetPayload(reinterpret_cast<const uint8_t*>(payload_reader.Data()),
|
|
size);
|
|
payload_reader.Consume(size);
|
|
LOG_ERROR("size = {}", size);
|
|
}
|
|
obu.size_ += obu.payload_size_;
|
|
// Skip obus that shouldn't be transfered over rtp.
|
|
int obu_type = ObuType(obu.header_);
|
|
// if (obu_type != kObuTypeTemporalDelimiter && //
|
|
// obu_type != kObuTypeTileList && //
|
|
// obu_type != kObuTypePadding) {
|
|
// result.push_back(obu);
|
|
// }
|
|
|
|
LOG_ERROR("Obu size = [{}], Obu type [{}]", obu.size_,
|
|
ObuTypeToString((OBU_TYPE)ObuType(obu.header_)));
|
|
if (1) {
|
|
result.push_back(obu);
|
|
}
|
|
}
|
|
|
|
LOG_ERROR("Obu size = [{}]", result.size());
|
|
for (int i = 0; i < result.size(); i++) {
|
|
LOG_ERROR("[{}] Obu size = [{}], Obu type [{}]", i, result[i].payload_size_,
|
|
ObuTypeToString((OBU_TYPE)ObuType(result[i].header_)));
|
|
}
|
|
|
|
return result;
|
|
} |