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
53c3365c
Commit
53c3365c
authored
Apr 19, 2018
by
François Grisez
Browse files
Migrates unpacking status from enum to C++ bitset
parent
ef0fa4bd
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
63 additions
and
119 deletions
+63
-119
src/videofilters/h264dec.cpp
src/videofilters/h264dec.cpp
+3
-4
src/voip/rfc3984.cpp
src/voip/rfc3984.cpp
+34
-78
src/voip/rfc3984.hpp
src/voip/rfc3984.hpp
+26
-37
No files found.
src/videofilters/h264dec.cpp
View file @
53c3365c
...
...
@@ -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
::
Status
Flag
::
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
::
Status
Flag
::
FrameCorrupted
)
)
requestPLI
=
TRUE
;
}
d
->
packet_num
++
;
}
...
...
src/voip/rfc3984.cpp
View file @
53c3365c
...
...
@@ -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
|=
Unpacking
Status
::
FrameCorrupted
;
_status
.
set
(
Status
Flag
::
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
(
Status
Flag
::
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
(
Status
Flag
::
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
(
Status
Flag
::
FrameCorrupted
))
{
if
(
res
.
test
(
Status
Flag
::
HasSPS
)
&&
res
.
test
(
Status
Flag
::
HasPPS
)
&&
!
res
.
test
(
Status
Flag
::
HasIDR
)
&&
!
res
.
test
(
Status
Flag
::
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
(
Status
Flag
::
HasSPS
)
&&
_status
.
test
(
Status
Flag
::
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
(
Status
Flag
::
IsKeyFrame
)
;
}
if
(
type
==
MSH264NaluTypeIDR
)
{
_status
|=
Status
::
HasIDR
;
_status
|=
Status
::
IsKeyFrame
;
_status
.
set
(
Status
Flag
::
HasIDR
)
;
_status
.
set
(
Status
Flag
::
IsKeyFrame
)
;
}
else
if
(
type
==
MSH264NaluTypeSPS
)
{
_status
|=
Status
::
HasSPS
;
_status
.
set
(
Status
Flag
::
HasSPS
)
;
if
(
updateParameterSet
(
&
_lastSps
,
nal
))
{
_status
|=
Status
::
NewSPS
;
_status
.
set
(
Status
Flag
::
NewSPS
)
;
}
}
else
if
(
type
==
MSH264NaluTypePPS
)
{
_status
|=
Status
::
HasPPS
;
_status
.
set
(
Status
Flag
::
HasPPS
)
;
if
(
updateParameterSet
(
&
_lastPps
,
nal
))
{
_status
|=
Status
::
NewPPS
;
_status
.
set
(
Status
Flag
::
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
()
;
}
}
src/voip/rfc3984.hpp
View file @
53c3365c
...
...
@@ -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
);
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