Skip to content

Commit 89dc4cf

Browse files
committed
Implementing a much faster NAL start code scanner
1 parent ebf5742 commit 89dc4cf

10 files changed

Lines changed: 73 additions & 145 deletions

File tree

src/fmt/nal.c

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/fmt/nal.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,19 @@ enum NalUnitType { // Table 7-1 NAL unit type codes
3434
NalUnitType_SEI_HEVC_2 = 40,
3535
};
3636

37-
char *nal_type_to_str(const enum NalUnitType nal_type);
37+
static inline unsigned int nal_find_startcode(const unsigned char *buf,
38+
unsigned int off, unsigned int len)
39+
{
40+
for (; off + 2 < len; off++) {
41+
if (buf[off] == 0 && buf[off + 1] == 0) {
42+
if (buf[off + 2] == 1)
43+
return off;
44+
if (off + 3 < len && buf[off + 2] == 0 && buf[off + 3] == 1)
45+
return off;
46+
}
47+
}
48+
return len;
49+
}
3850

3951
struct NAL {
4052
char isH265;
@@ -48,7 +60,3 @@ struct NAL {
4860
uint8_t unit_type_value;
4961
enum NalUnitType unit_type;
5062
};
51-
52-
void nal_parse_header(struct NAL *nal, const char first_byte);
53-
bool nal_chk4(const char *buf, const uint32_t offset);
54-
bool nal_chk3(const char *buf, const uint32_t offset);

src/hal/plus/gm_hal.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void *gm_audio_thread(void)
137137
(gm_aud_cb)(&outFrame);
138138
}
139139
}
140-
}
140+
}
141141
}
142142
abort:
143143
HAL_INFO("gm_venc", "Shutting down encoding thread...\n");
@@ -148,7 +148,7 @@ int gm_channel_bind(char index)
148148
{
149149
int ret;
150150

151-
_gm_venc_fds[index].bind =
151+
_gm_venc_fds[index].bind =
152152
gm_lib.fnBind(_gm_cap_grp, _gm_cap_dev, _gm_venc_dev[index]);
153153
_gm_venc_fds[index].evType = GM_POLL_READ;
154154

@@ -228,7 +228,7 @@ void gm_region_destroy(char handle)
228228
}
229229

230230
int gm_region_setbitmap(char handle, hal_bitmap *bitmap)
231-
{
231+
{
232232
gm_osd_imgs bitmaps = {
233233
.image = {
234234
{
@@ -293,7 +293,7 @@ int gm_video_create(char index, hal_vidconfig *config)
293293
break;
294294
case HAL_VIDPROFILE_HIGH:
295295
h264chn.profile = GM_VENC_H264PROF_HIGH;
296-
break;
296+
break;
297297
}
298298
h264chn.level = 41;
299299
gm_lib.fnSetDeviceConfig(_gm_venc_dev[index], &h264chn);
@@ -419,25 +419,27 @@ void *gm_video_thread(void)
419419
outPack[0].offset = 0;
420420
outPack[0].timestamp = pack->timestamp;
421421

422-
signed char n = 0;
423-
for (unsigned int p = 0; p < pack->bsSize - 4; p++) {
424-
if (pack->bsData[p] || pack->bsData[p + 1] ||
425-
pack->bsData[p + 2] || pack->bsData[p + 3] != 1) continue;
426-
outPack[0].nalu[n].type = pack->bsData[p + 4] & 0x1F;
427-
outPack[0].nalu[n++].offset = p;
428-
if (n == (pack->isKeyFrame ? 3 : 1)) break;
422+
unsigned int n = 0, sc, scanOff = 0;
423+
unsigned int pktLen = pack->bsSize;
424+
while ((sc = nal_find_startcode(pack->bsData, scanOff, pktLen)) < pktLen) {
425+
unsigned int scLen = (pack->bsData[sc + 2] == 1) ? 3 : 4;
426+
outPack[0].nalu[n].type = pack->bsData[sc + scLen] & 0x1F;
427+
outPack[0].nalu[n].offset = sc;
428+
n++;
429+
scanOff = sc + scLen;
430+
if (n == (pack->isKeyFrame ? 3u : 1u)) break;
429431
}
430432
outPack[0].naluCnt = n;
431-
outPack[0].nalu[n].offset = pack->bsSize;
433+
outPack[0].nalu[n].offset = pktLen;
432434
for (n = 0; n < outPack[0].naluCnt; n++)
433-
outPack[0].nalu[n].length =
435+
outPack[0].nalu[n].length =
434436
outPack[0].nalu[n + 1].offset -
435437
outPack[0].nalu[n].offset;
436438

437439
outStrm.pack = outPack;
438440
(*gm_vid_cb)(i, &outStrm);
439441
}
440-
}
442+
}
441443
}
442444
abort:
443445
HAL_INFO("gm_venc", "Shutting down encoding thread...\n");
@@ -464,4 +466,4 @@ int gm_system_init(void)
464466
return EXIT_SUCCESS;
465467
}
466468

