#include <core/consumer/frame_consumer.h>\r
#include <core/producer/frame_producer.h>\r
\r
+#include <tbb/mutex.h>\r
+\r
#if defined(_MSC_VER)\r
#pragma warning (disable : 4244)\r
#endif\r
}\r
\r
namespace caspar {\r
+ \r
+int ffmpeg_lock_callback(void **mutex, enum AVLockOp op) \r
+{ \r
+ static tbb::mutex container_mutex;\r
+ static std::vector<tbb::mutex> container; \r
+\r
+ if(!mutex)\r
+ return 0;\r
+\r
+ auto my_mutex = reinterpret_cast<tbb::mutex*>(*mutex);\r
+ \r
+ switch(op) \r
+ { \r
+ case AV_LOCK_CREATE: \r
+ { \r
+ tbb::mutex::scoped_lock lock(container_mutex);\r
+ container.push_back(tbb::mutex());\r
+ *mutex = &container.back(); \r
+ break; \r
+ } \r
+ case AV_LOCK_OBTAIN: \r
+ { \r
+ if(my_mutex)\r
+ my_mutex->lock(); \r
+ break; \r
+ } \r
+ case AV_LOCK_RELEASE: \r
+ { \r
+ if(my_mutex)\r
+ my_mutex->unlock(); \r
+ break; \r
+ } \r
+ case AV_LOCK_DESTROY: \r
+ { \r
+ tbb::mutex::scoped_lock lock(container_mutex);\r
+ container.erase(std::remove_if(container.begin(), container.end(), [&](const tbb::mutex& m)\r
+ {\r
+ return &m == my_mutex;\r
+ }), container.end());\r
+ break; \r
+ } \r
+ } \r
+ return 0; \r
+} \r
\r
void init_ffmpeg()\r
{\r
av_register_all();\r
avcodec_init();\r
+ av_lockmgr_register(ffmpeg_lock_callback);\r
\r
core::register_consumer_factory([](const std::vector<std::wstring>& params){return create_ffmpeg_consumer(params);});\r
core::register_producer_factory(create_ffmpeg_producer);\r
}\r
\r
+void uninit_ffmpeg()\r
+{\r
+ av_lockmgr_register(nullptr);\r
+}\r
+\r
std::wstring make_version(unsigned int ver)\r
{\r
std::wstringstream str;\r