h264bitwriter: Correct the all API to byte aligned.

In fact, all the h264 bit writer have byte aligned output except
the slice header. So we change the API from bit size in unit to
byte size, which is easy to use. For slice header, we add a extra
"trail_bits_num" to return the unaligned bits number.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3193>
This commit is contained in:
He Junyan 2022-10-27 13:42:17 +08:00 committed by GStreamer Marge Bot
parent 9dc76185fc
commit c294ba82e6
4 changed files with 51 additions and 44 deletions

View file

@ -424,7 +424,7 @@ error:
* @sps: the sps of #GstH264SPS to write * @sps: the sps of #GstH264SPS to write
* @start_code: whether adding the nal start code * @start_code: whether adding the nal start code
* @data: (out): the bit stream generated by the sps * @data: (out): the bit stream generated by the sps
* @size: (inout): the size in bits of the output * @size: (inout): the size in bytes of the input and output
* *
* Generating the according h264 bit stream by providing the sps. * Generating the according h264 bit stream by providing the sps.
* *
@ -434,7 +434,7 @@ error:
**/ **/
GstH264BitWriterResult GstH264BitWriterResult
gst_h264_bit_writer_sps (const GstH264SPS * sps, gboolean start_code, gst_h264_bit_writer_sps (const GstH264SPS * sps, gboolean start_code,
guint8 * data, gsize * size) guint8 * data, guint * size)
{ {
gboolean have_space = TRUE; gboolean have_space = TRUE;
GstBitWriter bw; GstBitWriter bw;
@ -467,7 +467,7 @@ gst_h264_bit_writer_sps (const GstH264SPS * sps, gboolean start_code,
goto error; goto error;
} }
*size = gst_bit_writer_get_size (&bw); *size = (gst_bit_writer_get_size (&bw)) / 8;
gst_bit_writer_reset (&bw); gst_bit_writer_reset (&bw);
return GST_H264_BIT_WRITER_OK; return GST_H264_BIT_WRITER_OK;
@ -595,7 +595,7 @@ error:
* @pps: the pps of #GstH264PPS to write * @pps: the pps of #GstH264PPS to write
* @start_code: whether adding the nal start code * @start_code: whether adding the nal start code
* @data: (out): the bit stream generated by the pps * @data: (out): the bit stream generated by the pps
* @size: (inout): the size in bits of the output * @size: (inout): the size in bytes of the input and output
* *
* Generating the according h264 bit stream by providing the pps. * Generating the according h264 bit stream by providing the pps.
* *
@ -605,7 +605,7 @@ error:
**/ **/
GstH264BitWriterResult GstH264BitWriterResult
gst_h264_bit_writer_pps (const GstH264PPS * pps, gboolean start_code, gst_h264_bit_writer_pps (const GstH264PPS * pps, gboolean start_code,
guint8 * data, gsize * size) guint8 * data, guint * size)
{ {
gboolean have_space = TRUE; gboolean have_space = TRUE;
GstBitWriter bw; GstBitWriter bw;
@ -639,7 +639,7 @@ gst_h264_bit_writer_pps (const GstH264PPS * pps, gboolean start_code,
goto error; goto error;
} }
*size = gst_bit_writer_get_size (&bw); *size = (gst_bit_writer_get_size (&bw)) / 8;
gst_bit_writer_reset (&bw); gst_bit_writer_reset (&bw);
return GST_H264_BIT_WRITER_OK; return GST_H264_BIT_WRITER_OK;
@ -986,7 +986,8 @@ error:
* @nal_type: the slice's nal type of #GstH264NalUnitType * @nal_type: the slice's nal type of #GstH264NalUnitType
* @is_ref: whether the slice is a reference * @is_ref: whether the slice is a reference
* @data: (out): the bit stream generated by the slice header * @data: (out): the bit stream generated by the slice header
* @size: (inout): the size in bits of the output * @size: (inout): the size in bytes of the input and output
* @trail_bits_num: (out): the trail bits number which is not byte aligned.
* *
* Generating the according h264 bit stream by providing the slice header. * Generating the according h264 bit stream by providing the slice header.
* *
@ -997,7 +998,7 @@ error:
GstH264BitWriterResult GstH264BitWriterResult
gst_h264_bit_writer_slice_hdr (const GstH264SliceHdr * slice, gst_h264_bit_writer_slice_hdr (const GstH264SliceHdr * slice,
gboolean start_code, GstH264NalUnitType nal_type, gboolean is_ref, gboolean start_code, GstH264NalUnitType nal_type, gboolean is_ref,
guint8 * data, gsize * size) guint8 * data, guint * size, guint * trail_bits_num)
{ {
gboolean have_space = TRUE; gboolean have_space = TRUE;
GstBitWriter bw; GstBitWriter bw;
@ -1011,6 +1012,7 @@ gst_h264_bit_writer_slice_hdr (const GstH264SliceHdr * slice,
g_return_val_if_fail (data != NULL, GST_H264_BIT_WRITER_ERROR); 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 != NULL, GST_H264_BIT_WRITER_ERROR);
g_return_val_if_fail (*size > 0, GST_H264_BIT_WRITER_ERROR); g_return_val_if_fail (*size > 0, GST_H264_BIT_WRITER_ERROR);
g_return_val_if_fail (trail_bits_num != NULL, GST_H264_BIT_WRITER_ERROR);
if (nal_type == GST_H264_NAL_SLICE_IDR) if (nal_type == GST_H264_NAL_SLICE_IDR)
g_return_val_if_fail (is_ref, GST_H264_BIT_WRITER_ERROR); g_return_val_if_fail (is_ref, GST_H264_BIT_WRITER_ERROR);
@ -1034,7 +1036,8 @@ gst_h264_bit_writer_slice_hdr (const GstH264SliceHdr * slice,
/* We do not add trailing bits here, the slice data should follow it. */ /* We do not add trailing bits here, the slice data should follow it. */
*size = gst_bit_writer_get_size (&bw); *size = gst_bit_writer_get_size (&bw) / 8;
*trail_bits_num = gst_bit_writer_get_size (&bw) % 8;
gst_bit_writer_reset (&bw); gst_bit_writer_reset (&bw);
return GST_H264_BIT_WRITER_OK; return GST_H264_BIT_WRITER_OK;
@ -1364,7 +1367,7 @@ error:
* @sei_messages: An array of #GstH264SEIMessage to write * @sei_messages: An array of #GstH264SEIMessage to write
* @start_code: whether adding the nal start code * @start_code: whether adding the nal start code
* @data: (out): the bit stream generated by the sei messages * @data: (out): the bit stream generated by the sei messages
* @size: (inout): the size in bits of the output * @size: (inout): the size in bytes of the input and output
* *
* Generating the according h264 bit stream by providing sei messages. * Generating the according h264 bit stream by providing sei messages.
* *
@ -1374,7 +1377,7 @@ error:
**/ **/
GstH264BitWriterResult GstH264BitWriterResult
gst_h264_bit_writer_sei (GArray * sei_messages, gboolean start_code, gst_h264_bit_writer_sei (GArray * sei_messages, gboolean start_code,
guint8 * data, gsize * size) guint8 * data, guint * size)
{ {
gboolean have_space = TRUE; gboolean have_space = TRUE;
GstBitWriter bw; GstBitWriter bw;
@ -1456,7 +1459,7 @@ gst_h264_bit_writer_sei (GArray * sei_messages, gboolean start_code,
goto error; goto error;
} }
*size = gst_bit_writer_get_size (&bw); *size = (gst_bit_writer_get_size (&bw)) / 8;
gst_bit_writer_reset (&bw); gst_bit_writer_reset (&bw);
return GST_H264_BIT_WRITER_OK; return GST_H264_BIT_WRITER_OK;
@ -1474,7 +1477,7 @@ error:
* as the H264 spec defines * as the H264 spec defines
* @start_code: whether adding the nal start code * @start_code: whether adding the nal start code
* @data: (out): the bit stream generated by the aud * @data: (out): the bit stream generated by the aud
* @size: (inout): the size in bits of the output * @size: (inout): the size in bytes of the input and output
* *
* Generating the according h264 bit stream of an aud. * Generating the according h264 bit stream of an aud.
* *
@ -1484,7 +1487,7 @@ error:
**/ **/
GstH264BitWriterResult GstH264BitWriterResult
gst_h264_bit_writer_aud (guint8 primary_pic_type, gboolean start_code, gst_h264_bit_writer_aud (guint8 primary_pic_type, gboolean start_code,
guint8 * data, gsize * size) guint8 * data, guint * size)
{ {
gboolean have_space = TRUE; gboolean have_space = TRUE;
GstBitWriter bw; GstBitWriter bw;
@ -1516,7 +1519,7 @@ gst_h264_bit_writer_aud (guint8 primary_pic_type, gboolean start_code,
goto error; goto error;
} }
*size = gst_bit_writer_get_size (&bw); *size = (gst_bit_writer_get_size (&bw)) / 8;
gst_bit_writer_reset (&bw); gst_bit_writer_reset (&bw);
return GST_H264_BIT_WRITER_OK; return GST_H264_BIT_WRITER_OK;
@ -1556,7 +1559,7 @@ error:
GstH264BitWriterResult GstH264BitWriterResult
gst_h264_bit_writer_convert_to_nal (guint nal_prefix_size, gboolean packetized, gst_h264_bit_writer_convert_to_nal (guint nal_prefix_size, gboolean packetized,
gboolean has_startcode, gboolean add_trailings, const guint8 * raw_data, gboolean has_startcode, gboolean add_trailings, const guint8 * raw_data,
gsize raw_size, guint8 * nal_data, guint32 * nal_size) gsize raw_size, guint8 * nal_data, guint * nal_size)
{ {
NalWriter nw; NalWriter nw;
guint8 *data; guint8 *data;

View file

@ -49,29 +49,30 @@ GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_sps (const GstH264SPS * sps, GstH264BitWriterResult gst_h264_bit_writer_sps (const GstH264SPS * sps,
gboolean start_code, gboolean start_code,
guint8 * data, guint8 * data,
gsize * size); guint * size);
GST_CODEC_PARSERS_API GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_pps (const GstH264PPS * pps, GstH264BitWriterResult gst_h264_bit_writer_pps (const GstH264PPS * pps,
gboolean start_code, gboolean start_code,
guint8 * data, guint8 * data,
gsize * size); guint * size);
GST_CODEC_PARSERS_API GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_slice_hdr (const GstH264SliceHdr * slice, GstH264BitWriterResult gst_h264_bit_writer_slice_hdr (const GstH264SliceHdr * slice,
gboolean start_code, gboolean start_code,
GstH264NalUnitType nal_type, GstH264NalUnitType nal_type,
gboolean is_ref, gboolean is_ref,
guint8 * data, guint8 * data,
gsize * size); guint * size,
guint * trail_bits_num);
GST_CODEC_PARSERS_API GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_sei (GArray * sei_messages, GstH264BitWriterResult gst_h264_bit_writer_sei (GArray * sei_messages,
gboolean start_code, gboolean start_code,
guint8 * data, guint8 * data,
gsize * size); guint * size);
GST_CODEC_PARSERS_API GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_aud (guint8 primary_pic_type, GstH264BitWriterResult gst_h264_bit_writer_aud (guint8 primary_pic_type,
gboolean start_code, gboolean start_code,
guint8 * data, guint8 * data,
gsize * size); guint * size);
GST_CODEC_PARSERS_API GST_CODEC_PARSERS_API
GstH264BitWriterResult gst_h264_bit_writer_convert_to_nal (guint nal_prefix_size, GstH264BitWriterResult gst_h264_bit_writer_convert_to_nal (guint nal_prefix_size,
gboolean packetized, gboolean packetized,
@ -80,7 +81,7 @@ GstH264BitWriterResult gst_h264_bit_writer_convert_to_nal (guint nal_prefix_
const guint8 * raw_data, const guint8 * raw_data,
gsize raw_size, gsize raw_size,
guint8 * nal_data, guint8 * nal_data,
guint32 * nal_size); guint * nal_size);
G_END_DECLS G_END_DECLS

View file

@ -2033,7 +2033,7 @@ static gboolean
_add_sequence_header (GstVaH264Enc * self, GstVaH264EncFrame * frame) _add_sequence_header (GstVaH264Enc * self, GstVaH264EncFrame * frame)
{ {
GstVaBaseEnc *base = GST_VA_BASE_ENC (self); GstVaBaseEnc *base = GST_VA_BASE_ENC (self);
gsize size; guint size;
#define SPS_SIZE 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + MAX_VUI_PARAMS_SIZE + \ #define SPS_SIZE 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE + MAX_VUI_PARAMS_SIZE + \
2 * MAX_HRD_PARAMS_SIZE) / 8 2 * MAX_HRD_PARAMS_SIZE) / 8
guint8 packed_sps[SPS_SIZE] = { 0, }; guint8 packed_sps[SPS_SIZE] = { 0, };
@ -2047,7 +2047,7 @@ _add_sequence_header (GstVaH264Enc * self, GstVaH264EncFrame * frame)
} }
if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture, if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture,
VAEncPackedHeaderSequence, packed_sps, size, FALSE)) { VAEncPackedHeaderSequence, packed_sps, size * 8, FALSE)) {
GST_ERROR_OBJECT (self, "Failed to add the packed sequence header"); GST_ERROR_OBJECT (self, "Failed to add the packed sequence header");
return FALSE; return FALSE;
} }
@ -2299,7 +2299,7 @@ _add_picture_header (GstVaH264Enc * self, GstVaH264EncFrame * frame,
#define PPS_SIZE 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8 #define PPS_SIZE 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8
guint8 packed_pps[PPS_SIZE] = { 0, }; guint8 packed_pps[PPS_SIZE] = { 0, };
#undef PPS_SIZE #undef PPS_SIZE
gsize size; guint size;
size = sizeof (packed_pps); size = sizeof (packed_pps);
if (gst_h264_bit_writer_pps (pps, TRUE, packed_pps, if (gst_h264_bit_writer_pps (pps, TRUE, packed_pps,
@ -2309,7 +2309,7 @@ _add_picture_header (GstVaH264Enc * self, GstVaH264EncFrame * frame,
} }
if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture, if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture,
VAEncPackedHeaderPicture, packed_pps, size, FALSE)) { VAEncPackedHeaderPicture, packed_pps, size * 8, FALSE)) {
GST_ERROR_OBJECT (self, "Failed to add the packed picture header"); GST_ERROR_OBJECT (self, "Failed to add the packed picture header");
return FALSE; return FALSE;
} }
@ -2562,7 +2562,7 @@ _add_slice_header (GstVaH264Enc * self, GstVaH264EncFrame * frame,
{ {
GstVaBaseEnc *base = GST_VA_BASE_ENC (self); GstVaBaseEnc *base = GST_VA_BASE_ENC (self);
GstH264SliceHdr slice_hdr; GstH264SliceHdr slice_hdr;
gsize size; guint size, trail_bits;
GstH264NalUnitType nal_type = GST_H264_NAL_SLICE; GstH264NalUnitType nal_type = GST_H264_NAL_SLICE;
#define SLICE_HDR_SIZE 4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8 #define SLICE_HDR_SIZE 4 + GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE) / 8
guint8 packed_slice_hdr[SLICE_HDR_SIZE] = { 0, }; guint8 packed_slice_hdr[SLICE_HDR_SIZE] = { 0, };
@ -2636,14 +2636,16 @@ _add_slice_header (GstVaH264Enc * self, GstVaH264EncFrame * frame,
} }
size = sizeof (packed_slice_hdr); size = sizeof (packed_slice_hdr);
trail_bits = 0;
if (gst_h264_bit_writer_slice_hdr (&slice_hdr, TRUE, nal_type, frame->is_ref, if (gst_h264_bit_writer_slice_hdr (&slice_hdr, TRUE, nal_type, frame->is_ref,
packed_slice_hdr, &size) != GST_H264_BIT_WRITER_OK) { packed_slice_hdr, &size, &trail_bits) != GST_H264_BIT_WRITER_OK) {
GST_ERROR_OBJECT (self, "Failed to generate the slice header"); GST_ERROR_OBJECT (self, "Failed to generate the slice header");
return FALSE; return FALSE;
} }
if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture, if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture,
VAEncPackedHeaderSlice, packed_slice_hdr, size, FALSE)) { VAEncPackedHeaderSlice, packed_slice_hdr, size * 8 + trail_bits,
FALSE)) {
GST_ERROR_OBJECT (self, "Failed to add the packed slice header"); GST_ERROR_OBJECT (self, "Failed to add the packed slice header");
return FALSE; return FALSE;
} }
@ -2656,7 +2658,7 @@ _add_aud (GstVaH264Enc * self, GstVaH264EncFrame * frame)
{ {
GstVaBaseEnc *base = GST_VA_BASE_ENC (self); GstVaBaseEnc *base = GST_VA_BASE_ENC (self);
guint8 aud_data[8] = { }; guint8 aud_data[8] = { };
gsize size; guint size;
guint8 primary_pic_type = 0; guint8 primary_pic_type = 0;
switch (frame->type) { switch (frame->type) {
@ -2682,7 +2684,7 @@ _add_aud (GstVaH264Enc * self, GstVaH264EncFrame * frame)
} }
if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture, if (!gst_va_encoder_add_packed_header (base->encoder, frame->picture,
VAEncPackedHeaderRawData, aud_data, size, FALSE)) { VAEncPackedHeaderRawData, aud_data, size * 8, FALSE)) {
GST_ERROR_OBJECT (self, "Failed to add the AUD"); GST_ERROR_OBJECT (self, "Failed to add the AUD");
return FALSE; return FALSE;
} }

View file

@ -171,8 +171,8 @@ GST_START_TEST (test_h264_bitwriter_sps_pps_slice_hdr)
GstH264SliceHdr slice_parsed; GstH264SliceHdr slice_parsed;
guint8 header_data[128] = { 0, }; guint8 header_data[128] = { 0, };
guint8 header_nal[128] = { 0, }; guint8 header_nal[128] = { 0, };
gsize size; guint size, trail_bits;
guint32 nal_size; guint nal_size;
guint i; guint i;
size = sizeof (header_data); size = sizeof (header_data);
@ -181,9 +181,9 @@ GST_START_TEST (test_h264_bitwriter_sps_pps_slice_hdr)
nal_size = sizeof (header_nal); nal_size = sizeof (header_nal);
ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE, ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE,
header_data, size, header_nal, &nal_size); header_data, size * 8, header_nal, &nal_size);
fail_if (ret != GST_H264_BIT_WRITER_OK); fail_if (ret != GST_H264_BIT_WRITER_OK);
fail_if (nal_size < GST_ROUND_UP_8 (size) / 8); fail_if (nal_size < size);
/* Parse it again */ /* Parse it again */
res = gst_h264_parser_identify_nalu (parser, header_nal, 0, res = gst_h264_parser_identify_nalu (parser, header_nal, 0,
@ -281,9 +281,9 @@ GST_START_TEST (test_h264_bitwriter_sps_pps_slice_hdr)
nal_size = sizeof (header_nal); nal_size = sizeof (header_nal);
ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE, ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE,
header_data, size, header_nal, &nal_size); header_data, size * 8, header_nal, &nal_size);
fail_if (ret != GST_H264_BIT_WRITER_OK); fail_if (ret != GST_H264_BIT_WRITER_OK);
fail_if (nal_size < GST_ROUND_UP_8 (size) / 8); fail_if (nal_size < size);
/* Parse it again */ /* Parse it again */
res = gst_h264_parser_identify_nalu (parser, header_nal, 0, res = gst_h264_parser_identify_nalu (parser, header_nal, 0,
@ -320,15 +320,16 @@ GST_START_TEST (test_h264_bitwriter_sps_pps_slice_hdr)
memset (header_nal, 0, sizeof (header_nal)); memset (header_nal, 0, sizeof (header_nal));
size = sizeof (header_data); size = sizeof (header_data);
trail_bits = 0;
ret = gst_h264_bit_writer_slice_hdr (&slice_hdr, TRUE, GST_H264_NAL_SLICE, ret = gst_h264_bit_writer_slice_hdr (&slice_hdr, TRUE, GST_H264_NAL_SLICE,
FALSE, header_data, &size); FALSE, header_data, &size, &trail_bits);
fail_if (ret != GST_H264_BIT_WRITER_OK); fail_if (ret != GST_H264_BIT_WRITER_OK);
nal_size = sizeof (header_nal); nal_size = sizeof (header_nal);
ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE, ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, TRUE,
header_data, GST_ROUND_UP_8 (size), header_nal, &nal_size); header_data, size * 8 + trail_bits, header_nal, &nal_size);
fail_if (ret != GST_H264_BIT_WRITER_OK); fail_if (ret != GST_H264_BIT_WRITER_OK);
fail_if (nal_size < GST_ROUND_UP_8 (size) / 8); fail_if (nal_size < size);
/* Parse it again */ /* Parse it again */
res = gst_h264_parser_identify_nalu (parser, header_nal, 0, res = gst_h264_parser_identify_nalu (parser, header_nal, 0,
@ -393,8 +394,8 @@ GST_START_TEST (test_h264_bitwriter_sei)
GArray *msg_array; GArray *msg_array;
GArray *sei_parsed = NULL; GArray *sei_parsed = NULL;
GstH264SEIMessage *sei_msg_parsed; GstH264SEIMessage *sei_msg_parsed;
gsize size; guint size;
guint32 size_nal; guint size_nal;
guint8 sei_data[128] = { 0, }; guint8 sei_data[128] = { 0, };
guint8 sei_nal[128] = { 0, }; guint8 sei_nal[128] = { 0, };
@ -459,7 +460,7 @@ GST_START_TEST (test_h264_bitwriter_sei)
size_nal = sizeof (sei_nal); size_nal = sizeof (sei_nal);
ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE, ret = gst_h264_bit_writer_convert_to_nal (4, FALSE, TRUE, FALSE,
sei_data, size, sei_nal, &size_nal); sei_data, size * 8, sei_nal, &size_nal);
fail_if (ret != GST_H264_BIT_WRITER_OK); fail_if (ret != GST_H264_BIT_WRITER_OK);
/* Parse it again. */ /* Parse it again. */