#define MS_CLASS "RTC::RTP::Codecs::Opus"
#include "RTC/RTP/Codecs/Opus.hpp"
#include "Logger.hpp"
namespace RTC
{
namespace RTP
{
namespace Codecs
{
Opus::PayloadDescriptor* Opus::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
if (len < 1)
{
MS_WARN_DEV("ignoring empty payload");
return nullptr;
}
std::unique_ptr<PayloadDescriptor> payloadDescriptor(new PayloadDescriptor());
const uint8_t byte = data[0];
payloadDescriptor->stereo = (byte >> 2) & 0x01;
payloadDescriptor->code = byte & 0x03;
switch (payloadDescriptor->code)
{
case 0:
case 1:
{
if (len == 1)
{
payloadDescriptor->isDtx = true;
}
break;
}
case 2:
{
if (len == 1)
{
MS_WARN_DEV("ignoring invalid payload (1)");
return nullptr;
}
if (len == 2)
{
payloadDescriptor->isDtx = true;
}
break;
}
case 3:
{
if (len == 1)
{
MS_WARN_DEV("ignoring invalid payload (2)");
return nullptr;
}
break;
}
default:;
}
return payloadDescriptor.release();
}
void Opus::ProcessRtpPacket(RTP::Packet* packet)
{
MS_TRACE();
auto* data = packet->GetPayload();
auto len = packet->GetPayloadLength();
PayloadDescriptor* payloadDescriptor = Opus::Parse(data, len);
if (!payloadDescriptor)
{
return;
}
auto* payloadDescriptorHandler = new PayloadDescriptorHandler(payloadDescriptor);
packet->SetPayloadDescriptorHandler(payloadDescriptorHandler);
}
void Opus::PayloadDescriptor::Dump(int indentation) const
{
MS_TRACE();
MS_DUMP_CLEAN(indentation, "<Opus::PayloadDescriptor>");
MS_DUMP_CLEAN(indentation, " stereo: %" PRIu8, this->stereo);
MS_DUMP_CLEAN(indentation, " code: %" PRIu8, this->code);
MS_DUMP_CLEAN(indentation, " is dtx: %s", this->isDtx ? "true" : "false");
MS_DUMP_CLEAN(indentation, "</Opus::PayloadDescriptor>");
}
Opus::PayloadDescriptorHandler::PayloadDescriptorHandler(Opus::PayloadDescriptor* payloadDescriptor)
{
MS_TRACE();
this->payloadDescriptor.reset(payloadDescriptor);
}
bool Opus::PayloadDescriptorHandler::Process(
Codecs::EncodingContext* encodingContext, RTP::Packet* , bool& )
{
MS_TRACE();
auto* context = static_cast<Codecs::Opus::EncodingContext*>(encodingContext);
return !(this->payloadDescriptor->isDtx && context->GetIgnoreDtx());
};
} } }