Commit d437a2a8 authored by François Grisez's avatar François Grisez
Browse files

Abstracts NALu types

parent 9e620f06
......@@ -86,8 +86,22 @@ uint8_t ms_h264_nalu_get_nri(const mblk_t *nalu) {
return ((*nalu->b_rptr) >> 5) & 0x3;
}
MSH264NaluType ms_h264_int_to_nalu_type(uint8_t val) {
switch (val) {
case MSH264NaluTypeIDR:
case MSH264NaluTypeSEI:
case MSH264NaluTypeSPS:
case MSH264NaluTypePPS:
case MSH264NaluTypeSTAPA:
case MSH264NaluTypeFUA:
return static_cast<MSH264NaluType>(val);
default:
return MSH264NaluTypeUnknown;
}
}
MSH264NaluType ms_h264_nalu_get_type(const mblk_t *nalu) {
return static_cast<MSH264NaluType>((*nalu->b_rptr) & ((1 << 5) - 1));
return ms_h264_int_to_nalu_type((*nalu->b_rptr) & ((1 << 5) - 1));
}
unsigned int _ms_h264_get_id(const mblk_t *parameter_set, size_t offset, const char *symbol_name) {
......
......@@ -27,6 +27,7 @@
* Enumeration that lists the different type of NAL unit
*/
typedef enum {
MSH264NaluTypeUnknown = -1,
MSH264NaluTypeIDR = 5,
MSH264NaluTypeSEI = 6,
MSH264NaluTypeSPS = 7,
......@@ -46,9 +47,15 @@ extern "C" {
uint8_t ms_h264_nalu_get_nri(const mblk_t *nalu);
/**
* Get the type of a NAL unit
* @param nalu The NAL unit to analyse
* @return The nalu type
* @brief Finds out the NALu type corresponding to a given integer according ITU's H264 standard and RFC3984.
* @return Returns the type should the integer be mapped to a known type, or #MSH264NaluTypeUnknown if shouldn't.
*/
MSH264NaluType ms_h264_int_to_nalu_type(uint8_t val);
/**
* Gets the type of a NAL unit.
* @param nalu The NAL unit to analyze.
* @return The NALu type or #MSH264NaluTypeUnknown if the type of the NALu is unknown.
*/
MSH264NaluType ms_h264_nalu_get_type(const mblk_t *nalu);
......
......@@ -207,8 +207,12 @@ bool_t Rfc3984Packer::updateParameterSet(mblk_t **last_parameter_set, mblk_t *ne
// AbstractUnpacker
// ================
Unpacker::Unpacker(NaluAggregatorInterface *aggregator, NaluSpliterInterface *spliter): _naluAggregator(aggregator), _naluSpliter(spliter) {
ms_queue_init(&_q);
}
Unpacker::Status Unpacker::unpack(mblk_t *im, MSQueue *out) {
uint8_t type = getNaluType(im);
PacketType type = getNaluType(im);
int marker = mblk_get_marker_info(im);
uint32_t ts = mblk_get_timestamp_info(im);
uint16_t cseq = mblk_get_cseq(im);
......@@ -241,21 +245,26 @@ Unpacker::Status Unpacker::unpack(mblk_t *im, MSQueue *out) {
}
}
if (type == MSH264NaluTypeSTAPA) {
ms_debug("Receiving STAP-A");
_naluSpliter->feedNalu(im);
while ((im = ms_queue_get(_naluSpliter->getNalus()))) {
switch (type) {
case PacketType::SingleNalUnit:
_naluAggregator->reset();
/*single nal unit*/
ms_debug("Receiving single NAL");
storeNal(im);
break;
case PacketType::FragmentationUnit: {
ms_debug("Receiving FU-A");
mblk_t *o = _naluAggregator->feedNalu(im);
if (o) storeNal(o);
break;
}
} else if (type == MSH264NaluTypeFUA) {
mblk_t *o = _naluAggregator->feedNalu(im);
ms_debug("Receiving FU-A");
if (o) storeNal(o);
} else {
_naluAggregator->reset();
/*single nal unit*/
ms_debug("Receiving single NAL");
storeNal(im);
case PacketType::AggregationPacket:
ms_debug("Receiving STAP-A");
_naluSpliter->feedNalu(im);
while ((im = ms_queue_get(_naluSpliter->getNalus()))) {
storeNal(im);
}
break;
}
if (marker) {
......@@ -374,11 +383,6 @@ void H264StapASpliter::feedNalu(mblk_t *im) {
// Public methods
// --------------
Rfc3984Unpacker::Rfc3984Unpacker(): Unpacker() {
_naluAggregator.reset(new H264FUAAggregator());
_naluSpliter.reset(new H264StapASpliter());
}
Rfc3984Unpacker::~Rfc3984Unpacker() {
if (_sps != nullptr) freemsg(_sps);
if (_pps != nullptr) freemsg(_pps);
......@@ -394,8 +398,12 @@ void Rfc3984Unpacker::setOutOfBandSpsPps(mblk_t *sps, mblk_t *pps) {
// Private methods
// ---------------
uint8_t Rfc3984Unpacker::getNaluType(const mblk_t *nalu) const {
return ms_h264_nalu_get_type(nalu);
Unpacker::PacketType Rfc3984Unpacker::getNaluType(const mblk_t *nalu) const {
switch (ms_h264_nalu_get_type(nalu)) {
case MSH264NaluTypeFUA: return PacketType::FragmentationUnit;
case MSH264NaluTypeSTAPA: return PacketType::AggregationPacket;
default: return PacketType::SingleNalUnit;
}
}
Rfc3984Unpacker::Status Rfc3984Unpacker::outputFrame(MSQueue *out, const Status &flags) {
......
......@@ -98,8 +98,9 @@ public:
static const size_t FrameCorrupted = 1;
static const size_t IsKeyFrame = 2;
};
typedef std::bitset<32> Status;
typedef std::bitset<3> Status;
Unpacker(NaluAggregatorInterface *aggregator, NaluSpliterInterface *spliter);
virtual ~Unpacker() {ms_queue_flush(&_q);}
/**
......@@ -113,10 +114,16 @@ public:
Status unpack(mblk_t *im, MSQueue *out);
protected:
enum class PacketType {
SingleNalUnit,
AggregationPacket,
FragmentationUnit
};
virtual Status outputFrame(MSQueue *out, const Status &flags);
virtual void storeNal(mblk_t *nal);
virtual uint8_t getNaluType(const mblk_t *nalu) const = 0;
virtual PacketType getNaluType(const mblk_t *nalu) const = 0;
MSQueue _q;
Status _status = 0;
......@@ -153,13 +160,13 @@ private:
class Rfc3984Unpacker: public Unpacker {
public:
Rfc3984Unpacker();
Rfc3984Unpacker(): Unpacker(new H264FUAAggregator(), new H264StapASpliter()) {}
~Rfc3984Unpacker();
void setOutOfBandSpsPps(mblk_t *sps, mblk_t *pps);
private:
uint8_t getNaluType(const mblk_t *nalu) const override;
Unpacker::PacketType getNaluType(const mblk_t *nalu) const override;
Status outputFrame(MSQueue *out, const Status &flags) override;
mblk_t *_sps = nullptr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment