Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

h264: fix for Annex-B bitstreams with 4-byte startcode #1092

Merged
merged 2 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/h264/nal.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ int h264_fu_hdr_decode(struct h264_fu *fu, struct mbuf *mb)
*
* @note: copied from ffmpeg source
*/
const uint8_t *h264_find_startcode(const uint8_t *p, const uint8_t *end)
static const uint8_t *h264_find_startcode_int(const uint8_t *p,
const uint8_t *end)
{
const uint8_t *a = p + 4 - ((size_t)p & 3);

Expand Down Expand Up @@ -191,6 +192,18 @@ const uint8_t *h264_find_startcode(const uint8_t *p, const uint8_t *end)
}


const uint8_t *h264_find_startcode(const uint8_t *p, const uint8_t *end)
{
const uint8_t *out = h264_find_startcode_int(p, end);

/* check for 4-byte startcode */
if (p<out && out<end && !out[-1])
--out;

return out;
}


static int rtp_send_data(const uint8_t *hdr, size_t hdr_sz,
const uint8_t *buf, size_t sz,
bool eof, uint64_t rtp_ts,
Expand Down
57 changes: 46 additions & 11 deletions test/h264.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ struct state {
struct mbuf *mb;
size_t frag_start;
bool frag;
bool long_startcode;

/* test */
uint8_t buf[256];
Expand All @@ -506,8 +507,11 @@ static void fragment_rewind(struct state *vds)
static int depack_handle_h264(struct state *st, bool marker,
struct mbuf *src)
{
static const uint8_t nal_seq[3] = {0, 0, 1};
static const uint8_t nal_seq3[3] = {0, 0, 1};
static const uint8_t nal_seq4[4] = {0, 0, 0, 1};
struct h264_nal_header h264_hdr;
size_t nal_seq_len = st->long_startcode ?
sizeof(nal_seq4) : sizeof(nal_seq3);
int err;

err = h264_nal_header_decode(&h264_hdr, src);
Expand All @@ -533,7 +537,9 @@ static int depack_handle_h264(struct state *st, bool marker,
--src->pos;

/* prepend H.264 NAL start sequence */
err = mbuf_write_mem(st->mb, nal_seq, sizeof(nal_seq));
err = mbuf_write_mem(st->mb,
st->long_startcode ? nal_seq4 : nal_seq3,
nal_seq_len);

err |= mbuf_write_mem(st->mb, mbuf_buf(src),
mbuf_get_left(src));
Expand Down Expand Up @@ -561,7 +567,9 @@ static int depack_handle_h264(struct state *st, bool marker,
st->frag = true;

/* prepend H.264 NAL start sequence */
mbuf_write_mem(st->mb, nal_seq, sizeof(nal_seq));
mbuf_write_mem(st->mb,
st->long_startcode ? nal_seq4 : nal_seq3,
nal_seq_len);

/* encode NAL header back to buffer */
err = h264_nal_header_encode(st->mb, &h264_hdr);
Expand Down Expand Up @@ -601,7 +609,8 @@ static int depack_handle_h264(struct state *st, bool marker,
--src->pos;

err = mbuf_write_mem(st->mb,
nal_seq, sizeof(nal_seq));
st->long_startcode ? nal_seq4 : nal_seq3,
nal_seq_len);
err |= mbuf_write_mem(st->mb, mbuf_buf(src), len);
if (err)
goto out;
Expand Down Expand Up @@ -661,21 +670,18 @@ static int packet_handler(bool marker, uint64_t rtp_ts,
}


/* bitstream in Annex-B format (with startcode 00 00 01) */
static const char *bitstream = "000001650010e2238712983719283719823798";


int test_h264_packet(void)
static int test_h264_packet_base(const char *bs, bool long_startcode)
{
struct state state;
const size_t MAX_PKTSIZE = 8;
int err;

memset(&state, 0, sizeof(state));

state.len = strlen(bitstream)/2;
state.long_startcode = long_startcode;
state.len = strlen(bs)/2;

err = str_hex(state.buf, state.len, bitstream);
err = str_hex(state.buf, state.len, bs);
if (err)
return err;

Expand All @@ -696,3 +702,32 @@ int test_h264_packet(void)

return err;
}


/* bitstream in Annex-B format (with startcode 00 00 01) */
static const char *bitstream =
"0000016701020304"
"0000016801020304"
"000001650010e2238712983719283719823798";


/* bitstream in Annex-B format (with startcode 00 00 00 01) */
static const char *bitstream_long =
"000000016701020304"
"000000016801020304"
"00000001650010e2238712983719283719823798";


int test_h264_packet(void)
{
int err;

err = test_h264_packet_base(bitstream, false);
TEST_ERR(err);

err = test_h264_packet_base(bitstream_long, true);
TEST_ERR(err);

out:
return err;
}
Loading