summaryrefslogtreecommitdiff
path: root/libavcodec/cbs_mpeg2_syntax_template.c
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2017-05-04 23:03:03 +0100
committerMark Thompson <sw@jkqxz.net>2017-08-20 13:59:17 +0100
commit2bc9ba8d3c41f3a8e56484bd67b05040c7909a01 (patch)
treead36ef5c3031d186127ae114bebccbc045c376de /libavcodec/cbs_mpeg2_syntax_template.c
parent768eb9182e94a94bc2ef46f565a0dac7afef3b57 (diff)
lavc: Add coded bitstream read/write support for MPEG-2
Also enable MPEG-2 support in the trace_headers filter.
Diffstat (limited to 'libavcodec/cbs_mpeg2_syntax_template.c')
-rw-r--r--libavcodec/cbs_mpeg2_syntax_template.c340
1 files changed, 340 insertions, 0 deletions
diff --git a/libavcodec/cbs_mpeg2_syntax_template.c b/libavcodec/cbs_mpeg2_syntax_template.c
new file mode 100644
index 0000000000..b6dd42d2ee
--- /dev/null
+++ b/libavcodec/cbs_mpeg2_syntax_template.c
@@ -0,0 +1,340 @@
+/*
+ * 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
+ */
+
+static int FUNC(sequence_header)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawSequenceHeader *current)
+{
+ CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
+ int err, i;
+
+ HEADER("Sequence Header");
+
+ ui(8, sequence_header_code);
+
+ ui(12, horizontal_size_value);
+ ui(12, vertical_size_value);
+
+ mpeg2->horizontal_size = current->horizontal_size_value;
+ mpeg2->vertical_size = current->vertical_size_value;
+
+ ui(4, aspect_ratio_information);
+ ui(4, frame_rate_code);
+ ui(18, bit_rate_value);
+
+ marker_bit();
+
+ ui(10, vbv_buffer_size_value);
+ ui(1, constrained_parameters_flag);
+
+ ui(1, load_intra_quantiser_matrix);
+ if (current->load_intra_quantiser_matrix) {
+ for (i = 0; i < 64; i++)
+ ui(8, intra_quantiser_matrix[i]);
+ }
+
+ ui(1, load_non_intra_quantiser_matrix);
+ if (current->load_non_intra_quantiser_matrix) {
+ for (i = 0; i < 64; i++)
+ ui(8, non_intra_quantiser_matrix[i]);
+ }
+
+ return 0;
+}
+
+static int FUNC(user_data)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawUserData *current)
+{
+ size_t k;
+ int err;
+
+ HEADER("User Data");
+
+ ui(8, user_data_start_code);
+
+#ifdef READ
+ k = bitstream_bits_left(rw);
+ av_assert0(k % 8 == 0);
+ current->user_data_length = k /= 8;
+ if (k > 0) {
+ current->user_data = av_malloc(k);
+ if (!current->user_data)
+ return AVERROR(ENOMEM);
+ }
+#endif
+
+ for (k = 0; k < current->user_data_length; k++)
+ xui(8, user_data, current->user_data[k]);
+
+ return 0;
+}
+
+static int FUNC(sequence_extension)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawSequenceExtension *current)
+{
+ CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
+ int err;
+
+ HEADER("Sequence Extension");
+
+ ui(8, profile_and_level_indication);
+ ui(1, progressive_sequence);
+ ui(2, chroma_format);
+ ui(2, horizontal_size_extension);
+ ui(2, vertical_size_extension);
+
+ mpeg2->horizontal_size = (mpeg2->horizontal_size & 0xfff) |
+ current->horizontal_size_extension << 12;
+ mpeg2->vertical_size = (mpeg2->vertical_size & 0xfff) |
+ current->vertical_size_extension << 12;
+
+ ui(12, bit_rate_extension);
+ marker_bit();
+ ui(8, vbv_buffer_size_extension);
+ ui(1, low_delay);
+ ui(2, frame_rate_extension_n);
+ ui(5, frame_rate_extension_d);
+
+ return 0;
+}
+
+static int FUNC(sequence_display_extension)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawSequenceDisplayExtension *current)
+{
+ int err;
+
+ HEADER("Sequence Display Extension");
+
+ ui(3, video_format);
+
+ ui(1, colour_description);
+ if (current->colour_description) {
+ ui(8, colour_primaries);
+ ui(8, transfer_characteristics);
+ ui(8, matrix_coefficients);
+ }
+
+ ui(14, display_horizontal_size);
+ marker_bit();
+ ui(14, display_vertical_size);
+
+ return 0;
+}
+
+static int FUNC(group_of_pictures_header)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawGroupOfPicturesHeader *current)
+{
+ int err;
+
+ HEADER("Group of Pictures Header");
+
+ ui(8, group_start_code);
+
+ ui(25, time_code);
+ ui(1, closed_gop);
+ ui(1, broken_link);
+
+ return 0;
+}
+
+static int FUNC(picture_header)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawPictureHeader *current)
+{
+ int err;
+
+ HEADER("Picture Header");
+
+ ui(8, picture_start_code);
+
+ ui(10, temporal_reference);
+ ui(3, picture_coding_type);
+ ui(16, vbv_delay);
+
+ if (current->picture_coding_type == 2 ||
+ current->picture_coding_type == 3) {
+ ui(1, full_pel_forward_vector);
+ ui(3, forward_f_code);
+ }
+
+ if (current->picture_coding_type == 3) {
+ ui(1, full_pel_backward_vector);
+ ui(3, backward_f_code);
+ }
+
+ ui(1, extra_bit_picture);
+
+ return 0;
+}
+
+static int FUNC(picture_coding_extension)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawPictureCodingExtension *current)
+{
+ int err;
+
+ HEADER("Picture Coding Extension");
+
+ ui(4, f_code[0][0]);
+ ui(4, f_code[0][1]);
+ ui(4, f_code[1][0]);
+ ui(4, f_code[1][1]);
+
+ ui(2, intra_dc_precision);
+ ui(2, picture_structure);
+ ui(1, top_field_first);
+ ui(1, frame_pred_frame_dct);
+ ui(1, concealment_motion_vectors);
+ ui(1, q_scale_type);
+ ui(1, intra_vlc_format);
+ ui(1, alternate_scan);
+ ui(1, repeat_first_field);
+ ui(1, chroma_420_type);
+ ui(1, progressive_frame);
+
+ ui(1, composite_display_flag);
+ if (current->composite_display_flag) {
+ ui(1, v_axis);
+ ui(3, field_sequence);
+ ui(1, sub_carrier);
+ ui(7, burst_amplitude);
+ ui(8, sub_carrier_phase);
+ }
+
+ return 0;
+}
+
+static int FUNC(quant_matrix_extension)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawQuantMatrixExtension *current)
+{
+ int err, i;
+
+ HEADER("Quant Matrix Extension");
+
+ ui(1, load_intra_quantiser_matrix);
+ if (current->load_intra_quantiser_matrix) {
+ for (i = 0; i < 64; i++)
+ ui(8, intra_quantiser_matrix[i]);
+ }
+
+ ui(1, load_non_intra_quantiser_matrix);
+ if (current->load_non_intra_quantiser_matrix) {
+ for (i = 0; i < 64; i++)
+ ui(8, non_intra_quantiser_matrix[i]);
+ }
+
+ ui(1, load_chroma_intra_quantiser_matrix);
+ if (current->load_chroma_intra_quantiser_matrix) {
+ for (i = 0; i < 64; i++)
+ ui(8, intra_quantiser_matrix[i]);
+ }
+
+ ui(1, load_chroma_non_intra_quantiser_matrix);
+ if (current->load_chroma_non_intra_quantiser_matrix) {
+ for (i = 0; i < 64; i++)
+ ui(8, chroma_non_intra_quantiser_matrix[i]);
+ }
+
+ return 0;
+}
+
+static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawExtensionData *current)
+{
+ int err;
+
+ HEADER("Extension Data");
+
+ ui(8, extension_start_code);
+ ui(4, extension_start_code_identifier);
+
+ switch (current->extension_start_code_identifier) {
+ case 1:
+ return FUNC(sequence_extension)
+ (ctx, rw, &current->data.sequence);
+ case 2:
+ return FUNC(sequence_display_extension)
+ (ctx, rw, &current->data.sequence_display);
+ case 3:
+ return FUNC(quant_matrix_extension)
+ (ctx, rw, &current->data.quant_matrix);
+ case 8:
+ return FUNC(picture_coding_extension)
+ (ctx, rw, &current->data.picture_coding);
+ default:
+ av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid extension ID %d.\n",
+ current->extension_start_code_identifier);
+ return AVERROR_INVALIDDATA;
+ }
+}
+
+static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawSliceHeader *current)
+{
+ CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data;
+ int err;
+
+ HEADER("Slice Header");
+
+ ui(8, slice_vertical_position);
+
+ if (mpeg2->vertical_size > 2800)
+ ui(3, slice_vertical_position_extension);
+ if (mpeg2->scalable) {
+ if (mpeg2->scalable_mode == 0)
+ ui(7, priority_breakpoint);
+ }
+
+ ui(5, quantiser_scale_code);
+
+ if (nextbits(1, 1, current->slice_extension_flag)) {
+ ui(1, slice_extension_flag);
+ ui(1, intra_slice);
+ ui(1, slice_picture_id_enable);
+ ui(6, slice_picture_id);
+
+ {
+ size_t k;
+#ifdef READ
+ BitstreamContext start;
+ uint8_t bit;
+ start = *rw;
+ for (k = 0; nextbits(1, 1, bit); k++)
+ bitstream_skip(rw, 8);
+ current->extra_information_length = k;
+ if (k > 0) {
+ *rw = start;
+ current->extra_information =
+ av_malloc(current->extra_information_length);
+ if (!current->extra_information)
+ return AVERROR(ENOMEM);
+ for (k = 0; k < current->extra_information_length; k++) {
+ xui(1, extra_bit_slice, bit);
+ xui(8, extra_information_slice,
+ current->extra_information[k]);
+ }
+ }
+#else
+ for (k = 0; k < current->extra_information_length; k++) {
+ xui(1, extra_bit_slice, 1);
+ xui(8, extra_information_slice, current->extra_information[k]);
+ }
+#endif
+ }
+ }
+ ui(1, extra_bit_slice);
+
+ return 0;
+}