changeset 3933:f67b48833a4f transcoding

new option "Throttling" to the GDCM plugin
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 15 May 2020 12:25:36 +0200
parents bf46e10de8ae
children 0b59e2706366
files Plugins/Samples/GdcmDecoder/Plugin.cpp
diffstat 1 files changed, 107 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Samples/GdcmDecoder/Plugin.cpp	Fri May 15 11:17:55 2020 +0200
+++ b/Plugins/Samples/GdcmDecoder/Plugin.cpp	Fri May 15 12:25:36 2020 +0200
@@ -21,6 +21,7 @@
 
 #include "../../../Core/Compatibility.h"
 #include "../../../Core/DicomFormat/DicomMap.h"
+#include "../../../Core/MultiThreading/Semaphore.h"
 #include "../../../Core/Toolbox.h"
 #include "GdcmDecoderCache.h"
 
@@ -34,7 +35,8 @@
 static OrthancPlugins::GdcmDecoderCache  cache_;
 static bool restrictTransferSyntaxes_ = false;
 static std::set<std::string> enabledTransferSyntaxes_;
-
+static bool hasThrottling_ = false;
+static std::unique_ptr<Orthanc::Semaphore> throttlingSemaphore_;
 
 static bool ExtractTransferSyntax(std::string& transferSyntax,
                                   const void* dicom,
@@ -111,6 +113,20 @@
 {
   try
   {
+    std::unique_ptr<Orthanc::Semaphore::Locker> locker;
+    
+    if (hasThrottling_)
+    {
+      if (throttlingSemaphore_.get() == NULL)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      }
+      else
+      {
+        locker.reset(new Orthanc::Semaphore::Locker(*throttlingSemaphore_));
+      }
+    }
+
     if (!IsTransferSyntaxEnabled(dicom, size))
     {
       *target = NULL;
@@ -166,6 +182,20 @@
 {
   try
   {
+    std::unique_ptr<Orthanc::Semaphore::Locker> locker;
+    
+    if (hasThrottling_)
+    {
+      if (throttlingSemaphore_.get() == NULL)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      }
+      else
+      {
+        locker.reset(new Orthanc::Semaphore::Locker(*throttlingSemaphore_));
+      }
+    }
+
     std::string dicom(reinterpret_cast<const char*>(buffer), size);
     std::stringstream stream(dicom);
 
@@ -297,66 +327,100 @@
   ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)
   {
     static const char* const KEY_GDCM = "Gdcm";
-    static const char* const KEY_ENABLE_GDCM = "EnableGdcm";
+    static const char* const KEY_ENABLE_GDCM = "Enable";
+    static const char* const KEY_THROTTLING = "Throttling";
     static const char* const KEY_RESTRICT_TRANSFER_SYNTAXES = "RestrictTransferSyntaxes";
 
-    OrthancPlugins::SetGlobalContext(context);
-    Orthanc::Logging::Initialize(context);
-    LOG(INFO) << "Initializing the decoder/transcoder of medical images using GDCM";
-
-    /* Check the version of the Orthanc core */
-    if (!OrthancPlugins::CheckMinimalOrthancVersion(0, 9, 5))
+    try
     {
-      LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion)
-                 << ") must be above 0.9.5 to run this plugin";
-      return -1;
-    }
+      OrthancPlugins::SetGlobalContext(context);
+      Orthanc::Logging::Initialize(context);
+      LOG(INFO) << "Initializing the decoder/transcoder of medical images using GDCM";
+
+      /* Check the version of the Orthanc core */
+      if (!OrthancPlugins::CheckMinimalOrthancVersion(0, 9, 5))
+      {
+        LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion)
+                   << ") must be above 0.9.5 to run this plugin";
+        return -1;
+      }
 
-    OrthancPluginSetDescription(context, "Decoder/transcoder of medical images using GDCM.");
+      OrthancPluginSetDescription(context, "Decoder/transcoder of medical images using GDCM.");
+
+      OrthancPlugins::OrthancConfiguration global;
 
-    OrthancPlugins::OrthancConfiguration global;
+      bool enabled = true;
+      hasThrottling_ = false;
+    
+      if (global.IsSection(KEY_GDCM))
+      {
+        OrthancPlugins::OrthancConfiguration config;
+        global.GetSection(config, KEY_GDCM);
+
+        enabled = config.GetBooleanValue(KEY_ENABLE_GDCM, true);
 
-    bool enabled = true;
-    
-    if (global.IsSection(KEY_GDCM))
-    {
-      OrthancPlugins::OrthancConfiguration config;
-      global.GetSection(config, KEY_GDCM);
-
-      enabled = config.GetBooleanValue(KEY_ENABLE_GDCM, true);
+        if (enabled &&
+            config.LookupSetOfStrings(enabledTransferSyntaxes_, KEY_RESTRICT_TRANSFER_SYNTAXES, false))
+        {
+          restrictTransferSyntaxes_ = true;
+        
+          for (std::set<std::string>::const_iterator it = enabledTransferSyntaxes_.begin();
+               it != enabledTransferSyntaxes_.end(); ++it)
+          {
+            LOG(WARNING) << "Orthanc will use GDCM to decode transfer syntax: " << *it;
+          }
+        }
 
-      if (config.LookupSetOfStrings(enabledTransferSyntaxes_, KEY_RESTRICT_TRANSFER_SYNTAXES, false))
-      {
-        restrictTransferSyntaxes_ = true;
-        
-        for (std::set<std::string>::const_iterator it = enabledTransferSyntaxes_.begin();
-             it != enabledTransferSyntaxes_.end(); ++it)
+        unsigned int throttling;
+        if (enabled &&
+            config.LookupUnsignedIntegerValue(throttling, KEY_THROTTLING))
         {
-          LOG(WARNING) << "Orthanc will use GDCM to decode transfer syntax: " << *it;
+          if (throttling == 0)
+          {
+            LOG(ERROR) << "Bad value for option \"" << KEY_THROTTLING
+                       << "\": Must be a strictly positive integer";
+            return -1;
+          }
+          else
+          {
+            LOG(WARNING) << "Throttling GDCM to " << throttling << " concurrent thread(s)";
+            hasThrottling_ = true;
+            throttlingSemaphore_.reset(new Orthanc::Semaphore(throttling));
+          }
         }
       }
-    }
+
+      if (enabled)
+      {
+        if (!hasThrottling_)
+        {
+          LOG(WARNING) << "GDCM throttling is disabled";
+        }
+
+        OrthancPluginRegisterDecodeImageCallback(context, DecodeImageCallback);
 
-    if (enabled)
-    {
-      OrthancPluginRegisterDecodeImageCallback(context, DecodeImageCallback);
-
-      if (OrthancPlugins::CheckMinimalOrthancVersion(1, 7, 0))
-      {
-        OrthancPluginRegisterTranscoderCallback(context, TranscoderCallback);
+        if (OrthancPlugins::CheckMinimalOrthancVersion(1, 7, 0))
+        {
+          OrthancPluginRegisterTranscoderCallback(context, TranscoderCallback);
+        }
+        else
+        {
+          LOG(WARNING) << "Your version of Orthanc (" << std::string(context->orthancVersion)
+                       << ") must be above 1.7.0 to benefit from transcoding";
+        }
       }
       else
       {
-        LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion)
-                   << ") must be above 1.7.0 to benefit from transcoding";
+        LOG(WARNING) << "The decoder/transcoder of medical images using GDCM is disabled";
       }
+    
+      return 0;
     }
-    else
+    catch (Orthanc::OrthancException& e)
     {
-      LOG(WARNING) << "The decoder/transcoder of medical images using GDCM is disabled";
+      LOG(ERROR) << "Exception while initializing the GDCM plugin: " << e.What();
+      return -1;
     }
-    
-    return 0;
   }