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

Makes H264FUAAggregator and H264StapASpliter respectively implements...

Makes H264FUAAggregator and H264StapASpliter respectively implements NaluAggregattorInterface and NaluSpliterInterface
parent cd8452c1
......@@ -28,95 +28,6 @@ using namespace std;
namespace mediastreamer2 {
// =======================
// H264FUAAggregator class
// =======================
void H264FUAAggregator::reset() {
if (_m) {
freemsg(_m);
_m = nullptr;
}
}
mblk_t *H264FUAAggregator::aggregate(mblk_t *im) {
mblk_t *om = nullptr;
uint8_t fu_header;
uint8_t nri, type;
bool_t start, end;
bool_t marker = mblk_get_marker_info(im);
fu_header = im->b_rptr[1];
type = ms_h264_nalu_get_type(im);
start = fu_header >> 7;
end = (fu_header >> 6) & 0x1;
if (start) {
mblk_t *new_header;
nri = ms_h264_nalu_get_nri(im);
if (_m != nullptr) {
ms_error("receiving FU-A start while previous FU-A is not "
"finished");
freemsg(_m);
_m = nullptr;
}
im->b_rptr += 2; /*skip the nal header and the fu header*/
new_header = allocb(1, 0); /* allocate small fragment to put the correct nal header, this is to avoid to write on the buffer
which can break processing of other users of the buffers */
nalHeaderInit(new_header->b_wptr, nri, type);
new_header->b_wptr++;
mblk_meta_copy(im, new_header);
concatb(new_header, im);
_m = new_header;
} else {
if (_m != nullptr) {
im->b_rptr += 2;
concatb(_m, im);
} else {
ms_error("Receiving continuation FU packet but no start.");
freemsg(im);
}
}
if (end && _m) {
msgpullup(_m, -1);
om = _m;
mblk_set_marker_info(om, marker); /*set the marker bit of this aggregated NAL as the last fragment received.*/
_m = nullptr;
}
return om;
}
// =====================
// H264StapASlicer class
// =====================
H264StapASpliter::H264StapASpliter() {
ms_queue_init(&_q);
}
H264StapASpliter::~H264StapASpliter() {
ms_queue_flush(&_q);
}
void H264StapASpliter::feed(mblk_t *im) {
uint16_t sz;
for (uint8_t *p = im->b_rptr + 1; p < im->b_wptr;) {
memcpy(&sz, p, 2);
sz = ntohs(sz);
mblk_t *nal = dupb(im);
p += 2;
nal->b_rptr = p;
p += sz;
nal->b_wptr = p;
if (p > im->b_wptr) {
ms_error("Malformed STAP-A packet");
freemsg(nal);
break;
}
ms_queue_put(&_q, nal);
}
freemsg(im);
}
//=================================================
// Rfc3984Pacer class
//=================================================
......@@ -375,6 +286,87 @@ void Unpacker::storeNal(mblk_t *nal) {
ms_queue_put(&_q, nal);
}
// =======================
// H264FUAAggregator class
// =======================
mblk_t *H264FUAAggregator::feedNalu(mblk_t *im) {
mblk_t *om = nullptr;
uint8_t fu_header;
uint8_t nri, type;
bool_t start, end;
bool_t marker = mblk_get_marker_info(im);
fu_header = im->b_rptr[1];
type = ms_h264_nalu_get_type(im);
start = fu_header >> 7;
end = (fu_header >> 6) & 0x1;
if (start) {
mblk_t *new_header;
nri = ms_h264_nalu_get_nri(im);
if (_m != nullptr) {
ms_error("receiving FU-A start while previous FU-A is not "
"finished");
freemsg(_m);
_m = nullptr;
}
im->b_rptr += 2; /*skip the nal header and the fu header*/
new_header = allocb(1, 0); /* allocate small fragment to put the correct nal header, this is to avoid to write on the buffer
which can break processing of other users of the buffers */
nalHeaderInit(new_header->b_wptr, nri, type);
new_header->b_wptr++;
mblk_meta_copy(im, new_header);
concatb(new_header, im);
_m = new_header;
} else {
if (_m != nullptr) {
im->b_rptr += 2;
concatb(_m, im);
} else {
ms_error("Receiving continuation FU packet but no start.");
freemsg(im);
}
}
if (end && _m) {
msgpullup(_m, -1);
om = _m;
mblk_set_marker_info(om, marker); /*set the marker bit of this aggregated NAL as the last fragment received.*/
_m = nullptr;
}
return om;
}
void H264FUAAggregator::reset() {
if (_m) {
freemsg(_m);
_m = nullptr;
}
}
// =====================
// H264StapASlicer class
// =====================
void H264StapASpliter::feedNalu(mblk_t *im) {
uint16_t sz;
for (uint8_t *p = im->b_rptr + 1; p < im->b_wptr;) {
memcpy(&sz, p, 2);
sz = ntohs(sz);
mblk_t *nal = dupb(im);
p += 2;
nal->b_rptr = p;
p += sz;
nal->b_wptr = p;
if (p > im->b_wptr) {
ms_error("Malformed STAP-A packet");
freemsg(nal);
break;
}
ms_queue_put(&_q, nal);
}
freemsg(im);
}
//==================================================
// Rfc3984Unpacker
//==================================================
......@@ -382,6 +374,11 @@ void Unpacker::storeNal(mblk_t *nal) {
// 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);
......
......@@ -33,33 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
namespace mediastreamer2 {
class H264FUAAggregator {
public:
~H264FUAAggregator() {if (_m) freemsg(_m);}
bool isAggregating() const {return _m != nullptr;}
void reset();
mblk_t *aggregate(mblk_t *im);
private:
static void nalHeaderInit(uint8_t *h, uint8_t nri, uint8_t type) {*h=((nri&0x3)<<5) | (type & ((1<<5)-1));}
mblk_t *_m = nullptr;
};
class H264StapASpliter {
public:
H264StapASpliter();
~H264StapASpliter();
void feed(mblk_t *im);
MSQueue *getNALus() {return &_q;}
private:
MSQueue _q;
};
class Rfc3984Packer {
public:
enum PacketizationMode {
......@@ -154,6 +127,30 @@ protected:
std::unique_ptr<NaluSpliterInterface> _naluSpliter;
};
class H264FUAAggregator: public NaluAggregatorInterface {
public:
~H264FUAAggregator() {if (_m) freemsg(_m);}
mblk_t *feedNalu(mblk_t *im) override;
bool isAggregating() const override {return _m != nullptr;}
void reset() override;
private:
static void nalHeaderInit(uint8_t *h, uint8_t nri, uint8_t type) {*h=((nri&0x3)<<5) | (type & ((1<<5)-1));}
mblk_t *_m = nullptr;
};
class H264StapASpliter: public NaluSpliterInterface {
public:
H264StapASpliter() {ms_queue_init(&_q);}
~H264StapASpliter() {ms_queue_flush(&_q);}
void feedNalu(mblk_t *im) override;
MSQueue *getNalus() override {return &_q;}
private:
MSQueue _q;
};
class Rfc3984Unpacker: public Unpacker {
public:
class StatusFlag {
......@@ -165,7 +162,7 @@ public:
static const size_t HasIDR = 7;
};
Rfc3984Unpacker() = default;
Rfc3984Unpacker();
~Rfc3984Unpacker();
void setOutOfBandSpsPps(mblk_t *sps, mblk_t *pps);
......
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