Fixed #2984304. Fix compilation errors reported by gcc 4.5.0.
[dirac-research.git] / encoder / encmain.cpp
blob3552de05c684942926a698c6e116df8fcee846fd
1 /* ***** BEGIN LICENSE BLOCK *****
3 * $Id$ $Name$
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
16 * The Original Code is BBC Research and Development code.
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.
23 * Contributor(s): Thomas Davies (Original Author),
24 * Scott R Ladd,
25 * Anuradha Suraparaju,
26 * Andrew Kennedy,
27 * David Flynn,
28 * Johannes Reinhardt,
29 * Myo Tun (Brunel University)
31 * Alternatively, the contents of this file may be used under the terms of
32 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
33 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
34 * the GPL or the LGPL are applicable instead of those above. If you wish to
35 * allow use of your version of this file only under the terms of the either
36 * the GPL or LGPL and not to allow others to use your version of this file
37 * under the MPL, indicate your decision by deleting the provisions above
38 * and replace them with the notice and other provisions required by the GPL
39 * or LGPL. If you do not delete the provisions above, a recipient may use
40 * your version of this file under the terms of any one of the MPL, the GPL
41 * or the LGPL.
42 * ***** END LICENSE BLOCK ***** */
44 #include <time.h>
45 #include <iostream>
46 #include <limits>
47 #include <fstream>
48 #include <set>
49 #include <cmath>
50 #include <ctime>
51 #include <cassert>
52 #include <string>
53 #include <libdirac_encoder/dirac_encoder.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <fcntl.h>
57 #include <cstdlib>
58 #include <cstring>
59 #include <climits>
61 using namespace std;
63 const int VIDEO_BUFFER_SIZE = 32*1024*1024;
64 unsigned char video_buf[VIDEO_BUFFER_SIZE];
66 static void display_help()
68 cout << "\nDIRAC wavelet video coder.";
69 cout << "\n";
70 cout << "\nUsage: progname -<flag1> [<flag1_val>] ... <input> <output>";
71 cout << "\nIn case of multiple assignment to the same parameter, the last holds.";
72 cout << "\n";
73 cout << "\nName Type Default Value Description";
74 cout << "\n==== ==== ============= =========== ";
75 cout << "\nQSIF525 bool false Use QSIF compression presets";
76 cout << "\nQCIF bool false Use QCIF compression presets";
77 cout << "\nSIF525 bool false Use SIF compression presets";
78 cout << "\nCIF bool false Use CIF compression presets";
79 cout << "\n4CIF bool false Use 4CIF compression presets";
80 cout << "\n4SIF525 bool false Use 4SIF compression presets";
81 cout << "\nSD480I60 bool false Use SD-480 compression presets";
82 cout << "\nSD576I50 bool false Use SD-576 compression presets";
83 cout << "\nHD720P60 bool false Use HD-720P60 compression presets";
84 cout << "\nHD720P50 bool false Use HD-720P50 compression presets";
85 cout << "\nHD1080I60 bool false Use HD-1080I60 compression presets";
86 cout << "\nHD1080I50 bool false Use HD-1080I50 compression presets";
87 cout << "\nHD1080P60 bool false Use HD-1080P60 compression presets";
88 cout << "\nHD1080P50 bool false Use HD-1080P50 compression presets";
89 cout << "\nUHDTV4K60 bool false Use UHDTV 4K60 compression presets";
90 cout << "\nUHDTV4K50 bool false Use UHDTV 4K50 compression presets";
91 cout << "\nUHDTV8K60 bool false Use UHDTV 8K60 compression presets";
92 cout << "\nUHDTV8K50 bool false Use UHDTV 8K50 compression presets";
93 cout << "\nDC2K24 bool false Use DIGITAL CINEMA 2K compression presets";
94 cout << "\nDC4K24 bool false Use DIGITAL CINEMA 4K compression presets";
95 cout << "\nfull_search ulong ulong 0UL 0UL Use full search motion estimation";
96 cout << "\ncombined_me bool false Use a combination of all 3 components to do ME";
97 cout << "\nwidth ulong Preset Width of frame";
98 cout << "\nheight ulong Preset Length of frame";
99 cout << "\nheight ulong Preset Length of frame";
100 cout << "\ncformat string YUV444P Chroma Sampling Format (YUV444P YUV422P YUV420P)";
101 cout << "\nfr ulong Preset Frame rate(s) (e.n or e/n format)";
102 cout << "\nsource_sampling string progressive source material type either progressive or interlaced";
103 cout << "\nstart ulong 0UL Frame number to start encoding from";
104 cout << "\nstop ulong EOF Frame number after which encoding finishes";
105 cout << "\nfield_coding bool false Set picture coding type to field coding. Default coding type is by frames";
106 cout << "\nL1_sep ulong 0UL Separation of L1 frames";
107 cout << "\nnum_L1 ulong 0UL Number of L1 frames";
108 cout << "\nxblen ulong 0UL Overlapping block horizontal length";
109 cout << "\nyblen ulong 0UL Overlapping block vertical length";
110 cout << "\nxbsep ulong 0UL Overlapping block horizontal separation";
111 cout << "\nybsep ulong 0UL Overlapping block vertical separation";
112 cout << "\ncpd ulong 0UL Perceptual weighting - vertical cycles per deg.";
113 cout << "\nqf float 0.0F Overall quality factor (>0, typically: 7=medium, 9=high)";
114 cout << "\ntargetrate ulong 0UL Target Bit Rate in Kbps";
115 cout << "\nlossless bool false Lossless coding (overrides qf)";
116 cout << "\niwlt_filter string DD13_7 Intra frame Transform Filter (DD9_7 LEGALL5_3 DD13_7 HAAR0 HAAR1 FIDELITY DAUB9_7)";
117 cout << "\nrwlt_filter string DD13_7 Inter frame Transform Filter (DD9_7 LEGALL5_3 DD13_7 HAAR0 HAAR1 FIDELITY DAUB9_7)";
118 cout << "\nwlt_depth ulong 4 Transform Depth";
119 cout << "\nmulti_quants bool false Use multiple quantisers";
120 cout << "\nmv_prec string false MV Pixel Precision (1, 1/2, 1/4, 1/8)";
121 cout << "\nno_spartition bool false Do not use spatial partitioning while coding transform data";
122 cout << "\nprefilter string/int NO_PF 0 Prefilter input giving filter name (NO_PF, CWM, RECTLP, DIAGLP) and strength (0-10)";
123 cout << "\nuse_vlc bool false Use VLC for entropy coding of coefficients";
124 cout << "\nlocal bool false Write diagnostics & locally decoded video";
125 cout << "\nverbose bool false Verbose mode";
126 cout << "\nh|help bool false Display help message";
127 cout << "\ninput string [ required ] Input file name";
128 cout << "\noutput string [ required ] Output file name [May not be '-']";
129 cout << endl;
134 bool WritePicData (std::ofstream &fdata, dirac_encoder_t *encoder)
136 dirac_sourceparams_t &sparams = encoder->enc_ctx.src_params;
137 dirac_framebuf_t &fbuf = encoder->dec_buf;
138 bool ret_stat = true;
140 if (encoder->decoded_frame_avail)
142 ios::iostate oldExceptions = fdata.exceptions();
143 fdata.exceptions (ios::failbit | ios::badbit);
146 assert (fbuf.buf[0] != 0);
147 fdata.write ((char *)fbuf.buf[0], sparams.width*sparams.height);
148 assert (fbuf.buf[1] != 0);
149 assert (fbuf.buf[2] != 0);
150 fdata.write ((char *)fbuf.buf[1],
151 sparams.chroma_width*sparams.chroma_height);
152 fdata.write ((char *)fbuf.buf[2],
153 sparams.chroma_width*sparams.chroma_height);
155 catch (...)
157 std::cout << "Incomplete frame " << std::endl;
158 ret_stat = false;
160 fdata.exceptions (oldExceptions);
162 return ret_stat;
165 bool WriteDiagnosticsHeader (std::ofstream &fdata, dirac_encoder_t *encoder)
167 bool ret_stat = true;
168 dirac_sourceparams_t &srcparams = encoder->enc_ctx.src_params;
169 ios::iostate oldExceptions = fdata.exceptions();
170 fdata.exceptions (ios::failbit | ios::badbit);
174 fdata << srcparams.chroma << std::endl;
175 fdata << srcparams.width << std::endl;
176 fdata << srcparams.height << std::endl;
177 fdata << srcparams.source_sampling << std::endl;
178 fdata << srcparams.topfieldfirst << std::endl;
179 fdata << srcparams.frame_rate.numerator << std::endl;
180 fdata << srcparams.frame_rate.denominator << std::endl;
181 fdata << srcparams.pix_asr.numerator << std::endl;
182 fdata << srcparams.pix_asr.denominator << std::endl;
183 fdata << encoder->enc_ctx.enc_params.picture_coding_mode << std::endl;
186 catch (...)
188 std::cerr << "Error writing sequence info in diagnostics file." << std::endl;
189 ret_stat = false;
191 fdata.exceptions (oldExceptions);
192 return ret_stat;
195 bool WriteDiagnosticsData (std::ofstream &fdata, dirac_encoder_t *encoder)
197 dirac_instr_t &instr = encoder->instr;
198 bool ret_stat = true;
200 if (encoder->instr_data_avail)
202 ios::iostate oldExceptions = fdata.exceptions();
203 fdata.exceptions (ios::failbit | ios::badbit);
206 fdata << std::endl << "[frame:" << instr.pnum << "]";
207 if (instr.ptype == INTRA_PICTURE)
209 fdata << ">intra" << std::endl;
210 return true;
213 fdata << ">mo_comp";
214 fdata << std::endl << std::endl << instr.num_refs << " ";
215 for (int i=0; i<instr.num_refs; ++i)
217 fdata << instr.refs[i] << " ";
219 fdata << instr.ybsep << " " << instr.xbsep << " ";
220 fdata << instr.sb_ylen << " " << instr.sb_xlen << " ";
221 fdata << instr.mv_ylen << " " << instr.mv_xlen
222 << std::endl << std::endl ;
223 for (int j=0; j<instr.sb_ylen; j++)
225 for (int i=0; i<instr.sb_xlen; i++)
226 fdata << instr.sb_split_mode[j*instr.sb_xlen + i] << " ";
227 fdata << std::endl;
229 fdata << std::endl;
231 for (int j=0; j<instr.sb_ylen; j++)
233 for (int i=0; i<instr.sb_xlen; i++)
234 fdata << instr.sb_costs[j*instr.sb_xlen + i] << " ";
235 fdata << std::endl;
237 fdata << std::endl;
239 for (int j=0; j<instr.mv_ylen; j++)
241 for (int i=0; i<instr.mv_xlen; i++)
242 fdata << instr.pred_mode[j*instr.mv_xlen + i] << " ";
243 fdata << std::endl;
245 fdata << std::endl;
247 for (int j=0; j<instr.mv_ylen; j++)
249 for (int i=0; i<instr.mv_xlen; i++)
250 fdata << instr.intra_costs[j*instr.mv_xlen + i] << " ";
251 fdata << std::endl;
253 fdata << std::endl;
255 if (instr.num_refs > 1)
257 for (int j=0; j<instr.mv_ylen; j++)
259 for (int i=0; i<instr.mv_xlen; i++)
261 fdata << instr.bipred_costs[j*instr.mv_xlen + i].SAD
262 <<" " << instr.bipred_costs[j*instr.mv_xlen + i].mvcost
263 << " ";;
265 fdata << std::endl;
268 fdata << std::endl;
270 for (int j=0; j<instr.mv_ylen; j++)
272 for (int i=0; i<instr.mv_xlen; i++)
273 fdata << instr.dc_ycomp[j*instr.mv_xlen + i] << " ";
274 fdata << std::endl;
277 // FIXME: always expects 3 components
278 fdata << std::endl;
279 for (int j=0; j<instr.mv_ylen; j++)
281 for (int i=0; i<instr.mv_xlen; i++)
282 fdata << instr.dc_ucomp[j*instr.mv_xlen + i] << " ";
283 fdata << std::endl;
285 fdata << std::endl;
286 for (int j=0; j<instr.mv_ylen; j++)
288 for (int i=0; i<instr.mv_xlen; i++)
289 fdata << instr.dc_vcomp[j*instr.mv_xlen + i] << " ";
290 fdata << std::endl;
293 for (int k = 0; k < instr.num_refs; k++)
295 fdata << std::endl;
296 for (int j=0; j<instr.mv_ylen; j++)
298 for (int i=0; i<instr.mv_xlen; i++)
300 fdata << instr.mv[k][j*instr.mv_xlen + i].x
301 <<" " << instr.mv[k][j*instr.mv_xlen + i].y
302 << " ";;
304 fdata << std::endl;
306 fdata << std::endl;
307 for (int j=0; j<instr.mv_ylen; j++)
309 for (int i=0; i<instr.mv_xlen; i++)
311 fdata << instr.pred_costs[k][j*instr.mv_xlen + i].SAD
312 <<" " << instr.pred_costs[k][j*instr.mv_xlen + i].mvcost
313 << " ";;
315 fdata << std::endl;
317 fdata << std::endl;
320 catch (...)
322 std::cout << "Error writing diagnostics data" << std::endl;
323 ret_stat = false;
325 fdata.exceptions (oldExceptions);
327 return ret_stat;
330 bool ReadPicData (std::ifstream &fdata, unsigned char *buffer, int frame_size)
332 bool ret_stat = true;
334 ios::iostate oldExceptions = fdata.exceptions();
335 fdata.exceptions (ios::failbit | ios::badbit);
338 fdata.read ((char *)buffer, frame_size);
340 catch (...)
342 ret_stat = false;
344 fdata.exceptions (oldExceptions);
345 return ret_stat;
348 bool Skip (std::ifstream &fdata, int start_frame, int frame_size)
350 bool ret_stat = true;
351 ios::iostate oldExceptions = fdata.exceptions();
352 fdata.exceptions (ios::failbit | ios::badbit);
355 unsigned char* buffer = new unsigned char[frame_size];
356 for (int i=0; i<start_frame; ++i)
357 ReadPicData(fdata, buffer, frame_size);
358 delete[] buffer;
360 catch (...)
362 std::cerr << "Skipping of first "<< start_frame << " frames failed"
363 << std::endl;
364 ret_stat = false;
366 fdata.exceptions (oldExceptions);
367 return ret_stat;
370 int GetFrameBufferSize (const dirac_encoder_context_t &enc_ctx)
372 int xl = enc_ctx.src_params.width;
373 int yl = enc_ctx.src_params.height;
375 int size;
377 switch (enc_ctx.src_params.chroma)
379 case format420:
380 size = (xl*yl*3)/2;
381 break;
382 case format422:
383 size = (xl*yl)*2;
384 break;
385 case format444:
386 size = (xl*yl)*3;
387 break;
388 default:
389 size = xl * yl;
390 break;
392 return size;
394 const string ChromaToString (dirac_chroma_t chroma)
396 switch (chroma)
398 case format422:
399 return string("YUV422P");
401 case format444:
402 return string("YUV444P");
404 case format420:
405 return string("YUV420P");
407 default:
408 break;
411 return string("Unknown");
414 const string PrefilterToString(dirac_prefilter_t pf)
416 switch (pf)
418 case CWM:
419 return string("CWM");
420 case RECTLP:
421 return string("RECTLP");
422 case DIAGLP:
423 return string("DIAGLP");
424 default:
425 return string("NO_PF");
430 dirac_chroma_t StringToChroma (const char* chroma)
432 if (strcmp(chroma, "YUV444P") == 0)
433 return format444;
434 else if (strcmp(chroma, "YUV422P") == 0)
435 return format422;
436 else if (strcmp(chroma, "YUV420P") == 0)
437 return format420;
438 else
439 return formatNK;
442 const string MvPrecisionToString (MVPrecisionType mv_type)
444 switch (mv_type)
446 case MV_PRECISION_PIXEL:
447 return string("Pixel");
448 case MV_PRECISION_HALF_PIXEL:
449 return string("Half Pixel");
450 case MV_PRECISION_QUARTER_PIXEL:
451 return string("Quarter Pixel");
452 case MV_PRECISION_EIGHTH_PIXEL:
453 return string("Eighth Pixel");
454 default:
455 return string("Undefined");
459 const string TransformFilterToString (WltFilter wf)
461 switch (wf)
463 case DD9_7:
464 return string("DD9_7");
465 case LEGALL5_3:
466 return string("LEGALL5_3");
467 case DD13_7:
468 return string("DD13_7");
469 case HAAR0:
470 return string("HAAR0");
471 case HAAR1:
472 return string("HAAR1");
473 case FIDELITY:
474 return string("FIDELITY");
475 case DAUB9_7:
476 return string("DAUB9_7");
477 default:
478 return string("Undefined");
482 WltFilter StringToTransformFilter (string wf)
484 if( wf=="DD9_7" )
485 return DD9_7;
486 else if( wf=="LEGALL5_3" )
487 return LEGALL5_3;
488 else if( wf=="DD13_7" )
489 return DD13_7;
490 else if( wf=="HAAR0" )
491 return HAAR0;
492 else if( wf=="HAAR1" )
493 return HAAR1;
494 else if( wf=="FIDELITY" )
495 return FIDELITY;
496 else if( wf=="DAUB9_7" )
497 return DAUB9_7;
498 else
499 return filterNK;
502 void display_codec_params(dirac_encoder_context_t &enc_ctx)
504 std::cout << "Source parameters : " << std::endl;
505 std::cout << "\theight=" << enc_ctx.src_params.height;
506 std::cout << " width=" << enc_ctx.src_params.width << std::endl;
507 std::cout << "\tchroma=" << ChromaToString(enc_ctx.src_params.chroma) << std::endl;
508 std::cout << "\tframe rate=" << enc_ctx.src_params.frame_rate.numerator;
509 std::cout << "/" << enc_ctx.src_params.frame_rate.denominator << std::endl;
510 std::cout << "Encoder parameters : " << std::endl;
511 std::cout << "\tquality factor=" << enc_ctx.enc_params.qf << std::endl;
512 std::cout << "\tGOP parameters : num_L1=" << enc_ctx.enc_params.num_L1;
513 if (enc_ctx.enc_params.num_L1 != 0)
515 std::cout << " L1_sep=" << enc_ctx.enc_params.L1_sep << std::endl;
516 std::cout << "\tBlock parameters : xblen=" << enc_ctx.enc_params.xblen;
517 std::cout << " yblen=" << enc_ctx.enc_params.yblen;
518 std::cout << " xbsep=" << enc_ctx.enc_params.xbsep;
519 std::cout << " ybsep=" << enc_ctx.enc_params.ybsep << std::endl;
520 std::cout << " \tMV Precision=" << MvPrecisionToString(enc_ctx.enc_params.mv_precision) << std::endl;
521 std::cout << " \tInter Frame Transform Filter=" << TransformFilterToString(enc_ctx.enc_params.inter_wlt_filter) << std::endl;
523 else
524 std::cout << " (I-frame only coding)" << std::endl;
525 std::cout << " \tIntra Frame Transform Filter=" << TransformFilterToString(enc_ctx.enc_params.intra_wlt_filter) << std::endl;
526 std::cout << " \tWavelet depth=" << enc_ctx.enc_params.wlt_depth << std::endl;
527 std::cout << " \tSpatial Partitioning=" << (enc_ctx.enc_params.spatial_partition ? "true" : "false") << std::endl;
528 std::cout << " \tMultiple Quantisers=" << (enc_ctx.enc_params.multi_quants ? "true" : "false") << std::endl;
529 std::cout << " \tPrefilter=" << PrefilterToString(enc_ctx.enc_params.prefilter) << std::endl;
530 std::cout << " \tField coding=" << (enc_ctx.enc_params.picture_coding_mode == 1? "true" : "false") << std::endl;
531 std::cout << " \tLossless Coding=" << (enc_ctx.enc_params.lossless ? "true" : "false") << std::endl;
532 std::cout << " \tEntropy Coding=" << (enc_ctx.enc_params.using_ac ? "Arithmetic Coding" : "Variable Length Coding") << std::endl;
535 int start_pos = 0;
536 int end_pos = -1;
537 bool verbose = false;
538 bool nolocal = true;
539 int fields_factor = 1;
541 bool parse_command_line(dirac_encoder_context_t& enc_ctx, int argc, char **argv)
543 /********** command line parameter parsing*********/
545 // An array indicating whether a parameter has been parsed
546 bool* parsed = new bool[argc];
548 // Program name has been parsed
549 parsed[0] = true;
551 // No other parameters
552 for (int i=1 ; i<argc ; ++i )
553 parsed[i] = false;
555 // The start and end-points of the parts of the file to be coded
556 // (end_pos set to -1 means code to the end)
558 memset (&enc_ctx, 0, sizeof(dirac_encoder_context_t));
560 //Now do the options
561 // Checking for presets. Assume custom by default
562 dirac_encoder_presets_t preset = VIDEO_FORMAT_CUSTOM;
563 for (int i = 1; i < argc; i++)
565 if ( strcmp(argv[i], "-help") == 0 ||
566 strcmp(argv[i], "-h") == 0)
568 display_help();
569 exit(EXIT_SUCCESS);
571 else if ( strcmp (argv[i], "-QSIF525") == 0 )
573 preset = VIDEO_FORMAT_QSIF525;
574 parsed[i] = true;
576 else if ( strcmp (argv[i], "-QCIF") == 0 )
578 preset = VIDEO_FORMAT_QCIF;
579 parsed[i] = true;
581 else if ( strcmp (argv[i], "-SIF525") == 0 )
583 preset = VIDEO_FORMAT_SIF525;
584 parsed[i] = true;
586 else if ( strcmp (argv[i], "-CIF") == 0 )
588 preset = VIDEO_FORMAT_CIF;
589 parsed[i] = true;
591 else if ( strcmp (argv[i], "-4CIF") == 0 )
593 preset = VIDEO_FORMAT_4CIF;
594 parsed[i] = true;
596 else if ( strcmp (argv[i], "-4SIF525") == 0 )
598 preset = VIDEO_FORMAT_4SIF525;
599 parsed[i] = true;
601 else if ( strcmp (argv[i], "-SD480I60") == 0 )
603 preset = VIDEO_FORMAT_SD_480I60;
604 parsed[i] = true;
606 else if ( strcmp (argv[i], "-SD576I50") == 0 )
608 preset = VIDEO_FORMAT_SD_576I50;
609 parsed[i] = true;
611 else if ( strcmp (argv[i], "-HD720P60") == 0 )
613 preset = VIDEO_FORMAT_HD_720P60;
614 parsed[i] = true;
616 else if ( strcmp (argv[i], "-HD720P50") == 0 )
618 preset = VIDEO_FORMAT_HD_720P50;
619 parsed[i] = true;
621 else if ( strcmp (argv[i], "-HD1080I60") == 0 )
623 preset = VIDEO_FORMAT_HD_1080I60;
624 parsed[i] = true;
626 else if ( strcmp (argv[i], "-HD1080I50") == 0 )
628 preset = VIDEO_FORMAT_HD_1080I50;
629 parsed[i] = true;
631 else if ( strcmp (argv[i], "-HD1080P60") == 0 )
633 preset = VIDEO_FORMAT_HD_1080P60;
634 parsed[i] = true;
636 else if ( strcmp (argv[i], "-HD1080P50") == 0 )
638 preset = VIDEO_FORMAT_HD_1080P50;
639 parsed[i] = true;
641 else if ( strcmp (argv[i], "-UHDTV4K60") == 0 )
643 preset = VIDEO_FORMAT_UHDTV_4K60;
644 parsed[i] = true;
646 else if ( strcmp (argv[i], "-UHDTV4K50") == 0 )
648 preset = VIDEO_FORMAT_UHDTV_4K50;
649 parsed[i] = true;
651 else if ( strcmp (argv[i], "-UHDTV8K60") == 0 )
653 preset = VIDEO_FORMAT_UHDTV_8K60;
654 parsed[i] = true;
656 else if ( strcmp (argv[i], "-UHDTV8K50") == 0 )
658 preset = VIDEO_FORMAT_UHDTV_8K50;
659 parsed[i] = true;
661 else if ( strcmp (argv[i], "-DC2K24") == 0 )
663 preset = VIDEO_FORMAT_DIGI_CINEMA_2K24;
664 parsed[i] = true;
666 else if ( strcmp (argv[i], "-DC4K24") == 0 )
668 preset = VIDEO_FORMAT_DIGI_CINEMA_4K24;
669 parsed[i] = true;
673 // initialise the encoder context
674 dirac_encoder_context_init (&enc_ctx, preset);
676 //now go over again and override video format presets with other values
677 for(int i=1; i < argc; )
679 if ( strcmp(argv[i], "-width") == 0 )
681 parsed[i] = true;
682 i++;
683 enc_ctx.src_params.width =
684 strtoul(argv[i],NULL,10);
685 parsed[i] = true;
687 else if ( strcmp(argv[i], "-height") == 0 )
689 parsed[i] = true;
690 i++;
691 enc_ctx.src_params.height =
692 strtoul(argv[i],NULL,10);
693 parsed[i] = true;
695 else if ( strcmp(argv[i], "-cformat") == 0 )
697 parsed[i] = true;
698 i++;
699 enc_ctx.src_params.chroma = StringToChroma (argv[i]);
700 if (enc_ctx.src_params.chroma == formatNK)
702 cerr << "Unsupported chroma format" << argv[i] << endl;
703 parsed[i] = false;
705 else
706 parsed[i] = true;
708 else if ( strcmp(argv[i], "-fr") == 0 )
710 parsed[i] = true;
711 i++;
712 if(strncmp(argv[i], "59.94", 5)==0)
714 parsed[i] = true;
715 enc_ctx.src_params.frame_rate.numerator=60000;
716 enc_ctx.src_params.frame_rate.denominator=1001;
718 else if(strncmp(argv[i], "23.98", 5)==0)
720 parsed[i] = true;
721 enc_ctx.src_params.frame_rate.numerator=24000;
722 enc_ctx.src_params.frame_rate.denominator=1001;
724 else if(strncmp(argv[i], "29.97", 5)==0)
726 parsed[i] = true;
727 enc_ctx.src_params.frame_rate.numerator=30000;
728 enc_ctx.src_params.frame_rate.denominator=1001;
730 //test for decimal format
731 else if(strcspn(argv[i], ".")!=strlen(argv[i]))
733 parsed[i] = true;
734 // look for whole number
735 char* num_token = strtok(argv[i], ".");
736 int whole = strtoul(num_token,NULL,10);
737 int decimal=0;
738 int decimal_length=0;
740 // look for decimal part
741 num_token = strtok(NULL, "");
742 if(num_token)
744 decimal_length=strlen(num_token);
745 decimal=strtoul(num_token, NULL, 10);
747 // calculate amount to raise to whole number
748 int multiply = (int)std::pow(10.0, decimal_length);
749 enc_ctx.src_params.frame_rate.numerator =
750 decimal == 0 ? whole : (multiply*whole)+decimal;
751 enc_ctx.src_params.frame_rate.denominator =
752 decimal == 0 ? 1 : multiply;
755 else
757 parsed[i] = true;
758 // assume e/d format
759 char* token = strtok(argv[i], "/");
760 enc_ctx.src_params.frame_rate.numerator =
761 strtoul(token,NULL,10);
762 enc_ctx.src_params.frame_rate.denominator = 1;
764 token = strtok(NULL, "");
765 if(token)
766 enc_ctx.src_params.frame_rate.denominator =
767 strtoul(token, NULL, 10);
770 else if ( strcmp(argv[i], "-source_sampling") == 0 )
772 parsed[i] = true;
773 i++;
774 parsed[i]= true;
775 if (!strcmp(argv[i], "progressive"))
776 enc_ctx.src_params.source_sampling = 0;
777 else if (!strcmp(argv[i], "interlaced"))
778 enc_ctx.src_params.source_sampling = 1;
779 else
781 cerr << "source_sampling should either be interlaced or progressive" << endl;
782 parsed[i] = false;
785 i++;
788 // finally, set the encoding paramters
790 // For small pictures, set better (more expensive) parameters
791 if (enc_ctx.src_params.width*enc_ctx.src_params.height<(702*480*2)/3){
792 enc_ctx.enc_params.mv_precision = MV_PRECISION_QUARTER_PIXEL;
793 enc_ctx.enc_params.xblen = 12;
794 enc_ctx.enc_params.yblen = 12;
795 enc_ctx.enc_params.xbsep = 8;
796 enc_ctx.enc_params.ybsep = 8;
799 for (int i=0; i<argc; ){
800 if ( strcmp(argv[i], "-field_coding") == 0 )
802 parsed[i] = true;
803 enc_ctx.enc_params.picture_coding_mode = 1;
804 fields_factor = 2;
806 else if ( strcmp(argv[i], "-qf") == 0 )
808 parsed[i] = true;
809 i++;
810 enc_ctx.enc_params.qf = atof(argv[i]);
811 parsed[i] = true;
813 else if ( strcmp(argv[i], "-full_search") == 0 )
815 parsed[i] = true;
816 enc_ctx.enc_params.full_search = 1;
817 i++;
819 enc_ctx.enc_params.x_range_me = strtoul(argv[i],NULL,10);
820 parsed[i] = true;
822 i++;
823 enc_ctx.enc_params.y_range_me = strtoul(argv[i],NULL,10);
824 parsed[i] = true;
827 else if ( strcmp(argv[i], "-combined_me") == 0 )
829 parsed[i] = true;
830 enc_ctx.enc_params.combined_me = 1;
832 else if ( strcmp(argv[i], "-targetrate") == 0 )
834 parsed[i] = true;
835 i++;
836 enc_ctx.enc_params.trate = strtoul(argv[i],NULL,10);
837 parsed[i] = true;
839 else if ( strcmp(argv[i], "-lossless") == 0 )
841 parsed[i] = true;
842 enc_ctx.enc_params.lossless = true;
844 else if ( strcmp(argv[i], "-L1_sep") == 0 )
846 parsed[i] = true;
847 i++;
848 enc_ctx.enc_params.L1_sep =
849 strtoul(argv[i],NULL,10);
850 parsed[i] = true;
852 else if ( strcmp(argv[i], "-num_L1") == 0 )
854 parsed[i] = true;
855 i++;
856 enc_ctx.enc_params.num_L1 =
857 strtoul(argv[i],NULL,10);
858 parsed[i] = true;
860 else if ( strcmp(argv[i], "-xblen") == 0 )
862 parsed[i] = true;
863 i++;
864 enc_ctx.enc_params.xblen =
865 strtoul(argv[i],NULL,10);
866 parsed[i] = true;
868 else if ( strcmp(argv[i], "-yblen") == 0 )
870 parsed[i] = true;
871 i++;
872 enc_ctx.enc_params.yblen =
873 strtoul(argv[i],NULL,10);
874 parsed[i] = true;
876 else if ( strcmp(argv[i], "-xbsep") == 0 )
878 parsed[i] = true;
879 i++;
880 enc_ctx.enc_params.xbsep =
881 strtoul(argv[i],NULL,10);
882 parsed[i] = true;
884 else if ( strcmp(argv[i], "-ybsep") == 0 )
886 parsed[i] = true;
887 i++;
888 enc_ctx.enc_params.ybsep =
889 strtoul(argv[i],NULL,10);
890 parsed[i] = true;
892 else if ( strcmp(argv[i], "-cpd") == 0 )
894 parsed[i] = true;
895 i++;
896 enc_ctx.enc_params.cpd =
897 strtoul(argv[i],NULL,10);
898 parsed[i] = true;
900 else if ( strcmp(argv[i], "-use_vlc") == 0 )
902 parsed[i] = true;
903 enc_ctx.enc_params.using_ac = false;
905 else if ( strcmp(argv[i], "-verbose") == 0 )
907 parsed[i] = true;
908 verbose = true;
910 else if ( strcmp(argv[i], "-local") == 0 )
912 parsed[i] = true;
913 nolocal = false;
915 else if ( strcmp(argv[i], "-start") == 0 )
917 parsed[i] = true;
918 i++;
919 start_pos = strtoul(argv[i],NULL,10);
920 parsed[i] = true;
922 else if ( strcmp(argv[i], "-stop") == 0 )
924 parsed[i] = true;
925 i++;
926 end_pos = strtoul(argv[i],NULL,10);
927 parsed[i] = true;
929 else if ( strcmp(argv[i], "-multi_quants") == 0 )
931 parsed[i] = true;
932 enc_ctx.enc_params.multi_quants = true;
934 else if ( strcmp(argv[i], "-no_spartition") == 0 )
936 parsed[i] = true;
937 enc_ctx.enc_params.spatial_partition = false;
939 else if ( strcmp(argv[i], "-prefilter") == 0 )
941 parsed[i] = true;
942 i++;
943 if(strcmp(argv[i], "DIAGLP")==0)
945 parsed[i] = true;
946 enc_ctx.enc_params.prefilter = DIAGLP;
947 i++;
948 enc_ctx.enc_params.prefilter_strength =
949 strtoul(argv[i],NULL,10);
950 parsed[i] = true;
952 else if(strcmp(argv[i], "RECTLP")==0)
954 parsed[i] = true;
955 enc_ctx.enc_params.prefilter = RECTLP;
956 i++;
957 enc_ctx.enc_params.prefilter_strength =
958 strtoul(argv[i],NULL,10);
959 parsed[i] = true;
961 else if(strcmp(argv[i], "CWM")==0)
963 parsed[i] = true;
964 enc_ctx.enc_params.prefilter = CWM;
965 i++;
966 enc_ctx.enc_params.prefilter_strength =
967 strtoul(argv[i],NULL,10);
968 parsed[i] = true;
970 else if(strcmp(argv[i], "NO_PF")==0)
972 parsed[i] = true;
973 enc_ctx.enc_params.prefilter = NO_PF;
974 i++;
975 enc_ctx.enc_params.prefilter_strength =
976 strtoul(argv[i],NULL,10);
977 parsed[i] = true;
980 else if ( strcmp(argv[i], "-wlt_depth") == 0 )
982 parsed[i] = true;
983 i++;
984 enc_ctx.enc_params.wlt_depth = strtoul(argv[i],NULL,10);
985 #if defined(HAVE_MMX)
986 if(enc_ctx.enc_params.wlt_depth > 4)
987 cerr << "Exceeds maximum transform depth ";
988 else
989 parsed[i] = true;
990 #else
991 parsed[i] = true;
992 #endif
994 else if ( strcmp(argv[i], "-iwlt_filter") == 0 )
996 parsed[i] = true;
997 i++;
998 WltFilter wf = StringToTransformFilter(string(argv[i]));
999 if (wf == filterNK)
1000 cerr << "Unrecognised Intra Wavelet Filter " << argv[i];
1001 else
1002 parsed[i] = true;
1003 enc_ctx.enc_params.intra_wlt_filter = wf;
1005 else if ( strcmp(argv[i], "-rwlt_filter") == 0 )
1007 parsed[i] = true;
1008 i++;
1009 WltFilter wf = StringToTransformFilter(argv[i]);
1010 if (wf == filterNK)
1011 cerr << "Unrecognised Intra Wavelet Filter " << argv[i];
1012 else
1013 parsed[i] = true;
1014 enc_ctx.enc_params.inter_wlt_filter = wf;
1016 else if ( strcmp(argv[i], "-mv_prec") == 0 )
1018 parsed[i]=true;
1019 ++i;
1020 if(strcmp(argv[i], "1/2")==0)
1022 parsed[i] = true;
1023 enc_ctx.enc_params.mv_precision = MV_PRECISION_HALF_PIXEL;
1025 else if(strcmp(argv[i], "1/4")==0)
1027 parsed[i] = true;
1028 enc_ctx.enc_params.mv_precision = MV_PRECISION_QUARTER_PIXEL;
1030 else if(strcmp(argv[i], "1/8")==0)
1032 parsed[i] = true;
1033 enc_ctx.enc_params.mv_precision = MV_PRECISION_EIGHTH_PIXEL;
1035 else if(strncmp(argv[i], "1", 3)==0)
1037 parsed[i] = true;
1038 enc_ctx.enc_params.mv_precision = MV_PRECISION_PIXEL;
1041 i++;
1042 }//opt
1044 // FIXME: currently only supporting vlc coding for iframe-only
1045 // sequences
1046 if (enc_ctx.enc_params.num_L1 != 0 && enc_ctx.enc_params.using_ac == 0)
1048 std::cerr<<std::endl<<"Entropy coding of coefficient data using VLC currently enabled for i-frame only sequences only"<<std::endl;
1049 return false;
1052 // check we have parsed everything
1053 bool all_parsed = true;
1054 for (int i=0 ; i<argc-2 ; ++i)
1056 if ( !parsed[i] )
1058 all_parsed = false;
1059 std::cerr<<std::endl<<"Unknown option "<<argv[i];
1062 if ( !all_parsed )
1064 display_help();
1065 return false;
1068 /* check that we have been suplied with input and output files */
1069 if(argc < 2 || parsed[argc-2] || parsed[argc-1]) {
1070 display_help();
1071 std::cerr<<std::endl<<"Insufficient arguments"<<std::endl;
1072 return false;
1076 delete[] parsed;
1078 return true;
1081 int main (int argc, char* argv[])
1083 // the variables we'll read parameters into
1084 dirac_encoder_context_t enc_ctx;
1086 if (!parse_command_line(enc_ctx, argc, argv))
1087 return EXIT_FAILURE;
1089 //output name for the bitstream
1090 string input,output;
1092 /*********************************************************************************/
1094 // last two arguments must be file names
1095 if (argv[argc-1][0] == '-')
1097 display_help();
1098 exit(1);
1101 if (argv[argc-2][0] == '-')
1102 input = "/dev/stdin";
1103 else
1104 input = argv[argc-2];
1106 output=argv[argc-1];
1108 //check we have real inputs
1109 if ((input.length() == 0) || (output.length() ==0))
1111 display_help();
1112 exit(1);
1116 if ( input==output )
1118 std::cerr << "Input and output file names must be different" << std::endl;
1119 exit(1);
1122 if ( verbose )
1123 display_codec_params(enc_ctx);
1127 /********************************************************************/
1128 //next do picture file stuff
1130 // Open uncompressed data file
1131 std::string input_name_yuv = input;
1132 std::ifstream
1133 ip_pic_ptr (input_name_yuv.c_str(), std::ios::in | std::ios::binary);
1134 if (!ip_pic_ptr)
1136 std::cerr << std::endl <<
1137 "Can't open input data file: " << input_name_yuv << std::endl;
1138 return EXIT_FAILURE;
1143 /********************************************************************/
1144 //open the bitstream file
1145 std::ofstream outfile(output.c_str(),std::ios::out | std::ios::binary); //bitstream output
1147 // open the decoded ouput file
1148 std::ofstream *outyuv = NULL, *outimt = NULL;
1150 if (nolocal == false)
1152 std::string output_name_yuv = output + ".localdec.yuv";
1153 std::string output_name_imt = output + ".imt";
1155 outyuv = new std::ofstream(output_name_yuv.c_str(),std::ios::out | std::ios::binary);
1157 // open the diagnostics ouput file
1158 outimt = new std::ofstream(output_name_imt.c_str(),std::ios::out | std::ios::binary);
1161 /********************************************************************/
1162 //do the work!!
1164 // Determine buffer size
1165 int frame_size = GetFrameBufferSize (enc_ctx);
1166 unsigned char *frame_buf = new unsigned char [frame_size];
1168 if ( end_pos == -1 )
1169 end_pos = INT_MAX;
1171 /* don't try and skip frames if they aren't any to skip, eg
1172 * this won't work on nonseekable filehandles. */
1173 if (start_pos && !Skip( ip_pic_ptr, start_pos, frame_size ))
1175 return EXIT_FAILURE;
1178 dirac_encoder_t *encoder;
1180 if (nolocal)
1182 enc_ctx.decode_flag = 0;
1183 enc_ctx.instr_flag = 0;
1185 else
1187 enc_ctx.decode_flag = 1;
1188 enc_ctx.instr_flag = 1;
1191 encoder = dirac_encoder_init( &enc_ctx, verbose );
1193 if (!encoder)
1195 std::cerr << "Unrecoverable Error: dirac_encoder_init failed. "
1196 << std::endl;
1197 return EXIT_FAILURE;
1201 if (outimt)
1202 WriteDiagnosticsHeader ( *outimt, encoder );
1205 int frames_loaded = 0;
1206 dirac_encoder_state_t state;
1208 clock_t start_t, stop_t;
1209 start_t = clock();
1211 bool go = true;
1214 if (frames_loaded <= (end_pos - start_pos) &&
1215 ReadPicData( ip_pic_ptr, frame_buf, frame_size ) == true)
1217 if (dirac_encoder_load( encoder, frame_buf, frame_size ) < 0)
1219 std::cerr << "dirac_encoder_load failed: Unrecoverable Encoder Error. Quitting..."
1220 << std::endl;
1221 return EXIT_FAILURE;
1223 frames_loaded++;
1225 else
1227 // push end of stream
1228 dirac_encoder_end_sequence( encoder );
1232 encoder->enc_buf.buffer = video_buf;
1233 encoder->enc_buf.size = VIDEO_BUFFER_SIZE;
1234 state = dirac_encoder_output ( encoder );
1235 switch (state)
1237 case ENC_STATE_AVAIL:
1238 assert (encoder->enc_buf.size > 0);
1240 outfile.write((char *)encoder->enc_buf.buffer,
1241 encoder->enc_buf.size);
1242 break;
1244 case ENC_STATE_BUFFER:
1245 break;
1246 case ENC_STATE_EOS:
1247 outfile.write((char *)encoder->enc_buf.buffer,
1248 encoder->enc_buf.size);
1249 go = false;
1250 break;
1251 case ENC_STATE_INVALID:
1252 std::cerr << "Invalid state. Unrecoverable Encoder Error. Quitting..."
1253 << std::endl;
1254 return EXIT_FAILURE;
1255 default:
1256 std::cerr << "Unknown Encoder state" << endl;
1257 break;
1260 WritePicData (*outyuv, encoder);
1261 WriteDiagnosticsData (*outimt, encoder);
1263 } while (state == ENC_STATE_AVAIL);
1265 } while (go);
1267 stop_t = clock();
1269 if ( verbose )
1270 std::cout << "The resulting bit-rate at "
1271 << (double)encoder->enc_ctx.src_params.frame_rate.numerator/
1272 encoder->enc_ctx.src_params.frame_rate.denominator
1273 << "Hz is " << encoder->enc_seqstats.bit_rate
1274 << " bits/sec." << std::endl;
1276 if ( verbose )
1278 std::cout<<"Time per frame: "<<
1279 (double)(stop_t-start_t)/(double)(CLOCKS_PER_SEC*frames_loaded);
1280 std::cout<<std::endl<<std::endl;
1282 /********************************************************************/
1284 // close the encoder
1285 dirac_encoder_close( encoder );
1286 // close the bitstream file
1287 outfile.close();
1288 // close the decoded output file
1289 if (outyuv)
1291 outyuv->close();
1292 delete outyuv;
1295 // close the decoded output header file
1296 if (outimt)
1298 outimt->close();
1299 delete outimt;
1301 // close the pic data file
1302 ip_pic_ptr.close();
1304 // delete frame buffer
1305 delete [] frame_buf;
1307 return EXIT_SUCCESS;