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() { VoxelTree::VoxelTree() {
rootNode = new VoxelNode(); rootNode = new VoxelNode();
rootNode->octalCode = new unsigned char[1];
*rootNode->octalCode = (char)0;
} }
char * VoxelTree::loadBitstream(char * bitstreamBuffer, unsigned char * VoxelTree::loadBitstreamBuffer(char *& bitstreamBuffer,
VoxelNode *bitstreamRootNode, unsigned char * stopOctalCode,
char ** startSplitPtr) { VoxelNode *currentVoxelNode)
static char **packetSplitPtr = startSplitPtr; {
static char *initialBitstreamPos = bitstreamBuffer;
if (bitstreamRootNode->childMask != 0) { char firstIndexToCheck = 0;
if (bitstreamRootNode == rootNode || (bitstreamBuffer + MAX_TREE_SLICE_BYTES - *packetSplitPtr) > MAX_VOXEL_PACKET_SIZE) { // we'll only be writing data if we're lower than
// we need to add a packet split here // 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 (strcmp((char *)stopOctalCode, (char *)currentVoxelNode->octalCode) == 0) {
if (bitstreamRootNode == rootNode) { // this is is the root node for this packet
// set the packetSplitPtr and increment bitstream buffer by 1 for leading V // add the leading V
*packetSplitPtr = bitstreamBuffer;
// lead packet with a V
*(bitstreamBuffer++) = '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 { } else {
// increment packetSplitPtr and set the pointer it points to childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer, stopOctalCode, currentVoxelNode->children[i]);
// 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;
} }
} }
// default color mask is 0, increment pointer for colors if (childStopOctalCode != NULL) {
*(bitstreamBuffer++) = 0; break;
// 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]);
}
} }
} }
return bitstreamBuffer; return childStopOctalCode;
} }

View file

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