1 /*
2 * video-dali.cc --
3 *
4 * Creates a Dali pseudo-device for transmitting video.
5 *
6 * Copyright (c) 1993-2001 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
34 /* @(#) $Header: /usr/mash/src/repository/mash/mash-1/fx/video-dali.cc,v 1.6 2002/08/04 03:29:29 chema Exp $ */
35
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <fstream.h>
40 #include <sys/stat.h>
41
42 #include "tclcl.h"
43 #include "module.h"
44 #include "video/video-device.h"
45 #include "rgb-converter.h"
46 #include "mid/vidreps.h"
47
48
49
50 //
51 // DaliVideoCapture
52 //
53 // this is the C++ object that implements the virtual, source module device
54 // that takes Dali images and acts as a VideoCapture device plugging them
55 // into an encoder
56 //
57 // Question: Why a SourceModule instead of the more-common VideoCapture?
58 //
59 // Answer: We don't use almost anything from VideoCapture, and we don't
60 // want the tcl class to inherit from VideoCapture because that will
61 // mean it will appear in vic as one of the "Device..."s. Actually we
62 // should even be careful with the Timer-related code in VideoCapture
63 // because in our case frame-capturing is triggered by the arriving of
64 // an FX-processed frame, while in the VideoCapture case is triggered
65 // by a Timer. FIXME: More on this decision coming...
66 //
67 //
68 //
69 class DaliVideoCapture : public VideoCapture {
70 public:
71 DaliVideoCapture(int csss);
72 virtual ~DaliVideoCapture();
73
74 virtual int command(int argc, const char*const* argv);
75 inline int sameframe(const Uncompressed* uf) {
76 return ((uf->width_ == inw_) && (uf->height_ == inh_) && (uf->bp_ == frame_));
77 }
78 void init_frame(Uncompressed* input);
79
80 void recv(Buffer* bp);
81
82 #ifdef NOTDEF
83 virtual void start();
84 virtual void stop();
85 virtual void grab();
86 #endif
87 inline Module* target() { return (target_); }
88
89 protected:
90 // int capture();
91 // void format();
92 // void setsize();
93
94 // Uncompressed *input_;
95 Module* target_;
96 // EncoderModule* encoder_;
97
98 int ts_;
99
100 int fd_;
101 int csss_;
102
103 // true if capture object okay
104 int status_;
105 };
106
107
108
109 //
110 // DaliVideoCapture::DaliVideoCapture
111 //
112 // Inputs:
113 // int csss: color subsampling scheme. It may be 422, 420, or 411
114 //
115 DaliVideoCapture::DaliVideoCapture (int csss)
116 : VideoCapture(), target_(0), ts_(0), status_(0)
117 // : VideoCapture(), input_(0), target_(0), encoder_(0), ts_(0), status_(0)
118 {
119
120 if ((csss != 444) && (csss != 422) && (csss != 420) && (csss != 411)) {
121 fprintf (stderr, "DaliVideoCapture: csss %d unsupported\n", csss);
122 abort();
123 }
124 csss_ = csss;
125
126
127 // create the VideoCapture registering methods (the tcl class won't inherit
128 // from VideoCapture!)
129 Tcl& tcl = Tcl::instance();
130 char *classname_ = "DaliVideoCapture/Uncompressed";
131 char *nickname_ = "dalisource";
132 char *attributes_ = "format { 411 422 420 } size { small large cif }";
133 tcl.evalf("%s set nickname_ {%s}", classname_, nickname_);
134 tcl.evalf("%s set attributes_ {%s}", classname_, attributes_);
135
136 // register as a Device so VideoTap is happy
137 tcl.evalf("import Device");
138 tcl.evalf("Device register_class %s", classname_);
139
140 // format();
141 }
142
143
144 //
145 // DaliVideoCapture::~DaliVideoCapture
146 //
147 DaliVideoCapture::~DaliVideoCapture()
148 {
149 }
150
151
152 //
153 // DaliVideoCapture::command
154 //
155 // This method is called from tcl to change the video-capture device
156 // settings
157 //
158 int DaliVideoCapture::command(int argc, const char*const* argv)
159 {
160
161 if (argc == 3) {
162
163 // if (strcmp(argv[1], "encoder") == 0) {
164 // encoder_ = (EncoderModule*)TclObject::lookup(argv[2]);
165 // return (TCL_OK);
166 // }
167
168 if (strcmp(argv[1], "target") == 0) {
169 target_ = (Module*)TclObject::lookup(argv[2]);
170 return (TCL_OK);
171 }
172
173 // if (strcmp(argv[1], "set-frame-buffer") == 0) {
174 // VidRep *fb;
175 // fb = (VidRep *)TclObject::lookup(argv[2]);
176 // return TCL_OK;
177 // }
178
179 if (strcmp(argv[1], "port") == 0) {
180 return (TCL_OK);
181 }
182
183 if (strcmp(argv[1], "fps") == 0) {
184 // what goes here?
185 return (TCL_OK);
186 }
187
188 if (strcmp(argv[1], "bps") == 0) {
189 // what goes here?
190 return (TCL_OK);
191 }
192
193 if (strcmp(argv[1], "send") == 0) {
194 // what goes here?
195 return TCL_OK;
196 }
197
198 } else if (argc == 2) {
199 Tcl& tcl = Tcl::instance();
200
201 if (strcmp(argv[1], "status") == 0) {
202 sprintf(tcl.buffer(), "%d", status_);
203 tcl.result(tcl.buffer());
204 return TCL_OK;
205 }
206
207 if (strcmp(argv[1], "need-capwin") == 0) {
208 tcl.result("");
209 return (TCL_OK);
210 }
211
212 if (strcmp(argv[1], "recv") == 0) {
213 grab();
214 return TCL_OK;
215 }
216 }
217
218 return (VideoCapture::command(argc, argv));
219 }
220
221
222 #ifdef NOTDEF
223 //
224 // DaliVideoCapture::start
225 //
226 void DaliVideoCapture::start()
227 {
228 format();
229 }
230
231 //
232 // DaliVideoCapture::stop
233 //
234 void DaliVideoCapture::stop()
235 {
236 }
237
238
239 //
240 // DaliVideoCapture::capture
241 //
242 // This method is called every time the effect implementation calls
243 // recv from tcl.
244 //
245 int DaliVideoCapture::capture()
246 {
247 if (input_ == 0) {
248 // input frame still unmapped
249 return 0;
250 }
251
252 frame_ = (u_char *)(input_->bp_);
253 return (1);
254 }
255
256 #endif
257
258
259 void DaliVideoCapture::init_frame(Uncompressed* input)
260 {
261 switch (csss_) {
262 case 422:
263 set_size_422(input->width_, input->height_);
264 break;
265
266 case 420:
267 set_size_420(input->width_, input->height_);
268 break;
269
270 case 411:
271 set_size_411(input->width_, input->height_);
272 break;
273
274 default:
275 fprintf(stderr, "DaliVideoCapture::init_frame -> bad geometry %dx%d\n",
276 input->width_, input->height_);
277 abort();
278 }
279
280 // set_size_xxx creates a new frame, but we prefer to use the
281 // one obtained from the EffectModule
282 delete[] framebase_;
283 frame_ = framebase_ = (u_char *)(input->bp_);
284
285 // allocate the ref_ frame
286 allocref();
287 return;
288 }
289
290
291 void DaliVideoCapture::recv(Buffer* bp)
292 {
293 Uncompressed *input = (Uncompressed *)bp;
294 #ifdef NOTDEF
295 YuvFrame* f = (YuvFrame *)bp;
296
297 crvec_ = (u_char *)f->crvec_;
298 suppress(f->bp_);
299 saveblks(f->bp_);
300 for (int i = 0; i < (f->width_ * f->height_); i++) {
301 crvec_[i] = 0xff;
302 };
303
304 if (target_ != NULL) {
305 target_->recv(f);
306 }
307 #endif
308
309 if (!sameframe(input)) {
310 init_frame(input);
311 }
312
313 suppress(frame_);
314 saveblks(frame_);
315
316 YuvFrame f(input->ts_, frame_, crvec_, outw_, outh_, csss_);
317 if (target_ != NULL) {
318 target_->recv(&f);
319 }
320 }
321
322
323
324 #ifdef NOTDEF
325 void DaliVideoCapture::recv(Uncompressed* input)
326 {
327 if (!sameframe(input)) {
328 init_frame(input);
329 }
330
331 suppress(frame_);
332 saveblks(frame_);
333
334 YuvFrame f(input->ts_, frame_, crvec_, outw_, outh_, csss_);
335 target_->recv(&f);
336 }
337
338 void DaliVideoCapture::grab()
339 {
340 if (capture() == 0)
341 return;
342 suppress(frame_);
343 saveblks(frame_);
344
345 for (int i=0; i<1584; i++) {
346 crvec_[i] = 0xff;
347 };
348 ts_++;
349 YuvFrame f(ts_, frame_, crvec_, outw_, outh_, csss_);
350 target_->recv(&f);
351 }
352
353 void DaliVideoCapture::format()
354 {
355 return;
356 }
357 #endif
358
359
360 static class DaliVideoCaptureClass : public TclClass {
361 public:
362 DaliVideoCaptureClass() : TclClass("DaliVideoCapture/Uncompressed") {}
363 TclObject* create(int argc, const char*const* argv) {
364 if (argc != 5) {
365 printf("Invalid arguments passed to DaliVideoCaptureClass\n");
366 return (0);
367 }
368 if (strcmp(argv[4], "422") == 0) {
369 return (new DaliVideoCapture(422));
370 } else if (strcmp(argv[4], "411") == 0) {
371 return (new DaliVideoCapture(411));
372 } else if (strcmp(argv[4], "420") == 0) {
373 return (new DaliVideoCapture(420));
374 } else if (strcmp(argv[4], "cif") == 0) {
375 return (new DaliVideoCapture(420));
376 } else {
377 printf("Invalid type passed to DaliVideoCaptureClass (%s)\n", argv[4]);
378 }
379 return (0);
380 }
381 } dalisourcemodule_class;
382
383
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.