]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/av1.c
avformat/mov: Don't allow negative sample sizes.
[ffmpeg] / libavformat / av1.c
index 876fd92733361424e0b3b81b429246e3b077487f..1e7a67d2f2ba57ee118409c8276ce8db8cc1429f 100644 (file)
 #include "avio.h"
 #include "avio_internal.h"
 
-int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
+static int av1_filter_obus(AVIOContext *pb, const uint8_t *buf,
+                           int size, int *offset)
 {
-    const uint8_t *end = buf + size;
+    const uint8_t *start = buf, *end = buf + size;
     int64_t obu_size;
-    int start_pos, type, temporal_id, spatial_id;
-
-    size = 0;
+    int off, start_pos, type, temporal_id, spatial_id;
+    enum {
+        START_NOT_FOUND,
+        START_FOUND,
+        END_FOUND,
+        OFFSET_IMPOSSIBLE,
+    } state = START_NOT_FOUND;
+
+    off = size = 0;
     while (buf < end) {
         int len = parse_obu_header(buf, end - buf, &obu_size, &start_pos,
                                    &type, &temporal_id, &spatial_id);
@@ -47,8 +54,16 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
         case AV1_OBU_REDUNDANT_FRAME_HEADER:
         case AV1_OBU_TILE_LIST:
         case AV1_OBU_PADDING:
+            if (state == START_FOUND)
+                state = END_FOUND;
             break;
         default:
+            if (state == START_NOT_FOUND) {
+                off   = buf - start;
+                state = START_FOUND;
+            } else if (state == END_FOUND) {
+                state = OFFSET_IMPOSSIBLE;
+            }
             if (pb)
                 avio_write(pb, buf, len);
             size += len;
@@ -57,19 +72,35 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
         buf += len;
     }
 
+    if (offset)
+        *offset = state != OFFSET_IMPOSSIBLE ? off : -1;
+
     return size;
 }
 
-int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size)
+int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
+{
+    return av1_filter_obus(pb, buf, size, NULL);
+}
+
+int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out,
+                           int *size, int *offset)
 {
     AVIOContext pb;
     uint8_t *buf;
-    int len, ret;
+    int len, off, ret;
 
-    len = ret = ff_av1_filter_obus(NULL, in, *size);
+    len = ret = av1_filter_obus(NULL, in, *size, &off);
     if (ret < 0) {
         return ret;
     }
+    if (off >= 0) {
+        *out    = (uint8_t *)in;
+        *size   = len;
+        *offset = off;
+
+        return 0;
+    }
 
     buf = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE);
     if (!buf)
@@ -77,14 +108,14 @@ int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size)
 
     ffio_init_context(&pb, buf, len, 1, NULL, NULL, NULL, NULL);
 
-    ret = ff_av1_filter_obus(&pb, in, *size);
+    ret = av1_filter_obus(&pb, in, *size, NULL);
     av_assert1(ret == len);
 
     memset(buf + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
 
-    av_freep(out);
     *out  = buf;
     *size = len;
+    *offset = 0;
 
     return 0;
 }