comparison Plugins/Engine/OrthancPlugins.cpp @ 3926:2910b0d30fe0 transcoding

Allow concurrent calls to the custom image decoders provided by the plugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 14 May 2020 07:37:44 +0200
parents dd112d2b83f0
children 4cdc875510d1
comparison
equal deleted inserted replaced
3925:dd112d2b83f0 3926:2910b0d30fe0
69 #include "../../OrthancServer/ServerContext.h" 69 #include "../../OrthancServer/ServerContext.h"
70 #include "../../OrthancServer/ServerToolbox.h" 70 #include "../../OrthancServer/ServerToolbox.h"
71 #include "PluginsEnumerations.h" 71 #include "PluginsEnumerations.h"
72 #include "PluginsJob.h" 72 #include "PluginsJob.h"
73 73
74 #include <boost/regex.hpp> 74 #include <boost/regex.hpp>
75 #include <dcmtk/dcmdata/dcdict.h> 75 #include <dcmtk/dcmdata/dcdict.h>
76 #include <dcmtk/dcmdata/dcdicent.h> 76 #include <dcmtk/dcmdata/dcdicent.h>
77 77
78 #define ERROR_MESSAGE_64BIT "A 64bit version of the Orthanc API is necessary" 78 #define ERROR_MESSAGE_64BIT "A 64bit version of the Orthanc API is necessary"
79
79 80
80 namespace Orthanc 81 namespace Orthanc
81 { 82 {
82 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target, 83 static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
83 const void* data, 84 const void* data,
916 boost::recursive_mutex restCallbackMutex_; 917 boost::recursive_mutex restCallbackMutex_;
917 boost::recursive_mutex storedCallbackMutex_; 918 boost::recursive_mutex storedCallbackMutex_;
918 boost::recursive_mutex changeCallbackMutex_; 919 boost::recursive_mutex changeCallbackMutex_;
919 boost::mutex findCallbackMutex_; 920 boost::mutex findCallbackMutex_;
920 boost::mutex worklistCallbackMutex_; 921 boost::mutex worklistCallbackMutex_;
921 boost::mutex decodeImageCallbackMutex_; 922 boost::shared_mutex decodeImageCallbackMutex_; // Changed from "boost::mutex" in Orthanc 1.7.0
922 boost::mutex jobsUnserializersMutex_; 923 boost::mutex jobsUnserializersMutex_;
923 boost::mutex refreshMetricsMutex_; 924 boost::mutex refreshMetricsMutex_;
924 boost::mutex storageCommitmentScpMutex_; 925 boost::mutex storageCommitmentScpMutex_;
925 boost::recursive_mutex invokeServiceMutex_; 926 boost::recursive_mutex invokeServiceMutex_;
926 927
2107 void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) 2108 void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters)
2108 { 2109 {
2109 const _OrthancPluginDecodeImageCallback& p = 2110 const _OrthancPluginDecodeImageCallback& p =
2110 *reinterpret_cast<const _OrthancPluginDecodeImageCallback*>(parameters); 2111 *reinterpret_cast<const _OrthancPluginDecodeImageCallback*>(parameters);
2111 2112
2112 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); 2113 boost::unique_lock<boost::shared_mutex> lock(pimpl_->decodeImageCallbackMutex_);
2113 2114
2114 pimpl_->decodeImageCallbacks_.push_back(p.callback); 2115 pimpl_->decodeImageCallbacks_.push_back(p.callback);
2115 LOG(INFO) << "Plugin has registered a callback to decode DICOM images (" 2116 LOG(INFO) << "Plugin has registered a callback to decode DICOM images ("
2116 << pimpl_->decodeImageCallbacks_.size() << " decoder(s) now active)"; 2117 << pimpl_->decodeImageCallbacks_.size() << " decoder(s) now active)";
2117 } 2118 }
2807 return; 2808 return;
2808 } 2809 }
2809 2810
2810 case _OrthancPluginService_GetInstanceDecodedFrame: 2811 case _OrthancPluginService_GetInstanceDecodedFrame:
2811 { 2812 {
2812 bool hasDecoderPlugin;
2813
2814 {
2815 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_);
2816 hasDecoderPlugin = !pimpl_->decodeImageCallbacks_.empty();
2817 }
2818
2819 std::unique_ptr<ImageAccessor> decoded; 2813 std::unique_ptr<ImageAccessor> decoded;
2820 if (p.targetImage == NULL) 2814 if (p.targetImage == NULL)
2821 { 2815 {
2822 throw OrthancException(ErrorCode_NullPointer); 2816 throw OrthancException(ErrorCode_NullPointer);
2823 } 2817 }
2824 else if (hasDecoderPlugin) 2818 else if (HasCustomImageDecoder())
2825 { 2819 {
2826 // TODO - This call could be speeded up the future, if a 2820 // TODO - This call could be speeded up the future, if a
2827 // "decoding context" gets introduced in the decoder plugins 2821 // "decoding context" gets introduced in the decoder plugins
2828 decoded.reset(Decode(instance.GetBufferData(), instance.GetBufferSize(), p.frameIndex)); 2822 decoded.reset(Decode(instance.GetBufferData(), instance.GetBufferSize(), p.frameIndex));
2829 } 2823 }
4824 } 4818 }
4825 4819
4826 4820
4827 bool OrthancPlugins::HasCustomImageDecoder() 4821 bool OrthancPlugins::HasCustomImageDecoder()
4828 { 4822 {
4829 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); 4823 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decodeImageCallbackMutex_);
4830 return !pimpl_->decodeImageCallbacks_.empty(); 4824 return !pimpl_->decodeImageCallbacks_.empty();
4831 } 4825 }
4832 4826
4833 4827
4834 ImageAccessor* OrthancPlugins::DecodeUnsafe(const void* dicom, 4828 ImageAccessor* OrthancPlugins::DecodeUnsafe(const void* dicom,
4835 size_t size, 4829 size_t size,
4836 unsigned int frame) 4830 unsigned int frame)
4837 { 4831 {
4838 boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); 4832 boost::shared_lock<boost::shared_mutex> lock(pimpl_->decodeImageCallbackMutex_);
4839 4833
4840 for (PImpl::DecodeImageCallbacks::const_iterator 4834 for (PImpl::DecodeImageCallbacks::const_iterator
4841 decoder = pimpl_->decodeImageCallbacks_.begin(); 4835 decoder = pimpl_->decodeImageCallbacks_.begin();
4842 decoder != pimpl_->decodeImageCallbacks_.end(); ++decoder) 4836 decoder != pimpl_->decodeImageCallbacks_.end(); ++decoder)
4843 { 4837 {