1 /* ***** BEGIN LICENSE BLOCK *****
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
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
23 * Contributor(s): Thomas Davies (Original Author),
25 * Anuradha Suraparaju,
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
42 * ***** END LICENSE BLOCK ***** */
53 #include <libdirac_encoder/dirac_encoder.h>
54 #include <sys/types.h>
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.";
70 cout
<< "\nUsage: progname -<flag1> [<flag1_val>] ... <input> <output>";
71 cout
<< "\nIn case of multiple assignment to the same parameter, the last holds.";
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 '-']";
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
);
157 std::cout
<< "Incomplete frame " << std::endl
;
160 fdata
.exceptions (oldExceptions
);
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
;
188 std::cerr
<< "Error writing sequence info in diagnostics file." << std::endl
;
191 fdata
.exceptions (oldExceptions
);
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
;
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
] << " ";
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
] << " ";
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
] << " ";
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
] << " ";
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
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
] << " ";
277 // FIXME: always expects 3 components
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
] << " ";
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
] << " ";
293 for (int k
= 0; k
< instr
.num_refs
; k
++)
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
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
322 std::cout
<< "Error writing diagnostics data" << std::endl
;
325 fdata
.exceptions (oldExceptions
);
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
);
344 fdata
.exceptions (oldExceptions
);
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
);
362 std::cerr
<< "Skipping of first "<< start_frame
<< " frames failed"
366 fdata
.exceptions (oldExceptions
);
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
;
377 switch (enc_ctx
.src_params
.chroma
)
394 const string
ChromaToString (dirac_chroma_t chroma
)
399 return string("YUV422P");
402 return string("YUV444P");
405 return string("YUV420P");
411 return string("Unknown");
414 const string
PrefilterToString(dirac_prefilter_t pf
)
419 return string("CWM");
421 return string("RECTLP");
423 return string("DIAGLP");
425 return string("NO_PF");
430 dirac_chroma_t
StringToChroma (const char* chroma
)
432 if (strcmp(chroma
, "YUV444P") == 0)
434 else if (strcmp(chroma
, "YUV422P") == 0)
436 else if (strcmp(chroma
, "YUV420P") == 0)
442 const string
MvPrecisionToString (MVPrecisionType 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");
455 return string("Undefined");
459 const string
TransformFilterToString (WltFilter wf
)
464 return string("DD9_7");
466 return string("LEGALL5_3");
468 return string("DD13_7");
470 return string("HAAR0");
472 return string("HAAR1");
474 return string("FIDELITY");
476 return string("DAUB9_7");
478 return string("Undefined");
482 WltFilter
StringToTransformFilter (string wf
)
486 else if( wf
=="LEGALL5_3" )
488 else if( wf
=="DD13_7" )
490 else if( wf
=="HAAR0" )
492 else if( wf
=="HAAR1" )
494 else if( wf
=="FIDELITY" )
496 else if( wf
=="DAUB9_7" )
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
;
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
;
537 bool verbose
= false;
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
551 // No other parameters
552 for (int i
=1 ; i
<argc
; ++i
)
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
));
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)
571 else if ( strcmp (argv
[i
], "-QSIF525") == 0 )
573 preset
= VIDEO_FORMAT_QSIF525
;
576 else if ( strcmp (argv
[i
], "-QCIF") == 0 )
578 preset
= VIDEO_FORMAT_QCIF
;
581 else if ( strcmp (argv
[i
], "-SIF525") == 0 )
583 preset
= VIDEO_FORMAT_SIF525
;
586 else if ( strcmp (argv
[i
], "-CIF") == 0 )
588 preset
= VIDEO_FORMAT_CIF
;
591 else if ( strcmp (argv
[i
], "-4CIF") == 0 )
593 preset
= VIDEO_FORMAT_4CIF
;
596 else if ( strcmp (argv
[i
], "-4SIF525") == 0 )
598 preset
= VIDEO_FORMAT_4SIF525
;
601 else if ( strcmp (argv
[i
], "-SD480I60") == 0 )
603 preset
= VIDEO_FORMAT_SD_480I60
;
606 else if ( strcmp (argv
[i
], "-SD576I50") == 0 )
608 preset
= VIDEO_FORMAT_SD_576I50
;
611 else if ( strcmp (argv
[i
], "-HD720P60") == 0 )
613 preset
= VIDEO_FORMAT_HD_720P60
;
616 else if ( strcmp (argv
[i
], "-HD720P50") == 0 )
618 preset
= VIDEO_FORMAT_HD_720P50
;
621 else if ( strcmp (argv
[i
], "-HD1080I60") == 0 )
623 preset
= VIDEO_FORMAT_HD_1080I60
;
626 else if ( strcmp (argv
[i
], "-HD1080I50") == 0 )
628 preset
= VIDEO_FORMAT_HD_1080I50
;
631 else if ( strcmp (argv
[i
], "-HD1080P60") == 0 )
633 preset
= VIDEO_FORMAT_HD_1080P60
;
636 else if ( strcmp (argv
[i
], "-HD1080P50") == 0 )
638 preset
= VIDEO_FORMAT_HD_1080P50
;
641 else if ( strcmp (argv
[i
], "-UHDTV4K60") == 0 )
643 preset
= VIDEO_FORMAT_UHDTV_4K60
;
646 else if ( strcmp (argv
[i
], "-UHDTV4K50") == 0 )
648 preset
= VIDEO_FORMAT_UHDTV_4K50
;
651 else if ( strcmp (argv
[i
], "-UHDTV8K60") == 0 )
653 preset
= VIDEO_FORMAT_UHDTV_8K60
;
656 else if ( strcmp (argv
[i
], "-UHDTV8K50") == 0 )
658 preset
= VIDEO_FORMAT_UHDTV_8K50
;
661 else if ( strcmp (argv
[i
], "-DC2K24") == 0 )
663 preset
= VIDEO_FORMAT_DIGI_CINEMA_2K24
;
666 else if ( strcmp (argv
[i
], "-DC4K24") == 0 )
668 preset
= VIDEO_FORMAT_DIGI_CINEMA_4K24
;
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 )
683 enc_ctx
.src_params
.width
=
684 strtoul(argv
[i
],NULL
,10);
687 else if ( strcmp(argv
[i
], "-height") == 0 )
691 enc_ctx
.src_params
.height
=
692 strtoul(argv
[i
],NULL
,10);
695 else if ( strcmp(argv
[i
], "-cformat") == 0 )
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
;
708 else if ( strcmp(argv
[i
], "-fr") == 0 )
712 if(strncmp(argv
[i
], "59.94", 5)==0)
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)
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)
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
]))
734 // look for whole number
735 char* num_token
= strtok(argv
[i
], ".");
736 int whole
= strtoul(num_token
,NULL
,10);
738 int decimal_length
=0;
740 // look for decimal part
741 num_token
= strtok(NULL
, "");
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
;
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
, "");
766 enc_ctx
.src_params
.frame_rate
.denominator
=
767 strtoul(token
, NULL
, 10);
770 else if ( strcmp(argv
[i
], "-source_sampling") == 0 )
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;
781 cerr
<< "source_sampling should either be interlaced or progressive" << endl
;
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 )
803 enc_ctx
.enc_params
.picture_coding_mode
= 1;
806 else if ( strcmp(argv
[i
], "-qf") == 0 )
810 enc_ctx
.enc_params
.qf
= atof(argv
[i
]);
813 else if ( strcmp(argv
[i
], "-full_search") == 0 )
816 enc_ctx
.enc_params
.full_search
= 1;
819 enc_ctx
.enc_params
.x_range_me
= strtoul(argv
[i
],NULL
,10);
823 enc_ctx
.enc_params
.y_range_me
= strtoul(argv
[i
],NULL
,10);
827 else if ( strcmp(argv
[i
], "-combined_me") == 0 )
830 enc_ctx
.enc_params
.combined_me
= 1;
832 else if ( strcmp(argv
[i
], "-targetrate") == 0 )
836 enc_ctx
.enc_params
.trate
= strtoul(argv
[i
],NULL
,10);
839 else if ( strcmp(argv
[i
], "-lossless") == 0 )
842 enc_ctx
.enc_params
.lossless
= true;
844 else if ( strcmp(argv
[i
], "-L1_sep") == 0 )
848 enc_ctx
.enc_params
.L1_sep
=
849 strtoul(argv
[i
],NULL
,10);
852 else if ( strcmp(argv
[i
], "-num_L1") == 0 )
856 enc_ctx
.enc_params
.num_L1
=
857 strtoul(argv
[i
],NULL
,10);
860 else if ( strcmp(argv
[i
], "-xblen") == 0 )
864 enc_ctx
.enc_params
.xblen
=
865 strtoul(argv
[i
],NULL
,10);
868 else if ( strcmp(argv
[i
], "-yblen") == 0 )
872 enc_ctx
.enc_params
.yblen
=
873 strtoul(argv
[i
],NULL
,10);
876 else if ( strcmp(argv
[i
], "-xbsep") == 0 )
880 enc_ctx
.enc_params
.xbsep
=
881 strtoul(argv
[i
],NULL
,10);
884 else if ( strcmp(argv
[i
], "-ybsep") == 0 )
888 enc_ctx
.enc_params
.ybsep
=
889 strtoul(argv
[i
],NULL
,10);
892 else if ( strcmp(argv
[i
], "-cpd") == 0 )
896 enc_ctx
.enc_params
.cpd
=
897 strtoul(argv
[i
],NULL
,10);
900 else if ( strcmp(argv
[i
], "-use_vlc") == 0 )
903 enc_ctx
.enc_params
.using_ac
= false;
905 else if ( strcmp(argv
[i
], "-verbose") == 0 )
910 else if ( strcmp(argv
[i
], "-local") == 0 )
915 else if ( strcmp(argv
[i
], "-start") == 0 )
919 start_pos
= strtoul(argv
[i
],NULL
,10);
922 else if ( strcmp(argv
[i
], "-stop") == 0 )
926 end_pos
= strtoul(argv
[i
],NULL
,10);
929 else if ( strcmp(argv
[i
], "-multi_quants") == 0 )
932 enc_ctx
.enc_params
.multi_quants
= true;
934 else if ( strcmp(argv
[i
], "-no_spartition") == 0 )
937 enc_ctx
.enc_params
.spatial_partition
= false;
939 else if ( strcmp(argv
[i
], "-prefilter") == 0 )
943 if(strcmp(argv
[i
], "DIAGLP")==0)
946 enc_ctx
.enc_params
.prefilter
= DIAGLP
;
948 enc_ctx
.enc_params
.prefilter_strength
=
949 strtoul(argv
[i
],NULL
,10);
952 else if(strcmp(argv
[i
], "RECTLP")==0)
955 enc_ctx
.enc_params
.prefilter
= RECTLP
;
957 enc_ctx
.enc_params
.prefilter_strength
=
958 strtoul(argv
[i
],NULL
,10);
961 else if(strcmp(argv
[i
], "CWM")==0)
964 enc_ctx
.enc_params
.prefilter
= CWM
;
966 enc_ctx
.enc_params
.prefilter_strength
=
967 strtoul(argv
[i
],NULL
,10);
970 else if(strcmp(argv
[i
], "NO_PF")==0)
973 enc_ctx
.enc_params
.prefilter
= NO_PF
;
975 enc_ctx
.enc_params
.prefilter_strength
=
976 strtoul(argv
[i
],NULL
,10);
980 else if ( strcmp(argv
[i
], "-wlt_depth") == 0 )
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 ";
994 else if ( strcmp(argv
[i
], "-iwlt_filter") == 0 )
998 WltFilter wf
= StringToTransformFilter(string(argv
[i
]));
1000 cerr
<< "Unrecognised Intra Wavelet Filter " << argv
[i
];
1003 enc_ctx
.enc_params
.intra_wlt_filter
= wf
;
1005 else if ( strcmp(argv
[i
], "-rwlt_filter") == 0 )
1009 WltFilter wf
= StringToTransformFilter(argv
[i
]);
1011 cerr
<< "Unrecognised Intra Wavelet Filter " << argv
[i
];
1014 enc_ctx
.enc_params
.inter_wlt_filter
= wf
;
1016 else if ( strcmp(argv
[i
], "-mv_prec") == 0 )
1020 if(strcmp(argv
[i
], "1/2")==0)
1023 enc_ctx
.enc_params
.mv_precision
= MV_PRECISION_HALF_PIXEL
;
1025 else if(strcmp(argv
[i
], "1/4")==0)
1028 enc_ctx
.enc_params
.mv_precision
= MV_PRECISION_QUARTER_PIXEL
;
1030 else if(strcmp(argv
[i
], "1/8")==0)
1033 enc_ctx
.enc_params
.mv_precision
= MV_PRECISION_EIGHTH_PIXEL
;
1035 else if(strncmp(argv
[i
], "1", 3)==0)
1038 enc_ctx
.enc_params
.mv_precision
= MV_PRECISION_PIXEL
;
1044 // FIXME: currently only supporting vlc coding for iframe-only
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
;
1052 // check we have parsed everything
1053 bool all_parsed
= true;
1054 for (int i
=0 ; i
<argc
-2 ; ++i
)
1059 std::cerr
<<std::endl
<<"Unknown option "<<argv
[i
];
1068 /* check that we have been suplied with input and output files */
1069 if(argc
< 2 || parsed
[argc
-2] || parsed
[argc
-1]) {
1071 std::cerr
<<std::endl
<<"Insufficient arguments"<<std::endl
;
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] == '-')
1101 if (argv
[argc
-2][0] == '-')
1102 input
= "/dev/stdin";
1104 input
= argv
[argc
-2];
1106 output
=argv
[argc
-1];
1108 //check we have real inputs
1109 if ((input
.length() == 0) || (output
.length() ==0))
1116 if ( input
==output
)
1118 std::cerr
<< "Input and output file names must be different" << std::endl
;
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
;
1133 ip_pic_ptr (input_name_yuv
.c_str(), std::ios::in
| std::ios::binary
);
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 /********************************************************************/
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 )
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
;
1182 enc_ctx
.decode_flag
= 0;
1183 enc_ctx
.instr_flag
= 0;
1187 enc_ctx
.decode_flag
= 1;
1188 enc_ctx
.instr_flag
= 1;
1191 encoder
= dirac_encoder_init( &enc_ctx
, verbose
);
1195 std::cerr
<< "Unrecoverable Error: dirac_encoder_init failed. "
1197 return EXIT_FAILURE
;
1202 WriteDiagnosticsHeader ( *outimt
, encoder
);
1205 int frames_loaded
= 0;
1206 dirac_encoder_state_t state
;
1208 clock_t start_t
, stop_t
;
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..."
1221 return EXIT_FAILURE
;
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
);
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
);
1244 case ENC_STATE_BUFFER
:
1247 outfile
.write((char *)encoder
->enc_buf
.buffer
,
1248 encoder
->enc_buf
.size
);
1251 case ENC_STATE_INVALID
:
1252 std::cerr
<< "Invalid state. Unrecoverable Encoder Error. Quitting..."
1254 return EXIT_FAILURE
;
1256 std::cerr
<< "Unknown Encoder state" << endl
;
1260 WritePicData (*outyuv
, encoder
);
1261 WriteDiagnosticsData (*outimt
, encoder
);
1263 } while (state
== ENC_STATE_AVAIL
);
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
;
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
1288 // close the decoded output file
1295 // close the decoded output header file
1301 // close the pic data file
1304 // delete frame buffer
1305 delete [] frame_buf
;
1307 return EXIT_SUCCESS
;