Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
mediastreamer2
Commits
3cedee87
Commit
3cedee87
authored
Apr 25, 2018
by
François Grisez
Browse files
Create an abstract class for packers
parent
e2fdd202
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
178 additions
and
147 deletions
+178
-147
src/videofilters/mkv.cpp
src/videofilters/mkv.cpp
+1
-1
src/voip/rfc3984.cpp
src/voip/rfc3984.cpp
+107
-107
src/voip/rfc3984.hpp
src/voip/rfc3984.hpp
+70
-39
No files found.
src/videofilters/mkv.cpp
View file @
3cedee87
...
...
@@ -292,7 +292,7 @@ typedef struct {
static
void
*
h264_module_new
(
MSFactory
*
factory
)
{
H264Module
*
mod
=
bctbx_new0
(
H264Module
,
1
);
mod
->
packer
=
new
Rfc3984Packer
(
factory
);
mod
->
packer
->
setMode
(
Rfc3984
Packer
::
NonInterleavedMode
);
mod
->
packer
->
setMode
(
Packer
::
NonInterleavedMode
);
mod
->
unpacker
=
new
Rfc3984Unpacker
();
return
mod
;
}
...
...
src/voip/rfc3984.cpp
View file @
3cedee87
...
...
@@ -30,114 +30,21 @@ using namespace std;
namespace
mediastreamer2
{
// ========================
// H264NaluToStapAggregator
// ========================
void
H264NaluToStapAggregator
::
setMaxSize
(
size_t
maxSize
)
{
if
(
isAggregating
())
{
throw
logic_error
(
"changing payload size while aggregating NALus into a STAP-A"
);
}
_maxsize
=
maxSize
;
}
mblk_t
*
H264NaluToStapAggregator
::
feedNalu
(
mblk_t
*
nalu
)
{
size_t
size
=
msgdsize
(
nalu
);
if
(
_stap
==
nullptr
)
{
_stap
=
nalu
;
_size
=
size
+
3
;
/* STAP-A header + size */
}
else
{
if
((
_size
+
size
)
<
(
_maxsize
-
2
))
{
_stap
=
concatNalus
(
_stap
,
nalu
);
_size
+=
(
size
+
2
);
/* +2 for the STAP-A size field */
}
else
{
return
completeAggregation
();
}
}
return
nullptr
;
}
void
H264NaluToStapAggregator
::
reset
()
{
if
(
_stap
)
freemsg
(
_stap
);
_size
=
0
;
}
mblk_t
*
H264NaluToStapAggregator
::
completeAggregation
()
{
mblk_t
*
res
=
_stap
;
_stap
=
nullptr
;
reset
();
return
res
;
}
mblk_t
*
H264NaluToStapAggregator
::
concatNalus
(
mblk_t
*
m1
,
mblk_t
*
m2
)
{
mblk_t
*
l
=
allocb
(
2
,
0
);
/*eventually append a STAP-A header to m1, if not already done*/
if
(
ms_h264_nalu_get_type
(
m1
)
!=
MSH264NaluTypeSTAPA
)
{
m1
=
prependStapA
(
m1
);
}
putNalSize
(
l
,
msgdsize
(
m2
));
l
->
b_cont
=
m2
;
concatb
(
m1
,
l
);
return
m1
;
}
mblk_t
*
H264NaluToStapAggregator
::
prependStapA
(
mblk_t
*
m
)
{
mblk_t
*
hm
=
allocb
(
3
,
0
);
H264Tools
::
nalHeaderInit
(
hm
->
b_wptr
,
ms_h264_nalu_get_nri
(
m
),
MSH264NaluTypeSTAPA
);
hm
->
b_wptr
+=
1
;
putNalSize
(
hm
,
msgdsize
(
m
));
hm
->
b_cont
=
m
;
return
hm
;
}
void
H264NaluToStapAggregator
::
putNalSize
(
mblk_t
*
m
,
size_t
sz
)
{
uint16_t
size
=
htons
((
uint16_t
)
sz
);
*
(
uint16_t
*
)
m
->
b_wptr
=
size
;
m
->
b_wptr
+=
2
;
}
//=================================================
// H264NalToFuaSpliter class
//=================================================
void
H264NaluToFuaSpliter
::
feedNalu
(
mblk_t
*
nalu
)
{
mblk_t
*
m
;
int
payload_max_size
=
_maxsize
-
2
;
/*minus FU-A header*/
uint8_t
fu_indicator
;
uint8_t
type
=
ms_h264_nalu_get_type
(
nalu
);
uint8_t
nri
=
ms_h264_nalu_get_nri
(
nalu
);
bool
start
=
true
;
H264Tools
::
nalHeaderInit
(
&
fu_indicator
,
nri
,
MSH264NaluTypeFUA
);
while
(
nalu
->
b_wptr
-
nalu
->
b_rptr
>
payload_max_size
)
{
m
=
dupb
(
nalu
);
nalu
->
b_rptr
+=
payload_max_size
;
m
->
b_wptr
=
nalu
->
b_rptr
;
m
=
H264Tools
::
prependFuIndicatorAndHeader
(
m
,
fu_indicator
,
start
,
FALSE
,
type
);
ms_queue_put
(
&
_q
,
m
);
start
=
false
;
}
/*send last packet */
m
=
H264Tools
::
prependFuIndicatorAndHeader
(
nalu
,
fu_indicator
,
FALSE
,
TRUE
,
type
);
ms_queue_put
(
&
_q
,
m
);
}
//=================================================
// Rfc3984Pacer class
//=================================================
// ======
// Packer
// ======
Rfc3984
Packer
::
Rfc3984
Packer
(
MSFactory
*
factory
)
:
_spliter
(
new
H264NaluToFuaS
pliter
()
),
_aggregator
(
new
H264NaluToStapA
ggregator
()
)
{
Packer
::
Packer
(
SpliterInterface
*
spliter
,
AggregatorInterface
*
aggregator
,
MSFactory
*
factory
)
:
_spliter
(
s
pliter
),
_aggregator
(
a
ggregator
)
{
setMaxPayloadSize
(
ms_factory_get_payload_max_size
(
factory
));
}
void
Rfc3984
Packer
::
setMaxPayloadSize
(
size_t
size
)
{
void
Packer
::
setMaxPayloadSize
(
size_t
size
)
{
_maxSize
=
size
;
_spliter
->
setMaxSize
(
size
);
_aggregator
->
setMaxSize
(
size
);
}
void
Rfc3984
Packer
::
pack
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
)
{
void
Packer
::
pack
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
)
{
switch
(
_mode
)
{
case
SingleNalUnitMode
:
packInSingleNalUnitMode
(
naluq
,
rtpq
,
ts
);
...
...
@@ -149,7 +56,7 @@ void Rfc3984Packer::pack(MSQueue *naluq, MSQueue *rtpq, uint32_t ts) {
}
// Private methods
void
Rfc3984
Packer
::
packInSingleNalUnitMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
)
{
void
Packer
::
packInSingleNalUnitMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
)
{
while
(
mblk_t
*
m
=
ms_queue_get
(
naluq
))
{
bool
end
=
ms_queue_empty
(
naluq
);
size_t
size
=
msgdsize
(
m
);
...
...
@@ -160,7 +67,7 @@ void Rfc3984Packer::packInSingleNalUnitMode(MSQueue *naluq, MSQueue *rtpq, uint3
}
}
void
Rfc3984
Packer
::
packInNonInterleavedMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
)
{
void
Packer
::
packInNonInterleavedMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
)
{
while
(
mblk_t
*
m
=
ms_queue_get
(
naluq
))
{
bool
end
=
ms_queue_empty
(
naluq
);
size_t
sz
=
msgdsize
(
m
);
...
...
@@ -199,7 +106,7 @@ void Rfc3984Packer::packInNonInterleavedMode(MSQueue *naluq, MSQueue *rtpq, uint
}
}
void
Rfc3984
Packer
::
fragNaluAndSend
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
nalu
,
bool_t
marker
)
{
void
Packer
::
fragNaluAndSend
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
nalu
,
bool_t
marker
)
{
_spliter
->
feedNalu
(
nalu
);
MSQueue
*
nalus
=
_spliter
->
getNalus
();
while
(
mblk_t
*
m
=
ms_queue_get
(
nalus
))
{
...
...
@@ -207,16 +114,109 @@ void Rfc3984Packer::fragNaluAndSend(MSQueue *rtpq, uint32_t ts, mblk_t *nalu, bo
}
}
void
Rfc3984
Packer
::
sendPacket
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
m
,
bool_t
marker
)
{
void
Packer
::
sendPacket
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
m
,
bool_t
marker
)
{
mblk_set_timestamp_info
(
m
,
ts
);
mblk_set_marker_info
(
m
,
marker
);
mblk_set_cseq
(
m
,
_refCSeq
++
);
ms_queue_put
(
rtpq
,
m
);
}
// ================
// AbstractUnpacker
// ================
// ========================
// H264NaluToStapAggregator
// ========================
void
H264NaluToStapAggregator
::
setMaxSize
(
size_t
maxSize
)
{
if
(
isAggregating
())
{
throw
logic_error
(
"changing payload size while aggregating NALus into a STAP-A"
);
}
_maxsize
=
maxSize
;
}
mblk_t
*
H264NaluToStapAggregator
::
feedNalu
(
mblk_t
*
nalu
)
{
size_t
size
=
msgdsize
(
nalu
);
if
(
_stap
==
nullptr
)
{
_stap
=
nalu
;
_size
=
size
+
3
;
/* STAP-A header + size */
}
else
{
if
((
_size
+
size
)
<
(
_maxsize
-
2
))
{
_stap
=
concatNalus
(
_stap
,
nalu
);
_size
+=
(
size
+
2
);
/* +2 for the STAP-A size field */
}
else
{
return
completeAggregation
();
}
}
return
nullptr
;
}
void
H264NaluToStapAggregator
::
reset
()
{
if
(
_stap
)
freemsg
(
_stap
);
_size
=
0
;
}
mblk_t
*
H264NaluToStapAggregator
::
completeAggregation
()
{
mblk_t
*
res
=
_stap
;
_stap
=
nullptr
;
reset
();
return
res
;
}
mblk_t
*
H264NaluToStapAggregator
::
concatNalus
(
mblk_t
*
m1
,
mblk_t
*
m2
)
{
mblk_t
*
l
=
allocb
(
2
,
0
);
/*eventually append a STAP-A header to m1, if not already done*/
if
(
ms_h264_nalu_get_type
(
m1
)
!=
MSH264NaluTypeSTAPA
)
{
m1
=
prependStapA
(
m1
);
}
putNalSize
(
l
,
msgdsize
(
m2
));
l
->
b_cont
=
m2
;
concatb
(
m1
,
l
);
return
m1
;
}
mblk_t
*
H264NaluToStapAggregator
::
prependStapA
(
mblk_t
*
m
)
{
mblk_t
*
hm
=
allocb
(
3
,
0
);
H264Tools
::
nalHeaderInit
(
hm
->
b_wptr
,
ms_h264_nalu_get_nri
(
m
),
MSH264NaluTypeSTAPA
);
hm
->
b_wptr
+=
1
;
putNalSize
(
hm
,
msgdsize
(
m
));
hm
->
b_cont
=
m
;
return
hm
;
}
void
H264NaluToStapAggregator
::
putNalSize
(
mblk_t
*
m
,
size_t
sz
)
{
uint16_t
size
=
htons
((
uint16_t
)
sz
);
*
(
uint16_t
*
)
m
->
b_wptr
=
size
;
m
->
b_wptr
+=
2
;
}
// =========================
// H264NalToFuaSpliter class
// =========================
void
H264NaluToFuaSpliter
::
feedNalu
(
mblk_t
*
nalu
)
{
mblk_t
*
m
;
int
payload_max_size
=
_maxsize
-
2
;
/*minus FU-A header*/
uint8_t
fu_indicator
;
uint8_t
type
=
ms_h264_nalu_get_type
(
nalu
);
uint8_t
nri
=
ms_h264_nalu_get_nri
(
nalu
);
bool
start
=
true
;
H264Tools
::
nalHeaderInit
(
&
fu_indicator
,
nri
,
MSH264NaluTypeFUA
);
while
(
nalu
->
b_wptr
-
nalu
->
b_rptr
>
payload_max_size
)
{
m
=
dupb
(
nalu
);
nalu
->
b_rptr
+=
payload_max_size
;
m
->
b_wptr
=
nalu
->
b_rptr
;
m
=
H264Tools
::
prependFuIndicatorAndHeader
(
m
,
fu_indicator
,
start
,
FALSE
,
type
);
ms_queue_put
(
&
_q
,
m
);
start
=
false
;
}
/*send last packet */
m
=
H264Tools
::
prependFuIndicatorAndHeader
(
nalu
,
fu_indicator
,
FALSE
,
TRUE
,
type
);
ms_queue_put
(
&
_q
,
m
);
}
// ========
// Unpacker
// ========
Unpacker
::
Unpacker
(
NaluAggregatorInterface
*
aggregator
,
NaluSpliterInterface
*
spliter
)
:
_naluAggregator
(
aggregator
),
_naluSpliter
(
spliter
)
{
ms_queue_init
(
&
_q
);
...
...
@@ -484,7 +484,7 @@ extern "C" {
ms_error
(
"invalid RFC3984 packetization mode [%d]"
,
mode
);
return
;
}
ctx
->
packer
.
setMode
(
mode
==
0
?
mediastreamer2
::
Rfc3984
Packer
::
SingleNalUnitMode
:
mediastreamer2
::
Rfc3984
Packer
::
SingleNalUnitMode
);
ctx
->
packer
.
setMode
(
mode
==
0
?
mediastreamer2
::
Packer
::
SingleNalUnitMode
:
mediastreamer2
::
Packer
::
SingleNalUnitMode
);
}
void
rfc3984_enable_stap_a
(
Rfc3984Context
*
ctx
,
bool_t
yesno
)
{
...
...
src/voip/rfc3984.hpp
View file @
3cedee87
...
...
@@ -49,13 +49,74 @@ public:
virtual
MSQueue
*
getNalus
()
=
0
;
};
class
H264NaluToStapAggregator
:
public
NaluAggregatorInterface
{
class
Packer
{
public:
enum
PacketizationMode
{
SingleNalUnitMode
,
NonInterleavedMode
};
class
AggregatorInterface
{
public:
virtual
~
AggregatorInterface
()
=
default
;
virtual
size_t
getMaxSize
()
const
=
0
;
virtual
void
setMaxSize
(
size_t
maxSize
)
=
0
;
virtual
mblk_t
*
feedNalu
(
mblk_t
*
nalu
)
=
0
;
virtual
bool
isAggregating
()
const
=
0
;
virtual
void
reset
()
=
0
;
virtual
mblk_t
*
completeAggregation
()
=
0
;
};
class
SpliterInterface
{
public:
virtual
~
SpliterInterface
()
=
default
;
virtual
size_t
getMaxSize
()
const
=
0
;
virtual
void
setMaxSize
(
size_t
maxSize
)
=
0
;
virtual
void
feedNalu
(
mblk_t
*
nalu
)
=
0
;
virtual
MSQueue
*
getNalus
()
=
0
;
};
Packer
(
SpliterInterface
*
spliter
,
AggregatorInterface
*
aggregator
)
{}
Packer
(
SpliterInterface
*
spliter
,
AggregatorInterface
*
aggregator
,
MSFactory
*
factory
);
void
setMode
(
PacketizationMode
mode
)
{
_mode
=
mode
;}
PacketizationMode
getMode
()
const
{
return
_mode
;}
// some stupid phones don't decode STAP-A packets ...
void
enableAggregation
(
bool
yesno
)
{
_aggregationEnabled
=
yesno
;}
bool
aggregationEnabled
()
const
{
return
_aggregationEnabled
;}
void
setMaxPayloadSize
(
size_t
size
);
size_t
getMaxPayloadSize
()
{
return
_maxSize
;}
// process NALus and pack them into RTP payloads
void
pack
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
);
private:
void
packInSingleNalUnitMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
);
void
packInNonInterleavedMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
);
void
fragNaluAndSend
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
nalu
,
bool_t
marker
);
void
sendPacket
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
m
,
bool_t
marker
);
size_t
_maxSize
=
MS_DEFAULT_MAX_PAYLOAD_SIZE
;
uint16_t
_refCSeq
=
0
;
PacketizationMode
_mode
=
SingleNalUnitMode
;
bool
_aggregationEnabled
=
false
;
std
::
unique_ptr
<
SpliterInterface
>
_spliter
;
std
::
unique_ptr
<
AggregatorInterface
>
_aggregator
;
};
class
H264NaluToStapAggregator
:
public
Packer
::
AggregatorInterface
{
public:
H264NaluToStapAggregator
()
{}
~
H264NaluToStapAggregator
()
{
reset
();}
size_t
getMaxSize
()
const
{
return
_maxsize
;}
void
setMaxSize
(
size_t
maxSize
);
size_t
getMaxSize
()
const
override
{
return
_maxsize
;}
void
setMaxSize
(
size_t
maxSize
)
override
;
mblk_t
*
feedNalu
(
mblk_t
*
nalu
)
override
;
bool
isAggregating
()
const
override
{
return
bool
(
_stap
);}
...
...
@@ -72,13 +133,13 @@ private:
size_t
_maxsize
=
MS_DEFAULT_MAX_PAYLOAD_SIZE
;
};
class
H264NaluToFuaSpliter
:
public
Nalu
SpliterInterface
{
class
H264NaluToFuaSpliter
:
public
Packer
::
SpliterInterface
{
public:
H264NaluToFuaSpliter
()
{
ms_queue_init
(
&
_q
);}
~
H264NaluToFuaSpliter
()
{
ms_queue_flush
(
&
_q
);}
size_t
getMaxSize
()
const
{
return
_maxsize
;}
void
setMaxSize
(
size_t
maxSize
)
{
_maxsize
=
maxSize
;}
size_t
getMaxSize
()
const
override
{
return
_maxsize
;}
void
setMaxSize
(
size_t
maxSize
)
override
{
_maxsize
=
maxSize
;}
void
feedNalu
(
mblk_t
*
nalu
)
override
;
MSQueue
*
getNalus
()
override
{
return
&
_q
;};
...
...
@@ -88,45 +149,15 @@ private:
MSQueue
_q
;
};
class
Rfc3984Packer
{
class
Rfc3984Packer
:
public
Packer
{
public:
enum
PacketizationMode
{
SingleNalUnitMode
,
NonInterleavedMode
};
Rfc3984Packer
()
:
_spliter
(
new
H264NaluToFuaSpliter
()),
_aggregator
(
new
H264NaluToStapAggregator
())
{}
Rfc3984Packer
(
MSFactory
*
factory
);
void
setMode
(
PacketizationMode
mode
)
{
_mode
=
mode
;}
PacketizationMode
getMode
()
const
{
return
_mode
;}
// some stupid phones don't decode STAP-A packets ...
void
enableAggregation
(
bool
yesno
)
{
_aggregationEnabled
=
yesno
;}
bool
aggregationEnabled
()
const
{
return
_aggregationEnabled
;}
void
setMaxPayloadSize
(
size_t
size
);
size_t
getMaxPayloadSize
()
{
return
_maxSize
;}
// process NALus and pack them into RTP payloads
void
pack
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
);
private:
void
packInSingleNalUnitMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
);
void
packInNonInterleavedMode
(
MSQueue
*
naluq
,
MSQueue
*
rtpq
,
uint32_t
ts
);
void
fragNaluAndSend
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
nalu
,
bool_t
marker
);
void
sendPacket
(
MSQueue
*
rtpq
,
uint32_t
ts
,
mblk_t
*
m
,
bool_t
marker
);
static
mblk_t
*
concatNalus
(
mblk_t
*
m1
,
mblk_t
*
m2
);
static
mblk_t
*
prependStapA
(
mblk_t
*
m
);
static
void
putNalSize
(
mblk_t
*
m
,
size_t
sz
);
size_t
_maxSize
=
MS_DEFAULT_MAX_PAYLOAD_SIZE
;
uint16_t
_refCSeq
=
0
;
PacketizationMode
_mode
=
SingleNalUnitMode
;
bool
_aggregationEnabled
=
false
;
std
::
unique_ptr
<
H264NaluToFuaSpliter
>
_spliter
;
std
::
unique_ptr
<
H264NaluToStapAggregator
>
_aggregator
;
Rfc3984Packer
()
:
Packer
(
new
H264NaluToFuaSpliter
(),
new
H264NaluToStapAggregator
())
{}
Rfc3984Packer
(
MSFactory
*
factory
)
:
Packer
(
new
H264NaluToFuaSpliter
(),
new
H264NaluToStapAggregator
(),
factory
)
{}
};
class
Unpacker
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment