EGL共享上下文和多个编解码器输入表面:相机预览旋转和缩放

时间:2015-08-11 13:19:33

标签: android opengl-es mediacodec

我正在使用GL part of LibStreaming,我修改了它的一部分,以便能够附加多个编解码器输入表面。我基本上只是修改了addMediaCodecInputSurface,removeMediaCodecInputSurface并运行了SurfaceView类的函数。

public SurfaceManager addMediaCodecSurface(Surface surface, FrameReadyI frameReadyCallback) {
    SurfaceManager mSurfaceManager = new SurfaceManager(surface, mViewSurfaceManager);
    mCodecSurfaceManager.add(mSurfaceManager);
    frameReadyCallbackList.add(frameReadyCallback);
    return mSurfaceManager;
}


@Override
public void run() {

    mViewSurfaceManager = new SurfaceManager(getHolder().getSurface());
    mViewSurfaceManager.makeCurrent();
    mTextureManager.createTexture().setOnFrameAvailableListener(this);

    mLock.release();

    try {
      while (mRunning) {
        synchronized (mSyncObject) {
          mSyncObject.wait(20);
          if (mFrameAvailable) {
            mFrameAvailable = false;

            mViewSurfaceManager.makeCurrent();
            mTextureManager.updateFrame();
            mTextureManager.drawFrame();
            mViewSurfaceManager.swapBuffer();

              if (mCodecSurfaceManager.size() > 0) {
                for (int idx = 0; idx < mCodecSurfaceManager.size(); idx++) {
                  try {
                    mCodecSurfaceManager.get(idx).makeCurrent();
                    mTextureManager.drawFrame();
                    mCodecSurfaceManager.get(idx).setPresentationTime(ts);
                    mCodecSurfaceManager.get(idx).swapBuffer();
                    /* the next time I call  ViewSurfaceManager.makeCurrent(); the preview image will be garbled */
                    this.frameReadyCallbackList.get(idx).OnFrameReady(ts);
                  } catch (Exception ignore) {  }
                }
              }
          }
        }
      }
    } catch (InterruptedException ignore) {
    } finally {
      mViewSurfaceManager.release();
      mTextureManager.release();
    }

}

此代码在大多数设备上都能正常运行。 preview how it looks on most devices

然而,在Galaxy S6上,只要其中一个编解码器输入表面处于当前状态,相机预览就会旋转并缩小。我附上一张图片来澄清会发生什么。 preview after media codec input surface has been made current

只要我不在那些表面上绘图,预览工作就完美了。 我查看了GL轨迹并注意到,在绘制到输入表面后,glUniformMatrix4fv矩阵会被修改,但我不知道如何处理这些信息。

更新1:

我进一步追查了这一点。当我开始相机预览时,我创建了一个上下文(上下文0),其中相机预览被绘制到我的预览表面上。然后,当我添加编解码器输入表面时,会为每个表面创建一个新的上下文。现在出现问题:我添加,比方说,2个编解码器输入表面(上下文2和3)。在GL跟踪中,我可以清楚地识别这些,并查看每个drawFrame()调用的转换矩阵。但是创建了一个额外的上下文(galaxy_s6.gltrace中的上下文1),它似乎也绘制到预览表面上,并且方法跟踪显示调用与所有其他上下文不同。所有其他上下文以相同的顺序调用相同的方法,而不是这个。为了看看这是否只发生在Galaxy S6上,我还在Nexus 9上进行了追踪。事实证明,在两台设备上都创建了第三个上下文,但是相机预览在Nexus 9上完美运行(实际上在所有其他设备上)我测试了)。我添加了跟踪,以防万一有人想看看它们。

Galaxy S6 GL trace

Nexus 9 GL trace

更新2:

我发现上下文1实际上是绘制应用程序的所有UI元素的上下文。然而,我很难找出导致旋转和缩小相机预览的原因。我应该指出录制的视频既不会旋转也不会缩放,只是预览会搞砸了。

0 个答案:

没有答案