SurfaceTexture 原理

  大家使用

SurfaceTexture.OnFrameAvailableListener mOnFrameAvailableListener = (surfaceTexture -> {
​​​​​​​}

  对应---


    /**
     * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
     * <p>
     * In single buffered mode the application is responsible for serializing access to the image
     * content buffer. Each time the image content is to be updated, the
     * {@link #releaseTexImage()} method must be called before the image content producer takes
     * ownership of the buffer. For example, when producing image content with the NDK
     * ANativeWindow_lock and ANativeWindow_unlockAndPost functions, {@link #releaseTexImage()}
     * must be called before each ANativeWindow_lock, or that call will fail. When producing
     * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first
     * OpenGL ES function call each frame.
     * <p>
     * Unlike {@link #SurfaceTexture(int, boolean)}, which takes an OpenGL texture object name,
     * this constructor creates the SurfaceTexture in detached mode. A texture name must be passed
     * in using {@link #attachToGLContext} before calling {@link #releaseTexImage()} and producing
     * image content using OpenGL ES.
     *
     * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
     *
     * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
     */
    public SurfaceTexture(boolean singleBufferMode) {
        mCreatorLooper = Looper.myLooper();
        mIsSingleBuffered = singleBufferMode;
        nativeInit(true, 0, singleBufferMode, new WeakReference<SurfaceTexture>(this));
    }

 private native void nativeInit(boolean isDetached, int texName,
             boolean singleBufferMode, WeakReference<SurfaceTexture> weakSelf)
             throws Surface.OutOfResourcesException;

为什么要   new WeakReference<SurfaceTexture>(this)  ???

全局搜索 nayiveInit 搜索到映射方法

/frameworks/base/core/jni/android_graphics_SurfaceTexture.cpp (映射第一行)

static const JNINativeMethod gSurfaceTextureMethods[] = {
          {"nativeInit", "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init},
          {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize},
          {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize},
          {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage},
          {"nativeReleaseTexImage", "()V", (void*)SurfaceTexture_releaseTexImage},
          {"nativeDetachFromGLContext", "()I", (void*)SurfaceTexture_detachFromGLContext},
          {"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext},
          {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix},
          {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp},
          {"nativeGetDataSpace", "()I", (void*)SurfaceTexture_getDataSpace},
          {"nativeRelease", "()V", (void*)SurfaceTexture_release},
          {"nativeIsReleased", "()Z", (void*)SurfaceTexture_isReleased},
  };

----------------------------------------------------------------------------------
  static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
          jint texName, jboolean singleBufferMode, jobject weakThiz)
  {
      sp<IGraphicBufferProducer> producer; // 创建生产者
      sp<IGraphicBufferConsumer> consumer; // 创建消费者
      BufferQueue::createBufferQueue(&producer, &consumer);//创建BufferQueue
  
      if (singleBufferMode) {
          consumer->setMaxBufferCount(1); //如果是单buffer模式设置 count=1
      }
  
      //定义SurfaceTexture
      sp<SurfaceTexture> surfaceTexture;
	  
	  //创建SurfaceTexture = 
      if (isDetached) {
          surfaceTexture = new SurfaceTexture(consumer, GL_TEXTURE_EXTERNAL_OES,
                  true, !singleBufferMode);
      } else {
          surfaceTexture = new SurfaceTexture(consumer, texName,
                  GL_TEXTURE_EXTERNAL_OES, true, !singleBufferMode);
      }
  
      if (surfaceTexture == 0) {
          jniThrowException(env, OutOfResourcesException,
                  "Unable to create native SurfaceTexture");
          return;
      }
	  
      surfaceTexture->setName(String8::format("SurfaceTexture-%d-%d-%d",
              (isDetached ? 0 : texName),
              getpid(),
              createProcessUniqueId()));
  
      // If the current context is protected, inform the producer.
      consumer->setConsumerIsProtected(isProtectedContext());
   
      //将Native SurfaceTexture指针(long)设给 Java SurfaceTexture的mSurfaceTexture
      SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
	  
	  //将Native producer指针(long)设给 Java SurfaceTexture的mProducer
      SurfaceTexture_setProducer(env, thiz, producer);
  
      //获取java SurfaceTexture 对象
      jclass clazz = env->GetObjectClass(thiz);
	  
	  //空指针判断-初始化不成功
      if (clazz == NULL) {
          jniThrowRuntimeException(env,
                  "Can't find android/graphics/SurfaceTexture");
          return;
      }
  
      // weakThiz表示Java层SurfaceTexture对象的弱引用,JNISurfaceTextureContext是JNI封装类,负责回调Java层SurfaceTexture.postEventFromNative方法
      sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
              clazz));
	
      //	
      surfaceTexture->setFrameAvailableListener(ctx);
	  
      SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
  }
  
  
  static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
          const sp<SurfaceTexture>& surfaceTexture)
  {
      SurfaceTexture* const p =
          (SurfaceTexture*)env->GetLongField(thiz, fields.surfaceTexture);
      if (surfaceTexture.get()) {
          surfaceTexture->incStrong((void*)SurfaceTexture_setSurfaceTexture);
      }
      if (p) {
          p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
      }
	  
	  //将Native SurfaceTexture指针(long)设给 Java SurfaceTexture 的 mSurfaceTexture对象
      env->SetLongField(thiz, fields.surfaceTexture, (jlong)surfaceTexture.get());
  }


  static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
          jobject thiz, sp<SurfaceTexture::FrameAvailableListener> listener)
  {
      SurfaceTexture::FrameAvailableListener* const p =
          (SurfaceTexture::FrameAvailableListener*)
              env->GetLongField(thiz, fields.frameAvailableListener);
      if (listener.get()) {
          listener->incStrong((void*)SurfaceTexture_setSurfaceTexture);
      }
      if (p) {
          p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
      }
	  //将Native listener指针(long)设给 Java SurfaceTexture的mFrameAvailableListener
      env->SetLongField(thiz, fields.frameAvailableListener, (jlong)listener.get());
  }


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SurfaceTexture 是 Android 中提供的一个类,用于将实时相机预览数据渲染到一个 OpenGL ES 纹理上,以便进行后续的图像处理。实现相机预览的一般流程如下: 1. 打开相机,设置相机参数; 2. 创建一个 SurfaceTexture 对象,并将其设置为相机预览回调中的 Surface; 3. 在 SurfaceTexture 的 onFrameAvailable 回调中,获取最新的相机预览帧数据,并将其渲染到一个 OpenGL ES 纹理上; 4. 在 OpenGL ES 纹理上进行后续的图像处理。 以下是一个简单的示例代码: ```java // 打开相机 Camera camera = Camera.open(); // 设置相机参数 Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(width, height); camera.setParameters(parameters); // 创建一个 SurfaceTexture 对象 SurfaceTexture surfaceTexture = new SurfaceTexture(0); surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { // 获取最新的相机预览帧数据,并将其渲染到一个 OpenGL ES 纹理上 surfaceTexture.updateTexImage(); // 在 OpenGL ES 纹理上进行后续的图像处理 // ... } }); // 将 SurfaceTexture 设置为相机预览回调中的 Surface camera.setPreviewTexture(surfaceTexture); // 开始相机预览 camera.startPreview(); ``` 需要注意的是,在渲染相机预览数据之前,需要先创建一个 OpenGL ES 纹理,可以使用 GLES20 类中的 glGenTextures 方法来生成一个纹理 ID。在渲染时,可以使用 SurfaceTexture 的 getTransformMatrix 方法获取纹理坐标变换矩阵,以便正确地将相机预览数据渲染到纹理上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值