change bitstream load function to return stateless MTU sized packets

This commit is contained in:
Stephen Birarda 2013-03-18 13:16:14 -07:00
parent ec5e4095c9
commit 807377ef97
3 changed files with 129 additions and 129 deletions

View file

@ -13,91 +13,99 @@ const int MAX_TREE_SLICE_BYTES = 26;
VoxelTree::VoxelTree() {
rootNode = new VoxelNode();
rootNode->octalCode = new unsigned char[1];
*rootNode->octalCode = (char)0;
}
char * VoxelTree::loadBitstream(char * bitstreamBuffer,
VoxelNode *bitstreamRootNode,
char ** startSplitPtr) {
static char **packetSplitPtr = startSplitPtr;
unsigned char * VoxelTree::loadBitstreamBuffer(char *& bitstreamBuffer,
unsigned char * stopOctalCode,
VoxelNode *currentVoxelNode)
{
static char *initialBitstreamPos = bitstreamBuffer;
if (bitstreamRootNode->childMask != 0) {
if (bitstreamRootNode == rootNode || (bitstreamBuffer + MAX_TREE_SLICE_BYTES - *packetSplitPtr) > MAX_VOXEL_PACKET_SIZE) {
// we need to add a packet split here
char firstIndexToCheck = 0;
// we'll only be writing data if we're lower than
// or at the same level as the stopOctalCode
if (*currentVoxelNode->octalCode >= *stopOctalCode) {
if (currentVoxelNode->childMask != 0) {
if ((bitstreamBuffer - initialBitstreamPos) + MAX_TREE_SLICE_BYTES > MAX_VOXEL_PACKET_SIZE) {
// we can't send this packet, not enough room
// return our octal code as the stop
return currentVoxelNode->octalCode;
}
if (bitstreamRootNode == rootNode) {
// set the packetSplitPtr and increment bitstream buffer by 1 for leading V
*packetSplitPtr = bitstreamBuffer;
// lead packet with a V
if (strcmp((char *)stopOctalCode, (char *)currentVoxelNode->octalCode) == 0) {
// this is is the root node for this packet
// add the leading V
*(bitstreamBuffer++) = 'V';
// root node octal code length byte is 0
*(bitstreamBuffer++) = 0;
// add its octal code to the packet
int octalCodeBytes = bytesRequiredForCodeLength(*currentVoxelNode->octalCode);
memcpy(bitstreamBuffer, currentVoxelNode->octalCode, octalCodeBytes);
bitstreamBuffer += octalCodeBytes;
}
// default color mask is 0, increment pointer for colors
*bitstreamBuffer = 0;
// keep a colorPointer so we can check how many colors were added
char *colorPointer = bitstreamBuffer + 1;
for (int i = 0; i < 8; i++) {
// check if the child exists and is not transparent
if (currentVoxelNode->children[i] != NULL
&& currentVoxelNode->children[i]->color[3] != 0) {
// copy in the childs color to bitstreamBuffer
memcpy(colorPointer, currentVoxelNode->children[i]->color, 3);
colorPointer += 3;
// set the colorMask by bitshifting the value of childExists
*bitstreamBuffer += (1 << (7 - i));
}
}
// push the bitstreamBuffer forwards for the number of added colors
bitstreamBuffer += (colorPointer - bitstreamBuffer);
// copy the childMask to the current position of the bitstreamBuffer
// and push the buffer pointer forwards
*(bitstreamBuffer++) = currentVoxelNode->childMask;
} else {
// if this node is a leaf, return a NULL stop code
// it has been visited
return NULL;
}
} else {
firstIndexToCheck = *stopOctalCode > 0
? branchIndexWithDescendant(currentVoxelNode->octalCode, stopOctalCode)
: 0;
}
unsigned char * childStopOctalCode = NULL;
for (int i = firstIndexToCheck; i < 8; i ++) {
// ask the child to load this bitstream buffer
// if they or their descendants fill the MTU we will receive the childStopOctalCode back
if (currentVoxelNode->children[i] != NULL) {
if (*currentVoxelNode->octalCode < *stopOctalCode
&& i > firstIndexToCheck
&& childStopOctalCode == NULL) {
return currentVoxelNode->children[i]->octalCode;
} else {
// increment packetSplitPtr and set the pointer it points to
// to the beginning of this tree section
// bistreamBuffer is incremented for leading V
*(++packetSplitPtr) = bitstreamBuffer;
// lead packet with a V
*(bitstreamBuffer++) = 'V';
// add the octal code for the current root
int bytesForOctalCode = bytesRequiredForCodeLength(*bitstreamRootNode->octalCode);
memcpy(bitstreamBuffer, bitstreamRootNode->octalCode, bytesForOctalCode);
// push the bitstreamBuffer forwards by the number of bytes used for the octal code
bitstreamBuffer += bytesForOctalCode;
}
// set the color bit for this node
*(bitstreamBuffer++) = (int)(bitstreamRootNode->color[3] != 0);
// copy this node's color into the bitstreamBuffer, if required
if (bitstreamRootNode->color[3] != 0) {
memcpy(bitstreamBuffer, bitstreamRootNode->color, 3);
bitstreamBuffer += 3;
childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer, stopOctalCode, currentVoxelNode->children[i]);
}
}
// default color mask is 0, increment pointer for colors
*(bitstreamBuffer++) = 0;
// keep a colorPointer so we can check how many colors were added
char *colorPointer = bitstreamBuffer;
for (int i = 0; i < 8; i++) {
// grab this child
VoxelNode *child = bitstreamRootNode->children[i];
// check if the child exists and is not transparent
if (child != NULL && child->color[3] != 0) {
// copy in the childs color to bitstreamBuffer
memcpy(colorPointer, child->color, 3);
colorPointer += 3;
// set the colorMask by bitshifting the value of childExists
*(bitstreamBuffer - 1) += (1 << (7 - i));
}
}
// push the bitstreamBuffer forwards for the number of added colors
bitstreamBuffer += (colorPointer - bitstreamBuffer);
// copy the childMask to the current position of the bitstreamBuffer
// and push the buffer pointer forwards
*(bitstreamBuffer++) = bitstreamRootNode->childMask;
for (int j = 0; j < 8; j++) {
// make sure we have a child to visit
if (bitstreamRootNode->children[j] != NULL) {
bitstreamBuffer = loadBitstream(bitstreamBuffer,
bitstreamRootNode->children[j]);
}
if (childStopOctalCode != NULL) {
break;
}
}
return bitstreamBuffer;
return childStopOctalCode;
}

View file

@ -20,12 +20,10 @@ public:
VoxelNode *rootNode;
void addBitstreamPacketMarker();
unsigned char * loadBitstreamBuffer(char *& bitstreamBuffer,
unsigned char * octalCode,
VoxelNode *currentVoxelNode);
void outputDebugInformation(VoxelNode *currentRootNode = NULL);
char * loadBitstream(char * bitstreamBuffer,
VoxelNode *bitstreamRootNode,
char ** curPacketSplitPtr = NULL);
};
#endif /* defined(__hifi__VoxelTree__) */

View file

@ -39,12 +39,10 @@ char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup
const int DOMAINSERVER_PORT = 40102;
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 1;
const int MAX_VOXEL_BITSTREAM_BYTES = 100000;
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 5;
AgentList agentList(VOXEL_LISTEN_PORT);
in_addr_t localAddress;
char voxelBitStream[MAX_VOXEL_BITSTREAM_BYTES];
unsigned char randomColorValue() {
return MIN_BRIGHTNESS + (rand() % (255 - MIN_BRIGHTNESS));
@ -96,8 +94,6 @@ void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
// give this child it's octal code
currentRootNode->children[i]->octalCode = childOctalCode(currentRootNode->octalCode, i);
printf("Child node in position %d at level %d\n", i, MAX_VOXEL_TREE_DEPTH_LEVELS - levelsToGo);
// fill out the lower levels of the tree using that node as the root node
randomlyFillVoxelTree(levelsToGo - 1, currentRootNode->children[i]);
@ -192,24 +188,22 @@ int main(int argc, const char * argv[])
// create an octal code buffer and load it with 0 so that the recursive tree fill can give
// octal codes to the tree nodes that it is creating
randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode);
char *packetSplitsPtrs[MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE] = {};
char *voxelPacket = new char[MAX_VOXEL_PACKET_SIZE];
char *voxelPacketEnd;
// returned unsigned char * is end of last write to bitstream
char *lastPacketSplit = randomTree.loadBitstream(voxelBitStream, randomTree.rootNode, packetSplitsPtrs);
int packetCount = 0;
// set the last packet split pointer to lastPacketSplit
for (int i = 1; i < MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE; i++) {
if (packetSplitsPtrs[i] == NULL) {
if (lastPacketSplit != NULL) {
// lastPacketSplit has not been read yet
// set this packetSplitPtr to that and set it NULL so we know it's been read
packetSplitsPtrs[i] = lastPacketSplit;
lastPacketSplit = NULL;
} else {
// no more split pointers to read, break out
break;
}
unsigned char *stopOctal = randomTree.rootNode->octalCode;
while (true) {
voxelPacketEnd = voxelPacket;
stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd, stopOctal, randomTree.rootNode);
printf("Packet %d is %ld bytes\n", ++packetCount, voxelPacketEnd - voxelPacket);
if (stopOctal == NULL) {
break;
}
}
@ -221,34 +215,34 @@ int main(int argc, const char * argv[])
int sentVoxels = 0;
// loop to send to agents requesting data
while (true) {
if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
if (packetData[0] == 'I') {
printf("Sending voxels to agent at address %s\n", inet_ntoa(agentPublicAddress.sin_addr));
// send the bitstream to the client
for (int i = 1; i < MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE; i++) {
if (packetSplitsPtrs[i] == NULL) {
// no more split pointers to read, break out
break;
}
// figure out the number of bytes in this packet
int thisPacketBytes = packetSplitsPtrs[i] - packetSplitsPtrs[i - 1];
agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress,
packetSplitsPtrs[i - 1],
thisPacketBytes);
// output the bits in each byte of this packet
for (int j = 0; j < thisPacketBytes; j++) {
outputBits(*(packetSplitsPtrs[i - 1] + j));
}
}
}
}
}
// while (true) {
// if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
// if (packetData[0] == 'I') {
// printf("Sending voxels to agent at address %s\n", inet_ntoa(agentPublicAddress.sin_addr));
//
// // send the bitstream to the client
// for (int i = 1; i < MAX_VOXEL_BITSTREAM_BYTES / MAX_PACKET_SIZE; i++) {
// if (packetSplitsPtrs[i] == NULL) {
// // no more split pointers to read, break out
// break;
// }
//
// // figure out the number of bytes in this packet
// int thisPacketBytes = packetSplitsPtrs[i] - packetSplitsPtrs[i - 1];
//
// agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress,
// packetSplitsPtrs[i - 1],
// thisPacketBytes);
//
//
// // output the bits in each byte of this packet
// for (int j = 0; j < thisPacketBytes; j++) {
// outputBits(*(packetSplitsPtrs[i - 1] + j));
// }
// }
// }
// }
// }
pthread_join(reportAliveThread, NULL);