1 /*
2 * archive-stream.cc --
3 *
4 * Archive stream object
5 *
6 * Copyright (c) 1997-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * @(#) $Header: /usr/mash/src/repository/mash/mash-1/archive/archive-stream.cc,v 1.17 2003/08/28 21:52:20 aswan Exp $
34 */
35
36 #include "archive/archive-stream.h"
37 #include "archive/timeval.h"
38 #include "misc/mtrace.h"
39 #include "misc/nethost.h"
40 #include "tclcl-mappings.h"
41
42 #ifndef WIN32
43 #include <unistd.h>
44 #include <pwd.h>
45 #include <sys/time.h>
46 #else
47 #include <time.h>
48 #endif
49
50 #include <sys/types.h>
51 #include <sys/types.h>
52 #include <timer.h>
53
54
55 #ifdef MTRACE
56 int ArchiveStream::count_ = 0;
57 #endif
58
59
60 /*
61 * FIXME:
62 * logical time of 0.0 is assumed to represent non-std conditions
63 * In PlaybackStream::NextEvent(), it is used to indicate that there are
64 * no more events to schedule
65 * In PlaybackStream::Clip(), it is used to indicate a non-existent
66 * start or end of clip (i.e. if start=0.0 then start from beginning,
67 * if end=0.0 then end at end-of-file)
68 */
69
70
71 /*
72 * <otcl> Class ArchiveStream
73 * FIXME base class for recording/playing media streams to/from a file
74 * on a per-source basis.
75 */
76 DEFINE_OTCL_CLASS(ArchiveStream, "ArchiveStream") {
77 INSTPROC(datafile);
78 INSTPROC(indexfile);
79 }
80
81
82 /*
83 * <otcl> Class ArchiveStream/Play
84 * FIXME base class for playing media streams from a file
85 * on a per-source basis.
86 */
87 DEFINE_ABSTRACT_OTCL_CLASS(PlaybackStream, "ArchiveStream/Play") {
88 INSTPROC(lts);
89 INSTPROC(clip);
90 }
91
92
93 /*
94 * <otcl> Class ArchiveStream/Record
95 * FIXME base class for recording media streams to a file
96 * on a per-source basis.
97 */
98 DEFINE_OTCL_CLASS(RecordStream, "ArchiveStream/Record") {
99 }
100
101
102 int
103 ArchiveStream::datafile(int argc, const char * const *argv)
104 {
105 Tcl &tcl = Tcl::instance();
106 if (argc==2) {
107 DataFile *file = DataFile_();
108 if (file==NULL || file->name()==NULL)
109 tcl.resultf("");
110 else
111 tcl.resultf("%s", file->name());
112 return TCL_OK;
113 }
114 else {
115 TclObject *file;
116 BEGIN_PARSE_ARGS(argc, argv);
117 ARG(file);
118 END_PARSE_ARGS;
119 DataFile_((DataFile*)file);
120 return TCL_OK;
121 }
122 }
123
124
125 int
126 ArchiveStream::indexfile(int argc, const char * const *argv)
127 {
128 Tcl &tcl = Tcl::instance();
129 if (argc==2) {
130 IndexFile *file = IndexFile_();
131 if (file==NULL || file->name()==NULL)
132 tcl.resultf("");
133 else
134 tcl.resultf("%s", file->name());
135 return TCL_OK;
136 }
137 else {
138 TclObject *file;
139 BEGIN_PARSE_ARGS(argc, argv);
140 ARG(file);
141 END_PARSE_ARGS;
142
143 IndexFile_((IndexFile*)file);
144 return TCL_OK;
145 }
146 }
147
148
149 int
150 PlaybackStream::lts(int argc, const char * const *argv)
151 {
152 Tcl &tcl = Tcl::instance();
153 if (argc==2) {
154 LTS *lts = LTS_();
155 if (lts==NULL || lts->name()==NULL)
156 tcl.resultf("");
157 else
158 tcl.resultf("%s", lts->name());
159 return TCL_OK;
160 }
161 else {
162 TclObject *lts;
163 BEGIN_PARSE_ARGS(argc, argv);
164 ARG(lts);
165 END_PARSE_ARGS;
166
167 LTS_((LTS*)lts);
168 return TCL_OK;
169 }
170 }
171
172
173 int
174 PlaybackStream::clip(int argc, const char * const * argv)
175 {
176 double start, end;
177 BEGIN_PARSE_ARGS(argc, argv);
178 ARG(start);
179 ARG(end);
180 END_PARSE_ARGS;
181
182 Clip(ftotv(start), ftotv(end));
183 return TCL_OK;
184 }
185
186
187
188 void
189 PlaybackStream::LTS_Changed()
190 {
191 double speed;
192 timeval next;
193
194
195 // cancel the current timer
196 cancel();
197
198 // get stats for log - not currently used
199 /*timeval tv;
200 timeval temp;
201 passwd *pw;
202 FILE *fp;
203
204 pw = getpwuid(getuid());
205 temp = LTS_()->NowLogical();
206 fp = fopen("/h/mash/archive/.log/log", "a");
207 if (is_first_ == 0) {
208 fprintf(fp, "------ \n");
209 is_first_=1;
210 }
211 tv = LTS_()->NowSystem();
212 */
213
214 speed = lts_->Speed();
215 if (speed==0.0) {
216 // we have paused the system
217 MTrace(trcArchive, ("LTS speed is zero; system has paused "
218 "(%d)", MYNUM(this)));
219 //fprintf(fp, "%s %s %u %u %u %u %u %u Pause \n", pw->pw_name, (DataFile_())->get_name(), tv.tv_sec, tv.tv_usec, temp.tv_sec, temp.tv_usec, 0, 0);
220 //fclose(fp);
221 return;
222 }
223 else {
224 MTrace(trcArchive, ("LTS has changed state; trying to "
225 "re-determine next timeout (%d)",
226 MYNUM(this)));
227 if (NextEvent(next)==TCL_ERROR) {
228 // FIXME: bgerror
229 return;
230 }
231 MTrace(trcArchive, ("Scheduling event for %s (%d)",
232 tvtoa(next), MYNUM(this)));
233 if (next.tv_sec==0 && next.tv_usec==0) {
234 // we're done! so just return
235 //fprintf(fp, "%s %s %u %u %u %u %u %u Done \n", pw->pw_name, (DataFile_())->get_name(), tv.tv_sec, tv.tv_usec, temp.tv_sec, temp.tv_usec, next.tv_sec, next.tv_usec);
236 //fclose(fp);
237 MTrace(trcArchive, ("stream is done (%d)",
238 MYNUM(this)));
239 return;
240 }
241 //fprintf(fp, "%s %s %u %u %u %u %u %u \n", pw->pw_name, (DataFile_())->get_name(), tv.tv_sec, tv.tv_usec, temp.tv_sec, temp.tv_usec, next.tv_sec, next.tv_usec);
242 //fclose(fp);
243 sched(next);
244 }
245 }
246
247
248 void
249 PlaybackStream::timeout()
250 {
251 timeval next;
252 MTrace(trcArchive|trcVerbose, ("Stream timeout occurred (%d)",
253 MYNUM(this)));
254 do {
255 DoEvent();
256 if (NextEvent(next)==TCL_ERROR) {
257 // FIXME: bgerror
258 MTrace(trcArchive, ("Error in NextEvent: %s (%d)",
259 Tcl::instance().result(),
260 MYNUM(this)));
261 return;
262 }
263 MTrace(trcVerbose|trcArchive, ("Scheduling event for %s (%d)",
264 tvtoa(next), MYNUM(this)));
265 if (next.tv_sec==0 && next.tv_usec==0) {
266 // we're done!
267 MTrace(trcArchive, ("stream is done (%d)",
268 MYNUM(this)));
269 return;
270 }
271 } while (next <= LTS_()->NowLogical());
272 sched(next);
273 }
274
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.