Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Using custom dll in C# program

yanqin
Beginner
511 Views
I'm doing a custom dll so that I can use it in C# by using PInvoke. One of the function i need to include in my custom dll is ippiRGBToYUV420_8u_C3P3. I'm not sure how should Icode it as there's a pointer array andI'm not surehowto call it in C# using intptr pointer.

The code i wrote is as follow:

/*_________in my custom dll_____________*/

int CIppEncoder::RGBtoYUV(BYTE* pSrc, BYTE ** pDst, int width, int height){
IppiSize imgSize;
imgSize.height = height;
imgSize.width = width;
IppStatus check;
check = ippiRGBToYUV420_8u_C3P3((Ipp8u*) pSrc, (Ipp8u**) pDst, (IppiSize) imgSize);

if (check == ippStsNullPtrErr) { return -1;}
if (check == ippStsSizeErr ) {return -2;}
if (check == ippStsDoubleSize) {return -3;}

return 1;
}

//function to export

IPPENCODER_API int BGRtoYUV(void* objPtr, BYTE* pSrc, BYTE ** pDst, int width, int height){
CIppEncoder* encodeSample = (CIppEncoder*) objPtr;
if (encodeSample)
return encodeSample->RGBtoYUV(pSrc, pDst, width, height);
else
return -5;
}


/*________in my C# code_____________*/

//under class SampleDllLib

[DllImport("IppEncoder.dll")]
internal static extern int BGRtoYUV(IntPtr objPtr, IntPtr pSrc, IntPtr pDst, int width, int height);

//under my calling program
IntPtr dstImg = Marshal.AllocCoTaskMem(m_videoHeight * m_videoWidth * 2 * 3);

if (m_SampleEncoder == IntPtr.Zero)
MessageBox.Show("Can't open IppEncoder.DLL!");
else
{
int result = SampleDllLib.BGRtoYUV(m_SampleEncoder, pRGB2, dstImg, TARGET_IMAGE_WIDTH, TARGET_IMAGE_HEIGHT);
}


My codewill always return me a -1. May i know which part of the code is wrong? Is it with the dstImg?

Thanks in advance.
0 Kudos
6 Replies
Ying_H_Intel
Employee
511 Views
Quoting - yanqin
I'm doing a custom dll so that I can use it in C# by using PInvoke. One of the function i need to include in my custom dll is ippiRGBToYUV420_8u_C3P3. I'm not sure how should Icode it as there's a pointer array andI'm not surehowto call it in C# using intptr pointer.

The code i wrote is as follow:

/*_________in my custom dll_____________*/

int CIppEncoder::RGBtoYUV(BYTE* pSrc, BYTE ** pDst, int width, int height){
IppiSize imgSize;
imgSize.height = height;
imgSize.width = width;
IppStatus check;
check = ippiRGBToYUV420_8u_C3P3((Ipp8u*) pSrc, (Ipp8u**) pDst, (IppiSize) imgSize);

if (check == ippStsNullPtrErr) { return -1;}
if (check == ippStsSizeErr ) {return -2;}
if (check == ippStsDoubleSize) {return -3;}

return 1;
}

//function to export

IPPENCODER_API int BGRtoYUV(void* objPtr, BYTE* pSrc, BYTE ** pDst, int width, int height){
CIppEncoder* encodeSample = (CIppEncoder*) objPtr;
if (encodeSample)
return encodeSample->RGBtoYUV(pSrc, pDst, width, height);
else
return -5;
}


/*________in my C# code_____________*/

//under class SampleDllLib

[DllImport("IppEncoder.dll")]
internal static extern int BGRtoYUV(IntPtr objPtr, IntPtr pSrc, IntPtr pDst, int width, int height);

//under my calling program
IntPtr dstImg = Marshal.AllocCoTaskMem(m_videoHeight * m_videoWidth * 2 * 3);

if (m_SampleEncoder == IntPtr.Zero)
MessageBox.Show("Can't open IppEncoder.DLL!");
else
{
int result = SampleDllLib.BGRtoYUV(m_SampleEncoder, pRGB2, dstImg, TARGET_IMAGE_WIDTH, TARGET_IMAGE_HEIGHT);
}


My codewill always return me a -1. May i know which part of the code is wrong? Is it with the dstImg?

Thanks in advance.

Hello,

