[FFmpeg-devel] [PATCH v6 15/22] cbs_h264: Add support for frame packing arrangement SEI messages

Mark Thompson sw at jkqxz.net
Thu Aug 13 00:04:12 EEST 2020


On 11/08/2020 21:13, Andreas Rheinhardt wrote:
> Mark Thompson:
>> ---
>>   libavcodec/cbs_h264.h                 | 24 ++++++++++++++++
>>   libavcodec/cbs_h2645.c                |  1 +
>>   libavcodec/cbs_h264_syntax_template.c | 40 +++++++++++++++++++++++++++
>>   3 files changed, 65 insertions(+)
>>
>> diff --git a/libavcodec/cbs_h264.h b/libavcodec/cbs_h264.h
>> index 88313629f5..ca717a3b57 100644
>> --- a/libavcodec/cbs_h264.h
>> +++ b/libavcodec/cbs_h264.h
>> @@ -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
>> diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
>> index 603017d8fe..1677731db9 100644
>> --- a/libavcodec/cbs_h2645.c
>> +++ b/libavcodec/cbs_h2645.c
>> @@ -1331,6 +1331,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:
>> diff --git a/libavcodec/cbs_h264_syntax_template.c b/libavcodec/cbs_h264_syntax_template.c
>> index b65460996b..7880b1472c 100644
>> --- a/libavcodec/cbs_h264_syntax_template.c
>> +++ b/libavcodec/cbs_h264_syntax_template.c
>> @@ -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);
> 
> Only values 0-7 are currently defined, yet all other values are reserved
> for future use. Same goes for content_interpretation_type and
> frame_packing_arrangement_reserved_byte. We typically don't error out if
> values reserved for future use are encountered (see for example the
> matrix and transfer stuff in the VUI).
> 
> The same goes for content_interpretation_type and
> frame_packing_arrangement_reserved_byte.
> 
>> +        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);
> 
> If this flag is set (where the value 1 is illegal for samples conforming
> to the current version of the spec), then there will be further data
> which should be ignored by decoders conforming to this version of the
> standard. Chances are that this SEI message will run afoul of the
> byte-alignment check or the incorrect SEI payload length check below
> (which mysteriously does not check for overreads, but only for
> underreads). I wish we could simply passthrough the data that follows,
> but unfortunately we don't know whether the data is already byte-aligned
> or not (unless the last byte of the SEI is zero). We could skip all the
> remaining bits and infer frame_packing_arrangement_extension_flag to be
> zero if it is 1.
> 
> Notice that it is possible for one of the reserved values of one of the
> fields above to require the presence of extension data, i.e. if we
> simply pass the above fields through and ignore the extension, we might
> create invalid output. I don't have a good solution for this.

As discussed on IRC, the one change I've made here is to disallow extensions by changing this line to:

+    u(1, frame_packing_arrangement_extension_flag, 0, 0);

Thanks,

- Mark


More information about the ffmpeg-devel mailing list