Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2016-04-27 14:36:57 +0300
committerThomas Volkert <thomas@netzeal.de>2016-06-14 09:00:17 +0300
commitcab237953ea60963c627df53833513a0764ff8fe (patch)
tree62e4ba612d9a0b3a78ff2feef8200c32f9a601f7
parentd50b3fe463138a8378d0d0884750bd71db825c82 (diff)
rtpdec_vp9: Support parsing the scalability structure
We still only support one single layer though, but this allows receiving streams that have this structure present even for single layer streams. Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavformat/rtpdec_vp9.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/libavformat/rtpdec_vp9.c b/libavformat/rtpdec_vp9.c
index d02c8b8525..4a7f934d6a 100644
--- a/libavformat/rtpdec_vp9.c
+++ b/libavformat/rtpdec_vp9.c
@@ -222,8 +222,64 @@ static int vp9_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_vp9_ctx,
* X: 1 if this layer index has an extended relative Picture ID.
*/
if (has_ss_data) {
- avpriv_report_missing_feature(ctx, "VP9 scalability structure data");
- return AVERROR_PATCHWELCOME;
+ int n_s, y, g, i;
+ if (len < 1) {
+ av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
+ return AVERROR_INVALIDDATA;
+ }
+ n_s = buf[0] >> 5;
+ y = !!(buf[0] & 0x10);
+ g = !!(buf[0] & 0x08);
+ buf++;
+ len--;
+ if (n_s > 0) {
+ avpriv_report_missing_feature(ctx, "VP9 scalability structure with multiple layers");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (y) {
+ if (len < 4 * (n_s + 1)) {
+ av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < n_s + 1; i++) {
+ av_unused int w, h;
+ w = AV_RB16(buf);
+ h = AV_RB16(buf + 2);
+ buf += 4;
+ len -= 4;
+ }
+ }
+ if (g) {
+ int n_g;
+ if (len < 1) {
+ av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
+ return AVERROR_INVALIDDATA;
+ }
+ n_g = buf[0];
+ buf++;
+ len--;
+ for (i = 0; i < n_g; i++) {
+ av_unused int t, u, r, j;
+ if (len < 1) {
+ av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
+ return AVERROR_INVALIDDATA;
+ }
+ t = buf[0] >> 5;
+ u = !!(buf[0] & 0x10);
+ r = (buf[0] >> 2) & 0x03;
+ buf++;
+ len--;
+ if (len < r) {
+ av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (j = 0; j < r; j++) {
+ av_unused int p_diff = buf[0];
+ buf++;
+ len--;
+ }
+ }
+ }
}
/*