467-
#endif
469+
#endif

src/hal/plus/gm_hal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "gm_venc.h"
88

99
#include "../globals.h"
10+
#include "../../fmt/nal.h"
1011

1112
#define GM_LIB_API "1.0"
1213
#define GM_MAX_SNAP (1024 * 1024)

src/hal/plus/rk_hal.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -807,15 +807,17 @@ void *rk_video_thread(void)
807807
switch (rk_state[i].payload) {
808808
case HAL_VIDCODEC_H264:
809809
if (pack->naluType.h264Nalu != RK_VENC_NALU_H264_IDRSLICE) {
810-
signed char n = 0;
811-
for (unsigned int p = 0; p < outPack[j].length - 4; p++) {
812-
if (outPack[j].data[p] || outPack[j].data[p + 1] ||
813-
outPack[j].data[p + 2] || outPack[j].data[p + 3] != 1) continue;
814-
outPack[0].nalu[n].type = outPack[j].data[p + 4] & 0x1F;
815-
outPack[0].nalu[n++].offset = p;
810+
unsigned int n = 0, sc, scanOff = 0;
811+
unsigned int pktLen = outPack[j].length;
812+
while ((sc = nal_find_startcode(outPack[j].data, scanOff, pktLen)) < pktLen) {
813+
unsigned int scLen = (outPack[j].data[sc + 2] == 1) ? 3 : 4;
814+
outPack[0].nalu[n].type = outPack[j].data[sc + scLen] & 0x1F;
815+
outPack[0].nalu[n].offset = sc;
816+
n++;
817+
scanOff = sc + scLen;
816818
}
817819
outPack[0].naluCnt = n;
818-
outPack[0].nalu[n].offset = pack->length;
820+
outPack[0].nalu[n].offset = pktLen;
819821
for (n = 0; n < outPack[0].naluCnt; n++)
820822
outPack[0].nalu[n].length =
821823
outPack[0].nalu[n + 1].offset -

src/hal/plus/rk_hal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "rk_vpss.h"
1212

1313
#include "../globals.h"
14+
#include "../../fmt/nal.h"
1415

1516
#include <fcntl.h>
1617
#include <pthread.h>

src/hal/star/i3_hal.c

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -770,30 +770,23 @@ void *i3_video_thread(void)
770770
outPack[j].length = pack->length;
771771
outPack[j].naluCnt = pack->packNum;
772772
if (series == 0xEF) {
773-
signed char n = 0;
774-
switch (i3_state[i].payload) {
775-
case HAL_VIDCODEC_H264:
776-
for (unsigned int p = 0; p < pack->length - 4; p++) {
777-
if (outPack[j].data[p] || outPack[j].data[p + 1] ||
778-
outPack[j].data[p + 2] || outPack[j].data[p + 3] != 1) continue;
779-
outPack[0].nalu[n].type = outPack[j].data[p + 4] & 0x1F;
780-
outPack[0].nalu[n++].offset = p;
781-
if (n == (outPack[j].naluCnt)) break;
782-
}
783-
break;
784-
case HAL_VIDCODEC_H265:
785-
for (unsigned int p = 0; p < pack->length - 4; p++) {
786-
if (outPack[j].data[p] || outPack[j].data[p + 1] ||
787-
outPack[j].data[p + 2] || outPack[j].data[p + 3] != 1) continue;
788-
outPack[0].nalu[n].type = (outPack[j].data[p + 4] & 0x7E) >> 1;
789-
outPack[0].nalu[n++].offset = p;
790-
if (n == (outPack[j].naluCnt)) break;
791-
}
792-
break;
773+
unsigned int n = 0;
774+
unsigned int sc, scanOff = 0;
775+
unsigned int pktLen = pack->length;
776+
while (n < 8 &&
777+
(sc = nal_find_startcode(outPack[j].data,
778+
scanOff, pktLen)) < pktLen) {
779+
unsigned int scLen = (outPack[j].data[sc + 2] == 1) ? 3 : 4;
780+
outPack[0].nalu[n].type =
781+
i3_state[i].payload == HAL_VIDCODEC_H264
782+
? (outPack[j].data[sc + scLen] & 0x1F)
783+
: ((outPack[j].data[sc + scLen] & 0x7E) >> 1);
784+
outPack[0].nalu[n].offset = sc;
785+
n++;
786+
scanOff = sc + scLen;
793787
}
794-
795788
outPack[0].naluCnt = n;
796-
outPack[0].nalu[n].offset = pack->length;
789+
outPack[0].nalu[n].offset = pktLen;
797790
for (n = 0; n < outPack[0].naluCnt; n++)
798791
outPack[0].nalu[n].length =
799792
outPack[0].nalu[n + 1].offset -

src/hal/star/i3_hal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "i3_vi.h"
1010

1111
#include "../globals.h"
12+
#include "../../fmt/nal.h"
1213

1314
#include <sys/select.h>
1415
#include <unistd.h>

src/hal/star/i6_hal.c

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -881,30 +881,23 @@ void *i6_video_thread(void)
881881
outPack[j].length = pack->length;
882882
outPack[j].naluCnt = pack->packNum;
883883
if (series == 0xEF) {
884-
signed char n = 0;
885-
switch (i6_state[i].payload) {
886-
case HAL_VIDCODEC_H264:
887-
for (unsigned int p = 0; p < pack->length - 4; p++) {
888-
if (outPack[j].data[p] || outPack[j].data[p + 1] ||
889-
outPack[j].data[p + 2] || outPack[j].data[p + 3] != 1) continue;
890-
outPack[0].nalu[n].type = outPack[j].data[p + 4] & 0x1F;
891-
outPack[0].nalu[n++].offset = p;
892-
if (n == (outPack[j].naluCnt)) break;
893-
}
894-
break;
895-
case HAL_VIDCODEC_H265:
896-
for (unsigned int p = 0; p < pack->length - 4; p++) {
897-
if (outPack[j].data[p] || outPack[j].data[p + 1] ||
898-
outPack[j].data[p + 2] || outPack[j].data[p + 3] != 1) continue;
899-
outPack[0].nalu[n].type = (outPack[j].data[p + 4] & 0x7E) >> 1;
900-
outPack[0].nalu[n++].offset = p;
901-
if (n == (outPack[j].naluCnt)) break;
902-
}
903-
break;
884+
unsigned int n = 0;
885+
unsigned int sc, scanOff = 0;
886+
unsigned int pktLen = pack->length;
887+
while (n < 8 &&
888+
(sc = nal_find_startcode(outPack[j].data,
889+
scanOff, pktLen)) < pktLen) {
890+
unsigned int scLen = (outPack[j].data[sc + 2] == 1) ? 3 : 4;
891+
outPack[0].nalu[n].type =
892+
i6_state[i].payload == HAL_VIDCODEC_H264
893+
? (outPack[j].data[sc + scLen] & 0x1F)
894+
: ((outPack[j].data[sc + scLen] & 0x7E) >> 1);
895+
outPack[0].nalu[n].offset = sc;
896+
n++;
897+
scanOff = sc + scLen;
904898
}
905-
906899
outPack[0].naluCnt = n;
907-
outPack[0].nalu[n].offset = pack->length;
900+
outPack[0].nalu[n].offset = pktLen;
908901
for (n = 0; n < outPack[0].naluCnt; n++)
909902
outPack[0].nalu[n].length =
910903
outPack[0].nalu[n + 1].offset -

src/hal/star/i6_hal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "i6_vpe.h"
1313

1414
#include "../globals.h"
15+
#include "../../fmt/nal.h"
1516

1617
#include <sys/select.h>
1718
#include <unistd.h>

0 commit comments

Comments
 (0)