00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <cstddef>
00039 #include <vector>
00040
00041 #include "Component/GlobalOpts.H"
00042 #include "Component/ModelOptionDef.H"
00043 #include "Component/OptionManager.H"
00044 #include "Component/Plugin.H"
00045 #include "Devices/DC1394Grabber2.H"
00046 #include "Devices/DiskDataStream.H"
00047 #include "Devices/IEEE1394grabber.H"
00048 #include "Devices/QuickTimeGrabber.H"
00049 #include "Devices/RTSPGrabber.H"
00050 #include "Devices/V4L2grabber.H"
00051 #include "Devices/V4Lgrabber.H"
00052 #include "Devices/KinectGrabber.H"
00053 #include "Devices/OpenNIGrabber.H"
00054 #include "GUI/ImageDisplayStream.H"
00055
00056 #include "Devices/XCgrabber.H"
00057 #include "Devices/XCgrabberFlex.H"
00058 #include "Media/FrameSeries.H"
00059
00060 #ifdef INVT_HAVE_QT4
00061 # include "GUI/QtDisplayStream4.H"
00062 #else
00063 #ifdef INVT_HAVE_QT3
00064 # include "GUI/QtDisplayStream.H"
00065 #endif
00066 #endif
00067
00068 #include "GUI/SDLdisplayStream.H"
00069 #include "Image/CutPaste.H"
00070 #include "Image/Image.H"
00071 #include "Image/Layout.H"
00072 #include "Image/Pixels.H"
00073 #include "Image/ShapeOps.H"
00074 #include "Media/FrameCounter.H"
00075 #include "Media/MediaOpts.H"
00076 #include "Media/MgzInputStream.H"
00077 #include "Media/MgzJInputStream.H"
00078 #include "Media/MgzOutputStream.H"
00079 #include "Media/MgzJOutputStream.H"
00080 #include "Media/MpegInputStream.H"
00081 #include "Media/MpegOutputStream.H"
00082 #include "Media/HttpOutputStream.H"
00083 #include "Media/MrawvInputStream.H"
00084 #include "Media/MrawvOutputStream.H"
00085 #include "Media/NullOutputStream.H"
00086 #include "Media/SequenceFileStream.H"
00087 #include "Media/UcbMpegOutputStream.H"
00088 #include "Raster/GenericFrame.H"
00089 #include "Transport/BobDeinterlacer.H"
00090 #include "Transport/BufferedFrameIstream.H"
00091 #include "Transport/CoerceVideoFormatOfilt.H"
00092 #include "Transport/ColorbarsInput.H"
00093 #include "Transport/ColorizeOfilt.H"
00094 #include "Transport/FrameInfo.H"
00095 #include "Transport/FrameIstreamFactory.H"
00096 #include "Transport/FrameOstreamFactory.H"
00097 #include "Transport/GameOfLifeInput.H"
00098 #include "Transport/HalfFieldDeinterlacer.H"
00099 #include "Transport/HashOutputSeries.H"
00100 #include "Transport/InfoOutputSeries.H"
00101 #include "Transport/LuminanceOfilt.H"
00102 #include "Transport/RandomInput.H"
00103 #include "Transport/DotStimuli.H"
00104 #include "Transport/BarStimuli.H"
00105 #include "Transport/ShiftedImage.H"
00106 #include "Transport/RasterInputSeries.H"
00107 #include "Transport/RasterOutputSeries.H"
00108 #include "Transport/RasterlistInputSeries.H"
00109 #include "Transport/SplitRgbOfilt.H"
00110 #include "Transport/StatsOutputSeries.H"
00111 #include "Transport/TransportOpts.H"
00112 #include "Transport/World2DInput.H"
00113 #include "Transport/World3DInput.H"
00114 #include "Transport/XMLInput.H"
00115 #include "Transport/Stimulus2D.H"
00116 #include "Util/AllocAux.H"
00117 #include "Util/TextLog.H"
00118 #include "Util/log.H"
00119 #include "Util/sformat.H"
00120
00121
00122
00123 namespace
00124 {
00125 bool isRectEmpty(const Rectangle& rect)
00126 {
00127 return
00128 (rect.isValid() == false)
00129 ||
00130 (rect.area() == 0);
00131 }
00132
00133 template <class T>
00134 Image<T> doResizeImage(const Image<T>& input,
00135 const Rectangle& rect,
00136 const Dims& dims,
00137 const int zoom,
00138 const bool preserveAspect)
00139 {
00140
00141
00142 if (!input.initialized()) return input;
00143
00144 if (dims.isEmpty() && zoom == 0) return input;
00145
00146 Image<T> cropped = input;
00147
00148 if (!isRectEmpty(rect))
00149 {
00150 cropped = crop(input, rect, true);
00151 }
00152
00153 if (zoom < 0)
00154 {
00155 const Dims zoomout(std::max(cropped.getWidth() >> (-zoom), 1),
00156 std::max(cropped.getHeight() >> (-zoom), 1));
00157
00158 cropped = rescale(cropped, zoomout);
00159 }
00160 else if (zoom > 0)
00161 {
00162 cropped = zoomXY(cropped, 1 << zoom, 1 << zoom);
00163 }
00164
00165 if (preserveAspect)
00166 {
00167 Image<T> res(dims, ZEROS);
00168 T bg = T(); bg += 64;
00169 inplaceEmbed(res, cropped, res.getBounds(), bg, true);
00170 return res;
00171 }
00172
00173 if (dims.isNonEmpty())
00174 return rescale(cropped, dims);
00175
00176 return cropped;
00177 }
00178
00179 GenericFrame doResizeFrame(const GenericFrame& input,
00180 const Rectangle& rect,
00181 const Dims& dims,
00182 const int zoom,
00183 const bool preserveAspect)
00184 {
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 if (zoom == 0
00198 && (dims.isEmpty() || dims == input.getDims())
00199 && !preserveAspect)
00200 return input;
00201
00202 switch (input.nativeType())
00203 {
00204 case GenericFrame::NONE:
00205 return GenericFrame();
00206
00207 case GenericFrame::RGB_U8:
00208 return GenericFrame(doResizeImage(input.asRgbU8(),
00209 rect, dims, zoom, preserveAspect));
00210
00211 case GenericFrame::RGBD:
00212 return GenericFrame(doResizeImage(input.asRgbU8(), rect, dims, zoom, preserveAspect),
00213 doResizeImage(input.asGrayU16(), rect, dims, zoom, preserveAspect));
00214
00215 case GenericFrame::RGB_F32:
00216 return GenericFrame(doResizeImage(input.asRgbF32(),
00217 rect, dims, zoom, preserveAspect),
00218 input.floatFlags());
00219
00220 case GenericFrame::GRAY_U8:
00221 return GenericFrame(doResizeImage(input.asGrayU8(),
00222 rect, dims, zoom, preserveAspect));
00223
00224 case GenericFrame::GRAY_F32:
00225 return GenericFrame(doResizeImage(input.asGrayF32(),
00226 rect, dims, zoom, preserveAspect),
00227 input.floatFlags());
00228
00229 case GenericFrame::VIDEO:
00230
00231
00232
00233 return GenericFrame(doResizeImage(input.asRgb(),
00234 rect, dims, zoom, preserveAspect));
00235
00236 case GenericFrame::RGB_U16:
00237 return GenericFrame(); break;
00238 case GenericFrame::GRAY_U16:
00239 return GenericFrame(); break;
00240
00241 }
00242
00243 ASSERT(0); return GenericFrame();
00244 }
00245
00246
00247
00248
00249
00250
00251
00252 OptionManager* init_manager = 0;
00253
00254 pthread_once_t istream_init_once = PTHREAD_ONCE_INIT;
00255
00256 void istream_init()
00257 {
00258 ASSERT(init_manager != 0);
00259
00260 OptionManager& mgr = *init_manager;
00261
00262 ComponentFactory<FrameIstream>& inTypeFactory = getFrameIstreamTypeFactory();
00263
00264
00265
00266
00267
00268
00269
00270 inTypeFactory.registerType<RasterInputSeries>("raster", mgr);
00271 inTypeFactory.registerType<RasterlistInputSeries>("rasterlist", mgr);
00272 inTypeFactory.registerType<InputMPEGStream>("mpeg", mgr);
00273 inTypeFactory.registerType<InputMPEGStream>("movie", mgr);
00274 inTypeFactory.registerType<RandomInput>("random", mgr);
00275 inTypeFactory.registerType<DotStimuli>("dots", mgr);
00276 inTypeFactory.registerType<BarStimuli>("bars", mgr);
00277 inTypeFactory.registerType<ShiftedImage>("shiftedImage", mgr);
00278 inTypeFactory.registerType<GameOfLifeInput>("life", mgr);
00279 inTypeFactory.registerType<World2DInput>("World2D", mgr);
00280 inTypeFactory.registerType<World3DInput>("World3D", mgr);
00281 inTypeFactory.registerType<Stimulus2D>("stimulus2D", mgr);
00282 inTypeFactory.registerType<XMLInput>("xmlfile", mgr);
00283 #ifdef HAVE_LINUX_VIDEODEV_H
00284 inTypeFactory.registerType<V4Lgrabber>("v4l", mgr);
00285 #endif
00286 #ifdef HAVE_LINUX_VIDEODEV2_H
00287 inTypeFactory.registerType<V4L2grabber>("v4l2", mgr);
00288 #endif
00289 inTypeFactory.registerType<IEEE1394grabber>("ieee1394", mgr);
00290 #ifdef HAVE_XCLIB
00291 inTypeFactory.registerType<XCgrabber>("XC", mgr);
00292 #endif
00293 #ifdef HAVE_XCLIB
00294 inTypeFactory.registerType<XCgrabberFlex>("XCFLEX", mgr);
00295 #endif
00296 inTypeFactory.registerType<DC1394Grabber2>("dc1394v2", mgr);
00297 inTypeFactory.registerType<QuickTimeGrabber>("qtgrab", mgr);
00298 #ifdef INVT_HAVE_LIBFREENECT
00299 inTypeFactory.registerType<KinectGrabber>("kinect", mgr);
00300 #endif
00301 #ifdef INVT_HAVE_OPENNI
00302 inTypeFactory.registerType<OpenNIGrabber>("openni", mgr);
00303 #endif
00304 inTypeFactory.registerType<RTSPGrabber>("rtsp", mgr);
00305 inTypeFactory.registerType<ColorbarsInput>("colorbars", mgr);
00306 inTypeFactory.registerType<BobDeinterlacer>("bob", mgr);
00307 inTypeFactory.registerType<HalfFieldDeinterlacer<true> >("bhf", mgr);
00308 inTypeFactory.registerType<HalfFieldDeinterlacer<false> >("thf", mgr);
00309 inTypeFactory.registerType<MgzInputStream>("mgz", mgr);
00310 inTypeFactory.registerType<MgzJInputStream>("mgzJ", mgr);
00311 inTypeFactory.registerType<BufferedFrameIstream>("buf", mgr);
00312 inTypeFactory.registerType<MrawvInputStream>("mraw", mgr);
00313
00314 inTypeFactory.set_fallback
00315 (rutz::make_shared(new PluginFallback(init_manager, "FrameIstream")));
00316
00317 ComponentFactory<FrameIstream>& inExtFactory = getFrameIstreamExtFactory();
00318
00319
00320
00321
00322
00323
00324
00325 inExtFactory.registerType<RasterInputSeries>("pnm", mgr);
00326 inExtFactory.registerType<RasterInputSeries>("pgm", mgr);
00327 inExtFactory.registerType<RasterInputSeries>("ppm", mgr);
00328 inExtFactory.registerType<RasterInputSeries>("pbm", mgr);
00329 inExtFactory.registerType<RasterInputSeries>("pfm", mgr);
00330 inExtFactory.registerType<RasterInputSeries>("png", mgr);
00331 inExtFactory.registerType<RasterInputSeries>("jpeg", mgr);
00332 inExtFactory.registerType<RasterInputSeries>("jpg", mgr);
00333 inExtFactory.registerType<RasterInputSeries>("dpx", mgr);
00334
00335 inExtFactory.registerType<RasterInputSeries>("grey", mgr);
00336 inExtFactory.registerType<RasterInputSeries>("rgb555", mgr);
00337 inExtFactory.registerType<RasterInputSeries>("rgb565", mgr);
00338 inExtFactory.registerType<RasterInputSeries>("rgb24", mgr);
00339 inExtFactory.registerType<RasterInputSeries>("rgb32", mgr);
00340 inExtFactory.registerType<RasterInputSeries>("yuv24", mgr);
00341 inExtFactory.registerType<RasterInputSeries>("yuyv", mgr);
00342 inExtFactory.registerType<RasterInputSeries>("uyvy", mgr);
00343 inExtFactory.registerType<RasterInputSeries>("yuv444", mgr);
00344 inExtFactory.registerType<RasterInputSeries>("yuv422", mgr);
00345 inExtFactory.registerType<RasterInputSeries>("yuv411", mgr);
00346 inExtFactory.registerType<RasterInputSeries>("yuv420", mgr);
00347 inExtFactory.registerType<RasterInputSeries>("yuv410", mgr);
00348 inExtFactory.registerType<RasterInputSeries>("yuv444p", mgr);
00349 inExtFactory.registerType<RasterInputSeries>("yuv422p", mgr);
00350 inExtFactory.registerType<RasterInputSeries>("yuv411p", mgr);
00351 inExtFactory.registerType<RasterInputSeries>("yuv420p", mgr);
00352 inExtFactory.registerType<RasterInputSeries>("yuv410p", mgr);
00353
00354 inExtFactory.registerType<RasterInputSeries>("grey.gz", mgr);
00355 inExtFactory.registerType<RasterInputSeries>("rgb555.gz", mgr);
00356 inExtFactory.registerType<RasterInputSeries>("rgb565.gz", mgr);
00357 inExtFactory.registerType<RasterInputSeries>("rgb24.gz", mgr);
00358 inExtFactory.registerType<RasterInputSeries>("rgb32.gz", mgr);
00359 inExtFactory.registerType<RasterInputSeries>("yuv24.gz", mgr);
00360 inExtFactory.registerType<RasterInputSeries>("yuyv.gz", mgr);
00361 inExtFactory.registerType<RasterInputSeries>("uyvy.gz", mgr);
00362 inExtFactory.registerType<RasterInputSeries>("yuv444.gz", mgr);
00363 inExtFactory.registerType<RasterInputSeries>("yuv422.gz", mgr);
00364 inExtFactory.registerType<RasterInputSeries>("yuv411.gz", mgr);
00365 inExtFactory.registerType<RasterInputSeries>("yuv420.gz", mgr);
00366 inExtFactory.registerType<RasterInputSeries>("yuv410.gz", mgr);
00367 inExtFactory.registerType<RasterInputSeries>("yuv444p.gz", mgr);
00368 inExtFactory.registerType<RasterInputSeries>("yuv422p.gz", mgr);
00369 inExtFactory.registerType<RasterInputSeries>("yuv411p.gz", mgr);
00370 inExtFactory.registerType<RasterInputSeries>("yuv420p.gz", mgr);
00371 inExtFactory.registerType<RasterInputSeries>("yuv410p.gz", mgr);
00372
00373 inExtFactory.registerType<RasterInputSeries>("grey.bz2", mgr);
00374 inExtFactory.registerType<RasterInputSeries>("rgb555.bz2", mgr);
00375 inExtFactory.registerType<RasterInputSeries>("rgb565.bz2", mgr);
00376 inExtFactory.registerType<RasterInputSeries>("rgb24.bz2", mgr);
00377 inExtFactory.registerType<RasterInputSeries>("rgb32.bz2", mgr);
00378 inExtFactory.registerType<RasterInputSeries>("yuv24.bz2", mgr);
00379 inExtFactory.registerType<RasterInputSeries>("yuyv.bz2", mgr);
00380 inExtFactory.registerType<RasterInputSeries>("uyvy.bz2", mgr);
00381 inExtFactory.registerType<RasterInputSeries>("yuv444.bz2", mgr);
00382 inExtFactory.registerType<RasterInputSeries>("yuv422.bz2", mgr);
00383 inExtFactory.registerType<RasterInputSeries>("yuv411.bz2", mgr);
00384 inExtFactory.registerType<RasterInputSeries>("yuv420.bz2", mgr);
00385 inExtFactory.registerType<RasterInputSeries>("yuv410.bz2", mgr);
00386 inExtFactory.registerType<RasterInputSeries>("yuv444p.bz2", mgr);
00387 inExtFactory.registerType<RasterInputSeries>("yuv422p.bz2", mgr);
00388 inExtFactory.registerType<RasterInputSeries>("yuv411p.bz2", mgr);
00389 inExtFactory.registerType<RasterInputSeries>("yuv420p.bz2", mgr);
00390 inExtFactory.registerType<RasterInputSeries>("yuv410p.bz2", mgr);
00391
00392 inExtFactory.registerType<InputMPEGStream>("avi", mgr);
00393 inExtFactory.registerType<InputMPEGStream>("mpg", mgr);
00394 inExtFactory.registerType<InputMPEGStream>("mpeg", mgr);
00395 inExtFactory.registerType<InputMPEGStream>("m4v", mgr);
00396 inExtFactory.registerType<InputMPEGStream>("mov", mgr);
00397 inExtFactory.registerType<InputMPEGStream>("flv", mgr);
00398 inExtFactory.registerType<InputMPEGStream>("dv", mgr);
00399 inExtFactory.registerType<InputMPEGStream>("asf", mgr);
00400 inExtFactory.registerType<InputMPEGStream>("wmv", mgr);
00401 inExtFactory.registerType<InputMPEGStream>("m2ts", mgr);
00402
00403 inExtFactory.registerType<MgzInputStream>("mgz", mgr);
00404 inExtFactory.registerType<MgzJInputStream>("mgzJ", mgr);
00405
00406 inExtFactory.registerType<MrawvInputStream>("mgrey", mgr);
00407 inExtFactory.registerType<MrawvInputStream>("mrgb555", mgr);
00408 inExtFactory.registerType<MrawvInputStream>("mrgb565", mgr);
00409 inExtFactory.registerType<MrawvInputStream>("mrgb24", mgr);
00410 inExtFactory.registerType<MrawvInputStream>("mrgb32", mgr);
00411 inExtFactory.registerType<MrawvInputStream>("myuv24", mgr);
00412 inExtFactory.registerType<MrawvInputStream>("myuyv", mgr);
00413 inExtFactory.registerType<MrawvInputStream>("muyvy", mgr);
00414 inExtFactory.registerType<MrawvInputStream>("myuv444", mgr);
00415 inExtFactory.registerType<MrawvInputStream>("myuv422", mgr);
00416 inExtFactory.registerType<MrawvInputStream>("myuv411", mgr);
00417 inExtFactory.registerType<MrawvInputStream>("myuv420", mgr);
00418 inExtFactory.registerType<MrawvInputStream>("myuv410", mgr);
00419 inExtFactory.registerType<MrawvInputStream>("myuv444p", mgr);
00420 inExtFactory.registerType<MrawvInputStream>("myuv422p", mgr);
00421 inExtFactory.registerType<MrawvInputStream>("myuv411p", mgr);
00422 inExtFactory.registerType<MrawvInputStream>("myuv420p", mgr);
00423 inExtFactory.registerType<MrawvInputStream>("myuv410p", mgr);
00424
00425 inExtFactory.registerType<MrawvInputStream>("mgrey.gz", mgr);
00426 inExtFactory.registerType<MrawvInputStream>("mrgb555.gz", mgr);
00427 inExtFactory.registerType<MrawvInputStream>("mrgb565.gz", mgr);
00428 inExtFactory.registerType<MrawvInputStream>("mrgb24.gz", mgr);
00429 inExtFactory.registerType<MrawvInputStream>("mrgb32.gz", mgr);
00430 inExtFactory.registerType<MrawvInputStream>("myuv24.gz", mgr);
00431 inExtFactory.registerType<MrawvInputStream>("myuyv.gz", mgr);
00432 inExtFactory.registerType<MrawvInputStream>("muyvy.gz", mgr);
00433 inExtFactory.registerType<MrawvInputStream>("myuv444.gz", mgr);
00434 inExtFactory.registerType<MrawvInputStream>("myuv422.gz", mgr);
00435 inExtFactory.registerType<MrawvInputStream>("myuv411.gz", mgr);
00436 inExtFactory.registerType<MrawvInputStream>("myuv420.gz", mgr);
00437 inExtFactory.registerType<MrawvInputStream>("myuv410.gz", mgr);
00438 inExtFactory.registerType<MrawvInputStream>("myuv444p.gz", mgr);
00439 inExtFactory.registerType<MrawvInputStream>("myuv422p.gz", mgr);
00440 inExtFactory.registerType<MrawvInputStream>("myuv411p.gz", mgr);
00441 inExtFactory.registerType<MrawvInputStream>("myuv420p.gz", mgr);
00442 inExtFactory.registerType<MrawvInputStream>("myuv410p.gz", mgr);
00443
00444 inExtFactory.registerType<MrawvInputStream>("mgrey.bz2", mgr);
00445 inExtFactory.registerType<MrawvInputStream>("mrgb555.bz2", mgr);
00446 inExtFactory.registerType<MrawvInputStream>("mrgb565.bz2", mgr);
00447 inExtFactory.registerType<MrawvInputStream>("mrgb24.bz2", mgr);
00448 inExtFactory.registerType<MrawvInputStream>("mrgb32.bz2", mgr);
00449 inExtFactory.registerType<MrawvInputStream>("myuv24.bz2", mgr);
00450 inExtFactory.registerType<MrawvInputStream>("myuyv.bz2", mgr);
00451 inExtFactory.registerType<MrawvInputStream>("muyvy.bz2", mgr);
00452 inExtFactory.registerType<MrawvInputStream>("myuv444.bz2", mgr);
00453 inExtFactory.registerType<MrawvInputStream>("myuv422.bz2", mgr);
00454 inExtFactory.registerType<MrawvInputStream>("myuv411.bz2", mgr);
00455 inExtFactory.registerType<MrawvInputStream>("myuv420.bz2", mgr);
00456 inExtFactory.registerType<MrawvInputStream>("myuv410.bz2", mgr);
00457 inExtFactory.registerType<MrawvInputStream>("myuv444p.bz2", mgr);
00458 inExtFactory.registerType<MrawvInputStream>("myuv422p.bz2", mgr);
00459 inExtFactory.registerType<MrawvInputStream>("myuv411p.bz2", mgr);
00460 inExtFactory.registerType<MrawvInputStream>("myuv420p.bz2", mgr);
00461 inExtFactory.registerType<MrawvInputStream>("myuv410p.bz2", mgr);
00462
00463 inExtFactory.registerType<XMLInput>("xml", mgr);
00464 inExtFactory.registerType<SequenceFileStream>("seq", mgr);
00465 inExtFactory.registerType<Stimulus2D>("stim2d", mgr);
00466 }
00467
00468 pthread_once_t ostream_init_once = PTHREAD_ONCE_INIT;
00469
00470 void ostream_init()
00471 {
00472 ASSERT(init_manager != 0);
00473
00474 OptionManager& mgr = *init_manager;
00475
00476 ComponentFactory<FrameOstream>& outTypeFactory = getFrameOstreamTypeFactory();
00477
00478
00479
00480
00481
00482
00483
00484 outTypeFactory.registerType<GenericRasterOutputSeries>("raster", mgr);
00485 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("pnm", mgr);
00486 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("pgm", mgr);
00487 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("ppm", mgr);
00488 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("pbm", mgr);
00489 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_PFM> >("pfm", mgr);
00490 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_PNG> >("png", mgr);
00491 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_RAW_VIDEO> >("rawvideo", mgr);
00492 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_TXT> >("txt", mgr);
00493 outTypeFactory.registerType<FixedRasterOutputSeries<RASFMT_CCODE> >("ccode", mgr);
00494
00495 outTypeFactory.registerType<DiskDataStream>("bkg-rawvideo", mgr);
00496
00497 outTypeFactory.registerType<ImageDisplayStream>("display", mgr);
00498 #ifdef HAVE_SDL_SDL_H
00499 outTypeFactory.registerType<SDLdisplayStream>("sdl", mgr);
00500 #endif
00501 #if defined(INVT_HAVE_QT3) || defined(INVT_HAVE_QT4)
00502 outTypeFactory.registerType<QtDisplayStream>("qt", mgr);
00503 #endif
00504 #ifdef INVT_HAVE_AVCODEC
00505 outTypeFactory.registerType<OutputMPEGStream>("mpeg", mgr);
00506 outTypeFactory.registerType<OutputMPEGStream>("movie", mgr);
00507 outTypeFactory.registerType<OutputHttpStream>("http", mgr);
00508 #endif
00509 #ifdef MPEGENCODE_PROG
00510 outTypeFactory.registerType<UcbMpegOutputStream>("ucbmpeg", mgr);
00511 #endif
00512 outTypeFactory.registerType<HashOutputSeries>("hash", mgr);
00513 outTypeFactory.registerType<InfoOutputSeries>("info", mgr);
00514 outTypeFactory.registerType<StatsOutputSeries>("stats", mgr);
00515 outTypeFactory.registerType<MgzOutputStream>("mgz", mgr);
00516 outTypeFactory.registerType<MgzJOutputStream>("mgzJ", mgr);
00517 outTypeFactory.registerType<MrawvOutputStream>("mraw", mgr);
00518 outTypeFactory.registerType<NullOutputStream>("null", mgr);
00519 outTypeFactory.registerType<SplitRgbOfilt>("splitrgb", mgr);
00520 outTypeFactory.registerType<LuminanceOfilt>("luminance", mgr);
00521 outTypeFactory.registerType<ColorizeOfilt>("colorize", mgr);
00522
00523 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_GREY> >("coerce-grey", mgr);
00524 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_RGB555> >("coerce-rgb555", mgr);
00525 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_RGB565> >("coerce-rgb565", mgr);
00526 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_RGB24> >("coerce-rgb24", mgr);
00527 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_RGB32> >("coerce-rgb32", mgr);
00528 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV24> >("coerce-yuv24", mgr);
00529 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUYV> >("coerce-yuyv", mgr);
00530 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_UYVY> >("coerce-uyvy", mgr);
00531 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV444> >("coerce-yuv444", mgr);
00532 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV422> >("coerce-yuv422", mgr);
00533 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV411> >("coerce-yuv411", mgr);
00534 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV444P> >("coerce-yuv444p", mgr);
00535 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV422P> >("coerce-yuv422p", mgr);
00536 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV411P> >("coerce-yuv411p", mgr);
00537 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV420P> >("coerce-yuv420p", mgr);
00538 outTypeFactory.registerType<TCoerceVideoFormatOfilt<VIDFMT_YUV410P> >("coerce-yuv410p", mgr);
00539
00540 outTypeFactory.set_fallback
00541 (rutz::make_shared(new PluginFallback(init_manager, "FrameOstream")));
00542
00543 ComponentFactory<FrameOstream>& outExtFactory = getFrameOstreamExtFactory();
00544
00545
00546
00547
00548
00549
00550
00551 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("pnm", mgr);
00552 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("pgm", mgr);
00553 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("ppm", mgr);
00554 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_PNM> >("pbm", mgr);
00555 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_PFM> >("pfm", mgr);
00556 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_PNG> >("png", mgr);
00557 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_TXT> >("txt", mgr);
00558 outExtFactory.registerType<FixedRasterOutputSeries<RASFMT_CCODE> >("C", mgr);
00559
00560 #ifdef INVT_HAVE_AVCODEC
00561 outExtFactory.registerType<OutputMPEGStream>("mpg", mgr);
00562 outExtFactory.registerType<OutputMPEGStream>("mpeg", mgr);
00563 outExtFactory.registerType<OutputMPEGStream>("m4v", mgr);
00564 #endif
00565
00566 outExtFactory.registerType<MgzOutputStream>("mgz", mgr);
00567 outExtFactory.registerType<MgzJOutputStream>("mgzJ", mgr);
00568 }
00569 }
00570
00571
00572
00573
00574
00575 struct InputFrameSeries::Impl
00576 {
00577 Impl(OptionManager& mgr, const FrameRange& range, bool wrap=false)
00578 :
00579 source(),
00580 sourceDescription(),
00581 echoes(),
00582 numEchoed(0),
00583 inputEof(false),
00584 lastUpdateTime(SimTime::ZERO()),
00585 counter(range, wrap)
00586 {
00587 }
00588
00589 nub::soft_ref<FrameIstream> source;
00590 std::string sourceDescription;
00591 std::vector<nub::ref<FrameOstream> > echoes;
00592
00593 int numEchoed;
00594
00595 bool inputEof;
00596
00597 SimTime lastUpdateTime;
00598
00599 FrameCounter counter;
00600
00601 bool setFrameNumber(int n)
00602 {
00603
00604
00605 if(!this->source->supportsSeek() && this->counter.currentFrame() > n) return false;
00606
00607 return this->counter.setCurrent(n);
00608 }
00609
00610
00611
00612 GenericFrame readFrame(InputFrameSeries* self)
00613 {
00614
00615 ASSERT(this->source.is_valid());
00616
00617 const int fnum = this->counter.currentFrame();
00618 if (this->source->setFrameNumber(fnum))
00619 {
00620 const GenericFrame ima =
00621 doResizeFrame(this->source->readFrame(),
00622 self->itsCropRect.getVal(),
00623 self->itsDims.getVal(),
00624 0,
00625 self->itsPreserveAspect.getVal());
00626
00627 if (ima.initialized())
00628 {
00629 LDEBUG("%s frame %d at %.2fms",
00630 self->tagName().c_str(), fnum,
00631 this->lastUpdateTime.msecs());
00632
00633 textLog(self->itsLogFile.getVal(),
00634 self->tagName().c_str(),
00635 sformat("frame %d", fnum),
00636 this->lastUpdateTime);
00637
00638
00639 for (uint i = 0; i < this->echoes.size(); ++i)
00640 {
00641 this->echoes[i]->setFrameNumber(fnum);
00642 this->echoes[i]->writeFrame
00643 (ima, "input-echo",
00644 FrameInfo("copy of input frame", SRC_POS));
00645 ++this->numEchoed;
00646 }
00647
00648
00649
00650 invt_allocation_set_stats_units(ima.frameSpec().dims.sz());
00651
00652 return ima;
00653 }
00654 else
00655 LINFO("input exhausted (readFrame() returned empty)");
00656 }
00657 else
00658 LINFO("input exhausted (setFrameNumber() returned false)");
00659
00660
00661
00662 this->inputEof = true;
00663
00664 return GenericFrame();
00665 }
00666 };
00667
00668 InputFrameSeries::InputFrameSeries(OptionManager& mgr,
00669 const std::string& descrName,
00670 const std::string& tag) :
00671 FrameIstream(mgr, "Input "+descrName, "Input"+tag),
00672 itsLogFile(&OPT_TextLogFile, this),
00673 itsTestMode(&OPT_TestMode, this),
00674 itsFrameRange(&OPT_InputFrameRange, this),
00675 itsFrameWrap(&OPT_InputFramesWrap, this),
00676 itsCropRect(&OPT_InputFrameCrop, this),
00677 itsDims(&OPT_InputFrameDims, this),
00678 itsPreserveAspect(&OPT_InputPreserveAspect, this),
00679 itsZeroNumberFrames(&OPT_ZeroNumberFrames, this),
00680 itsFrameSource(&OPT_InputFrameSource, this),
00681 itsInOut(&OPT_InputOutputComboSpec, this),
00682 itsInputEcho(&OPT_InputEchoDest, this),
00683 itsWaitForUser(&OPT_WaitForUser, this),
00684 itsKeepGoing(&OPT_KeepGoing, this),
00685 rep(new Impl(mgr, itsFrameRange.getVal(), itsFrameWrap.getVal()))
00686 {
00687 init_manager = &mgr;
00688 pthread_once(&istream_init_once, &istream_init);
00689 pthread_once(&ostream_init_once, &ostream_init);
00690 }
00691
00692
00693 InputFrameSeries::~InputFrameSeries()
00694 {
00695 delete rep;
00696 }
00697
00698
00699 void InputFrameSeries::reset1()
00700 {
00701
00702 rep->counter.reset(itsFrameRange.getVal(), false, itsFrameWrap.getVal());
00703 rep->numEchoed = 0;
00704 rep->inputEof = false;
00705
00706
00707 FrameIstream::reset1();
00708 }
00709
00710
00711
00712 void InputFrameSeries::setFrameDims(Dims d)
00713 {
00714 OptionManager& mgr = getManager();
00715 mgr.setOptionValString(&OPT_InputFrameDims,
00716 convertToString(d));
00717 }
00718
00719
00720 Dims InputFrameSeries::getFrameDims()
00721 {
00722 return itsDims.getVal();
00723 }
00724
00725
00726
00727
00728 void InputFrameSeries::paramChanged(ModelParamBase* const param,
00729 const bool valueChanged,
00730 ParamClient::ChangeStatus* status)
00731 {
00732 FrameIstream::paramChanged(param, valueChanged, status);
00733
00734 if (param == &itsFrameSource)
00735 {
00736 if (itsFrameSource.getVal() != "")
00737 this->setFrameSource(itsFrameSource.getVal());
00738 }
00739 else if (param == &itsInOut)
00740 {
00741 if (itsInOut.getVal() != "")
00742 this->setFrameSource(itsInOut.getVal());
00743 }
00744 else if (param == &itsInputEcho)
00745 {
00746 OptionManager& mgr = getManager();
00747
00748 if (itsInputEcho.getVal() == "")
00749 {
00750
00751 }
00752 else if (itsInputEcho.getVal() == "none")
00753 {
00754 rep->echoes.clear();
00755 }
00756 else
00757 {
00758 nub::ref<FrameOstream> f = makeFrameOstream(itsInputEcho.getVal(), mgr);
00759
00760 rep->echoes.push_back(f);
00761 this->addSubComponent(f);
00762 f->exportOptions(MC_RECURSE);
00763 }
00764 }
00765 else if (param == &itsFrameRange)
00766 {
00767 rep->counter.reset(itsFrameRange.getVal(), false);
00768 }
00769 }
00770
00771
00772 FrameState InputFrameSeries::update(const SimTime& stime)
00773 {
00774
00775
00776 if (rep->inputEof)
00777 {
00778 if (itsKeepGoing.getVal())
00779
00780 return FRAME_SAME;
00781 else
00782
00783 return FRAME_COMPLETE;
00784 }
00785
00786 rep->numEchoed = 0;
00787
00788 rep->lastUpdateTime = stime;
00789
00790 const FrameState result = rep->counter.update(stime);
00791
00792 if (result != FRAME_SAME)
00793 {
00794 const int fnum = rep->counter.currentFrame();
00795
00796 LDEBUG("%s frame %d at %.2fms",
00797 rep->source->tagName().c_str(), fnum, stime.msecs());
00798 }
00799
00800 return result;
00801 }
00802
00803
00804 FrameState InputFrameSeries::updateNext()
00805 {
00806 return rep->counter.updateNext();
00807 }
00808
00809
00810 bool InputFrameSeries::shouldWait() const
00811 {
00812 return rep->numEchoed > 0
00813 && itsWaitForUser.getVal() == true
00814 && !itsTestMode.getVal();
00815 }
00816
00817
00818 void InputFrameSeries::start1()
00819 {
00820 if (!rep->source.is_valid())
00821 {
00822 LFATAL("\n\tOops, you didn't specify an input frame source.\n"
00823 "\tFor example, you can use --in=raster:path/to/filestem,\n"
00824 "\tor --in=mpeg:path/to/file.mpg, or --in=random:256x256.");
00825 }
00826
00827 rep->counter.reset(itsFrameRange.getVal(), false, itsFrameWrap.getVal());
00828
00829 const int fnum = rep->counter.currentFrame();
00830 if (!rep->source->setFrameNumber(fnum))
00831 LFATAL("couldn't initialize frame source %s to frame number %d",
00832 rep->sourceDescription.c_str(), fnum);
00833
00834 rep->inputEof = false;
00835 }
00836
00837
00838 void InputFrameSeries::start2()
00839 {
00840 FrameIstream::start2();
00841
00842
00843
00844 const Dims indims = this->peekDims();
00845
00846 OptionManager& mgr = getManager();
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 Dims idim(0, 0);
00860 convertFromString(mgr.getOptionValString(&OPT_InputFrameDims), idim);
00861 if (idim.isEmpty())
00862 mgr.setOptionValString(&OPT_InputFrameDims,
00863 convertToString(indims));
00864
00865 ASSERT(rep->source.is_valid());
00866
00867
00868
00869
00870
00871 FrameRange repRng = rep->source->getFrameRange();
00872 FrameRange usrRng = this->getFrameRange();
00873 if(repRng != FrameRange())
00874 {
00875 std::vector<SimTime> delayTimes(usrRng.numDelayTimes());
00876 for(size_t i=0; i<usrRng.numDelayTimes(); i++)
00877 delayTimes.at(i) = usrRng.getDelayTime(i);
00878
00879 FrameRange newRange(
00880 repRng.getFirst() > usrRng.getFirst() ? repRng.getFirst() : usrRng.getFirst(),
00881 usrRng.getStep(),
00882 repRng.getLast() < usrRng.getLast() ? repRng.getLast() : usrRng.getLast(),
00883 delayTimes,
00884 usrRng.isEventTriggered()
00885 );
00886
00887 rep->counter.reset(newRange, true);
00888 itsFrameRange.setVal(newRange);
00889 }
00890
00891
00892
00893
00894 const GenericFrameSpec origspec = rep->source->peekFrameSpec();
00895 const GenericFrameSpec finalspec = this->peekFrameSpec();
00896
00897 const std::string description =
00898 origspec == finalspec
00899 ? origspec.getDescription()
00900 : sformat("originally %s; converted to %s",
00901 origspec.getDescription().c_str(),
00902 finalspec.getDescription().c_str());
00903
00904 LINFO("input frames: %s", description.c_str());
00905 textLog(itsLogFile.getVal(),
00906 "InputDims", sformat("%dx%d", indims.w(), indims.h()));
00907 }
00908
00909
00910 GenericFrameSpec InputFrameSeries::peekFrameSpec()
00911 {
00912
00913 ASSERT(rep->source.is_valid());
00914
00915 const int fnum = rep->counter.currentFrame();
00916
00917 if (!rep->source->setFrameNumber(fnum))
00918 LFATAL("couldn't initialize frame source %s to frame number %d",
00919 rep->sourceDescription.c_str(), fnum);
00920
00921 const GenericFrameSpec origspec = rep->source->peekFrameSpec();
00922
00923 GenericFrameSpec result = origspec;
00924
00925
00926 if (itsDims.getVal().isNonEmpty())
00927 result.dims = itsDims.getVal();
00928
00929
00930 else if (!isRectEmpty(itsCropRect.getVal()))
00931 result.dims = itsCropRect.getVal().dims();
00932
00933
00934
00935 if (result.dims != origspec.dims
00936 && origspec.nativeType == GenericFrame::VIDEO)
00937 result.nativeType = GenericFrame::RGB_U8;
00938
00939 return result;
00940 }
00941
00942
00943 void InputFrameSeries::startStream()
00944 {
00945 if (!this->started())
00946 LFATAL("startStream() must not be called until after start()");
00947
00948
00949 ASSERT(rep->source.is_valid());
00950
00951 rep->source->startStream();
00952 }
00953
00954
00955 GenericFrame InputFrameSeries::readFrame()
00956 {
00957 if (!this->started())
00958 LFATAL("readFrame() must not be called until after start()");
00959
00960 return rep->readFrame(this);
00961 }
00962
00963
00964 void InputFrameSeries::setFrameSource(const std::string& source)
00965 {
00966 nub::soft_ref<FrameIstream> in =
00967 makeFrameIstream(source);
00968
00969 if (!in.is_valid())
00970 {
00971 LFATAL("unknown value for %s: '%s'\n\tvalid values are %s",
00972 itsFrameSource.getOptionDef()->longoptname,
00973 source.c_str(),
00974 itsFrameSource.getOptionDef()->validvals);
00975 }
00976
00977 if (rep->source.is_valid())
00978 this->removeSubComponent(*rep->source);
00979 rep->source = in;
00980 rep->sourceDescription = source;
00981 this->addSubComponent(rep->source);
00982 rep->source->exportOptions(MC_RECURSE);
00983 }
00984
00985
00986 int InputFrameSeries::frame() const
00987 {
00988 return rep->counter.currentFrame();
00989 }
00990
00991
00992 nub::ref<FrameIstream> InputFrameSeries::getFrameSource() const
00993 {
00994 if (!rep->source.is_valid())
00995 LFATAL("Oops! I don't have any frame source");
00996
00997 return rep->source;
00998 }
00999
01000
01001 FrameRange InputFrameSeries::getFrameRange() const
01002 {
01003 return itsFrameRange.getVal();
01004 }
01005
01006
01007 bool InputFrameSeries::setFrameNumber(int n)
01008 {
01009 return rep->setFrameNumber(n);
01010 }
01011
01012
01013
01014
01015
01016
01017 struct OutputFrameSeries::Impl
01018 {
01019 Impl(OptionManager& mgr, const FrameRange& range)
01020 :
01021 vec(),
01022 explicitNone(false),
01023 counter(range),
01024 wasNonvoidAtStart(false)
01025 {}
01026
01027 typedef std::vector<nub::ref<FrameOstream> > VecType;
01028
01029 VecType vec;
01030
01031
01032
01033
01034
01035
01036 bool explicitNone;
01037
01038 FrameCounter counter;
01039
01040 bool wasNonvoidAtStart;
01041 };
01042
01043 OutputFrameSeries::OutputFrameSeries(OptionManager& mgr,
01044 const std::string& descrName,
01045 const std::string& tag) :
01046 FrameOstream(mgr, "Output " + descrName, "Output"+tag),
01047 itsLogFile(&OPT_TextLogFile, this),
01048 itsTestMode(&OPT_TestMode, this),
01049 itsFrameRange(&OPT_OutputFrameRange, this),
01050 itsDims(&OPT_OutputFrameDims, this),
01051 itsPreserveAspect(&OPT_OutputPreserveAspect, this),
01052 itsZoom(&OPT_OutputZoom, this),
01053 itsZeroNumberFrames(&OPT_ZeroNumberFrames, this),
01054 itsFrameSink(&OPT_OutputFrameSink, this),
01055 itsInOut(&OPT_InputOutputComboSpec, this),
01056 itsWaitForUser(&OPT_WaitForUser, this),
01057 itsOutputReplicate(&OPT_OutputReplicate, this),
01058 itsNumWritten(0),
01059 rep(new Impl(mgr, itsFrameRange.getVal()))
01060 {
01061 init_manager = &mgr;
01062 pthread_once(&istream_init_once, &istream_init);
01063 pthread_once(&ostream_init_once, &ostream_init);
01064 }
01065
01066
01067 OutputFrameSeries::~OutputFrameSeries()
01068 {
01069 delete rep;
01070 }
01071
01072
01073 void OutputFrameSeries::reset1()
01074 {
01075
01076 rep->counter.reset(itsFrameRange.getVal(), true);
01077 itsNumWritten = 0;
01078
01079 rep->explicitNone = false;
01080 rep->vec.clear();
01081
01082
01083 FrameOstream::reset1();
01084 }
01085
01086
01087 void OutputFrameSeries::paramChanged(ModelParamBase* const param,
01088 const bool valueChanged,
01089 ParamClient::ChangeStatus* status)
01090 {
01091 FrameOstream::paramChanged(param, valueChanged, status);
01092
01093 if (param == &itsFrameSink)
01094 {
01095 this->addFrameDest(itsFrameSink.getVal());
01096 }
01097 else if (param == &itsInOut)
01098 {
01099 this->addFrameDest(itsInOut.getVal());
01100 }
01101 else if (param == &itsFrameRange)
01102 {
01103 rep->counter.reset(itsFrameRange.getVal(), false);
01104 }
01105 }
01106
01107
01108 FrameState OutputFrameSeries::update(const SimTime& stime,
01109 bool new_event)
01110 {
01111
01112 itsNumWritten = 0;
01113
01114 const FrameState result = rep->counter.update(stime, new_event);
01115
01116 if (result != FRAME_SAME)
01117 {
01118 const int fnum = rep->counter.currentFrame();
01119
01120 LDEBUG("%-20s frame %d at %.2fms",
01121 this->tagName().c_str(), fnum, stime.msecs());
01122
01123 textLog(itsLogFile.getVal(),
01124 this->tagName().c_str(),
01125 sformat("frame %d", fnum), stime);
01126 }
01127
01128 return result;
01129 }
01130
01131
01132 FrameState OutputFrameSeries::updateNext()
01133 {
01134 return rep->counter.updateNext();
01135 }
01136
01137
01138 bool OutputFrameSeries::shouldWait() const
01139 {
01140 return itsNumWritten > 0
01141 && itsWaitForUser.getVal() == true
01142 && !itsTestMode.getVal();
01143 }
01144
01145
01146 void OutputFrameSeries::writeFrame(const GenericFrame& orig,
01147 const std::string& shortname,
01148 const FrameInfo& auxinfo)
01149 {
01150 int fnum;
01151 if(itsZeroNumberFrames.getVal())
01152 fnum = 0;
01153 else
01154 fnum = rep->counter.currentFrame();
01155
01156 const GenericFrame frame =
01157 doResizeFrame(orig, Rectangle(), itsDims.getVal(),
01158 itsZoom.getVal(), itsPreserveAspect.getVal());
01159
01160
01161 ASSERT(rep->vec.size() > 0 || rep->explicitNone);
01162
01163 for (size_t i = 0; i < rep->vec.size(); ++i)
01164 {
01165 for (size_t k = 0; k < itsOutputReplicate.getVal(); ++k)
01166 {
01167 rep->vec[i]->setFrameNumber(k + fnum * itsOutputReplicate.getVal());
01168 rep->vec[i]->writeFrame(frame, shortname, auxinfo);
01169 }
01170 ++itsNumWritten;
01171 }
01172 }
01173
01174
01175 bool OutputFrameSeries::isVoid() const
01176 {
01177
01178 for (size_t i = 0; i < rep->vec.size(); ++i)
01179 if (!rep->vec[i]->isVoid())
01180 return false;
01181
01182
01183 return true;
01184 }
01185
01186
01187 bool OutputFrameSeries::becameVoid() const
01188 {
01189 return rep->wasNonvoidAtStart && this->isVoid();
01190 }
01191
01192
01193 void OutputFrameSeries::closeStream(const std::string& shortname)
01194 {
01195 for (size_t i = 0; i < rep->vec.size(); ++i)
01196 rep->vec[i]->closeStream(shortname);
01197 }
01198
01199
01200 void OutputFrameSeries::addFrameDest(const std::string& source)
01201 {
01202 if (source == "")
01203 return;
01204
01205 OptionManager& mgr = getManager();
01206
01207 if (source == "none")
01208 {
01209
01210
01211 while (rep->vec.size() != 0)
01212 {
01213 nub::ref<FrameOstream> f = rep->vec.back();
01214 rep->vec.pop_back();
01215 this->removeSubComponent(*f);
01216 }
01217 rep->explicitNone = true;
01218 }
01219 else
01220 {
01221 nub::ref<FrameOstream> f = makeFrameOstream(source, mgr);
01222
01223 rep->vec.push_back(f);
01224 this->addSubComponent(f);
01225 f->exportOptions(MC_RECURSE);
01226 }
01227 }
01228
01229
01230 size_t OutputFrameSeries::getNumFrameDests() const
01231 {
01232 return rep->vec.size();
01233 }
01234
01235
01236 nub::ref<FrameOstream> OutputFrameSeries::getFrameDest(size_t n) const
01237 {
01238 ASSERT(n < rep->vec.size());
01239
01240 return rep->vec[n];
01241 }
01242
01243
01244 void OutputFrameSeries::start2()
01245 {
01246 rep->counter.reset(itsFrameRange.getVal(), true);
01247
01248 if (rep->vec.empty() && !rep->explicitNone)
01249 LFATAL("\n\tOops, you didn't specify an output destination with\n"
01250 "\tan --out option. If this is actually the behavior\n"
01251 "\tyou want, you can do an explicit --out=none to avoid\n"
01252 "\tthis error message. Otherwise, you can use an option\n"
01253 "\tlike --out=raster:path/to/filestem or --out=mpeg:\n"
01254 "\tor --out=display: to request particular output format.");
01255
01256 rep->wasNonvoidAtStart = !this->isVoid();
01257 }
01258
01259
01260 int OutputFrameSeries::frame() const
01261 {
01262 if(itsZeroNumberFrames.getVal())
01263 return 0;
01264 else
01265 return rep->counter.currentFrame();
01266 }
01267
01268
01269
01270
01271
01272
01273