///////////////////////////////////////////////////////
// Set up the vImage buffer for the destination
///////////////////////////////////////////////////////
int aRowLength = self.inputWidthLEDWall * 4;
vDestBuffer.data = malloc(self.inputHeightLEDWall * aRowLength);
YIKES!
I was leaking a whole image buffer on every frame, no wonder my patch
slowed down to a crawl.
Corrected version below.
- (BOOL)execute:(id <QCPlugInContext>)context
atTime:(NSTimeInterval)time withArguments:(NSDictionary *)arguments
{
if([connectSocket isDisconnected] || [self
didValueForInputKeyChange:@"inputPort"] || [self
didValueForInputKeyChange:@"inputHost"])
{
// stop listening for incomming connections
[connectSocket disconnect];
if(![connectSocket connectToHost:self.inputIpAddressPixelmaster
onPort:self.inputPort error:nil])
{
NSLog(@"could not connect to host, port");
return NO;
}
}
if([connectSocket isDisconnected])
{
NSLog(@"Not connected!");
return NO;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Protocol setup from hereon in order to send data
// for that to happen, we need to build the protocol
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NSUInteger lengthInBytes = self.inputWidthLEDWall *
self.inputHeightLEDWall * 3 + 35;
// setting up the send buffer
char* sendBuffer = malloc(lengthInBytes);
// build the header (magic bytes)
memcpy(sendBuffer, [self.inputProtMagic UTF8String],
self.inputProtMagic.length);
//databytes per protocol
sendBuffer[20] = lengthInBytes / 256; // HI-Byte
sendBuffer[21] = lengthInBytes % 256; // LO-Byte
// typeByte
sendBuffer[22] = self.inputProtTypeByte;
// message ID
counter = self.inputProtMessageID;
sendBuffer[23] = counter / 256; // HI-Byte
sendBuffer[24] = counter % 256; // LO-Byte
// type byte
sendBuffer[25] = self.inputProtTypeByte;
// fixImage
sendBuffer[26] = self.inputProtFixImagesEnable;
// Byte 27 = 50 in the recorded stream, is this the fps in Hz?
// byte 28-31 = reserved
sendBuffer[27] = self.inputProtReserved27Byte;
sendBuffer[28] = self.inputProtReserved28Byte;
sendBuffer[29] = self.inputProtReserved29Byte;
sendBuffer[30] = self.inputProtReserved30Byte;
sendBuffer[31] = self.inputProtReserved31Byte;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// -- image data procession from hereon /////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// get the image to use
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
id<QCPlugInInputImageSource> imageToUse = self.inputImage;
CGColorSpaceRef colorSpace = (CGColorSpaceGetModel([imageToUse
imageColorSpace]) == kCGColorSpaceModelRGB ? [imageToUse
imageColorSpace] : [context colorSpace]);
if (![imageToUse
lockBufferRepresentationWithPixelFormat:QCPlugInPixelFormatARGB8
colorSpace:colorSpace
forBounds:[imageToUse imageBounds]])
{
NSLog(@"Locking of image failed.");
return NO;
}
///////////////////////////////////////////////////////
// we got the image locked now, read out pixel data ...
///////////////////////////////////////////////////////
vImage_Buffer buffer;
vImage_Buffer vDestBuffer;
///////////////////////////////////////////////////////
// Set up the vImage buffer for the source image
///////////////////////////////////////////////////////
buffer.data = (void*)[imageToUse bufferBaseAddress];
buffer.rowBytes = [imageToUse bufferBytesPerRow];
buffer.width = [imageToUse bufferPixelsWide];
buffer.height = [imageToUse bufferPixelsHigh];
///////////////////////////////////////////////////////
// Set up the vImage buffer for the destination
///////////////////////////////////////////////////////
int aRowLength = self.inputWidthLEDWall * 4;
void* pixelBuffer = malloc(self.inputHeightLEDWall * aRowLength);
vDestBuffer.data = pixelBuffer;
vDestBuffer.height = self.inputHeightLEDWall;
vDestBuffer.width = self.inputWidthLEDWall;
vDestBuffer.rowBytes = aRowLength;
///////////////////////////////////////////////////////
// do the scale
///////////////////////////////////////////////////////
Boolean notOk = vImageScale_ARGB8888(&buffer, &vDestBuffer, NULL, 0);
// we must unlock the image in any case
[imageToUse unlockBufferRepresentation];
if (notOk)
{
return NO;
}
///////////////////////////////////////////////////////
// read out pixeldata from the scaled down image
///////////////////////////////////////////////////////
for(int y=0;y<vDestBuffer.height;y++)
{
for(int x=0;x<vDestBuffer.width;x++)
{
long offset_sendBuffer = 32+ vDestBuffer.width * y * 3 + x * 3;
long offset_pixelBuffer = y * vDestBuffer.rowBytes + x * 4;
sendBuffer[offset_sendBuffer] =
((char*)vDestBuffer.data)[offset_pixelBuffer + 1 ];
sendBuffer[offset_sendBuffer + 1] =
((char*)vDestBuffer.data)[offset_pixelBuffer + 2 ];
sendBuffer[offset_sendBuffer + 2] =
((char*)vDestBuffer.data)[offset_pixelBuffer + 3 ];
}
}
free(pixelBuffer);
// end protocolframe
sendBuffer[lengthInBytes-3] = 'e';
sendBuffer[lengthInBytes-2] = 'n';
sendBuffer[lengthInBytes-1] = 'd';
///////////////////////////////////////////////////////////////////////////////////////
// send it out!
///////////////////////////////////////////////////////////////////////////////////////
[connectSocket writeData:[NSData dataWithBytesNoCopy:sendBuffer
length:lengthInBytes freeWhenDone:YES] withTimeout:-1 tag:0];
NSLog(@"%d bytes written with message id %d", lengthInBytes, counter);
return YES;
}
--
Christophe Leske
multimedial.de
----------------------------------------
www.multimedial.de - i...@multimedial.de
Hohler Strasse 17 - 51645 Gummersbach
+49(0)2261-99824540 // +49(0)177-2497031
----------------------------------------
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list (Quartzcomposer-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com
This email sent to arch...@mail-archive.com