1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: instrmain.cpp,v 1.15 2008/01/15 04:36:24 asuraparaju Exp $ $Name: Dirac_1_0_2 $
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
15 *
16 * The Original Code is BBC Research and Development code.
17 *
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
22 *
23 * Contributor(s): Chris Bowley (Original Author)
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28 * the GPL or the LGPL are applicable instead of those above. If you wish to
29 * allow use of your version of this file only under the terms of the either
30 * the GPL or LGPL and not to allow others to use your version of this file
31 * under the MPL, indicate your decision by deleting the provisions above
32 * and replace them with the notice and other provisions required by the GPL
33 * or LGPL. If you do not delete the provisions above, a recipient may use
34 * your version of this file under the terms of any one of the MPL, the GPL
35 * or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37 
38 #include <iostream>
39 #include <fstream>
40 #include <sstream>
41 #include <libdirac_common/cmd_line.h>
42 using namespace dirac;
43 
44 #include <util/instrumentation/process_sequence.h>
45 using namespace dirac_instr;
46 
47 using namespace std;
48 
DisplayHelp()49 static void DisplayHelp()
50 {
51     cout << "\nInstrumentation display for DIRAC wavelet video coder";
52     cout << "\n=====================================================";
53     cout << "\n";
54     cout << "\nUsage: progname -<flag1> [<flag_val>] ... <input1> <input2> ...";
55     cout << "\nIn case of multiple assignment to the same parameter, the last holds.";
56     cout << "\n";
57     cout << "\nName                 Type   I/O Default Value Description";
58     cout << "\n====                 ====   === ============= ===========";
59     cout << "\ninput                string  I  [ required ]  Input file name";
60     cout << "\noutput               string  I  [ required ]  Output file name";
61     cout << "\n";
62     cout << "\nmotion_colour        bool    I  true          Display motion vectors using colour wheel";
63     cout << "\nmotion_arrows        bool    I  false         Display motion vectors as arrows";
64     cout << "\nmotion_colour_arrows bool    I  false         Display motion vectors as arrows with colour size";
65     cout << "\nsplit_mode           bool    I  false         Display macroblock splitting mode";
66     cout << "\nsad                  bool    I  false         Display block SAD values";
67     cout << "\npred_mode            bool    I  false         Display block prediction mode";
68     cout << "\nglobal_inliers       bool    I  false         Display global motion inlier mask";
69     cout << "\n";
70     cout << "\nno_bg                bool    I  false         Display over grey background";
71     cout << "\nno_legend            bool    I  false         Do not display colour legend";
72     cout << "\n";
73     cout << "\nglobal               bool    I  false         Display global motion";
74     cout << "\nglobal_diff          bool    I  false         Display global motion error";
75     cout << "\nclip                 int     I  25 / 10000    Clip for max value motion vector / SAD overlays";
76     cout << "\nref                  int     I  1             Reference frame";
77     cout << "\nstart                int     I  0             Frame number at which process starts";
78     cout << "\nend                  int     I  end           Frame number at which process stops";
79     cout << "\nbuffer               int     I  50            Size of internal buffer for motion data";
80     cout << "\n";
81     cout << "\nverbose              bool    I  false         Display information during process";
82 }
83 
ReadInstrumentationHeader(std::istream & in,SourceParams & srcparams,bool & field_coding)84 bool ReadInstrumentationHeader (std::istream &in, SourceParams& srcparams, bool &field_coding)
85 {
86     if (! in )
87         return false;
88 
89     int temp_int;
90     bool temp_bool;
91 
92     in >> temp_int;
93     srcparams.SetCFormat( (ChromaFormat)temp_int );
94 
95     in >> temp_int;
96     srcparams.SetXl( temp_int );
97 
98     in >> temp_int;
99     srcparams.SetYl( temp_int );
100 
101     in >> temp_int;
102     srcparams.SetSourceSampling( temp_int );
103 
104     in >> temp_bool;
105     srcparams.SetTopFieldFirst( temp_bool );
106 
107     int num, denom;
108     in >> num;
109     in >> denom;
110     srcparams.SetFrameRate( num, denom );
111 
112     in >> num;
113     in >> denom;
114     srcparams.SetPixelAspectRatio( num, denom );
115 
116     in >> field_coding;
117     return true;
118 }
119 
120 
main(int argc,char * argv[])121 int main (int argc, char* argv[])
122 {
123     // read command line options
124     string input,output;
125     int ref = 1;              // use reference 1
126     bool verbose = false;
127     int start = 0, stop = -1;
128     int buffer = 50;
129 
130     // set defaults
131     OverlayParams oparams;
132     oparams.SetOption(motion_colour);   // motion vector colour wheel
133     oparams.SetReference(1);            // reference 1
134     oparams.SetBackground(true);        // background on
135     oparams.SetLegend(true);            // legend on
136     oparams.SetMvClip(25);              // motion vector clip = 25
137     oparams.SetSADClip(10000);          // SAD clip = 10000
138 
139     // create a list of boolean options
140     set<string> bool_opts;
141     bool_opts.insert("verbose");
142     bool_opts.insert("no_bg");
143     bool_opts.insert("no_legend");
144     bool_opts.insert("motion_colour");
145     bool_opts.insert("motion_arrows");
146     bool_opts.insert("motion_colour_arrows");
147     bool_opts.insert("split_mode");
148     bool_opts.insert("sad");
149     bool_opts.insert("pred_mode");
150     bool_opts.insert("global");
151     bool_opts.insert("global_diff");
152     bool_opts.insert("global_inliers");
153 
154     // parse command line options
155     CommandLine args(argc,argv,bool_opts);
156 
157     // need at least 3 arguments - the program name, an input and an output
158     if (argc < 3)
159     {
160         DisplayHelp();
161         exit(1);
162     }
163     else
164     {
165         // do required inputs
166         if (args.GetInputs().size() == 2)
167         {
168             input=args.GetInputs()[0];
169             output=args.GetInputs()[1];
170         }
171 
172         // check we have real inputs
173         if ((input.length() == 0) || (output.length() == 0))
174         {
175             DisplayHelp();
176             exit(1);
177         }
178 
179         // now process presets
180         for (vector<CommandLine::option>::const_iterator opt = args.GetOptions().begin();
181             opt != args.GetOptions().end(); ++opt)
182         {
183             if (opt->m_name == "motion_arrows")
184                 oparams.SetOption(motion_arrows);
185 
186             else if (opt->m_name == "motion_colour_arrows")
187                 oparams.SetOption(motion_colour_arrows);
188 
189             else if (opt->m_name == "motion_colour")
190                 oparams.SetOption(motion_colour);
191 
192             else if (opt->m_name == "split_mode")
193                 oparams.SetOption(split_mode);
194 
195             else if (opt->m_name == "sad")
196                 oparams.SetOption(SAD);
197 
198             else if (opt->m_name == "pred_mode")
199                 oparams.SetOption(pred_mode);
200 
201             else if (opt->m_name == "global_inliers")
202                 oparams.SetOption(gm_inliers);
203 
204             if (opt->m_name == "no_bg")
205                 oparams.SetBackground(false);
206 
207             if (opt->m_name == "no_legend")
208                 oparams.SetLegend(false);
209 
210             if (opt->m_name == "verbose")
211                 verbose = true;
212 
213             if (opt->m_name == "global")
214             {
215                 if (oparams.Option() == motion_arrows)
216                     oparams.SetOption(gm_arrows);
217 
218                 if (oparams.Option() == motion_colour_arrows)
219                     oparams.SetOption(gm_colour_arrows);
220 
221                 if (oparams.Option() == motion_colour)
222                     oparams.SetOption(gm_colour);
223             }
224 
225             if (opt->m_name == "global_diff")
226             {
227                 if (oparams.Option() == motion_arrows
228                     || oparams.Option() == gm_arrows)
229                     oparams.SetOption(gm_diff_arrows);
230 
231                 if (oparams.Option() == motion_colour_arrows
232                     || oparams.Option() == gm_colour_arrows)
233                     oparams.SetOption(gm_diff_colour_arrows);
234 
235                 if (oparams.Option() == motion_colour
236                     || oparams.Option() == gm_colour)
237                     oparams.SetOption(gm_diff_colour);
238             }
239 
240         }
241 
242         // parameters
243         for (vector<CommandLine::option>::const_iterator opt = args.GetOptions().begin();
244             opt != args.GetOptions().end(); ++opt)
245         {
246             if (opt->m_name == "ref")
247             {
248                 ref = strtoul(opt->m_value.c_str(),NULL,10);
249 
250                 if (ref==2)
251                     oparams.SetReference(2);
252                 else
253                     oparams.SetReference(1);
254             } // m_name
255 
256             if (opt->m_name == "clip")
257             {
258                 if (oparams.Option() == SAD)
259                 {
260                     oparams.SetSADClip(strtoul(opt->m_value.c_str(),NULL,10));
261                     // ensure value is +ve
262                     if (oparams.SADClip() <= 0)
263                         oparams.SetSADClip(10000);
264                 }
265                 else
266                 {
267                     oparams.SetMvClip(strtoul(opt->m_value.c_str(),NULL,10));
268                     // ensure value is +ve
269                     if (oparams.MvClip() <= 0)
270                         oparams.SetMvClip(25);
271                 }
272             } // m_name
273 
274             if (opt->m_name == "start")
275             {
276                 start = strtoul(opt->m_value.c_str(),NULL,10);
277             } // m_name
278 
279             if (opt->m_name == "stop")
280             {
281                 stop = strtoul(opt->m_value.c_str(),NULL,10);
282             } // m_name
283 
284             if (opt->m_name == "buffer")
285             {
286                 buffer = strtoul(opt->m_value.c_str(),NULL,10);
287             } // m_name
288         } // opt
289     } // args > 3
290 
291     // read motion data from file
292     if (verbose) cerr << endl << "Opening motion data file ";
293     char mv_file[FILENAME_MAX];
294     strcpy(mv_file, input.c_str());
295     strcat(mv_file, ".imt");
296     if (verbose) cerr << mv_file;
297     ifstream in(mv_file, ios::in);
298 
299     if (!in)
300     {
301         cerr << endl << "Failed to open sequence motion data file. Exiting." << endl;
302         exit(EXIT_FAILURE);
303     }
304 
305     SourceParams srcparams;
306     bool field_coding; // true if material has been coded as fields and not frames
307     ReadInstrumentationHeader (in, srcparams, field_coding);
308     SourceParams out_srcparams(srcparams);
309 
310     // Create objects for input and output picture sequences
311     char yuv_file[FILENAME_MAX];
312     strcpy(yuv_file, input.c_str());
313     strcat(yuv_file, ".localdec.yuv");
314     // hack hack - set interlace flag in source params to field_coding
315     // so that the Frame Parameters are set correctly.
316     srcparams.SetSourceSampling(field_coding);
317     FileStreamInput inputpic(yuv_file, srcparams, field_coding);
318 
319     if (field_coding)
320         out_srcparams.SetYl(out_srcparams.Yl()>>1);
321     FileStreamOutput outputpic(output.c_str(), out_srcparams, false);
322 
323     if (verbose) cerr << " ... ok" << endl << "Processing sequence...";
324     // *** process the sequence ***
325     ProcessSequence process(oparams, inputpic, outputpic, in, verbose, buffer, srcparams);
326     process.DoSequence(start, stop);
327     if (verbose) cerr << endl << "Done sequence." << endl;
328     return 0;
329 }
330 
331 
332