@@ -296,6 +296,29 @@ typedef struct H264RawSEIRecoveryPoint {
uint8_t changing_slice_group_idc;
} H264RawSEIRecoveryPoint;
+typedef struct H264RawSEIFramePackingArrangement {
+ uint32_t frame_packing_arrangement_id;
+ uint8_t frame_packing_arrangement_cancel_flag;
+
+ uint8_t frame_packing_arrangement_type;
+ uint8_t quincunx_sampling_flag;
+ uint8_t content_interpretation_type;
+ uint8_t spatial_flipping_flag;
+ uint8_t frame0_flipped_flag;
+ uint8_t field_views_flag;
+ uint8_t current_frame_is_frame0_flag;
+ uint8_t frame0_self_contained_flag;
+ uint8_t frame1_self_contained_flag;
+ uint8_t frame0_grid_position_x;
+ uint8_t frame0_grid_position_y;
+ uint8_t frame1_grid_position_x;
+ uint8_t frame1_grid_position_y;
+ uint8_t frame_packing_arrangement_reserved_byte;
+ uint16_t frame_packing_arrangement_repetition_period;
+
+ uint8_t frame_packing_arrangement_extension_flag;
+} H264RawSEIFramePackingArrangement;
+
typedef struct H264RawSEIDisplayOrientation {
uint8_t display_orientation_cancel_flag;
uint8_t hor_flip;
@@ -329,6 +352,7 @@ typedef struct H264RawSEIPayload {
H264RawSEIUserDataRegistered user_data_registered;
H264RawSEIUserDataUnregistered user_data_unregistered;
H264RawSEIRecoveryPoint recovery_point;
+ H264RawSEIFramePackingArrangement frame_packing_arrangement;
H264RawSEIDisplayOrientation display_orientation;
H264RawSEIMasteringDisplayColourVolume mastering_display_colour_volume;
H264RawSEIAlternativeTransferCharacteristics
@@ -1320,6 +1320,7 @@ void ff_cbs_h264_free_sei_payload(H264RawSEIPayload *payload)
case H264_SEI_TYPE_PIC_TIMING:
case H264_SEI_TYPE_PAN_SCAN_RECT:
case H264_SEI_TYPE_RECOVERY_POINT:
+ case H264_SEI_TYPE_FRAME_PACKING:
case H264_SEI_TYPE_DISPLAY_ORIENTATION:
case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME:
case H264_SEI_TYPE_ALTERNATIVE_TRANSFER:
@@ -779,6 +779,42 @@ static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw,
return 0;
}
+static int FUNC(sei_frame_packing_arrangement)(CodedBitstreamContext *ctx, RWContext *rw,
+ H264RawSEIFramePackingArrangement *current)
+{
+ int err;
+
+ HEADER("Frame Packing Arrangement");
+
+ ue(frame_packing_arrangement_id, 0, UINT32_MAX - 1);
+ flag(frame_packing_arrangement_cancel_flag);
+
+ if (!current->frame_packing_arrangement_cancel_flag) {
+ u(7, frame_packing_arrangement_type, 0, 7);
+ flag(quincunx_sampling_flag);
+ u(6, content_interpretation_type, 0, 2);
+ flag(spatial_flipping_flag);
+ flag(frame0_flipped_flag);
+ flag(field_views_flag);
+ flag(current_frame_is_frame0_flag);
+ flag(frame0_self_contained_flag);
+ flag(frame1_self_contained_flag);
+ if (!current->quincunx_sampling_flag &&
+ current->frame_packing_arrangement_type != 5) {
+ ub(4, frame0_grid_position_x);
+ ub(4, frame0_grid_position_y);
+ ub(4, frame1_grid_position_x);
+ ub(4, frame1_grid_position_y);
+ }
+ u(8, frame_packing_arrangement_reserved_byte, 0, 0);
+ ue(frame_packing_arrangement_repetition_period, 0, 16384);
+ }
+
+ flag(frame_packing_arrangement_extension_flag);
+
+ return 0;
+}
+
static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw,
H264RawSEIDisplayOrientation *current)
{
@@ -879,6 +915,10 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw,
CHECK(FUNC(sei_display_orientation)
(ctx, rw, ¤t->payload.display_orientation));
break;
+ case H264_SEI_TYPE_FRAME_PACKING:
+ CHECK(FUNC(sei_frame_packing_arrangement)
+ (ctx, rw, ¤t->payload.frame_packing_arrangement));
+ break;
case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME:
CHECK(FUNC(sei_mastering_display_colour_volume)
(ctx, rw, ¤t->payload.mastering_display_colour_volume));