com.google.android.exoplayer2.util.Log Java Examples

The following examples show how to use com.google.android.exoplayer2.util.Log. 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: SimpleCache.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
@Override
public synchronized void release() {
  if (released) {
    return;
  }
  listeners.clear();
  removeStaleSpans();
  try {
    contentIndex.store();
  } catch (IOException e) {
    Log.e(TAG, "Storing index file failed", e);
  } finally {
    unlockFolder(cacheDir);
    released = true;
  }
}
 
Example #2
Source File: CacheDataSink.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * @param cache The cache into which data should be written.
 * @param fragmentSize For requests that should be fragmented into multiple cache files, this is
 *     the maximum size of a cache file in bytes. If set to {@link C#LENGTH_UNSET} then no
 *     fragmentation will occur. Using a small value allows for finer-grained cache eviction
 *     policies, at the cost of increased overhead both on the cache implementation and the file
 *     system. Values under {@code (2 * 1024 * 1024)} are not recommended.
 * @param bufferSize The buffer size in bytes for writing to a cache file. A zero or negative
 *     value disables buffering.
 */
public CacheDataSink(Cache cache, long fragmentSize, int bufferSize) {
  Assertions.checkState(
      fragmentSize > 0 || fragmentSize == C.LENGTH_UNSET,
      "fragmentSize must be positive or C.LENGTH_UNSET.");
  if (fragmentSize != C.LENGTH_UNSET && fragmentSize < MIN_RECOMMENDED_FRAGMENT_SIZE) {
    Log.w(
        TAG,
        "fragmentSize is below the minimum recommended value of "
            + MIN_RECOMMENDED_FRAGMENT_SIZE
            + ". This may cause poor cache performance.");
  }
  this.cache = Assertions.checkNotNull(cache);
  this.fragmentSize = fragmentSize == C.LENGTH_UNSET ? Long.MAX_VALUE : fragmentSize;
  this.bufferSize = bufferSize;
}
 
Example #3
Source File: SimpleCache.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Loads the cache UID from the files belonging to the root directory.
 *
 * @param files The files belonging to the root directory.
 * @return The loaded UID, or {@link #UID_UNSET} if a UID has not yet been created.
 * @throws IOException If there is an error loading or generating the UID.
 */
private static long loadUid(File[] files) {
  for (File file : files) {
    String fileName = file.getName();
    if (fileName.endsWith(UID_FILE_SUFFIX)) {
      try {
        return parseUid(fileName);
      } catch (NumberFormatException e) {
        // This should never happen, but if it does delete the malformed UID file and continue.
        Log.e(TAG, "Malformed UID file: " + file);
        file.delete();
      }
    }
  }
  return UID_UNSET;
}
 
Example #4
Source File: WebvttCueParser.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private static Alignment parseTextAlignment(String s) {
  switch (s) {
    case "start":
    case "left":
      return Alignment.ALIGN_NORMAL;
    case "center":
    case "middle":
      return Alignment.ALIGN_CENTER;
    case "end":
    case "right":
      return Alignment.ALIGN_OPPOSITE;
    default:
      Log.w(TAG, "Invalid alignment value: " + s);
      return null;
  }
}
 
Example #5
Source File: DownloadManager.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private void release() {
  for (Task task : activeTasks.values()) {
    task.cancel(/* released= */ true);
  }
  try {
    downloadIndex.setDownloadingStatesToQueued();
  } catch (IOException e) {
    Log.e(TAG, "Failed to update index.", e);
  }
  downloads.clear();
  thread.quit();
  synchronized (this) {
    released = true;
    notifyAll();
  }
}
 
Example #6
Source File: SimpleCache.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
@Override
public synchronized void release() {
  if (released) {
    return;
  }
  listeners.clear();
  removeStaleSpans();
  try {
    contentIndex.store();
  } catch (IOException e) {
    Log.e(TAG, "Storing index file failed", e);
  } finally {
    unlockFolder(cacheDir);
    released = true;
  }
}
 
Example #7
Source File: DashManifestParser.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
protected static int parseCea608AccessibilityChannel(
    List<Descriptor> accessibilityDescriptors) {
  for (int i = 0; i < accessibilityDescriptors.size(); i++) {
    Descriptor descriptor = accessibilityDescriptors.get(i);
    if ("urn:scte:dash:cc:cea-608:2015".equals(descriptor.schemeIdUri)
        && descriptor.value != null) {
      Matcher accessibilityValueMatcher = CEA_608_ACCESSIBILITY_PATTERN.matcher(descriptor.value);
      if (accessibilityValueMatcher.matches()) {
        return Integer.parseInt(accessibilityValueMatcher.group(1));
      } else {
        Log.w(TAG, "Unable to parse CEA-608 channel number from: " + descriptor.value);
      }
    }
  }
  return Format.NO_VALUE;
}
 
Example #8
Source File: MetadataUtil.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
@Nullable
private static ApicFrame parseCoverArt(ParsableByteArray data) {
  int atomSize = data.readInt();
  int atomType = data.readInt();
  if (atomType == Atom.TYPE_data) {
    int fullVersionInt = data.readInt();
    int flags = Atom.parseFullAtomFlags(fullVersionInt);
    String mimeType = flags == 13 ? "image/jpeg" : flags == 14 ? "image/png" : null;
    if (mimeType == null) {
      Log.w(TAG, "Unrecognized cover art flags: " + flags);
      return null;
    }
    data.skipBytes(4); // empty (4)
    byte[] pictureData = new byte[atomSize - 16];
    data.readBytes(pictureData, 0, pictureData.length);
    return new ApicFrame(
        mimeType,
        /* description= */ null,
        /* pictureType= */ PICTURE_TYPE_FRONT_COVER,
        pictureData);
  }
  Log.w(TAG, "Failed to parse cover art attribute");
  return null;
}
 
Example #9
Source File: DownloadManager.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
private Download putDownload(Download download) {
  // Downloads in terminal states shouldn't be in the downloads list.
  Assertions.checkState(download.state != STATE_COMPLETED && download.state != STATE_FAILED);
  int changedIndex = getDownloadIndex(download.request.id);
  if (changedIndex == C.INDEX_UNSET) {
    downloads.add(download);
    Collections.sort(downloads, InternalHandler::compareStartTimes);
  } else {
    boolean needsSort = download.startTimeMs != downloads.get(changedIndex).startTimeMs;
    downloads.set(changedIndex, download);
    if (needsSort) {
      Collections.sort(downloads, InternalHandler::compareStartTimes);
    }
  }
  try {
    downloadIndex.putDownload(download);
  } catch (IOException e) {
    Log.e(TAG, "Failed to update index.", e);
  }
  DownloadUpdate update =
      new DownloadUpdate(download, /* isRemove= */ false, new ArrayList<>(downloads));
  mainHandler.obtainMessage(MSG_DOWNLOAD_UPDATE, update).sendToTarget();
  return download;
}
 
Example #10
Source File: DownloadManager.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
private void onRemoveTaskStopped(Download download) {
  if (download.state == STATE_RESTARTING) {
    putDownloadWithState(
        download, download.stopReason == STOP_REASON_NONE ? STATE_QUEUED : STATE_STOPPED);
    syncTasks();
  } else {
    int removeIndex = getDownloadIndex(download.request.id);
    downloads.remove(removeIndex);
    try {
      downloadIndex.removeDownload(download.request.id);
    } catch (IOException e) {
      Log.e(TAG, "Failed to remove from database");
    }
    DownloadUpdate update =
        new DownloadUpdate(download, /* isRemove= */ true, new ArrayList<>(downloads));
    mainHandler.obtainMessage(MSG_DOWNLOAD_UPDATE, update).sendToTarget();
  }
}
 
Example #11
Source File: SsaDecoder.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
@Cue.AnchorType
private static int toPositionAnchor(@SsaStyle.SsaAlignment int alignment) {
  switch (alignment) {
    case SsaStyle.SSA_ALIGNMENT_BOTTOM_LEFT:
    case SsaStyle.SSA_ALIGNMENT_MIDDLE_LEFT:
    case SsaStyle.SSA_ALIGNMENT_TOP_LEFT:
      return Cue.ANCHOR_TYPE_START;
    case SsaStyle.SSA_ALIGNMENT_BOTTOM_CENTER:
    case SsaStyle.SSA_ALIGNMENT_MIDDLE_CENTER:
    case SsaStyle.SSA_ALIGNMENT_TOP_CENTER:
      return Cue.ANCHOR_TYPE_MIDDLE;
    case SsaStyle.SSA_ALIGNMENT_BOTTOM_RIGHT:
    case SsaStyle.SSA_ALIGNMENT_MIDDLE_RIGHT:
    case SsaStyle.SSA_ALIGNMENT_TOP_RIGHT:
      return Cue.ANCHOR_TYPE_END;
    case SsaStyle.SSA_ALIGNMENT_UNKNOWN:
      return Cue.TYPE_UNSET;
    default:
      Log.w(TAG, "Unknown alignment: " + alignment);
      return Cue.TYPE_UNSET;
  }
}
 
Example #12
Source File: WebvttCue.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
private Builder derivePositionAnchorFromAlignment() {
  if (textAlignment == null) {
    positionAnchor = Cue.TYPE_UNSET;
  } else {
    switch (textAlignment) {
      case ALIGN_NORMAL:
        positionAnchor = Cue.ANCHOR_TYPE_START;
        break;
      case ALIGN_CENTER:
        positionAnchor = Cue.ANCHOR_TYPE_MIDDLE;
        break;
      case ALIGN_OPPOSITE:
        positionAnchor = Cue.ANCHOR_TYPE_END;
        break;
      default:
        Log.w(TAG, "Unrecognized alignment: " + textAlignment);
        positionAnchor = Cue.ANCHOR_TYPE_START;
        break;
    }
  }
  return this;
}
 
Example #13
Source File: WebvttCueParser.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses a string containing a list of cue settings.
 *
 * @param cueSettingsList String containing the settings for a given cue.
 * @param builder The {@link WebvttCue.Builder} where incremental construction takes place.
 */
/* package */ static void parseCueSettingsList(String cueSettingsList,
    WebvttCue.Builder builder) {
  // Parse the cue settings list.
  Matcher cueSettingMatcher = CUE_SETTING_PATTERN.matcher(cueSettingsList);
  while (cueSettingMatcher.find()) {
    String name = cueSettingMatcher.group(1);
    String value = cueSettingMatcher.group(2);
    try {
      if ("line".equals(name)) {
        parseLineAttribute(value, builder);
      } else if ("align".equals(name)) {
        builder.setTextAlignment(parseTextAlignment(value));
      } else if ("position".equals(name)) {
        parsePositionAttribute(value, builder);
      } else if ("size".equals(name)) {
        builder.setWidth(WebvttParserUtil.parsePercentage(value));
      } else {
        Log.w(TAG, "Unknown cue setting " + name + ":" + value);
      }
    } catch (NumberFormatException e) {
      Log.w(TAG, "Skipping bad cue setting: " + cueSettingMatcher.group());
    }
  }
}
 
Example #14
Source File: DownloadManager.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
private void release() {
  for (Task task : activeTasks.values()) {
    task.cancel(/* released= */ true);
  }
  try {
    downloadIndex.setDownloadingStatesToQueued();
  } catch (IOException e) {
    Log.e(TAG, "Failed to update index.", e);
  }
  downloads.clear();
  thread.quit();
  synchronized (this) {
    released = true;
    notifyAll();
  }
}
 
Example #15
Source File: SsaDecoder.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Parses the event body of the subtitle.
 *
 * @param data A {@link ParsableByteArray} from which the body should be read.
 * @param cues A list to which parsed cues will be added.
 * @param cueTimesUs A sorted list to which parsed cue timestamps will be added.
 */
private void parseEventBody(ParsableByteArray data, List<List<Cue>> cues, List<Long> cueTimesUs) {
  @Nullable
  SsaDialogueFormat format = haveInitializationData ? dialogueFormatFromInitializationData : null;
  @Nullable String currentLine;
  while ((currentLine = data.readLine()) != null) {
    if (currentLine.startsWith(FORMAT_LINE_PREFIX)) {
      format = SsaDialogueFormat.fromFormatLine(currentLine);
    } else if (currentLine.startsWith(DIALOGUE_LINE_PREFIX)) {
      if (format == null) {
        Log.w(TAG, "Skipping dialogue line before complete format: " + currentLine);
        continue;
      }
      parseDialogueLine(currentLine, format, cues, cueTimesUs);
    }
  }
}
 
Example #16
Source File: DefaultAudioSink.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void onSystemTimeUsMismatch(
    long audioTimestampPositionFrames,
    long audioTimestampSystemTimeUs,
    long systemTimeUs,
    long playbackPositionUs) {
  String message =
      "Spurious audio timestamp (system clock mismatch): "
          + audioTimestampPositionFrames
          + ", "
          + audioTimestampSystemTimeUs
          + ", "
          + systemTimeUs
          + ", "
          + playbackPositionUs
          + ", "
          + getSubmittedFrames()
          + ", "
          + getWrittenFrames();
  if (failOnSpuriousAudioTimestamp) {
    throw new InvalidAudioTrackTimestampException(message);
  }
  Log.w(TAG, message);
}
 
Example #17
Source File: WebvttCueParser.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private static boolean parseCue(String id, Matcher cueHeaderMatcher, ParsableByteArray webvttData,
    WebvttCue.Builder builder, StringBuilder textBuilder, List<WebvttCssStyle> styles) {
  try {
    // Parse the cue start and end times.
    builder.setStartTime(WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(1)))
        .setEndTime(WebvttParserUtil.parseTimestampUs(cueHeaderMatcher.group(2)));
  } catch (NumberFormatException e) {
    Log.w(TAG, "Skipping cue with bad header: " + cueHeaderMatcher.group());
    return false;
  }

  parseCueSettingsList(cueHeaderMatcher.group(3), builder);

  // Parse the cue text.
  textBuilder.setLength(0);
  String line;
  while (!TextUtils.isEmpty(line = webvttData.readLine())) {
    if (textBuilder.length() > 0) {
      textBuilder.append("\n");
    }
    textBuilder.append(line.trim());
  }
  parseCueText(id, textBuilder.toString(), builder, styles);
  return true;
}
 
Example #18
Source File: MetadataUtil.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
@Nullable
private static TextInformationFrame parseIndexAndCountAttribute(
    int type, String attributeName, ParsableByteArray data) {
  int atomSize = data.readInt();
  int atomType = data.readInt();
  if (atomType == Atom.TYPE_data && atomSize >= 22) {
    data.skipBytes(10); // version (1), flags (3), empty (4), empty (2)
    int index = data.readUnsignedShort();
    if (index > 0) {
      String value = "" + index;
      int count = data.readUnsignedShort();
      if (count > 0) {
        value += "/" + count;
      }
      return new TextInformationFrame(attributeName, /* description= */ null, value);
    }
  }
  Log.w(TAG, "Failed to parse index/count attribute: " + Atom.getAtomTypeString(type));
  return null;
}
 
Example #19
Source File: CacheDataSink.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * @param cache The cache into which data should be written.
 * @param fragmentSize For requests that should be fragmented into multiple cache files, this is
 *     the maximum size of a cache file in bytes. If set to {@link C#LENGTH_UNSET} then no
 *     fragmentation will occur. Using a small value allows for finer-grained cache eviction
 *     policies, at the cost of increased overhead both on the cache implementation and the file
 *     system. Values under {@code (2 * 1024 * 1024)} are not recommended.
 * @param bufferSize The buffer size in bytes for writing to a cache file. A zero or negative
 *     value disables buffering.
 */
public CacheDataSink(Cache cache, long fragmentSize, int bufferSize) {
  Assertions.checkState(
      fragmentSize > 0 || fragmentSize == C.LENGTH_UNSET,
      "fragmentSize must be positive or C.LENGTH_UNSET.");
  if (fragmentSize != C.LENGTH_UNSET && fragmentSize < MIN_RECOMMENDED_FRAGMENT_SIZE) {
    Log.w(
        TAG,
        "fragmentSize is below the minimum recommended value of "
            + MIN_RECOMMENDED_FRAGMENT_SIZE
            + ". This may cause poor cache performance.");
  }
  this.cache = Assertions.checkNotNull(cache);
  this.fragmentSize = fragmentSize == C.LENGTH_UNSET ? Long.MAX_VALUE : fragmentSize;
  this.bufferSize = bufferSize;
}
 
Example #20
Source File: DownloadManager.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private void updateProgress() {
  for (int i = 0; i < downloads.size(); i++) {
    Download download = downloads.get(i);
    if (download.state == STATE_DOWNLOADING) {
      try {
        downloadIndex.putDownload(download);
      } catch (IOException e) {
        Log.e(TAG, "Failed to update index.", e);
      }
    }
  }
  sendEmptyMessageDelayed(MSG_UPDATE_PROGRESS, UPDATE_PROGRESS_INTERVAL_MS);
}
 
Example #21
Source File: PsshAtomUtil.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses the scheme specific data from a PSSH atom. Version 0 and 1 PSSH atoms are supported.
 *
 * <p>The scheme specific data is only parsed if the data is a valid PSSH atom matching the given
 * UUID, or if the data is a valid PSSH atom of any type in the case that the passed UUID is null.
 *
 * @param atom The atom to parse.
 * @param uuid The required UUID of the PSSH atom, or null to accept any UUID.
 * @return The parsed scheme specific data. Null if the input is not a valid PSSH atom, or if the
 *     PSSH atom has an unsupported version, or if the PSSH atom does not match the passed UUID.
 */
public static @Nullable byte[] parseSchemeSpecificData(byte[] atom, UUID uuid) {
  PsshAtom parsedAtom = parsePsshAtom(atom);
  if (parsedAtom == null) {
    return null;
  }
  if (uuid != null && !uuid.equals(parsedAtom.uuid)) {
    Log.w(TAG, "UUID mismatch. Expected: " + uuid + ", got: " + parsedAtom.uuid + ".");
    return null;
  }
  return parsedAtom.schemeData;
}
 
Example #22
Source File: TeeAudioProcessor.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private void reset() throws IOException {
  RandomAccessFile randomAccessFile = this.randomAccessFile;
  if (randomAccessFile == null) {
    return;
  }

  try {
    scratchByteBuffer.clear();
    scratchByteBuffer.putInt(bytesWritten - 8);
    randomAccessFile.seek(FILE_SIZE_MINUS_8_OFFSET);
    randomAccessFile.write(scratchBuffer, 0, 4);

    scratchByteBuffer.clear();
    scratchByteBuffer.putInt(bytesWritten - 44);
    randomAccessFile.seek(FILE_SIZE_MINUS_44_OFFSET);
    randomAccessFile.write(scratchBuffer, 0, 4);
  } catch (IOException e) {
    // The file may still be playable, so just log a warning.
    Log.w(TAG, "Error updating file size", e);
  }

  try {
    randomAccessFile.close();
  } finally {
    this.randomAccessFile = null;
  }
}
 
Example #23
Source File: DefaultHttpDataSource.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Closes the current connection quietly, if there is one.
 */
private void closeConnectionQuietly() {
  if (connection != null) {
    try {
      connection.disconnect();
    } catch (Exception e) {
      Log.e(TAG, "Unexpected error while disconnecting", e);
    }
    connection = null;
  }
}
 
Example #24
Source File: ExoPlayerImplInternal.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@Override
public synchronized void sendMessage(PlayerMessage message) {
  if (released) {
    Log.w(TAG, "Ignoring messages sent after release.");
    message.markAsProcessed(/* isDelivered= */ false);
    return;
  }
  handler.obtainMessage(MSG_SEND_MESSAGE, message).sendToTarget();
}
 
Example #25
Source File: DownloadService.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private void setSchedulerEnabled(boolean enabled, Requirements requirements) {
  if (!enabled) {
    scheduler.cancel();
  } else {
    String servicePackage = context.getPackageName();
    boolean success = scheduler.schedule(requirements, servicePackage, ACTION_RESTART);
    if (!success) {
      Log.e(TAG, "Scheduling downloads failed.");
    }
  }
}
 
Example #26
Source File: MediaCodecUtil.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Nullable
private static Pair<Integer, Integer> getVp9ProfileAndLevel(String codec, String[] parts) {
  if (parts.length < 3) {
    Log.w(TAG, "Ignoring malformed VP9 codec string: " + codec);
    return null;
  }
  int profileInteger;
  int levelInteger;
  try {
    profileInteger = Integer.parseInt(parts[1]);
    levelInteger = Integer.parseInt(parts[2]);
  } catch (NumberFormatException e) {
    Log.w(TAG, "Ignoring malformed VP9 codec string: " + codec);
    return null;
  }

  int profile = VP9_PROFILE_NUMBER_TO_CONST.get(profileInteger, -1);
  if (profile == -1) {
    Log.w(TAG, "Unknown VP9 profile: " + profileInteger);
    return null;
  }
  int level = VP9_LEVEL_NUMBER_TO_CONST.get(levelInteger, -1);
  if (level == -1) {
    Log.w(TAG, "Unknown VP9 level: " + levelInteger);
    return null;
  }
  return new Pair<>(profile, level);
}
 
Example #27
Source File: MetadataUtil.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private static int parseUint8AttributeValue(ParsableByteArray data) {
  data.skipBytes(4); // atomSize
  int atomType = data.readInt();
  if (atomType == Atom.TYPE_data) {
    data.skipBytes(8); // version (1), flags (3), empty (4)
    return data.readUnsignedByte();
  }
  Log.w(TAG, "Failed to parse uint8 attribute value");
  return -1;
}
 
Example #28
Source File: DownloadService.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private void setSchedulerEnabled(boolean enabled, Requirements requirements) {
  if (!enabled) {
    scheduler.cancel();
  } else {
    String servicePackage = context.getPackageName();
    boolean success = scheduler.schedule(requirements, servicePackage, ACTION_RESTART);
    if (!success) {
      Log.e(TAG, "Scheduling downloads failed.");
    }
  }
}
 
Example #29
Source File: WebvttCueParser.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Cue.AnchorType
private static int parsePositionAnchor(String s) {
  switch (s) {
    case "start":
      return Cue.ANCHOR_TYPE_START;
    case "center":
    case "middle":
      return Cue.ANCHOR_TYPE_MIDDLE;
    case "end":
      return Cue.ANCHOR_TYPE_END;
    default:
      Log.w(TAG, "Invalid anchor value: " + s);
      return Cue.TYPE_UNSET;
  }
}
 
Example #30
Source File: MediaCodecAudioRenderer.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
  super.onStreamChanged(formats, offsetUs);
  if (lastInputTimeUs != C.TIME_UNSET) {
    if (pendingStreamChangeCount == pendingStreamChangeTimesUs.length) {
      Log.w(
          TAG,
          "Too many stream changes, so dropping change at "
              + pendingStreamChangeTimesUs[pendingStreamChangeCount - 1]);
    } else {
      pendingStreamChangeCount++;
    }
    pendingStreamChangeTimesUs[pendingStreamChangeCount - 1] = lastInputTimeUs;
  }
}