diff options
-rw-r--r-- | src/odr-padenc.cpp | 117 | ||||
-rw-r--r-- | src/odr-padenc.h | 22 |
2 files changed, 133 insertions, 6 deletions
diff --git a/src/odr-padenc.cpp b/src/odr-padenc.cpp index b656c02..319a037 100644 --- a/src/odr-padenc.cpp +++ b/src/odr-padenc.cpp @@ -64,7 +64,7 @@ static void usage(const char* name) { " -o, --output=FILENAME FIFO to write PAD data into.\n" " Default: %s\n" " -t, --dls=FILENAME FIFO or file to read DLS text from.\n" - " If specified more than once, use next file after slide switch.\n" + " If specified more than once, use next file after slide switch (for uniform PAD encoder, -l is used instead).\n" " -p, --pad=LENGTH Set the PAD length.\n" " Possible values: %s\n" " Default: %zu\n" @@ -79,11 +79,23 @@ static void usage(const char* name) { " -R, --raw-slides Do not process slides. Integrity checks and resizing\n" " slides is skipped. Use this if you know what you are doing !\n" " It is useful only when -d is used\n" - " -v, --verbose Print more information to the console\n", + " -v, --verbose Print more information to the console\n" + "\n" + "Parameters for uniform PAD encoder only:\n" + " -f, --frame-dur=DUR Enable the uniform PAD encoder and set the duration of one frame/AU in milliseconds.\n" + " -l, --label=DUR Wait DUR seconds between each label (if more than one file used)\n" + " Default: %d\n" + " -L, --label-ins=DUR Insert label every DUR milliseconds\n" + " Default: %d\n" + " -i, --init-burst=COUNT Sets a PAD burst amount to initially fill the output FIFO\n" + " Default: %d\n", options_default.slide_interval, options_default.output, PADPacketizer::ALLOWED_PADLEN.c_str(), - options_default.padlen + options_default.padlen, + options_default.label_interval, + options_default.label_insertion, + options_default.init_burst ); } @@ -117,12 +129,16 @@ int main(int argc, char *argv[]) { {"sleep", required_argument, 0, 's'}, {"raw-slides", no_argument, 0, 'R'}, {"help", no_argument, 0, 'h'}, + {"frame-dur", required_argument, 0, 'f'}, + {"label", required_argument, 0, 'l'}, + {"label-ins", required_argument, 0, 'L'}, + {"init-burst", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {0,0,0,0}, }; int ch; - while((ch = getopt_long(argc, argv, "eChRrc:d:o:p:s:t:v", longopts, NULL)) != -1) { + while((ch = getopt_long(argc, argv, "eChRrc:d:o:p:s:t:f:l:L:i:v", longopts, NULL)) != -1) { switch (ch) { case 'c': options.dl_params.charset = (DABCharset) atoi(optarg); @@ -154,6 +170,18 @@ int main(int argc, char *argv[]) { case 'R': options.raw_slides = true; break; + case 'f': + options.frame_dur = atoi(optarg); + break; + case 'l': + options.label_interval = atoi(optarg); + break; + case 'L': + options.label_insertion = atoi(optarg); + break; + case 'i': + options.init_burst = atoi(optarg); + break; case 'v': verbose++; break; @@ -231,8 +259,18 @@ int main(int argc, char *argv[]) { } } - // invoke encoder - pad_encoder = new BurstPadEncoder(options); + + // TODO: check uniform PAD encoder options!? + + + // invoke selected encoder + if (options.frame_dur) { + fprintf(stderr, "ODR-PadEnc using uniform PAD encoder\n"); + pad_encoder = new UniformPadEncoder(options); + } else { + fprintf(stderr, "ODR-PadEnc using burst PAD encoder\n"); + pad_encoder = new BurstPadEncoder(options); + } int result = pad_encoder->Main(); delete pad_encoder; @@ -391,3 +429,70 @@ int BurstPadEncoder::Encode() { return 0; } + + +// --- UniformPadEncoder ----------------------------------------------------------------- +UniformPadEncoder::UniformPadEncoder(PadEncoderOptions options) : PadEncoder(options) { + // PAD related timelines + pad_timeline = steady_clock::now(); + next_slide = pad_timeline; + next_label = pad_timeline; + next_label_insertion = pad_timeline; + + // consider initial burst + run_timeline -= std::chrono::milliseconds(options.init_burst * options.frame_dur); + + // if multiple DLS files, ensure that initial increment leads to first one + if (options.dls_files.size() > 1) + curr_dls_file = -1; +} + +int UniformPadEncoder::Encode() { + int result = 0; + + // handle SLS + if (options.SLSEnabled()) { + if (options.slide_interval > 0) { + // encode slides regularly + if (pad_timeline >= next_slide) { + result = EncodeSlide(true); + next_slide += std::chrono::seconds(options.slide_interval); + } + } else { + // encode slide as soon as previous slide has been transmitted + if (!pad_packetizer.QueueContainsDG(SLSEncoder::APPTYPE_MOT_START)) + result = EncodeSlide(true); + } + } + if (result) + return result; + + // handle DLS + if (options.DLSEnabled()) { + if (options.dls_files.size() > 1 && pad_timeline >= next_label) { + // switch to next DLS file + curr_dls_file = (curr_dls_file + 1) % options.dls_files.size(); + next_label += std::chrono::seconds(options.label_interval); + + // enforce label insertion + next_label_insertion = pad_timeline; + } + + if (pad_timeline >= next_label_insertion) { + // encode label + result = EncodeLabel(true); + next_label_insertion += std::chrono::milliseconds(options.label_insertion); + } + } + if (result) + return result; + + // flush one PAD + pad_packetizer.WriteAllPADs(output_fd, 1, true); + pad_timeline += std::chrono::milliseconds(options.frame_dur); + + // schedule next run at next frame/AU + run_timeline += std::chrono::milliseconds(options.frame_dur); + + return 0; +} diff --git a/src/odr-padenc.h b/src/odr-padenc.h index 7bdb057..fe5d375 100644 --- a/src/odr-padenc.h +++ b/src/odr-padenc.h @@ -51,6 +51,10 @@ struct PadEncoderOptions { size_t padlen; bool erase_after_tx; int slide_interval; + int frame_dur; // uniform PAD encoder only + int label_interval; // uniform PAD encoder only + int label_insertion; // uniform PAD encoder only + int init_burst; // uniform PAD encoder only bool raw_slides; DL_PARAMS dl_params; @@ -62,6 +66,10 @@ struct PadEncoderOptions { padlen(58), erase_after_tx(false), slide_interval(10), + frame_dur(0), + label_interval(12), + label_insertion(1200), + init_burst(12), raw_slides(false), sls_dir(NULL), output("/tmp/pad.fifo") @@ -118,3 +126,17 @@ private: public: BurstPadEncoder(PadEncoderOptions options) : PadEncoder(options) {} }; + + +// --- UniformPadEncoder ----------------------------------------------------------------- +class UniformPadEncoder : public PadEncoder { +private: + steady_clock::time_point pad_timeline; + steady_clock::time_point next_slide; + steady_clock::time_point next_label; + steady_clock::time_point next_label_insertion; + + int Encode(); +public: + UniformPadEncoder(PadEncoderOptions options); +}; |