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

Migrates unpacking status from enum to C++ bitset

parent ef0fa4bd
......@@ -282,7 +282,6 @@ static void dec_process(MSFilter *f){
mblk_t *im, *om;
MSQueue nalus;
bool_t requestPLI = FALSE;
unsigned int ret = 0;
ms_queue_init(&nalus);
while((im=ms_queue_get(f->inputs[0]))!=NULL){
......@@ -301,9 +300,9 @@ static void dec_process(MSFilter *f){
d->sps=NULL;
d->pps=NULL;
}
ret = d->unpacker->unpack(im,&nalus);
Rfc3984Unpacker::Status ret = d->unpacker->unpack(im,&nalus);
if (ret & Rfc3984Unpacker::Status::FrameAvailable){
if (ret.test(Rfc3984Unpacker::StatusFlag::FrameAvailable)){
int size;
uint8_t *p,*end;
bool_t need_reinit=FALSE;
......@@ -339,7 +338,7 @@ static void dec_process(MSFilter *f){
}
p+=len;
}
if (ret & Rfc3984Unpacker::Status::FrameCorrupted) requestPLI = TRUE;
if (ret.test(Rfc3984Unpacker::StatusFlag::FrameCorrupted)) requestPLI = TRUE;
}
d->packet_num++;
}
......
......@@ -300,19 +300,21 @@ AbstractUnpacker::~AbstractUnpacker() {
ms_queue_flush(&_q);
}
unsigned int AbstractUnpacker::unpack(mblk_t *im, MSQueue *out) {
AbstractUnpacker::Status AbstractUnpacker::unpack(mblk_t *im, MSQueue *out) {
uint8_t 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);
unsigned int ret = 0;
Status ret;
if (_lastTs != ts) {
/*a new frame is arriving, in case the marker bit was not set in previous frame, output it now,
* unless it is a FU-A packet (workaround for buggy implementations)*/
_lastTs = ts;
if (!_naluAggregator->isAggregating() && !ms_queue_empty(&_q)) {
ret = outputFrame(out, UnpackingStatus::FrameAvailable | UnpackingStatus::FrameCorrupted);
Status status;
status.set(StatusFlag::FrameAvailable).set(StatusFlag::FrameCorrupted);
ret = outputFrame(out, status);
ms_warning("Incomplete H264 frame (missing marker bit after seq number %u)",
mblk_get_cseq(ms_queue_peek_last(out)));
}
......@@ -328,7 +330,7 @@ unsigned int AbstractUnpacker::unpack(mblk_t *im, MSQueue *out) {
if (_refCSeq != cseq) {
ms_message("sequence inconsistency detected (diff=%i)", (int)(cseq - _refCSeq));
_refCSeq = cseq;
_status |= UnpackingStatus::FrameCorrupted;
_status.set(StatusFlag::FrameCorrupted);
}
}
......@@ -352,14 +354,16 @@ unsigned int AbstractUnpacker::unpack(mblk_t *im, MSQueue *out) {
if (marker) {
_lastTs = ts;
ms_debug("Marker bit set");
ret = outputFrame(out, static_cast<unsigned int>(UnpackingStatus::FrameAvailable));
Status status;
status.set(StatusFlag::FrameAvailable);
ret = outputFrame(out, status);
}
return ret;
}
unsigned int AbstractUnpacker::outputFrame(MSQueue *out, unsigned int flags) {
unsigned int res = _status;
AbstractUnpacker::Status AbstractUnpacker::outputFrame(MSQueue *out, Status flags) {
Status res = _status;
if (!ms_queue_empty(out)) {
ms_warning("rfc3984_unpack: output_frame invoked several times in a row, this should not happen");
}
......@@ -400,12 +404,12 @@ void Rfc3984Unpacker::setOutOfBandSpsPps(mblk_t *sps, mblk_t *pps) {
_pps = pps;
}
unsigned int Rfc3984Unpacker::unpack(mblk_t *im, MSQueue *out) {
Rfc3984Unpacker::Status Rfc3984Unpacker::unpack(mblk_t *im, MSQueue *out) {
uint8_t type = ms_h264_nalu_get_type(im);
int marker = mblk_get_marker_info(im);
uint32_t ts = mblk_get_timestamp_info(im);
uint16_t cseq = mblk_get_cseq(im);
unsigned int ret = 0;
Status ret;
//ms_message("Seeing timestamp %u, sequence %u", ts, (int)cseq);
......@@ -414,7 +418,9 @@ unsigned int Rfc3984Unpacker::unpack(mblk_t *im, MSQueue *out) {
* unless it is a FU-A packet (workaround for buggy implementations)*/
_lastTs = ts;
if (!_fuaAggregator.isAggregating() && !ms_queue_empty(&_q)) {
ret = outputFrame(out, Status::FrameAvailable | Status::FrameCorrupted);
Status status;
status.set(StatusFlag::FrameAvailable).set(StatusFlag::FrameCorrupted);
ret = outputFrame(out, status);
ms_warning("Incomplete H264 frame (missing marker bit after seq number %u)",
mblk_get_cseq(ms_queue_peek_last(out)));
}
......@@ -430,7 +436,7 @@ unsigned int Rfc3984Unpacker::unpack(mblk_t *im, MSQueue *out) {
if (_refCSeq != cseq) {
ms_message("sequence inconsistency detected (diff=%i)", (int)(cseq - _refCSeq));
_refCSeq = cseq;
_status |= Status::FrameCorrupted;
_status.set(StatusFlag::FrameCorrupted);
}
}
......@@ -454,7 +460,9 @@ unsigned int Rfc3984Unpacker::unpack(mblk_t *im, MSQueue *out) {
if (marker) {
_lastTs = ts;
ms_debug("Marker bit set");
ret = outputFrame(out, static_cast<unsigned int>(Status::FrameAvailable));
Status status;
status.set(StatusFlag::FrameAvailable);
ret = outputFrame(out, status);
}
return ret;
......@@ -463,14 +471,14 @@ unsigned int Rfc3984Unpacker::unpack(mblk_t *im, MSQueue *out) {
// Private methods
// ---------------
unsigned int Rfc3984Unpacker::outputFrame(MSQueue *out, unsigned int flags) {
unsigned int res = _status;
Rfc3984Unpacker::Status Rfc3984Unpacker::outputFrame(MSQueue *out, const Status &flags) {
Status res = _status;
if (!ms_queue_empty(out)) {
ms_warning("rfc3984_unpack: output_frame invoked several times in a row, this should not happen");
}
res |= flags;
if ((res & Status::IsKeyFrame) && _sps && _pps) {
if (res.test(StatusFlag::IsKeyFrame) && _sps && _pps) {
/*prepend out of band provided sps and pps*/
ms_queue_put(out, _sps);
_sps = NULL;
......@@ -479,8 +487,8 @@ unsigned int Rfc3984Unpacker::outputFrame(MSQueue *out, unsigned int flags) {
}
/* Log some bizarre things */
if ((res & Status::FrameCorrupted) == 0) {
if ((res & Status::HasSPS) && (res & Status::HasPPS) && !(res & Status::HasIDR) && !(res & Status::IsKeyFrame)) {
if (res.test(StatusFlag::FrameCorrupted)) {
if (res.test(StatusFlag::HasSPS) && res.test(StatusFlag::HasPPS) && !res.test(StatusFlag::HasIDR) && !res.test(StatusFlag::IsKeyFrame)) {
/*some decoders may not be happy with this*/
ms_warning("rfc3984_unpack: a frame with SPS+PPS but no IDR was output, starting at seq number %u",
mblk_get_cseq(ms_queue_peek_first(&_q)));
......@@ -498,23 +506,23 @@ unsigned int Rfc3984Unpacker::outputFrame(MSQueue *out, unsigned int flags) {
void Rfc3984Unpacker::storeNal(mblk_t *nal) {
uint8_t type = ms_h264_nalu_get_type(nal);
if ((_status & Status::HasSPS) && (_status & Status::HasPPS) && type != MSH264NaluTypeIDR && mblk_get_marker_info(nal) && isUniqueISlice(nal->b_rptr + 1)) {
if (_status.test(StatusFlag::HasSPS) && _status.test(StatusFlag::HasPPS) && type != MSH264NaluTypeIDR && mblk_get_marker_info(nal) && isUniqueISlice(nal->b_rptr + 1)) {
ms_warning("Receiving a nal unit which is not IDR but a single I-slice bundled with SPS & PPS - considering it as a key frame.");
_status |= Status::IsKeyFrame;
_status.set(StatusFlag::IsKeyFrame);
}
if (type == MSH264NaluTypeIDR) {
_status |= Status::HasIDR;
_status |= Status::IsKeyFrame;
_status.set(StatusFlag::HasIDR);
_status.set(StatusFlag::IsKeyFrame);
} else if (type == MSH264NaluTypeSPS) {
_status |= Status::HasSPS;
_status.set(StatusFlag::HasSPS);
if (updateParameterSet(&_lastSps, nal)) {
_status |= Status::NewSPS;
_status.set(StatusFlag::NewSPS);
}
} else if (type == MSH264NaluTypePPS) {
_status |= Status::HasPPS;
_status.set(StatusFlag::HasPPS);
if (updateParameterSet(&_lastPps, nal)) {
_status |= Status::NewPPS;
_status.set(StatusFlag::NewPPS);
}
}
ms_queue_put(&_q, nal);
......@@ -545,58 +553,6 @@ int Rfc3984Unpacker::isUniqueISlice(const uint8_t *slice_header) {
}; // end of mediastreamer2 namespace
//=================================================
// Global public functions
//=================================================
unsigned int operator&(mediastreamer2::UnpackingStatus val1, mediastreamer2::UnpackingStatus val2) {
return static_cast<unsigned int>(val1) & static_cast<unsigned int>(val1);
}
unsigned int operator&(unsigned int val1, mediastreamer2::UnpackingStatus val2) {
return val1 & static_cast<unsigned int>(val2);
}
unsigned int &operator&=(unsigned int &val1, mediastreamer2::UnpackingStatus val2) {
return val1 &= static_cast<unsigned int>(val2);
}
unsigned int operator|(mediastreamer2::UnpackingStatus val1, mediastreamer2::UnpackingStatus val2) {
return static_cast<unsigned int>(val1) & static_cast<unsigned int>(val1);
}
unsigned int operator|(unsigned int val1, mediastreamer2::UnpackingStatus val2) {
return val1 | static_cast<unsigned int>(val2);
}
unsigned int &operator|=(unsigned int &val1, mediastreamer2::UnpackingStatus val2) {
return val1 |= static_cast<unsigned int>(val2);
}
unsigned int operator&(mediastreamer2::Rfc3984Unpacker::Status val1, mediastreamer2::Rfc3984Unpacker::Status val2) {
return static_cast<unsigned int>(val1) & static_cast<unsigned int>(val1);
}
unsigned int operator&(unsigned int val1, mediastreamer2::Rfc3984Unpacker::Status val2) {
return val1 & static_cast<unsigned int>(val2);
}
unsigned int &operator&=(unsigned int &val1, mediastreamer2::Rfc3984Unpacker::Status val2) {
return val1 &= static_cast<unsigned int>(val2);
}
unsigned int operator|(mediastreamer2::Rfc3984Unpacker::Status val1, mediastreamer2::Rfc3984Unpacker::Status val2) {
return static_cast<unsigned int>(val1) & static_cast<unsigned int>(val1);
}
unsigned int operator|(unsigned int val1, mediastreamer2::Rfc3984Unpacker::Status val2) {
return val1 | static_cast<unsigned int>(val2);
}
unsigned int &operator|=(unsigned int &val1, mediastreamer2::Rfc3984Unpacker::Status val2) {
return val1 |= static_cast<unsigned int>(val2);
}
//==================================================
// C wrapper implementation
//==================================================
......@@ -645,7 +601,7 @@ extern "C" {
}
unsigned int rfc3984_unpack2(Rfc3984Context *ctx, mblk_t *im, MSQueue *naluq) {
return ctx->unpacker.unpack(im, naluq);
return ctx->unpacker.unpack(im, naluq).to_ulong();
}
}
......@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once
#include <bitset>
#include <memory>
#include "mediastreamer2/mscommon.h"
......@@ -116,26 +117,28 @@ public:
virtual MSQueue *getNalus() = 0;
};
enum class UnpackingStatus {
FrameAvailable = 1,
FrameCorrupted = 1<<1,
IsKeyFrame = 1<<2
};
class AbstractUnpacker {
public:
class StatusFlag {
public:
static const unsigned int FrameAvailable = 0;
static const unsigned int FrameCorrupted = 1;
static const unsigned int IsKeyFrame = 2;
};
typedef std::bitset<32> Status;
~AbstractUnpacker();
unsigned int unpack(mblk_t *im, MSQueue *out);
Status unpack(mblk_t *im, MSQueue *out);
protected:
unsigned int outputFrame(MSQueue *out, unsigned int flags);
Status outputFrame(MSQueue *out, Status flags);
void storeNal(mblk_t *nal);
virtual uint8_t getNaluType(const mblk_t *nalu) const = 0;
MSQueue _q;
unsigned int _status = 0;
Status _status = 0;
uint32_t _lastTs = 0x943FEA43;
bool _initializedRefCSeq = false;
uint16_t _refCSeq = 0;
......@@ -145,16 +148,18 @@ protected:
class Rfc3984Unpacker {
public:
enum class Status {
FrameAvailable = 1,
FrameCorrupted = 1<<1,
IsKeyFrame = 1<<2, // set when a frame has SPS + PPS or IDR (possibly both)
NewSPS = 1<<3,
NewPPS = 1<<4,
HasSPS = 1<<5,
HasPPS = 1<<6,
HasIDR = 1<<7,
class StatusFlag {
public:
static const size_t FrameAvailable = 0;
static const size_t FrameCorrupted = 1;
static const size_t IsKeyFrame = 2; // set when a frame has SPS + PPS or IDR (possibly both)
static const size_t NewSPS = 3;
static const size_t NewPPS = 4;
static const size_t HasSPS = 5;
static const size_t HasPPS = 6;
static const size_t HasIDR = 7;
};
typedef std::bitset<32> Status;
Rfc3984Unpacker();
~Rfc3984Unpacker();
......@@ -169,10 +174,10 @@ public:
* @return a bitmask of Rfc3984Status values.
* The return value is a bitmask of the #Rfc3984Status enum.
**/
unsigned int unpack(mblk_t *im, MSQueue *naluq);
Status unpack(mblk_t *im, MSQueue *naluq);
private:
unsigned int outputFrame(MSQueue *out, unsigned int flags);
Status outputFrame(MSQueue *out, const Status &flags);
void storeNal(mblk_t *nal);
bool_t updateParameterSet(mblk_t **last_parameter_set, mblk_t *new_parameter_set);
......@@ -181,7 +186,7 @@ private:
MSQueue _q;
H264FUAAggregator _fuaAggregator;
H264StapASpliter _stapASpliter;
unsigned int _status = 0;
Status _status;
mblk_t *_sps = nullptr;
mblk_t *_pps = nullptr;
mblk_t *_lastSps = nullptr;
......@@ -192,19 +197,3 @@ private:
};
}; // end of mediastreamer2 namespace
unsigned int operator&(mediastreamer2::UnpackingStatus val1, mediastreamer2::UnpackingStatus val2);
unsigned int operator&(unsigned int val1, mediastreamer2::UnpackingStatus val2);
unsigned int &operator&=(unsigned int &val1, mediastreamer2::UnpackingStatus val2);
unsigned int operator|(mediastreamer2::UnpackingStatus val1, mediastreamer2::UnpackingStatus val2);
unsigned int operator|(unsigned int val1, mediastreamer2::UnpackingStatus val2);
unsigned int &operator|=(unsigned int &val1, mediastreamer2::UnpackingStatus val2);
unsigned int operator&(mediastreamer2::Rfc3984Unpacker::Status val1, mediastreamer2::Rfc3984Unpacker::Status val2);
unsigned int operator&(unsigned int val1, mediastreamer2::Rfc3984Unpacker::Status val2);
unsigned int &operator&=(unsigned int &val1, mediastreamer2::Rfc3984Unpacker::Status val2);
unsigned int operator|(mediastreamer2::Rfc3984Unpacker::Status val1, mediastreamer2::Rfc3984Unpacker::Status val2);
unsigned int operator|(unsigned int val1, mediastreamer2::Rfc3984Unpacker::Status val2);
unsigned int &operator|=(unsigned int &val1, mediastreamer2::Rfc3984Unpacker::Status val2);
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