Merge branch 'master' of /home/tmbinc/enigma2-git into tmbinc/FixTimingBugs
[vuplus_dvbapp] / lib / dvb / dvb.cpp
index 2460943..c320fc7 100644 (file)
@@ -974,7 +974,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
        }
 #endif
 
-#if 1 /* not yet */
+#if 1 /* This codepath is required on Broadcom-based Dreamboxes (DM800, DM8000) and strips away non-I-frames. */
        if (!m_iframe_search)
                return len;
 
@@ -990,9 +990,9 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
                unsigned char *ts = data + ts_offset;
                int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
 
-               if ((d[3] == 0) && (m_pid == pid))  /* picture start */
+               if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid))  /* picture start */
                {
-                       int picture_type = (d[5] >> 3) & 7;
+                       int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
                        d += 4;
 
 //                     eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
@@ -1036,16 +1036,25 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
                        }
                } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
                {
-                       if (m_pid != pid)
+                               /* verify that this is actually a PES header, not just some ES data */
+                       if (ts[1] & 0x40) /* PUSI set */
                        {
-                               eDebug("now locked to pid %04x", pid);
-                               m_pid = pid;
+                               int payload_start = 4;
+                               if (ts[3] & 0x20) /* adaptation field present */
+                                       payload_start += ts[4] + 1; /* skip AF */
+                               if (payload_start == (offset%188)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */
+                               {
+                                       if (m_pid != pid)
+                                       {
+                                               eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]);
+                                               m_pid = pid;
+                                       }
+                               }
                        }
 //                     m_pid = 0x6e;
                        d += 4;
                } else
                        d += 4; /* ignore */
-
        }
 
        if (m_iframe_state == 1)
@@ -1200,7 +1209,7 @@ void eDVBChannel::cueSheetEvent(int event)
                {
                        off_t offset_in, offset_out;
                        pts_t pts_in = i->first, pts_out = i->second;
-                       if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
+                       if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
                        {
                                eDebug("span translation failed.\n");
                                continue;
@@ -1328,13 +1337,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                                eDebug("AP relative seeking failed!");
                        } else
                        {
-                               eDebug("next ap is %llx\n", pts);
                                pts = nextap;
+                               eDebug("next ap is %llx\n", pts);
                        }
                }
 
                off_t offset = 0;
-               if (m_tstools.getOffset(offset, pts))
+               if (m_tstools.getOffset(offset, pts, -1))
                {
                        eDebug("get offset for pts=%lld failed!", pts);
                        continue;
@@ -1408,16 +1417,29 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                }
        }
 
-       if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
-       {
-               eDebug("reached SOF");
-               m_skipmode_m = 0;
-               m_pvr_thread->sendEvent(eFilePushThread::evtUser);
+       if (m_source_span.empty()) {
+               if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
+               {
+                       eDebug("reached SOF");
+                       m_skipmode_m = 0;
+                       m_pvr_thread->sendEvent(eFilePushThread::evtUser);
+               }
+               start = current_offset;
+               size = max;
+       } else {
+               off_t tmp2, tmp = align(m_source_span.rbegin()->second, blocksize);
+               pts_t len;
+               getLength(len);
+               m_tstools.getOffset(tmp2, len, 1);
+               if (current_offset == tmp || current_offset == tmp2) {
+                       start = tmp2;
+                       size = max;
+               } else {
+                       start = tmp - align(512*1024, blocksize);
+                       size = align(512*1024, blocksize);
+               }
        }
 
-       start = current_offset;
-       size = max;
-
        eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
        return;
 }