Skip to content

Commit 6c3cf93

Browse files
committed
Rework streaming to support compressed streams, cleanup
Signed-off-by: Hector Martin <[email protected]>
1 parent c6ed7fe commit 6c3cf93

File tree

2 files changed

+103
-79
lines changed

2 files changed

+103
-79
lines changed

src/cameras.c

+100-73
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,15 @@ static int stream_process(freenect_context *ctx, packet_stream *strm, uint8_t *p
5454
uint8_t *data = pkt + sizeof(*hdr);
5555
int datalen = len - sizeof(*hdr);
5656

57+
freenect_loglevel l_info = LL_INFO;
58+
freenect_loglevel l_notice = LL_NOTICE;
59+
freenect_loglevel l_warning = LL_WARNING;
60+
if (strm->valid_frames < 2)
61+
l_info = l_notice = l_warning = LL_SPEW;
62+
5763
if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
58-
FN_LOG(strm->valid_frames < 2 ? LL_SPEW : LL_NOTICE, \
59-
"[Stream %02x] Invalid magic %02x%02x\n", strm->flag, hdr->magic[0], hdr->magic[1]);
64+
FN_LOG(l_notice, "[Stream %02x] Invalid magic %02x%02x\n",
65+
strm->flag, hdr->magic[0], hdr->magic[1]);
6066
return 0;
6167
}
6268

@@ -79,16 +85,14 @@ static int stream_process(freenect_context *ctx, packet_stream *strm, uint8_t *p
7985
strm->got_pkts = 0;
8086
}
8187

82-
int got_frame = 0;
88+
int got_frame_size = 0;
8389

8490
// handle lost packets
8591
if (strm->seq != hdr->seq) {
8692
uint8_t lost = hdr->seq - strm->seq;
87-
FN_LOG(strm->valid_frames < 2 ? LL_SPEW : LL_INFO, \
88-
"[Stream %02x] Lost %d packets\n", strm->flag, lost);
89-
if (lost > 5) {
90-
FN_LOG(strm->valid_frames < 2 ? LL_SPEW : LL_NOTICE, \
91-
"[Stream %02x] Lost too many packets, resyncing...\n", strm->flag);
93+
FN_LOG(l_info, "[Stream %02x] Lost %d packets\n", strm->flag, lost);
94+
if (lost > 5 || strm->variable_length) {
95+
FN_LOG(l_notice, "[Stream %02x] Lost too many packets, resyncing...\n", strm->flag);
9296
strm->synced = 0;
9397
return 0;
9498
}
@@ -98,36 +102,60 @@ static int stream_process(freenect_context *ctx, packet_stream *strm, uint8_t *p
98102
strm->pkt_num = lost - left;
99103
strm->valid_pkts = strm->got_pkts;
100104
strm->got_pkts = 0;
101-
got_frame = 1;
105+
got_frame_size = strm->frame_size;
102106
strm->timestamp = strm->last_timestamp;
103107
strm->valid_frames++;
104108
} else {
105109
strm->pkt_num += lost;
106110
}
107111
}
108112

109-
// check the header to make sure it's what we expect
110-
if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
111-
!(strm->pkt_num == strm->pkts_per_frame-1 && hdr->flag == eof) &&
112-
!(strm->pkt_num > 0 && strm->pkt_num < strm->pkts_per_frame-1 && hdr->flag == mof)) {
113-
FN_LOG(strm->valid_frames < 2 ? LL_SPEW : LL_NOTICE, \
114-
"[Stream %02x] Inconsistent flag %02x with %d packets in buf (%d total), resyncing...\n",
115-
strm->flag, hdr->flag, strm->pkt_num, strm->pkts_per_frame);
116-
strm->synced = 0;
117-
return got_frame;
118-
}
113+
int expected_pkt_size = (strm->pkt_num == strm->pkts_per_frame-1) ? strm->last_pkt_size : strm->pkt_size;
119114

