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
4e2c98bb
Commit
4e2c98bb
authored
May 19, 2014
by
Ghislain MARY
Browse files
Fix last VP8 artifacts with AVPF enabled + add some debug traces.
parent
f080bec2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
95 additions
and
12 deletions
+95
-12
src/voip/vp8rtpfmt.c
src/voip/vp8rtpfmt.c
+95
-12
No files found.
src/voip/vp8rtpfmt.c
View file @
4e2c98bb
...
...
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "vp8rtpfmt.h"
/*#define VP8RTPFMT_OUTPUT_INCOMPLETE_PARTITIONS*/
/*#define VP8RTPFMT_DEBUG*/
...
...
@@ -73,7 +74,7 @@ static void print_partition(void *data) {
static
void
print_frame
(
void
*
data
)
{
Vp8RtpFmtFrame
*
frame
=
(
Vp8RtpFmtFrame
*
)
data
;
ms_message
(
"frame [%p]:
\t
ts=%u
\t
pictureid=
%u
\t
N=%d
\t
error=%d"
,
ms_message
(
"frame [%p]:
\t
ts=%u
\t
pictureid=
0x%04x
\t
N=%d
\t
error=%d"
,
frame
,
get_frame_ts
(
frame
),
get_frame_pictureid
(
frame
),
is_frame_non_reference
(
frame
),
frame
->
error
);
ms_list_for_each
(
frame
->
partitions_list
,
print_partition
);
}
...
...
@@ -267,6 +268,7 @@ static void generate_partitions_list(Vp8RtpFmtUnpackerCtx *ctx, Vp8RtpFmtFrame *
frame
->
error
=
Vp8RtpFmtIncompleteFrame
;
}
else
{
/* Notify that at least one frame has been completely lost. */
ms_warning
(
"VP8 decoder gap in sequence numbers."
);
send_pli
(
ctx
);
}
}
...
...
@@ -308,6 +310,12 @@ static void generate_partitions_list(Vp8RtpFmtUnpackerCtx *ctx, Vp8RtpFmtFrame *
}
}
static
void
mark_last_present_partition_as_last_in_frame
(
Vp8RtpFmtFrame
*
frame
)
{
uint8_t
nb_partitions
=
ms_list_size
(
frame
->
partitions_list
);
Vp8RtpFmtPartition
*
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
nb_partitions
-
1
);
partition
->
last_partition_of_frame
=
TRUE
;
}
static
bool_t
is_first_partition_present_in_frame
(
Vp8RtpFmtFrame
*
frame
)
{
Vp8RtpFmtPartition
*
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
0
);
Vp8RtpFmtPacket
*
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
...
...
@@ -317,6 +325,36 @@ static bool_t is_first_partition_present_in_frame(Vp8RtpFmtFrame *frame) {
return
FALSE
;
}
static
bool_t
is_last_partition_present_in_frame
(
Vp8RtpFmtFrame
*
frame
)
{
uint8_t
nb_partitions
=
ms_list_size
(
frame
->
partitions_list
);
Vp8RtpFmtPartition
*
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
nb_partitions
-
1
);
return
partition
->
last_partition_of_frame
;
}
static
bool_t
are_all_partitions_present_in_frame
(
Vp8RtpFmtFrame
*
frame
)
{
uint8_t
nb_partitions
=
ms_list_size
(
frame
->
partitions_list
);
Vp8RtpFmtPartition
*
partition
;
Vp8RtpFmtPacket
*
packet
;
uint8_t
i
;
for
(
i
=
0
;
i
<
nb_partitions
;
i
++
)
{
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
i
);
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
if
(
packet
->
pd
->
pid
!=
i
)
return
FALSE
;
}
return
TRUE
;
}
static
bool_t
is_complete_frame
(
Vp8RtpFmtFrame
*
frame
)
{
if
(
is_first_partition_present_in_frame
(
frame
)
!=
TRUE
)
return
FALSE
;
if
(
is_last_partition_present_in_frame
(
frame
)
!=
TRUE
)
{
mark_last_present_partition_as_last_in_frame
(
frame
);
return
FALSE
;
}
return
are_all_partitions_present_in_frame
(
frame
);
}
static
void
add_frame
(
Vp8RtpFmtUnpackerCtx
*
ctx
,
MSList
**
packets_list
)
{
Vp8RtpFmtFrame
*
frame
;
...
...
@@ -324,9 +362,7 @@ static void add_frame(Vp8RtpFmtUnpackerCtx *ctx, MSList **packets_list) {
frame
=
ms_new0
(
Vp8RtpFmtFrame
,
1
);
generate_partitions_list
(
ctx
,
frame
,
*
packets_list
);
if
(
ms_list_size
(
frame
->
partitions_list
)
>
0
)
{
if
(
is_first_partition_present_in_frame
(
frame
)
==
TRUE
)
{
/* The first packet of the frame is really the start of the frame. */
}
else
{
if
(
is_complete_frame
(
frame
)
!=
TRUE
)
{
frame
->
error
=
Vp8RtpFmtIncompleteFrame
;
}
ctx
->
frames_list
=
ms_list_append
(
ctx
->
frames_list
,
(
void
*
)
frame
);
...
...
@@ -368,6 +404,11 @@ static void generate_frames_list(Vp8RtpFmtUnpackerCtx *ctx, MSList *packets_list
add_frame
(
ctx
,
&
frame_packets_list
);
}
}
if
(
ms_list_size
(
frame_packets_list
)
>
0
)
{
/* If some packets are left, add incomplete frame. */
add_frame
(
ctx
,
&
frame_packets_list
);
}
}
static
bool_t
is_frame_marker_present
(
Vp8RtpFmtFrame
*
frame
)
{
...
...
@@ -409,8 +450,11 @@ static void output_frame(MSQueue *out, Vp8RtpFmtFrame *frame) {
}
static
void
output_valid_partitions
(
Vp8RtpFmtUnpackerCtx
*
ctx
,
MSQueue
*
out
)
{
Vp8RtpFmtPartition
*
partition
=
NULL
;
Vp8RtpFmtFrame
*
frame
;
Vp8RtpFmtPartition
*
partition
=
NULL
;
#ifdef VP8RTPFMT_DEBUG
Vp8RtpFmtPacket
*
packet
=
NULL
;
#endif
int
nb_frames
=
ms_list_size
(
ctx
->
frames_list
);
int
nb_partitions
;
int
i
;
...
...
@@ -434,6 +478,12 @@ static void output_valid_partitions(Vp8RtpFmtUnpackerCtx *ctx, MSQueue *out) {
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
j
);
output_partition
(
out
,
partition
);
}
#ifdef VP8RTPFMT_DEBUG
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
if
(
packet
->
pd
->
pictureid_present
==
TRUE
)
{
ms_message
(
"VP8 decoder: Output frame with pictureID=0x%04x"
,
packet
->
pd
->
pictureid
);
}
#endif
}
else
{
/* Output the full frame in one mblk_t. */
output_frame
(
out
,
frame
);
...
...
@@ -443,6 +493,20 @@ static void output_valid_partitions(Vp8RtpFmtUnpackerCtx *ctx, MSQueue *out) {
}
else
{
if
(
ctx
->
waiting_for_reference_frame
==
TRUE
)
{
/* Do not decode frames while we are waiting for a reference frame. */
#ifdef VP8RTPFMT_DEBUG
nb_partitions
=
ms_list_size
(
frame
->
partitions_list
);
if
(
nb_partitions
>
0
)
{
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
0
);
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
}
else
{
packet
=
NULL
;
}
if
(
packet
&&
(
packet
->
pd
->
pictureid_present
==
TRUE
))
{
ms_warning
(
"VP8 decoder: Drop frame because we are waiting for reference frame: pictureID=0x%04x"
,
packet
->
pd
->
pictureid
);
}
else
#endif
ms_warning
(
"VP8 decoder: Drop frame because we are waiting for reference frame."
);
frame
->
discarded
=
TRUE
;
}
else
{
/* Drop frames until the first keyframe is successfully received. */
ms_warning
(
"VP8 frame dropped because keyframe has not been received yet."
);
...
...
@@ -452,7 +516,7 @@ static void output_valid_partitions(Vp8RtpFmtUnpackerCtx *ctx, MSQueue *out) {
}
}
else
if
(
is_frame_marker_present
(
frame
)
==
TRUE
)
{
if
(
is_first_partition_present_in_frame
(
frame
)
==
TRUE
)
{
#if
0
#if
def VP8RTPFMT_OUTPUT_INCOMPLETE_PARTITIONS
if
(
ctx
->
output_partitions
==
TRUE
)
{
/* Output the valid partitions of the frame. */
nb_partitions
=
ms_list_size
(
frame
->
partitions_list
);
...
...
@@ -470,21 +534,40 @@ static void output_valid_partitions(Vp8RtpFmtUnpackerCtx *ctx, MSQueue *out) {
#endif
{
/* Drop the frame for which some partitions are missing/invalid. */
ms_warning
(
"VP8 frame with some partitions missing/invalid."
);
#ifdef VP8RTPFMT_DEBUG
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
0
);
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
if
(
packet
->
pd
->
pictureid_present
==
TRUE
)
{
ms_warning
(
"VP8 frame with some partitions missing/invalid: pictureID=0x%04x"
,
packet
->
pd
->
pictureid
);
}
else
#endif
ms_warning
(
"VP8 frame with some partitions missing/invalid."
);
frame
->
discarded
=
TRUE
;
}
send_sli
(
ctx
,
frame
);
}
else
{
/* Drop the frame for which the first partition is missing. */
ms_warning
(
"VP8 frame without first partition."
);
#ifdef VP8RTPFMT_DEBUG
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
0
);
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
if
(
packet
->
pd
->
pictureid_present
==
TRUE
)
{
ms_warning
(
"VP8 frame without first partition: pictureID=0x%04x"
,
packet
->
pd
->
pictureid
);
}
else
#endif
ms_warning
(
"VP8 frame without first partition."
);
frame
->
discarded
=
TRUE
;
send_sli
(
ctx
,
frame
);
}
}
else
{
/* The last packet of the frame has not been received.
* Wait for the next iteration of the filter to see if we have it then. */
ms_warning
(
"VP8 frame without last packet."
);
// TODO: Try to get the missing packets at the next iteration of the filter.
/* The last packet of the frame has not been received. */
#ifdef VP8RTPFMT_DEBUG
partition
=
ms_list_nth_data
(
frame
->
partitions_list
,
0
);
packet
=
ms_list_nth_data
(
partition
->
packets_list
,
0
);
if
(
packet
->
pd
->
pictureid_present
==
TRUE
)
{
ms_warning
(
"VP8 frame without last packet: pictureID=0x%04x"
,
packet
->
pd
->
pictureid
);
}
else
#endif
ms_warning
(
"VP8 frame without last packet."
);
frame
->
discarded
=
TRUE
;
send_sli
(
ctx
,
frame
);
}
...
...
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