+int av_opt_set(void *obj, const char *name, const char *val, int search_flags)\r
+{\r
+ AVClass* av_class = *(AVClass**)obj;\r
+\r
+ if((strcmp(name, "pix_fmt") == 0 || strcmp(name, "pixel_format") == 0) && strcmp(av_class->class_name, "AVCodecContext") == 0)\r
+ {\r
+ AVCodecContext* c = (AVCodecContext*)obj; \r
+ auto pix_fmt = av_get_pix_fmt(val);\r
+ if(pix_fmt == PIX_FMT_NONE)\r
+ return -1; \r
+ c->pix_fmt = pix_fmt;\r
+ return 0;\r
+ }\r
+ if((strcmp(name, "r") == 0 || strcmp(name, "frame_rate") == 0) && strcmp(av_class->class_name, "AVCodecContext") == 0)\r
+ {\r
+ AVCodecContext* c = (AVCodecContext*)obj; \r
+\r
+ if(c->codec_type != AVMEDIA_TYPE_VIDEO)\r
+ return -1;\r
+\r
+ AVRational rate;\r
+ int ret = av_parse_video_rate(&rate, val);\r
+ if(ret < 0)\r
+ return ret;\r
+\r
+ c->time_base.num = rate.den;\r
+ c->time_base.den = rate.num;\r
+ return 0;\r
+ }\r
+\r
+ return ::av_opt_set(obj, name, val, search_flags);\r
+}\r
+\r
+struct option\r
+{\r
+ std::string name;\r
+ std::string value;\r
+\r
+ option(std::string name, std::string value)\r
+ : name(std::move(name))\r
+ , value(std::move(value))\r
+ {\r
+ }\r
+};\r
+ \r
+struct output_format\r
+{\r
+ AVOutputFormat* format;\r
+ int width;\r
+ int height;\r
+ CodecID vcodec;\r
+ CodecID acodec;\r
+\r
+ output_format(const core::video_format_desc& format_desc, const std::string& filename, std::vector<option>& options)\r
+ : format(av_guess_format(nullptr, filename.c_str(), nullptr))\r
+ , width(format_desc.width)\r
+ , height(format_desc.height)\r
+ , vcodec(CODEC_ID_NONE)\r
+ , acodec(CODEC_ID_NONE)\r
+ {\r
+ boost::range::remove_erase_if(options, [&](const option& o)\r
+ {\r
+ return set_opt(o.name, o.value);\r
+ });\r
+ \r
+ if(vcodec == CODEC_ID_NONE)\r
+ vcodec = format->video_codec;\r
+\r
+ if(acodec == CODEC_ID_NONE)\r
+ acodec = format->audio_codec;\r
+ \r
+ if(vcodec == CODEC_ID_NONE)\r
+ vcodec = CODEC_ID_H264;\r
+ \r
+ if(acodec == CODEC_ID_NONE)\r
+ acodec = CODEC_ID_PCM_S16LE;\r
+ }\r
+ \r
+ bool set_opt(const std::string& name, const std::string& value)\r
+ {\r
+ //if(name == "target")\r
+ //{ \r
+ // enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;\r
+ // \r
+ // if(name.find("pal-") != std::string::npos)\r
+ // norm = PAL;\r
+ // else if(name.find("ntsc-") != std::string::npos)\r
+ // norm = NTSC;\r
+\r
+ // if(norm == UNKNOWN)\r
+ // BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("target"));\r
+ // \r
+ // if (name.find("-dv") != std::string::npos) \r
+ // {\r
+ // set_opt("f", "dv");\r
+ // set_opt("s", norm == PAL ? "720x576" : "720x480");\r
+ // //set_opt("pix_fmt", name.find("-dv50") != std::string::npos ? "yuv422p" : norm == PAL ? "yuv420p" : "yuv411p");\r
+ // //set_opt("ar", "48000");\r
+ // //set_opt("ac", "2");\r
+ // } \r
+ //}\r
+ if(name == "f")\r
+ {\r
+ format = av_guess_format(value.c_str(), nullptr, nullptr);\r
+\r
+ if(format == nullptr)\r
+ BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("f"));\r
+\r
+ return true;\r
+ }\r
+ else if(name == "vcodec")\r
+ {\r
+ auto c = avcodec_find_encoder_by_name(value.c_str());\r
+ if(c == nullptr)\r
+ BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("vcodec"));\r
+\r
+ vcodec = avcodec_find_encoder_by_name(value.c_str())->id;\r
+ return true;\r
+\r
+ }\r
+ else if(name == "acodec")\r
+ {\r
+ auto c = avcodec_find_encoder_by_name(value.c_str());\r
+ if(c == nullptr)\r
+ BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("acodec"));\r
+\r
+ acodec = avcodec_find_encoder_by_name(value.c_str())->id;\r
+\r
+ return true;\r
+ }\r
+ else if(name == "s")\r
+ {\r
+ if(av_parse_video_size(&width, &height, value.c_str()) < 0)\r
+ BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("s"));\r
+ \r
+ return true;\r
+ }\r
+\r
+ return false;\r
+ }\r
+};\r
+\r
+typedef std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>> byte_vector;\r
+\r