Program: 110326
Project: 110326
Buggy source:
private void updatePeriods() throws ExoPlaybackException, IOException {
  if (timeline == null) {
    mediaSource.maybeThrowSourceInfoRefreshError();
    return;
  }
  if (loadingPeriodHolder == null || (loadingPeriodHolder.isFullyBuffered() && !loadingPeriodHolder.isLast && bufferAheadPeriodCount < MAXIMUM_BUFFER_AHEAD_PERIODS)) {
    int newLoadingPeriodIndex=loadingPeriodHolder == null ? playbackInfo.periodIndex : loadingPeriodHolder.index + 1;
    if (newLoadingPeriodIndex >= timeline.getPeriodCount()) {
      mediaSource.maybeThrowSourceInfoRefreshError();
    }
 else {
      int windowIndex=timeline.getPeriod(newLoadingPeriodIndex,period).windowIndex;
      boolean isFirstPeriodInWindow=newLoadingPeriodIndex == timeline.getWindow(windowIndex,window).firstPeriodIndex;
      long periodStartPositionUs=loadingPeriodHolder == null ? playbackInfo.positionUs : (isFirstPeriodInWindow ? C.TIME_UNSET : 0);
      if (periodStartPositionUs == C.TIME_UNSET) {
        long defaultPositionProjectionUs=loadingPeriodHolder == null ? 0 : (loadingPeriodHolder.rendererPositionOffsetUs + timeline.getPeriod(loadingPeriodHolder.index,period).getDurationUs() - loadingPeriodHolder.startPositionUs - rendererPositionUs);
        Pair<Integer,Long> defaultPosition=getPeriodPosition(timeline,windowIndex,C.TIME_UNSET,Math.max(0,defaultPositionProjectionUs));
        if (defaultPosition == null) {
          newLoadingPeriodIndex=C.INDEX_UNSET;
          periodStartPositionUs=C.TIME_UNSET;
        }
 else {
          newLoadingPeriodIndex=defaultPosition.first;
          periodStartPositionUs=defaultPosition.second;
        }
      }
      if (newLoadingPeriodIndex != C.INDEX_UNSET) {
        Object newPeriodUid=timeline.getPeriod(newLoadingPeriodIndex,period,true).uid;
        MediaPeriod newMediaPeriod=mediaSource.createPeriod(newLoadingPeriodIndex,loadControl.getAllocator(),periodStartPositionUs);
        newMediaPeriod.prepare(this);
        MediaPeriodHolder newPeriodHolder=new MediaPeriodHolder(renderers,rendererCapabilities,trackSelector,mediaSource,newMediaPeriod,newPeriodUid,periodStartPositionUs);
        timeline.getWindow(windowIndex,window);
        newPeriodHolder.setIndex(timeline,window,newLoadingPeriodIndex);
        if (loadingPeriodHolder != null) {
          loadingPeriodHolder.setNext(newPeriodHolder);
          newPeriodHolder.rendererPositionOffsetUs=loadingPeriodHolder.rendererPositionOffsetUs + timeline.getPeriod(loadingPeriodHolder.index,period).getDurationUs() - loadingPeriodHolder.startPositionUs;
        }
 else {
          newPeriodHolder.rendererPositionOffsetUs=periodStartPositionUs;
        }
        bufferAheadPeriodCount++;
        loadingPeriodHolder=newPeriodHolder;
        setIsLoading(true);
      }
    }
  }
  if (loadingPeriodHolder == null || loadingPeriodHolder.isFullyBuffered()) {
    setIsLoading(false);
  }
 else   if (loadingPeriodHolder != null && loadingPeriodHolder.needsContinueLoading) {
    maybeContinueLoading();
  }
  if (playingPeriodHolder == null) {
    return;
  }
  while (playingPeriodHolder != readingPeriodHolder && playingPeriodHolder.next != null && rendererPositionUs >= playingPeriodHolder.next.rendererPositionOffsetUs) {
    playingPeriodHolder.release();
    setPlayingPeriodHolder(playingPeriodHolder.next);
    bufferAheadPeriodCount--;
    playbackInfo=new PlaybackInfo(playingPeriodHolder.index,playingPeriodHolder.startPositionUs);
    updatePlaybackPositions();
    eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY,playbackInfo).sendToTarget();
  }
  updateTimelineState();
  if (readingPeriodHolder.isLast) {
    for (    Renderer renderer : enabledRenderers) {
      renderer.setCurrentStreamIsFinal();
    }
    return;
  }
  for (  Renderer renderer : enabledRenderers) {
    if (!renderer.hasReadStreamToEnd()) {
      return;
    }
  }
  if (readingPeriodHolder.next != null && readingPeriodHolder.next.prepared) {
    TrackSelectionArray oldTrackSelections=readingPeriodHolder.trackSelections;
    readingPeriodHolder=readingPeriodHolder.next;
    TrackSelectionArray newTrackSelections=readingPeriodHolder.trackSelections;
    for (int i=0; i < renderers.length; i++) {
      Renderer renderer=renderers[i];
      TrackSelection oldSelection=oldTrackSelections.get(i);
      TrackSelection newSelection=newTrackSelections.get(i);
      if (oldSelection != null) {
        if (newSelection != null) {
          Format[] formats=new Format[newSelection.length()];
          for (int j=0; j < formats.length; j++) {
            formats[j]=newSelection.getFormat(j);
          }
          renderer.replaceStream(formats,readingPeriodHolder.sampleStreams[i],readingPeriodHolder.getRendererOffset());
        }
 else {
          renderer.setCurrentStreamIsFinal();
        }
      }
    }
  }
}

