Я пишу приложение для Android, чтобы захватить данные экрана и сделать из него MP4.Первым шагом в этом является использование некоторых вызовов openGL для считывания пикселей с экрана.
private void screenScrape() {
Log.d(TAG, "In screenScrape");
//read pixels from frame buffer into PBO (GL_PIXEL_PACK_BUFFER)
mySurface.queueEvent(new Runnable() {
@Override
public void run() {
Log.d(TAG, "In Screen Scrape 1");
//generate and bind buffer ID
GLES30.glGenBuffers(1, pboIds);
checkGlError("Gen Buffers");
GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pboIds.get(0));
checkGlError("Bind Buffers");
//creates and initializes data store for PBO. Any pre-existing data store is deleted
GLES30.glBufferData(GLES30.GL_PIXEL_PACK_BUFFER, (mWidth * mHeight * 4), null, GLES30.GL_STATIC_READ);
checkGlError("Buffer Data");
glReadPixelsPBO(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, 0);
checkGlError("Read Pixels");
}
});
//map PBO data into client address space
mySurface.queueEvent(new Runnable() {
@Override
public void run() {
Log.d(TAG, "In Screen Scrape 2");
//read pixels from PBO into a byte buffer for processing. Unmap buffer for use in next pass
mapBuffer = ((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_PIXEL_PACK_BUFFER, 0, 4 * mWidth * mHeight, GLES30.GL_MAP_READ_BIT)).order(ByteOrder.nativeOrder());
checkGlError("Map Buffer");
GLES30.glUnmapBuffer(GLES30.GL_PIXEL_PACK_BUFFER);
checkGlError("Unmap Buffer");
//openGL calls return pixels in a flipped format. Flip buffer so image presented right side up
for (int i = 0; i < mWidth; ++i) {
for (int j = 0; j < mHeight; ++j) {
for (int k = 0; k < 4; ++k) {
flippedBuffer.put((i + j * mWidth) * 4 + k, mapBuffer.get((i + (mHeight - 1 - j) * mWidth) * 4 + k));
}
}
}
isByteBufferEmpty(mapBuffer, "MAP BUFFER");
Log.d(TAG, "Flipped Buffer Position: " + flippedBuffer.position() + "Remaining: " + flippedBuffer.remaining() + " Limit: " + flippedBuffer.limit());
convertColorSpaceByteArray(flippedBuffer);
mapBuffer.clear();
}
});
}
mySurface
- это GLMapsurface, который я инициализирую из входного параметра.
например, GLMapSurface mySurface = inputSurface
, где inputSurface
- передаваемый параметр.
Теперь моя проблема заключается в том, что вызов glMapBufferRange блокирует пользовательский интерфейс.Как я могу заставить этот вызов выполняться в фоновом потоке, чтобы он не блокировал пользовательский интерфейс?
Я пытался создать новый объект GLMapSurface
и поместить в него события, но они никогда не выполнялись.