tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cbs_internal.h (13795B)


      1 /*
      2 * This file is part of FFmpeg.
      3 *
      4 * FFmpeg is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU Lesser General Public
      6 * License as published by the Free Software Foundation; either
      7 * version 2.1 of the License, or (at your option) any later version.
      8 *
      9 * FFmpeg is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with FFmpeg; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17 */
     18 
     19 #ifndef AVCODEC_CBS_INTERNAL_H
     20 #define AVCODEC_CBS_INTERNAL_H
     21 
     22 #include <stddef.h>
     23 #include <stdint.h>
     24 
     25 #include "libavutil/log.h"
     26 
     27 #include "cbs.h"
     28 #include "codec_id.h"
     29 #include "get_bits.h"
     30 #include "put_bits.h"
     31 #include "libavutil/refstruct.h"
     32 
     33 
     34 enum CBSContentType {
     35    // Unit content may contain some references to other structures, but all
     36    // managed via buffer reference counting.  The descriptor defines the
     37    // structure offsets of every buffer reference.
     38    CBS_CONTENT_TYPE_INTERNAL_REFS,
     39    // Unit content is something more complex.  The descriptor defines
     40    // special functions to manage the content.
     41    CBS_CONTENT_TYPE_COMPLEX,
     42 };
     43 
     44 enum {
     45      // Maximum number of unit types described by the same non-range
     46      // unit type descriptor.
     47      CBS_MAX_LIST_UNIT_TYPES = 3,
     48      // Maximum number of reference buffer offsets in any one unit.
     49      CBS_MAX_REF_OFFSETS = 2,
     50      // Special value used in a unit type descriptor to indicate that it
     51      // applies to a large range of types rather than a set of discrete
     52      // values.
     53      CBS_UNIT_TYPE_RANGE = -1,
     54 };
     55 
     56 typedef const struct CodedBitstreamUnitTypeDescriptor {
     57    // Number of entries in the unit_types array, or the special value
     58    // CBS_UNIT_TYPE_RANGE to indicate that the range fields should be
     59    // used instead.
     60    int nb_unit_types;
     61 
     62    union {
     63        // Array of unit types that this entry describes.
     64        CodedBitstreamUnitType list[CBS_MAX_LIST_UNIT_TYPES];
     65        // Start and end of unit type range, used if nb_unit_types is
     66        // CBS_UNIT_TYPE_RANGE.
     67        struct {
     68            CodedBitstreamUnitType start;
     69            CodedBitstreamUnitType end;
     70        } range;
     71    } unit_type;
     72 
     73    // The type of content described.
     74    enum CBSContentType content_type;
     75    // The size of the structure which should be allocated to contain
     76    // the decomposed content of this type of unit.
     77    size_t content_size;
     78 
     79    union {
     80        // This union's state is determined by content_type:
     81        // ref for CBS_CONTENT_TYPE_INTERNAL_REFS,
     82        // complex for CBS_CONTENT_TYPE_COMPLEX.
     83        struct {
     84            // Number of entries in the ref_offsets array.
     85            // May be zero, then the structure is POD-like.
     86            int nb_offsets;
     87            // The structure must contain two adjacent elements:
     88            //   type        *field;
     89            //   AVBufferRef *field_ref;
     90            // where field points to something in the buffer referred to by
     91            // field_ref.  This offset is then set to offsetof(struct, field).
     92            size_t offsets[CBS_MAX_REF_OFFSETS];
     93        } ref;
     94 
     95        struct {
     96            void (*content_free)(AVRefStructOpaque opaque, void *content);
     97            int  (*content_clone)(void **new_content, CodedBitstreamUnit *unit);
     98        } complex;
     99    } type;
    100 } CodedBitstreamUnitTypeDescriptor;
    101 
    102 typedef struct CodedBitstreamType {
    103    enum AVCodecID codec_id;
    104 
    105    // A class for the private data, used to declare private AVOptions.
    106    // This field is NULL for types that do not declare any options.
    107    // If this field is non-NULL, the first member of the filter private data
    108    // must be a pointer to AVClass.
    109    const AVClass *priv_class;
    110 
    111    size_t priv_data_size;
    112 
    113    // List of unit type descriptors for this codec.
    114    // Terminated by a descriptor with nb_unit_types equal to zero.
    115    const CodedBitstreamUnitTypeDescriptor *unit_types;
    116 
    117    // Split frag->data into coded bitstream units, creating the
    118    // frag->units array.  Fill data but not content on each unit.
    119    // The header argument should be set if the fragment came from
    120    // a header block, which may require different parsing for some
    121    // codecs (e.g. the AVCC header in H.264).
    122    int (*split_fragment)(CodedBitstreamContext *ctx,
    123                          CodedBitstreamFragment *frag,
    124                          int header);
    125 
    126    // Read the unit->data bitstream and decompose it, creating
    127    // unit->content.
    128    int (*read_unit)(CodedBitstreamContext *ctx,
    129                     CodedBitstreamUnit *unit);
    130 
    131    // Write the data bitstream from unit->content into pbc.
    132    // Return value AVERROR(ENOSPC) indicates that pbc was too small.
    133    int (*write_unit)(CodedBitstreamContext *ctx,
    134                      CodedBitstreamUnit *unit,
    135                      PutBitContext *pbc);
    136 
    137    // Return 1 when the unit should be dropped according to 'skip',
    138    // 0 otherwise.
    139    int (*discarded_unit)(CodedBitstreamContext *ctx,
    140                          const CodedBitstreamUnit *unit,
    141                          enum AVDiscard skip);
    142 
    143    // Read the data from all of frag->units and assemble it into
    144    // a bitstream for the whole fragment.
    145    int (*assemble_fragment)(CodedBitstreamContext *ctx,
    146                             CodedBitstreamFragment *frag);
    147 
    148    // Reset the codec internal state.
    149    void (*flush)(CodedBitstreamContext *ctx);
    150 
    151    // Free the codec internal state.
    152    void (*close)(CodedBitstreamContext *ctx);
    153 } CodedBitstreamType;
    154 
    155 
    156 // Helper functions for trace output.
    157 
    158 void ff_cbs_trace_header(CodedBitstreamContext *ctx,
    159                         const char *name);
    160 
    161 
    162 // Helper functions for read/write of common bitstream elements, including
    163 // generation of trace output. The simple functions are equivalent to
    164 // their non-simple counterparts except that their range is unrestricted
    165 // (i.e. only limited by the amount of bits used) and they lack
    166 // the ability to use subscripts.
    167 
    168 int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
    169                         int width, const char *name,
    170                         const int *subscripts, uint32_t *write_to,
    171                         uint32_t range_min, uint32_t range_max);
    172 
    173 int ff_cbs_read_simple_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc,
    174                                int width, const char *name, uint32_t *write_to);
    175 
    176 int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
    177                          int width, const char *name,
    178                          const int *subscripts, uint32_t value,
    179                          uint32_t range_min, uint32_t range_max);
    180 
    181 int ff_cbs_write_simple_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc,
    182                                 int width, const char *name, uint32_t value);
    183 
    184 int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc,
    185                       int width, const char *name,
    186                       const int *subscripts, int32_t *write_to,
    187                       int32_t range_min, int32_t range_max);
    188 
    189 int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc,
    190                        int width, const char *name,
    191                        const int *subscripts, int32_t value,
    192                        int32_t range_min, int32_t range_max);
    193 
    194 // The largest unsigned value representable in N bits, suitable for use as
    195 // range_max in the above functions.
    196 #define MAX_UINT_BITS(length) ((UINT64_C(1) << (length)) - 1)
    197 
    198 // The largest signed value representable in N bits, suitable for use as
    199 // range_max in the above functions.
    200 #define MAX_INT_BITS(length) ((INT64_C(1) << ((length) - 1)) - 1)
    201 
    202 // The smallest signed value representable in N bits, suitable for use as
    203 // range_min in the above functions.
    204 #define MIN_INT_BITS(length) (-(INT64_C(1) << ((length) - 1)))
    205 
    206 
    207 // Start of a syntax element during read tracing.
    208 #define CBS_TRACE_READ_START() \
    209    GetBitContext trace_start; \
    210    do { \
    211        if (ctx->trace_enable) \
    212            trace_start = *gbc; \
    213    } while (0)
    214 
    215 // End of a syntax element for tracing, make callback.
    216 #define CBS_TRACE_READ_END() \
    217    do { \
    218        if (ctx->trace_enable) { \
    219            int start_position = get_bits_count(&trace_start); \
    220            int end_position   = get_bits_count(gbc); \
    221            av_assert0(start_position <= end_position); \
    222            ctx->trace_read_callback(ctx->trace_context, &trace_start, \
    223                                     end_position - start_position, \
    224                                     name, subscripts, value); \
    225        } \
    226    } while (0)
    227 
    228 // End of a syntax element with no subscript entries.
    229 #define CBS_TRACE_READ_END_NO_SUBSCRIPTS() \
    230    do { \
    231        const int *subscripts = NULL; \
    232        CBS_TRACE_READ_END(); \
    233    } while (0)
    234 
    235 // End of a syntax element which is made up of subelements which
    236 // are aleady traced, so we are only showing the value.
    237 #define CBS_TRACE_READ_END_VALUE_ONLY() \
    238    do { \
    239        if (ctx->trace_enable) { \
    240            ctx->trace_read_callback(ctx->trace_context, &trace_start, 0, \
    241                                     name, subscripts, value); \
    242        } \
    243    } while (0)
    244 
    245 // Start of a syntax element during write tracing.
    246 #define CBS_TRACE_WRITE_START() \
    247    int start_position; \
    248    do { \
    249        if (ctx->trace_enable) \
    250            start_position = put_bits_count(pbc);; \
    251    } while (0)
    252 
    253 // End of a syntax element for tracing, make callback.
    254 #define CBS_TRACE_WRITE_END() \
    255    do { \
    256        if (ctx->trace_enable) { \
    257            int end_position   = put_bits_count(pbc); \
    258            av_assert0(start_position <= end_position); \
    259            ctx->trace_write_callback(ctx->trace_context, pbc, \
    260                                      end_position - start_position, \
    261                                      name, subscripts, value); \
    262        } \
    263    } while (0)
    264 
    265 // End of a syntax element with no subscript entries.
    266 #define CBS_TRACE_WRITE_END_NO_SUBSCRIPTS() \
    267    do { \
    268        const int *subscripts = NULL; \
    269        CBS_TRACE_WRITE_END(); \
    270    } while (0)
    271 
    272 // End of a syntax element which is made up of subelements which are
    273 // aleady traced, so we are only showing the value.  This forges a
    274 // PutBitContext to point to the position of the start of the syntax
    275 // element, but the other state doesn't matter because length is zero.
    276 #define CBS_TRACE_WRITE_END_VALUE_ONLY() \
    277    do { \
    278        if (ctx->trace_enable) { \
    279            PutBitContext tmp; \
    280            init_put_bits(&tmp, pbc->buf, start_position); \
    281            skip_put_bits(&tmp, start_position); \
    282            ctx->trace_write_callback(ctx->trace_context, &tmp, 0, \
    283                                      name, subscripts, value); \
    284        } \
    285    } while (0)
    286 
    287 #define TYPE_LIST(...) { __VA_ARGS__ }
    288 #define CBS_UNIT_TYPE_POD(type_, structure) { \
    289        .nb_unit_types  = 1, \
    290        .unit_type.list = { type_ }, \
    291        .content_type   = CBS_CONTENT_TYPE_INTERNAL_REFS, \
    292        .content_size   = sizeof(structure), \
    293        .type.ref       = { .nb_offsets = 0 }, \
    294    }
    295 #define CBS_UNIT_RANGE_POD(range_start, range_end, structure) { \
    296        .nb_unit_types         = CBS_UNIT_TYPE_RANGE, \
    297        .unit_type.range.start = range_start, \
    298        .unit_type.range.end   = range_end, \
    299        .content_type          = CBS_CONTENT_TYPE_INTERNAL_REFS, \
    300        .content_size          = sizeof(structure), \
    301        .type.ref              = { .nb_offsets = 0 }, \
    302    }
    303 
    304 #define CBS_UNIT_TYPES_INTERNAL_REF(types, structure, ref_field) { \
    305        .nb_unit_types  = FF_ARRAY_ELEMS((CodedBitstreamUnitType[])TYPE_LIST types), \
    306        .unit_type.list = TYPE_LIST types, \
    307        .content_type   = CBS_CONTENT_TYPE_INTERNAL_REFS, \
    308        .content_size   = sizeof(structure), \
    309        .type.ref       = { .nb_offsets = 1, \
    310                            .offsets    = { offsetof(structure, ref_field) } }, \
    311    }
    312 #define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) \
    313    CBS_UNIT_TYPES_INTERNAL_REF((type), structure, ref_field)
    314 
    315 #define CBS_UNIT_RANGE_INTERNAL_REF(range_start, range_end, structure, ref_field) { \
    316        .nb_unit_types         = CBS_UNIT_TYPE_RANGE, \
    317        .unit_type.range.start = range_start, \
    318        .unit_type.range.end   = range_end, \
    319        .content_type          = CBS_CONTENT_TYPE_INTERNAL_REFS, \
    320        .content_size          = sizeof(structure), \
    321        .type.ref = { .nb_offsets = 1, \
    322                      .offsets    = { offsetof(structure, ref_field) } }, \
    323    }
    324 
    325 #define CBS_UNIT_TYPES_COMPLEX(types, structure, free_func) { \
    326        .nb_unit_types  = FF_ARRAY_ELEMS((CodedBitstreamUnitType[])TYPE_LIST types), \
    327        .unit_type.list = TYPE_LIST types, \
    328        .content_type   = CBS_CONTENT_TYPE_COMPLEX, \
    329        .content_size   = sizeof(structure), \
    330        .type.complex   = { .content_free = free_func }, \
    331    }
    332 #define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) \
    333    CBS_UNIT_TYPES_COMPLEX((type), structure, free_func)
    334 
    335 #define CBS_UNIT_TYPE_END_OF_LIST { .nb_unit_types = 0 }
    336 
    337 
    338 extern const CodedBitstreamType ff_cbs_type_av1;
    339 extern const CodedBitstreamType ff_cbs_type_h264;
    340 extern const CodedBitstreamType ff_cbs_type_h265;
    341 extern const CodedBitstreamType ff_cbs_type_h266;
    342 extern const CodedBitstreamType ff_cbs_type_jpeg;
    343 extern const CodedBitstreamType ff_cbs_type_mpeg2;
    344 extern const CodedBitstreamType ff_cbs_type_vp8;
    345 extern const CodedBitstreamType ff_cbs_type_vp9;
    346 
    347 
    348 #endif /* AVCODEC_CBS_INTERNAL_H */