summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/cbs_mpeg2.c43
-rw-r--r--libavcodec/cbs_mpeg2.h14
-rw-r--r--libavcodec/cbs_mpeg2_syntax_template.c72
3 files changed, 71 insertions, 58 deletions
diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c
index 2466f569f6..516b728a64 100644
--- a/libavcodec/cbs_mpeg2.c
+++ b/libavcodec/cbs_mpeg2.c
@@ -48,17 +48,26 @@
xui(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
#define uirs(width, name, subs, ...) \
xui(width, name, current->name, 1, MAX_UINT_BITS(width), subs, __VA_ARGS__)
+#define xui(width, name, var, range_min, range_max, subs, ...) \
+ xuia(width, #name, var, range_min, range_max, subs, __VA_ARGS__)
#define sis(width, name, subs, ...) \
xsi(width, name, current->name, subs, __VA_ARGS__)
+#define marker_bit() \
+ bit("marker_bit", 1)
+#define bit(string, value) do { \
+ av_unused uint32_t bit = value; \
+ xuia(1, string, bit, value, value, 0); \
+ } while (0)
+
#define READ
#define READWRITE read
#define RWContext GetBitContext
-#define xui(width, name, var, range_min, range_max, subs, ...) do { \
+#define xuia(width, string, var, range_min, range_max, subs, ...) do { \
uint32_t value; \
- CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
+ CHECK(ff_cbs_read_unsigned(ctx, rw, width, string, \
SUBSCRIPTS(subs, __VA_ARGS__), \
&value, range_min, range_max)); \
var = value; \
@@ -73,11 +82,6 @@
var = value; \
} while (0)
-#define marker_bit() do { \
- av_unused uint32_t one; \
- CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", NULL, &one, 1, 1)); \
- } while (0)
-
#define nextbits(width, compare, var) \
(get_bits_left(rw) >= width && \
(var = show_bits(rw, width)) == (compare))
@@ -91,9 +95,8 @@
#undef READ
#undef READWRITE
#undef RWContext
-#undef xui
+#undef xuia
#undef xsi
-#undef marker_bit
#undef nextbits
#undef infer
@@ -102,8 +105,8 @@
#define READWRITE write
#define RWContext PutBitContext
-#define xui(width, name, var, range_min, range_max, subs, ...) do { \
- CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
+#define xuia(width, string, var, range_min, range_max, subs, ...) do { \
+ CHECK(ff_cbs_write_unsigned(ctx, rw, width, string, \
SUBSCRIPTS(subs, __VA_ARGS__), \
var, range_min, range_max)); \
} while (0)
@@ -115,10 +118,6 @@
MAX_INT_BITS(width))); \
} while (0)
-#define marker_bit() do { \
- CHECK(ff_cbs_write_unsigned(ctx, rw, 1, "marker_bit", NULL, 1, 1, 1)); \
- } while (0)
-
#define nextbits(width, compare, var) (var)
#define infer(name, value) do { \
@@ -135,13 +134,19 @@
#undef WRITE
#undef READWRITE
#undef RWContext
-#undef xui
+#undef xuia
#undef xsi
-#undef marker_bit
#undef nextbits
#undef infer
+static void cbs_mpeg2_free_picture_header(void *unit, uint8_t *content)
+{
+ MPEG2RawPictureHeader *picture = (MPEG2RawPictureHeader*)content;
+ av_buffer_unref(&picture->extra_information_picture.extra_information_ref);
+ av_freep(&content);
+}
+
static void cbs_mpeg2_free_user_data(void *unit, uint8_t *content)
{
MPEG2RawUserData *user = (MPEG2RawUserData*)content;
@@ -152,7 +157,7 @@ static void cbs_mpeg2_free_user_data(void *unit, uint8_t *content)
static void cbs_mpeg2_free_slice(void *unit, uint8_t *content)
{
MPEG2RawSlice *slice = (MPEG2RawSlice*)content;
- av_buffer_unref(&slice->header.extra_information_ref);
+ av_buffer_unref(&slice->header.extra_information_slice.extra_information_ref);
av_buffer_unref(&slice->data_ref);
av_freep(&content);
}
@@ -255,7 +260,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
} \
break;
START(MPEG2_START_PICTURE, MPEG2RawPictureHeader,
- picture_header, NULL);
+ picture_header, &cbs_mpeg2_free_picture_header);
START(MPEG2_START_USER_DATA, MPEG2RawUserData,
user_data, &cbs_mpeg2_free_user_data);
START(MPEG2_START_SEQUENCE_HEADER, MPEG2RawSequenceHeader,
diff --git a/libavcodec/cbs_mpeg2.h b/libavcodec/cbs_mpeg2.h
index 11f93b9df8..2befaab275 100644
--- a/libavcodec/cbs_mpeg2.h
+++ b/libavcodec/cbs_mpeg2.h
@@ -114,6 +114,12 @@ typedef struct MPEG2RawGroupOfPicturesHeader {
uint8_t broken_link;
} MPEG2RawGroupOfPicturesHeader;
+typedef struct MPEG2RawExtraInformation {
+ uint8_t *extra_information;
+ AVBufferRef *extra_information_ref;
+ size_t extra_information_length;
+} MPEG2RawExtraInformation;
+
typedef struct MPEG2RawPictureHeader {
uint8_t picture_start_code;
@@ -126,7 +132,7 @@ typedef struct MPEG2RawPictureHeader {
uint8_t full_pel_backward_vector;
uint8_t backward_f_code;
- uint8_t extra_bit_picture;
+ MPEG2RawExtraInformation extra_information_picture;
} MPEG2RawPictureHeader;
typedef struct MPEG2RawPictureCodingExtension {
@@ -194,11 +200,7 @@ typedef struct MPEG2RawSliceHeader {
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;
- AVBufferRef *extra_information_ref;
+ MPEG2RawExtraInformation extra_information_slice;
} MPEG2RawSliceHeader;
typedef struct MPEG2RawSlice {
diff --git a/libavcodec/cbs_mpeg2_syntax_template.c b/libavcodec/cbs_mpeg2_syntax_template.c
index d9ef480f39..e7332abe6e 100644
--- a/libavcodec/cbs_mpeg2_syntax_template.c
+++ b/libavcodec/cbs_mpeg2_syntax_template.c
@@ -173,6 +173,40 @@ static int FUNC(group_of_pictures_header)(CodedBitstreamContext *ctx, RWContext
return 0;
}
+static int FUNC(extra_information)(CodedBitstreamContext *ctx, RWContext *rw,
+ MPEG2RawExtraInformation *current,
+ const char *element_name, const char *marker_name)
+{
+ int err;
+ size_t k;
+#ifdef READ
+ GetBitContext start = *rw;
+ uint8_t bit;
+
+ for (k = 0; nextbits(1, 1, bit); k++)
+ skip_bits(rw, 1 + 8);
+ current->extra_information_length = k;
+ if (k > 0) {
+ *rw = start;
+ current->extra_information_ref =
+ av_buffer_allocz(k + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!current->extra_information_ref)
+ return AVERROR(ENOMEM);
+ current->extra_information = current->extra_information_ref->data;
+ }
+#endif
+
+ for (k = 0; k < current->extra_information_length; k++) {
+ bit(marker_name, 1);
+ xuia(8, element_name,
+ current->extra_information[k], 0, 255, 1, k);
+ }
+
+ bit(marker_name, 0);
+
+ return 0;
+}
+
static int FUNC(picture_header)(CodedBitstreamContext *ctx, RWContext *rw,
MPEG2RawPictureHeader *current)
{
@@ -197,7 +231,8 @@ static int FUNC(picture_header)(CodedBitstreamContext *ctx, RWContext *rw,
ui(3, backward_f_code);
}
- ui(1, extra_bit_picture);
+ CHECK(FUNC(extra_information)(ctx, rw, &current->extra_information_picture,
+ "extra_information_picture[k]", "extra_bit_picture"));
return 0;
}
@@ -369,39 +404,10 @@ static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
ui(1, intra_slice);
ui(1, slice_picture_id_enable);
ui(6, slice_picture_id);
-
- {
- size_t k;
-#ifdef READ
- GetBitContext start;
- uint8_t bit;
- start = *rw;
- for (k = 0; nextbits(1, 1, bit); k++)
- skip_bits(rw, 8);
- current->extra_information_length = k;
- if (k > 0) {
- *rw = start;
- current->extra_information_ref =
- av_buffer_alloc(current->extra_information_length);
- if (!current->extra_information_ref)
- return AVERROR(ENOMEM);
- current->extra_information = current->extra_information_ref->data;
- for (k = 0; k < current->extra_information_length; k++) {
- xui(1, extra_bit_slice, bit, 1, 1, 0);
- xui(8, extra_information_slice[k],
- current->extra_information[k], 0, 255, 1, k);
- }
- }
-#else
- for (k = 0; k < current->extra_information_length; k++) {
- xui(1, extra_bit_slice, 1, 1, 1, 0);
- xui(8, extra_information_slice[k],
- current->extra_information[k], 0, 255, 1, k);
- }
-#endif
- }
}
- ui(1, extra_bit_slice);
+
+ CHECK(FUNC(extra_information)(ctx, rw, &current->extra_information_slice,
+ "extra_information_slice[k]", "extra_bit_slice"));
return 0;
}