IPP provide some C# sample, like image processing, string processingand provide docomention how to do these.would you like try them at<<http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-code-samples/>>?

Regards,
Ying
0 Kudos
yanqin
Beginner
511 Views

Hi,

Thanks for your help. I overlook that example. I'm able to use the function now. May i ask how could i get just a single pointer to point to the converted YUV data instead of an array of pointers to each color plane?

IppStatus ippiRGBToYUV420_8u_C3P3(const Ipp8u* pSrc, Ipp8u* pDst[3], IppiSize imgSize) return me an array pointer.

I use to try compose everything to one pointer with the below function but I get a totally green image as output

IppStatus ippiCopy_8u_P3C3R( const Ipp* const pSrc[3], int srcStep, Ipp* pDst, int dstStep, IppiSize roiSize);

I'm my roiSize is my whole image and my srcStep and dstStep is 0 for the function i use. Please help and thanks.

YanQin


0 Kudos
Ying_H_Intel
Employee
511 Views

Hi YanQin,

Seem a little hardif use ippiCopy_8u_P3C3R as the 3 seperateYUV planehave diferent stepByte,your pDst dstStep can be neither 0, nor Width of Y,U,V.

As I understand, you hope to store YUV420 3 plane in one consecutive Array, right? For example,theRGB image is 320x240.
Then your first part of connect_YUV array is Y(320x240), then U (160x120), then V (160x120).

is there any reason for you to use such kind of array? mayyour follow operationuse the YUV 420 in one array?
If you have toconnectthe3 seperate arraystogether, you may copy them one by one.
ippiCopy_8u_C1R(Yplane, Ystep, pDst, Ystep, roiSize)
ippiCopy_8u_C1R(Uplane, Ustep, pDst+Ystep*height, roisize/2);
ippiCopy_8u_C1R(Vplane, Vstep, pDst+5*Ystep*height/4, roisize/2);

Regards,
Ying

0 Kudos
yanqin
Beginner
511 Views

Hi,

Yes. I would like to store the 3 plane in a consecutive array. I wanted to do so because i wanted to pass encode this data to h264 format. As for the code i used for encoding h264, it's the one providedat http://software.intel.com/en-us/articles/getting-started-with-intel-ipp-unified-media-classes-sample/
under EncodeStream, the code required me to pass in a ipp8u* data instead of an array.
Is there any other approach thatcan use? like changing thesomelines in the encoder topass in the array?

Best Regards,
YanQin
0 Kudos
yanqin
Beginner
511 Views
Hi,

Thanks for your help. I've already found a solution to my problems. I amend the simple encoder so that it could read in the 3 plane seperately instead of taking it as a single pointer.

For people who encounter the same problem as me, this is what i reference from:
http://software.intel.com/en-us/forums/showthread.php?t=64882


i change

DataIn.SetBufferPointer((Ipp8u* cYUVData,imgWidth*imgHeight*3/2);

to

DataIn->SetPlanePointer(cYUVData[0], 0); // Y
DataIn->SetPlanePointer(cYUVData[1], 1); // U
DataIn->SetPlanePointer(cYUVData[2], 2); // V

Best regards,
YanQin

0 Kudos
Ying_H_Intel
Employee
511 Views
Quoting - yanqin
Hi,

Thanks for your help. I've already found a solution to my problems. I amend the simple encoder so that it could read in the 3 plane seperately instead of taking it as a single pointer.

For people who encounter the same problem as me, this is what i reference from:
http://software.intel.com/en-us/forums/showthread.php?t=64882


i change

DataIn.SetBufferPointer((Ipp8u* cYUVData,imgWidth*imgHeight*3/2);

to

DataIn->SetPlanePointer(cYUVData[0], 0); // Y
DataIn->SetPlanePointer(cYUVData[1], 1); // U
DataIn->SetPlanePointer(cYUVData[2], 2); // V

Best regards,
YanQin


Hi YanQin,

I see. Thank you a lot for sharing. No wander you ask a single consecutive pointer of YUV data,not 3 seperate pointer, where it is stored in Y, U, V 3 seperate arraynaturally. I add onenotes to the Artilce
http://software.intel.com/en-us/articles/getting-started-with-intel-ipp-unified-media-classes-sample/
to notify more users the problem.

Thanks
Ying
0 Kudos
Reply