120-
// copy data
121-
if (datalen > strm->pkt_size) {
122-
FN_LOG(strm->valid_frames < 2 ? LL_SPEW : LL_WARNING, \
123-
"[Stream %02x] Expected %d data bytes, but got %d. Dropping...\n", strm->flag, strm->pkt_size, datalen);
124-
return got_frame;
115+
if (!strm->variable_length) {
116+
// check the header to make sure it's what we expect
117+
if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
118+
!(strm->pkt_num == strm->pkts_per_frame-1 && hdr->flag == eof) &&
119+
!(strm->pkt_num > 0 && strm->pkt_num < strm->pkts_per_frame-1 && hdr->flag == mof)) {
120+
FN_LOG(l_notice, "[Stream %02x] Inconsistent flag %02x with %d packets in buf (%d total), resyncing...\n",
121+
strm->flag, hdr->flag, strm->pkt_num, strm->pkts_per_frame);
122+
strm->synced = 0;
123+
return got_frame_size;
124+
}
125+
// check data length
126+
if (datalen > expected_pkt_size) {
127+
FN_LOG(l_warning, "[Stream %02x] Expected max %d data bytes, but got %d. Dropping...\n",
128+
strm->flag, expected_pkt_size, datalen);
129+
return got_frame_size;
130+
}
131+
if (datalen < expected_pkt_size)
132+
FN_LOG(l_warning, "[Stream %02x] Expected %d data bytes, but got %d\n",
133+
strm->flag, expected_pkt_size, datalen);
134+
} else {
135+
// check the header to make sure it's what we expect
136+
if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
137+
!(strm->pkt_num < strm->pkts_per_frame && (hdr->flag == eof || hdr->flag == mof))) {
138+
FN_LOG(l_notice, "[Stream %02x] Inconsistent flag %02x with %d packets in buf (%d total), resyncing...\n",
139+
strm->flag, hdr->flag, strm->pkt_num, strm->pkts_per_frame);
140+
strm->synced = 0;
141+
return got_frame_size;
142+
}
143+
// check data length
144+
if (datalen > expected_pkt_size) {
145+
FN_LOG(l_warning, "[Stream %02x] Expected max %d data bytes, but got %d. Resyncng...\n",
146+
strm->flag, expected_pkt_size, datalen);
147+
strm->synced = 0;
148+
return got_frame_size;
149+
}
150+
if (datalen < expected_pkt_size && hdr->flag != eof) {
151+
FN_LOG(l_warning, "[Stream %02x] Expected %d data bytes, but got %d. Resyncing...\n",
152+
strm->flag, expected_pkt_size, datalen);
153+
strm->synced = 0;
154+
return got_frame_size;
155+
}
125156
}
126157

127-
if (datalen != strm->pkt_size && hdr->flag != eof)
128-
FN_LOG(strm->valid_frames < 2 ? LL_SPEW : LL_WARNING, \
129-
"[Stream %02x] Expected %d data bytes, but got only %d\n", strm->flag, strm->pkt_size, datalen);
130-
158+
// copy data
131159
uint8_t *dbuf = strm->raw_buf + strm->pkt_num * strm->pkt_size;
132160
memcpy(dbuf, data, datalen);
133161

