1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.exoplayer2.transformer; 18 19 import static com.google.android.exoplayer2.util.Assertions.checkState; 20 21 import com.google.android.exoplayer2.C; 22 import com.google.android.exoplayer2.MediaItem; 23 import com.google.android.exoplayer2.util.ListenerSet; 24 import com.google.android.exoplayer2.util.Util; 25 26 /** 27 * Listener for fallback {@link TransformationRequest TransformationRequests} from the audio and 28 * video renderers. 29 */ 30 /* package */ final class FallbackListener { 31 32 private final MediaItem mediaItem; 33 private final TransformationRequest originalTransformationRequest; 34 private final ListenerSet<Transformer.Listener> transformerListeners; 35 36 private TransformationRequest fallbackTransformationRequest; 37 private int trackCount; 38 39 /** 40 * Creates a new instance. 41 * 42 * @param mediaItem The {@link MediaItem} to transform. 43 * @param transformerListeners The {@linkplain Transformer.Listener listeners} to forward events 44 * to. 45 * @param originalTransformationRequest The original {@link TransformationRequest}. 46 */ FallbackListener( MediaItem mediaItem, ListenerSet<Transformer.Listener> transformerListeners, TransformationRequest originalTransformationRequest)47 public FallbackListener( 48 MediaItem mediaItem, 49 ListenerSet<Transformer.Listener> transformerListeners, 50 TransformationRequest originalTransformationRequest) { 51 this.mediaItem = mediaItem; 52 this.transformerListeners = transformerListeners; 53 this.originalTransformationRequest = originalTransformationRequest; 54 this.fallbackTransformationRequest = originalTransformationRequest; 55 } 56 57 /** 58 * Registers an output track. 59 * 60 * <p>All tracks must be registered before a transformation request is {@linkplain 61 * #onTransformationRequestFinalized(TransformationRequest) finalized}. 62 */ registerTrack()63 public void registerTrack() { 64 trackCount++; 65 } 66 67 /** 68 * Updates the fallback {@link TransformationRequest}. 69 * 70 * <p>Should be called with the final {@link TransformationRequest} for each track after all 71 * fallback has been applied. Calls {@link Transformer.Listener#onFallbackApplied(MediaItem, 72 * TransformationRequest, TransformationRequest)} once this method has been called for each track. 73 * 74 * @param transformationRequest The final {@link TransformationRequest} for a track. 75 * @throws IllegalStateException If called for more tracks than registered using {@link 76 * #registerTrack()}. 77 */ onTransformationRequestFinalized(TransformationRequest transformationRequest)78 public void onTransformationRequestFinalized(TransformationRequest transformationRequest) { 79 checkState(trackCount-- > 0); 80 81 TransformationRequest.Builder fallbackRequestBuilder = 82 fallbackTransformationRequest.buildUpon(); 83 if (!Util.areEqual( 84 transformationRequest.audioMimeType, originalTransformationRequest.audioMimeType)) { 85 fallbackRequestBuilder.setAudioMimeType(transformationRequest.audioMimeType); 86 } 87 if (!Util.areEqual( 88 transformationRequest.videoMimeType, originalTransformationRequest.videoMimeType)) { 89 fallbackRequestBuilder.setVideoMimeType(transformationRequest.videoMimeType); 90 } 91 if (transformationRequest.outputHeight != originalTransformationRequest.outputHeight) { 92 fallbackRequestBuilder.setResolution(transformationRequest.outputHeight); 93 } 94 fallbackTransformationRequest = fallbackRequestBuilder.build(); 95 96 if (trackCount == 0 && !originalTransformationRequest.equals(fallbackTransformationRequest)) { 97 transformerListeners.queueEvent( 98 /* eventFlag= */ C.INDEX_UNSET, 99 listener -> 100 listener.onFallbackApplied( 101 mediaItem, originalTransformationRequest, fallbackTransformationRequest)); 102 transformerListeners.flushEvents(); 103 } 104 } 105 } 106