]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/v210dec.c
avcodec/mss4: Check input size against skip bits
[ffmpeg] / libavcodec / v210dec.c
index 99199ddc157a766a0ee826aa81108d152df254d0..5a33d8c08997636fa65f8ef057a2a0cc2e339dfd 100644 (file)
@@ -27,6 +27,7 @@
 #include "libavutil/bswap.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
+#include "libavutil/intreadwrite.h"
 
 #define READ_PIXELS(a, b, c)         \
     do {                             \
@@ -49,6 +50,13 @@ static void v210_planar_unpack_c(const uint32_t *src, uint16_t *y, uint16_t *u,
     }
 }
 
+av_cold void ff_v210dec_init(V210DecContext *s)
+{
+    s->unpack_frame = v210_planar_unpack_c;
+    if (ARCH_X86)
+        ff_v210_x86_init(s);
+}
+
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     V210DecContext *s = avctx->priv_data;
@@ -56,10 +64,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = AV_PIX_FMT_YUV422P10;
     avctx->bits_per_raw_sample = 10;
 
-    s->unpack_frame            = v210_planar_unpack_c;
-
-    if (HAVE_MMX)
-        ff_v210_x86_init(s);
+    s->aligned_input = 0;
+    ff_v210dec_init(s);
 
     return 0;
 }
@@ -92,12 +98,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             return AVERROR_INVALIDDATA;
         }
     }
+    if (   avctx->codec_tag == MKTAG('C', '2', '1', '0')
+        && avpkt->size > 64
+        && AV_RN32(psrc) == AV_RN32("INFO")
+        && avpkt->size - 64 >= stride * avctx->height)
+        psrc += 64;
 
-    aligned_input = !((uintptr_t)psrc & 0xf) && !(stride & 0xf);
+    aligned_input = !((uintptr_t)psrc & 0x1f) && !(stride & 0x1f);
     if (aligned_input != s->aligned_input) {
         s->aligned_input = aligned_input;
-        if (HAVE_MMX)
-            ff_v210_x86_init(s);
+        ff_v210dec_init(s);
     }
 
     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
@@ -113,7 +123,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         const uint32_t *src = (const uint32_t*)psrc;
         uint32_t val;
 
-        w = (avctx->width / 6) * 6;
+        w = (avctx->width / 12) * 12;
         s->unpack_frame(src, y, u, v, w);
 
         y += w;
@@ -121,6 +131,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         v += w >> 1;
         src += (w << 1) / 3;
 
+        if (w < avctx->width - 5) {
+            READ_PIXELS(u, y, v);
+            READ_PIXELS(y, u, y);
+            READ_PIXELS(v, y, u);
+            READ_PIXELS(y, v, y);
+            w += 6;
+        }
+
         if (w < avctx->width - 1) {
             READ_PIXELS(u, y, v);