aboutsummaryrefslogtreecommitdiff
path: root/lib/dvb/pvrparse.cpp
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2008-10-31 02:03:15 +0100
committerAndreas Oberritter <obi@saftware.de>2008-11-06 01:51:46 +0100
commit6c6704a6c897cef2aca87bd8d5a732ae1a2bac4a (patch)
treefd201d5447a95622d2c347e0fabf81c7086d9917 /lib/dvb/pvrparse.cpp
parentfe9c79a96232f5e5dd12158bf948188110412664 (diff)
downloadenigma2-6c6704a6c897cef2aca87bd8d5a732ae1a2bac4a.tar.gz
enigma2-6c6704a6c897cef2aca87bd8d5a732ae1a2bac4a.zip
Patch by Anders Holst:
* Undo "sparse-AP-fix" At March 25 a patch was checked in that makes sure that AP:s closer than half a second from each other are filtered away. I don't know the exact purpose of this fix, but I don't think it is a good idea: Besides being the cause of bugs 4 and 5 above, all seek operations are based on the AP:s, and it is a pity to cripple the precision here. And for example, when cutting movies it is important to be able to reach the right GOP boundary. (And the next fix relies on all boundaries being available.) (If you wonder, bug 5 was caused by a destructive interaction of this with the discontinuity handling.) * Hit GOP:s somewhat before GOP start It turns out that if you jump exactly to the GOP start, then that GOP is nevertheless skipped and playback starts from the GOP thereafter. However, if you jump to (at least) one frame before the GOP start, playback starts from that GOP. I don't know if this is a bug in the driver or elsewhere, but the best I can do is this workaround: Hit the GOP by jumping to half a GOP length before the GOP start. (By scanning the ts file it is of course possible to find the exact frame boundaries, but why bother since anywhere between the previous GOP start and the previous frame start will do.) Similarly, to show the first frame of a GOP, a few more frames must be included. Therefore, add half a GOP at the end of each source span. * Jump over discontinuities during AP relative seek The above two fixes together *almost* take care of bugs 1 and 2 above. Now seekRelative(1) moves one forward and seekRelative(-1) one backwards. However, at discontinuities they may get stuck. This is remedied by an extra if statement to check for discontinuities when stepping throught the AP:s in AP relative seek. * Stop after last source span In the function eDVBChannel::getNextSourceSpan there was no code to take care of the case when the seeked-to point is after the last source span. Currently it just goes on until the movie ends. I have added code for this, which takes care of bug 3, and as a fortunate bonus effect bug 6 too. (But please check my code here, I hope I can use current_offset the way I do, and return 0 size when it should stop.)
Diffstat (limited to 'lib/dvb/pvrparse.cpp')
-rw-r--r--lib/dvb/pvrparse.cpp48
1 files changed, 33 insertions, 15 deletions
diff --git a/lib/dvb/pvrparse.cpp b/lib/dvb/pvrparse.cpp
index 1b827d3c..35ba9091 100644
--- a/lib/dvb/pvrparse.cpp
+++ b/lib/dvb/pvrparse.cpp
@@ -36,8 +36,6 @@ int eMPEGStreamInformation::load(const char *filename)
return -1;
m_access_points.clear();
m_pts_to_offset.clear();
- pts_t last = -(1LL<<62);
- int loaded = 0, skipped = 0;
while (1)
{
unsigned long long d[2];
@@ -48,16 +46,9 @@ int eMPEGStreamInformation::load(const char *filename)
d[0] = bswap_64(d[0]);
d[1] = bswap_64(d[1]);
#endif
- if ((d[1] - last) > 90000/2)
- {
- m_access_points[d[0]] = d[1];
- m_pts_to_offset.insert(std::pair<pts_t,off_t>(d[1], d[0]));
- last = d[1];
- loaded++;
- } else
- skipped++;
+ m_access_points[d[0]] = d[1];
+ m_pts_to_offset.insert(std::pair<pts_t,off_t>(d[1], d[0]));
}
- eDebug("loaded %d, skipped %d", loaded, skipped);
fclose(f);
fixupDiscontinuties();
return 0;
@@ -216,30 +207,45 @@ pts_t eMPEGStreamInformation::getInterpolated(off_t offset)
return before_ts + diff;
}
-off_t eMPEGStreamInformation::getAccessPoint(pts_t ts)
+off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg)
{
/* FIXME: more efficient implementation */
off_t last = 0;
+ off_t last2 = 0;
+ pts_t lastc = 0;
for (std::map<off_t, pts_t>::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i)
{
pts_t delta = getDelta(i->first);
pts_t c = i->second - delta;
- if (c > ts)
- break;
+ if (c > ts) {
+ if (marg > 0)
+ return (last + i->first)/376*188;
+ else if (marg < 0)
+ return (last + last2)/376*188;
+ else
+ return last;
+ }
+ lastc = c;
+ last2 = last;
last = i->first;
}
- return last;
+ if (marg < 0)
+ return (last + last2)/376*188;
+ else
+ return last;
}
int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction)
{
off_t offset = getAccessPoint(start);
+ pts_t c1, c2;
std::map<off_t, pts_t>::const_iterator i = m_access_points.find(offset);
if (i == m_access_points.end())
{
eDebug("getNextAccessPoint: initial AP not found");
return -1;
}
+ c1 = i->second - getDelta(i->first);
while (direction)
{
if (direction > 0)
@@ -247,6 +253,12 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in
if (i == m_access_points.end())
return -1;
++i;
+ c2 = i->second - getDelta(i->first);
+ if (c1 == c2) { // Discontinuity
+ ++i;
+ c2 = i->second - getDelta(i->first);
+ }
+ c1 = c2;
direction--;
}
if (direction < 0)
@@ -257,6 +269,12 @@ int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, in
return -1;
}
--i;
+ c2 = i->second - getDelta(i->first);
+ if (c1 == c2) { // Discontinuity
+ --i;
+ c2 = i->second - getDelta(i->first);
+ }
+ c1 = c2;
direction++;
}
}