Xamarin.ios: переход с Objective-C на C#

Я переношу приложение из iOS в проект Xamarin. Класс Objective-C работает, но я действительно не знаю, как написать его версию на С#. Если кто-то увидит что-то не так, буду признателен.

- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection
{

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

    CVPixelBufferLockBaseAddress(imageBuffer,0);

    baseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer,0);

    int pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer);

    switch (pixelFormat)
     {
        case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:

            bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,0);
            width = bytesPerRow;
            height = CVPixelBufferGetHeightOfPlane(imageBuffer,0);
            break;

        case kCVPixelFormatType_422YpCbCr8:

            bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,0);
            width = CVPixelBufferGetWidth(imageBuffer);
            height = CVPixelBufferGetHeight(imageBuffer);
            int len = width*height;
            int dstpos=1;
            for (int i=0;i<len;i++)
            {
                baseAddress[i]=baseAddress[dstpos];
                dstpos+=2;
            }

            break;
        default:

            break;
    }

    unsigned char *pResult=NULL;

    int resLength = MWB_scanGrayscaleImage(baseAddress,width,height, &pResult);

.................
}

Это часть моего кода, где я пытаюсь портировать его для платформы Xamarin:

public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
{
   using (var pixelBuffer = sampleBuffer.GetImageBuffer () as CVPixelBuffer)
   {
       pixelBuffer.Lock (0);

       var baseAddress = pixelBuffer.BaseAddress;
       int bytesPerRow = pixelBuffer.BytesPerRow;
       int width = pixelBuffer.Width;
       int height = pixelBuffer.Height;

    //this is where i have to make a conversion because i need a byte[] from baseAddress
       byte [] managedArray = new byte[width*height];
       Marshal.Copy(baseAddress, managedArray, 0, width*height);

       byte [] rawResult = new byte[3000];

    // When it hits this line the app comes to a stop without any error message
    // Declaration: public static extern int MWB_scanGrayscaleImage (byte[] gray, int width, int height, out byte[] result);
       int resLength = BarcodeScannerClass.MWB_scanGrayscaleImage(managedArray,width,height,out rawResult);

..............
}

person Macaret    schedule 20.11.2013    source источник


Ответы (1)


Возник ряд проблем с преобразованием этого класса в c#. Одна вещь, которую я делал, это устанавливал неправильный PixelFormatType в AVCaptureVideoDataOutput, поэтому pixelBuffer был неправильным. И сразу после получения resLength необходимо разблокировать pixelBuffer. Рабочий класс это:

public class OutputRecorder : AVCaptureVideoDataOutputSampleBufferDelegate 
{   
    public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
    {
        try 
        {
            using (var pixelBuffer = sampleBuffer.GetImageBuffer () as CVPixelBuffer)
            {
                pixelBuffer.Lock (0);

                CVPixelFormatType ft = pixelBuffer.PixelFormatType;

                var baseAddress = pixelBuffer.BaseAddress;
                int bytesPerRow = pixelBuffer.BytesPerRow;
                int width = pixelBuffer.Width;
                int height = pixelBuffer.Height;

                byte [] managedArray = new byte[width * height];
                Marshal.Copy(baseAddress, managedArray, 0, width * height);

                byte [] rawResult = new byte[3000];

                int resLength = BarcodeScannerClass.MWB_scanGrayscaleImage(managedArray,width,height,out rawResult);

                pixelBuffer.Unlock (0);
person Macaret    schedule 22.11.2013