Program: 110352
Project: 110352
Buggy source:
/** 
 * Parses a trun atom (defined in 14496-12).
 * @param trackBundle The {@link TrackBundle} that contains the {@link TrackFragment} intowhich parsed data should be placed.
 * @param index Index of the track run in the fragment.
 * @param decodeTime The decode time of the first sample in the fragment run.
 * @param flags Flags to allow any required workaround to be executed.
 * @param trun The trun atom to decode.
 * @return The starting position of samples for the next run.
 */
private static int parseTrun(TrackBundle trackBundle,int index,long decodeTime,int flags,ParsableByteArray trun,int trackRunStart){
  trun.setPosition(Atom.HEADER_SIZE);
  int fullAtom=trun.readInt();
  int atomFlags=Atom.parseFullAtomFlags(fullAtom);
  Track track=trackBundle.track;
  TrackFragment fragment=trackBundle.fragment;
  DefaultSampleValues defaultSampleValues=fragment.header;
  fragment.trunLength[index]=trun.readUnsignedIntToInt();
  if ((atomFlags & 0x01) != 0) {
    fragment.trunDataPosition[index]=fragment.dataPosition + trun.readInt();
  }
  boolean firstSampleFlagsPresent=(atomFlags & 0x04) != 0;
  int firstSampleFlags=defaultSampleValues.flags;
  if (firstSampleFlagsPresent) {
    firstSampleFlags=trun.readUnsignedIntToInt();
  }
  boolean sampleDurationsPresent=(atomFlags & 0x100) != 0;
  boolean sampleSizesPresent=(atomFlags & 0x200) != 0;
  boolean sampleFlagsPresent=(atomFlags & 0x400) != 0;
  boolean sampleCompositionTimeOffsetsPresent=(atomFlags & 0x800) != 0;
  long edtsOffset=0;
  if (track.editListDurations != null && track.editListDurations.length == 1 && track.editListDurations[0] == 0) {
    edtsOffset=Util.scaleLargeTimestamp(track.editListMediaTimes[0],1000,track.timescale);
  }
  int[] sampleSizeTable=fragment.sampleSizeTable;
  int[] sampleCompositionTimeOffsetTable=fragment.sampleCompositionTimeOffsetTable;
  long[] sampleDecodingTimeTable=fragment.sampleDecodingTimeTable;
  boolean[] sampleIsSyncFrameTable=fragment.sampleIsSyncFrameTable;
  boolean workaroundEveryVideoFrameIsSyncFrame=track.type == C.TRACK_TYPE_VIDEO && (flags & FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME) != 0;
  int trackRunEnd=trackRunStart + fragment.trunLength[index];
  long timescale=track.timescale;
  long cumulativeTime=index > 0 ? fragment.nextFragmentDecodeTime : decodeTime;
  for (int i=trackRunStart; i < trackRunEnd; i++) {
    int sampleDuration=sampleDurationsPresent ? trun.readUnsignedIntToInt() : defaultSampleValues.duration;
    int sampleSize=sampleSizesPresent ? trun.readUnsignedIntToInt() : defaultSampleValues.size;
    int sampleFlags=(i == 0 && firstSampleFlagsPresent) ? firstSampleFlags : sampleFlagsPresent ? trun.readInt() : defaultSampleValues.flags;
    if (sampleCompositionTimeOffsetsPresent) {
      int sampleOffset=trun.readInt();
      sampleCompositionTimeOffsetTable[i]=(int)((sampleOffset * 1000) / timescale);
    }
 else {
      sampleCompositionTimeOffsetTable[i]=0;
    }
    sampleDecodingTimeTable[i]=Util.scaleLargeTimestamp(cumulativeTime,1000,timescale) - edtsOffset;
    sampleSizeTable[i]=sampleSize;
    sampleIsSyncFrameTable[i]=((sampleFlags >> 16) & 0x1) == 0 && (!workaroundEveryVideoFrameIsSyncFrame || i == 0);
    cumulativeTime+=sampleDuration;
  }
  fragment.nextFragmentDecodeTime=cumulativeTime;
  return trackRunEnd;
}

