5858import androidx .media3 .common .PlaybackException ;
5959import androidx .media3 .common .Player ;
6060import androidx .media3 .common .VideoFrameProcessingException ;
61+ import androidx .media3 .common .VideoGraph ;
6162import androidx .media3 .common .util .ConditionVariable ;
6263import androidx .media3 .common .util .GlProgram ;
6364import androidx .media3 .common .util .GlUtil ;
6465import androidx .media3 .common .util .NullableType ;
6566import androidx .media3 .common .util .UnstableApi ;
6667import androidx .media3 .common .util .Util ;
68+ import androidx .media3 .effect .DefaultGlObjectsProvider ;
69+ import androidx .media3 .effect .DefaultVideoFrameProcessor ;
6770import androidx .media3 .effect .GlEffect ;
6871import androidx .media3 .effect .GlShaderProgram ;
6972import androidx .media3 .effect .MatrixTransformation ;
7073import androidx .media3 .effect .PassthroughShaderProgram ;
7174import androidx .media3 .effect .RgbMatrix ;
7275import androidx .media3 .effect .ScaleAndRotateTransformation ;
76+ import androidx .media3 .effect .SingleInputVideoGraph ;
7377import androidx .media3 .exoplayer .DecoderCounters ;
7478import androidx .media3 .exoplayer .DecoderReuseEvaluation ;
7579import androidx .media3 .exoplayer .ExoPlaybackException ;
8387import androidx .media3 .exoplayer .source .DefaultMediaSourceFactory ;
8488import androidx .media3 .exoplayer .source .MediaSource ;
8589import androidx .media3 .exoplayer .video .MediaCodecVideoRenderer ;
90+ import androidx .media3 .exoplayer .video .PlaybackVideoGraphWrapper ;
91+ import androidx .media3 .exoplayer .video .VideoFrameReleaseControl ;
8692import androidx .media3 .exoplayer .video .VideoRendererEventListener ;
8793import androidx .media3 .extractor .DefaultExtractorsFactory ;
8894import com .google .common .collect .ImmutableList ;
@@ -135,6 +141,7 @@ public static final class Builder {
135141 private SeekParameters seekParameters ;
136142 private MediaCodecSelector mediaCodecSelector ;
137143 private boolean extractHdrFrames ;
144+ @ Nullable private GlObjectsProvider glObjectsProvider ;
138145
139146 /** Creates a new instance with default values. */
140147 public Builder () {
@@ -196,9 +203,24 @@ public Builder setExtractHdrFrames(boolean extractHdrFrames) {
196203 return this ;
197204 }
198205
206+ /**
207+ * Sets the {@link GlObjectsProvider} to be used by the effect processing pipeline.
208+ *
209+ * <p>By default, a {@link DefaultGlObjectsProvider} is used.
210+ *
211+ * @param glObjectsProvider The {@link GlObjectsProvider}.
212+ * @return This builder.
213+ */
214+ @ CanIgnoreReturnValue
215+ public Builder setGlObjectsProvider (GlObjectsProvider glObjectsProvider ) {
216+ this .glObjectsProvider = glObjectsProvider ;
217+ return this ;
218+ }
219+
199220 /** Builds a new {@link Configuration} instance. */
200221 public Configuration build () {
201- return new Configuration (seekParameters , mediaCodecSelector , extractHdrFrames );
222+ return new Configuration (
223+ seekParameters , mediaCodecSelector , extractHdrFrames , glObjectsProvider );
202224 }
203225 }
204226
@@ -211,13 +233,18 @@ public Configuration build() {
211233 /** Whether extracting HDR frames is requested. */
212234 public final boolean extractHdrFrames ;
213235
236+ /** The {@link GlObjectsProvider}. */
237+ @ Nullable public final GlObjectsProvider glObjectsProvider ;
238+
214239 private Configuration (
215240 SeekParameters seekParameters ,
216241 MediaCodecSelector mediaCodecSelector ,
217- boolean extractHdrFrames ) {
242+ boolean extractHdrFrames ,
243+ @ Nullable GlObjectsProvider glObjectsProvider ) {
218244 this .seekParameters = seekParameters ;
219245 this .mediaCodecSelector = mediaCodecSelector ;
220246 this .extractHdrFrames = extractHdrFrames ;
247+ this .glObjectsProvider = glObjectsProvider ;
221248 }
222249 }
223250
@@ -294,7 +321,8 @@ public ExperimentalFrameExtractor(Context context, Configuration configuration)
294321 context ,
295322 configuration .mediaCodecSelector ,
296323 videoRendererEventListener ,
297- /* toneMapHdrToSdr= */ !configuration .extractHdrFrames )
324+ /* toneMapHdrToSdr= */ !configuration .extractHdrFrames ,
325+ configuration .glObjectsProvider )
298326 },
299327 mediaSourceFactory )
300328 .setSeekParameters (configuration .seekParameters )
@@ -650,6 +678,7 @@ private void ensureConfigured(GlObjectsProvider glObjectsProvider, int width, in
650678 /** A custom MediaCodecVideoRenderer that renders only one frame per position reset. */
651679 private final class FrameExtractorRenderer extends MediaCodecVideoRenderer {
652680 private final boolean toneMapHdrToSdr ;
681+ @ Nullable private final GlObjectsProvider glObjectsProvider ;
653682
654683 private boolean frameRenderedSinceLastPositionReset ;
655684 private List <Effect > effectsFromPlayer ;
@@ -659,7 +688,8 @@ public FrameExtractorRenderer(
659688 Context context ,
660689 MediaCodecSelector mediaCodecSelector ,
661690 VideoRendererEventListener videoRendererEventListener ,
662- boolean toneMapHdrToSdr ) {
691+ boolean toneMapHdrToSdr ,
692+ @ Nullable GlObjectsProvider glObjectsProvider ) {
663693 super (
664694 new Builder (context )
665695 .setMediaCodecSelector (mediaCodecSelector )
@@ -668,9 +698,27 @@ public FrameExtractorRenderer(
668698 .setEventListener (videoRendererEventListener )
669699 .setMaxDroppedFramesToNotify (0 ));
670700 this .toneMapHdrToSdr = toneMapHdrToSdr ;
701+ this .glObjectsProvider = glObjectsProvider ;
671702 effectsFromPlayer = ImmutableList .of ();
672703 }
673704
705+ @ Override
706+ protected PlaybackVideoGraphWrapper createPlaybackVideoGraphWrapper (
707+ Context context , VideoFrameReleaseControl videoFrameReleaseControl ) {
708+ if (glObjectsProvider == null ) {
709+ return super .createPlaybackVideoGraphWrapper (context , videoFrameReleaseControl );
710+ }
711+ DefaultVideoFrameProcessor .Factory .Builder videoFrameProcessorFactoryBuilder =
712+ new DefaultVideoFrameProcessor .Factory .Builder ().setGlObjectsProvider (glObjectsProvider );
713+ VideoGraph .Factory videoGraphFactory =
714+ new SingleInputVideoGraph .Factory (videoFrameProcessorFactoryBuilder .build ());
715+ return new PlaybackVideoGraphWrapper .Builder (context , videoFrameReleaseControl )
716+ .setEnablePlaylistMode (true )
717+ .setClock (getClock ())
718+ .setVideoGraphFactory (videoGraphFactory )
719+ .build ();
720+ }
721+
674722 @ Override
675723 protected void onStreamChanged (
676724 Format [] formats ,
0 commit comments