Various work on poznan encoder interface.
authorCarl Hetherington <cth@carlh.net>
Sat, 2 May 2015 19:31:26 +0000 (20:31 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 21 Mar 2016 16:41:07 +0000 (16:41 +0000)
src/lib/jpeg2000_encoder.cc
src/lib/jpeg2000_encoder.h
src/lib/openjpeg_encoder.cc
src/lib/openjpeg_encoder.h
src/lib/poznan_encoder.cc
src/lib/poznan_encoder.h

index 9224f23708877d18f74ac5c0e55ec7571289881b..fd0780a38b95c5d2081671e75f1e7ff81c043153 100644 (file)
@@ -70,24 +70,17 @@ JPEG2000Encoder::from_id (string id)
 shared_ptr<EncodedData>
 JPEG2000Encoder::encode (shared_ptr<const dcp::XYZImage> input,        dcp::NoteHandler note, int bandwidth, int frame_rate, Resolution resolution, bool threed)
 {
-       if (!_last_bandwidth || _last_bandwidth.get() != bandwidth) {
-               _last_bandwidth = bandwidth;
-               set_bandwidth (bandwidth);
-       }
-
-       if (!_last_frame_rate || _last_frame_rate.get() != frame_rate) {
-               _last_frame_rate = frame_rate;
-               set_frame_rate (frame_rate);
-       }
-
-       if (!_last_resolution || _last_resolution.get() != resolution) {
-               _last_resolution = resolution;
-               set_frame_rate (resolution);
-       }
-       
-       if (!_last_threed || _last_threed.get() != threed) {
-               _last_threed = threed;
-               set_frame_rate (threed);
+       if (!_bandwidth || _bandwidth.get() != bandwidth ||
+           !_frame_rate || _frame_rate.get() != frame_rate ||
+           !_resolution || _resolution.get() != resolution ||
+           !_threed || _threed.get() != threed) {
+
+               _bandwidth = bandwidth;
+               _frame_rate = frame_rate;
+               _resolution = resolution;
+               _threed = threed;
+               
+               parameters_changed ();
        }
 
        return do_encode (input, note);
index f20422770eb827bc64a4dc38a47c95fabd5bd25e..a1e9a6669db494e896ffc6b8fb79c2e194fc545a 100644 (file)
@@ -67,16 +67,13 @@ protected:
                boost::shared_ptr<const dcp::XYZImage> input,
                dcp::NoteHandler note_handler
                ) = 0;
-       
-       virtual void set_bandwidth (int bandwidth) = 0;
-       virtual void set_frame_rate (int frame_rate) = 0;
-       virtual void set_resolution (Resolution resolution) = 0;
-       virtual void set_threed (bool threed) = 0;
-
-       boost::optional<int> _last_bandwidth;
-       boost::optional<int> _last_frame_rate;
-       boost::optional<Resolution> _last_resolution;
-       boost::optional<bool> _last_threed;
+
+       virtual void parameters_changed () {}
+
+       boost::optional<int> _bandwidth;
+       boost::optional<int> _frame_rate;
+       boost::optional<Resolution> _resolution;
+       boost::optional<bool> _threed;
 
        static std::vector<boost::shared_ptr<JPEG2000Encoder> > _encoders;
 };
index 545c6ad1888534da48c65686b66eea0b0b5ea0c2..89de687f06a5bad8749f944645b0aaedfcda9349 100644 (file)
@@ -38,8 +38,8 @@ shared_ptr<EncodedData>
 OpenJPEGEncoder::do_encode (shared_ptr<const dcp::XYZImage> input, dcp::NoteHandler note)
 {
        /* Set the max image and component sizes based on frame_rate */
-       int max_cs_len = ((float) _bandwidth) / 8 / _frame_rate;
-       if (_threed) {
+       int max_cs_len = ((float) _bandwidth.get()) / 8 / _frame_rate.get();
+       if (_threed.get()) {
                /* In 3D we have only half the normal bandwidth per eye */
                max_cs_len /= 2;
        }
@@ -90,8 +90,8 @@ OpenJPEGEncoder::do_encode (shared_ptr<const dcp::XYZImage> input, dcp::NoteHand
        parameters.tcp_rates[0] = 0;
        parameters.tcp_numlayers++;
        parameters.cp_disto_alloc = 1;
-       parameters.cp_rsiz = _resolution == RESOLUTION_2K ? CINEMA2K : CINEMA4K;
-       if (_resolution == RESOLUTION_4K) {
+       parameters.cp_rsiz = _resolution.get() == RESOLUTION_2K ? CINEMA2K : CINEMA4K;
+       if (_resolution.get() == RESOLUTION_4K) {
                parameters.numpocs = 2;
                parameters.POC[0].tile = 1;
                parameters.POC[0].resno0 = 0; 
@@ -110,7 +110,7 @@ OpenJPEGEncoder::do_encode (shared_ptr<const dcp::XYZImage> input, dcp::NoteHand
        }
        
        parameters.cp_comment = strdup (N_("DCP-o-matic"));
-       parameters.cp_cinema = _resolution == RESOLUTION_2K ? CINEMA2K_24 : CINEMA4K_24;
+       parameters.cp_cinema = _resolution.get() == RESOLUTION_2K ? CINEMA2K_24 : CINEMA4K_24;
 
        /* 3 components, so use MCT */
        parameters.tcp_mct = 1;
@@ -147,27 +147,3 @@ OpenJPEGEncoder::do_encode (shared_ptr<const dcp::XYZImage> input, dcp::NoteHand
        return enc;
 }
 
-
-void
-OpenJPEGEncoder::set_bandwidth (int bandwidth)
-{
-       _bandwidth = bandwidth;
-}
-
-void
-OpenJPEGEncoder::set_frame_rate (int frame_rate)
-{
-       _frame_rate = frame_rate;
-}
-
-void
-OpenJPEGEncoder::set_resolution (Resolution resolution)
-{
-       _resolution = resolution;
-}
-
-void
-OpenJPEGEncoder::set_threed (bool threed)
-{
-       _threed = threed;
-}
index 9de65b144a14165f6ad0aff5af0de308d10fa744..94206f056c96b6dcc0fd8294b44bf41994d2ed3f 100644 (file)
@@ -31,15 +31,4 @@ public:
 
 protected:
        boost::shared_ptr<EncodedData> do_encode (boost::shared_ptr<const dcp::XYZImage> input, dcp::NoteHandler note_handler);
-
-private:
-       void set_bandwidth (int bandwidth);
-       void set_threed (bool threed);
-       void set_resolution (Resolution resolution);
-       void set_frame_rate (int frame_rate);
-
-       int _bandwidth;
-       bool _threed;
-       Resolution _resolution;
-       int _frame_rate;
 };
index 2da97701c5f04bf1494b323a23c95f15d10a3c8f..17f5b6ac6dd05195bc68a994a4316cecf069ab09 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "poznan_encoder.h"
 #include "exceptions.h"
-#include "poznan/config/parameters.h"
 #include <dlfcn.h>
 
 #include "i18n.h"
@@ -29,84 +28,104 @@ using boost::shared_ptr;
 
 PoznanEncoder::PoznanEncoder ()
 {
-       /* XXX: need cross-platform implementation of dlopen etc. */
+       void* config = open_library ("config");
+       void* preprocessing = open_library ("preprocessing");
+       void* dwt = open_library ("dwt");
+       void* tier1 = open_library ("tier1");
+       void* tier2 = open_library ("tier2");
        
-       void* config = dlopen ("libdcpomatic-config.so", RTLD_LAZY | RTLD_GLOBAL);
-       if (!config) {
-               throw JPEG2000EncoderUnavailableException (name(), "could not find libdcpomatic-config.so");
-       }
-
-       void* misc = dlopen ("libdcpomatic-misc.so", RTLD_LAZY | RTLD_GLOBAL);
-       if (!misc) {
-               throw JPEG2000EncoderUnavailableException (name(), "could not find libdcpomatic-misc.so");
-       }
+       _init_device = (void (*)(type_parameters *)) dlsym (config, "init_device");
+       _mct = (void (*)(type_image *, type_parameters *)) dlsym (preprocessing, "mct");
+       _fwt = (void (*)(type_tile *)) dlsym (dwt, "fwt");
+       _quantize_tile = (void (*)(type_tile *)) dlsym (tier1, "quantize_tile");
+       _encode_tile = (void (*)(type_tile *)) dlsym (tier1, "encode_tile");
+       _write_codestream = (void (*)(type_image *)) dlsym (tier2, "write_codestream");
        
-       void (*init_device) (type_parameters *);
-       init_device = (void (*)(type_parameters *)) dlsym (config, "init_device");
-       if (!init_device) {
+       if (!_init_device || !_mct || !_fwt || !_quantize_tile || !_encode_tile || !_write_codestream) {
                throw JPEG2000EncoderUnavailableException (name(), "missing symbol");
        }
-               
-       type_parameters param;
 
-       /* One tile which covers entire image */
-       param.param_tile_w = -1;
-       param.param_tile_h = -1;
-
-       /* XXX */
-       /*
-       uint8_t param_tile_comp_dlvls;
-       uint8_t param_cblk_exp_w; ///Maximum codeblock size is 2^6 x 2^6 ( 64 x 64 ).
-       uint8_t param_cblk_exp_h; ///Maximum codeblock size is 2^6 x 2^6 ( 64 x 64 ).
-       uint8_t param_wavelet_type; ///Lossy encoding
-       uint8_t param_use_mct;//Multi-component transform
-       */
-       param.param_device = 0;
-       /*
-       uint32_t param_target_size;//Target size of output file
-       float param_bp;//Bits per pixel per component
-       uint8_t param_use_part2_mct; // Multiple component transform as in 15444-2
-       uint8_t param_mct_compression_method; // 0 klt 2 wavelet
-       uint32_t param_mct_klt_iterations; // max number of iterations of Gram-Schmidt algorithm
-       float param_mct_klt_border_eigenvalue; // cut-off for dumping components 
-       float param_mct_klt_err; // error sufficient for Gram-Schmit algorithm to end iteration
-       */
-       
-       init_device (&param);
+       setup_device ();
 }
 
-string
-PoznanEncoder::name () const
+void *
+PoznanEncoder::open_library (string library_name)
 {
-       return _("CUDA (GPU) encoder (Poznan Supercomputing and Networking Center)");
+       /* XXX: need cross-platform implementation of dlopen etc. */
+       
+       library_name = "libdcpomatic-" + library_name + ".so";
+       void* lib = dlopen (library_name.c_str(), RTLD_LAZY | RTLD_GLOBAL);
+       if (!lib) {
+               throw JPEG2000EncoderUnavailableException (name(), "could not find " + library_name);
+       }
+       return lib;
 }
 
 void
-PoznanEncoder::set_bandwidth (int bandwidth)
+PoznanEncoder::setup_device ()
 {
-       /* XXX */
-}
+       /* One tile which covers entire image */
+       _param.param_tile_w = -1;
+       _param.param_tile_h = -1;
 
-void
-PoznanEncoder::set_frame_rate (int frame_rate)
-{
-       /* XXX */
-}
+       /* Wavelet decomposition levels */
+       _param.param_tile_comp_dlvls = _resolution.get() == RESOLUTION_2K ? 5 : 6;
 
-void
-PoznanEncoder::set_resolution (Resolution resolution)
-{
-       /* XXX */
+       /* Power of 2 for maximum codeblock size */
+       _param.param_cblk_exp_w = 5;
+       _param.param_cblk_exp_h = 5;
+
+       /* DWT 9/7 transform */
+       _param.param_wavelet_type = 1;
+
+       /* Use MCT */
+       _param.param_use_mct = 1;
+
+       /* Device to run on */
+       _param.param_device = 0;
+
+       /* Target file size */
+       _param.param_target_size = (_bandwidth.get() / _frame_rate.get()) / 8;
+       if (_threed.get ()) {
+               _param.param_target_size /= 2;
+       }
+
+       /* Bits per pixel per component */
+       _param.param_bp = 12;
+
+       /* Don't know about these: use the defaults */
+       _param.param_use_part2_mct = 0;
+       _param.param_mct_compression_method = 0;
+       _param.param_mct_klt_iterations = 10000;
+       _param.param_mct_klt_border_eigenvalue = 0.000001;
+       _param.param_mct_klt_err = 1.0e-7;
+       
+       _init_device (&_param);
 }
 
-void
-PoznanEncoder::set_threed (bool threed)
+string
+PoznanEncoder::name () const
 {
-       /* XXX */
+       return _("CUDA (GPU) encoder (Poznan Supercomputing and Networking Center)");
 }
 
 shared_ptr<EncodedData>
 PoznanEncoder::do_encode (shared_ptr<const dcp::XYZImage> input, dcp::NoteHandler note_handler)
 {
+       type_image img;
+       _mct (&img, &_param);
+       for (size_t i = 0; i < img.num_tiles; ++i) {
+               type_tile* tile = &(img.tile[i]);
+               _fwt (tile);
+               _quantize_tile (tile);
+               _encode_tile (tile);
+       }
+       _write_codestream (&img);
        return shared_ptr<EncodedData> ();
 }
+
+void
+PoznanEncoder::parameters_changed ()
+{
+       setup_device ();
+}
index 3a29c71e0bf906439c9fb01fa141d5f2bdd2297b..4f2f0cc4d4e4da19d91edf9b8c1ada63f2256a5c 100644 (file)
@@ -18,6 +18,8 @@
 */
 
 #include "jpeg2000_encoder.h"
+#include <poznan/config/parameters.h>
+#include <poznan/types/image_types.h>
 #include <string>
 
 class PoznanEncoder : public JPEG2000Encoder
@@ -37,9 +39,19 @@ protected:
                boost::shared_ptr<const dcp::XYZImage> input,
                dcp::NoteHandler note_handler
                );
+
+       void parameters_changed ();
+       
+private:
+       void* open_library (std::string name);
+       void setup_device ();
+       
+       type_parameters _param;
        
-       void set_bandwidth (int bandwidth);
-       void set_frame_rate (int frame_rate);
-       void set_resolution (Resolution resolution);
-       void set_threed (bool threed);
+       void (*_init_device) (type_parameters *);
+       void (*_mct) (type_image *, type_parameters *);
+       void (*_fwt) (type_tile *);     
+       void (*_quantize_tile) (type_tile *);   
+       void (*_encode_tile) (type_tile *);     
+       void (*_write_codestream) (type_image *);
 };