2015-11-09 2 views
1

Цель: Я использую SurfaceTexture для отображения предварительного просмотра камеры, и нужно рисовать на верхней поверхности, приобретая контекст GL от НДК. Я выбрал подход SurfaceTexture, так как я могу избежать ручного управления буфером кадров камеры от java до NDK, чтобы сохранить некоторую производительность.GL контекст захватывая SurfaceTexture от НДК

public class MainActivity extends Activity implements SurfaceTextureListener { 

private Camera mCamera; 
private TextureView mTextureView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mTextureView = new TextureView(this); 
    mTextureView.setSurfaceTextureListener(this); 

    setContentView(mTextureView); 
} 

@Override 
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
    mCamera = Camera.open(); 
    Camera.Size previewSize = mCamera.getParameters().getPreviewSize(); 
    mTextureView.setLayoutParams(new FrameLayout.LayoutParams(previewSize.width, previewSize.height, Gravity.CENTER)); 

    try { 
     mCamera.setPreviewTexture(surface); 
    } catch (IOException t) { 
    } 

    mCamera.startPreview(); 
} 

@Override 
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 
    // Ignored, the Camera does all the work for us 
} 

@Override 
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
    mCamera.stopPreview(); 
    mCamera.release(); 
    return true; 
} 

@Override 
public void onSurfaceTextureUpdated(SurfaceTexture surface) { 
    // Update your view here 
} 

Что я пробовал: Я полагаю SurfaceTexture внутренне использует функцию GL для рисования контекста. От NDK получение отображения по умолчанию с ошибкой BAD_DISPLAY.

EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 

Конечно, я смог инициализировать новый контекст GL и сделать свой рисунок, но все же я хочу, чтобы сохранить текстуру отображается из кода Java в фоновом режиме.

Вопрос: Возможно ли вообще захватить контекст GL из NDK при использовании SurfaceTexture? Возможно, мне нужно использовать на GLSurfaceView, инициализировать контекст GL вручную из java-кода и захватить его из NDK?

+0

Вы видели ответ Романа Гая (https://groups.google.com/d/msg/android-developers/U5RXFGpAHPE/IqHeIeGXhr0J) о работе с TextureView и получении контекста EGL? –

ответ

2

Ваш вопрос не имеет для меня никакого смысла, поэтому позвольте мне изложить несколько вещей.

  • SurfaceTexture ничего не рисует. Когда камера подключена как производитель, SurfaceTexture получает кадр YUV и использует функции EGL, чтобы настроить его как «внешнюю» текстуру. Затем вы можете визуализировать эту текстуру с помощью GLES.

  • Контексты EGL могут быть «текущими» в одном потоке за раз. Указатель на текущий контекст хранится в собственном потоковом локальном хранилище. Связи GLES на Java-языке представляют собой тонкую оболочку вокруг собственного кода, поэтому при работе с GLES существует мало концептуальной разницы между Java и C++.

  • Текстура SurfaceTexture будет ассоциирована с тем, какой контекст был текущим, когда объект был создан, но вы можете переключить его в другой контекст, используя вызовы attach/detach. Вы не можете «захватить» контекст EGL SurfaceTexture, но вы можете сказать, какой из них вы хотите использовать.

  • SurfaceTexture (и поверхность в целом) может иметь только один производитель. Вы не можете отправлять кадры камеры на поверхность, на которую вы оказываете визуализацию, с помощью GLES. Вы можете переключаться между ними, но обычно лучше использовать два разных объекта Surface.

  • A TextureView - это вид со встроенной поверхностью. Когда его попросят перерисовать, он использует GLES для рендеринга из текстуры (именно поэтому вы вообще ничего не видите, если отключите аппаратное рендеринг).

Если я понять ваш вопрос правильно, я думаю, что вы хотите сделать, это:

  • Отправить выход камеры к новому SurfaceTexture, созданного на средства визуализации потока.
  • Создайте поверхность EGLS для текстуры TextureView SurfaceTexture.
  • Окажите на TextureView с помощью GLES, используя текстуру с камеры в качестве источника образца. Добавьте любой другой рендеринг GLES.

Различные примеры можно найти в Grafika, например. действие «текстура из камеры».

+0

Спасибо за разъяснение о внутренних деталях! – deimus

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