Камера Android, одновременный предварительный просмотр Raw и Rake TakePicture

Поэтому я работаю над чем-то вроде приложения для камеры. Он рисует предварительный просмотр в реальном времени на естественной текстуре OpenGL. Если нажата кнопка, неподвижное изображение захватывается (возможно, с более высоким разрешением, чем предварительный просмотр в реальном времени) в его исходной форме.

Вот общая схема моего кода. Для ясности я не показываю менее значимые фрагменты. Это упрощенная ситуация, когда разрешения предварительного просмотра и неподвижного разрешения идентичны.

void Setup(Activity a) { // .. snip .. mSurfaceView = new SurfaceView(a); mSurfaceView.getHolder().addCallback(this); //put the surface off-screen AbsoluteLayout.LayoutParams alp = new AbsoluteLayout.LayoutParams(8, 8, -8, -8); a.addContentView(mSurfaceView, alp); //need this, otherwise surface is not created mCamera = Camera.open(miCameraId); mCamera.setPreviewCallbackWithBuffer(this); ConfigureCameraDefaults(640,480); } // -------------------------------------------------------------------- // void ConfigureCameraDefaults(int iX, int iY) { Camera.Parameters oParameters=mCamera.getParameters(); oParameters.setPreviewFormat(ImageFormat.NV21); oParameters.setPictureFormat(ImageFormat.NV21); oParameters.setPreviewSize(iX, iY); // for live preview oParameters.setPictureSize(iX, iY); // for still capture int bpp = ImageFormat.getBitsPerPixel(ImageFormat.NV21); int iBufSize = (int) (iX*iY*((float)bpp/8)); mBuffer = new byte[iBufSize]; mCamera.addCallbackBuffer(mBuffer); try { mCamera.setParameters(oParameters); } catch (Exception e) { // .. snip .. } } void startPreview() { mCamera.startPreview(); } void stopPreview() { mCamera.stopPreview(); } void takePicture() { mCamera.takePicture(null, this, null, null); //2nd is the raw callback } // -------------------------------------------------------------------- // @Override public void onPreviewFrame(byte[] data, Camera camera) { // -- at this point the buffer is in a safe state, until it is added again onPreviewFrame_native(data); // -- make buffer writable again mCamera.addCallbackBuffer(mBuffer); } @Override public void onPictureTaken(byte[] data, Camera camera) { onStillCapture_native(data); mCamera.startPreview(); //otherwise preview will stop } 

Хорошо, теперь вопросы. Когда takePicture() не вызывается, все функционирует в соответствии с планом. Кадры предварительного просмотра прибывают, они обрабатываются, буфер переупорядочивается. Однако, если я startPreview() то takePicture() , обратный вызов изображения получает нулевой массив данных. Каждый раз. В документах Google есть что сказать о takePicture() :

The raw callback occurs when the raw image data is available (NOTE: the data will be null if there is no raw image callback buffer available or the raw image callback buffer is not large enough to hold the raw image).

Это мне не совсем понятно, так как:

  1. Не существует функции для установки буфера для неподвижного захвата, только для превентивных кадров
  2. Даже если один и тот же буфер используется как для кеш-кадров, так и для предварительных кадров, у меня есть буфер в очереди.
  3. Добавление второго буфера (идентичного буферу предварительного просмотра), специально для кепков, абсолютно не влияет
  4. Предварительный просмотр должен быть запущен, чтобы takePicture() был действительным вызовом.

Мне что-то не хватает? Или нам не разрешено получать необработанные кадры из видео и все же в одно и то же время? В документах об этом вообще ничего нет. Я также посмотрел на источник камеры, но безрезультатно.

Любая помощь будет принята с благодарностью.

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

Кажется, нет никакого способа получить исходное изображение. Метод addCallbackBuffer используется только для обратных вызовов предварительного просмотра. Существует еще один метод addRawImageCallbackBuffer который должен делать то, что вы хотите. Он публичный, но не экспортируемый, поэтому вы не можете его напрямую назвать. Вы можете назвать это следующим образом:

  try { final Method addRawImageCallbackBuffer = camera0.getClass() .getDeclaredMethod("addRawImageCallbackBuffer", byte[].class); addRawImageCallbackBuffer.invoke(camera0, new byte[100000000]); } catch (Exception e) { Log.e("RNG", "Error", e); } 

Но на моем Nexus 5 он по-прежнему возвращает null для обратного вызова, поэтому я думаю, что он просто не поддерживается.