まず、すばらしい例を提供してくれた fadden に感謝します。
このContinuousCapture.java の例に従って試してみ たところ、以下のプログラムが作成されました。
1)
ANativeWwindow 参照を取得し、ANative lock メソッドと unlockpost メソッドを使用して BufferQueue を取得し、データを入力することで、ネイティブ レイヤーの TextureView に画像を表示しようとして います。
すなわち:
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
親切に私を助けてください。