@@ -137,20 +165,25 @@ static int stream_process(freenect_context *ctx, packet_stream *strm, uint8_t *p
137165

138166
strm->last_timestamp = fn_le32(hdr->timestamp);
139167

140-
if (strm->pkt_num == strm->pkts_per_frame) {
168+
if (hdr->flag == eof) {
169+
if (strm->variable_length)
170+
got_frame_size = (dbuf - strm->raw_buf) + datalen;
171+
else
172+
got_frame_size = (dbuf - strm->raw_buf) + strm->last_pkt_size;
141173
strm->pkt_num = 0;
142174
strm->valid_pkts = strm->got_pkts;
143175
strm->got_pkts = 0;
144176
strm->timestamp = strm->last_timestamp;
145177
strm->valid_frames++;
146-
return 1;
147-
} else {
148-
return got_frame;
149178
}
179+
return got_frame_size;
150180
}
151181

152-
static void stream_initbufs(freenect_context *ctx, packet_stream *strm, int rlen, int plen)
182+
static void stream_init(freenect_context *ctx, packet_stream *strm, int rlen, int plen)
153183
{
184+
strm->valid_frames = 0;
185+
strm->synced = 0;
186+
154187
if (strm->usr_buf) {
155188
strm->lib_buf = NULL;
156189
strm->proc_buf = strm->usr_buf;
@@ -162,10 +195,17 @@ static void stream_initbufs(freenect_context *ctx, packet_stream *strm, int rlen
162195
if (rlen == 0) {
163196
strm->split_bufs = 0;
164197
strm->raw_buf = strm->proc_buf;
198+
strm->frame_size = plen;
165199
} else {
166200
strm->split_bufs = 1;
167201
strm->raw_buf = malloc(rlen);
202+
strm->frame_size = rlen;
168203
}
204+
205+
strm->last_pkt_size = strm->frame_size % strm->pkt_size;
206+
if (strm->last_pkt_size == 0)
207+
strm->last_pkt_size = strm->pkt_size;
208+
strm->pkts_per_frame = (strm->frame_size + strm->pkt_size - 1) / strm->pkt_size;
169209
}
170210

171211
static void stream_freebufs(freenect_context *ctx, packet_stream *strm)
@@ -244,13 +284,13 @@ static void depth_process(freenect_device *dev, uint8_t *pkt, int len)
244284
if (!dev->depth.running)
245285
return;
246286

247-
int got_frame = stream_process(ctx, &dev->depth, pkt, len);
287+
int got_frame_size = stream_process(ctx, &dev->depth, pkt, len);
248288

249-
if (!got_frame)
289+
if (!got_frame_size)
250290
return;
251291

252-
FN_SPEW("Got depth frame %d/%d packets arrived, TS %08x\n",
253-
dev->depth.valid_pkts, dev->depth.pkts_per_frame, dev->depth.timestamp);
292+
FN_SPEW("Got depth frame of size %d/%d, %d/%d packets arrived, TS %08x\n", got_frame_size,
293+
dev->depth.frame_size, dev->depth.valid_pkts, dev->depth.pkts_per_frame, dev->depth.timestamp);
254294

255295
switch (dev->depth_format) {
256296
case FREENECT_DEPTH_11BIT:
@@ -475,13 +515,13 @@ static void video_process(freenect_device *dev, uint8_t *pkt, int len)
475515
if (!dev->video.running)
476516
return;
477517

478-
int got_frame = stream_process(ctx, &dev->video, pkt, len);
518+
int got_frame_size = stream_process(ctx, &dev->video, pkt, len);
479519

480-
if (!got_frame)
520+
if (!got_frame_size)
481521
return;
482522

483-
FN_SPEW("Got RGB frame %d/%d packets arrived, TS %08x\n", dev->video.valid_pkts,
484-
dev->video.pkts_per_frame, dev->video.timestamp);
523+
FN_SPEW("Got video frame of size %d/%d, %d/%d packets arrived, TS %08x\n", got_frame_size,
524+
dev->video.frame_size, dev->video.valid_pkts, dev->video.pkts_per_frame, dev->video.timestamp);
485525

486526
switch (dev->video_format) {
487527
case FREENECT_VIDEO_RGB:
@@ -611,30 +651,25 @@ int freenect_start_depth(freenect_device *dev)
611651
if (dev->depth.running)
612652
return -1;
613653

654+
dev->depth.pkt_size = DEPTH_PKTDSIZE;
655+
dev->depth.flag = 0x70;
656+
dev->depth.variable_length = 0;
657+
614658
switch (dev->depth_format) {
615659
case FREENECT_DEPTH_11BIT:
616-
stream_initbufs(ctx, &dev->depth, FREENECT_DEPTH_11BIT_PACKED_SIZE, FREENECT_DEPTH_11BIT_SIZE);
617-
dev->depth.pkts_per_frame = DEPTH_PKTS_11_BIT_PER_FRAME;
660+
stream_init(ctx, &dev->depth, FREENECT_DEPTH_11BIT_PACKED_SIZE, FREENECT_DEPTH_11BIT_SIZE);
618661
break;
619662
case FREENECT_DEPTH_10BIT:
620-
stream_initbufs(ctx, &dev->depth, FREENECT_DEPTH_10BIT_PACKED_SIZE, FREENECT_DEPTH_10BIT_SIZE);
621-
dev->depth.pkts_per_frame = DEPTH_PKTS_10_BIT_PER_FRAME;
663+
stream_init(ctx, &dev->depth, FREENECT_DEPTH_10BIT_PACKED_SIZE, FREENECT_DEPTH_10BIT_SIZE);
622664
break;
623665
case FREENECT_DEPTH_11BIT_PACKED:
624-
stream_initbufs(ctx, &dev->depth, 0, FREENECT_DEPTH_11BIT_PACKED_SIZE);
625-
dev->depth.pkts_per_frame = DEPTH_PKTS_11_BIT_PER_FRAME;
666+
stream_init(ctx, &dev->depth, 0, FREENECT_DEPTH_11BIT_PACKED_SIZE);
626667
break;
627668
case FREENECT_DEPTH_10BIT_PACKED:
628-
stream_initbufs(ctx, &dev->depth, 0, FREENECT_DEPTH_11BIT_PACKED_SIZE);
629-
dev->depth.pkts_per_frame = DEPTH_PKTS_10_BIT_PER_FRAME;
669+
stream_init(ctx, &dev->depth, 0, FREENECT_DEPTH_11BIT_PACKED_SIZE);
630670
break;
631671
}
632672

633-
dev->depth.pkt_size = DEPTH_PKTDSIZE;
634-
dev->depth.synced = 0;
635-
dev->depth.flag = 0x70;
636-
dev->depth.valid_frames = 0;
637-
638673
res = fnusb_start_iso(&dev->usb_cam, &dev->depth_isoc, depth_process, 0x82, NUM_XFERS, PKTS_PER_XFER, DEPTH_PKTBUF);
639674
if (res < 0)
640675
return res;
@@ -666,42 +701,34 @@ int freenect_start_video(freenect_device *dev)
666701
if (dev->video.running)
667702
return -1;
668703

704+
dev->video.pkt_size = VIDEO_PKTDSIZE;
705+
dev->video.flag = 0x80;
706+
dev->video.variable_length = 0;
707+
669708
switch (dev->video_format) {
670709
case FREENECT_VIDEO_RGB:
671-
stream_initbufs(ctx, &dev->video, FREENECT_VIDEO_BAYER_SIZE, FREENECT_VIDEO_RGB_SIZE);
672-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME;
710+
stream_init(ctx, &dev->video, FREENECT_VIDEO_BAYER_SIZE, FREENECT_VIDEO_RGB_SIZE);
673711
break;
674712
case FREENECT_VIDEO_BAYER:
675-
stream_initbufs(ctx, &dev->video, 0, FREENECT_VIDEO_BAYER_SIZE);
676-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME;
713+
stream_init(ctx, &dev->video, 0, FREENECT_VIDEO_BAYER_SIZE);
677714
break;
678715
case FREENECT_VIDEO_IR_8BIT:
679-
stream_initbufs(ctx, &dev->video, FREENECT_VIDEO_IR_10BIT_PACKED_SIZE, FREENECT_VIDEO_IR_8BIT_SIZE);
680-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME_IR;
716+
stream_init(ctx, &dev->video, FREENECT_VIDEO_IR_10BIT_PACKED_SIZE, FREENECT_VIDEO_IR_8BIT_SIZE);
681717
break;
682718
case FREENECT_VIDEO_IR_10BIT:
683-
stream_initbufs(ctx, &dev->video, FREENECT_VIDEO_IR_10BIT_PACKED_SIZE, FREENECT_VIDEO_BAYER_SIZE);
684-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME_IR;
719+
stream_init(ctx, &dev->video, FREENECT_VIDEO_IR_10BIT_PACKED_SIZE, FREENECT_VIDEO_BAYER_SIZE);
685720
break;
686721
case FREENECT_VIDEO_IR_10BIT_PACKED:
687-
stream_initbufs(ctx, &dev->video, 0, FREENECT_VIDEO_IR_10BIT_PACKED_SIZE);
688-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME_IR;
722+
stream_init(ctx, &dev->video, 0, FREENECT_VIDEO_IR_10BIT_PACKED_SIZE);
689723
break;
690724
case FREENECT_VIDEO_YUV_RGB:
691-
stream_initbufs(ctx, &dev->video, FREENECT_VIDEO_YUV_RAW_SIZE, FREENECT_VIDEO_RGB_SIZE);
692-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME_YUV;
725+
stream_init(ctx, &dev->video, FREENECT_VIDEO_YUV_RAW_SIZE, FREENECT_VIDEO_RGB_SIZE);
693726
break;
694727
case FREENECT_VIDEO_YUV_RAW:
695-
stream_initbufs(ctx, &dev->video, 0, FREENECT_VIDEO_YUV_RAW_SIZE);
696-
dev->video.pkts_per_frame = VIDEO_PKTS_PER_FRAME_YUV;
728+
stream_init(ctx, &dev->video, 0, FREENECT_VIDEO_YUV_RAW_SIZE);
697729
break;
698730
}
699731

700-
dev->video.pkt_size = VIDEO_PKTDSIZE;
701-
dev->video.synced = 0;
702-
dev->video.flag = 0x80;
703-
dev->video.valid_frames = 0;
704-
705732
res = fnusb_start_iso(&dev->usb_cam, &dev->video_isoc, video_process, 0x81, NUM_XFERS, PKTS_PER_XFER, VIDEO_PKTBUF);
706733
if (res < 0)
707734
return res;

src/freenect_internal.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,6 @@ static inline uint32_t fn_le32(uint32_t d)
8888
#define DEPTH_PKTDSIZE (DEPTH_PKTSIZE-12)
8989
#define VIDEO_PKTDSIZE (VIDEO_PKTSIZE-12)
9090

91-
#define DEPTH_PKTS_10_BIT_PER_FRAME ((FREENECT_DEPTH_10BIT_PACKED_SIZE+DEPTH_PKTDSIZE-1)/DEPTH_PKTDSIZE)
92-
#define DEPTH_PKTS_11_BIT_PER_FRAME ((FREENECT_DEPTH_11BIT_PACKED_SIZE+DEPTH_PKTDSIZE-1)/DEPTH_PKTDSIZE)
93-
#define VIDEO_PKTS_PER_FRAME ((FRAME_PIX+VIDEO_PKTDSIZE-1)/VIDEO_PKTDSIZE)
94-
#define VIDEO_PKTS_PER_FRAME_IR ((FREENECT_VIDEO_IR_10BIT_PACKED_SIZE+VIDEO_PKTDSIZE-1)/VIDEO_PKTDSIZE)
95-
#define VIDEO_PKTS_PER_FRAME_YUV ((FREENECT_VIDEO_YUV_RAW_SIZE+VIDEO_PKTDSIZE-1)/VIDEO_PKTDSIZE)
96-
9791
#define VID_MICROSOFT 0x45e
9892
#define PID_NUI_CAMERA 0x02ae
9993
#define PID_NUI_MOTOR 0x02b0
@@ -107,8 +101,11 @@ typedef struct {
107101
int pkt_num;
108102
int pkts_per_frame;
109103
int pkt_size;
104+
int frame_size;
105+
int last_pkt_size;
110106
int valid_pkts;
111107
int valid_frames;
108+
int variable_length;
112109
uint32_t last_timestamp;
113110
uint32_t timestamp;
114111
int split_bufs;

0 commit comments

Comments
 (0)