首先,感谢 fadden 提供的精彩示例。
我尝试遵循 这个ContinuousCapture.java 示例,并生成了以下程序。
1)
我试图通过获取其 ANativeWwindow 引用并使用 ANative lock 和 unlockpost 方法来获取 BufferQueue并填充数据,将图像显示到本机层的 TextureView 中。
IE:
ANativeWindow_lock(*window, &buffer, NULL)
ANativeWindow_unlockAndPost(*window);
2)
同时我想从这个 Surface 检索数据并将其传递给编码器。或者,将其显示到另一个表面。
作为第一步,我创建了下面的类,它将 EglCore 初始化到不同的线程中,并尝试在 EglContext 中配置用户给定的表面。到目前为止,一切都很好。但是,当我尝试通过 lock 和 unlockAndPost 方法将数据复制到缓冲区时,我收到以下错误。
E/BufferQueueProducer: [unnamed-7679-0] connect(P): already connected (cur=1 req=2)
E/BufferQueueProducer: [unnamed-7679-0] connect(P): already connected (cur=1 req=2)
E/BufferQueueProducer: [unnamed-7679-0] connect(P): already connected (cur=1 req=2)
问题: 这是正确的方法吗?或者我忽略了什么?
package com.super.dump
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.opengl.EGLSurface;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.util.SparseArray;
import android.view.Surface;
import java.io.File;
import java.io.IOException;
import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.opengl.EGLSurface;
import android.opengl.GLES20;
import android.os.Environment;
import android.util.Log;
import android.util.SparseArray;
import android.view.Surface;
import android.view.View;
import android.widget.TextView;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class SuperDump {
RenderThread rT;
Surface userProvidedSurface;
public SuperDump() {
userProvidedSurface = null;
rT = null;
}
public void init(Surface userSurface)
{
if ( userSurface != null) {
userProvidedSurface = userSurface;
rT = new RenderThread(userProvidedSurface);
rT.start();
rT.waitUntilRendererReady();
}
}
private class RenderThread extends Thread {
public String TAG = "RenderThread";
RenderHandler mHandler;
private Object mSyncForRenderAvailability = new Object();
boolean mIsRendererReady = false;
private EglCore mEglCore;
private Surface mSurfaceUser;
private WindowSurface mSurfaceWindowUser;
public RenderThread() {
}
public RenderThread(Surface userSurface) {
mSurfaceUser = userSurface;
}
@Override
public void run() {
Looper.prepare();
mHandler = new RenderHandler(this);
mEglCore = new EglCore(null, EglCore.FLAG_RECORDABLE);
mSurfaceWindowUser = new WindowSurface(mEglCore, mSurfaceUser, false);
synchronized (mSyncForRenderAvailability) {
mIsRendererReady = true;
mSyncForRenderAvailability.notifyAll();
}
Looper.loop();
Log.d (TAG, "End of RenderThread..");
}
public RenderHandler getHandler() {
return mHandler;
}
public void waitUntilRendererReady()
{
synchronized (mSyncForRenderAvailability) {
while(!mIsRendererReady) {
try {
mSyncForRenderAvailability.wait();
} catch (InterruptedException e) {
Log.d (TAG, "Wait interrupted..");
}
}
}
}
} // RenderThread
private static class RenderHandler extends Handler {
public String TAG = "RenderHandler";
private static final int MSG_RENDER_QUIT = 1;
private WeakReference<RenderThread> mWeakRenderThread;
public RenderHandler(RenderThread rT)
{
mWeakRenderThread = new WeakReference<RenderThread>(rT);
}
public void stopMe() {
sendMessage(obtainMessage(MSG_RENDER_QUIT));
}
@Override
public void handleMessage(Message msg) {
Log.d (TAG, "Inside handleMessage..");
switch(msg.what) {
case MSG_RENDER_QUIT:
Looper.getMainLooper().quit(); // detaching from thread.
}
}
} // RenderHandler Class.
}; //SuperDump class
请帮助我。