Skip to content

Commit 40e80b1

Browse files
authored
Fix overwriting of 7-bit PictureID when doing VP8 simulcast (#3121)
1 parent e139a1c commit 40e80b1

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

fuzzers/rtp_fuzzer.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
9292
janus_h264_is_keyframe(payload, plen);
9393

9494
/* VP8 targets */
95+
gboolean m = FALSE;
9596
uint16_t picid = 0;
9697
uint8_t tlzi = 0, tid = 0, ybit = 0, keyidx = 0;
9798
janus_vp8_simulcast_context vp8_context;
9899
memset(&vp8_context, 0, sizeof(janus_vp8_simulcast_context));
99100
janus_vp8_is_keyframe(payload, plen);
100-
janus_vp8_parse_descriptor(payload, plen, &picid, &tlzi, &tid, &ybit, &keyidx);
101+
janus_vp8_parse_descriptor(payload, plen, &m, &picid, &tlzi, &tid, &ybit, &keyidx);
101102
janus_vp8_simulcast_descriptor_update(copy_payload, plen, &vp8_context, TRUE);
102103

103104
/* VP9 targets */

src/rtp.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1210,12 +1210,13 @@ gboolean janus_rtp_simulcasting_context_process_rtp(janus_rtp_simulcasting_conte
12101210
/* Temporal layers are only available for VP8, so don't do anything else for other codecs */
12111211
if(vcodec == JANUS_VIDEOCODEC_VP8) {
12121212
/* Check if there's any temporal scalability to take into account */
1213+
gboolean m = FALSE;
12131214
uint16_t picid = 0;
12141215
uint8_t tlzi = 0;
12151216
uint8_t tid = 0;
12161217
uint8_t ybit = 0;
12171218
uint8_t keyidx = 0;
1218-
if(janus_vp8_parse_descriptor(payload, plen, &picid, &tlzi, &tid, &ybit, &keyidx) == 0) {
1219+
if(janus_vp8_parse_descriptor(payload, plen, &m, &picid, &tlzi, &tid, &ybit, &keyidx) == 0) {
12191220
//~ JANUS_LOG(LOG_WARN, "%"SCNu16", %u, %u, %u, %u\n", picid, tlzi, tid, ybit, keyidx);
12201221
if(context->templayer != context->templayer_target && tid == context->templayer_target) {
12211222
/* FIXME We should be smarter in deciding when to switch */

src/utils.c

+15-5
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ gboolean janus_h265_is_keyframe(const char *buffer, int len) {
916916
}
917917

918918
int janus_vp8_parse_descriptor(char *buffer, int len,
919-
uint16_t *picid, uint8_t *tl0picidx, uint8_t *tid, uint8_t *y, uint8_t *keyidx) {
919+
gboolean *m, uint16_t *picid, uint8_t *tl0picidx, uint8_t *tid, uint8_t *y, uint8_t *keyidx) {
920920
if(!buffer || len < 6)
921921
return -1;
922922
if(picid)
@@ -951,6 +951,8 @@ int janus_vp8_parse_descriptor(char *buffer, int len,
951951
partpicid = (wholepicid & 0x7FFF);
952952
buffer++;
953953
}
954+
if(m)
955+
*m = (mbit ? TRUE : FALSE);
954956
if(picid)
955957
*picid = partpicid;
956958
}
@@ -976,7 +978,7 @@ int janus_vp8_parse_descriptor(char *buffer, int len,
976978
return 0;
977979
}
978980

979-
static int janus_vp8_replace_descriptor(char *buffer, int len, uint16_t picid, uint8_t tl0picidx) {
981+
static int janus_vp8_replace_descriptor(char *buffer, int len, gboolean m, uint16_t picid, uint8_t tl0picidx) {
980982
if(!buffer || len < 6)
981983
return -1;
982984
uint8_t vp8pd = *buffer;
@@ -994,7 +996,7 @@ static int janus_vp8_replace_descriptor(char *buffer, int len, uint16_t picid, u
994996
buffer++;
995997
vp8pd = *buffer;
996998
uint8_t mbit = (vp8pd & 0x80);
997-
if(!mbit) {
999+
if(!mbit || !m) {
9981000
*buffer = picid;
9991001
} else {
10001002
uint16_t wholepicid = htons(picid);
@@ -1031,13 +1033,14 @@ void janus_vp8_simulcast_context_reset(janus_vp8_simulcast_context *context) {
10311033
void janus_vp8_simulcast_descriptor_update(char *buffer, int len, janus_vp8_simulcast_context *context, gboolean switched) {
10321034
if(!buffer || len < 0)
10331035
return;
1036+
gboolean m = FALSE;
10341037
uint16_t picid = 0;
10351038
uint8_t tlzi = 0;
10361039
uint8_t tid = 0;
10371040
uint8_t ybit = 0;
10381041
uint8_t keyidx = 0;
10391042
/* Parse the identifiers in the VP8 payload descriptor */
1040-
if(janus_vp8_parse_descriptor(buffer, len, &picid, &tlzi, &tid, &ybit, &keyidx) < 0)
1043+
if(janus_vp8_parse_descriptor(buffer, len, &m, &picid, &tlzi, &tid, &ybit, &keyidx) < 0)
10411044
return;
10421045
if(switched) {
10431046
context->base_picid_prev = context->last_picid;
@@ -1046,9 +1049,16 @@ void janus_vp8_simulcast_descriptor_update(char *buffer, int len, janus_vp8_simu
10461049
context->base_tlzi = tlzi;
10471050
}
10481051
context->last_picid = (picid-context->base_picid)+context->base_picid_prev+1;
1052+
if(!m && context->last_picid > 127) {
1053+
context->last_picid -= 128;
1054+
if(context->last_picid > 127)
1055+
context->last_picid = 0;
1056+
} else if(m && context->last_picid > 32767) {
1057+
context->last_picid -= 32768;
1058+
}
10491059
context->last_tlzi = (tlzi-context->base_tlzi)+context->base_tlzi_prev+1;
10501060
/* Overwrite the values in the VP8 payload descriptors with the ones we have */
1051-
janus_vp8_replace_descriptor(buffer, len, context->last_picid, context->last_tlzi);
1061+
janus_vp8_replace_descriptor(buffer, len, m, context->last_picid, context->last_tlzi);
10521062
}
10531063

10541064
/* Helper method to parse a VP9 RTP video frame and get some SVC-related info:

src/utils.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -356,14 +356,15 @@ void janus_vp8_simulcast_context_reset(janus_vp8_simulcast_context *context);
356356
/*! \brief Helper method to parse a VP8 payload descriptor for useful info (e.g., when simulcasting)
357357
* @param[in] buffer The RTP payload to process
358358
* @param[in] len The length of the RTP payload
359+
* @param[out] m Whether the Picture ID is 15 bit or 7 bit
359360
* @param[out] picid The Picture ID
360361
* @param[out] tl0picidx Temporal level zero index
361362
* @param[out] tid Temporal-layer index
362363
* @param[out] y Layer sync bit
363364
* @param[out] keyidx Temporal key frame index
364365
* @returns 0 in case of success, a negative integer otherwise */
365366
int janus_vp8_parse_descriptor(char *buffer, int len,
366-
uint16_t *picid, uint8_t *tl0picidx, uint8_t *tid, uint8_t *y, uint8_t *keyidx);
367+
gboolean *m, uint16_t *picid, uint8_t *tl0picidx, uint8_t *tid, uint8_t *y, uint8_t *keyidx);
367368

368369
/*! \brief Use the context info to update the RTP header of a packet, if needed
369370
* @param[in] buffer The RTP payload to process

0 commit comments

Comments
 (0)