2015-03-25 13 views
9

Sto cercando di modificare il codice Android-Camera2Basic per catturare una raffica di immagini. Tuttavia, non riesco a ottenere il ritardo tra le immagini più veloce di 200-300 ms sul mio Nexus 5, con L 5.0.1.Android burst di acquisizione camera2 è troppo lento

Ho provato un sacco di cose, ma questo è il più semplice. Questa è l'unica parte del codice Camera2Basic che ho modificato. La mia anteprima TextureView è solo 50x50dp, ma non dovrebbe essere importante, giusto?

Per quello che vale, questo codice ha solo ritardi intorno a 50-100 ms sul mio Nexus 6, con L 5.1.

private void captureStillPicture() { 
    try { 
     List<CaptureRequest> captureList = new ArrayList<CaptureRequest>(); 
     mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); 

     for (int i=0;i<10;i++) { 
      captureList.add(mPreviewRequestBuilder.build()); 
     } 

     mCaptureSession.stopRepeating(); 
     mCaptureSession.captureBurst(captureList, cameraCaptureCallback, null); 
     mPreviewRequestBuilder.removeTarget(mImageReader.getSurface()); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

CameraCaptureSession.CaptureCallback cameraCaptureCallback = new CameraCaptureSession.CaptureCallback() { 
    @Override 
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 
      TotalCaptureResult result) { 
     Log.d("camera","saved"); 
     mPictureCounter++; 
     if (mPictureCounter >= 10) 
      unlockFocus(); 
    } 
}; 
+0

acheroncaptain Puoi allegare un codice come hai implementato la modalità burst? – user0770

risposta

14

Il problema che si sta verificando è un artefatto del formato di output dell'immagine richiesto. Il processo di codifica JPEG mette un grande tempo di stallo sulla pipeline della telecamera, quindi c'è un gran numero di tempi morti tra quando una esposizione finisce e la successiva inizia mentre questa codifica avviene.

La velocità di 30 fps citata può essere ottenuta impostando il formato di immagine di output su ImageReader come YUV, poiché si tratta di un'uscita più "nativa" per la telecamera. Questo sarebbe il modo di archiviare le immagini mentre vengono catturate, e in seguito dovresti eseguire la codifica JPEG, a parte l'elaborazione inline della videocamera.

Ad esempio, sul Nexus 5 il tempo di stallo di uscita per la codifica JPEG è 243 ms, che è stato osservato. Per l'output YUV_420_888, è 0 ms. Allo stesso modo, a causa delle loro grandi dimensioni, la codifica RAW_SENSOR introduce un tempo di stallo di 200 ms.

Si noti inoltre che anche se si rimuove l'ostacolo del tempo di stallo scegliendo un formato "più veloce", c'è ancora un tempo minimo di frame, a seconda della dimensione dell'immagine in uscita. Ma per l'output a piena risoluzione di un Nexus 5, questo è 33ms, che è quello che ti aspettavi.

Le informazioni pertinenti si trovano nell'oggetto StreamConfigurationMap dei metadati della fotocamera, here. Controlla i metodi getOutputStallDuration(int format, Size size) e getOutputMinFrameDuration(int format, Size size) per conferma.

+1

YUV_420_888 lo ha fatto sicuramente. Grazie per l'aiuto! – acheroncaptain

+0

In realtà, il formato JPEG può essere più veloce di YUV (o RAW) su alcuni dispositivi. Ciò dipende dall'implementazione del firmware del codificatore JPEG, ad es. [DM3730] (https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/537/t/431683) supporta lo streaming in formato jpeg. Snapdragon 810 può produrre scatti JPEG da 16 megapixel a 15 FPS [proof] (https://www.qualcomm.com/media/documents/files/whitepaper-breakthrough-mobile-imaging-experiences.pdf): non c'è modo di averne abbastanza larghezza di banda per RAW o YUV. –

-2

In base a questo articolo PCMag: http://www.pcmag.com/article2/0,2817,2428017,00.asp La modalità burst Nexus 5 consente di scattare 3 immagini al secondo. Quindi ottenere molto meno di 333ms tra le foto è altamente improbabile.

Avete una fonte di informazioni che suggerisce che il burst Nexus 5 dovrebbe essere più veloce?

+1

Questo è per l'API Camera2. 30 fps dovrebbero essere possibili con un dispositivo FULL capace. http://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL – acheroncaptain

+1

Inoltre, vedere questa domanda: http: // stackoverflow.it/questions/28566898/android-camera2-speed-up – acheroncaptain

+0

@acheroncaptain Quindi hai confermato che android.request.availableCapabilities contiene BURST_CAPTURE sul tuo N5? – iheanyi

5

tenta di impostare a seguito della richiesta di acquisizione parametri

requestBuilder = camDevice 
     .createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 

requestBuilder.set(CaptureRequest.EDGE_MODE, 
     CaptureRequest.EDGE_MODE_OFF); 
requestBuilder.set(
     CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, 
     CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON); 
requestBuilder.set(
     CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE, 
     CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF); 
requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, 
     CaptureRequest.NOISE_REDUCTION_MODE_OFF); 
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, 
     CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); 

requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true); 
requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true); 

io non sono sicuro di come informazioni velocemente viene in CameraCaptureSession.CaptureCallback. Non ha dati immagine e potrebbe essere chiamato prima o dopo ImageReader.OnImageAvailableListener. Provare a misurare il tempo tra le chiamate ImageReader.OnImageAvailableListener. E non dimenticare di leggere le immagini e rilasciarle, perché le nuove immagini non sono disponibili se il buffer è pieno e le immagini non vengono rilasciate. Ad esempio:

private class imageAvailableListener implements 
      ImageReader.OnImageAvailableListener { 
     @Override 
     public void onImageAvailable(ImageReader ir) { 
      Log.i(TAG, "Time = " + System.currentTimeMillis()); 
      Image im = ir.acquireNextImage(); 
      im.close(); 
     } 
    } 

ImageReader mImageReader = ImageReader.newInstance(imageReaderWidth, 
        imageReaderHeight, ImageFormat.YUV_420_888, 2); 
mImageReader.setOnImageAvailableListener(
        new imageAvailableListener(), null); 
+0

Avrei dovuto dire che stavo usando JPEG e non YUV. Questa era la principale differenza nel nostro codice (che ho appena notato nella seconda parte della risposta). Quindi, mio ​​cattivo. Apprezzo l'aiuto però. – acheroncaptain

+0

LAVORO! ridurre 100 ms su galassia s3 - cyanogenmod 12.1 (lecca-lecca) – Lucas