]> git.sesse.net Git - casparcg/commitdiff
ffmpeg_consumer: Fixed options and changed syntex to more closely resemble ffmpeg.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 25 Jan 2012 18:57:40 +0000 (18:57 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 25 Jan 2012 18:57:40 +0000 (18:57 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/trunk@2163 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/ffmpeg/consumer/ffmpeg_consumer.cpp

index a21350b85b7f7ceb19978ab05a9b2c9f5d7f43ba..758f3c0d5d21a77b565b66dba4473454bffb3238 100644 (file)
@@ -88,7 +88,7 @@ struct ffmpeg_consumer : boost::noncopyable
        int64_t                                                                 frame_number_;\r
        \r
 public:\r
-       ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc, const std::string& codec, const std::string& options)\r
+       ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc, const std::string& codec, const std::vector<std::string>& options)\r
                : filename_(filename)\r
                , video_outbuf_(1920*1080*8)\r
                , oc_(avformat_alloc_context(), av_free)\r
@@ -159,7 +159,7 @@ public:
                return L"ffmpeg[" + widen(filename_) + L"]";\r
        }\r
 \r
-       std::shared_ptr<AVStream> add_video_stream(enum CodecID codec_id, const std::string& options)\r
+       std::shared_ptr<AVStream> add_video_stream(enum CodecID codec_id, const std::vector<std::string>& options)\r
        { \r
                auto st = av_new_stream(oc_.get(), 0);\r
                if (!st)                \r
@@ -186,7 +186,6 @@ public:
                {                       \r
                        c->bit_rate     = format_desc_.width < 1280 ? 63*1000000 : 220*1000000;\r
                        c->pix_fmt      = PIX_FMT_YUV422P10;\r
-                       THROW_ON_ERROR2(av_set_options_string(c->priv_data, options.c_str(), "=", ":"), "[ffmpeg_consumer]");\r
                }\r
                else if(c->codec_id == CODEC_ID_DNXHD)\r
                {\r
@@ -195,8 +194,6 @@ public:
 \r
                        c->bit_rate     = 220*1000000;\r
                        c->pix_fmt      = PIX_FMT_YUV422P;\r
-\r
-                       THROW_ON_ERROR2(av_set_options_string(c->priv_data, options.c_str(), "=", ":"), "[ffmpeg_consumer]");\r
                }\r
                else if(c->codec_id == CODEC_ID_DVVIDEO)\r
                {\r
@@ -208,9 +205,7 @@ public:
                        if(format_desc_.duration == 1001)                       \r
                                c->width = format_desc_.height == 1080 ? 1280 : c->width;                       \r
                        else\r
-                               c->width = format_desc_.height == 1080 ? 1440 : c->width;\r
-                       \r
-                       THROW_ON_ERROR2(av_set_options_string(c->priv_data, options.c_str(), "=", ":"), "[ffmpeg_consumer]");\r
+                               c->width = format_desc_.height == 1080 ? 1440 : c->width;                       \r
                }\r
                else if(c->codec_id == CODEC_ID_H264)\r
                {                          \r
@@ -221,8 +216,6 @@ public:
                                av_opt_set(c->priv_data, "tune",   "fastdecode",   0);\r
                                av_opt_set(c->priv_data, "crf",    "5",     0);\r
                        }\r
-\r
-                       THROW_ON_ERROR2(av_set_options_string(c->priv_data, options.c_str(), "=", ":"), "[ffmpeg_consumer]");\r
                }\r
                else if(c->codec_id == CODEC_ID_QTRLE)\r
                {\r
@@ -230,12 +223,14 @@ public:
                }\r
                else\r
                {\r
-                       THROW_ON_ERROR2(av_set_options_string(c->priv_data, options.c_str(), "=", ":"), "[ffmpeg_consumer]");\r
-                       CASPAR_LOG(warning) << " Potentially unsupported output parameters.";\r
+                       BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported output parameters."));\r
                }\r
                \r
-               c->max_b_frames = 0; // b-franes not supported.\r
+               c->max_b_frames = 0; // b-frames not supported.\r
 \r
