]> git.sesse.net Git - casparcg/blobdiff - modules/ffmpeg/ffmpeg.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/trunk@2161...
[casparcg] / modules / ffmpeg / ffmpeg.cpp
index ad416eebdd6dbd6d243f9dec8b35ed4389cce796..c11babbd1c6371bbd610f83e96bab675268a9c14 100644 (file)
@@ -1,34 +1,40 @@
 /*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
 *\r
-*  This file is part of CasparCG.\r
+* This file is part of CasparCG (www.casparcg.com).\r
 *\r
-*    CasparCG is free software: you can redistribute it and/or modify\r
-*    it under the terms of the GNU General Public License as published by\r
-*    the Free Software Foundation, either version 3 of the License, or\r
-*    (at your option) any later version.\r
+* CasparCG is free software: you can redistribute it and/or modify\r
+* it under the terms of the GNU General Public License as published by\r
+* the Free Software Foundation, either version 3 of the License, or\r
+* (at your option) any later version.\r
 *\r
-*    CasparCG is distributed in the hope that it will be useful,\r
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-*    GNU General Public License for more details.\r
-\r
-*    You should have received a copy of the GNU General Public License\r
-*    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
+* CasparCG is distributed in the hope that it will be useful,\r
+* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+* GNU General Public License for more details.\r
+*\r
+* You should have received a copy of the GNU General Public License\r
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
 *\r
+* Author: Robert Nagy, ronag89@gmail.com\r
 */\r
+\r
 #include "StdAfx.h"\r
 \r
 #include "consumer/ffmpeg_consumer.h"\r
 #include "producer/ffmpeg_producer.h"\r
 \r
+#include <common/log/log.h>\r
+\r
 #include <core/consumer/frame_consumer.h>\r
 #include <core/producer/frame_producer.h>\r
 \r
-#include <tbb/mutex.h>\r
+#include <tbb/recursive_mutex.h>\r
 \r
 #if defined(_MSC_VER)\r
 #pragma warning (disable : 4244)\r
+#pragma warning (disable : 4603)\r
+#pragma warning (disable : 4996)\r
 #endif\r
 \r
 extern "C" \r
@@ -41,20 +47,20 @@ extern "C"
        #include <libavfilter/avfilter.h>\r
 }\r
 \r
-namespace caspar {\r
+namespace caspar { namespace ffmpeg {\r
        \r
 int ffmpeg_lock_callback(void **mutex, enum AVLockOp op) \r
 { \r
        if(!mutex)\r
                return 0;\r
 \r
-       auto my_mutex = reinterpret_cast<tbb::mutex*>(*mutex);\r
+       auto my_mutex = reinterpret_cast<tbb::recursive_mutex*>(*mutex);\r
        \r
        switch(op) \r
        { \r
                case AV_LOCK_CREATE: \r
                { \r
-                       *mutex = new tbb::mutex(); \r
+                       *mutex = new tbb::recursive_mutex(); \r
                        break; \r
                } \r
                case AV_LOCK_OBTAIN: \r
@@ -79,18 +85,136 @@ int ffmpeg_lock_callback(void **mutex, enum AVLockOp op)
        return 0; \r
 } \r
 \r
-void init_ffmpeg()\r
+static void sanitize(uint8_t *line)\r
+{\r
+    while(*line)\r
+       {\r
+        if(*line < 0x08 || (*line > 0x0D && *line < 0x20))\r
+            *line='?';\r
+        line++;\r
+    }\r
+}\r
+\r
+void log_callback(void* ptr, int level, const char* fmt, va_list vl)\r
+{\r
+    static int print_prefix=1;\r
+    static int count;\r
+    static char prev[1024];\r
+    char line[8192];\r
+    static int is_atty;\r
+    AVClass* avc= ptr ? *(AVClass**)ptr : NULL;\r
+    if(level > av_log_get_level())\r
+        return;\r
+    line[0]=0;\r
+       \r
+#undef fprintf\r
+    if(print_prefix && avc) \r
+       {\r
+        if (avc->parent_log_context_offset) \r
+               {\r
+            AVClass** parent= *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset);\r
+            if(parent && *parent)\r
+                std::sprintf(line, "[%s @ %p] ", (*parent)->item_name(parent), parent);            \r
+        }\r
+        std::sprintf(line + strlen(line), "[%s @ %p] ", avc->item_name(ptr), ptr);\r
+    }\r
+\r
+    std::vsprintf(line + strlen(line), fmt, vl);\r
+\r
+    print_prefix = strlen(line) && line[strlen(line)-1] == '\n';\r
+       \r
+    //if(print_prefix && !strcmp(line, prev)){\r
+    //    count++;\r
+    //    if(is_atty==1)\r
+    //        fprintf(stderr, "    Last message repeated %d times\r", count);\r
+    //    return;\r
+    //}\r
+    //if(count>0){\r
+    //    fprintf(stderr, "    Last message repeated %d times\n", count);\r
+    //    count=0;\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
+       else if(level == AV_LOG_INFO)\r
+               CASPAR_LOG(info) << L"[ffmpeg] " << line;\r
+       else if(level == AV_LOG_WARNING)\r
+               CASPAR_LOG(warning) << L"[ffmpeg] " << line;\r
+       else if(level == AV_LOG_ERROR)\r
+               CASPAR_LOG(error) << L"[ffmpeg] " << line;\r
+       else if(level == AV_LOG_FATAL)\r
+               CASPAR_LOG(fatal) << L"[ffmpeg] " << line;\r
+       else\r
+               CASPAR_LOG(trace) << L"[ffmpeg] " << line;\r
+\r
+    //colored_fputs(av_clip(level>>3, 0, 6), line);\r
+}\r
+\r
+//static int query_yadif_formats(AVFilterContext *ctx)\r
+//{\r
+//    static const int pix_fmts[] = {\r
+//        PIX_FMT_YUV444P,\r
+//        PIX_FMT_YUV422P,\r
+//        PIX_FMT_YUV420P,\r
+//        PIX_FMT_YUV410P,\r
+//        PIX_FMT_YUV411P,\r
+//        PIX_FMT_GRAY8,\r
+//        PIX_FMT_YUVJ444P,\r
+//        PIX_FMT_YUVJ422P,\r
+//        PIX_FMT_YUVJ420P,\r
+//        AV_NE( PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE ),\r
+//        PIX_FMT_YUV440P,\r
+//        PIX_FMT_YUVJ440P,\r
+//        AV_NE( PIX_FMT_YUV444P16BE, PIX_FMT_YUV444P16LE ),\r
+//        AV_NE( PIX_FMT_YUV422P16BE, PIX_FMT_YUV422P16LE ),\r
+//        AV_NE( PIX_FMT_YUV420P16BE, PIX_FMT_YUV420P16LE ),\r
+//        PIX_FMT_YUVA420P,\r
+//        PIX_FMT_NONE\r
+//    };\r
+//    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));\r
+//\r
+//    return 0;\r
+//}\r
+//\r
+//#pragma warning (push)\r
+//#pragma warning (disable : 4706)\r
+//void fix_yadif_filter_format_query()\r
+//{\r
+//     AVFilter** filter = nullptr;\r
+//    while((filter = av_filter_next(filter)) && *filter)\r
+//     {\r
+//             if(strstr((*filter)->name, "yadif") != 0)\r
+//                     (*filter)->query_formats = query_yadif_formats;\r
+//     }\r
+//}\r
+//#pragma warning (pop)\r
+\r
+void init()\r
 {\r
+       av_lockmgr_register(ffmpeg_lock_callback);\r
+       av_log_set_callback(log_callback);\r
+\r
+    avfilter_register_all();\r
+       //fix_yadif_filter_format_query();\r
        av_register_all();\r
+    avformat_network_init();\r
        avcodec_init();\r
-       av_lockmgr_register(ffmpeg_lock_callback);\r
+    avcodec_register_all();\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
+       core::register_consumer_factory([](const std::vector<std::wstring>& params){return create_consumer(params);});\r
+       core::register_producer_factory(create_producer);\r
 }\r
 \r
-void uninit_ffmpeg()\r
+void uninit()\r
 {\r
+       avfilter_uninit();\r
+    avformat_network_deinit();\r
        av_lockmgr_register(nullptr);\r
 }\r
 \r
@@ -126,4 +250,4 @@ std::wstring get_swscale_version()
        return make_version(swscale_version());\r
 }\r
 \r
-}
\ No newline at end of file
+}}
\ No newline at end of file