Java Code Examples for com.google.android.exoplayer2.ExoPlaybackException#createForRenderer()

The following examples show how to use com.google.android.exoplayer2.ExoPlaybackException#createForRenderer() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MediaCodecAudioRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
protected void renderToEndOfStream() throws ExoPlaybackException {
  try {
    audioSink.playToEndOfStream();
  } catch (AudioSink.WriteException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 2
Source File: MediaCodecRenderer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@TargetApi(23)
private void updateDrmSessionOrReinitializeCodecV23() throws ExoPlaybackException {
  FrameworkMediaCrypto sessionMediaCrypto = sourceDrmSession.getMediaCrypto();
  if (sessionMediaCrypto == null) {
    // We'd only expect this to happen if the CDM from which the pending session is obtained needs
    // provisioning. This is unlikely to happen (it probably requires a switch from one DRM scheme
    // to another, where the new CDM hasn't been used before and needs provisioning). It would be
    // possible to handle this case more efficiently (i.e. with a new renderer state that waits
    // for provisioning to finish and then calls mediaCrypto.setMediaDrmSession), but the extra
    // complexity is not warranted given how unlikely the case is to occur.
    reinitializeCodec();
    return;
  }
  if (C.PLAYREADY_UUID.equals(sessionMediaCrypto.uuid)) {
    // The PlayReady CDM does not implement setMediaDrmSession.
    // TODO: Add API check once [Internal ref: b/128835874] is fixed.
    reinitializeCodec();
    return;
  }

  if (flushOrReinitializeCodec()) {
    // The codec was reinitialized. The new codec will be using the new DRM session, so there's
    // nothing more to do.
    return;
  }

  try {
    mediaCrypto.setMediaDrmSession(sessionMediaCrypto.sessionId);
  } catch (MediaCryptoException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
  setCodecDrmSession(sourceDrmSession);
  codecDrainState = DRAIN_STATE_NONE;
  codecDrainAction = DRAIN_ACTION_NONE;
}
 
Example 3
Source File: SimpleDecoderAudioRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
  Format oldFormat = inputFormat;
  inputFormat = newFormat;

  boolean drmInitDataChanged = !Util.areEqual(inputFormat.drmInitData, oldFormat == null ? null
      : oldFormat.drmInitData);
  if (drmInitDataChanged) {
    if (inputFormat.drmInitData != null) {
      if (drmSessionManager == null) {
        throw ExoPlaybackException.createForRenderer(
            new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
      }
      pendingDrmSession = drmSessionManager.acquireSession(Looper.myLooper(),
          inputFormat.drmInitData);
      if (pendingDrmSession == drmSession) {
        drmSessionManager.releaseSession(pendingDrmSession);
      }
    } else {
      pendingDrmSession = null;
    }
  }

  if (decoderReceivedBuffers) {
    // Signal end of stream and wait for any final output buffers before re-initialization.
    decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
  } else {
    // There aren't any final output buffers, so release the decoder immediately.
    releaseDecoder();
    maybeInitDecoder();
    audioTrackNeedsConfigure = true;
  }

  encoderDelay = newFormat.encoderDelay;
  encoderPadding = newFormat.encoderPadding;

  eventDispatcher.inputFormatChanged(newFormat);
}
 
Example 4
Source File: SimpleDecoderAudioRenderer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private void maybeInitDecoder() throws ExoPlaybackException {
  if (decoder != null) {
    return;
  }

  setDecoderDrmSession(sourceDrmSession);

  ExoMediaCrypto mediaCrypto = null;
  if (decoderDrmSession != null) {
    mediaCrypto = decoderDrmSession.getMediaCrypto();
    if (mediaCrypto == null) {
      DrmSessionException drmError = decoderDrmSession.getError();
      if (drmError != null) {
        // Continue for now. We may be able to avoid failure if the session recovers, or if a new
        // input format causes the session to be replaced before it's used.
      } else {
        // The drm session isn't open yet.
        return;
      }
    }
  }

  try {
    long codecInitializingTimestamp = SystemClock.elapsedRealtime();
    TraceUtil.beginSection("createAudioDecoder");
    decoder = createDecoder(inputFormat, mediaCrypto);
    TraceUtil.endSection();
    long codecInitializedTimestamp = SystemClock.elapsedRealtime();
    eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
        codecInitializedTimestamp - codecInitializingTimestamp);
    decoderCounters.decoderInitCount++;
  } catch (AudioDecoderException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 5
Source File: SimpleDecoderAudioRenderer.java    From K-Sonic with MIT License 5 votes vote down vote up
private boolean shouldWaitForKeys(boolean bufferEncrypted) throws ExoPlaybackException {
  if (drmSession == null) {
    return false;
  }
  @DrmSession.State int drmSessionState = drmSession.getState();
  if (drmSessionState == DrmSession.STATE_ERROR) {
    throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
  }
  return drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS
      && (bufferEncrypted || !playClearSamplesWithoutKeys);
}
 
Example 6
Source File: SimpleDecoderAudioRenderer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
  Format oldFormat = inputFormat;
  inputFormat = newFormat;

  boolean drmInitDataChanged = !Util.areEqual(inputFormat.drmInitData, oldFormat == null ? null
      : oldFormat.drmInitData);
  if (drmInitDataChanged) {
    if (inputFormat.drmInitData != null) {
      if (drmSessionManager == null) {
        throw ExoPlaybackException.createForRenderer(
            new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
      }
      DrmSession<ExoMediaCrypto> session =
          drmSessionManager.acquireSession(Looper.myLooper(), newFormat.drmInitData);
      if (session == decoderDrmSession || session == sourceDrmSession) {
        // We already had this session. The manager must be reference counting, so release it once
        // to get the count attributed to this renderer back down to 1.
        drmSessionManager.releaseSession(session);
      }
      setSourceDrmSession(session);
    } else {
      setSourceDrmSession(null);
    }
  }

  if (decoderReceivedBuffers) {
    // Signal end of stream and wait for any final output buffers before re-initialization.
    decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
  } else {
    // There aren't any final output buffers, so release the decoder immediately.
    releaseDecoder();
    maybeInitDecoder();
    audioTrackNeedsConfigure = true;
  }

  encoderDelay = newFormat.encoderDelay;
  encoderPadding = newFormat.encoderPadding;

  eventDispatcher.inputFormatChanged(newFormat);
}
 
Example 7
Source File: SimpleDecoderAudioRenderer.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private boolean shouldWaitForKeys(boolean bufferEncrypted) throws ExoPlaybackException {
  if (decoderDrmSession == null || (!bufferEncrypted && playClearSamplesWithoutKeys)) {
    return false;
  }
  @DrmSession.State int drmSessionState = decoderDrmSession.getState();
  if (drmSessionState == DrmSession.STATE_ERROR) {
    throw ExoPlaybackException.createForRenderer(decoderDrmSession.getError(), getIndex());
  }
  return drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS;
}
 
Example 8
Source File: SimpleDecoderAudioRenderer.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private boolean shouldWaitForKeys(boolean bufferEncrypted) throws ExoPlaybackException {
  if (decoderDrmSession == null || (!bufferEncrypted && playClearSamplesWithoutKeys)) {
    return false;
  }
  @DrmSession.State int drmSessionState = decoderDrmSession.getState();
  if (drmSessionState == DrmSession.STATE_ERROR) {
    throw ExoPlaybackException.createForRenderer(decoderDrmSession.getError(), getIndex());
  }
  return drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS;
}
 
Example 9
Source File: MediaCodecRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public final int supportsFormat(Format format) throws ExoPlaybackException {
  try {
    return supportsFormat(mediaCodecSelector, drmSessionManager, format);
  } catch (DecoderQueryException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 10
Source File: MediaCodecAudioRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
protected boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs, MediaCodec codec,
    ByteBuffer buffer, int bufferIndex, int bufferFlags, long bufferPresentationTimeUs,
    boolean shouldSkip) throws ExoPlaybackException {
  if (passthroughEnabled && (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
    // Discard output buffers from the passthrough (raw) decoder containing codec specific data.
    codec.releaseOutputBuffer(bufferIndex, false);
    return true;
  }

  if (shouldSkip) {
    codec.releaseOutputBuffer(bufferIndex, false);
    decoderCounters.skippedOutputBufferCount++;
    audioSink.handleDiscontinuity();
    return true;
  }

  try {
    if (audioSink.handleBuffer(buffer, bufferPresentationTimeUs)) {
      codec.releaseOutputBuffer(bufferIndex, false);
      decoderCounters.renderedOutputBufferCount++;
      return true;
    }
  } catch (AudioSink.InitializationException | AudioSink.WriteException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
  return false;
}
 
Example 11
Source File: MediaCodecAudioRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
protected void onOutputFormatChanged(MediaCodec codec, MediaFormat outputFormat)
    throws ExoPlaybackException {
  @C.Encoding int encoding;
  MediaFormat format;
  if (passthroughMediaFormat != null) {
    encoding = MimeTypes.getEncoding(passthroughMediaFormat.getString(MediaFormat.KEY_MIME));
    format = passthroughMediaFormat;
  } else {
    encoding = pcmEncoding;
    format = outputFormat;
  }
  int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
  int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
  int[] channelMap;
  if (codecNeedsDiscardChannelsWorkaround && channelCount == 6 && this.channelCount < 6) {
    channelMap = new int[this.channelCount];
    for (int i = 0; i < this.channelCount; i++) {
      channelMap[i] = i;
    }
  } else {
    channelMap = null;
  }

  try {
    audioSink.configure(encoding, channelCount, sampleRate, 0, channelMap, encoderDelay,
        encoderPadding);
  } catch (AudioSink.ConfigurationException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 12
Source File: MediaCodecRenderer.java    From K-Sonic with MIT License 5 votes vote down vote up
private boolean shouldWaitForKeys(boolean bufferEncrypted) throws ExoPlaybackException {
  if (drmSession == null) {
    return false;
  }
  @DrmSession.State int drmSessionState = drmSession.getState();
  if (drmSessionState == DrmSession.STATE_ERROR) {
    throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
  }
  return drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS
      && (bufferEncrypted || !playClearSamplesWithoutKeys);
}
 
Example 13
Source File: SimpleDecoderAudioRenderer.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private void maybeInitDecoder() throws ExoPlaybackException {
  if (decoder != null) {
    return;
  }

  drmSession = pendingDrmSession;
  ExoMediaCrypto mediaCrypto = null;
  if (drmSession != null) {
    mediaCrypto = drmSession.getMediaCrypto();
    if (mediaCrypto == null) {
      DrmSessionException drmError = drmSession.getError();
      if (drmError != null) {
        // Continue for now. We may be able to avoid failure if the session recovers, or if a new
        // input format causes the session to be replaced before it's used.
      } else {
        // The drm session isn't open yet.
        return;
      }
    }
  }

  try {
    long codecInitializingTimestamp = SystemClock.elapsedRealtime();
    TraceUtil.beginSection("createAudioDecoder");
    decoder = createDecoder(inputFormat, mediaCrypto);
    TraceUtil.endSection();
    long codecInitializedTimestamp = SystemClock.elapsedRealtime();
    eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
        codecInitializedTimestamp - codecInitializingTimestamp);
    decoderCounters.decoderInitCount++;
  } catch (AudioDecoderException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 14
Source File: MediaCodecRenderer.java    From K-Sonic with MIT License 5 votes vote down vote up
/**
 * Called when a new format is read from the upstream {@link MediaPeriod}.
 *
 * @param newFormat The new format.
 * @throws ExoPlaybackException If an error occurs reinitializing the {@link MediaCodec}.
 */
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
  Format oldFormat = format;
  format = newFormat;

  boolean drmInitDataChanged = !Util.areEqual(format.drmInitData, oldFormat == null ? null
      : oldFormat.drmInitData);
  if (drmInitDataChanged) {
    if (format.drmInitData != null) {
      if (drmSessionManager == null) {
        throw ExoPlaybackException.createForRenderer(
            new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
      }
      pendingDrmSession = drmSessionManager.acquireSession(Looper.myLooper(), format.drmInitData);
      if (pendingDrmSession == drmSession) {
        drmSessionManager.releaseSession(pendingDrmSession);
      }
    } else {
      pendingDrmSession = null;
    }
  }

  if (pendingDrmSession == drmSession && codec != null
      && canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) {
    codecReconfigured = true;
    codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
    codecNeedsAdaptationWorkaroundBuffer = codecNeedsAdaptationWorkaround
        && format.width == oldFormat.width && format.height == oldFormat.height;
  } else {
    if (codecReceivedBuffers) {
      // Signal end of stream and wait for any final output buffers before re-initialization.
      codecReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM;
    } else {
      // There aren't any final output buffers, so perform re-initialization immediately.
      releaseCodec();
      maybeInitCodec();
    }
  }
}
 
Example 15
Source File: SimpleDecoderAudioRenderer.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private void maybeInitDecoder() throws ExoPlaybackException {
  if (decoder != null) {
    return;
  }

  setDecoderDrmSession(sourceDrmSession);

  ExoMediaCrypto mediaCrypto = null;
  if (decoderDrmSession != null) {
    mediaCrypto = decoderDrmSession.getMediaCrypto();
    if (mediaCrypto == null) {
      DrmSessionException drmError = decoderDrmSession.getError();
      if (drmError != null) {
        // Continue for now. We may be able to avoid failure if the session recovers, or if a new
        // input format causes the session to be replaced before it's used.
      } else {
        // The drm session isn't open yet.
        return;
      }
    }
  }

  try {
    long codecInitializingTimestamp = SystemClock.elapsedRealtime();
    TraceUtil.beginSection("createAudioDecoder");
    decoder = createDecoder(inputFormat, mediaCrypto);
    TraceUtil.endSection();
    long codecInitializedTimestamp = SystemClock.elapsedRealtime();
    eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
        codecInitializedTimestamp - codecInitializingTimestamp);
    decoderCounters.decoderInitCount++;
  } catch (AudioDecoderException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 16
Source File: MetadataRenderer.java    From K-Sonic with MIT License 5 votes vote down vote up
@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
  if (!inputStreamEnded && pendingMetadataCount < MAX_PENDING_METADATA_COUNT) {
    buffer.clear();
    int result = readSource(formatHolder, buffer, false);
    if (result == C.RESULT_BUFFER_READ) {
      if (buffer.isEndOfStream()) {
        inputStreamEnded = true;
      } else if (buffer.isDecodeOnly()) {
        // Do nothing. Note this assumes that all metadata buffers can be decoded independently.
        // If we ever need to support a metadata format where this is not the case, we'll need to
        // pass the buffer to the decoder and discard the output.
      } else {
        buffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
        buffer.flip();
        try {
          int index = (pendingMetadataIndex + pendingMetadataCount) % MAX_PENDING_METADATA_COUNT;
          pendingMetadata[index] = decoder.decode(buffer);
          pendingMetadataTimestamps[index] = buffer.timeUs;
          pendingMetadataCount++;
        } catch (MetadataDecoderException e) {
          throw ExoPlaybackException.createForRenderer(e, getIndex());
        }
      }
    }
  }

  if (pendingMetadataCount > 0 && pendingMetadataTimestamps[pendingMetadataIndex] <= positionUs) {
    invokeRenderer(pendingMetadata[pendingMetadataIndex]);
    pendingMetadata[pendingMetadataIndex] = null;
    pendingMetadataIndex = (pendingMetadataIndex + 1) % MAX_PENDING_METADATA_COUNT;
    pendingMetadataCount--;
  }
}
 
Example 17
Source File: MediaCodecAudioRenderer.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
@Override
protected boolean processOutputBuffer(
    long positionUs,
    long elapsedRealtimeUs,
    MediaCodec codec,
    ByteBuffer buffer,
    int bufferIndex,
    int bufferFlags,
    long bufferPresentationTimeUs,
    boolean isDecodeOnlyBuffer,
    boolean isLastBuffer,
    Format format)
    throws ExoPlaybackException {
  if (codecNeedsEosBufferTimestampWorkaround
      && bufferPresentationTimeUs == 0
      && (bufferFlags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0
      && lastInputTimeUs != C.TIME_UNSET) {
    bufferPresentationTimeUs = lastInputTimeUs;
  }

  if (passthroughEnabled && (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
    // Discard output buffers from the passthrough (raw) decoder containing codec specific data.
    codec.releaseOutputBuffer(bufferIndex, false);
    return true;
  }

  if (isDecodeOnlyBuffer) {
    codec.releaseOutputBuffer(bufferIndex, false);
    decoderCounters.skippedOutputBufferCount++;
    audioSink.handleDiscontinuity();
    return true;
  }

  try {
    if (audioSink.handleBuffer(buffer, bufferPresentationTimeUs)) {
      codec.releaseOutputBuffer(bufferIndex, false);
      decoderCounters.renderedOutputBufferCount++;
      return true;
    }
  } catch (AudioSink.InitializationException | AudioSink.WriteException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
  return false;
}
 
Example 18
Source File: MediaCodecRenderer.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Called when a new format is read from the upstream {@link MediaPeriod}.
 *
 * @param newFormat The new format.
 * @throws ExoPlaybackException If an error occurs reinitializing the {@link MediaCodec}.
 */
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
  Format oldFormat = format;
  format = newFormat;

  boolean drmInitDataChanged =
      !Util.areEqual(format.drmInitData, oldFormat == null ? null : oldFormat.drmInitData);
  if (drmInitDataChanged) {
    if (format.drmInitData != null) {
      if (drmSessionManager == null) {
        throw ExoPlaybackException.createForRenderer(
            new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
      }
      pendingDrmSession = drmSessionManager.acquireSession(Looper.myLooper(), format.drmInitData);
      if (pendingDrmSession == drmSession) {
        drmSessionManager.releaseSession(pendingDrmSession);
      }
    } else {
      pendingDrmSession = null;
    }
  }

  boolean keepingCodec = false;
  if (pendingDrmSession == drmSession && codec != null) {
    switch (canKeepCodec(codec, codecInfo, oldFormat, format)) {
      case KEEP_CODEC_RESULT_NO:
        // Do nothing.
        break;
      case KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION:
        keepingCodec = true;
        break;
      case KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION:
        keepingCodec = true;
        codecReconfigured = true;
        codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
        codecNeedsAdaptationWorkaroundBuffer =
            codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_ALWAYS
                || (codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION
                    && format.width == oldFormat.width
                    && format.height == oldFormat.height);
        break;
      default:
        throw new IllegalStateException(); // Never happens.
    }
  }

  if (!keepingCodec) {
    reinitializeCodec();
  } else {
    updateCodecOperatingRate();
  }
}
 
Example 19
Source File: MediaCodecRenderer.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Called when a new format is read from the upstream {@link MediaPeriod}.
 *
 * @param newFormat The new format.
 * @throws ExoPlaybackException If an error occurs re-initializing the {@link MediaCodec}.
 */
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
  Format oldFormat = inputFormat;
  inputFormat = newFormat;
  waitingForFirstSampleInFormat = true;

  boolean drmInitDataChanged =
      !Util.areEqual(newFormat.drmInitData, oldFormat == null ? null : oldFormat.drmInitData);
  if (drmInitDataChanged) {
    if (newFormat.drmInitData != null) {
      if (drmSessionManager == null) {
        throw ExoPlaybackException.createForRenderer(
            new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
      }
      DrmSession<FrameworkMediaCrypto> session =
          drmSessionManager.acquireSession(Looper.myLooper(), newFormat.drmInitData);
      if (session == sourceDrmSession || session == codecDrmSession) {
        // We already had this session. The manager must be reference counting, so release it once
        // to get the count attributed to this renderer back down to 1.
        drmSessionManager.releaseSession(session);
      }
      setSourceDrmSession(session);
    } else {
      setSourceDrmSession(null);
    }
  }

  if (codec == null) {
    maybeInitCodec();
    return;
  }

  // We have an existing codec that we may need to reconfigure or re-initialize. If the existing
  // codec instance is being kept then its operating rate may need to be updated.

  if ((sourceDrmSession == null && codecDrmSession != null)
      || (sourceDrmSession != null && codecDrmSession == null)
      || (sourceDrmSession != null && !codecInfo.secure)
      || (Util.SDK_INT < 23 && sourceDrmSession != codecDrmSession)) {
    // We might need to switch between the clear and protected output paths, or we're using DRM
    // prior to API level 23 where the codec needs to be re-initialized to switch to the new DRM
    // session.
    drainAndReinitializeCodec();
    return;
  }

  switch (canKeepCodec(codec, codecInfo, codecFormat, newFormat)) {
    case KEEP_CODEC_RESULT_NO:
      drainAndReinitializeCodec();
      break;
    case KEEP_CODEC_RESULT_YES_WITH_FLUSH:
      codecFormat = newFormat;
      updateCodecOperatingRate();
      if (sourceDrmSession != codecDrmSession) {
        drainAndUpdateCodecDrmSession();
      } else {
        drainAndFlushCodec();
      }
      break;
    case KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION:
      if (codecNeedsReconfigureWorkaround) {
        drainAndReinitializeCodec();
      } else {
        codecReconfigured = true;
        codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
        codecNeedsAdaptationWorkaroundBuffer =
            codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_ALWAYS
                || (codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION
                    && newFormat.width == codecFormat.width
                    && newFormat.height == codecFormat.height);
        codecFormat = newFormat;
        updateCodecOperatingRate();
        if (sourceDrmSession != codecDrmSession) {
          drainAndUpdateCodecDrmSession();
        }
      }
      break;
    case KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION:
      codecFormat = newFormat;
      updateCodecOperatingRate();
      if (sourceDrmSession != codecDrmSession) {
        drainAndUpdateCodecDrmSession();
      }
      break;
    default:
      throw new IllegalStateException(); // Never happens.
  }
}
 
Example 20
Source File: MediaCodecRenderer.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
protected final void maybeInitCodec() throws ExoPlaybackException {
  if (codec != null || format == null) {
    // We have a codec already, or we don't have a format with which to instantiate one.
    return;
  }

  drmSession = pendingDrmSession;
  String mimeType = format.sampleMimeType;
  MediaCrypto wrappedMediaCrypto = null;
  boolean drmSessionRequiresSecureDecoder = false;
  if (drmSession != null) {
    FrameworkMediaCrypto mediaCrypto = drmSession.getMediaCrypto();
    if (mediaCrypto == null) {
      DrmSessionException drmError = drmSession.getError();
      if (drmError != null) {
        // Continue for now. We may be able to avoid failure if the session recovers, or if a new
        // input format causes the session to be replaced before it's used.
      } else {
        // The drm session isn't open yet.
        return;
      }
    } else {
      wrappedMediaCrypto = mediaCrypto.getWrappedMediaCrypto();
      drmSessionRequiresSecureDecoder = mediaCrypto.requiresSecureDecoderComponent(mimeType);
    }
    if (deviceNeedsDrmKeysToConfigureCodecWorkaround()) {
      @DrmSession.State int drmSessionState = drmSession.getState();
      if (drmSessionState == DrmSession.STATE_ERROR) {
        throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
      } else if (drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS) {
        // Wait for keys.
        return;
      }
    }
  }

  try {
    if (!initCodecWithFallback(wrappedMediaCrypto, drmSessionRequiresSecureDecoder)) {
      // We can't initialize a codec yet.
      return;
    }
  } catch (DecoderInitializationException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }

  String codecName = codecInfo.name;
  codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
  codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, format);
  codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
  codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecInfo);
  codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
  codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
  codecNeedsMonoChannelCountWorkaround = codecNeedsMonoChannelCountWorkaround(codecName, format);
  codecHotswapDeadlineMs =
      getState() == STATE_STARTED
          ? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
          : C.TIME_UNSET;
  resetInputBuffer();
  resetOutputBuffer();
  waitingForFirstSyncFrame = true;
  decoderCounters.decoderInitCount++;
}