+               for(size_t n = 0; n < options.size()/2; ++n)\r
+                       THROW_ON_ERROR2(av_opt_set(c, options[n*2+0].c_str(), options[n*2+1].c_str(), AV_OPT_SEARCH_CHILDREN), "[ffmpeg_consumer]");\r
+               \r
                if(oc_->oformat->flags & AVFMT_GLOBALHEADER)\r
                        c->flags |= CODEC_FLAG_GLOBAL_HEADER;\r
                \r
@@ -388,16 +383,16 @@ public:
 \r
 struct ffmpeg_consumer_proxy : public core::frame_consumer\r
 {\r
-       const std::wstring      filename_;\r
-       const bool                      key_only_;\r
-       const std::wstring      codec_;\r
-       const std::wstring      options_;\r
+       const std::wstring                              filename_;\r
+       const bool                                              key_only_;\r
+       const std::wstring                              codec_;\r
+       const std::vector<std::string>  options_;\r
 \r
        std::unique_ptr<ffmpeg_consumer> consumer_;\r
 \r
 public:\r
 \r
-       ffmpeg_consumer_proxy(const std::wstring& filename, bool key_only, const std::wstring codec, const std::wstring& options)\r
+       ffmpeg_consumer_proxy(const std::wstring& filename, bool key_only, const std::wstring codec, const std::vector<std::string>& options)\r
                : filename_(filename)\r
                , key_only_(key_only)\r
                , codec_(boost::to_lower_copy(codec))\r
@@ -408,7 +403,7 @@ public:
        virtual void initialize(const core::video_format_desc& format_desc, int)\r
        {\r
                consumer_.reset();\r
-               consumer_.reset(new ffmpeg_consumer(narrow(filename_), format_desc, narrow(codec_), narrow(options_)));\r
+               consumer_.reset(new ffmpeg_consumer(narrow(filename_), format_desc, narrow(codec_), options_));\r
        }\r
        \r
        virtual bool send(const safe_ptr<core::read_frame>& frame) override\r
@@ -428,8 +423,7 @@ public:
                info.add(L"type", L"ffmpeg-consumer");\r
                info.add(L"key-only", key_only_);\r
                info.add(L"filename", filename_);\r
-               info.add(L"codec", codec_);\r
-               info.add(L"options", options_);\r
+               info.add(L"vcodec", codec_);\r
                return info;\r
        }\r
                \r
@@ -456,17 +450,26 @@ safe_ptr<core::frame_consumer> create_consumer(const std::vector<std::wstring>&
        \r
        auto filename   = (params.size() > 1 ? params[1] : L"");\r
        bool key_only   = get_param(L"KEY_ONLY", params, false);\r
-       auto codec              = get_param(L"CODEC", params, L"libx264");\r
-       auto options    = get_param(L"OPTIONS", params);\r
-       \r
+       auto codec              = get_param(L"-VCODEC", params,  get_param(L"CODEC", params, L"libx264"));\r
+\r
+       std::vector<std::string> options;\r
+       auto opt_it = std::find(params.begin(), params.end(), L"-VCODEC");\r
+\r
+       if(std::distance(opt_it, params.end()) > 2)\r
+       {\r
+               std::advance(opt_it, 2);\r
+               while(opt_it != params.end())\r
+                       options.push_back(narrow(boost::replace_all_copy(boost::trim_copy(boost::to_lower_copy(*opt_it++)), L"-", L"")));               \r
+\r
+       }\r
+\r
+               \r
        if(codec == L"H264")\r
                codec = L"libx264";\r
 \r
        if(codec == L"DVCPRO")\r
                codec = L"dvvideo";\r
-\r
-       boost::to_lower(options);\r
-\r
+       \r
        return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + filename, key_only, codec, options);\r
 }\r
 \r
@@ -474,10 +477,9 @@ safe_ptr<core::frame_consumer> create_consumer(const boost::property_tree::wptre
 {\r
        auto filename   = ptree.get<std::wstring>(L"path");\r
        auto key_only   = ptree.get(L"key-only", false);\r
-       auto codec              = ptree.get(L"codec", L"libx264");\r
-       auto options    = ptree.get(L"options", L"");\r
+       auto codec              = ptree.get(L"vcodec", L"libx264");\r
        \r
-       return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + filename, key_only, codec, options);\r
+       return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + filename, key_only, codec, std::vector<std::string>());\r
 }\r
 \r
 }}\r