2012-03-30

First foray into RLP

Got around to speed testing the RLP code today. The C/C++ code used for testing computes average value for each of the colour channels, then combines them back into a single value.
int AverageColour_c(unsigned char *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
 // total number of pixels pass onto us
 unsigned int arraySize = *(unsigned int*)args[0];

 int i = 0, red = 0, green = 0, blue = 0;
 if( generalArray == 0)
  return -1;
 
 // iterate through colour values
 for(i = 54; i < arraySize;)
 {
  red += generalArray[i++];
  green += generalArray[i++];
  blue += generalArray[i++];
 }

 // extract how many pixels were there in total
 int total = (arraySize - 54) / 3;

 // compute average value for each colour
 red /= total;
 green /= total;
 blue /= total;

 // convert into final Color value
 total = (blue << 16) | (green << 8) | red;

 return total;
}
It assumes that the data passed into it is Gadgeteer.Picture.PictureData byte array. This byte array has colour data starting at the 54th byte location and stores colour data as BGRBGRBGR bytes.

The total running time of the aforementioned RLP call is 214ms. The exact same code, encapsulated in a NETMF function call runs for a total of 16335ms. In other words, approximately 76 times faster. For a very simple piece of code.

The NET side of the code is pretty simple in itself:

RLP.Procedure AverageColour;

// This method is run when the mainboard is powered up or reset.   
void ProgramStarted()
{
    // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
    Debug.Print( "Program Started" );

    InitializeRLP();

    // setup Gadgeteer modules
    button.ButtonReleased += new Button.ButtonEventHandler( button_ButtonReleased );
    camera.PictureCaptured += new Camera.PictureCapturedEventHandler( camera_PictureCaptured );
    camera.DebugPrintEnabled = false;
    camera.CurrentPictureResolution = Camera.PictureResolution.Resolution320x240;
}

void InitializeRLP()
{
    // personal unlock code
    RLP.Unlock( "...", new byte[] { ... } );

    // fetch, load and initialize our RLP
    byte[] elf_file = Resources.GetBytes( Resources.BinaryResources.RLP_test );
    RLP.LoadELF( elf_file );
    RLP.InitializeBSSRegion( elf_file );

    // extract the procedures
    AverageColour = RLP.GetProcedure( elf_file, "AverageColour_c" );

    // dispose of the loaded binary data we no longer need
    elf_file = null;
    Debug.GC( true );
}

void camera_PictureCaptured( Camera sender, GT.Picture picture )
{
    const int pixels = 320 * 240;

    int colour = AverageColour.InvokeEx( picture.PictureData, 54 + pixels * 3 );
    Color average = (Color)colour;
    Debug.Print( "Average colour: Red - " +
                 ColorUtility.GetRValue( average ) +
                 " Green - " +
                 ColorUtility.GetGValue( average ) +
                 " Blue - " +
                 ColorUtility.GetBValue( average ) );
}

void button_ButtonReleased( Button sender, Button.ButtonState state )
{
    camera.TakePicture();
}

No comments:

Post a Comment