diff options
Diffstat (limited to 'src/odr-padenc.cpp')
-rw-r--r-- | src/odr-padenc.cpp | 117 |
1 files changed, 111 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; +} |