2015-03-25 10 views
9

Próbuję zmodyfikować kod Android-Camera2Basic, aby uchwycić serię zdjęć. Jednak nie mogę uzyskać opóźnienia między zdjęciami szybciej niż 200-300ms na moim Nexusie 5, działającym w wersji 5.0.1.Aparaty do przechwytywania aparatów z rodziny Android2 są zbyt wolne.

Próbowałem wielu rzeczy, ale to jest najbardziej podstawowe. To jedyna część zmodyfikowanego przeze mnie kodu Camera2Basic. Mój podgląd TextureView to tylko 50x50dp, ale to nie powinno mieć znaczenia, prawda?

Co jest warte, ten kod ma opóźnienia około 50-100ms na moim Nexusie 6, z 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 Czy możesz dołączyć kod, w jaki sposób zaimplementowano tryb zdjęć seryjnych? – user0770

Odpowiedz

14

Kwestia używasz do jest artefaktem formatu wyjściowego obrazu masz wezwanego. Proces kodowania JPEG powoduje znaczny czas opóźnienia w rurociągu kamery, dlatego istnieje wiele przestojów pomiędzy końcem jednej ekspozycji a kolejną rozpoczyna się podczas tego kodowania.

Podana częstość 30 fps może zostać osiągnięta poprzez ustawienie wyjściowego formatu obrazu na ImageReader jako YUV, ponieważ jest to bardziej "natywne" wyjście dla kamery. To byłby sposób przechowywania obrazów podczas ich przechwytywania, a następnie musiałbyś wykonać kodowanie JPEG, niezależnie od przetwarzania liniowego kamery.

Na przykład na Nexusie 5 czas opóźnienia wyjścia dla kodowania JPEG wynosi 243 ms, które obserwowałeś. Dla wyjścia YUV_420_888 wynosi ono 0 ms. Podobnie, ze względu na ich duży rozmiar, kodowanie RAW_SENSOR wprowadza czas utknięcia 200 ms.

Należy również pamiętać, że nawet jeśli usuniesz przeszkodę czasową, wybierając "szybszy" format, pozostanie minimalny czas klatek, w zależności od rozmiaru obrazu wyjściowego. Ale dla pełnej rozdzielczości Nexusa 5 to 33ms, czego się spodziewałeś.

Istotne informacje znajdują się w obiekcie metadanych kamery StreamConfigurationMap, here. Zapoznaj się z metodami potwierdzenia dla getOutputStallDuration(int format, Size size) i getOutputMinFrameDuration(int format, Size size).

+1

YUV_420_888 zdecydowanie to zrobił. Dzięki za pomoc! – acheroncaptain

+0

W rzeczywistości format JPEG może być szybszy niż YUV (lub RAW) na niektórych urządzeniach. Zależy to od implementacji oprogramowania układowego kodera JPEG, np. [DM3730] (https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/537/t/431683) obsługuje przesyłanie strumieniowe w formacie jpeg. Snapdragon 810 może produkować 16 megapikselowe zdjęcia seryjne JPEG przy 15 FPS [dowód] (https://www.qualcomm.com/media/documents/files/whitepaper-breakthrough-mobile-imaging-experiences.pdf): brak możliwości przepustowość dla RAW lub YUV. –

-2

Na podstawie tego artykułu PCMag: http://www.pcmag.com/article2/0,2817,2428017,00.asp trybie seryjnym Nexus 5 pozwala wziąć 3 zdjęć na sekundę. Tak więc uzyskanie znacznie mniejszej niż 333 ms między zdjęciami jest mało prawdopodobne.

Czy masz źródło informacji, które sugeruje, że seria Nexus 5 powinna być szybsza?

+1

To jest dla API Camera2. 30 klatek na sekundę powinno być możliwe przy użyciu urządzenia FULL. http://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL – acheroncaptain

+1

Zobacz także to pytanie: http: // stackoverflow.com/questions/28566898/android-camera2-speed-up – acheroncaptain

+0

@acheroncaptain Więc potwierdziłeś, że android.request.availableCapabilities zawiera BURST_CAPTURE na twoim N5? – iheanyi

5

Spróbuj ustawić następujące parametry przechwytywania wniosek

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); 

nie jestem pewien, jak szybko informacji wchodzi CameraCaptureSession.CaptureCallback. Nie ma danych obrazu i może zostać wywołana przed lub po ImageReader.OnImageAvailableListener. Spróbuj zmierzyć czas między wywołaniami ImageReader.OnImageAvailableListener. I nie zapomnij przeczytać obrazów i zwolnij je, ponieważ nowe obrazy nie są dostępne, jeśli bufor jest wypełniony i obrazy nie zostały zwolnione. Na przykład:

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

Powinienem wspomnieć, że używałem JPEG, a nie YUV. To była główna różnica w naszym kodzie (co właśnie zauważyłem w drugiej połowie twojej odpowiedzi). Tak, moje złe. Doceniam jednak pomoc. – acheroncaptain

+0

PRACA! zredukować 100 ms na galaktyce s3 - cyanogenmod 12.1 (lizak) – Lucas

Powiązane problemy