Skip to content

Commit e77407c

Browse files
committed
cameras.c: optimized function to unpack 11-bit pixel data into 16-bit buffers.
Loop-unrolling the unpacking routine makes the bit-shifting code much faster. Originally authored by Alex Kushleyev <[email protected]> Signed-off-by: Kyle Machulis <[email protected]> Signed-off-by: Drew Fisher <[email protected]>
1 parent e715186 commit e77407c

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/cameras.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,39 @@ static inline void convert_packed_to_8bit(uint8_t *raw, uint8_t *frame, int vw,
308308
}
309309
}
310310

311+
// Loop-unrolled version of the 11-to-16 bit unpacker. n must be a multiple of 8.
312+
static void convert_packed11_to_16bit(uint8_t *raw, uint16_t *frame, int n)
313+
{
314+
uint16_t baseMask = (1 << 11) - 1;
315+
while(n >= 8)
316+
{
317+
uint8_t r0 = *(raw+0);
318+
uint8_t r1 = *(raw+1);
319+
uint8_t r2 = *(raw+2);
320+
uint8_t r3 = *(raw+3);
321+
uint8_t r4 = *(raw+4);
322+
uint8_t r5 = *(raw+5);
323+
uint8_t r6 = *(raw+6);
324+
uint8_t r7 = *(raw+7);
325+
uint8_t r8 = *(raw+8);
326+
uint8_t r9 = *(raw+9);
327+
uint8_t r10 = *(raw+10);
328+
329+
frame[0] = (r0<<3) | (r1>>5);
330+
frame[1] = ((r1<<6) | (r2>>2) ) & baseMask;
331+
frame[2] = ((r2<<9) | (r3<<1) | (r4>>7) ) & baseMask;
332+
frame[3] = ((r4<<4) | (r5>>4) ) & baseMask;
333+
frame[4] = ((r5<<7) | (r6>>1) ) & baseMask;
334+
frame[5] = ((r6<<10) | (r7<<2) | (r8>>6) ) & baseMask;
335+
frame[6] = ((r8<<5) | (r9>>3) ) & baseMask;
336+
frame[7] = ((r9<<8) | (r10) ) & baseMask;
337+
338+
n -= 8;
339+
raw += 11;
340+
frame += 8;
341+
}
342+
}
343+
311344
static void depth_process(freenect_device *dev, uint8_t *pkt, int len)
312345
{
313346
freenect_context *ctx = dev->parent;
@@ -328,7 +361,7 @@ static void depth_process(freenect_device *dev, uint8_t *pkt, int len)
328361

329362
switch (dev->depth_format) {
330363
case FREENECT_DEPTH_11BIT:
331-
convert_packed_to_16bit(dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf, 11, 640*480);
364+
convert_packed11_to_16bit(dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf, 640*480);
332365
break;
333366
case FREENECT_DEPTH_10BIT:
334367
convert_packed_to_16bit(dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf, 10, 640*480);

0 commit comments

Comments
 (0)