remove generated file "config.h":
[vuplus_dvbapp] / lib / dvb / tstools.cpp
1 #include <lib/dvb/tstools.h>
2 #include <lib/base/eerror.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5
6 #include <stdio.h>
7
8 eDVBTSTools::eDVBTSTools()
9 {
10         m_fd = -1;
11         m_pid = -1;
12         m_maxrange = 256*1024;
13         
14         m_begin_valid = 0;
15         m_end_valid = 0;
16 }
17
18 eDVBTSTools::~eDVBTSTools()
19 {
20         closeFile();
21 }
22
23 int eDVBTSTools::openFile(const char *filename)
24 {
25         closeFile();
26         m_fd = ::open(filename, O_RDONLY);
27         if (m_fd < 0)
28                 return -1;
29         return 0;
30 }
31
32 void eDVBTSTools::closeFile()
33 {
34         if (m_fd >= 0)
35                 ::close(m_fd);
36 }
37
38 void eDVBTSTools::setSyncPID(int pid)
39 {
40         m_pid = pid;
41 }
42
43 void eDVBTSTools::setSearchRange(int maxrange)
44 {
45         m_maxrange = maxrange;
46 }
47
48 int eDVBTSTools::getPTS(off_t &offset, pts_t &pts)
49 {
50         if (m_fd < 0)
51                 return -1;
52
53         offset -= offset % 188;
54         
55                 // TODO: multiple files!        
56         if (lseek(m_fd, offset, SEEK_SET) < 0)
57                 return -1;
58
59         int left = m_maxrange;
60         
61         while (left >= 188)
62         {
63                 unsigned char block[188];
64                 if (read(m_fd, block, 188) != 188)
65                         break;
66                 left -= 188;
67                 offset += 188;
68                 
69                 if (block[0] != 0x47)
70                 {
71                         int i = 0;
72                         while (i < 188)
73                         {
74                                 if (block[i] == 0x47)
75                                         break;
76                                 ++i;
77                         }
78                         offset = lseek(m_fd, i - 188, SEEK_CUR);
79                         continue;
80                 }
81                 
82                 int pid = ((block[1] << 8) | block[2]) & 0x1FFF;
83                 int pusi = !!(block[1] & 0x40);
84                 
85 //              printf("PID %04x, PUSI %d\n", pid, pusi);
86                 
87                 if (m_pid >= 0)
88                         if (pid != m_pid)
89                                 continue;
90                 if (!pusi)
91                         continue;
92                 
93                         /* ok, now we have a PES header */
94                 unsigned char *pes;
95                 
96                         /* check for adaption field */
97                 if (block[3] & 0x20)
98                         pes = block + block[4] + 4 + 1;
99                 else
100                         pes = block + 4;
101                 
102                         /* somehow not a startcode. (this is invalid, since pusi was set.) ignore it. */
103                 if (pes[0] || pes[1] || (pes[2] != 1))
104                         continue;
105                 
106                 if (pes[7] & 0x80) /* PTS */
107                 {
108                         pts  = ((unsigned long long)(pes[ 9]&0xE))  << 29;
109                         pts |= ((unsigned long long)(pes[10]&0xFF)) << 22;
110                         pts |= ((unsigned long long)(pes[11]&0xFE)) << 14;
111                         pts |= ((unsigned long long)(pes[12]&0xFF)) << 7;
112                         pts |= ((unsigned long long)(pes[13]&0xFE)) >> 1;
113                         offset -= 188;
114                         return 0;
115                 }
116         }
117         
118         return -1;
119 }
120
121 void eDVBTSTools::calcBegin()
122 {
123         if (m_fd < 0)   
124                 return;
125
126         if (!m_begin_valid)
127         {
128                 m_offset_begin = 0;
129                 if (!getPTS(m_offset_begin, m_pts_begin))
130                         m_begin_valid = 1;
131         }
132 }
133
134 void eDVBTSTools::calcEnd()
135 {
136         if (m_fd < 0)   
137                 return;
138         
139         m_offset_end = lseek(m_fd, 0, SEEK_END);
140         
141         int maxiter = 10;
142         
143         while (!m_end_valid)
144         {
145                 if (!--maxiter)
146                         return;
147                 
148                 m_offset_end -= m_maxrange;
149                 if (m_offset_end < 0)
150                         m_offset_end = 0;
151                 if (!getPTS(m_offset_end, m_pts_end))
152                         m_end_valid = 1;
153                 if (!m_offset_end)
154                         return;
155         }
156 }
157
158 int eDVBTSTools::calcLen(pts_t &len)
159 {
160         calcBegin(); calcEnd();
161         if (!(m_begin_valid && m_end_valid))
162                 return -1;
163         len = m_pts_end - m_pts_begin;
164         return 0;
165 }
166
167 int eDVBTSTools::calcBitrate()
168 {
169         calcBegin(); calcEnd();
170         if (!(m_begin_valid && m_end_valid))
171                 return -1;
172
173         pts_t len_in_pts = m_pts_end - m_pts_begin;
174         off_t len_in_bytes = m_offset_end - m_offset_begin;
175         
176         if (!len_in_pts)
177                 return -1;
178         
179         unsigned long long bitrate = len_in_bytes * 90000 * 8 / len_in_pts;
180         if ((bitrate < 10000) || (bitrate > 100000000))
181                 return -1;
182         
183         return bitrate;
184 }