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
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel