/*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
+* Copyright 2013 Sveriges Television AB http://casparcg.com/\r
*\r
* This file is part of CasparCG (www.casparcg.com).\r
*\r
#include "StdAfx.h"\r
\r
#include "consumer/ffmpeg_consumer.h"\r
+#include "consumer/streaming_consumer.h"\r
#include "producer/ffmpeg_producer.h"\r
+#include "producer/util/util.h"\r
\r
#include <common/log/log.h>\r
+#include <common/exception/win32_exception.h>\r
\r
+#include <core/parameters/parameters.h>\r
#include <core/consumer/frame_consumer.h>\r
#include <core/producer/frame_producer.h>\r
+#include <core/producer/media_info/media_info.h>\r
+#include <core/producer/media_info/media_info_repository.h>\r
\r
#include <tbb/recursive_mutex.h>\r
\r
+#include <boost/thread.hpp>\r
+\r
#if defined(_MSC_VER)\r
#pragma warning (disable : 4244)\r
#pragma warning (disable : 4603)\r
#include <libswscale/swscale.h>\r
#include <libavutil/avutil.h>\r
#include <libavfilter/avfilter.h>\r
+ #include <libavdevice/avdevice.h>\r
}\r
\r
namespace caspar { namespace ffmpeg {\r
\r
int ffmpeg_lock_callback(void **mutex, enum AVLockOp op) \r
{ \r
+ win32_exception::ensure_handler_installed_for_thread("ffmpeg-thread");\r
if(!mutex)\r
return 0;\r
\r
//}\r
strcpy(prev, line);\r
sanitize((uint8_t*)line);\r
+\r
+ int len = strlen(line);\r
+ if(len > 0)\r
+ line[len-1] = 0;\r
\r
if(level == AV_LOG_DEBUG)\r
CASPAR_LOG(debug) << L"[ffmpeg] " << line;\r
//colored_fputs(av_clip(level>>3, 0, 6), line);\r
}\r
\r
+boost::thread_specific_ptr<bool>& get_disable_logging_for_thread()\r
+{\r
+ static boost::thread_specific_ptr<bool> disable_logging_for_thread;\r
+\r
+ return disable_logging_for_thread;\r
+}\r
+\r
+void disable_logging_for_thread()\r
+{\r
+ if (get_disable_logging_for_thread().get() == nullptr)\r
+ get_disable_logging_for_thread().reset(new bool); // bool value does not matter\r
+}\r
+\r
+bool is_logging_already_disabled_for_thread()\r
+{\r
+ return get_disable_logging_for_thread().get() != nullptr;\r
+}\r
+\r
+std::shared_ptr<void> temporary_disable_logging_for_thread(bool disable)\r
+{\r
+ if (!disable || is_logging_already_disabled_for_thread())\r
+ return std::shared_ptr<void>();\r
+\r
+ disable_logging_for_thread();\r
+\r
+ return std::shared_ptr<void>(nullptr, [] (void*)\r
+ {\r
+ get_disable_logging_for_thread().release(); // Only works correctly if destructed in same thread as original caller.\r
+ });\r
+}\r
+\r
+void log_for_thread(void* ptr, int level, const char* fmt, va_list vl)\r
+{\r
+ win32_exception::ensure_handler_installed_for_thread("ffmpeg-thread");\r
+ if (get_disable_logging_for_thread().get() == nullptr) // It does not matter what the value of the bool is\r
+ log_callback(ptr, level, fmt, vl);\r
+}\r
+\r
//static int query_yadif_formats(AVFilterContext *ctx)\r
//{\r
// static const int pix_fmts[] = {\r
//}\r
//#pragma warning (pop)\r
\r
-void init()\r
+void init(const safe_ptr<core::media_info_repository>& media_info_repo)\r
{\r
+ av_lockmgr_register(ffmpeg_lock_callback);\r
+ av_log_set_callback(log_for_thread);\r
+ \r
+ avcodec_register_all(); \r
+ avdevice_register_all();\r
avfilter_register_all();\r
- //fix_yadif_filter_format_query();\r
- av_register_all();
+ av_register_all();\r
avformat_network_init();\r
- avcodec_init();\r
- avcodec_register_all();\r
- av_lockmgr_register(ffmpeg_lock_callback);\r
- av_log_set_callback(log_callback);\r
\r
- core::register_consumer_factory([](const std::vector<std::wstring>& params){return create_consumer(params);});\r
+ core::register_consumer_factory([](const core::parameters& params){return ffmpeg::create_consumer(params);});\r
+ core::register_consumer_factory([](const core::parameters& params){return ffmpeg::create_streaming_consumer(params);});\r
core::register_producer_factory(create_producer);\r
+ core::register_thumbnail_producer_factory(create_thumbnail_producer);\r
+\r
+ media_info_repo->register_extractor(\r
+ [](const std::wstring& file, core::media_info& info) -> bool\r
+ {\r
+ auto disable_logging = temporary_disable_logging_for_thread(true);\r
+\r
+ return is_valid_file(file) && try_get_duration(file, info.duration, info.time_base);\r
+ });\r
}\r
\r
void uninit()\r
{\r
- avfilter_uninit();
+ avfilter_uninit();\r
avformat_network_deinit();\r
av_lockmgr_register(nullptr);\r
}\r