Program: 110335
Project: 110335
Buggy source:
private void processManifest(){
  for (int i=0; i < periodsById.size(); i++) {
    int id=periodsById.keyAt(i);
    if (id >= firstPeriodId) {
      periodsById.valueAt(i).updateManifest(manifest,id - firstPeriodId);
    }
 else {
    }
  }
  handler.removeCallbacks(simulateManifestRefreshRunnable);
  int lastPeriodIndex=manifest.getPeriodCount() - 1;
  PeriodSeekInfo firstPeriodSeekInfo=PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(0),manifest.getPeriodDurationUs(0));
  PeriodSeekInfo lastPeriodSeekInfo=PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(lastPeriodIndex),manifest.getPeriodDurationUs(lastPeriodIndex));
  long currentStartTimeUs=firstPeriodSeekInfo.availableStartTimeUs;
  long currentEndTimeUs=lastPeriodSeekInfo.availableEndTimeUs;
  if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) {
    long liveStreamDurationUs=getNowUnixTimeUs() - C.msToUs(manifest.availabilityStartTime);
    long liveStreamEndPositionInLastPeriodUs=liveStreamDurationUs - C.msToUs(manifest.getPeriod(lastPeriodIndex).startMs);
    currentEndTimeUs=Math.min(liveStreamEndPositionInLastPeriodUs,currentEndTimeUs);
    if (manifest.timeShiftBufferDepth != C.TIME_UNSET) {
      long timeShiftBufferDepthUs=C.msToUs(manifest.timeShiftBufferDepth);
      long offsetInPeriodUs=currentEndTimeUs - timeShiftBufferDepthUs;
      int periodIndex=lastPeriodIndex;
      while (offsetInPeriodUs < 0 && periodIndex > 0) {
        offsetInPeriodUs+=manifest.getPeriodDurationUs(--periodIndex);
      }
      if (periodIndex == 0) {
        currentStartTimeUs=Math.max(currentStartTimeUs,offsetInPeriodUs);
      }
 else {
        currentStartTimeUs=manifest.getPeriodDurationUs(0);
      }
    }
    handler.postDelayed(simulateManifestRefreshRunnable,NOTIFY_MANIFEST_INTERVAL_MS);
  }
  long windowDurationUs=currentEndTimeUs - currentStartTimeUs;
  for (int i=0; i < manifest.getPeriodCount() - 1; i++) {
    windowDurationUs+=manifest.getPeriodDurationUs(i);
  }
  long windowDefaultStartPositionUs=0;
  if (manifest.dynamic) {
    long presentationDelayForManifestMs=livePresentationDelayMs;
    if (presentationDelayForManifestMs == DEFAULT_LIVE_PRESENTATION_DELAY_PREFER_MANIFEST_MS) {
      presentationDelayForManifestMs=manifest.suggestedPresentationDelay != C.TIME_UNSET ? manifest.suggestedPresentationDelay : DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS;
    }
    long defaultStartPositionUs=windowDurationUs - C.msToUs(presentationDelayForManifestMs);
    if (defaultStartPositionUs < MIN_LIVE_DEFAULT_START_POSITION_US) {
      defaultStartPositionUs=Math.min(MIN_LIVE_DEFAULT_START_POSITION_US,windowDurationUs / 2);
    }
    int periodIndex=0;
    long defaultStartPositionInPeriodUs=currentStartTimeUs + defaultStartPositionUs;
    long periodDurationUs=manifest.getPeriodDurationUs(periodIndex);
    while (periodIndex < manifest.getPeriodCount() - 1 && defaultStartPositionInPeriodUs >= periodDurationUs) {
      defaultStartPositionInPeriodUs-=periodDurationUs;
      periodIndex++;
      periodDurationUs=manifest.getPeriodDurationUs(periodIndex);
    }
    Period period=manifest.getPeriod(periodIndex);
    int videoAdaptationSetIndex=period.getAdaptationSetIndex(C.TRACK_TYPE_VIDEO);
    if (videoAdaptationSetIndex != C.INDEX_UNSET) {
      DashSegmentIndex index=period.adaptationSets.get(videoAdaptationSetIndex).representations.get(0).getIndex();
      int segmentNum=index.getSegmentNum(defaultStartPositionInPeriodUs,periodDurationUs);
      windowDefaultStartPositionUs=defaultStartPositionUs - defaultStartPositionInPeriodUs + index.getTimeUs(segmentNum);
    }
 else {
      windowDefaultStartPositionUs=defaultStartPositionUs;
    }
  }
  long windowStartTimeMs=manifest.availabilityStartTime + manifest.getPeriod(0).startMs + C.usToMs(currentStartTimeUs);
  DashTimeline timeline=new DashTimeline(manifest.availabilityStartTime,windowStartTimeMs,firstPeriodId,currentStartTimeUs,windowDurationUs,windowDefaultStartPositionUs,manifest);
  sourceListener.onSourceInfoRefreshed(timeline,manifest);
}

