]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/cbs_av1.c
lavc/qsvenc: Fix bitrate_limit to allow AVC encode in limited bitrate
[ffmpeg] / libavcodec / cbs_av1.c
index 02f168b58d5381e2c0efad89912f358789360985..c02793321800d91ee2df931ecfbb5db510f3496b 100644 (file)
@@ -207,68 +207,12 @@ static int cbs_av1_write_leb128(CodedBitstreamContext *ctx, PutBitContext *pbc,
     return 0;
 }
 
-static int cbs_av1_read_su(CodedBitstreamContext *ctx, GetBitContext *gbc,
-                           int width, const char *name,
-                           const int *subscripts, int32_t *write_to)
-{
-    int position;
-    int32_t value;
-
-    if (ctx->trace_enable)
-        position = get_bits_count(gbc);
-
-    if (get_bits_left(gbc) < width) {
-        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid signed value at "
-               "%s: bitstream ended.\n", name);
-        return AVERROR_INVALIDDATA;
-    }
-
-    value = get_sbits(gbc, width);
-
-    if (ctx->trace_enable) {
-        char bits[33];
-        int i;
-        for (i = 0; i < width; i++)
-            bits[i] = value & (1 << (width - i - 1)) ? '1' : '0';
-        bits[i] = 0;
-
-        ff_cbs_trace_syntax_element(ctx, position,
-                                    name, subscripts, bits, value);
-    }
-
-    *write_to = value;
-    return 0;
-}
-
-static int cbs_av1_write_su(CodedBitstreamContext *ctx, PutBitContext *pbc,
-                            int width, const char *name,
-                            const int *subscripts, int32_t value)
-{
-    if (put_bits_left(pbc) < width)
-        return AVERROR(ENOSPC);
-
-    if (ctx->trace_enable) {
-        char bits[33];
-        int i;
-        for (i = 0; i < width; i++)
-            bits[i] = value & (1 << (width - i - 1)) ? '1' : '0';
-        bits[i] = 0;
-
-        ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc),
-                                    name, subscripts, bits, value);
-    }
-
-    put_sbits(pbc, width, value);
-
-    return 0;
-}
-
 static int cbs_av1_read_ns(CodedBitstreamContext *ctx, GetBitContext *gbc,
                            uint32_t n, const char *name,
                            const int *subscripts, uint32_t *write_to)
 {
-    uint32_t w, m, v, extra_bit, value;
-    int position;
+    uint32_t m, v, extra_bit, value;
+    int position, w;
 
     av_assert0(n > 0);
 
@@ -574,6 +518,17 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
     return diff;
 }
 
+static size_t cbs_av1_get_payload_bytes_left(GetBitContext *gbc)
+{
+    GetBitContext tmp = *gbc;
+    size_t size = 0;
+    for (int i = 0; get_bits_left(&tmp) >= 8; i++) {
+        if (get_bits(&tmp, 8))
+            size = i;
+    }
+    return size;
+}
+
 
 #define HEADER(name) do { \
         ff_cbs_trace_header(ctx, name); \
@@ -619,7 +574,7 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
 #define RWContext GetBitContext
 
 #define xf(width, name, var, range_min, range_max, subs, ...) do { \
-        uint32_t value = range_min; \
+        uint32_t value; \
         CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
                                    SUBSCRIPTS(subs, __VA_ARGS__), \
                                    &value, range_min, range_max)); \
@@ -627,34 +582,36 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
     } while (0)
 
 #define xsu(width, name, var, subs, ...) do { \
-        int32_t value = 0; \
-        CHECK(cbs_av1_read_su(ctx, rw, width, #name, \
-                              SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
+        int32_t value; \
+        CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
+                                 SUBSCRIPTS(subs, __VA_ARGS__), &value, \
+                                 MIN_INT_BITS(width), \
+                                 MAX_INT_BITS(width))); \
         var = value; \
     } while (0)
 
 #define uvlc(name, range_min, range_max) do { \
-        uint32_t value = range_min; \
+        uint32_t value; \
         CHECK(cbs_av1_read_uvlc(ctx, rw, #name, \
                                 &value, range_min, range_max)); \
         current->name = value; \
     } while (0)
 
 #define ns(max_value, name, subs, ...) do { \
