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
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
{ \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
\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
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
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
}\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
\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
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
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
\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
{\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