Fixed version (ground truth):
private void processManifest(){
  for (int i=0; i < periodsById.size(); i++) {
    int id=periodsById.keyAt(i);
    if (id >= firstPeriodId) {
      periodsById.valueAt(i).updateManifest(manifest,id - firstPeriodId);
    }
 else {
    }
  }
  handler.removeCallbacks(simulateManifestRefreshRunnable);
  int lastPeriodIndex=manifest.getPeriodCount() - 1;
  PeriodSeekInfo firstPeriodSeekInfo=PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(0),manifest.getPeriodDurationUs(0));
  PeriodSeekInfo lastPeriodSeekInfo=PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(lastPeriodIndex),manifest.getPeriodDurationUs(lastPeriodIndex));
  long currentStartTimeUs=firstPeriodSeekInfo.availableStartTimeUs;
  long currentEndTimeUs=lastPeriodSeekInfo.availableEndTimeUs;
  if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) {
    long liveStreamDurationUs=getNowUnixTimeUs() - C.msToUs(manifest.availabilityStartTime);
    long liveStreamEndPositionInLastPeriodUs=liveStreamDurationUs - C.msToUs(manifest.getPeriod(lastPeriodIndex).startMs);
    currentEndTimeUs=Math.min(liveStreamEndPositionInLastPeriodUs,currentEndTimeUs);
    if (manifest.timeShiftBufferDepth != C.TIME_UNSET) {
      long timeShiftBufferDepthUs=C.msToUs(manifest.timeShiftBufferDepth);
      long offsetInPeriodUs=currentEndTimeUs - timeShiftBufferDepthUs;
      int periodIndex=lastPeriodIndex;
      while (offsetInPeriodUs < 0 && periodIndex > 0) {
        offsetInPeriodUs+=manifest.getPeriodDurationUs(--periodIndex);
      }
      if (periodIndex == 0) {
        currentStartTimeUs=Math.max(currentStartTimeUs,offsetInPeriodUs);
      }
 else {
        currentStartTimeUs=manifest.getPeriodDurationUs(0);
      }
    }
    handler.postDelayed(simulateManifestRefreshRunnable,NOTIFY_MANIFEST_INTERVAL_MS);
  }
  long windowDurationUs=currentEndTimeUs - currentStartTimeUs;
  for (int i=0; i < manifest.getPeriodCount() - 1; i++) {
    windowDurationUs+=manifest.getPeriodDurationUs(i);
  }
  long windowDefaultStartPositionUs=0;
  if (manifest.dynamic) {
    long presentationDelayForManifestMs=livePresentationDelayMs;
    if (presentationDelayForManifestMs == DEFAULT_LIVE_PRESENTATION_DELAY_PREFER_MANIFEST_MS) {
      presentationDelayForManifestMs=manifest.suggestedPresentationDelay != C.TIME_UNSET ? manifest.suggestedPresentationDelay : DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS;
    }
    long defaultStartPositionUs=windowDurationUs - C.msToUs(presentationDelayForManifestMs);
    if (defaultStartPositionUs < MIN_LIVE_DEFAULT_START_POSITION_US) {
      defaultStartPositionUs=Math.min(MIN_LIVE_DEFAULT_START_POSITION_US,windowDurationUs / 2);
    }
    int periodIndex=0;
    long defaultStartPositionInPeriodUs=currentStartTimeUs + defaultStartPositionUs;
    long periodDurationUs=manifest.getPeriodDurationUs(periodIndex);
    while (periodIndex < manifest.getPeriodCount() - 1 && defaultStartPositionInPeriodUs >= periodDurationUs) {
      defaultStartPositionInPeriodUs-=periodDurationUs;
      periodIndex++;
      periodDurationUs=manifest.getPeriodDurationUs(periodIndex);
    }
    Period period=manifest.getPeriod(periodIndex);
    int videoAdaptationSetIndex=period.getAdaptationSetIndex(C.TRACK_TYPE_VIDEO);
    if (videoAdaptationSetIndex != C.INDEX_UNSET) {
      DashSegmentIndex index=period.adaptationSets.get(videoAdaptationSetIndex).representations.get(0).getIndex();
      if (index != null) {
        int segmentNum=index.getSegmentNum(defaultStartPositionInPeriodUs,periodDurationUs);
        windowDefaultStartPositionUs=defaultStartPositionUs - defaultStartPositionInPeriodUs + index.getTimeUs(segmentNum);
      }
 else {
        windowDefaultStartPositionUs=defaultStartPositionUs;
      }
    }
 else {
      windowDefaultStartPositionUs=defaultStartPositionUs;
    }
  }
  long windowStartTimeMs=manifest.availabilityStartTime + manifest.getPeriod(0).startMs + C.usToMs(currentStartTimeUs);
  DashTimeline timeline=new DashTimeline(manifest.availabilityStartTime,windowStartTimeMs,firstPeriodId,currentStartTimeUs,windowDurationUs,windowDefaultStartPositionUs,manifest);
  sourceListener.onSourceInfoRefreshed(timeline,manifest);
}