]> git.vomp.tv Git - vompclient.git/blob - stream.cc
Remove manual sync buttons
[vompclient.git] / stream.cc
1 /*
2     Copyright 2005 Mark Calderbank
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "stream.h"
22
23 Stream::Stream()
24 {
25   initted = 0;
26 #ifdef NEW_DEMUXER
27   cur_packet_pos=0;
28   draintarget=NULL;
29 #endif
30 }
31
32 Stream::~Stream()
33 {
34   shutdown();
35 }
36
37 void Stream::shutdown()
38 {
39   if (initted) free(outbuf);
40   initted = 0;
41 }
42
43 int Stream::init(int bufsize)
44 {
45   outbuf = (UCHAR*) malloc(bufsize);
46   if (!outbuf) return 0;
47   bufferSize = bufsize;
48   bufferHead = 0;
49   bufferTail = 0;
50   bufferMark = -1;
51   initted = 1;
52   return 1;
53 }
54
55 void Stream::flush()
56 {
57 #ifdef NEW_DEMUXER
58   mediapackets.clear();
59 #endif
60   bufferHead = 0;
61   bufferTail = 0;
62   bufferMark = -1;
63 }
64
65 #ifndef NEW_DEMUXER
66 int Stream::put(UCHAR* inbuf, int len)
67 {
68   int ret = 0;
69   int tail = bufferTail;
70   int head = bufferHead;
71   if (tail == 0) tail = bufferSize;
72
73   if (head < tail)
74   {
75     // The free space is in one continuous chunk.
76     if (len < tail - head)
77     {
78       memcpy(outbuf + head, inbuf, len);
79       bufferHead += len;
80       ret = len;
81     }
82   }
83   else if (len <= bufferSize - head)
84   {
85     // There is enough space above the Head.
86     memcpy(outbuf + head, inbuf, len);
87     if (head + len == bufferSize)
88       bufferHead = 0;
89     else
90       bufferHead += len;
91     ret = len;
92   }
93   else if (len < tail)
94   {
95     bufferMark = head;
96     memcpy(outbuf, inbuf, len);
97     bufferHead = len;
98     ret = len;
99   }
100   return ret;
101 }
102 #else
103 int Stream::put(UCHAR* inbuf, int len)
104 {
105   int ret = 0;
106   int tail = bufferTail;
107   int head = bufferHead;
108   if (tail == 0) tail = bufferSize;
109
110   if (!draintarget) return 0;
111   MediaPacket newPacket;
112   newPacket.length=len;
113   newPacket.pos_buffer=0;
114   newPacket.recording_byte_pos=0;
115   newPacket.synched=false;
116   newPacket.disconti=false;
117   newPacket.pts=0;
118   newPacket.presentation_time=0;
119   //Extract the pts...
120   if ((inbuf[7] & 0x80) && len>14 ) {
121     newPacket.synched=true;
122     newPacket.pts=((ULLONG)(inbuf[9] & 0x0E) << 29 ) |
123                 ( (ULLONG)(inbuf[10])        << 22 ) |
124                 ( (ULLONG)(inbuf[11] & 0xFE) << 14 ) |
125                 ( (ULLONG)(inbuf[12])        <<  7 ) |
126                 ( (ULLONG)(inbuf[13] & 0xFE) >>  1 );
127   //ok we have the pts now convert it to a continously time code in 100ns units
128     newPacket.presentation_time=(ULLONG)(newPacket.pts*10000LL/90LL);
129     newPacket.presentation_time-=draintarget->SetStartOffset(newPacket.presentation_time,&newPacket.disconti);
130   }
131
132   if (head < tail)
133   {
134     // The free space is in one continuous chunk.
135     if (len < tail - head)
136     {
137       memcpy(outbuf + head, inbuf, len);
138       bufferHead += len;
139       ret = len;
140       newPacket.pos_buffer=head;
141       mediapackets.push_front(newPacket);
142     }
143   }
144   else if (len <= bufferSize - head)
145   {
146     // There is enough space above the Head.
147     memcpy(outbuf + head, inbuf, len);
148     if (head + len == bufferSize)
149       bufferHead = 0;
150     else
151       bufferHead += len;
152
153     newPacket.pos_buffer=head;
154     mediapackets.push_front(newPacket);
155
156     ret = len;
157   }
158   else if (len < tail)
159   {
160     bufferMark = head;
161     memcpy(outbuf, inbuf, len);
162     bufferHead = len;
163     ret = len;
164     newPacket.pos_buffer=0;
165     mediapackets.push_front(newPacket);
166   }
167   return ret;
168 }
169 #endif
170
171 #ifndef NEW_DEMUXER
172
173 int Stream::drain(int fd)
174 {
175   int ret = 0;
176   int head = bufferHead;
177   int tail = bufferTail;
178   int mark = bufferMark;
179   int written;
180
181   if (mark == -1 && tail > head) mark = bufferSize;
182
183   if (mark >= 0)
184   {
185     // Drain up to the marker.
186 #ifndef WIN32
187     written = write(fd, outbuf + tail, (mark - tail));
188 #else
189     written=mark-tail;
190     MILLISLEEP(1);
191 #endif
192     if (written < 0) return ret;
193     ret += written;
194     if (written == (mark - tail))
195     {
196       bufferMark = -1;
197       bufferTail = tail = 0;
198     }
199     else
200     {
201       bufferTail += written;
202       return ret;
203     }
204   }
205
206   if (tail == head) return ret; // Empty
207 #ifndef WIN32
208   written = write(fd, outbuf + tail, (head - tail));
209 #else
210   written=(head - tail);
211   MILLISLEEP(1);
212 #endif
213   if (written < 0) return ret;
214   ret += written;
215   bufferTail = tail + written;
216   return ret;
217 }
218 #else
219 int Stream::drain(DrainTarget* dt)
220 {
221   int ret = 0;
222   int written=1;
223   draintarget=dt;
224
225
226
227   if (mediapackets.empty()) {
228     return 0;
229   }
230    // using mediapackets, may be this is slower but it is more flexible
231  // while (!mediapackets.empty() && written) {
232
233   int head = bufferHead;
234   int tail = bufferTail;
235   int mark = bufferMark;
236   if (mark == -1 && tail > head) mark = bufferSize;
237   MediaPacket cur_mp=mediapackets.back();
238   written=0;
239   written=dt->DeliverMediaSample(cur_mp,outbuf,&cur_packet_pos);
240
241   ret+=written;
242
243   if (cur_packet_pos==cur_mp.length) {
244     cur_packet_pos=0;
245     mediapackets.pop_back();
246 //    if ((int)(tail+cur_mp.length) < mark) {
247     if ((((ULONG)tail)+cur_mp.length) < ((ULONG)mark))
248     {
249       bufferTail=tail+cur_mp.length;
250     } else {
251       bufferTail=0;
252       bufferMark=-1;
253     }
254
255   }
256
257   return ret;
258 }
259
260 #endif