From 9cd06977daa3c4903be2ba6231fae3b398278544 Mon Sep 17 00:00:00 2001 From: ronag Date: Wed, 8 Jun 2011 15:50:33 +0000 Subject: [PATCH] 2.0.0.2: ffmpeg_consumer: Misc work. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@866 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- core/video_channel_context.cpp | 2 +- .../decklink/consumer/decklink_consumer.cpp | 4 +- .../decklink/producer/decklink_producer.cpp | 16 +- modules/ffmpeg/consumer/ffmpeg_consumer.cpp | 334 +++++++++--------- modules/ffmpeg/consumer/ffmpeg_consumer.h | 4 +- modules/ffmpeg/ffmpeg.cpp | 2 +- modules/ffmpeg/ffmpeg.vcxproj | 4 - shell/main.cpp | 4 +- shell/server.cpp | 4 +- 9 files changed, 184 insertions(+), 190 deletions(-) diff --git a/core/video_channel_context.cpp b/core/video_channel_context.cpp index 800e30783..677c1180e 100644 --- a/core/video_channel_context.cpp +++ b/core/video_channel_context.cpp @@ -35,7 +35,7 @@ ogl_device& video_channel_context::ogl() { return ogl_;} std::wstring video_channel_context::print() const { - return L"video_channel[" + boost::lexical_cast(index_+1) + L"-" + format_desc_.name + L"]"; + return L"video_channel[" + boost::lexical_cast(index_+1) + L"|" + format_desc_.name + L"]"; } }} \ No newline at end of file diff --git a/modules/decklink/consumer/decklink_consumer.cpp b/modules/decklink/consumer/decklink_consumer.cpp index 2252d97e4..e513d53c3 100644 --- a/modules/decklink/consumer/decklink_consumer.cpp +++ b/modules/decklink/consumer/decklink_consumer.cpp @@ -243,7 +243,9 @@ public: BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable video output.")); if(FAILED(output_->SetScheduledFrameCompletionCallback(this))) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback.")); + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info(narrow(print()) + " Failed to set playback completion callback.") + << boost::errinfo_api_function("SetScheduledFrameCompletionCallback")); } void start_playback() diff --git a/modules/decklink/producer/decklink_producer.cpp b/modules/decklink/producer/decklink_producer.cpp index 4dc625803..94613a887 100644 --- a/modules/decklink/producer/decklink_producer.cpp +++ b/modules/decklink/producer/decklink_producer.cpp @@ -97,16 +97,24 @@ public: // NOTE: bmdFormat8BitARGB is currently not supported by any decklink card. (2011-05-08) if(FAILED(input_->EnableVideoInput(display_mode, bmdFormat8BitYUV, 0))) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable video input.")); + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info(narrow(print()) + " Could not enable video input.") + << boost::errinfo_api_function("EnableVideoInput")); if(FAILED(input_->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2))) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable audio input.")); + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info(narrow(print()) + " Could not enable audio input.") + << boost::errinfo_api_function("EnableAudioInput")); if (FAILED(input_->SetCallback(this)) != S_OK) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set input callback.")); + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info(narrow(print()) + " Failed to set input callback.") + << boost::errinfo_api_function("SetCallback")); if(FAILED(input_->StartStreams())) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to start input stream.")); + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info(narrow(print()) + " Failed to start input stream.") + << boost::errinfo_api_function("StartStreams")); CASPAR_LOG(info) << print() << L" Successfully Initialized."; } diff --git a/modules/ffmpeg/consumer/ffmpeg_consumer.cpp b/modules/ffmpeg/consumer/ffmpeg_consumer.cpp index 714e37c72..e19515756 100644 --- a/modules/ffmpeg/consumer/ffmpeg_consumer.cpp +++ b/modules/ffmpeg/consumer/ffmpeg_consumer.cpp @@ -54,78 +54,70 @@ namespace caspar { struct ffmpeg_consumer : boost::noncopyable { - std::string filename_; + const std::string filename_; + const size_t bitrate_; + + const std::shared_ptr oc_; + const core::video_format_desc format_desc_; + + executor executor_; // Audio - AVStream* audio_st_; - std::vector> audio_outbuf_; + std::shared_ptr audio_st_; + std::vector audio_outbuf_; + + std::vector audio_input_buffer_; // Video - AVStream* video_st_; - std::vector> picture_buf_; + std::shared_ptr video_st_; + std::vector video_outbuf_; - std::vector> video_outbuf_; - SwsContext* img_convert_ctx_; + std::vector picture_buf_; + std::shared_ptr img_convert_ctx_; - AVOutputFormat* fmt_; - std::shared_ptr oc_; - core::video_format_desc format_desc_; - - std::vector> audio_input_buffer_; - - boost::unique_future active_; - - executor executor_; public: - ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc) + ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc, size_t bitrate) : filename_(filename) - , audio_st_(nullptr) - , video_st_(nullptr) - , fmt_(nullptr) - , img_convert_ctx_(nullptr) + , bitrate_(bitrate) , video_outbuf_(1920*1080*4) , audio_outbuf_(48000) + , oc_(avformat_alloc_context(), av_free) , format_desc_(format_desc) - , executor_(L"ffmpeg_consumer") + , executor_(print()) { - active_ = executor_.begin_invoke([]{}); - - fmt_ = av_guess_format(nullptr, filename_.c_str(), nullptr); - if (!fmt_) + if (!oc_) { - CASPAR_LOG(info) << "Could not deduce output format from ffmpeg extension: using MPEG."; - fmt_ = av_guess_format("mpeg", nullptr, nullptr); - filename_ = filename_ + ".avi"; + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info("Could not alloc format-context") + << boost::errinfo_api_function("avformat_alloc_context")); } - if (!fmt_) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not find suitable output format")); + + executor_.set_capacity(CONSUMER_BUFFER_DEPTH); + + oc_->oformat = av_guess_format(nullptr, filename_.c_str(), nullptr); + if (!oc_->oformat) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not find suitable output format.")); - oc_.reset(avformat_alloc_context(), av_free); - if (!oc_) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Memory error")); std::copy_n(filename_.c_str(), filename_.size(), oc_->filename); - - oc_->oformat = fmt_; - // To avoid mpeg buffer underflow (http://www.mail-archive.com/libav-user@mplayerhq.hu/msg00194.html) - oc_->preload = static_cast(0.5*AV_TIME_BASE); - oc_->max_delay = static_cast(0.7*AV_TIME_BASE); - + // Add the audio and video streams using the default format codecs and initialize the codecs . - if (fmt_->video_codec != CODEC_ID_NONE) - video_st_ = add_video_stream(fmt_->video_codec); + if (oc_->oformat->video_codec != CODEC_ID_NONE) + video_st_ = add_video_stream(oc_->oformat->video_codec); - if (fmt_->audio_codec != CODEC_ID_NONE) - audio_st_ = add_audio_stream(fmt_->audio_codec); + //if (oc_->oformat->audio_codec != CODEC_ID_NONE) + // audio_st_ = add_audio_stream(oc_->oformat->audio_codec); // Set the output parameters (must be done even if no parameters). - int errn = 0; - if ((errn = -av_set_parameters(oc_.get(), nullptr)) > 0) + int errn = av_set_parameters(oc_.get(), nullptr); + if (errn < 0) + { BOOST_THROW_EXCEPTION( file_read_error() << msg_info("Invalid output format parameters") << boost::errinfo_api_function("avcodec_open") << - boost::errinfo_errno(errn) << + boost::errinfo_errno(AVUNERROR(errn)) << boost::errinfo_file_name(filename_)); + } dump_format(oc_.get(), 0, filename_.c_str(), 1); @@ -146,16 +138,18 @@ public: } // Open the output ffmpeg, if needed. - if (!(fmt_->flags & AVFMT_NOFILE)) + if (!(oc_->oformat->flags & AVFMT_NOFILE)) { - int errn = 0; - if ((errn = -url_fopen(&oc_->pb, filename_.c_str(), URL_WRONLY)) > 0) + int errn = url_fopen(&oc_->pb, filename_.c_str(), URL_WRONLY); + if (errn < 0) + { BOOST_THROW_EXCEPTION( file_not_found() << msg_info("Could not open file") << boost::errinfo_api_function("url_fopen") << - boost::errinfo_errno(errn) << + boost::errinfo_errno(AVUNERROR(errn)) << boost::errinfo_file_name(filename_)); + } } av_write_header(oc_.get()); // write the stream header, if any @@ -165,26 +159,15 @@ public: ~ffmpeg_consumer() { - executor_.invoke([]{}); executor_.stop(); + executor_.join(); - av_write_trailer(oc_.get()); + audio_st_.reset(); + video_st_.reset(); - // Close each codec. - if (video_st_) - avcodec_close(video_st_->codec); + av_write_trailer(oc_.get()); - if (audio_st_) - avcodec_close(audio_st_->codec); - - // Free the streams. - for(size_t i = 0; i < oc_->nb_streams; ++i) - { - av_freep(&oc_->streams[i]->codec); - av_freep(&oc_->streams[i]); - } - - if (!(fmt_->flags & AVFMT_NOFILE)) + if (!(oc_->oformat->flags & AVFMT_NOFILE)) url_fclose(oc_->pb); // Close the output ffmpeg. } @@ -198,47 +181,89 @@ public: return L"ffmpeg[" + widen(filename_) + L"]"; } - AVStream* add_video_stream(enum CodecID codec_id) + std::shared_ptr add_video_stream(enum CodecID codec_id) { auto st = av_new_stream(oc_.get(), 0); if (!st) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not alloc stream")); - - auto c = st->codec; - c->codec_id = codec_id; - c->codec_type = AVMEDIA_TYPE_VIDEO; - - // Put sample parameters. - c->bit_rate = static_cast(static_cast(format_desc_.size)*format_desc_.fps*0.1326); - c->width = format_desc_.width; - c->height = format_desc_.height; - c->time_base.den = static_cast(format_desc_.fps); - c->time_base.num = 1; - c->pix_fmt = c->pix_fmt == -1 ? PIX_FMT_YUV420P : c->pix_fmt; - - // Some formats want stream headers to be separate. - if(oc_->oformat->flags & AVFMT_GLOBALHEADER) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; + { + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info("Could not alloc video-stream") + << boost::errinfo_api_function("av_new_stream")); + } + + st->codec->codec_id = codec_id; + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + st->codec->bit_rate = bitrate_; + st->codec->width = format_desc_.width; + st->codec->height = format_desc_.height; + st->codec->time_base.den = format_desc_.time_scale; + st->codec->time_base.num = format_desc_.duration; + st->codec->pix_fmt = st->codec->pix_fmt == -1 ? PIX_FMT_YUV420P : st->codec->pix_fmt; - return st; + return std::shared_ptr(st, [](AVStream* st) + { + avcodec_close(st->codec); + //av_freep(st); + }); + } + + std::shared_ptr add_audio_stream(enum CodecID codec_id) + { + auto st = av_new_stream(oc_.get(), 1); + if (!st) + { + BOOST_THROW_EXCEPTION(caspar_exception() + << msg_info("Could not alloc audio-stream") + << boost::errinfo_api_function("av_new_stream")); + } + + st->codec->codec_id = codec_id; + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->sample_rate = 48000; + st->codec->channels = 2; + st->codec->sample_fmt = SAMPLE_FMT_S16; + + return std::shared_ptr(st, [](AVStream* st) + { + avcodec_close(st->codec); + //av_freep(st); + }); } - void open_video(AVStream* st) - { - auto c = st->codec; - - auto codec = avcodec_find_encoder(c->codec_id); + void open_video(std::shared_ptr& st) + { + auto codec = avcodec_find_encoder(st->codec->codec_id); if (!codec) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found")); - int errn = 0; - if ((errn = -avcodec_open(c, codec)) > 0) + int errn = avcodec_open(st->codec, codec); + if (errn < 0) + { BOOST_THROW_EXCEPTION( file_read_error() << msg_info("Could not open video codec.") << boost::errinfo_api_function("avcodec_open") << - boost::errinfo_errno(errn) << - boost::errinfo_file_name(filename_)); + boost::errinfo_errno(AVUNERROR(errn)) << + boost::errinfo_file_name(filename_)); + } + } + + void open_audio(std::shared_ptr& st) + { + auto codec = avcodec_find_encoder(st->codec->codec_id); + if (!codec) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found")); + + int errn = avcodec_open(st->codec, codec); + if (errn < 0) + { + BOOST_THROW_EXCEPTION( + file_read_error() << + msg_info("Could not open audio codec") << + boost::errinfo_api_function("avcodec_open") << + boost::errinfo_errno(AVUNERROR(errn)) << + boost::errinfo_file_name(filename_)); + } } void encode_video_frame(const safe_ptr& frame) @@ -248,9 +273,9 @@ public: AVCodecContext* c = video_st_->codec; - if (img_convert_ctx_ == nullptr) + if(!img_convert_ctx_) { - img_convert_ctx_ = sws_getContext(format_desc_.width, format_desc_.height, PIX_FMT_BGRA, c->width, c->height, c->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr); + img_convert_ctx_.reset(sws_getContext(format_desc_.width, format_desc_.height, PIX_FMT_BGRA, c->width, c->height, c->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr), sws_freeContext); if (img_convert_ctx_ == nullptr) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Cannot initialize the conversion context")); } @@ -262,84 +287,45 @@ public: picture_buf_.resize(avpicture_get_size(c->pix_fmt, format_desc_.width, format_desc_.height)); avpicture_fill(reinterpret_cast(local_av_frame.get()), picture_buf_.data(), c->pix_fmt, format_desc_.width, format_desc_.height); - sws_scale(img_convert_ctx_, av_frame->data, av_frame->linesize, 0, c->height, local_av_frame->data, local_av_frame->linesize); - - int ret = avcodec_encode_video(c, video_outbuf_.data(), video_outbuf_.size(), local_av_frame.get()); + sws_scale(img_convert_ctx_.get(), av_frame->data, av_frame->linesize, 0, c->height, local_av_frame->data, local_av_frame->linesize); - int errn = -ret; - if (errn > 0) + int errn = avcodec_encode_video(c, video_outbuf_.data(), video_outbuf_.size(), local_av_frame.get()); + if (errn < 0) + { BOOST_THROW_EXCEPTION( invalid_operation() << msg_info("Could not encode video frame.") << boost::errinfo_api_function("avcodec_encode_video") << - boost::errinfo_errno(errn) << + boost::errinfo_errno(AVUNERROR(errn)) << boost::errinfo_file_name(filename_)); + } - auto out_size = ret; AVPacket pkt; av_init_packet(&pkt); - pkt.size = out_size; + pkt.size = errn; // If zero size, it means the image was buffered. - if (out_size > 0) + if (errn > 0) { if (c->coded_frame->pts != AV_NOPTS_VALUE) pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st_->time_base); + if(c->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; pkt.stream_index = video_st_->index; - pkt.data = video_outbuf_.data(); + pkt.data = video_outbuf_.data(); if (av_interleaved_write_frame(oc_.get(), &pkt) != 0) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Error while writing video frame")); } } - - AVStream* add_audio_stream(enum CodecID codec_id) - { - audio_st_ = av_new_stream(oc_.get(), 1); - if (!audio_st_) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not alloc stream")); - - auto c = audio_st_->codec; - c->codec_id = codec_id; - c->codec_type = AVMEDIA_TYPE_AUDIO; - - // Put sample parameters. - c->bit_rate = 192000; - c->sample_rate = 48000; - c->channels = 2; - - // Some formats want stream headers to be separate. - if(oc_->oformat->flags & AVFMT_GLOBALHEADER) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - - return audio_st_; - } - - void open_audio(AVStream* st) - { - auto c = st->codec; - - // Find the audio encoder. - auto codec = avcodec_find_encoder(c->codec_id); - if (!codec) - BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found")); - // Open it. - int errn = 0; - if ((errn = -avcodec_open(c, codec)) > 0) - BOOST_THROW_EXCEPTION( - file_read_error() << - msg_info("Could not open audio codec") << - boost::errinfo_api_function("avcodec_open") << - boost::errinfo_errno(errn) << - boost::errinfo_file_name(filename_)); - } - void encode_audio_frame(const safe_ptr& frame) { + if(!audio_st_) + return; + if(!frame->audio_data().empty()) audio_input_buffer_.insert(audio_input_buffer_.end(), frame->audio_data().begin(), frame->audio_data().end()); else @@ -350,9 +336,6 @@ public: bool encode_audio_packet() { - if(!audio_st_) - return false; - auto c = audio_st_->codec; auto frame_bytes = c->frame_size * 2 * 2; // samples per frame * 2 channels * 2 bytes per sample @@ -362,25 +345,26 @@ public: AVPacket pkt; av_init_packet(&pkt); - int ret = avcodec_encode_audio(c, audio_outbuf_.data(), audio_outbuf_.size(), audio_input_buffer_.data()); - - int errn = -ret; - if (errn > 0) + int errn = avcodec_encode_audio(c, audio_outbuf_.data(), audio_outbuf_.size(), audio_input_buffer_.data()); + if (errn < 0) + { BOOST_THROW_EXCEPTION( invalid_operation() << msg_info("Could not encode audio samples.") << boost::errinfo_api_function("avcodec_encode_audio") << - boost::errinfo_errno(errn) << + boost::errinfo_errno(AVUNERROR(errn)) << boost::errinfo_file_name(filename_)); + } - pkt.size = ret; - audio_input_buffer_ = std::vector>(audio_input_buffer_.begin() + frame_bytes/2, audio_input_buffer_.end()); + pkt.size = errn; + audio_input_buffer_ = std::vector(audio_input_buffer_.begin() + frame_bytes/2, audio_input_buffer_.end()); if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_st_->time_base); - pkt.flags |= AV_PKT_FLAG_KEY; + + pkt.flags |= AV_PKT_FLAG_KEY; pkt.stream_index = audio_st_->index; - pkt.data = audio_outbuf_.data(); + pkt.data = audio_outbuf_.data(); if (av_interleaved_write_frame(oc_.get(), &pkt) != 0) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Error while writing audio frame")); @@ -390,12 +374,10 @@ public: void send(const safe_ptr& frame) { - active_.get(); - active_ = executor_.begin_invoke([=] + executor_.begin_invoke([=] { - auto my_frame = frame; - encode_video_frame(my_frame); - encode_audio_frame(my_frame); + encode_video_frame(frame); + encode_audio_frame(frame); }); } @@ -406,18 +388,20 @@ struct ffmpeg_consumer_proxy : public core::frame_consumer { const std::wstring filename_; const bool key_only_; + const size_t bitrate_; std::unique_ptr consumer_; public: - ffmpeg_consumer_proxy(const std::wstring& filename, bool key_only) + ffmpeg_consumer_proxy(const std::wstring& filename, bool key_only, size_t bitrate) : filename_(filename) - , key_only_(key_only){} + , key_only_(key_only) + , bitrate_(bitrate){} virtual void initialize(const core::video_format_desc& format_desc) { - consumer_.reset(new ffmpeg_consumer(narrow(filename_), format_desc)); + consumer_.reset(new ffmpeg_consumer(narrow(filename_), format_desc, bitrate_)); } virtual void send(const safe_ptr& frame) @@ -434,6 +418,11 @@ public: { return key_only_; } + + virtual bool has_synchronization_clock() const + { + return false; + } virtual const core::video_format_desc& get_video_format_desc() const { @@ -450,15 +439,16 @@ safe_ptr create_ffmpeg_consumer(const std::vector(env::media_folder() + params[1], key_only); + return make_safe(env::media_folder() + params[1], key_only, 100000000); } safe_ptr create_ffmpeg_consumer(const boost::property_tree::ptree& ptree) { - std::string filename = ptree.get("filename"); + std::string filename = ptree.get("path"); bool key_only = ptree.get("key-only", false); + size_t bitrate = ptree.get("bitrate", 100000000); - return make_safe(env::media_folder() + widen(filename), key_only); + return make_safe(env::media_folder() + widen(filename), key_only, bitrate); } } diff --git a/modules/ffmpeg/consumer/ffmpeg_consumer.h b/modules/ffmpeg/consumer/ffmpeg_consumer.h index 3cc9c7562..decc821a8 100644 --- a/modules/ffmpeg/consumer/ffmpeg_consumer.h +++ b/modules/ffmpeg/consumer/ffmpeg_consumer.h @@ -29,7 +29,7 @@ namespace caspar { -//safe_ptr create_ffmpeg_consumer(const std::vector& params); -//safe_ptr create_ffmpeg_consumer(const boost::property_tree::ptree& ptree); +safe_ptr create_ffmpeg_consumer(const std::vector& params); +safe_ptr create_ffmpeg_consumer(const boost::property_tree::ptree& ptree); } \ No newline at end of file diff --git a/modules/ffmpeg/ffmpeg.cpp b/modules/ffmpeg/ffmpeg.cpp index b47275123..21490a92d 100644 --- a/modules/ffmpeg/ffmpeg.cpp +++ b/modules/ffmpeg/ffmpeg.cpp @@ -46,7 +46,7 @@ void init_ffmpeg() av_register_all(); avcodec_init(); - //core::register_consumer_factory([](const std::vector& params){return create_ffmpeg_consumer(params);}); + core::register_consumer_factory([](const std::vector& params){return create_ffmpeg_consumer(params);}); core::register_producer_factory(create_ffmpeg_producer); } diff --git a/modules/ffmpeg/ffmpeg.vcxproj b/modules/ffmpeg/ffmpeg.vcxproj index 5b27feb47..623f7065b 100644 --- a/modules/ffmpeg/ffmpeg.vcxproj +++ b/modules/ffmpeg/ffmpeg.vcxproj @@ -272,10 +272,6 @@ ../StdAfx.h ../StdAfx.h ../StdAfx.h - true - true - true - true diff --git a/shell/main.cpp b/shell/main.cpp index 1eb540b12..a89c0fb94 100644 --- a/shell/main.cpp +++ b/shell/main.cpp @@ -36,7 +36,6 @@ #include #include -#include #include @@ -242,7 +241,6 @@ int main(int argc, wchar_t* argv[]) CASPAR_LOG(info) << "Successfully shutdown CasparCG Server."; Sleep(100); // CAPSAR_LOG is asynchronous. Try to get text in correct order. - std::wcout << L"Press Any Key To Exit.\n"; - _getwch(); + system("pause"); return 0; } \ No newline at end of file diff --git a/shell/server.cpp b/shell/server.cpp index 52ac618a5..d094fdf8d 100644 --- a/shell/server.cpp +++ b/shell/server.cpp @@ -112,8 +112,8 @@ struct server::implementation : boost::noncopyable channels_.back()->output()->add(index++, create_bluefish_consumer(xml_consumer.second)); else if(name == "decklink") channels_.back()->output()->add(index++, create_decklink_consumer(xml_consumer.second)); - //else if(name == "file") - // channels_.back()->output()->add(index++, create_ffmpeg_consumer(xml_consumer.second)); + else if(name == "file") + channels_.back()->output()->add(index++, create_ffmpeg_consumer(xml_consumer.second)); else if(name == "audio") channels_.back()->output()->add(index++, make_safe()); else if(name != "") -- 2.39.5