avformat/hvcc: zero initialize the nal buffers past the last written byte
[ffmpeg.git] / libavcodec / vp9_parser.c
index ab33c33..2d622ac 100644 (file)
  */
 
 #include "libavutil/intreadwrite.h"
+#include "libavcodec/get_bits.h"
 #include "parser.h"
 
 typedef struct VP9ParseContext {
     int n_frames; // 1-8
     int size[8];
+    int marker_size;
     int64_t pts;
 } VP9ParseContext;
 
-static void parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size)
+static int parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size)
 {
     VP9ParseContext *s = ctx->priv_data;
+    GetBitContext gb;
+    int res, profile, keyframe, invisible;
+
+    if ((res = init_get_bits8(&gb, buf, size)) < 0)
+        return res;
+    get_bits(&gb, 2); // frame marker
+    profile  = get_bits1(&gb);
+    profile |= get_bits1(&gb) << 1;
+    if (profile == 3) profile += get_bits1(&gb);
+
+    if (get_bits1(&gb)) {
+        keyframe = 0;
+        invisible = 0;
+    } else {
+        keyframe  = !get_bits1(&gb);
+        invisible = !get_bits1(&gb);
+    }
 
-    if (buf[0] & 0x4) {
+    if (!keyframe) {
         ctx->pict_type = AV_PICTURE_TYPE_P;
         ctx->key_frame = 0;
     } else {
@@ -42,7 +61,7 @@ static void parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size)
         ctx->key_frame = 1;
     }
 
-    if (buf[0] & 0x2) {
+    if (!invisible) {
         if (ctx->pts == AV_NOPTS_VALUE)
             ctx->pts = s->pts;
         s->pts = AV_NOPTS_VALUE;
@@ -50,6 +69,8 @@ static void parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size)
         s->pts = ctx->pts;
         ctx->pts = AV_NOPTS_VALUE;
     }
+
+    return 0;
 }
 
 static int parse(AVCodecParserContext *ctx,
@@ -69,6 +90,21 @@ static int parse(AVCodecParserContext *ctx,
     }
 
     if (s->n_frames > 0) {
+        int i;
+        int size_sum = 0;
+
+        for (i = 0; i < s->n_frames ;i++)
+            size_sum += s->size[i];
+        size_sum += s->marker_size;
+
+        if (size_sum != size) {
+            av_log(avctx, AV_LOG_ERROR, "Inconsistent input frame sizes %d %d\n",
+                   size_sum, size);
+            s->n_frames = 0;
+        }
+    }
+
+    if (s->n_frames > 0) {
         *out_data = data;
         *out_size = s->size[--s->n_frames];
         parse_frame(ctx, *out_data, *out_size);
@@ -111,6 +147,7 @@ static int parse(AVCodecParserContext *ctx,
                     data += sz; \
                     size -= sz; \
                 } \
+                s->marker_size = size; \
                 parse_frame(ctx, *out_data, *out_size); \
                 return *out_size