Fixed version (ground truth):
/** 
 * Parses a trun atom (defined in 14496-12).
 * @param trackBundle The {@link TrackBundle} that contains the {@link TrackFragment} intowhich parsed data should be placed.
 * @param index Index of the track run in the fragment.
 * @param decodeTime The decode time of the first sample in the fragment run.
 * @param flags Flags to allow any required workaround to be executed.
 * @param trun The trun atom to decode.
 * @return The starting position of samples for the next run.
 */
private static int parseTrun(TrackBundle trackBundle,int index,long decodeTime,int flags,ParsableByteArray trun,int trackRunStart){
  trun.setPosition(Atom.HEADER_SIZE);
  int fullAtom=trun.readInt();
  int atomFlags=Atom.parseFullAtomFlags(fullAtom);
  Track track=trackBundle.track;
  TrackFragment fragment=trackBundle.fragment;
  DefaultSampleValues defaultSampleValues=fragment.header;
  fragment.trunLength[index]=trun.readUnsignedIntToInt();
  fragment.trunDataPosition[index]=fragment.dataPosition;
  if ((atomFlags & 0x01) != 0) {
    fragment.trunDataPosition[index]+=trun.readInt();
  }
  boolean firstSampleFlagsPresent=(atomFlags & 0x04) != 0;
  int firstSampleFlags=defaultSampleValues.flags;
  if (firstSampleFlagsPresent) {
    firstSampleFlags=trun.readUnsignedIntToInt();
  }
  boolean sampleDurationsPresent=(atomFlags & 0x100) != 0;
  boolean sampleSizesPresent=(atomFlags & 0x200) != 0;
  boolean sampleFlagsPresent=(atomFlags & 0x400) != 0;
  boolean sampleCompositionTimeOffsetsPresent=(atomFlags & 0x800) != 0;
  long edtsOffset=0;
  if (track.editListDurations != null && track.editListDurations.length == 1 && track.editListDurations[0] == 0) {
    edtsOffset=Util.scaleLargeTimestamp(track.editListMediaTimes[0],1000,track.timescale);
  }
  int[] sampleSizeTable=fragment.sampleSizeTable;
  int[] sampleCompositionTimeOffsetTable=fragment.sampleCompositionTimeOffsetTable;
  long[] sampleDecodingTimeTable=fragment.sampleDecodingTimeTable;
  boolean[] sampleIsSyncFrameTable=fragment.sampleIsSyncFrameTable;
  boolean workaroundEveryVideoFrameIsSyncFrame=track.type == C.TRACK_TYPE_VIDEO && (flags & FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME) != 0;
  int trackRunEnd=trackRunStart + fragment.trunLength[index];
  long timescale=track.timescale;
  long cumulativeTime=index > 0 ? fragment.nextFragmentDecodeTime : decodeTime;
  for (int i=trackRunStart; i < trackRunEnd; i++) {
    int sampleDuration=sampleDurationsPresent ? trun.readUnsignedIntToInt() : defaultSampleValues.duration;
    int sampleSize=sampleSizesPresent ? trun.readUnsignedIntToInt() : defaultSampleValues.size;
    int sampleFlags=(i == 0 && firstSampleFlagsPresent) ? firstSampleFlags : sampleFlagsPresent ? trun.readInt() : defaultSampleValues.flags;
    if (sampleCompositionTimeOffsetsPresent) {
      int sampleOffset=trun.readInt();
      sampleCompositionTimeOffsetTable[i]=(int)((sampleOffset * 1000) / timescale);
    }
 else {
      sampleCompositionTimeOffsetTable[i]=0;
    }
    sampleDecodingTimeTable[i]=Util.scaleLargeTimestamp(cumulativeTime,1000,timescale) - edtsOffset;
    sampleSizeTable[i]=sampleSize;
    sampleIsSyncFrameTable[i]=((sampleFlags >> 16) & 0x1) == 0 && (!workaroundEveryVideoFrameIsSyncFrame || i == 0);
    cumulativeTime+=sampleDuration;
  }
  fragment.nextFragmentDecodeTime=cumulativeTime;
  return trackRunEnd;
}