diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2020-09-17 15:10:13 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2020-09-17 15:11:58 +0200 |
commit | cd2198f0b60a01e7f40755efd8e4ab98e60d103c (patch) | |
tree | e37dbba1357f607efd771bb52976b1e1be3ff7c9 /src | |
parent | e36865985abf9c4f31d34a9542c790f5baf8fe60 (diff) | |
parent | 867ec108066adb47a4f86fc5241fff96a28708d9 (diff) | |
download | ODR-PadEnc-cd2198f0b60a01e7f40755efd8e4ab98e60d103c.tar.gz ODR-PadEnc-cd2198f0b60a01e7f40755efd8e4ab98e60d103c.tar.bz2 ODR-PadEnc-cd2198f0b60a01e7f40755efd8e4ab98e60d103c.zip |
Merge branch 'next' into padsocket
Diffstat (limited to 'src')
-rw-r--r-- | src/odr-padenc.cpp | 44 | ||||
-rw-r--r-- | src/odr-padenc.h | 2 | ||||
-rw-r--r-- | src/sls.cpp | 77 | ||||
-rw-r--r-- | src/sls.h | 6 |
4 files changed, 105 insertions, 24 deletions
diff --git a/src/odr-padenc.cpp b/src/odr-padenc.cpp index 41a1ea1..a22cba6 100644 --- a/src/odr-padenc.cpp +++ b/src/odr-padenc.cpp @@ -61,6 +61,8 @@ static void usage(const char* name) { " -s, --sleep=DUR Wait DUR seconds between each slide\n" " Default: %d\n" " -o, --output=IDENTIFIER Socket to communicate with audio encoder\n" + " --dump-current-slide=F1 Write the slide currently being transmitted to the file F1\n" + " --dump-completed-slide=F2 Once the slide is transmitted, move the file from F1 to F2\n" " -t, --dls=FILENAME FIFO or file to read DLS text from.\n" " If specified more than once, use next file after -l delay.\n" " -c, --charset=ID ID of the character set encoding used for DLS text input.\n" @@ -76,10 +78,11 @@ static void usage(const char* name) { " Default: %zu (Simple Profile)\n" " -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" + " Slides whose name ends in _PadEncRawMode.jpg or _PadEncRawMode.png are always transmitted unprocessed, regardless of\n" + " the -R option being set \n" " It is useful only when -d is used\n" " -v, --verbose Print more information to the console (may be used more than once)\n" - "\n" - "Parameters for uniform PAD encoder only:\n" + " --version Print version information and quit\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" @@ -111,6 +114,18 @@ static std::string list_dls_files(std::vector<std::string> dls_files) { int main(int argc, char *argv[]) { + // Version handling is done very early to ensure nothing else but the version gets printed out + if (argc == 2 and strcmp(argv[1], "--version") == 0) { + fprintf(stdout, "%s\n", +#if defined(GITVERSION) + GITVERSION +#else + PACKAGE_VERSION +#endif + ); + return 0; + } + header(); // get/check options @@ -133,6 +148,8 @@ int main(int argc, char *argv[]) { {"label-ins", required_argument, 0, 'L'}, {"xpad-interval", required_argument, 0, 'X'}, {"verbose", no_argument, 0, 'v'}, + {"dump-current-slide", required_argument, 0, 1}, + {"dump-completed-slide", required_argument, 0, 2}, {0,0,0,0}, }; @@ -184,6 +201,12 @@ int main(int argc, char *argv[]) { case 'v': verbose++; break; + case 1: // dump-current-slide + options.current_slide_dump_name = optarg; + break; + case 2: // dump-completed-slide + options.completed_slide_dump_name = optarg; + break; case '?': case 'h': usage(argv[0]); @@ -409,7 +432,7 @@ int PadEncoder::EncodeSlide(bool skip_if_already_queued) { if (!slides.Empty()) { slide_metadata_t slide = slides.GetSlide(); - if (sls_encoder.encodeSlide(slide.filepath, slide.fidx, options.raw_slides, options.max_slide_size)) { + if (sls_encoder.encodeSlide(slide.filepath, slide.fidx, options.raw_slides, options.max_slide_size, options.current_slide_dump_name)) { slides_success = true; if (options.erase_after_tx) { if (unlink(slide.filepath.c_str())) @@ -453,6 +476,21 @@ int PadEncoder::Encode(PadInterface& intf) { // handle SLS if (options.SLSEnabled()) { + + // Check if slide transmission is complete + if ( not options.completed_slide_dump_name.empty() and + not options.current_slide_dump_name.empty() and + not pad_packetizer.QueueContainsDG(SLSEncoder::APPTYPE_MOT_START)) { + if (rename(options.current_slide_dump_name.c_str(), options.completed_slide_dump_name.c_str())) { + if (errno != ENOENT) { + perror("ODR-PadEnc Error: renaming completed slide file failed"); + } + } + else { + fprintf(stderr, "ODR-PadEnc completed slide transmission.\n"); + } + } + if (options.slide_interval > 0) { // encode slides regularly if (pad_timeline >= next_slide) { diff --git a/src/odr-padenc.h b/src/odr-padenc.h index 85dd11b..56b48f8 100644 --- a/src/odr-padenc.h +++ b/src/odr-padenc.h @@ -65,6 +65,8 @@ struct PadEncoderOptions { std::string socket_ident; std::vector<std::string> dls_files; const char *item_state_file = nullptr; + std::string current_slide_dump_name; + std::string completed_slide_dump_name; bool DLSEnabled() const { return !dls_files.empty(); } bool SLSEnabled() const { return sls_dir; } diff --git a/src/sls.cpp b/src/sls.cpp index f19829f..f6cfb6f 100644 --- a/src/sls.cpp +++ b/src/sls.cpp @@ -353,8 +353,36 @@ size_t SLSEncoder::resizeImage(MagickWand* m_wand, unsigned char** blob, const s } #endif +static void dump_slide(const std::string& dump_name, const uint8_t *blob, size_t size) +{ + FILE* fd = fopen(dump_name.c_str(), "w"); + + if (fd == nullptr) { + perror(("ODR-PadEnc Error: Unable to open file '" + dump_name + "' for writing").c_str()); + return; + } + + if (fwrite(blob, size, 1, fd) == 0) { + perror(("ODR-PadEnc Error: Unable to write to file '" + dump_name + "'").c_str()); + } + + fclose(fd); +} + +static bool filename_specifies_raw_mode(const std::string& fname) +{ + const size_t sep = fname.rfind("_"); + if (sep != std::string::npos) { + std::string suffix = fname.substr(sep, std::string::npos); + std::transform(suffix.begin(), suffix.end(), suffix.begin(), ::tolower); + return suffix == "_padencrawmode.png" or suffix == "_padencrawmode.jpg"; + } + else { + return false; + } +} -bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides, size_t max_slide_size) +bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides, size_t max_slide_size, const std::string& dump_name) { bool result = false; @@ -362,11 +390,14 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides MagickWand *m_wand = NULL; #endif - uint8_t* blob = NULL; + uint8_t *raw_blob = NULL; + uint8_t *magick_blob = NULL; size_t blobsize; bool jfif_not_png = true; - if (!raw_slides) { + const bool raw_slide = filename_specifies_raw_mode(fname) or raw_slides; + + if (!raw_slide) { #if HAVE_MAGICKWAND /*! By default, we do resize the image to 320x240, with a quality such that * the blobsize is at most MAXSLIDESIZE. @@ -436,7 +467,7 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides if (native_support && height <= 240 && width <= 320 && not jpeg_progr) { // Don't recompress the image and check if the blobsize is suitable - blob = MagickGetImageBlob(m_wand, &blobsize); + magick_blob = MagickGetImageBlob(m_wand, &blobsize); if (blobsize <= max_slide_size) { if (verbose) { @@ -445,13 +476,13 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides } resize_required = false; } else { - MagickRelinquishMemory(blob); - blob = NULL; + MagickRelinquishMemory(magick_blob); + magick_blob = NULL; } } if (resize_required) { - blobsize = resizeImage(m_wand, &blob, fname, &jfif_not_png, max_slide_size); + blobsize = resizeImage(m_wand, &magick_blob, fname, &jfif_not_png, max_slide_size); } else { // warn if unresized image smaller than default dimension warnOnSmallerImage(height, width, fname); @@ -486,15 +517,15 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides } // allocate memory to contain the whole file: - blob = (uint8_t*) malloc(blobsize); - if (blob == NULL) { + raw_blob = (uint8_t*) malloc(blobsize); + if (raw_blob == NULL) { fprintf(stderr, "ODR-PadEnc Error: Memory allocation error\n"); fclose(pFile); goto encodefile_out; } // copy the file into the buffer: - if (fread(blob, blobsize, 1, pFile) != 1) { + if (fread(raw_blob, blobsize, 1, pFile) != 1) { fprintf(stderr, "ODR-PadEnc Error: Could not read file\n"); fclose(pFile); goto encodefile_out; @@ -522,6 +553,12 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides } if (blobsize) { + if (raw_blob == nullptr and magick_blob == nullptr) { + fprintf(stderr, "ODR-PadEnc logic error: either raw_blob or magick_blob must be non-null! See src/sls.cpp line %d\n", __LINE__); + abort(); + } + const uint8_t *blob = raw_blob ? raw_blob : magick_blob; + MSCDG msc; DATA_GROUP* dgli; DATA_GROUP* mscdg; @@ -546,7 +583,7 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides // MOT Body for (size_t i = 0; i < nseg; i++) { - unsigned char *curseg = blob + i * MAXSEGLEN; + const uint8_t *curseg = blob + i * MAXSEGLEN; size_t curseglen; int last; @@ -566,18 +603,22 @@ bool SLSEncoder::encodeSlide(const std::string& fname, int fidx, bool raw_slides pad_packetizer->AddDG(mscdg, false); } + if (not dump_name.empty()) { + dump_slide(dump_name, blob, blobsize); + } + result = true; } encodefile_out: - if (blob) { - if(raw_slides) { - free(blob); - } else { + if (raw_blob) { + free(raw_blob); + } + + if (magick_blob) { #if HAVE_MAGICKWAND - MagickRelinquishMemory(blob); + MagickRelinquishMemory(magick_blob); #endif - } } #if HAVE_MAGICKWAND @@ -711,7 +752,7 @@ uint8_vector_t SLSEncoder::createMotHeader(size_t blobsize, int fidx, bool jfif_ void SLSEncoder::createMscDG(MSCDG* msc, unsigned short int dgtype, int *cindex, unsigned short int segnum, unsigned short int lastseg, - unsigned short int tid, unsigned char* data, + unsigned short int tid, const uint8_t* data, unsigned short int datalen) { msc->extflag = 0; @@ -73,7 +73,7 @@ struct MSCDG { unsigned char rcount; // 3 bits unsigned short int seglen; // 13 bits // Mot segment - unsigned char* segdata; + const uint8_t* segdata; // MSC data group CRC unsigned short int crc; // 16 bits }; @@ -237,7 +237,7 @@ private: uint8_vector_t createMotHeader(size_t blobsize, int fidx, bool jfif_not_png, const std::string ¶ms_fname); void createMscDG(MSCDG* msc, unsigned short int dgtype, int *cindex, unsigned short int segnum, unsigned short int lastseg, - unsigned short int tid, unsigned char* data, + unsigned short int tid, const uint8_t* data, unsigned short int datalen); DATA_GROUP* packMscDG(MSCDG* msc); @@ -252,7 +252,7 @@ public: SLSEncoder(PADPacketizer* pad_packetizer) : pad_packetizer(pad_packetizer), cindex_header(0), cindex_body(0) {} - bool encodeSlide(const std::string& fname, int fidx, bool raw_slides, size_t max_slide_size); + bool encodeSlide(const std::string& fname, int fidx, bool raw_slides, size_t max_slide_size, const std::string& dump_name); static bool isSlideParamFileFilename(const std::string& filename); }; |