Quoting Mark Thompson (2017-07-29 23:16:30)
> ---
>  libavcodec/cbs.c              |   1 +
>  libavcodec/cbs_internal.h     |   1 +
>  libavcodec/cbs_mpeg2.c        | 355 
> ++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/cbs_mpeg2.h        | 208 +++++++++++++++++++++++++
>  libavcodec/cbs_mpeg2_syntax.c | 340 ++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 905 insertions(+)
>  create mode 100644 libavcodec/cbs_mpeg2.c
>  create mode 100644 libavcodec/cbs_mpeg2.h
>  create mode 100644 libavcodec/cbs_mpeg2_syntax.c
> 
> diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c
> index 6030cfd48..2b98b519b 100644
> --- a/libavcodec/cbs.c
> +++ b/libavcodec/cbs.c
> @@ -29,6 +29,7 @@
>  static const CodedBitstreamType *cbs_type_table[] = {
>      &ff_cbs_type_h264,
>      &ff_cbs_type_h265,
> +    &ff_cbs_type_mpeg2,
>  };
>  
>  int ff_cbs_init(CodedBitstreamContext *ctx,
> diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h
> index 46d41db6d..57c7f1e36 100644
> --- a/libavcodec/cbs_internal.h
> +++ b/libavcodec/cbs_internal.h
> @@ -98,6 +98,7 @@ int ff_cbs_write_se_golomb(CodedBitstreamContext *ctx, 
> PutBitContext *pbc,
>  
>  extern const CodedBitstreamType ff_cbs_type_h264;
>  extern const CodedBitstreamType ff_cbs_type_h265;
> +extern const CodedBitstreamType ff_cbs_type_mpeg2;
>  
>  
>  #endif /* AVCODEC_CBS_INTERNAL_H */
> diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c
> new file mode 100644
> index 000000000..ef54311ae
> --- /dev/null
> +++ b/libavcodec/cbs_mpeg2.c
> @@ -0,0 +1,355 @@
> +/*
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "libavutil/avassert.h"
> +
> +#include "cbs.h"
> +#include "cbs_internal.h"
> +#include "cbs_mpeg2.h"
> +#include "internal.h"
> +
> +
> +#define HEADER(name) do { \
> +        ff_cbs_trace_header(ctx, name); \
> +    } while (0)
> +
> +#define CHECK(call) do { \
> +        err = (call); \
> +        if (err < 0) \
> +            return err; \
> +    } while (0)
> +
> +#define FUNC_NAME(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
> +#define FUNC_MPEG2(rw, name) FUNC_NAME(rw, mpeg2, name)
> +#define FUNC(name) FUNC_MPEG2(READWRITE, name)
> +
> +
> +#define READ
> +#define READWRITE read
> +#define RWContext BitstreamContext
> +
> +#define xui(width, name, var) do { \
> +        uint32_t value = 0; \
> +        CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
> +                                   &value, 0, (1 << width) - 1)); \
> +        var = value; \
> +    } while (0)
> +
> +#define ui(width, name) \
> +        xui(width, name, current->name)
> +
> +#define marker_bit() do { \
> +        av_unused int one = 1; \
> +        CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", &one, 1, 1)); \
> +    } while (0)
> +
> +#define nextbits(width, compare, var) (var = bitstream_peek(rw, width), \
> +                                       var == (compare))
> +
> +#include "cbs_mpeg2_syntax.c"
> +
> +#undef READ
> +#undef READWRITE
> +#undef RWContext
> +#undef xui
> +#undef ui
> +#undef marker_bit
> +#undef nextbits
> +
> +
> +#define WRITE
> +#define READWRITE write
> +#define RWContext PutBitContext
> +
> +#define xui(width, name, var) do { \
> +        CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
> +                                    var, 0, (1 << width) - 1)); \
> +    } while (0)
> +
> +#define ui(width, name) \
> +        xui(width, name, current->name)
> +
> +#define marker_bit() do { \
> +        CHECK(ff_cbs_write_unsigned(ctx, rw, 1, "marker_bit", 1, 1, 1)); \
> +    } while (0)
> +
> +#define nextbits(width, compare, var) (var)
> +
> +#include "cbs_mpeg2_syntax.c"
> +
> +#undef READ
> +#undef READWRITE
> +#undef RWContext
> +#undef xui
> +#undef ui
> +#undef marker_bit
> +#undef nextbits
> +
> +
> +static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
> +                                    CodedBitstreamFragment *frag,
> +                                    int header)
> +{
> +    const uint8_t *start, *end;
> +    uint8_t *unit_data;
> +    uint32_t start_code = -1, next_start_code = -1;
> +    size_t unit_size;
> +    int err, i, unit_type;
> +
> +    if (frag->nb_units != 0)
> +        return AVERROR(EINVAL);
> +
> +    start = avpriv_find_start_code(frag->data, frag->data + frag->data_size,
> +                                   &start_code);
> +    for (i = 0;; i++) {
> +        end = avpriv_find_start_code(start, frag->data + frag->data_size,
> +                                     &next_start_code);
> +
> +        unit_type = start_code & 0xff;
> +
> +        if (end == frag->data + frag->data_size)
> +            unit_size = end - (start - 1);
> +        else
> +            unit_size = (end - 4) - (start - 1);

Are you sure this will not do anything untoward (like a zero or overflow
in unit_size, or an infinite loop) for corrupted streams? The behaviour
of avpriv_find_start_code() in such cases is not immediately obvious to
me.

> +
> +        unit_data = av_malloc(unit_size);
> +        if (!unit_data)
> +            return AVERROR(ENOMEM);
> +        memcpy(unit_data, start - 1, unit_size);
> +
> +        err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type,
> +                                      unit_data, unit_size);
> +        if (err < 0)

leaking unit_data?

> +const CodedBitstreamType ff_cbs_type_mpeg2 = {
> +    .codec_id          = AV_CODEC_ID_MPEG2VIDEO,
> +
> +    .priv_data_size    = 1, //sizeof(CodedBitstreamMPEG2Context),

Already mentioned on IRC.

> +
> +    .split_fragment    = &cbs_mpeg2_split_fragment,
> +    .read_unit         = &cbs_mpeg2_read_unit,
> +    .write_unit        = &cbs_mpeg2_write_unit,
> +    .assemble_fragment = &cbs_mpeg2_assemble_fragment,
> +
> +    .free_unit         = &cbs_mpeg2_free_unit,
> +};
> diff --git a/libavcodec/cbs_mpeg2.h b/libavcodec/cbs_mpeg2.h
> new file mode 100644
> index 000000000..e031fa455
> --- /dev/null
> +++ b/libavcodec/cbs_mpeg2.h
> @@ -0,0 +1,208 @@
> +/*
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#ifndef AVCODEC_CBS_MPEG2_H
> +#define AVCODEC_CBS_MPEG2_H
> +
> +#include <stddef.h>
> +#include <stdint.h>
> +
> +
> +enum {
> +    MPEG2_START_PICTURE         = 0x00,
> +    MPEG2_START_SLICE_MIN       = 0x01,
> +    MPEG2_START_SLICE_MAX       = 0xaf,
> +    MPEG2_START_USER_DATA       = 0xb2,
> +    MPEG2_START_SEQUENCE_HEADER = 0xb3,
> +    MPEG2_START_SEQUENCE_ERROR  = 0xb4,
> +    MPEG2_START_EXTENSION       = 0xb5,
> +    MPEG2_START_SEQUENCE_END    = 0xb7,
> +    MPEG2_START_GROUP           = 0xb8,
> +};
> +
> +enum {
> +    MPEG2_EXTENSION_SEQUENCE                  = 0x1,
> +    MPEG2_EXTENSION_SEQUENCE_DISPLAY          = 0x2,
> +    MPEG2_EXTENSION_QUANT_MATRIX              = 0x3,
> +    MPEG2_EXTENSION_COPYRIGHT                 = 0x4,
> +    MPEG2_EXTENSION_SEQUENCE_SCALABLE         = 0x5,
> +    MPEG2_EXTENSION_PICTURE_DISPLAY           = 0x7,
> +    MPEG2_EXTENSION_PICTURE_CODING            = 0x8,
> +    MPEG2_EXTENSION_PICTURE_SPATIAL_SCALABLE  = 0x9,
> +    MPEG2_EXTENSION_PICTURE_TEMPORAL_SCALABLE = 0xa,
> +    MPEG2_EXTENSION_CAMAERA_PARAMETERS        = 0xb,
> +    MPEG2_EXTENSION_ITU_T                     = 0xc,
> +};
> +
> +
> +typedef struct MPEG2RawSequenceHeader {
> +    uint8_t sequence_header_code;
> +
> +    uint16_t horizontal_size_value;
> +    uint16_t vertical_size_value;
> +    uint8_t aspect_ratio_information;
> +    uint8_t frame_rate_code;
> +    uint32_t bit_rate_value;
> +    uint16_t vbv_buffer_size_value;
> +    uint8_t constrained_parameters_flag;
> +
> +    uint8_t load_intra_quantiser_matrix;
> +    uint8_t intra_quantiser_matrix[64];
> +    uint8_t load_non_intra_quantiser_matrix;
> +    uint8_t non_intra_quantiser_matrix[64];
> +} MPEG2RawSequenceHeader;
> +
> +typedef struct MPEG2RawUserData {
> +    uint8_t user_data_start_code;
> +
> +    uint8_t *user_data;
> +    size_t user_data_length;
> +} MPEG2RawUserData;
> +
> +typedef struct MPEG2RawSequenceExtension {
> +    uint8_t profile_and_level_indication;
> +    uint8_t progressive_sequence;
> +    uint8_t chroma_format;
> +    uint8_t horizontal_size_extension;
> +    uint8_t vertical_size_extension;
> +    uint16_t bit_rate_extension;
> +    uint8_t vbv_buffer_size_extension;
> +    uint8_t low_delay;
> +    uint8_t frame_rate_extension_n;
> +    uint8_t frame_rate_extension_d;
> +} MPEG2RawSequenceExtension;
> +
> +typedef struct MPEG2RawSequenceDisplayExtension {
> +    uint8_t video_format;
> +
> +    uint8_t colour_description;
> +    uint8_t colour_primaries;
> +    uint8_t transfer_characteristics;
> +    uint8_t matrix_coefficients;
> +
> +    uint16_t display_horizontal_size;
> +    uint16_t display_vertical_size;
> +} MPEG2RawSequenceDisplayExtension;
> +
> +typedef struct MPEG2RawGroupOfPicturesHeader {
> +    uint8_t group_start_code;
> +
> +    uint32_t time_code;
> +    uint8_t closed_gop;
> +    uint8_t broken_link;
> +} MPEG2RawGroupOfPicturesHeader;
> +
> +typedef struct MPEG2RawPictureHeader {
> +    uint8_t picture_start_code;
> +
> +    uint16_t temporal_reference;
> +    uint8_t picture_coding_type;
> +    uint16_t vbv_delay;
> +
> +    uint8_t full_pel_forward_vector;
> +    uint8_t forward_f_code;
> +    uint8_t full_pel_backward_vector;
> +    uint8_t backward_f_code;
> +
> +    uint8_t extra_bit_picture;
> +} MPEG2RawPictureHeader;
> +
> +typedef struct MPEG2RawPictureCodingExtension {
> +    uint8_t f_code[2][2];
> +
> +    uint8_t intra_dc_precision;
> +    uint8_t picture_structure;
> +    uint8_t top_field_first;
> +    uint8_t frame_pred_frame_dct;
> +    uint8_t concealment_motion_vectors;
> +    uint8_t q_scale_type;
> +    uint8_t intra_vlc_format;
> +    uint8_t alternate_scan;
> +    uint8_t repeat_first_field;
> +    uint8_t chroma_420_type;
> +    uint8_t progressive_frame;
> +
> +    uint8_t composite_display_flag;
> +    uint8_t v_axis;
> +    uint8_t field_sequence;
> +    uint8_t sub_carrier;
> +    uint8_t burst_amplitude;
> +    uint8_t sub_carrier_phase;
> +} MPEG2RawPictureCodingExtension;
> +
> +typedef struct MPEG2RawQuantMatrixExtension {
> +    uint8_t load_intra_quantiser_matrix;
> +    uint8_t intra_quantiser_matrix[64];
> +    uint8_t load_non_intra_quantiser_matrix;
> +    uint8_t non_intra_quantiser_matrix[64];
> +    uint8_t load_chroma_intra_quantiser_matrix;
> +    uint8_t chroma_intra_quantiser_matrix[64];
> +    uint8_t load_chroma_non_intra_quantiser_matrix;
> +    uint8_t chroma_non_intra_quantiser_matrix[64];
> +} MPEG2RawQuantMatrixExtension;
> +
> +typedef struct MPEG2RawExtensionData {
> +    uint8_t extension_start_code;
> +    uint8_t extension_start_code_identifier;
> +
> +    union {
> +        MPEG2RawSequenceExtension sequence;
> +        MPEG2RawSequenceDisplayExtension sequence_display;
> +        MPEG2RawQuantMatrixExtension quant_matrix;
> +        MPEG2RawPictureCodingExtension picture_coding;
> +    } data;
> +} MPEG2RawExtensionData;
> +
> +typedef struct MPEG2RawSliceHeader {
> +    uint8_t slice_vertical_position;
> +
> +    uint8_t slice_vertical_position_extension;
> +    uint8_t priority_breakpoint;
> +
> +    uint8_t quantiser_scale_code;
> +
> +    uint8_t slice_extension_flag;
> +    uint8_t intra_slice;
> +    uint8_t slice_picture_id_enable;
> +    uint8_t slice_picture_id;
> +
> +    uint8_t extra_bit_slice;
> +
> +    size_t extra_information_length;
> +    uint8_t *extra_information;

Does this get freed? Same for user_data.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to