+int eDVBTSTools::fixupPTS(const off_t &offset, pts_t &now)
+{
+ if (m_use_streaminfo)
+ {
+ return m_streaminfo.fixupPTS(offset, now);
+ } else
+ {
+ /* for the simple case, we assume one epoch, with up to one wrap around in the middle. */
+ calcBegin();
+ if (!m_begin_valid)
+ {
+ eDebug("begin not valid, can't fixup");
+ return -1;
+ }
+
+ pts_t pos = m_pts_begin;
+ if ((now < pos) && ((pos - now) < 90000 * 10))
+ {
+ pos = 0;
+ return 0;
+ }
+
+ if (now < pos) /* wrap around */
+ now = now + 0x200000000LL - pos;
+ else
+ now -= pos;
+ return 0;
+ }
+}
+
+int eDVBTSTools::getOffset(off_t &offset, pts_t &pts)
+{
+ if (m_use_streaminfo)
+ {
+ offset = m_streaminfo.getAccessPoint(pts);
+ return 0;
+ } else
+ {
+ calcBegin(); calcEnd();
+
+ if (!m_begin_valid)
+ return -1;
+ if (!m_end_valid)
+ return -1;
+
+ if (!m_samples_taken)
+ takeSamples();
+
+ if (!m_samples.empty())
+ {
+ int maxtries = 5;
+ pts_t p = -1;
+
+ while (maxtries--)
+ {
+ /* search entry before and after */
+ std::map<pts_t, off_t>::const_iterator l = m_samples.lower_bound(pts);
+ std::map<pts_t, off_t>::const_iterator u = l;
+
+ if (l != m_samples.begin())
+ --l;
+
+ /* we could have seeked beyond the end */
+ if (u == m_samples.end())
+ {
+ /* use last segment for interpolation. */
+ if (l != m_samples.begin())
+ {
+ --u;
+ --l;
+ }
+ }
+
+ /* if we don't have enough points */
+ if (u == m_samples.end())
+ break;
+
+ pts_t pts_diff = u->first - l->first;
+ off_t offset_diff = u->second - l->second;
+
+ if (offset_diff < 0)
+ {
+ eDebug("something went wrong when taking samples.");
+ m_samples.clear();
+ takeSamples();
+ continue;
+ }
+
+ eDebug("using: %llx:%llx -> %llx:%llx", l->first, u->first, l->second, u->second);
+
+ int bitrate;
+
+ if (pts_diff)
+ bitrate = offset_diff * 90000 * 8 / pts_diff;
+ else
+ bitrate = 0;
+
+ offset = l->second;
+ offset += ((pts - l->first) * (pts_t)bitrate) / 8ULL / 90000ULL;
+ offset -= offset % 188;
+
+ p = pts;
+
+ if (!takeSample(offset, p))
+ {
+ int diff = (p - pts) / 90;
+
+ eDebug("calculated diff %d ms", diff);
+ if (abs(diff) > 300)
+ {
+ eDebug("diff to big, refining");
+ continue;
+ }
+ } else
+ eDebug("no sample taken, refinement not possible.");
+
+ break;
+ }
+
+ /* if even the first sample couldn't be taken, fall back. */
+ /* otherwise, return most refined result. */
+ if (p != -1)
+ {
+ pts = p;
+ eDebug("aborting. Taking %llx as offset for %lld", offset, pts);
+ return 0;
+ }
+ }
+
+ int bitrate = calcBitrate();
+ offset = pts * (pts_t)bitrate / 8ULL / 90000ULL;
+ eDebug("fallback, bitrate=%d, results in %016llx", bitrate, offset);
+ offset -= offset % 188;
+
+ return 0;
+ }
+}
+
+int eDVBTSTools::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction)
+{
+ if (m_use_streaminfo)
+ return m_streaminfo.getNextAccessPoint(ts, start, direction);
+ else
+ {
+ eDebug("can't get next access point without streaminfo");
+ return -1;
+ }
+}
+