docs: private void handleFrameAvailable(SurfaceTexture surfaceTexture) {
          if (TRACE) Trace.beginSection("handleFrameAvail");
          synchronized (mReadyForFrameFence) {
              if (!mReadyForFrames) {
                  if (VERBOSE) Log.i(TAG, "Ignoring available frame, not ready");
                  return;
              }
              mFrameNum++;
              if (VERBOSE && (mFrameNum % 30 == 0)) Log.i(TAG, "handleFrameAvailable");
              if (!surfaceTexture.equals(mSurfaceTexture))
                  Log.w(TAG, "SurfaceTexture from OnFrameAvailable does not match saved SurfaceTexture!");
  
              if (mRecording) {
                  mInputWindowSurface.makeCurrent();
                  if (TRACE) Trace.beginSection("drainVEncoder");
                  mVideoEncoder.drainEncoder(false);
                  if (TRACE) Trace.endSection();
                  if (mCurrentFilter != mNewFilter) {
                      Filters.updateFilter(mFullScreen, mNewFilter);
                      mCurrentFilter = mNewFilter;
                      mIncomingSizeUpdated = true;
                  }
  
                  if (mIncomingSizeUpdated) {
                      mFullScreen.getProgram().setTexSize(mSessionConfig.getVideoWidth(), mSessionConfig.getVideoHeight());
                      mIncomingSizeUpdated = false;
                  }
  
                  surfaceTexture.getTransformMatrix(mTransform);
                  if (TRACE) Trace.beginSection("drawVEncoderFrame");
                  mFullScreen.drawFrame(mTextureId, mTransform);
                  if (TRACE) Trace.endSection();
                  if (!mEncodedFirstFrame) {
                      mEncodedFirstFrame = true;
                  }
  
                  if (mThumbnailRequestedOnFrame == mFrameNum) {
                      mThumbnailRequested = true;
                  }
                  if (mThumbnailRequested) {
                      saveFrameAsImage();
                      mThumbnailRequested = false;
                  }
  
                  mInputWindowSurface.setPresentationTime(mSurfaceTexture.getTimestamp());
                  mInputWindowSurface.swapBuffers();
  
                  if (mEosRequested) {
                      /*if (VERBOSE) */
                      Log.i(TAG, "Sending last video frame. Draining encoder");
                      mVideoEncoder.signalEndOfStream();
                      mVideoEncoder.drainEncoder(true);
                      mRecording = false;
                      mEosRequested = false;
                      releaseEncoder();
                      mState = STATE.UNINITIALIZED;
                      synchronized (mStopFence) {
                          mStopFence.notify();
                      }
                  }
              }
          }
  
          // Signal GLSurfaceView to render
          mDisplayView.requestRender();
  
          if (TRACE) Trace.endSection();
      }