77#include < toucanRender/Read.h>
88#include < toucanRender/Util.h>
99
10- #include < feather-tk/core/CmdLine.h>
1110#include < feather-tk/core/Time.h>
1211
1312#include < OpenImageIO/imagebufalgo.h>
@@ -48,18 +47,13 @@ namespace toucan
4847 const std::shared_ptr<feather_tk::Context>& context,
4948 std::vector<std::string>& argv)
5049 {
51- std::vector<std::shared_ptr<feather_tk::ICmdLineArg> > args;
52- args.push_back (feather_tk::CmdLineValueArg<std::string>::create (
53- _args.input ,
50+ _cmdLine.input = feather_tk::CmdLineValueArg<std::string>::create (
5451 " input" ,
55- " Input .otio file." ));
56- auto outArg = feather_tk::CmdLineValueArg<std::string>::create (
57- _args.output ,
52+ " Input .otio file." );
53+ _cmdLine.output = feather_tk::CmdLineValueArg<std::string>::create (
5854 " output" ,
5955 " Output image or movie file. Use a dash ('-') to write raw frames or y4m to stdout." );
60- args.push_back (outArg);
6156
62- std::vector<std::shared_ptr<feather_tk::ICmdLineOption> > options;
6357 std::vector<std::string> rawList;
6458 for (const auto & spec : rawSpecs)
6559 {
@@ -70,57 +64,60 @@ namespace toucan
7064 {
7165 y4mList.push_back (spec.first );
7266 }
73- options.push_back (feather_tk::CmdLineValueOption<std::string>::create (
74- _options.videoCodec ,
67+ _cmdLine.videoCodec = feather_tk::CmdLineValueOption<std::string>::create (
7568 std::vector<std::string>{ " -vcodec" },
7669 " Set the video codec." ,
77- _options. videoCodec ,
78- feather_tk::join ( ffmpeg::getVideoCodecStrings (), " , " )));
79- options. push_back ( feather_tk::CmdLineFlagOption::create (
80- _options .printStart ,
70+ " " ,
71+ " MJPEG " ,
72+ feather_tk::join ( ffmpeg::getVideoCodecStrings (), " , " ));
73+ _cmdLine .printStart = feather_tk::CmdLineFlagOption::create (
8174 std::vector<std::string>{ " -print_start" },
82- " Print the timeline start time and exit." ));
83- options.push_back (feather_tk::CmdLineFlagOption::create (
84- _options.printDuration ,
75+ " Print the timeline start time and exit." );
76+ _cmdLine.printDuration = feather_tk::CmdLineFlagOption::create (
8577 std::vector<std::string>{ " -print_duration" },
86- " Print the timeline duration and exit." ));
87- options.push_back (feather_tk::CmdLineFlagOption::create (
88- _options.printRate ,
78+ " Print the timeline duration and exit." );
79+ _cmdLine.printRate = feather_tk::CmdLineFlagOption::create (
8980 std::vector<std::string>{ " -print_rate" },
90- " Print the timeline frame rate and exit." ));
91- options.push_back (feather_tk::CmdLineFlagOption::create (
92- _options.printSize ,
81+ " Print the timeline frame rate and exit." );
82+ _cmdLine.printSize = feather_tk::CmdLineFlagOption::create (
9383 std::vector<std::string>{ " -print_size" },
94- " Print the timeline image size." ));
95- options.push_back (feather_tk::CmdLineValueOption<std::string>::create (
96- _options.raw ,
84+ " Print the timeline image size." );
85+ _cmdLine.raw = feather_tk::CmdLineValueOption<std::string>::create (
9786 std::vector<std::string>{ " -raw" },
9887 " Raw pixel format to send to stdout." ,
99- _options. raw ,
100- feather_tk::join (rawList, " , " )));
101- options. push_back ( feather_tk::CmdLineValueOption<std::string>:: create (
102- _options .y4m ,
88+ " " ,
89+ std::optional<std::string>(),
90+ feather_tk::join (rawList, " , " ));
91+ _cmdLine .y4m = feather_tk::CmdLineValueOption<std::string>:: create (
10392 std::vector<std::string>{ " -y4m" },
10493 " y4m format to send to stdout." ,
105- _options. y4m ,
106- feather_tk::join (y4mList, " , " )));
107- options. push_back ( feather_tk::CmdLineFlagOption::create (
108- _options .verbose ,
94+ " " ,
95+ std::optional<std::string>(),
96+ feather_tk::join (y4mList, " , " ));
97+ _cmdLine .verbose = feather_tk::CmdLineFlagOption::create (
10998 std::vector<std::string>{ " -v" },
110- " Print verbose output." )) ;
99+ " Print verbose output." );
111100
112101 IApp::_init (
113102 context,
114103 argv,
115104 " toucan-render" ,
116105 " Render timeline files" ,
117- args,
118- options);
119-
120- _args.outputRaw = " -" == _args.output ;
121- if (_args.outputRaw )
106+ { _cmdLine.input , _cmdLine.output },
107+ {
108+ _cmdLine.videoCodec ,
109+ _cmdLine.printStart ,
110+ _cmdLine.printDuration ,
111+ _cmdLine.printRate ,
112+ _cmdLine.printSize ,
113+ _cmdLine.raw ,
114+ _cmdLine.y4m ,
115+ _cmdLine.verbose
116+ });
117+
118+ if (_cmdLine.output ->hasValue () && _cmdLine.output ->getValue () == " -" )
122119 {
123- _options. verbose = false ;
120+ _cmdLine. outputRaw = true ;
124121 }
125122 }
126123
@@ -155,8 +152,8 @@ namespace toucan
155152 void App::run ()
156153 {
157154 const std::filesystem::path parentPath = std::filesystem::path (getExeName ()).parent_path ();
158- const std::filesystem::path inputPath (_args .input );
159- const std::filesystem::path outputPath (_args .output );
155+ const std::filesystem::path inputPath (_cmdLine .input -> getValue () );
156+ const std::filesystem::path outputPath (_cmdLine .output -> getValue () );
160157 const auto outputSplit = splitFileNameNumber (outputPath.stem ().string ());
161158 const int outputStartFrame = atoi (outputSplit.second .c_str ());
162159 const size_t outputNumberPadding = getNumberPadding (outputSplit.second );
@@ -177,22 +174,22 @@ namespace toucan
177174 const IMATH_NAMESPACE::V2d imageSize = _graph->getImageSize ();
178175
179176 // Print information.
180- if (_options .printStart )
177+ if (_cmdLine .printStart -> found () )
181178 {
182179 std::cout << timeRange.start_time ().value () << std::endl;
183180 return ;
184181 }
185- else if (_options .printDuration )
182+ else if (_cmdLine .printDuration -> found () )
186183 {
187184 std::cout << timeRange.duration ().value () << std::endl;
188185 return ;
189186 }
190- else if (_options .printRate )
187+ else if (_cmdLine .printRate -> found () )
191188 {
192189 std::cout << timeRange.duration ().rate () << std::endl;
193190 return ;
194191 }
195- else if (_options .printSize )
192+ else if (_cmdLine .printSize -> found () )
196193 {
197194 std::cout << imageSize.x << " x" << imageSize.y << std::endl;
198195 return ;
@@ -205,8 +202,11 @@ namespace toucan
205202 std::shared_ptr<ffmpeg::Write> ffWrite;
206203 if (MovieReadNode::hasExtension (outputPath.extension ().string ()))
207204 {
208- ffmpeg::VideoCodec videoCodec = ffmpeg::VideoCodec::First;
209- ffmpeg::fromString (_options.videoCodec , videoCodec);
205+ ffmpeg::VideoCodec videoCodec = ffmpeg::VideoCodec::MJPEG;
206+ if (_cmdLine.videoCodec ->hasValue ())
207+ {
208+ ffmpeg::fromString (_cmdLine.videoCodec ->getValue (), videoCodec);
209+ }
210210 ffWrite = std::make_shared<ffmpeg::Write>(
211211 outputPath,
212212 OIIO::ImageSpec (imageSize.x , imageSize.y , 3 ),
@@ -215,15 +215,15 @@ namespace toucan
215215 }
216216
217217 // Render the timeline frames.
218- if (!_options .y4m . empty ())
218+ if (_cmdLine .y4m -> hasValue ())
219219 {
220220 _writeY4mHeader ();
221221 }
222222 for (OTIO_NS::RationalTime time = timeRange.start_time ();
223223 time <= timeRange.end_time_inclusive ();
224224 time += timeInc)
225225 {
226- if (!_args .outputRaw )
226+ if (!_cmdLine .outputRaw )
227227 {
228228 std::cout << (time - timeRange.start_time ()).value () << " /" <<
229229 timeRange.duration ().value () << std::endl;
@@ -235,7 +235,7 @@ namespace toucan
235235 const auto buf = node->exec ();
236236
237237 // Save the image.
238- if (!_args .outputRaw )
238+ if (!_cmdLine .outputRaw )
239239 {
240240 if (ffWrite)
241241 {
@@ -252,11 +252,11 @@ namespace toucan
252252 buf.write (fileName);
253253 }
254254 }
255- else if (!_options .raw . empty ())
255+ else if (_cmdLine .raw -> hasValue ())
256256 {
257257 _writeRawFrame (buf);
258258 }
259- else if (!_options .y4m . empty ())
259+ else if (_cmdLine .y4m -> hasValue ())
260260 {
261261 _writeY4mFrame (buf);
262262 }
@@ -269,7 +269,7 @@ namespace toucan
269269 const OIIO::ImageBuf* p = &buf;
270270 auto spec = buf.spec ();
271271
272- const auto i = rawSpecs.find (_options .raw );
272+ const auto i = rawSpecs.find (_cmdLine .raw -> getValue () );
273273 if (i == rawSpecs.end ())
274274 {
275275 throw std::runtime_error (" Cannot find the given raw format" );
@@ -329,7 +329,7 @@ namespace toucan
329329
330330 {
331331 std::stringstream ss;
332- ss << " C" << _options .y4m ;
332+ ss << " C" << _cmdLine .y4m -> getValue () ;
333333 s = ss.str ();
334334 }
335335 fwrite (s.c_str (), s.size (), 1 , stdout);
@@ -345,7 +345,7 @@ namespace toucan
345345 const OIIO::ImageBuf* p = &buf;
346346 auto spec = buf.spec ();
347347
348- const auto i = y4mSpecs.find (_options .y4m );
348+ const auto i = y4mSpecs.find (_cmdLine .y4m -> getValue () );
349349 if (i == y4mSpecs.end ())
350350 {
351351 throw std::runtime_error (" Cannot find the given y4m format" );
@@ -371,22 +371,22 @@ namespace toucan
371371
372372 if (!_swsContext)
373373 {
374- if (" 422" == _options .y4m )
374+ if (" 422" == _cmdLine .y4m -> getValue () )
375375 {
376376 _avInputPixelFormat = AV_PIX_FMT_RGB24;
377377 _avOutputPixelFormat = AV_PIX_FMT_YUV422P;
378378 }
379- else if (" 444" == _options .y4m )
379+ else if (" 444" == _cmdLine .y4m -> getValue () )
380380 {
381381 _avInputPixelFormat = AV_PIX_FMT_RGB24;
382382 _avOutputPixelFormat = AV_PIX_FMT_YUV444P;
383383 }
384- else if (" 444alpha" == _options .y4m )
384+ else if (" 444alpha" == _cmdLine .y4m -> getValue () )
385385 {
386386 _avInputPixelFormat = AV_PIX_FMT_RGBA;
387387 _avOutputPixelFormat = AV_PIX_FMT_YUVA444P;
388388 }
389- else if (" 444p16" == _options .y4m )
389+ else if (" 444p16" == _cmdLine .y4m -> getValue () )
390390 {
391391 _avInputPixelFormat = AV_PIX_FMT_RGB48;
392392 _avOutputPixelFormat = AV_PIX_FMT_YUV444P16;
@@ -423,7 +423,7 @@ namespace toucan
423423 av_image_get_buffer_size (_avInputPixelFormat, spec.width , spec.height , 1 ));
424424 sws_scale_frame (_swsContext, _avFrame2, _avFrame);
425425
426- if (" 422" == _options .y4m )
426+ if (" 422" == _cmdLine .y4m -> getValue () )
427427 {
428428 fwrite (
429429 _avFrame2->data [0 ],
@@ -441,7 +441,7 @@ namespace toucan
441441 1 ,
442442 stdout);
443443 }
444- else if (" 444" == _options .y4m || " 444p16" == _options .y4m )
444+ else if (" 444" == _cmdLine .y4m -> getValue () || " 444p16" == _cmdLine .y4m -> getValue () )
445445 {
446446 fwrite (
447447 _avFrame2->data [0 ],
@@ -459,7 +459,7 @@ namespace toucan
459459 1 ,
460460 stdout);
461461 }
462- else if (" 444alpha" == _options .y4m )
462+ else if (" 444alpha" == _cmdLine .y4m -> getValue () )
463463 {
464464 fwrite (
465465 _avFrame2->data [0 ],
0 commit comments