2016-05-11 4 views
2

При использовании SurfaceHolder/SurfaceView для настройки CaptureSession я ожидал, что SurfaceView может иметь любой размер макета, в то время как я установил хороший размер предварительного просмотра с тем же соотношением сторон для него с помощью surfaceView.getHolder(). setFixedSize (preview_width, preview_height). Результатом должно быть то, что входящий буфер предварительного просмотра может быть уменьшен до размера макета.camera2 выйдет из строя, если размер SurfaceView не является одним из поддерживаемых размеров.

Но в камере2 - аппаратный уровень LEGACY - настройка CaptureSession будет работать только в том случае, если я использую SurfaceView с точно таким же размером макета, как тот, который находится в списке, возвращаемом streamConfigurationMap.getOutputSizes (SurfaceHolder.class). Если нет, изображение не будет уменьшено, но настройка вызывает ошибку.

/** 
* Prerequisites: 
* - The device must be opened. 
* - The surface view must be ready. 
*/ 
protected void init() { 

    // ... 

    try { 

     CameraCaptureSession.StateCallback cb = new CameraCaptureSession.StateCallback() { 

      // ... 
     }; 

     // The following line will result in an error*, if the viewfinder has not the right size: 
     cameraDevice.createCaptureSession(Arrays.asList(viewfinder.getHolder().getSurface(), imageReaderSmall.getSurface()), cb, null); 
    } 
    catch (CameraAccessException e) { 

     // ... 
    } 
} 

Из журнала (Samsung Galaxy A3 '14, SDV v21):

05-12 ...: Output sizes for SurfaceHolder.class: [1440x1080, 1280x720, 960x720, 880x720, 960x540, 720x540, 800x480, 720x480, 640x480, 528x432, 352x288, 320x240, 176x144] 
... 
05-12 ... I/CameraManager: Using legacy camera HAL. 
... 
05-12 ... I/OpenGLRenderer: Initialized EGL, version 1.4 
05-12 ... D/OpenGLRenderer: Get maximum texture size. GL_MAX_TEXTURE_SIZE is 4096 
05-12 ... D/OpenGLRenderer: Enabling debug mode 0 
05-12 ....CameraActivity: Surface created 
05-12 ....CameraActivity: Surface changed 4 540x405 
*) 05-12 ... E/CameraDevice-0-LE: Surface with size (w=540, h=405) and format 0x4 is not valid, size not in valid set: [1440x1080, 1280x720, 960x720, 880x720, 960x540, 720x540, 800x480, 720x480, 640x480, 528x432, 352x288, 320x240, 176x144] 
05-12 ... W/CameraDevice-JV-0: Stream configuration failed 
05-12 ... E/CameraCaptureSession: Session 0: Failed to create capture session; configuration failed 
... 
05-12 ....CameraActivity: Configure failed! 

Используя Nexus 5X, SDK v23, и ждет surfaceChanged() вызова после surfaceHolder.setFixedSize(), нет никакой ошибки с размер предварительного просмотра, который отсутствует в списке поддерживаемых размеров вывода, но предварительный просмотр не запускается. Из журнала:

05-12 08:47:10.052 ....CameraActivity: Surface created 
05-12 08:47:10.053 ....CameraActivity: Surface changed 4 1455x1080 
05-12 08:47:10.054 ....CameraActivity: Find preview size for 1455x1080 (1.347424:1) px 
05-12 08:47:10.054 ....CameraActivity: Preview size 1600x1200 px 
05-12 08:47:10.070 ....CameraActivity: Surface changed 4 1600x1200 
05-12 08:47:10.110 ....CameraActivity: Session started 
05-12 08:47:10.163 ....CameraActivity: Surface: Surface(name=null)/@0xec338e5 

Результат: Предварительный просмотр не запускается, я могу выразить мнение поверхности цвет фона, чтобы продемонстрировать его.

Как решить эту проблему и по-прежнему использовать SurfaceView, который более эффективен и обратно совместим с использованием SurfaceTexture.

+1

Старая API-интерфейс камеры не заботился о том, какой размер SurfaceView - входящие изображения были просто масштабированы до отображения до того размера, который был. Что произойдет, если вы не вызываете 'setFixedSize()'? Можете ли вы вставить фактический журнал ошибок в вопрос? – fadden

+0

Вызов 'setFixedSize()' - в моем случае с поддерживаемым размером 640x480px - приведет к той же ошибке. Поворот устройства в альбомный режим будет работать, так как поддерживается размер макетной поверхности: 720x540. В следующие дни я попробую это с не устаревшим устройством и отчитаюсь. Если это будет работать, тогда проблем нет, поскольку устройства, не принадлежащие к предыдущему, никогда не должны использовать API-интерфейс Camera2: многие параметры все еще отсутствуют, которые доступны в первом API. – Andi

+0

Это может быть ошибка с конкретным ПЗУ. Я не удивлюсь, если у разных устройств с частичной поддержкой камеры2 нет такой же проблемы. OTOH, существует проблема с API-интерфейсом камеры2 и ориентацией устройства. –

ответ

3

После вызова setFixedSize вам нужно дождаться, когда обратный вызов surfaceChanged() снова загорится, прежде чем создавать сеанс захвата камеры.

setFixedSize создает необходимые изменения SurfaceView, но они не вступают в силу немедленно.

+0

Значит, SurfaceView не будет соответствовать его контейнеру? –

+0

Извините за вводящие в заблуждение ответы раньше. Нет, он все еще не работает, предварительный просмотр в режиме ландшафта в порядке, но он будет слишком маленьким и растянут потом в портретном режиме. Предварительный просмотр не начинается вообще на моем Nexus 5X. – Andi

+0

На растяжке предварительного просмотра - вы настраиваете размер вашего SurfaceView, чтобы иметь правильное соотношение сторон (setFixedSize не влияет на размеры макета SurfaceView, только его буфер поддержки) на портрете? Буферы, полученные SurfaceView, будут масштабированы, чтобы заполнить размеры макета SurfaceView, так что это приведет к растягиванию, если соотношение сторон формата макета не соответствует формату формата буфера. –

Смежные вопросы