+add_packed_sei_header (GstVaapiEncoderH264 * encoder,
+ GstVaapiEncPicture * picture,
+ GstVaapiH264SeiPayloadType payloadtype)
+{
+ GstVaapiEncPackedHeader *packed_sei;
+ GstBitWriter bs, bs_buf_period, bs_pic_timing;
+ VAEncPackedHeaderParameterBuffer packed_sei_param = { 0 };
+ guint32 data_bit_size;
+ guint8 buf_period_payload_size = 0, pic_timing_payload_size = 0;
+ guint8 *data, *buf_period_payload, *pic_timing_payload;
+ gboolean need_buf_period, need_pic_timing;
+
+ gst_bit_writer_init (&bs_buf_period, 128 * 8);
+ gst_bit_writer_init (&bs_pic_timing, 128 * 8);
+ gst_bit_writer_init (&bs, 128 * 8);
+
+ need_buf_period = GST_VAAPI_H264_SEI_BUF_PERIOD & payloadtype;
+ need_pic_timing = GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype;
+
+ if (need_buf_period) {
+ /* Write a Buffering Period SEI message */
+ bs_write_sei_buf_period (&bs_buf_period, encoder, picture);
+ /* Write byte alignment bits */
+ if (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period) % 8 != 0)
+ bs_write_trailing_bits(&bs_buf_period);
+ buf_period_payload_size =
+ (GST_BIT_WRITER_BIT_SIZE (&bs_buf_period)) / 8;
+ buf_period_payload = GST_BIT_WRITER_DATA (&bs_buf_period);
+ }
+
+ if (need_pic_timing) {
+ /* Write a Picture Timing SEI message */
+ if (GST_VAAPI_H264_SEI_PIC_TIMING & payloadtype)
+ bs_write_sei_pic_timing (&bs_pic_timing, encoder, picture);
+ /* Write byte alignment bits */
+ if (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing) % 8 != 0)
+ bs_write_trailing_bits(&bs_pic_timing);
+ pic_timing_payload_size =
+ (GST_BIT_WRITER_BIT_SIZE (&bs_pic_timing)) / 8;
+ pic_timing_payload = GST_BIT_WRITER_DATA (&bs_pic_timing);
+ }
+
+ /* Write the SEI message */
+ WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
+ bs_write_nal_header (&bs, GST_H264_NAL_REF_IDC_NONE, GST_H264_NAL_SEI);
+
+ if (need_buf_period) {
+ WRITE_UINT32 (&bs, GST_H264_SEI_BUF_PERIOD, 8);
+ WRITE_UINT32 (&bs, buf_period_payload_size, 8);
+ /* Add buffering period sei message */
+ gst_bit_writer_put_bytes (&bs, buf_period_payload, buf_period_payload_size);
+ }
+
+ if (need_pic_timing) {
+ WRITE_UINT32 (&bs, GST_H264_SEI_PIC_TIMING, 8);
+ WRITE_UINT32 (&bs, pic_timing_payload_size, 8);
+ /* Add picture timing sei message */
+ gst_bit_writer_put_bytes (&bs, pic_timing_payload, pic_timing_payload_size);
+ }
+
+ /* rbsp_trailing_bits */
+ bs_write_trailing_bits (&bs);
+
+ g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
+ data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
+ data = GST_BIT_WRITER_DATA (&bs);
+
+ packed_sei_param.type = VAEncPackedHeaderH264_SEI;
+ packed_sei_param.bit_length = data_bit_size;
+ packed_sei_param.has_emulation_bytes = 0;
+
+ packed_sei = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
+ &packed_sei_param, sizeof (packed_sei_param),
+ data, (data_bit_size + 7) / 8);
+ g_assert (packed_sei);
+
+ gst_vaapi_enc_picture_add_packed_header (picture, packed_sei);
+ gst_vaapi_codec_object_replace (&packed_sei, NULL);
+
+ gst_bit_writer_clear (&bs_buf_period, TRUE);
+ gst_bit_writer_clear (&bs_pic_timing, TRUE);
+ gst_bit_writer_clear (&bs, TRUE);
+ return TRUE;
+
+ /* ERRORS */
+bs_error:
+ {
+ GST_WARNING ("failed to write SEI NAL unit");
+ gst_bit_writer_clear (&bs_buf_period, TRUE);
+ gst_bit_writer_clear (&bs_pic_timing, TRUE);
+ gst_bit_writer_clear (&bs, TRUE);
+ return FALSE;
+ }
+}
+
+static gboolean