-        uint32_t value = 0; \
+        uint32_t value; \
         CHECK(cbs_av1_read_ns(ctx, rw, max_value, #name, \
                               SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
         current->name = value; \
     } while (0)
 
 #define increment(name, min, max) do { \
-        uint32_t value = 0; \
+        uint32_t value; \
         CHECK(cbs_av1_read_increment(ctx, rw, min, max, #name, &value)); \
         current->name = value; \
     } while (0)
 
 #define subexp(name, max, subs, ...) do { \
-        uint32_t value = 0; \
+        uint32_t value; \
         CHECK(cbs_av1_read_subexp(ctx, rw, max, #name, \
                                   SUBSCRIPTS(subs, __VA_ARGS__), &value)); \
         current->name = value; \
@@ -672,7 +629,7 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
     } while (0)
 
 #define leb128(name) do { \
-        uint64_t value = 0; \
+        uint64_t value; \
         CHECK(cbs_av1_read_leb128(ctx, rw, #name, &value)); \
         current->name = value; \
     } while (0)
@@ -691,7 +648,6 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
 #undef xf
 #undef xsu
 #undef uvlc
-#undef leb128
 #undef ns
 #undef increment
 #undef subexp
@@ -712,8 +668,10 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
     } while (0)
 
 #define xsu(width, name, var, subs, ...) do { \
-        CHECK(cbs_av1_write_su(ctx, rw, width, #name, \
-                               SUBSCRIPTS(subs, __VA_ARGS__), var)); \
+        CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \
+                                  SUBSCRIPTS(subs, __VA_ARGS__), var, \
+                                  MIN_INT_BITS(width), \
+                                  MAX_INT_BITS(width))); \
     } while (0)
 
 #define uvlc(name, range_min, range_max) do { \
@@ -761,17 +719,17 @@ static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq,
 
 #include "cbs_av1_syntax_template.c"
 
-#undef READ
+#undef WRITE
 #undef READWRITE
 #undef RWContext
 #undef xf
 #undef xsu
 #undef uvlc
-#undef leb128
 #undef ns
 #undef increment
 #undef subexp
 #undef delta_q
+#undef leb128
 #undef infer
 #undef byte_alignment
 
@@ -857,6 +815,11 @@ static void cbs_av1_free_tile_data(AV1RawTileData *td)
     av_buffer_unref(&td->data_ref);
 }
 
+static void cbs_av1_free_padding(AV1RawPadding *pd)
+{
+    av_buffer_unref(&pd->payload_ref);
+}
+
 static void cbs_av1_free_metadata(AV1RawMetadata *md)
 {
     switch (md->metadata_type) {
@@ -866,7 +829,7 @@ static void cbs_av1_free_metadata(AV1RawMetadata *md)
     }
 }
 
-static void cbs_av1_free_obu(void *unit, uint8_t *content)
+static void cbs_av1_free_obu(void *opaque, uint8_t *content)
 {
     AV1RawOBU *obu = (AV1RawOBU*)content;
 
@@ -883,6 +846,9 @@ static void cbs_av1_free_obu(void *unit, uint8_t *content)
     case AV1_OBU_METADATA:
         cbs_av1_free_metadata(&obu->obu.metadata);
         break;
+    case AV1_OBU_PADDING:
+        cbs_av1_free_padding(&obu->obu.padding);
+        break;
     }
 
     av_freep(&obu);
@@ -956,7 +922,7 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
 
     if (obu->header.obu_extension_flag) {
         priv->temporal_id = obu->header.temporal_id;
-        priv->spatial_id  = obu->header.temporal_id;
+        priv->spatial_id  = obu->header.spatial_id;
 
         if (obu->header.obu_type != AV1_OBU_SEQUENCE_HEADER &&
             obu->header.obu_type != AV1_OBU_TEMPORAL_DELIMITER &&
@@ -1057,6 +1023,12 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx,
         }
         break;
     case AV1_OBU_PADDING:
+        {
+            err = cbs_av1_read_padding_obu(ctx, &gbc, &obu->obu.padding);
+            if (err < 0)
+                return err;
+        }
+        break;
     default:
         return AVERROR(ENOSYS);
     }
@@ -1182,6 +1154,12 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
         }
         break;
     case AV1_OBU_PADDING:
+        {
+            err = cbs_av1_write_padding_obu(ctx, pbc, &obu->obu.padding);
+            if (err < 0)
+                return err;
+        }
+        break;
     default:
         return AVERROR(ENOSYS);
     }