/*
 * Copyright 2020 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 com.google.android.exoplayer2.transformer;

import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;

import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.source.SampleStream.ReadDataResult;

@RequiresApi(18)
/* package */ final class TransformerAudioRenderer extends TransformerBaseRenderer {

  private static final String TAG = "TransformerAudioRenderer";

  private final DecoderInputBuffer decoderInputBuffer;

  public TransformerAudioRenderer(
      MuxerWrapper muxerWrapper, TransformerMediaClock mediaClock, Transformation transformation) {
    super(C.TRACK_TYPE_AUDIO, muxerWrapper, mediaClock, transformation);
    decoderInputBuffer =
        new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
  }

  @Override
  public String getName() {
    return TAG;
  }

  /** Attempts to read the input format and to initialize the {@link SamplePipeline}. */
  @Override
  protected boolean ensureConfigured() throws ExoPlaybackException {
    if (samplePipeline != null) {
      return true;
    }
    FormatHolder formatHolder = getFormatHolder();
    @ReadDataResult
    int result = readSource(formatHolder, decoderInputBuffer, /* readFlags= */ FLAG_REQUIRE_FORMAT);
    if (result != C.RESULT_FORMAT_READ) {
      return false;
    }
    Format inputFormat = checkNotNull(formatHolder.format);
    if ((transformation.audioMimeType != null
            && !transformation.audioMimeType.equals(inputFormat.sampleMimeType))
        || transformation.flattenForSlowMotion) {
      samplePipeline = new AudioSamplePipeline(inputFormat, transformation, getIndex());
    } else {
      samplePipeline = new PassthroughSamplePipeline(inputFormat);
    }
    return true;
  }
}

@@ -822,16 +822,53 @@
 tNull;%0A%0A
+import androidx.annotation.Nullable;%0A
 import a
@@ -1155,24 +1155,146 @@
 nputBuffer;%0A
+import com.google.android.exoplayer2.metadata.Metadata;%0Aimport com.google.android.exoplayer2.metadata.mp4.SlowMotionData;%0A
 import com.g
@@ -2500,13 +2500,47 @@
     
-if ((
+boolean shouldChangeMimeType =%0A        
 tran
@@ -2655,20 +2655,58 @@
 ype)
-)
+;
 %0A    
+boolean shouldFlattenForSlowMotion =%0A
     
-%7C%7C
+   
  tra
@@ -2733,24 +2733,113 @@
 orSlowMotion
+ && isSlowMotion(inputFormat);%0A    if (shouldChangeMimeType %7C%7C shouldFlattenForSlowMotion
 ) %7B%0A      sa
@@ -3025,11 +3025,334 @@
 rue;%0A  %7D
+%0A%0A  private static boolean isSlowMotion(Format format) %7B%0A    @Nullable Metadata metadata = format.metadata;%0A    if (metadata == null) %7B%0A      return false;%0A    %7D%0A    for (int i = 0; i %3C metadata.length(); i++) %7B%0A      if (metadata.get(i) instanceof SlowMotionData) %7B%0A        return true;%0A      %7D%0A    %7D%0A    return false;%0A  %7D
 %0A%7D%0A

Use audio passthrough if flattening is requested but not needed.