       if mediaRateFraction isnt 0
         logger.warn "[mp4] warning: media_rate_fraction is not 0 in elst box: #{mediaRateFraction}"
       @entries.push
-        segmentDuration: segmentDuration
+        segmentDuration: segmentDuration  # in Movie Header Box (mvhd) timescale
         segmentDurationSeconds: segmentDuration / mvhdBox.timescale
-        mediaTime: mediaTime
+        mediaTime: mediaTime  # in media (mdhd) timescale
         mediaRate: mediaRateInteger + mediaRateFraction / 65536 # TODO: Is this correct?
 
     if bits.has_more_data()
       throw new Error "elst box has more data"
 
+  # Returns the starting offset for this track in mdhd timescale units
+  getEmptyDuration: ->
+    time = 0
+    for entry in @entries
+      if entry.mediaTime is -1  # empty edit
+        # moov
+        #   mvhd <- find target
+        #   iods
+        #   trak
+        #     tkhd
+        #     edts
+        #       elst <- self
+        mvhdBox = @findParent('moov').child('mvhd')
+
+        #   trak
+        #     tkhd
+        #     edts
+        #       elst <- self
+        #     mdia
+        #       mdhd <- find target
+        mdhdBox = @findParent('trak').child('mdia').child('mdhd')
+        if not mdhdBox?
+          throw new Error "cannot access mdhd box (not parsed yet?)"
+
+        # Convert segmentDuration from mvhd timescale to mdhd timescale
+        time += entry.segmentDuration * mdhdBox.timescale / mvhdBox.timescale
+      else
+        # mediaTime is already in mdhd timescale, so no conversion needed
+        return time + entry.mediaTime
+
   getDetails: (detailLevel) ->
-    @entries.map((entry) ->
-      "segmentDurationSeconds=#{entry.segmentDurationSeconds} mediaTime=#{entry.mediaTime} mediaRate=#{entry.mediaRate}"
+    @entries.map((entry, index) ->
+      "[#{index}]:segmentDuration=#{entry.segmentDuration},segmentDurationSeconds=#{entry.segmentDurationSeconds},mediaTime=#{entry.mediaTime},mediaRate=#{entry.mediaRate}"
     ).join(',')
 
   getTree: ->

  getDetails: (detailLevel) ->
    str = "entryCount=#{@entryCount}"
    if detailLevel >= 2
      str += ' ' + @entries.map((entry) ->
        "sampleCount=#{entry.sampleCount} sampleDelta=#{entry.sampleDelta}"
      ).join(',')
    return str


      time += entry.sampleDelta * entry.sampleCount
    return time / mdhdBox.timescale

  # Returns a sample which comes exactly at or immediately after
  # the specified time (in seconds). If isExclusive=true, it excludes
  # a sample whose timestamp is equal to the specified time.
  # If there is no matching sample, this method returns null.
  getSampleAfterSeconds: (sec, isExclusive=false) ->
    timescale = @findParent('mdia').find('mdhd').timescale
    remainingTime = sec * timescale
    sampleNumber = 1
    totalTime = 0
    for entry in @entries
      numSamples = Math.ceil(remainingTime / entry.sampleDelta)
      if numSamples <= entry.sampleCount
        totalTime += numSamples * entry.sampleDelta
        totalSeconds = totalTime / timescale
        if isExclusive and (totalSeconds <= sec)
          numSamples++
          totalTime += entry.sampleDelta
          totalSeconds = totalTime / timescale
        return {
          sampleNumber: sampleNumber + numSamples
          time: totalTime
          seconds: totalSeconds
        }
      sampleNumber += entry.sampleCount
      entryDuration = entry.sampleDelta * entry.sampleCount
      totalTime += entryDuration
      remainingTime -= entryDuration

    # EOF
    return null

  # Returns a sample which represents the data at the specified time
  # (in seconds). If there is no sample at the specified time, this
  # method returns null.
  getSampleAtSeconds: (sec) ->
    timescale = @findParent('mdia').find('mdhd').timescale
    remainingTime = sec * timescale
    sampleNumber = 1
    totalTime = 0
    for entry in @entries
      sampleIndexInChunk = Math.floor(remainingTime / entry.sampleDelta)
      if sampleIndexInChunk < entry.sampleCount
        totalTime += sampleIndexInChunk * entry.sampleDelta
        return {
          sampleNumber: sampleNumber + sampleIndexInChunk
          time: totalTime
          seconds: totalTime / timescale
        }
      sampleNumber += entry.sampleCount
      entryDuration = entry.sampleDelta * entry.sampleCount
      totalTime += entryDuration
      remainingTime -= entryDuration

    # EOF
    return null

  # Returns a decoding time for the given sample number.
  # The sample number starts at 1.
  getDecodingTime: (sampleNumber) ->
    trakBox = @findParent('trak')
    elstBox = trakBox.child('edts')?.child('elst')
    mdhdBox = trakBox.child('mdia').child('mdhd')

    sampleNumber--
    if elstBox?
      time = elstBox.getEmptyDuration()
    else
      time = 0
    for entry in @entries
      if sampleNumber > entry.sampleCount
        time += entry.sampleDelta * entry.sampleCount
