Показывать потоковую передачу камеры из кадров с помощью сбоя утечки памяти UIImageView - PullRequest
1 голос
/ 24 февраля 2012

Я использую библиотеку QCAR и получаю кадр камеры из библиотеки в каждом кадре.

Я пытаюсь показать этот кадр, используя setImage на моем UIImageView* mCurFrameView. Сначала это работает, и я вижу, что кадры работают плавно, но через 20 секунд происходит сбой.

Иногда я получаю EXC_BAD_ACCESS на

int retVal = UIApplicationMain(argc, argv, nil, nil); 

Иногда это просто gdb и пауза.

Иногда до его падения я получаю

2012-02-24 15:59:15.726 QRAR_nextGen[226:707] Received memory warning.

Вот мой код:

-(void)SaveCurrentFrame:(UIImage*)image
{

        mCurFrameView.image = image;

}


- (void)renderFrameQCAR
{

   cout<<"I am starting"<<endl;


QCAR::State state = QCAR::Renderer::getInstance().begin();


QCAR::setFrameFormat(QCAR::RGB888, true);

const QCAR::Image *image = state.getFrame().getImage(1);// 0: YUV, 1: Grayscale image

if (image)
{
    const char *data = (const char *)image->getPixels();
    int width = image->getWidth(); int height = image->getHeight();

    colorSpace = CGColorSpaceCreateDeviceRGB();
    bitmapInfo = kCGBitmapByteOrderDefault;
    provider = CGDataProviderCreateWithData(NULL, data, width*height*3, NULL);
    intent = kCGRenderingIntentDefault;
    imageRef = CGImageCreate(width, height, 8, 8*3, width * 3, colorSpace, bitmapInfo,    provider, NULL, NO, intent);

    mCurFrame = [UIImage imageWithCGImage:imageRef];


    cout<<"I am waiting"<<endl;
   [self performSelectorOnMainThread:@selector(SaveCurrentFrame:) withObject:mCurFrame waitUntilDone:YES];

}

Я пробовал несколько вещей: показывать CALayer для показа камеры, отпускать, сохранять, автоматически освобождать, определять и не определять свойства и синтезировать.

Буду очень признателен, если кто-нибудь сможет мне помочь. Я схожу с ума. Большое спасибо.

Ответы [ 3 ]

0 голосов
/ 11 апреля 2013

Может быть, вам не хватает этого:

   QCAR::Renderer::getInstance().end();

Вот фрагмент, работающий на iPhone 4S / 5 iOS 6

- (void)renderFrameIntoImage {
   QCAR::State state = QCAR::Renderer::getInstance().begin();
   QCAR::setFrameFormat(QCAR::GRAYSCALE, true);
   const QCAR::Image *image = state.getFrame().getImage(0); // 0: YUV, 1: Grayscale image
   const char *data = (const char *)image->getPixels();
   int width = image->getWidth(); int height = image->getHeight();
   CGColorSpace *colorSpace = CGColorSpaceCreateDeviceGray();
   CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
   CGDataProvider *provider = CGDataProviderCreateWithData(NULL, data, width*height, NULL);
   CGColorRenderingIntent intent = kCGRenderingIntentDefault;
   CGImageRef imageRef = CGImageCreate(width, height, 8, 8, width * 1, colorSpace, bitmapInfo, provider, NULL, NO, intent);
   UIImage *myImage = [UIImage imageWithCGImage:imageRef];
   QCAR::Renderer::getInstance().end();
   UIImageWriteToSavedPhotosAlbum(myImage, nil, nil, NULL);
}

С уважением ...

0 голосов
/ 06 апреля 2015

У вас три утечки.

Вы должны вызывать метод Release для каждого метода CoreFoundation со словом Create.

  1. CGColorSpaceRelease(colorSpace);
  2. CGDataProviderRelease(provider);
  3. CGImageRelease(imageRef);

Метод C ++ для преобразования QCAR :: Image в UIImage

inline UIImage *imageWithQCARCameraImage(const QCAR::Image *cameraImage)
{
    UIImage *image = nil;

    if (cameraImage) {
        CGColorSpaceRef colorSpace = NULL;
        QCAR::PIXEL_FORMAT pixelFormat = cameraImage->getFormat();

        int bitsPerPixel = QCAR::getBitsPerPixel(pixelFormat);

        switch (pixelFormat) {
            case QCAR::RGB888:
                colorSpace = CGColorSpaceCreateDeviceRGB();
                break;
            case QCAR::GRAYSCALE:
                colorSpace = CGColorSpaceCreateDeviceGray();
                break;
            case QCAR::YUV:
            case QCAR::RGB565:
            case QCAR::RGBA8888:
            case QCAR::INDEXED:
                std::cerr << "Image format conversion not implemented." << std::endl;
                break;
            case QCAR::UNKNOWN_FORMAT:
                std::cerr << "Image format unknown." << std::endl;
                break;
        }

        float width = cameraImage->getWidth();
        float height = cameraImage->getHeight();
        int bytesPerRow = cameraImage->getStride();
        const void *baseAddress = cameraImage->getPixels();
        size_t totalBytes = QCAR::getBufferSize(width, height, pixelFormat);

        if (bitsPerPixel > 0 && colorSpace != NULL) {
            CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
                                                                      baseAddress,
                                                                      totalBytes,
                                                                      NULL);

            int bitsPerComponent = 8;
            CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone;
            CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
            CGImageRef imageRef = CGImageCreate(width,
                                                height,
                                                bitsPerComponent,
                                                bitsPerPixel,
                                                bytesPerRow,
                                                colorSpace,
                                                bitmapInfo,
                                                provider,
                                                NULL,
                                                NO,
                                                renderingIntent);

            image = [UIImage imageWithCGImage:imageRef];
            CGColorSpaceRelease(colorSpace);
            CGDataProviderRelease(provider);
            CGImageRelease(imageRef);
        }
    }

    return image;
}
0 голосов
/ 27 февраля 2012

Вы не выпускаете (не пропускаете) каждый CGDataProvider, это означает, что вы храните все данные изображений в памяти.Попробуйте выполнить CGDataProviderRelease (поставщик) после executeSelectorOnMainThread.

...