1 /*****************************************************************************
2  * schroedinger.c: Dirac decoder module making use of libschroedinger.
3  *          (http://www.bbc.co.uk/rd/projects/dirac/index.shtml)
4  *          (http://diracvideo.org)
5  *****************************************************************************
6  * Copyright (C) 2008-2011 VLC authors and VideoLAN
7  *
8  * Authors: Jonathan Rosser <jonathan.rosser@gmail.com>
9  *          David Flynn <davidf at rd dot bbc.co.uk>
10  *          Anuradha Suraparaju <asuraparaju at gmail dot com>
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU Lesser General Public License as published by
14  * the Free Software Foundation; either version 2.1 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26 
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34 
35 #include <assert.h>
36 
37 #include <vlc_common.h>
38 #include <vlc_plugin.h>
39 #include <vlc_codec.h>
40 
41 #include <schroedinger/schro.h>
42 
43 /*****************************************************************************
44  * Module descriptor
45  *****************************************************************************/
46 static int        OpenDecoder  ( vlc_object_t * );
47 static void       CloseDecoder ( vlc_object_t * );
48 static int        OpenEncoder  ( vlc_object_t * );
49 static void       CloseEncoder ( vlc_object_t * );
50 
51 #define ENC_CFG_PREFIX "sout-schro-"
52 
53 #define ENC_CHROMAFMT "chroma-fmt"
54 #define ENC_CHROMAFMT_TEXT N_("Chroma format")
55 #define ENC_CHROMAFMT_LONGTEXT N_("Picking chroma format will force a " \
56                                   "conversion of the video into that format")
57 static const char *const enc_chromafmt_list[] =
58   { "420", "422", "444" };
59 static const char *const enc_chromafmt_list_text[] =
60   { N_("4:2:0"), N_("4:2:2"), N_("4:4:4") };
61 
62 #define ENC_RATE_CONTROL "rate-control"
63 #define ENC_RATE_CONTROL_TEXT N_("Rate control method")
64 #define ENC_RATE_CONTROL_LONGTEXT N_("Method used to encode the video sequence")
65 
66 static const char *enc_rate_control_list[] = {
67   "constant_noise_threshold",
68   "constant_bitrate",
69   "low_delay",
70   "lossless",
71   "constant_lambda",
72   "constant_error",
73   "constant_quality"
74 };
75 
76 static const char *enc_rate_control_list_text[] = {
77   N_("Constant noise threshold mode"),
78   N_("Constant bitrate mode (CBR)"),
79   N_("Low Delay mode"),
80   N_("Lossless mode"),
81   N_("Constant lambda mode"),
82   N_("Constant error mode"),
83   N_("Constant quality mode")
84 };
85 
86 #define ENC_GOP_STRUCTURE "gop-structure"
87 #define ENC_GOP_STRUCTURE_TEXT N_("GOP structure")
88 #define ENC_GOP_STRUCTURE_LONGTEXT N_("GOP structure used to encode the video sequence")
89 
90 static const char *enc_gop_structure_list[] = {
91   "adaptive",
92   "intra_only",
93   "backref",
94   "chained_backref",
95   "biref",
96   "chained_biref"
97 };
98 
99 static const char *enc_gop_structure_list_text[] = {
100   N_("No fixed gop structure. A picture can be intra or inter and refer to previous or future pictures."),
101   N_("I-frame only sequence"),
102   N_("Inter pictures refere to previous pictures only"),
103   N_("Inter pictures refere to previous pictures only"),
104   N_("Inter pictures can refer to previous or future pictures"),
105   N_("Inter pictures can refer to previous or future pictures")
106 };
107 
108 #define ENC_QUALITY "quality"
109 #define ENC_QUALITY_TEXT N_("Constant quality factor")
110 #define ENC_QUALITY_LONGTEXT N_("Quality factor to use in constant quality mode")
111 
112 #define ENC_NOISE_THRESHOLD "noise-threshold"
113 #define ENC_NOISE_THRESHOLD_TEXT N_("Noise Threshold")
114 #define ENC_NOISE_THRESHOLD_LONGTEXT N_("Noise threshold to use in constant noise threshold mode")
115 
116 #define ENC_BITRATE "bitrate"
117 #define ENC_BITRATE_TEXT N_("CBR bitrate (kbps)")
118 #define ENC_BITRATE_LONGTEXT N_("Target bitrate in kbps when encoding in constant bitrate mode")
119 
120 #define ENC_MAX_BITRATE "max-bitrate"
121 #define ENC_MAX_BITRATE_TEXT N_("Maximum bitrate (kbps)")
122 #define ENC_MAX_BITRATE_LONGTEXT N_("Maximum bitrate in kbps when encoding in constant bitrate mode")
123 
124 #define ENC_MIN_BITRATE "min-bitrate"
125 #define ENC_MIN_BITRATE_TEXT N_("Minimum bitrate (kbps)")
126 #define ENC_MIN_BITRATE_LONGTEXT N_("Minimum bitrate in kbps when encoding in constant bitrate mode")
127 
128 #define ENC_AU_DISTANCE "gop-length"
129 #define ENC_AU_DISTANCE_TEXT N_("GOP length")
130 #define ENC_AU_DISTANCE_LONGTEXT N_("Number of pictures between successive sequence headers i.e. length of the group of pictures")
131 
132 
133 #define ENC_PREFILTER "filtering"
134 #define ENC_PREFILTER_TEXT N_("Prefilter")
135 #define ENC_PREFILTER_LONGTEXT N_("Enable adaptive prefiltering")
136 
137 static const char *enc_filtering_list[] = {
138   "none",
139   "center_weighted_median",
140   "gaussian",
141   "add_noise",
142   "adaptive_gaussian",
143   "lowpass"
144 };
145 
146 static const char *enc_filtering_list_text[] = {
147   N_("No pre-filtering"),
148   N_("Centre Weighted Median"),
149   N_("Gaussian Low Pass Filter"),
150   N_("Add Noise"),
151   N_("Gaussian Adaptive Low Pass Filter"),
152   N_("Low Pass Filter"),
153 };
154 
155 #define ENC_PREFILTER_STRENGTH "filter-value"
156 #define ENC_PREFILTER_STRENGTH_TEXT N_("Amount of prefiltering")
157 #define ENC_PREFILTER_STRENGTH_LONGTEXT N_("Higher value implies more prefiltering")
158 
159 #define ENC_CODINGMODE "coding-mode"
160 #define ENC_CODINGMODE_TEXT N_("Picture coding mode")
161 #define ENC_CODINGMODE_LONGTEXT N_("Field coding is where interlaced fields are coded" \
162                                    " separately as opposed to a pseudo-progressive frame")
163 static const char *const enc_codingmode_list[] =
164   { "auto", "progressive", "field" };
165 static const char *const enc_codingmode_list_text[] =
166   { N_("auto - let encoder decide based upon input (Best)"),
167     N_("force coding frame as single picture"),
168     N_("force coding frame as separate interlaced fields"),
169   };
170 
171 /* advanced option only */
172 #define ENC_MCBLK_SIZE "motion-block-size"
173 #define ENC_MCBLK_SIZE_TEXT N_("Size of motion compensation blocks")
174 
175 static const char *enc_block_size_list[] = {
176   "automatic",
177   "small",
178   "medium",
179   "large"
180 };
181 static const char *const enc_block_size_list_text[] =
182   { N_("automatic - let encoder decide based upon input (Best)"),
183     N_("small - use small motion compensation blocks"),
184     N_("medium - use medium motion compensation blocks"),
185     N_("large - use large motion compensation blocks"),
186   };
187 
188 /* advanced option only */
189 #define ENC_MCBLK_OVERLAP "motion-block-overlap"
190 #define ENC_MCBLK_OVERLAP_TEXT N_("Overlap of motion compensation blocks")
191 
192 static const char *enc_block_overlap_list[] = {
193   "automatic",
194   "none",
195   "partial",
196   "full"
197 };
198 static const char *const enc_block_overlap_list_text[] =
199   { N_("automatic - let encoder decide based upon input (Best)"),
200     N_("none - Motion compensation blocks do not overlap"),
201     N_("partial - Motion compensation blocks only partially overlap"),
202     N_("full - Motion compensation blocks fully overlap"),
203   };
204 
205 
206 #define ENC_MVPREC "mv-precision"
207 #define ENC_MVPREC_TEXT N_("Motion Vector precision")
208 #define ENC_MVPREC_LONGTEXT N_("Motion Vector precision in pels")
209 static const char *const enc_mvprec_list[] =
210   { "1", "1/2", "1/4", "1/8" };
211 
212 /* advanced option only */
213 #define ENC_ME_COMBINED "me-combined"
214 #define ENC_ME_COMBINED_TEXT N_("Three component motion estimation")
215 #define ENC_ME_COMBINED_LONGTEXT N_("Use chroma as part of the motion estimation process")
216 
217 #define ENC_DWTINTRA "intra-wavelet"
218 #define ENC_DWTINTRA_TEXT N_("Intra picture DWT filter")
219 
220 #define ENC_DWTINTER "inter-wavelet"
221 #define ENC_DWTINTER_TEXT N_("Inter picture DWT filter")
222 
223 static const char *enc_wavelet_list[] = {
224   "desl_dubuc_9_7",
225   "le_gall_5_3",
226   "desl_dubuc_13_7",
227   "haar_0",
228   "haar_1",
229   "fidelity",
230   "daub_9_7"
231 };
232 
233 static const char *enc_wavelet_list_text[] = {
234   "Deslauriers-Dubuc (9,7)",
235   "LeGall (5,3)",
236   "Deslauriers-Dubuc (13,7)",
237   "Haar with no shift",
238   "Haar with single shift per level",
239   "Fidelity filter",
240   "Daubechies (9,7) integer approximation"
241 };
242 
243 #define ENC_DWTDEPTH "transform-depth"
244 #define ENC_DWTDEPTH_TEXT N_("Number of DWT iterations")
245 #define ENC_DWTDEPTH_LONGTEXT N_("Also known as DWT levels")
246 
247 
248 /* advanced option only */
249 #define ENC_MULTIQUANT "enable-multiquant"
250 #define ENC_MULTIQUANT_TEXT N_("Enable multiple quantizers")
251 #define ENC_MULTIQUANT_LONGTEXT N_("Enable multiple quantizers per subband (one per codeblock)")
252 
253 /* advanced option only */
254 #define ENC_NOAC "enable-noarith"
255 #define ENC_NOAC_TEXT N_("Disable arithmetic coding")
256 #define ENC_NOAC_LONGTEXT N_("Use variable length codes instead, useful for very high bitrates")
257 
258 /* visual modelling */
259 /* advanced option only */
260 #define ENC_PWT "perceptual-weighting"
261 #define ENC_PWT_TEXT N_("perceptual weighting method")
262 
263 static const char *enc_perceptual_weighting_list[] = {
264   "none",
265   "ccir959",
266   "moo",
267   "manos_sakrison"
268 };
269 
270 /* advanced option only */
271 #define ENC_PDIST "perceptual-distance"
272 #define ENC_PDIST_TEXT N_("perceptual distance")
273 #define ENC_PDIST_LONGTEXT N_("perceptual distance to calculate perceptual weight")
274 
275 /* advanced option only */
276 #define ENC_HSLICES "horiz-slices"
277 #define ENC_HSLICES_TEXT N_("Horizontal slices per frame")
278 #define ENC_HSLICES_LONGTEXT N_("Number of horizontal slices per frame in low delay mode")
279 
280 /* advanced option only */
281 #define ENC_VSLICES "vert-slices"
282 #define ENC_VSLICES_TEXT N_("Vertical slices per frame")
283 #define ENC_VSLICES_LONGTEXT N_("Number of vertical slices per frame in low delay mode")
284 
285 /* advanced option only */
286 #define ENC_SCBLK_SIZE "codeblock-size"
287 #define ENC_SCBLK_SIZE_TEXT N_("Size of code blocks in each subband")
288 
289 static const char *enc_codeblock_size_list[] = {
290   "automatic",
291   "small",
292   "medium",
293   "large",
294   "full"
295 };
296 static const char *const enc_codeblock_size_list_text[] =
297   { N_("automatic - let encoder decide based upon input (Best)"),
298     N_("small - use small code blocks"),
299     N_("medium - use medium sized code blocks"),
300     N_("large - use large code blocks"),
301     N_("full - One code block per subband"),
302   };
303 
304 /* advanced option only */
305 #define ENC_ME_HIERARCHICAL "enable-hierarchical-me"
306 #define ENC_ME_HIERARCHICAL_TEXT N_("Enable hierarchical Motion Estimation")
307 
308 /* advanced option only */
309 #define ENC_ME_DOWNSAMPLE_LEVELS "downsample-levels"
310 #define ENC_ME_DOWNSAMPLE_LEVELS_TEXT N_("Number of levels of downsampling")
311 #define ENC_ME_DOWNSAMPLE_LEVELS_LONGTEXT N_("Number of levels of downsampling in hierarchical motion estimation mode")
312 
313 /* advanced option only */
314 #define ENC_ME_GLOBAL_MOTION "enable-global-me"
315 #define ENC_ME_GLOBAL_MOTION_TEXT N_("Enable Global Motion Estimation")
316 
317 /* advanced option only */
318 #define ENC_ME_PHASECORR "enable-phasecorr-me"
319 #define ENC_ME_PHASECORR_TEXT N_("Enable Phase Correlation Estimation")
320 
321 /* advanced option only */
322 #define ENC_SCD "enable-scd"
323 #define ENC_SCD_TEXT N_("Enable Scene Change Detection")
324 
325 /* advanced option only */
326 #define ENC_FORCE_PROFILE "force-profile"
327 #define ENC_FORCE_PROFILE_TEXT N_("Force Profile")
328 
329 static const char *enc_profile_list[] = {
330   "auto",
331   "vc2_low_delay",
332   "vc2_simple",
333   "vc2_main",
334   "main"
335 };
336 
337 static const char *const enc_profile_list_text[] =
338   { N_("automatic - let encoder decide based upon input (Best)"),
339     N_("VC2 Low Delay Profile"),
340     N_("VC2 Simple Profile"),
341     N_("VC2 Main Profile"),
342     N_("Main Profile"),
343   };
344 
345 static const char *const ppsz_enc_options[] = {
346     ENC_RATE_CONTROL, ENC_GOP_STRUCTURE, ENC_QUALITY, ENC_NOISE_THRESHOLD, ENC_BITRATE,
347     ENC_MIN_BITRATE, ENC_MAX_BITRATE, ENC_AU_DISTANCE, ENC_CHROMAFMT,
348     ENC_PREFILTER, ENC_PREFILTER_STRENGTH, ENC_CODINGMODE, ENC_MCBLK_SIZE,
349     ENC_MCBLK_OVERLAP, ENC_MVPREC, ENC_ME_COMBINED, ENC_DWTINTRA, ENC_DWTINTER,
350     ENC_DWTDEPTH, ENC_MULTIQUANT, ENC_NOAC, ENC_PWT, ENC_PDIST, ENC_HSLICES,
351     ENC_VSLICES, ENC_SCBLK_SIZE, ENC_ME_HIERARCHICAL, ENC_ME_DOWNSAMPLE_LEVELS,
352     ENC_ME_GLOBAL_MOTION, ENC_ME_PHASECORR, ENC_SCD, ENC_FORCE_PROFILE,
353     NULL
354 };
355 
356 
357 /* Module declaration */
358 
359 vlc_module_begin ()
360     set_category( CAT_INPUT )
361     set_subcategory( SUBCAT_INPUT_VCODEC )
362     set_shortname( "Schroedinger" )
363     set_description( N_("Dirac video decoder using libschroedinger") )
364     set_capability( "video decoder", 200 )
365     set_callbacks( OpenDecoder, CloseDecoder )
366     add_shortcut( "schroedinger" )
367 
368     /* encoder */
369     add_submodule()
370     set_section( N_("Encoding") , NULL )
371     set_description( N_("Dirac video encoder using libschroedinger") )
372     set_capability( "encoder", 110 )
373     set_callbacks( OpenEncoder, CloseEncoder )
374     add_shortcut( "schroedinger", "schro" )
375 
376     add_string( ENC_CFG_PREFIX ENC_RATE_CONTROL, NULL,
377                  ENC_RATE_CONTROL_TEXT, ENC_RATE_CONTROL_LONGTEXT, false )
378     change_string_list( enc_rate_control_list, enc_rate_control_list_text )
379 
380     add_float( ENC_CFG_PREFIX ENC_QUALITY, -1.,
381                ENC_QUALITY_TEXT, ENC_QUALITY_LONGTEXT, false )
382     change_float_range(-1., 10.);
383 
384     add_float( ENC_CFG_PREFIX ENC_NOISE_THRESHOLD, -1.,
385                ENC_NOISE_THRESHOLD_TEXT, ENC_NOISE_THRESHOLD_LONGTEXT, false )
386     change_float_range(-1., 100.);
387 
388     add_integer( ENC_CFG_PREFIX ENC_BITRATE, -1,
389                  ENC_BITRATE_TEXT, ENC_BITRATE_LONGTEXT, false )
390     change_integer_range(-1, INT_MAX);
391 
392     add_integer( ENC_CFG_PREFIX ENC_MAX_BITRATE, -1,
393                  ENC_MAX_BITRATE_TEXT, ENC_MAX_BITRATE_LONGTEXT, false )
394     change_integer_range(-1, INT_MAX);
395 
396     add_integer( ENC_CFG_PREFIX ENC_MIN_BITRATE, -1,
397                  ENC_MIN_BITRATE_TEXT, ENC_MIN_BITRATE_LONGTEXT, false )
398     change_integer_range(-1, INT_MAX);
399 
400     add_string( ENC_CFG_PREFIX ENC_GOP_STRUCTURE, NULL,
401                  ENC_GOP_STRUCTURE_TEXT, ENC_GOP_STRUCTURE_LONGTEXT, false )
402     change_string_list( enc_gop_structure_list, enc_gop_structure_list_text )
403 
404     add_integer( ENC_CFG_PREFIX ENC_AU_DISTANCE, -1,
405                  ENC_AU_DISTANCE_TEXT, ENC_AU_DISTANCE_LONGTEXT, false )
406     change_integer_range(-1, INT_MAX);
407 
408     add_string( ENC_CFG_PREFIX ENC_CHROMAFMT, "420",
409                 ENC_CHROMAFMT_TEXT, ENC_CHROMAFMT_LONGTEXT, false )
410     change_string_list( enc_chromafmt_list, enc_chromafmt_list_text )
411 
412     add_string( ENC_CFG_PREFIX ENC_CODINGMODE, "auto",
413                 ENC_CODINGMODE_TEXT, ENC_CODINGMODE_LONGTEXT, false )
414     change_string_list( enc_codingmode_list, enc_codingmode_list_text )
415 
416     add_string( ENC_CFG_PREFIX ENC_MVPREC, NULL,
417                 ENC_MVPREC_TEXT, ENC_MVPREC_LONGTEXT, false )
418     change_string_list( enc_mvprec_list, enc_mvprec_list )
419 
420     /* advanced option only */
421     add_string( ENC_CFG_PREFIX ENC_MCBLK_SIZE, NULL,
422                 ENC_MCBLK_SIZE_TEXT, ENC_MCBLK_SIZE_TEXT, true )
423     change_string_list( enc_block_size_list, enc_block_size_list_text )
424 
425 
426     /* advanced option only */
427     add_string( ENC_CFG_PREFIX ENC_MCBLK_OVERLAP, NULL,
428                 ENC_MCBLK_OVERLAP_TEXT, ENC_MCBLK_OVERLAP_TEXT, true )
429     change_string_list( enc_block_overlap_list, enc_block_overlap_list_text )
430 
431     /* advanced option only */
432     add_integer( ENC_CFG_PREFIX ENC_ME_COMBINED, -1,
433               ENC_ME_COMBINED_TEXT, ENC_ME_COMBINED_LONGTEXT, true )
434     change_integer_range(-1, 1 );
435 
436     /* advanced option only */
437     add_integer( ENC_CFG_PREFIX ENC_ME_HIERARCHICAL, -1,
438                  ENC_ME_HIERARCHICAL_TEXT, ENC_ME_HIERARCHICAL_TEXT, true )
439     change_integer_range(-1, 1 );
440 
441     /* advanced option only */
442     add_integer( ENC_CFG_PREFIX ENC_ME_DOWNSAMPLE_LEVELS, -1,
443                  ENC_ME_DOWNSAMPLE_LEVELS_TEXT, ENC_ME_DOWNSAMPLE_LEVELS_LONGTEXT, true )
444     change_integer_range(-1, 8 );
445 
446     /* advanced option only */
447     add_integer( ENC_CFG_PREFIX ENC_ME_GLOBAL_MOTION, -1,
448                  ENC_ME_GLOBAL_MOTION_TEXT, ENC_ME_GLOBAL_MOTION_TEXT, true )
449     change_integer_range(-1, 1 );
450 
451     /* advanced option only */
452     add_integer( ENC_CFG_PREFIX ENC_ME_PHASECORR, -1,
453                  ENC_ME_PHASECORR_TEXT, ENC_ME_PHASECORR_TEXT, true )
454     change_integer_range(-1, 1 );
455 
456     add_string( ENC_CFG_PREFIX ENC_DWTINTRA, NULL,
457                 ENC_DWTINTRA_TEXT, ENC_DWTINTRA_TEXT, false )
458     change_string_list( enc_wavelet_list, enc_wavelet_list_text )
459 
460     add_string( ENC_CFG_PREFIX ENC_DWTINTER, NULL,
461                 ENC_DWTINTER_TEXT, ENC_DWTINTER_TEXT, false )
462     change_string_list( enc_wavelet_list, enc_wavelet_list_text )
463 
464     add_integer( ENC_CFG_PREFIX ENC_DWTDEPTH, -1,
465                  ENC_DWTDEPTH_TEXT, ENC_DWTDEPTH_LONGTEXT, false )
466     change_integer_range(-1, SCHRO_LIMIT_ENCODER_TRANSFORM_DEPTH );
467 
468     /* advanced option only */
469     add_integer( ENC_CFG_PREFIX ENC_MULTIQUANT, -1,
470                  ENC_MULTIQUANT_TEXT, ENC_MULTIQUANT_LONGTEXT, true )
471     change_integer_range(-1, 1 );
472 
473     /* advanced option only */
474     add_string( ENC_CFG_PREFIX ENC_SCBLK_SIZE, NULL,
475                 ENC_SCBLK_SIZE_TEXT, ENC_SCBLK_SIZE_TEXT, true )
476     change_string_list( enc_codeblock_size_list, enc_codeblock_size_list_text )
477 
478     add_string( ENC_CFG_PREFIX ENC_PREFILTER, NULL,
479                 ENC_PREFILTER_TEXT, ENC_PREFILTER_LONGTEXT, false )
480     change_string_list( enc_filtering_list, enc_filtering_list_text )
481 
482     add_float( ENC_CFG_PREFIX ENC_PREFILTER_STRENGTH, -1.,
483                  ENC_PREFILTER_STRENGTH_TEXT, ENC_PREFILTER_STRENGTH_LONGTEXT, false )
484     change_float_range(-1., 100.0);
485 
486     /* advanced option only */
487     add_integer( ENC_CFG_PREFIX ENC_SCD, -1,
488                  ENC_SCD_TEXT, ENC_SCD_TEXT, true )
489     change_integer_range(-1, 1 );
490 
491     /* advanced option only */
492     add_string( ENC_CFG_PREFIX ENC_PWT, NULL,
493                 ENC_PWT_TEXT, ENC_PWT_TEXT, true )
494     change_string_list( enc_perceptual_weighting_list, enc_perceptual_weighting_list )
495 
496     /* advanced option only */
497     add_float( ENC_CFG_PREFIX ENC_PDIST, -1,
498                ENC_PDIST_TEXT, ENC_PDIST_LONGTEXT, true )
499     change_float_range(-1., 100.);
500 
501     /* advanced option only */
502     add_integer( ENC_CFG_PREFIX ENC_NOAC, -1,
503               ENC_NOAC_TEXT, ENC_NOAC_LONGTEXT, true )
504     change_integer_range(-1, 1 );
505 
506     /* advanced option only */
507     add_integer( ENC_CFG_PREFIX ENC_HSLICES, -1,
508                  ENC_HSLICES_TEXT, ENC_HSLICES_LONGTEXT, true )
509     change_integer_range(-1, INT_MAX );
510 
511     /* advanced option only */
512     add_integer( ENC_CFG_PREFIX ENC_VSLICES, -1,
513                  ENC_VSLICES_TEXT, ENC_VSLICES_LONGTEXT, true )
514     change_integer_range(-1, INT_MAX );
515 
516     /* advanced option only */
517     add_string( ENC_CFG_PREFIX ENC_FORCE_PROFILE, NULL,
518                 ENC_FORCE_PROFILE_TEXT, ENC_FORCE_PROFILE_TEXT, true )
519     change_string_list( enc_profile_list, enc_profile_list_text )
520 
521 vlc_module_end ()
522 
523 
524 /*****************************************************************************
525  * Local prototypes
526  *****************************************************************************/
527 static int DecodeBlock  ( decoder_t *p_dec, block_t *p_block );
528 static void Flush( decoder_t * );
529 
530 struct picture_free_t
531 {
532    picture_t *p_pic;
533    decoder_t *p_dec;
534 };
535 
536 /*****************************************************************************
537  * decoder_sys_t : Schroedinger decoder descriptor
538  *****************************************************************************/
539 struct decoder_sys_t
540 {
541     /*
542      * Dirac properties
543      */
544     mtime_t i_lastpts;
545     mtime_t i_frame_pts_delta;
546     SchroDecoder *p_schro;
547     SchroVideoFormat *p_format;
548 };
549 
550 /*****************************************************************************
551  * OpenDecoder: probe the decoder and return score
552  *****************************************************************************/
OpenDecoder(vlc_object_t * p_this)553 static int OpenDecoder( vlc_object_t *p_this )
554 {
555     decoder_t *p_dec = (decoder_t*)p_this;
556     decoder_sys_t *p_sys;
557     SchroDecoder *p_schro;
558 
559     if( p_dec->fmt_in.i_codec != VLC_CODEC_DIRAC )
560     {
561         return VLC_EGENERIC;
562     }
563 
564     /* Allocate the memory needed to store the decoder's structure */
565     p_sys = malloc(sizeof(decoder_sys_t));
566     if( p_sys == NULL )
567         return VLC_ENOMEM;
568 
569     /* Initialise the schroedinger (and hence liboil libraries */
570     /* This does no allocation and is safe to call */
571     schro_init();
572 
573     /* Initialise the schroedinger decoder */
574     if( !(p_schro = schro_decoder_new()) )
575     {
576         free( p_sys );
577         return VLC_EGENERIC;
578     }
579 
580     p_dec->p_sys = p_sys;
581     p_sys->p_schro = p_schro;
582     p_sys->p_format = NULL;
583     p_sys->i_lastpts = VLC_TS_INVALID;
584     p_sys->i_frame_pts_delta = 0;
585 
586     /* Set output properties */
587     p_dec->fmt_out.i_codec = VLC_CODEC_I420;
588 
589     /* Set callbacks */
590     p_dec->pf_decode = DecodeBlock;
591     p_dec->pf_flush  = Flush;
592 
593     return VLC_SUCCESS;
594 }
595 
596 /*****************************************************************************
597  * SetPictureFormat: Set the decoded picture params to the ones from the stream
598  *****************************************************************************/
SetVideoFormat(decoder_t * p_dec)599 static void SetVideoFormat( decoder_t *p_dec )
600 {
601     decoder_sys_t *p_sys = p_dec->p_sys;
602 
603     p_sys->p_format = schro_decoder_get_video_format(p_sys->p_schro);
604     if( p_sys->p_format == NULL ) return;
605 
606     p_sys->i_frame_pts_delta = CLOCK_FREQ
607                             * p_sys->p_format->frame_rate_denominator
608                             / p_sys->p_format->frame_rate_numerator;
609 
610     switch( p_sys->p_format->chroma_format )
611     {
612     case SCHRO_CHROMA_420: p_dec->fmt_out.i_codec = VLC_CODEC_I420; break;
613     case SCHRO_CHROMA_422: p_dec->fmt_out.i_codec = VLC_CODEC_I422; break;
614     case SCHRO_CHROMA_444: p_dec->fmt_out.i_codec = VLC_CODEC_I444; break;
615     default:
616         p_dec->fmt_out.i_codec = 0;
617         break;
618     }
619 
620     p_dec->fmt_out.video.i_visible_width = p_sys->p_format->clean_width;
621     p_dec->fmt_out.video.i_x_offset = p_sys->p_format->left_offset;
622     p_dec->fmt_out.video.i_width = p_sys->p_format->width;
623 
624     p_dec->fmt_out.video.i_visible_height = p_sys->p_format->clean_height;
625     p_dec->fmt_out.video.i_y_offset = p_sys->p_format->top_offset;
626     p_dec->fmt_out.video.i_height = p_sys->p_format->height;
627 
628     /* aspect_ratio_[numerator|denominator] describes the pixel aspect ratio */
629     p_dec->fmt_out.video.i_sar_num = p_sys->p_format->aspect_ratio_numerator;
630     p_dec->fmt_out.video.i_sar_den = p_sys->p_format->aspect_ratio_denominator;
631 
632     p_dec->fmt_out.video.i_frame_rate =
633         p_sys->p_format->frame_rate_numerator;
634     p_dec->fmt_out.video.i_frame_rate_base =
635         p_sys->p_format->frame_rate_denominator;
636 }
637 
638 /*****************************************************************************
639  * SchroFrameFree: schro_frame callback to release the associated picture_t
640  * When schro_decoder_reset() is called there will be pictures in the
641  * decoding pipeline that need to be released rather than displayed.
642  *****************************************************************************/
SchroFrameFree(SchroFrame * frame,void * priv)643 static void SchroFrameFree( SchroFrame *frame, void *priv)
644 {
645     struct picture_free_t *p_free = priv;
646 
647     if( !p_free )
648         return;
649 
650     picture_Release( p_free->p_pic );
651     free(p_free);
652     (void)frame;
653 }
654 
655 /*****************************************************************************
656  * CreateSchroFrameFromPic: wrap a picture_t in a SchroFrame
657  *****************************************************************************/
CreateSchroFrameFromPic(decoder_t * p_dec)658 static SchroFrame *CreateSchroFrameFromPic( decoder_t *p_dec )
659 {
660     decoder_sys_t *p_sys = p_dec->p_sys;
661     SchroFrame *p_schroframe = schro_frame_new();
662     picture_t *p_pic = NULL;
663     struct picture_free_t *p_free;
664 
665     if( !p_schroframe )
666         return NULL;
667 
668     if( decoder_UpdateVideoFormat( p_dec ) )
669         return NULL;
670     p_pic = decoder_NewPicture( p_dec );
671 
672     if( !p_pic )
673         return NULL;
674 
675     p_schroframe->format = SCHRO_FRAME_FORMAT_U8_420;
676     if( p_sys->p_format->chroma_format == SCHRO_CHROMA_422 )
677     {
678         p_schroframe->format = SCHRO_FRAME_FORMAT_U8_422;
679     }
680     else if( p_sys->p_format->chroma_format == SCHRO_CHROMA_444 )
681     {
682         p_schroframe->format = SCHRO_FRAME_FORMAT_U8_444;
683     }
684 
685     p_schroframe->width = p_sys->p_format->width;
686     p_schroframe->height = p_sys->p_format->height;
687 
688     p_free = malloc( sizeof( *p_free ) );
689     p_free->p_pic = p_pic;
690     p_free->p_dec = p_dec;
691     schro_frame_set_free_callback( p_schroframe, SchroFrameFree, p_free );
692 
693     for( int i=0; i<3; i++ )
694     {
695         p_schroframe->components[i].width = p_pic->p[i].i_visible_pitch;
696         p_schroframe->components[i].stride = p_pic->p[i].i_pitch;
697         p_schroframe->components[i].height = p_pic->p[i].i_visible_lines;
698         p_schroframe->components[i].length =
699             p_pic->p[i].i_pitch * p_pic->p[i].i_lines;
700         p_schroframe->components[i].data = p_pic->p[i].p_pixels;
701 
702         if(i!=0)
703         {
704             p_schroframe->components[i].v_shift =
705                 SCHRO_FRAME_FORMAT_V_SHIFT( p_schroframe->format );
706             p_schroframe->components[i].h_shift =
707                 SCHRO_FRAME_FORMAT_H_SHIFT( p_schroframe->format );
708         }
709     }
710 
711     p_pic->b_progressive = !p_sys->p_format->interlaced;
712     p_pic->b_top_field_first = p_sys->p_format->top_field_first;
713     p_pic->i_nb_fields = 2;
714 
715     return p_schroframe;
716 }
717 
718 /*****************************************************************************
719  * SchroBufferFree: schro_buffer callback to release the associated block_t
720  *****************************************************************************/
SchroBufferFree(SchroBuffer * buf,void * priv)721 static void SchroBufferFree( SchroBuffer *buf, void *priv )
722 {
723     block_t *p_block = priv;
724 
725     if( !p_block )
726         return;
727 
728     block_Release( p_block );
729     (void)buf;
730 }
731 
732 /*****************************************************************************
733  * CloseDecoder: decoder destruction
734  *****************************************************************************/
CloseDecoder(vlc_object_t * p_this)735 static void CloseDecoder( vlc_object_t *p_this )
736 {
737     decoder_t *p_dec = (decoder_t *)p_this;
738     decoder_sys_t *p_sys = p_dec->p_sys;
739 
740     schro_decoder_free( p_sys->p_schro );
741     free( p_sys );
742 }
743 
744 /*****************************************************************************
745  * Flush:
746  *****************************************************************************/
Flush(decoder_t * p_dec)747 static void Flush( decoder_t *p_dec )
748 {
749     decoder_sys_t *p_sys = p_dec->p_sys;
750 
751     schro_decoder_reset( p_sys->p_schro );
752     p_sys->i_lastpts = VLC_TS_INVALID;
753 }
754 
755 /****************************************************************************
756  * DecodeBlock: the whole thing
757  ****************************************************************************
758  * Blocks need not be Dirac dataunit aligned.
759  * If a block has a PTS signaled, it applies to the first picture at or after p_block
760  ****************************************************************************/
DecodeBlock(decoder_t * p_dec,block_t * p_block)761 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
762 {
763     decoder_sys_t *p_sys = p_dec->p_sys;
764 
765     if( !p_block ) /* No Drain */
766         return VLCDEC_SUCCESS;
767     else {
768 
769         /* reset the decoder when seeking as the decode in progress is invalid */
770         /* discard the block as it is just a null magic block */
771         if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
772         {
773             Flush( p_dec );
774             if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
775             {
776                 block_Release( p_block );
777                 return VLCDEC_SUCCESS;
778             }
779         }
780 
781         SchroBuffer *p_schrobuffer;
782         p_schrobuffer = schro_buffer_new_with_data( p_block->p_buffer, p_block->i_buffer );
783         p_schrobuffer->free = SchroBufferFree;
784         p_schrobuffer->priv = p_block;
785         if( p_block->i_pts > VLC_TS_INVALID ) {
786             mtime_t *p_pts = malloc( sizeof(*p_pts) );
787             if( p_pts ) {
788                 *p_pts = p_block->i_pts;
789                 /* if this call fails, p_pts is freed automatically */
790                 p_schrobuffer->tag = schro_tag_new( p_pts, free );
791             }
792         }
793 
794         /* this stops the same block being fed back into this function if
795          * we were on the next iteration of this loop to output a picture */
796         schro_decoder_autoparse_push( p_sys->p_schro, p_schrobuffer );
797         /* DO NOT refer to p_block after this point, it may have been freed */
798     }
799 
800     while( 1 )
801     {
802         SchroFrame *p_schroframe;
803         picture_t *p_pic;
804         int state = schro_decoder_autoparse_wait( p_sys->p_schro );
805 
806         switch( state )
807         {
808         case SCHRO_DECODER_FIRST_ACCESS_UNIT:
809             SetVideoFormat( p_dec );
810             break;
811 
812         case SCHRO_DECODER_NEED_BITS:
813             return VLCDEC_SUCCESS;
814 
815         case SCHRO_DECODER_NEED_FRAME:
816             p_schroframe = CreateSchroFrameFromPic( p_dec );
817 
818             if( !p_schroframe )
819             {
820                 msg_Err( p_dec, "Could not allocate picture for decoder");
821                 return VLCDEC_SUCCESS;
822             }
823 
824             schro_decoder_add_output_picture( p_sys->p_schro, p_schroframe);
825             break;
826 
827         case SCHRO_DECODER_OK: {
828             SchroTag *p_tag = schro_decoder_get_picture_tag( p_sys->p_schro );
829             p_schroframe = schro_decoder_pull( p_sys->p_schro );
830             if( !p_schroframe || !p_schroframe->priv )
831             {
832                 /* frame can't be one that was allocated by us
833                  *   -- no private data: discard */
834                 if( p_tag ) schro_tag_free( p_tag );
835                 if( p_schroframe ) schro_frame_unref( p_schroframe );
836                 break;
837             }
838             p_pic = ((struct picture_free_t*) p_schroframe->priv)->p_pic;
839             p_schroframe->priv = NULL;
840 
841             if( p_tag )
842             {
843                 /* free is handled by schro_frame_unref */
844                 p_pic->date = *(mtime_t*) p_tag->value;
845                 schro_tag_free( p_tag );
846             }
847             else if( p_sys->i_lastpts > VLC_TS_INVALID )
848             {
849                 /* NB, this shouldn't happen since the packetizer does a
850                  * very thorough job of inventing timestamps.  The
851                  * following is just a very rough fall back incase packetizer
852                  * is missing. */
853                 /* maybe it would be better to set p_pic->b_force ? */
854                 p_pic->date = p_sys->i_lastpts + p_sys->i_frame_pts_delta;
855             }
856             p_sys->i_lastpts = p_pic->date;
857 
858             schro_frame_unref( p_schroframe );
859             decoder_QueueVideo( p_dec, p_pic );
860             return VLCDEC_SUCCESS;
861         }
862         case SCHRO_DECODER_EOS:
863             /* NB, the new api will not emit _EOS, it handles the reset internally */
864             break;
865 
866         case SCHRO_DECODER_ERROR:
867             msg_Err( p_dec, "SCHRO_DECODER_ERROR");
868             return VLCDEC_SUCCESS;
869         }
870     }
871 }
872 
873 /*****************************************************************************
874  * Local prototypes
875  *****************************************************************************/
876 static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
877 
878 
879 /*****************************************************************************
880  * picture_pts_t : store pts alongside picture number, not carried through
881  * encoder
882  *****************************************************************************/
883 struct picture_pts_t
884 {
885    mtime_t i_pts;    /* associated pts */
886    uint32_t u_pnum;  /* dirac picture number */
887    bool b_empty;     /* entry is invalid */
888 };
889 
890 /*****************************************************************************
891  * encoder_sys_t : Schroedinger encoder descriptor
892  *****************************************************************************/
893 #define SCHRO_PTS_TLB_SIZE 256
894 struct encoder_sys_t
895 {
896     /*
897      * Schro properties
898      */
899     SchroEncoder *p_schro;
900     SchroVideoFormat *p_format;
901     int started;
902     bool b_auto_field_coding;
903 
904     uint32_t i_input_picnum;
905     block_fifo_t *p_dts_fifo;
906 
907     block_t *p_chain;
908 
909     struct picture_pts_t pts_tlb[SCHRO_PTS_TLB_SIZE];
910     mtime_t i_pts_offset;
911     mtime_t i_field_time;
912 
913     bool b_eos_signalled;
914     bool b_eos_pulled;
915 };
916 
917 static struct
918 {
919     unsigned int i_height;
920     int i_approx_fps;
921     SchroVideoFormatEnum i_vf;
922 } schro_format_guess[] = {
923     /* Important: Keep this list ordered in ascending picture height */
924     {1, 0, SCHRO_VIDEO_FORMAT_CUSTOM},
925     {120, 15, SCHRO_VIDEO_FORMAT_QSIF},
926     {144, 12, SCHRO_VIDEO_FORMAT_QCIF},
927     {240, 15, SCHRO_VIDEO_FORMAT_SIF},
928     {288, 12, SCHRO_VIDEO_FORMAT_CIF},
929     {480, 30, SCHRO_VIDEO_FORMAT_SD480I_60},
930     {480, 15, SCHRO_VIDEO_FORMAT_4SIF},
931     {576, 12, SCHRO_VIDEO_FORMAT_4CIF},
932     {576, 25, SCHRO_VIDEO_FORMAT_SD576I_50},
933     {720, 50, SCHRO_VIDEO_FORMAT_HD720P_50},
934     {720, 60, SCHRO_VIDEO_FORMAT_HD720P_60},
935     {1080, 24, SCHRO_VIDEO_FORMAT_DC2K_24},
936     {1080, 25, SCHRO_VIDEO_FORMAT_HD1080I_50},
937     {1080, 30, SCHRO_VIDEO_FORMAT_HD1080I_60},
938     {1080, 50, SCHRO_VIDEO_FORMAT_HD1080P_50},
939     {1080, 60, SCHRO_VIDEO_FORMAT_HD1080P_60},
940     {2160, 24, SCHRO_VIDEO_FORMAT_DC4K_24},
941     {0, 0, 0},
942 };
943 
944 /*****************************************************************************
945  * ResetPTStlb: Purge all entries in @p_enc@'s PTS-tlb
946  *****************************************************************************/
ResetPTStlb(encoder_t * p_enc)947 static void ResetPTStlb( encoder_t *p_enc )
948 {
949     encoder_sys_t *p_sys = p_enc->p_sys;
950     for( int i = 0; i < SCHRO_PTS_TLB_SIZE; i++ )
951     {
952         p_sys->pts_tlb[i].b_empty = true;
953     }
954 }
955 
956 
957 /*****************************************************************************
958  * StorePicturePTS: Store the PTS value for a particular picture number
959  *****************************************************************************/
StorePicturePTS(encoder_t * p_enc,uint32_t u_pnum,mtime_t i_pts)960 static void StorePicturePTS( encoder_t *p_enc, uint32_t u_pnum, mtime_t i_pts )
961 {
962     encoder_sys_t *p_sys = p_enc->p_sys;
963 
964     for( int i = 0; i<SCHRO_PTS_TLB_SIZE; i++ )
965     {
966         if( p_sys->pts_tlb[i].b_empty )
967         {
968             p_sys->pts_tlb[i].u_pnum = u_pnum;
969             p_sys->pts_tlb[i].i_pts = i_pts;
970             p_sys->pts_tlb[i].b_empty = false;
971 
972             return;
973         }
974     }
975 
976     msg_Err( p_enc, "Could not store PTS %"PRId64" for frame %u", i_pts, u_pnum );
977 }
978 
979 /*****************************************************************************
980  * GetPicturePTS: Retrieve the PTS value for a particular picture number
981  *****************************************************************************/
GetPicturePTS(encoder_t * p_enc,uint32_t u_pnum)982 static mtime_t GetPicturePTS( encoder_t *p_enc, uint32_t u_pnum )
983 {
984     encoder_sys_t *p_sys = p_enc->p_sys;
985 
986     for( int i = 0; i < SCHRO_PTS_TLB_SIZE; i++ )
987     {
988         if( !p_sys->pts_tlb[i].b_empty &&
989             p_sys->pts_tlb[i].u_pnum == u_pnum )
990         {
991              p_sys->pts_tlb[i].b_empty = true;
992              return p_sys->pts_tlb[i].i_pts;
993         }
994     }
995 
996     msg_Err( p_enc, "Could not retrieve PTS for picture %u", u_pnum );
997     return 0;
998 }
999 
SchroSetEnum(const encoder_t * p_enc,int i_list_size,const char * list[],const char * psz_name,const char * psz_name_text,const char * psz_value)1000 static inline bool SchroSetEnum( const encoder_t *p_enc, int i_list_size, const char *list[],
1001                   const char *psz_name,  const char *psz_name_text,  const char *psz_value)
1002 {
1003     encoder_sys_t *p_sys = p_enc->p_sys;
1004     if( list && psz_name_text && psz_name && psz_value ) {
1005         for( int i = 0; i < i_list_size; ++i ) {
1006             if( strcmp( list[i], psz_value ) )
1007                 continue;
1008             schro_encoder_setting_set_double( p_sys->p_schro, psz_name, i );
1009             return true;
1010         }
1011         msg_Err( p_enc, "Invalid %s: %s", psz_name_text, psz_value );
1012     }
1013     return false;
1014 }
1015 
SetEncChromaFormat(encoder_t * p_enc,uint32_t i_codec)1016 static bool SetEncChromaFormat( encoder_t *p_enc, uint32_t i_codec )
1017 {
1018     encoder_sys_t *p_sys = p_enc->p_sys;
1019 
1020     switch( i_codec ) {
1021     case VLC_CODEC_I420:
1022         p_enc->fmt_in.i_codec = i_codec;
1023         p_enc->fmt_in.video.i_bits_per_pixel = 12;
1024         p_sys->p_format->chroma_format = SCHRO_CHROMA_420;
1025            break;
1026     case VLC_CODEC_I422:
1027         p_enc->fmt_in.i_codec = i_codec;
1028         p_enc->fmt_in.video.i_bits_per_pixel = 16;
1029         p_sys->p_format->chroma_format = SCHRO_CHROMA_422;
1030         break;
1031     case VLC_CODEC_I444:
1032         p_enc->fmt_in.i_codec = i_codec;
1033         p_enc->fmt_in.video.i_bits_per_pixel = 24;
1034         p_sys->p_format->chroma_format = SCHRO_CHROMA_444;
1035         break;
1036     default:
1037         return false;
1038     }
1039 
1040     return true;
1041 }
1042 
1043 #define SCHRO_SET_FLOAT(psz_name, pschro_name) \
1044     f_tmp = var_GetFloat( p_enc, ENC_CFG_PREFIX psz_name ); \
1045     if( f_tmp >= 0.0 ) \
1046         schro_encoder_setting_set_double( p_sys->p_schro, pschro_name, f_tmp );
1047 
1048 #define SCHRO_SET_INTEGER(psz_name, pschro_name, ignore_val) \
1049     i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX psz_name ); \
1050     if( i_tmp > ignore_val ) \
1051         schro_encoder_setting_set_double( p_sys->p_schro, pschro_name, i_tmp );
1052 
1053 #define SCHRO_SET_ENUM(list, psz_name, psz_name_text, pschro_name) \
1054     psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX psz_name ); \
1055     if( !psz_tmp ) \
1056         goto error; \
1057     else if ( *psz_tmp != '\0' ) { \
1058         int i_list_size = ARRAY_SIZE(list); \
1059         if( !SchroSetEnum( p_enc, i_list_size, list, pschro_name, psz_name_text, psz_tmp ) ) { \
1060             free( psz_tmp ); \
1061             goto error; \
1062         } \
1063     } \
1064     free( psz_tmp );
1065 
1066 /*****************************************************************************
1067  * OpenEncoder: probe the encoder and return score
1068  *****************************************************************************/
OpenEncoder(vlc_object_t * p_this)1069 static int OpenEncoder( vlc_object_t *p_this )
1070 {
1071     encoder_t *p_enc = (encoder_t *)p_this;
1072     encoder_sys_t *p_sys;
1073     int i_tmp;
1074     float f_tmp;
1075     char *psz_tmp;
1076 
1077     if( p_enc->fmt_out.i_codec != VLC_CODEC_DIRAC &&
1078         !p_enc->obj.force )
1079     {
1080         return VLC_EGENERIC;
1081     }
1082 
1083     if( !p_enc->fmt_in.video.i_frame_rate || !p_enc->fmt_in.video.i_frame_rate_base ||
1084         !p_enc->fmt_in.video.i_visible_height || !p_enc->fmt_in.video.i_visible_width )
1085     {
1086         msg_Err( p_enc, "Framerate and picture dimensions must be non-zero" );
1087         return VLC_EGENERIC;
1088     }
1089 
1090     /* Allocate the memory needed to store the decoder's structure */
1091     if( ( p_sys = calloc( 1, sizeof( *p_sys ) ) ) == NULL )
1092         return VLC_ENOMEM;
1093 
1094     p_enc->p_sys = p_sys;
1095     p_enc->pf_encode_video = Encode;
1096     p_enc->fmt_out.i_codec = VLC_CODEC_DIRAC;
1097     p_enc->fmt_out.i_cat = VIDEO_ES;
1098 
1099     if( ( p_sys->p_dts_fifo = block_FifoNew() ) == NULL )
1100     {
1101         CloseEncoder( p_this );
1102         return VLC_ENOMEM;
1103     }
1104 
1105     ResetPTStlb( p_enc );
1106 
1107     /* guess the video format based upon number of lines and picture height */
1108     int i = 0;
1109     SchroVideoFormatEnum guessed_video_fmt = SCHRO_VIDEO_FORMAT_CUSTOM;
1110     /* Pick the dirac_video_format in this order of preference:
1111      *  1. an exact match in frame height and an approximate fps match
1112      *  2. the previous preset with a smaller number of lines.
1113      */
1114     do
1115     {
1116         if( schro_format_guess[i].i_height > p_enc->fmt_in.video.i_height )
1117         {
1118             guessed_video_fmt = schro_format_guess[i-1].i_vf;
1119             break;
1120         }
1121         if( schro_format_guess[i].i_height != p_enc->fmt_in.video.i_height )
1122             continue;
1123         int src_fps = p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base;
1124         int delta_fps = abs( schro_format_guess[i].i_approx_fps - src_fps );
1125         if( delta_fps > 2 )
1126             continue;
1127 
1128         guessed_video_fmt = schro_format_guess[i].i_vf;
1129         break;
1130     } while( schro_format_guess[++i].i_height );
1131 
1132     schro_init();
1133     p_sys->p_schro = schro_encoder_new();
1134     if( !p_sys->p_schro ) {
1135         msg_Err( p_enc, "Failed to initialize libschroedinger encoder" );
1136         return VLC_EGENERIC;
1137     }
1138     schro_encoder_set_packet_assembly( p_sys->p_schro, true );
1139 
1140     if( !( p_sys->p_format = schro_encoder_get_video_format( p_sys->p_schro ) ) ) {
1141         msg_Err( p_enc, "Failed to get Schroedigner video format" );
1142         schro_encoder_free( p_sys->p_schro );
1143         return VLC_EGENERIC;
1144     }
1145 
1146     /* initialise the video format parameters to the guessed format */
1147     schro_video_format_set_std_video_format( p_sys->p_format, guessed_video_fmt );
1148 
1149     /* constants set from the input video format */
1150     p_sys->p_format->width                  = p_enc->fmt_in.video.i_visible_width;
1151     p_sys->p_format->height                 = p_enc->fmt_in.video.i_visible_height;
1152     p_sys->p_format->frame_rate_numerator   = p_enc->fmt_in.video.i_frame_rate;
1153     p_sys->p_format->frame_rate_denominator = p_enc->fmt_in.video.i_frame_rate_base;
1154     unsigned u_asr_num, u_asr_den;
1155     vlc_ureduce( &u_asr_num, &u_asr_den,
1156                  p_enc->fmt_in.video.i_sar_num,
1157                  p_enc->fmt_in.video.i_sar_den, 0 );
1158     p_sys->p_format->aspect_ratio_numerator   = u_asr_num;
1159     p_sys->p_format->aspect_ratio_denominator = u_asr_den;
1160 
1161     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
1162 
1163     SCHRO_SET_ENUM(enc_rate_control_list, ENC_RATE_CONTROL, ENC_RATE_CONTROL_TEXT, "rate_control")
1164 
1165     SCHRO_SET_ENUM(enc_gop_structure_list, ENC_GOP_STRUCTURE, ENC_GOP_STRUCTURE_TEXT, "gop_structure")
1166 
1167     psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CHROMAFMT );
1168     if( !psz_tmp )
1169         goto error;
1170     else {
1171         uint32_t i_codec;
1172         if( !strcmp( psz_tmp, "420" ) ) {
1173             i_codec = VLC_CODEC_I420;
1174         }
1175         else if( !strcmp( psz_tmp, "422" ) ) {
1176             i_codec = VLC_CODEC_I422;
1177         }
1178         else if( !strcmp( psz_tmp, "444" ) ) {
1179             i_codec = VLC_CODEC_I444;
1180         }
1181         else {
1182             msg_Err( p_enc, "Invalid chroma format: %s", psz_tmp );
1183             free( psz_tmp );
1184             goto error;
1185         }
1186         SetEncChromaFormat( p_enc, i_codec );
1187     }
1188     free( psz_tmp );
1189 
1190     SCHRO_SET_FLOAT(ENC_QUALITY, "quality")
1191 
1192     SCHRO_SET_FLOAT(ENC_NOISE_THRESHOLD, "noise_threshold")
1193 
1194     /* use bitrate from sout-transcode-vb in kbps */
1195     i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_BITRATE );
1196     if( i_tmp > -1 )
1197         schro_encoder_setting_set_double( p_sys->p_schro, "bitrate", i_tmp * 1000 );
1198     else
1199         schro_encoder_setting_set_double( p_sys->p_schro, "bitrate", p_enc->fmt_out.i_bitrate );
1200 
1201        p_enc->fmt_out.i_bitrate = schro_encoder_setting_get_double( p_sys->p_schro, "bitrate" );
1202 
1203     i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MIN_BITRATE );
1204     if( i_tmp > -1 )
1205         schro_encoder_setting_set_double( p_sys->p_schro, "min_bitrate", i_tmp * 1000 );
1206 
1207     i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MAX_BITRATE );
1208     if( i_tmp > -1 )
1209         schro_encoder_setting_set_double( p_sys->p_schro, "max_bitrate", i_tmp * 1000 );
1210 
1211     SCHRO_SET_INTEGER(ENC_AU_DISTANCE, "au_distance", -1)
1212 
1213     SCHRO_SET_ENUM(enc_filtering_list, ENC_PREFILTER, ENC_PREFILTER_TEXT, "filtering")
1214 
1215     SCHRO_SET_FLOAT(ENC_PREFILTER_STRENGTH, "filter_value")
1216 
1217 
1218     psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CODINGMODE );
1219     if( !psz_tmp )
1220         goto error;
1221     else if( !strcmp( psz_tmp, "auto" ) ) {
1222         p_sys->b_auto_field_coding = true;
1223     }
1224     else if( !strcmp( psz_tmp, "progressive" ) ) {
1225         p_sys->b_auto_field_coding = false;
1226         schro_encoder_setting_set_double( p_sys->p_schro, "interlaced_coding", false);
1227     }
1228     else if( !strcmp( psz_tmp, "field" ) ) {
1229         p_sys->b_auto_field_coding = false;
1230         schro_encoder_setting_set_double( p_sys->p_schro, "interlaced_coding", true);
1231     }
1232     else {
1233         msg_Err( p_enc, "Invalid codingmode: %s", psz_tmp );
1234         free( psz_tmp );
1235         goto error;
1236     }
1237     free( psz_tmp );
1238 
1239     SCHRO_SET_ENUM(enc_block_size_list, ENC_MCBLK_SIZE, ENC_MCBLK_SIZE_TEXT, "motion_block_size")
1240 
1241     SCHRO_SET_ENUM(enc_block_overlap_list, ENC_MCBLK_OVERLAP, ENC_MCBLK_OVERLAP_TEXT, "motion_block_overlap")
1242 
1243     psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_MVPREC );
1244     if( !psz_tmp )
1245         goto error;
1246     else if( *psz_tmp != '\0') {
1247         if( !strcmp( psz_tmp, "1" ) ) {
1248             schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 0 );
1249         }
1250         else if( !strcmp( psz_tmp, "1/2" ) ) {
1251             schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 1 );
1252         }
1253         else if( !strcmp( psz_tmp, "1/4" ) ) {
1254             schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 2 );
1255         }
1256         else if( !strcmp( psz_tmp, "1/8" ) ) {
1257             schro_encoder_setting_set_double( p_sys->p_schro, "mv_precision", 3 );
1258         }
1259         else {
1260             msg_Err( p_enc, "Invalid mv_precision: %s", psz_tmp );
1261             free( psz_tmp );
1262             goto error;
1263         }
1264     }
1265     free( psz_tmp );
1266 
1267     SCHRO_SET_INTEGER(ENC_ME_COMBINED, "enable_chroma_me", -1)
1268 
1269     SCHRO_SET_ENUM(enc_wavelet_list, ENC_DWTINTRA, ENC_DWTINTRA_TEXT, "intra_wavelet")
1270 
1271     SCHRO_SET_ENUM(enc_wavelet_list, ENC_DWTINTER, ENC_DWTINTER_TEXT, "inter_wavelet")
1272 
1273     SCHRO_SET_INTEGER(ENC_DWTDEPTH, "transform_depth", -1)
1274 
1275     SCHRO_SET_INTEGER(ENC_MULTIQUANT, "enable_multiquant", -1)
1276 
1277     SCHRO_SET_INTEGER(ENC_NOAC, "enable_noarith", -1)
1278 
1279     SCHRO_SET_ENUM(enc_perceptual_weighting_list, ENC_PWT, ENC_PWT_TEXT, "perceptual_weighting")
1280 
1281     SCHRO_SET_FLOAT(ENC_PDIST, "perceptual_distance")
1282 
1283     SCHRO_SET_INTEGER(ENC_HSLICES, "horiz_slices", -1)
1284 
1285     SCHRO_SET_INTEGER(ENC_VSLICES, "vert_slices", -1)
1286 
1287     SCHRO_SET_ENUM(enc_codeblock_size_list, ENC_SCBLK_SIZE, ENC_SCBLK_SIZE_TEXT, "codeblock_size")
1288 
1289     SCHRO_SET_INTEGER(ENC_ME_HIERARCHICAL, "enable_hierarchical_estimation", -1)
1290 
1291     SCHRO_SET_INTEGER(ENC_ME_DOWNSAMPLE_LEVELS, "downsample_levels", 1)
1292 
1293     SCHRO_SET_INTEGER(ENC_ME_GLOBAL_MOTION, "enable_global_motion", -1)
1294 
1295     SCHRO_SET_INTEGER(ENC_ME_PHASECORR, "enable_phasecorr_estimation", -1)
1296 
1297     SCHRO_SET_INTEGER(ENC_SCD, "enable_scene_change_detection", -1)
1298 
1299     SCHRO_SET_ENUM(enc_profile_list, ENC_FORCE_PROFILE, ENC_FORCE_PROFILE_TEXT, "force_profile")
1300 
1301     p_sys->started = 0;
1302 
1303     return VLC_SUCCESS;
1304 error:
1305     CloseEncoder( p_this );
1306     return VLC_EGENERIC;
1307 }
1308 
1309 
1310 struct enc_picture_free_t
1311 {
1312    picture_t *p_pic;
1313    encoder_t *p_enc;
1314 };
1315 
1316 /*****************************************************************************
1317  * EncSchroFrameFree: schro_frame callback to release the associated picture_t
1318  * When schro_encoder_reset() is called there will be pictures in the
1319  * encoding pipeline that need to be released rather than displayed.
1320  *****************************************************************************/
EncSchroFrameFree(SchroFrame * frame,void * priv)1321 static void EncSchroFrameFree( SchroFrame *frame, void *priv )
1322 {
1323     struct enc_picture_free_t *p_free = priv;
1324 
1325     if( !p_free )
1326         return;
1327 
1328     picture_Release( p_free->p_pic );
1329     free( p_free );
1330     (void)frame;
1331 }
1332 
1333 /*****************************************************************************
1334  * CreateSchroFrameFromPic: wrap a picture_t in a SchroFrame
1335  *****************************************************************************/
CreateSchroFrameFromInputPic(encoder_t * p_enc,picture_t * p_pic)1336 static SchroFrame *CreateSchroFrameFromInputPic( encoder_t *p_enc,  picture_t *p_pic )
1337 {
1338     encoder_sys_t *p_sys = p_enc->p_sys;
1339     SchroFrame *p_schroframe = schro_frame_new();
1340     struct enc_picture_free_t *p_free;
1341 
1342     if( !p_schroframe )
1343         return NULL;
1344 
1345     if( !p_pic )
1346         return NULL;
1347 
1348     p_schroframe->format = SCHRO_FRAME_FORMAT_U8_420;
1349     if( p_sys->p_format->chroma_format == SCHRO_CHROMA_422 )
1350     {
1351         p_schroframe->format = SCHRO_FRAME_FORMAT_U8_422;
1352     }
1353     else if( p_sys->p_format->chroma_format == SCHRO_CHROMA_444 )
1354     {
1355         p_schroframe->format = SCHRO_FRAME_FORMAT_U8_444;
1356     }
1357 
1358     p_schroframe->width  = p_sys->p_format->width;
1359     p_schroframe->height = p_sys->p_format->height;
1360 
1361     p_free = malloc( sizeof( *p_free ) );
1362     if( unlikely( p_free == NULL ) ) {
1363         schro_frame_unref( p_schroframe );
1364         return NULL;
1365     }
1366 
1367     p_free->p_pic = p_pic;
1368     p_free->p_enc = p_enc;
1369     schro_frame_set_free_callback( p_schroframe, EncSchroFrameFree, p_free );
1370 
1371     for( int i=0; i<3; i++ )
1372     {
1373         p_schroframe->components[i].width  = p_pic->p[i].i_visible_pitch;
1374         p_schroframe->components[i].stride = p_pic->p[i].i_pitch;
1375         p_schroframe->components[i].height = p_pic->p[i].i_visible_lines;
1376         p_schroframe->components[i].length =
1377             p_pic->p[i].i_pitch * p_pic->p[i].i_lines;
1378         p_schroframe->components[i].data   = p_pic->p[i].p_pixels;
1379 
1380         if( i!=0 )
1381         {
1382             p_schroframe->components[i].v_shift =
1383                 SCHRO_FRAME_FORMAT_V_SHIFT( p_schroframe->format );
1384             p_schroframe->components[i].h_shift =
1385                 SCHRO_FRAME_FORMAT_H_SHIFT( p_schroframe->format );
1386         }
1387     }
1388 
1389     return p_schroframe;
1390 }
1391 
1392 /* Attempt to find dirac picture number in an encapsulation unit */
ReadDiracPictureNumber(uint32_t * p_picnum,block_t * p_block)1393 static int ReadDiracPictureNumber( uint32_t *p_picnum, block_t *p_block )
1394 {
1395     uint32_t u_pos = 4;
1396     /* protect against falling off the edge */
1397     while( u_pos + 13 < p_block->i_buffer )
1398     {
1399         /* find the picture startcode */
1400         if( p_block->p_buffer[u_pos] & 0x08 )
1401         {
1402             *p_picnum = GetDWBE( p_block->p_buffer + u_pos + 9 );
1403             return 1;
1404         }
1405         /* skip to the next dirac data unit */
1406         uint32_t u_npo = GetDWBE( p_block->p_buffer + u_pos + 1 );
1407         assert( u_npo <= UINT32_MAX - u_pos );
1408         if( u_npo == 0 )
1409             u_npo = 13;
1410         u_pos += u_npo;
1411     }
1412     return 0;
1413 }
1414 
1415 
Encode(encoder_t * p_enc,picture_t * p_pic)1416 static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
1417 {
1418     encoder_sys_t *p_sys = p_enc->p_sys;
1419     block_t *p_block, *p_output_chain = NULL;
1420     SchroFrame *p_frame;
1421     bool b_go = true;
1422 
1423     if( !p_pic ) {
1424         if( !p_sys->started || p_sys->b_eos_pulled )
1425             return NULL;
1426 
1427         if( !p_sys->b_eos_signalled ) {
1428             p_sys->b_eos_signalled = 1;
1429             schro_encoder_end_of_stream( p_sys->p_schro );
1430         }
1431     } else {
1432         /* we only know if the sequence is interlaced when the first
1433          * picture arrives, so final setup is done here */
1434         /* XXX todo, detect change of interlace */
1435         p_sys->p_format->interlaced = !p_pic->b_progressive;
1436         p_sys->p_format->top_field_first = p_pic->b_top_field_first;
1437 
1438         if( p_sys->b_auto_field_coding )
1439             schro_encoder_setting_set_double( p_sys->p_schro, "interlaced_coding", !p_pic->b_progressive );
1440     }
1441 
1442     if( !p_sys->started ) {
1443         date_t date;
1444 
1445         if( p_pic->format.i_chroma != p_enc->fmt_in.i_codec ) {
1446             char chroma_in[5], chroma_out[5];
1447             vlc_fourcc_to_char( p_pic->format.i_chroma, chroma_in );
1448             chroma_in[4]  = '\0';
1449             chroma_out[4] = '\0';
1450             vlc_fourcc_to_char( p_enc->fmt_in.i_codec, chroma_out );
1451             msg_Warn( p_enc, "Resetting chroma from %s to %s", chroma_out, chroma_in );
1452             if( !SetEncChromaFormat( p_enc, p_pic->format.i_chroma ) ) {
1453                 msg_Err( p_enc, "Could not reset chroma format to %s", chroma_in );
1454                 return NULL;
1455             }
1456         }
1457 
1458         date_Init( &date, p_enc->fmt_in.video.i_frame_rate, p_enc->fmt_in.video.i_frame_rate_base );
1459         /* FIXME - Unlike dirac-research codec Schro doesn't have a function that returns the delay in pics yet.
1460          *   Use a default of 1
1461          */
1462         date_Increment( &date, 1 );
1463         p_sys->i_pts_offset = date_Get( &date );
1464         if( schro_encoder_setting_get_double( p_sys->p_schro, "interlaced_coding" ) > 0.0 ) {
1465             date_Set( &date, 0 );
1466             date_Increment( &date, 1);
1467             p_sys->i_field_time = date_Get( &date ) / 2;
1468         }
1469 
1470         schro_video_format_set_std_signal_range( p_sys->p_format, SCHRO_SIGNAL_RANGE_8BIT_VIDEO );
1471         schro_encoder_set_video_format( p_sys->p_schro, p_sys->p_format );
1472         schro_encoder_start( p_sys->p_schro );
1473         p_sys->started = 1;
1474     }
1475 
1476     if( !p_sys->b_eos_signalled ) {
1477         /* create a schro frame from the input pic and load */
1478         /* Increase ref count by 1 so that the picture is not freed until
1479            Schro finishes with it */
1480         picture_Hold( p_pic );
1481 
1482         p_frame = CreateSchroFrameFromInputPic( p_enc, p_pic );
1483         if( !p_frame )
1484             return NULL;
1485         schro_encoder_push_frame( p_sys->p_schro, p_frame );
1486 
1487 
1488         /* store pts in a lookaside buffer, so that the same pts may
1489         * be used for the picture in coded order */
1490         StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date );
1491         p_sys->i_input_picnum++;
1492 
1493         /* store dts in a queue, so that they appear in order in
1494          * coded order */
1495         p_block = block_Alloc( 1 );
1496         if( !p_block )
1497             return NULL;
1498         p_block->i_dts = p_pic->date - p_sys->i_pts_offset;
1499         block_FifoPut( p_sys->p_dts_fifo, p_block );
1500         p_block = NULL;
1501 
1502         /* for field coding mode, insert an extra value into both the
1503          * pts lookaside buffer and dts queue, offset to correspond
1504          * to a one field delay. */
1505         if( schro_encoder_setting_get_double( p_sys->p_schro, "interlaced_coding" ) > 0.0 ) {
1506             StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date + p_sys->i_field_time );
1507             p_sys->i_input_picnum++;
1508 
1509             p_block = block_Alloc( 1 );
1510             if( !p_block )
1511                 return NULL;
1512             p_block->i_dts = p_pic->date - p_sys->i_pts_offset + p_sys->i_field_time;
1513             block_FifoPut( p_sys->p_dts_fifo, p_block );
1514             p_block = NULL;
1515         }
1516     }
1517 
1518     do
1519     {
1520         SchroStateEnum state;
1521         state = schro_encoder_wait( p_sys->p_schro );
1522         switch( state )
1523         {
1524         case SCHRO_STATE_NEED_FRAME:
1525             b_go = false;
1526             break;
1527         case SCHRO_STATE_AGAIN:
1528             break;
1529         case SCHRO_STATE_END_OF_STREAM:
1530             p_sys->b_eos_pulled = 1;
1531             b_go = false;
1532             break;
1533         case SCHRO_STATE_HAVE_BUFFER:
1534         {
1535             SchroBuffer *p_enc_buf;
1536             uint32_t u_pic_num;
1537             int i_presentation_frame;
1538             p_enc_buf = schro_encoder_pull( p_sys->p_schro, &i_presentation_frame );
1539             p_block = block_Alloc( p_enc_buf->length );
1540             if( !p_block )
1541                 return NULL;
1542 
1543             memcpy( p_block->p_buffer, p_enc_buf->data, p_enc_buf->length );
1544             schro_buffer_unref( p_enc_buf );
1545 
1546             /* Presence of a Sequence header indicates a seek point */
1547             if( 0 == p_block->p_buffer[4] )
1548             {
1549                 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
1550 
1551                 if( !p_enc->fmt_out.p_extra ) {
1552                     const uint8_t eos[] = { 'B','B','C','D',0x10,0,0,0,13,0,0,0,0 };
1553                     uint32_t len = GetDWBE( p_block->p_buffer + 5 );
1554                     /* if it hasn't been done so far, stash a copy of the
1555                      * sequence header for muxers such as ogg */
1556                     /* The OggDirac spec advises that a Dirac EOS DataUnit
1557                      * is appended to the sequence header to allow guard
1558                      * against poor streaming servers */
1559                     /* XXX, should this be done using the packetizer ? */
1560 
1561                     if( len > UINT32_MAX - sizeof( eos ) )
1562                         return NULL;
1563 
1564                     p_enc->fmt_out.p_extra = malloc( len + sizeof( eos ) );
1565                     if( !p_enc->fmt_out.p_extra )
1566                         return NULL;
1567                     memcpy( p_enc->fmt_out.p_extra, p_block->p_buffer, len );
1568                     memcpy( (uint8_t*)p_enc->fmt_out.p_extra + len, eos, sizeof( eos ) );
1569                     SetDWBE( (uint8_t*)p_enc->fmt_out.p_extra + len + sizeof(eos) - 4, len );
1570                     p_enc->fmt_out.i_extra = len + sizeof( eos );
1571                 }
1572             }
1573 
1574             if( ReadDiracPictureNumber( &u_pic_num, p_block ) ) {
1575                 block_t *p_dts_block = block_FifoGet( p_sys->p_dts_fifo );
1576                 p_block->i_dts = p_dts_block->i_dts;
1577                    p_block->i_pts = GetPicturePTS( p_enc, u_pic_num );
1578                 block_Release( p_dts_block );
1579                 block_ChainAppend( &p_output_chain, p_block );
1580             } else {
1581                 /* End of sequence */
1582                 block_ChainAppend( &p_output_chain, p_block );
1583             }
1584             break;
1585         }
1586         default:
1587             break;
1588         }
1589     } while( b_go );
1590 
1591     return p_output_chain;
1592 }
1593 
1594 /*****************************************************************************
1595  * CloseEncoder: Schro encoder destruction
1596  *****************************************************************************/
CloseEncoder(vlc_object_t * p_this)1597 static void CloseEncoder( vlc_object_t *p_this )
1598 {
1599     encoder_t *p_enc = (encoder_t *)p_this;
1600     encoder_sys_t *p_sys = p_enc->p_sys;
1601 
1602     /* Free the encoder resources */
1603     if( p_sys->p_schro )
1604         schro_encoder_free( p_sys->p_schro );
1605 
1606     free( p_sys->p_format );
1607 
1608     if( p_sys->p_dts_fifo )
1609         block_FifoRelease( p_sys->p_dts_fifo );
1610 
1611     block_ChainRelease( p_sys->p_chain );
1612 
1613     free( p_sys );
1614 }
1615