2016-02-17 6 views
1

Почему, когда я рисую ofImage с ofxAndroidVideoGrabber, который установлен в OF_PIXELS_RGB, похоже ли это? screenshot of weird color encodingVideoGrabber OF_PIXELS_RGB рендеринг неправильно на Android

Вот мой код:

void ofApp::setup(){ 
    ofBackground(0,0,0); 

    grabber.setPixelFormat(OF_PIXELS_RGB); 

    // Start the grabber 
    grabber.setup(640,480); 

    // Get the native android video grabber 
    ofxAndroidVideoGrabber* androidGrabber = (ofxAndroidVideoGrabber*)grabber.getGrabber().get(); 

    // Ensure facing the correct direction 
    androidGrabber->setDeviceID(androidGrabber->getBackCamera()); 
} 

void ofApp::update(){ 
    grabber.update(); 
    if(grabber.isFrameNew()){ 
     // Add frame 
     ofPixels nextFrame = grabber.getPixels(); 
     frameQueue.push(nextFrame); 
    } 
} 

void ofApp::draw(){  
    // Calculate aspect ratio of grabber image 
    float grabberAspectRatio = grabber.getWidth()/grabber.getHeight(); 

    // Draw camera image centered in the window 
    ofPushMatrix(); 
    ofSetHexColor(0xFFFFFF); 
    ofSetRectMode(OF_RECTMODE_CENTER); 

    ofTranslate(ofGetWidth()/2, ofGetHeight()/2); 

    // Initial check that the next frame should be rendered 
    if (! frameQueue.empty()) { 
     ofPixels nextFrame = frameQueue.front(); 
     grabberImage.setFromPixels(nextFrame); 
     grabberImage.mirror(false, true); 
     grabberImage.update(); 

     // Advance 
     frameQueue.pop(); 
    } 


    if (grabberImage.isAllocated()) { 
     if(ofGetWidth() > ofGetHeight()) { 
      grabberImage.draw(0, 0, ofGetHeight() * grabberAspectRatio, ofGetHeight()); 
     } else { 
      grabberImage.draw(0, 0, ofGetWidth(), ofGetWidth() * 1.0/grabberAspectRatio); 
     } 
    } 

    ofPopMatrix(); 
    ofSetRectMode(OF_RECTMODE_CORNER); 
} 

Насколько мне известно, видео приходит как NV21 и преобразуется в RGB с помощью openframeworks. Мое предположение, что:

  1. я делаю что-то неправильно, что пропускает, что преобразование
  2. Существует ошибка в России.

Я попробовал пример камеры, и я получаю такой же эффект.

ответ

2

Оказывается, что мой эмулятор использовал другой формат, чем большинство устройств Android для его видеопотока.

Основная проблема заключалась в том, что openframework предполагал, что каналы U и V для каждого пикселя были рядом друг с другом или полуплоскостями. Но вместо этого, основываясь на просмотре android source, я обнаружил, что изображение YUV может быть либо YUV420Planar, либо YUV420SemiPlanar. Если изображение YUV420Planar, то канал V следует за всем каналом U. IE, индекс канала V первого пикселя составляет startIndexU + width * height. Большинство устройств Android, которые я тестировал, являются полупланарными, поэтому, если вы видите видео, подобное моему, вероятно, именно ваш эмулятор дает плоский канал вместо полуплоскостного канала.