public class

PassthroughShaderProgram

extends java.lang.Object

implements GlShaderProgram

 java.lang.Object

↳androidx.media3.effect.PassthroughShaderProgram

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-effect', version: '1.5.0-alpha01'

  • groupId: androidx.media3
  • artifactId: media3-effect
  • version: 1.5.0-alpha01

Artifact androidx.media3:media3-effect:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

A GlShaderProgram that passes a frame from the input to the output listener without copying.

This shader program can only process one input frame at a time.

Summary

Constructors
publicPassthroughShaderProgram()

Methods
public voidflush()

protected final GlShaderProgram.InputListenergetInputListener()

protected final voidonError(java.lang.Exception e)

public voidqueueInputFrame(GlObjectsProvider glObjectsProvider, GlTextureInfo inputTexture, long presentationTimeUs)

public voidrelease()

public voidreleaseOutputFrame(GlTextureInfo outputTexture)

public voidsetErrorListener(java.util.concurrent.Executor executor, GlShaderProgram.ErrorListener errorListener)

public voidsetInputListener(GlShaderProgram.InputListener inputListener)

public voidsetOutputListener(GlShaderProgram.OutputListener outputListener)

public voidsignalEndOfCurrentInputStream()

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public PassthroughShaderProgram()

Methods

public void setInputListener(GlShaderProgram.InputListener inputListener)

public void setOutputListener(GlShaderProgram.OutputListener outputListener)

public void setErrorListener(java.util.concurrent.Executor executor, GlShaderProgram.ErrorListener errorListener)

public void queueInputFrame(GlObjectsProvider glObjectsProvider, GlTextureInfo inputTexture, long presentationTimeUs)

public void releaseOutputFrame(GlTextureInfo outputTexture)

public void signalEndOfCurrentInputStream()

public void flush()

public void release()

protected final GlShaderProgram.InputListener getInputListener()

protected final void onError(java.lang.Exception e)

Source

/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.effect;

import static androidx.media3.common.util.Assertions.checkState;

import androidx.media3.common.C;
import androidx.media3.common.GlObjectsProvider;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
import androidx.media3.common.util.UnstableApi;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.Executor;

/**
 * A {@linkplain GlShaderProgram} that passes a frame from the input to the output listener without
 * copying.
 *
 * <p>This shader program can only process one input frame at a time.
 */
@UnstableApi
public class PassthroughShaderProgram implements GlShaderProgram {

  private InputListener inputListener;
  private OutputListener outputListener;
  private ErrorListener errorListener;
  private Executor errorListenerExecutor;
  private int texIdInUse;

  public PassthroughShaderProgram() {
    inputListener = new InputListener() {};
    outputListener = new OutputListener() {};
    errorListener = (frameProcessingException) -> {};
    errorListenerExecutor = MoreExecutors.directExecutor();
    texIdInUse = C.INDEX_UNSET;
  }

  @Override
  public void setInputListener(InputListener inputListener) {
    this.inputListener = inputListener;
    if (texIdInUse == C.INDEX_UNSET) {
      inputListener.onReadyToAcceptInputFrame();
    }
  }

  @Override
  public void setOutputListener(OutputListener outputListener) {
    this.outputListener = outputListener;
  }

  @Override
  public void setErrorListener(Executor executor, ErrorListener errorListener) {
    this.errorListenerExecutor = executor;
    this.errorListener = errorListener;
  }

  @Override
  public void queueInputFrame(
      GlObjectsProvider glObjectsProvider, GlTextureInfo inputTexture, long presentationTimeUs) {
    texIdInUse = inputTexture.texId;
    outputListener.onOutputFrameAvailable(inputTexture, presentationTimeUs);
  }

  @Override
  public void releaseOutputFrame(GlTextureInfo outputTexture) {
    checkState(outputTexture.texId == texIdInUse);
    texIdInUse = C.INDEX_UNSET;
    inputListener.onInputFrameProcessed(outputTexture);
    inputListener.onReadyToAcceptInputFrame();
  }

  @Override
  public void signalEndOfCurrentInputStream() {
    outputListener.onCurrentOutputStreamEnded();
  }

  @Override
  public void flush() {
    texIdInUse = C.INDEX_UNSET;
    inputListener.onFlush();
    inputListener.onReadyToAcceptInputFrame();
  }

  @Override
  public void release() throws VideoFrameProcessingException {
    texIdInUse = C.INDEX_UNSET;
  }

  protected final InputListener getInputListener() {
    return inputListener;
  }

  protected final void onError(Exception e) {
    errorListenerExecutor.execute(
        () -> errorListener.onError(VideoFrameProcessingException.from(e)));
  }
}