h264bitwriter: implement gst_h264_bit_writer_filler()

This is required for vulkan encoder since it can only write slides after aligned
offsets.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7785>
This commit is contained in:
Víctor Manuel Jáquez Leal 2024-10-11 11:57:15 -04:00 committed by GStreamer Marge Bot
parent 8be9693b1e
commit d9aa8a78ea
3 changed files with 99 additions and 0 deletions

View file

@ -1661,3 +1661,64 @@ error:
return need_more_space ? GST_H264_BIT_WRITER_INVALID_DATA :
GST_H264_BIT_WRITER_NO_MORE_SPACE;
}
/**
* gst_h264_bit_writer_filler:
* @start_code: whether adding the nal start code
* @num: number of filler codes to add
* @data: (inout): bit stream storage
* @size: (inout): size in bytes of the input and output
*
* Generates the according h264 bit stream nal bitstream of a filler with @size.
*
* Returns: a #GstH264BitWriterResult
*
* Since: 1.26
**/
GstH264BitWriterResult
gst_h264_bit_writer_filler (gboolean start_code, guint num, guint8 * data,
guint * size)
{
gboolean have_space = TRUE;
GstBitWriter bw;
guint i;
g_return_val_if_fail (data != NULL, GST_H264_BIT_WRITER_ERROR);
g_return_val_if_fail (size != NULL, GST_H264_BIT_WRITER_ERROR);
g_return_val_if_fail (*size > 0, GST_H264_BIT_WRITER_ERROR);
gst_bit_writer_init_with_data (&bw, data, *size, FALSE);
if (start_code)
WRITE_BITS (&bw, 0x00000001, 32);
/* nal header */
/* forbidden_zero_bit */
WRITE_BITS (&bw, 0, 1);
/* nal_ref_idc */
WRITE_BITS (&bw, 0, 2);
/* nal_unit_type */
WRITE_BITS (&bw, GST_H264_NAL_FILLER_DATA, 5);
for (i = 0; i < num; i++)
WRITE_BITS (&bw, 0xff, 8);
/* Add trailings. */
WRITE_BITS (&bw, 1, 1);
if (!gst_bit_writer_align_bytes (&bw, 0)) {
have_space = FALSE;
goto error;
}
*size = (gst_bit_writer_get_size (&bw)) / 8;
gst_bit_writer_reset (&bw);
return GST_H264_BIT_WRITER_OK;
error:
gst_bit_writer_reset (&bw);
*size = 0;
return have_space ? GST_H264_BIT_WRITER_INVALID_DATA :
GST_H264_BIT_WRITER_NO_MORE_SPACE;
}

View file

@ -74,6 +74,11 @@ GstH264BitWriterResult gst_h264_bit_writer_aud (guint8 primary_pic_typ
guint8 * data,
guint * size);
GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_filler (gboolean start_code,
guint num,
guint8 * data,
guint * size);
GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_convert_to_nal (guint nal_prefix_size,
gboolean packetized,
gboolean has_startcode,

View file

@ -523,6 +523,38 @@ GST_START_TEST (test_h264_bitwriter_sei)
GST_END_TEST;
GST_START_TEST (test_h264_bitwriter_filler)
{
GstH264ParserResult res;
GstH264BitWriterResult ret;
GstH264NalParser *const parser = gst_h264_nal_parser_new ();
guint size, nal_size;
guint8 header_data[128] = { 0, };
guint8 header_nal[128] = { 0, };
GstH264NalUnit nalu;
size = sizeof (header_data);
ret = gst_h264_bit_writer_filler (TRUE, 5, header_data, &size);
fail_if (ret != GST_H264_BIT_WRITER_OK);
nal_size = sizeof (header_nal);
ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE,
header_data, size * 8, header_nal, &nal_size);
fail_if (ret != GST_H264_BIT_WRITER_OK);
fail_if (nal_size < size);
/* Parse it again */
res = gst_h264_parser_identify_nalu (parser, header_nal, 0,
sizeof (header_nal), &nalu);
assert_equals_int (res, GST_H264_PARSER_NO_NAL_END);
fail_if (nalu.type != GST_H264_NAL_FILLER_DATA);
fail_if (nalu.size != sizeof (header_nal) - nalu.offset);
gst_h264_nal_parser_free (parser);
}
GST_END_TEST;
static Suite *
h264bitwriter_suite (void)
{
@ -533,6 +565,7 @@ h264bitwriter_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_h264_bitwriter_sps_pps_slice_hdr);
tcase_add_test (tc_chain, test_h264_bitwriter_sei);
tcase_add_test (tc_chain, test_h264_bitwriter_filler);
return s;
}