Fixed version (ground truth):
private void updatePeriods() throws ExoPlaybackException, IOException {
  if (timeline == null) {
    mediaSource.maybeThrowSourceInfoRefreshError();
    return;
  }
  if (loadingPeriodHolder == null || (loadingPeriodHolder.isFullyBuffered() && !loadingPeriodHolder.isLast && bufferAheadPeriodCount < MAXIMUM_BUFFER_AHEAD_PERIODS)) {
    int newLoadingPeriodIndex=loadingPeriodHolder == null ? playbackInfo.periodIndex : loadingPeriodHolder.index + 1;
    if (newLoadingPeriodIndex >= timeline.getPeriodCount()) {
      mediaSource.maybeThrowSourceInfoRefreshError();
    }
 else {
      int windowIndex=timeline.getPeriod(newLoadingPeriodIndex,period).windowIndex;
      boolean isFirstPeriodInWindow=newLoadingPeriodIndex == timeline.getWindow(windowIndex,window).firstPeriodIndex;
      long periodStartPositionUs;
      if (loadingPeriodHolder == null) {
        periodStartPositionUs=playbackInfo.startPositionUs;
      }
 else       if (!isFirstPeriodInWindow) {
        periodStartPositionUs=0;
      }
 else {
        long defaultPositionProjectionUs=loadingPeriodHolder.rendererPositionOffsetUs + timeline.getPeriod(loadingPeriodHolder.index,period).getDurationUs() - loadingPeriodHolder.startPositionUs - rendererPositionUs;
        Pair<Integer,Long> defaultPosition=getPeriodPosition(timeline,windowIndex,C.TIME_UNSET,Math.max(0,defaultPositionProjectionUs));
        if (defaultPosition == null) {
          newLoadingPeriodIndex=C.INDEX_UNSET;
          periodStartPositionUs=C.TIME_UNSET;
        }
 else {
          newLoadingPeriodIndex=defaultPosition.first;
          periodStartPositionUs=defaultPosition.second;
        }
      }
      if (newLoadingPeriodIndex != C.INDEX_UNSET) {
        Object newPeriodUid=timeline.getPeriod(newLoadingPeriodIndex,period,true).uid;
        MediaPeriod newMediaPeriod=mediaSource.createPeriod(newLoadingPeriodIndex,loadControl.getAllocator(),periodStartPositionUs);
        newMediaPeriod.prepare(this);
        MediaPeriodHolder newPeriodHolder=new MediaPeriodHolder(renderers,rendererCapabilities,trackSelector,mediaSource,newMediaPeriod,newPeriodUid,periodStartPositionUs);
        timeline.getWindow(windowIndex,window);
        newPeriodHolder.setIndex(timeline,window,newLoadingPeriodIndex);
        if (loadingPeriodHolder != null) {
          loadingPeriodHolder.setNext(newPeriodHolder);
          newPeriodHolder.rendererPositionOffsetUs=loadingPeriodHolder.rendererPositionOffsetUs + timeline.getPeriod(loadingPeriodHolder.index,period).getDurationUs() - loadingPeriodHolder.startPositionUs;
        }
 else {
          newPeriodHolder.rendererPositionOffsetUs=periodStartPositionUs;
        }
        bufferAheadPeriodCount++;
        loadingPeriodHolder=newPeriodHolder;
        setIsLoading(true);
      }
    }
  }
  if (loadingPeriodHolder == null || loadingPeriodHolder.isFullyBuffered()) {
    setIsLoading(false);
  }
 else   if (loadingPeriodHolder != null && loadingPeriodHolder.needsContinueLoading) {
    maybeContinueLoading();
  }
  if (playingPeriodHolder == null) {
    return;
  }
  while (playingPeriodHolder != readingPeriodHolder && playingPeriodHolder.next != null && rendererPositionUs >= playingPeriodHolder.next.rendererPositionOffsetUs) {
    playingPeriodHolder.release();
    setPlayingPeriodHolder(playingPeriodHolder.next);
    bufferAheadPeriodCount--;
    playbackInfo=new PlaybackInfo(playingPeriodHolder.index,playingPeriodHolder.startPositionUs);
    updatePlaybackPositions();
    eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY,playbackInfo).sendToTarget();
  }
  updateTimelineState();
  if (readingPeriodHolder.isLast) {
    for (    Renderer renderer : enabledRenderers) {
      renderer.setCurrentStreamIsFinal();
    }
    return;
  }
  for (  Renderer renderer : enabledRenderers) {
    if (!renderer.hasReadStreamToEnd()) {
      return;
    }
  }
  if (readingPeriodHolder.next != null && readingPeriodHolder.next.prepared) {
    TrackSelectionArray oldTrackSelections=readingPeriodHolder.trackSelections;
    readingPeriodHolder=readingPeriodHolder.next;
    TrackSelectionArray newTrackSelections=readingPeriodHolder.trackSelections;
    for (int i=0; i < renderers.length; i++) {
      Renderer renderer=renderers[i];
      TrackSelection oldSelection=oldTrackSelections.get(i);
      TrackSelection newSelection=newTrackSelections.get(i);
      if (oldSelection != null) {
        if (newSelection != null) {
          Format[] formats=new Format[newSelection.length()];
          for (int j=0; j < formats.length; j++) {
            formats[j]=newSelection.getFormat(j);
          }
          renderer.replaceStream(formats,readingPeriodHolder.sampleStreams[i],readingPeriodHolder.getRendererOffset());
        }
 else {
          renderer.setCurrentStreamIsFinal();
        }
      }
    }
  }
}