]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: ffmpeg_consumer: Misc work.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 8 Jun 2011 15:50:33 +0000 (15:50 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 8 Jun 2011 15:50:33 +0000 (15:50 +0000)
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
modules/decklink/consumer/decklink_consumer.cpp
modules/decklink/producer/decklink_producer.cpp
modules/ffmpeg/consumer/ffmpeg_consumer.cpp
modules/ffmpeg/consumer/ffmpeg_consumer.h
modules/ffmpeg/ffmpeg.cpp
modules/ffmpeg/ffmpeg.vcxproj
shell/main.cpp
shell/server.cpp

index 800e30783cbd1587a8daf95977d4d03d1ec90044..677c1180e9696daddd86c3c9a33587aee8f9d07a 100644 (file)
@@ -35,7 +35,7 @@ ogl_device& video_channel_context::ogl() { return ogl_;}
 \r
 std::wstring video_channel_context::print() const\r
 {\r
-       return L"video_channel[" + boost::lexical_cast<std::wstring>(index_+1) + L"-" +  format_desc_.name + L"]";\r
+       return L"video_channel[" + boost::lexical_cast<std::wstring>(index_+1) + L"|" +  format_desc_.name + L"]";\r
 }\r
 \r
 }}
\ No newline at end of file
index 2252d97e40ea99178aedf4134cfd4ad52abef8cc..e513d53c3a08e1dcd88592a61d062a5eee28dc63 100644 (file)
@@ -243,7 +243,9 @@ public:
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable video output."));\r
                \r
                if(FAILED(output_->SetScheduledFrameCompletionCallback(this)))\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback."));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                                                                       << msg_info(narrow(print()) + " Failed to set playback completion callback.")\r
+                                                                       << boost::errinfo_api_function("SetScheduledFrameCompletionCallback"));\r
        }\r
 \r
        void start_playback()\r
index 4dc625803535153098dc70075389805b150848c5..94613a887063508de8e7abb23f8e6842c0e3e05e 100644 (file)
@@ -97,16 +97,24 @@ public:
                \r
                // NOTE: bmdFormat8BitARGB is currently not supported by any decklink card. (2011-05-08)\r
                if(FAILED(input_->EnableVideoInput(display_mode, bmdFormat8BitYUV, 0))) \r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable video input."));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                                                                       << msg_info(narrow(print()) + " Could not enable video input.")\r
+                                                                       << boost::errinfo_api_function("EnableVideoInput"));\r
 \r
                if(FAILED(input_->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2))) \r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable audio input."));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                                                                       << msg_info(narrow(print()) + " Could not enable audio input.")\r
+                                                                       << boost::errinfo_api_function("EnableAudioInput"));\r
                        \r
                if (FAILED(input_->SetCallback(this)) != S_OK)\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set input callback."));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                                                                       << msg_info(narrow(print()) + " Failed to set input callback.")\r
+                                                                       << boost::errinfo_api_function("SetCallback"));\r
                        \r
                if(FAILED(input_->StartStreams()))\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to start input stream."));\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                                                                       << msg_info(narrow(print()) + " Failed to start input stream.")\r
+                                                                       << boost::errinfo_api_function("StartStreams"));\r
 \r
                CASPAR_LOG(info) << print() << L" Successfully Initialized.";\r
        }\r
index 714e37c729e6148e16d558cbef4133ae7b3e702f..e19515756a6e2acea2d0b3fb22b2af81ff3b0314 100644 (file)
@@ -54,78 +54,70 @@ namespace caspar {
        \r
 struct ffmpeg_consumer : boost::noncopyable\r
 {              \r
-       std::string filename_;\r
+       const std::string                                               filename_;\r
+       const size_t                                                    bitrate_;\r
+               \r
+       const std::shared_ptr<AVFormatContext>  oc_;\r
+       const core::video_format_desc                   format_desc_;\r
+       \r
+       executor                                                                executor_;\r
 \r
        // Audio\r
-       AVStream* audio_st_;\r
-       std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>> audio_outbuf_;\r
+       std::shared_ptr<AVStream>                               audio_st_;\r
+       std::vector<uint8_t>                                    audio_outbuf_;\r
+\r
+       std::vector<int16_t>                                    audio_input_buffer_;\r
 \r
        // Video\r
-       AVStream* video_st_;\r
-       std::vector<uint8_t, tbb::cache_aligned_allocator<unsigned char>> picture_buf_;\r
+       std::shared_ptr<AVStream>                               video_st_;\r
+       std::vector<uint8_t>                                    video_outbuf_;\r
 \r
-       std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>> video_outbuf_;\r
-       SwsContext* img_convert_ctx_;\r
+       std::vector<uint8_t>                                    picture_buf_;\r
+       std::shared_ptr<SwsContext>                             img_convert_ctx_;\r
        \r
-       AVOutputFormat* fmt_;\r
-       std::shared_ptr<AVFormatContext> oc_;\r
-       core::video_format_desc format_desc_;\r
-\r
-       std::vector<short, tbb::cache_aligned_allocator<short>> audio_input_buffer_;\r
-\r
-       boost::unique_future<void> active_;\r
-\r
-       executor executor_;\r
 public:\r
-       ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc)\r
+       ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc, size_t bitrate)\r
                : filename_(filename)\r
-               , audio_st_(nullptr)\r
-               , video_st_(nullptr)\r
-               , fmt_(nullptr)\r
-               , img_convert_ctx_(nullptr)\r
+               , bitrate_(bitrate)\r
                , video_outbuf_(1920*1080*4)\r
                , audio_outbuf_(48000)\r
+               , oc_(avformat_alloc_context(), av_free)\r
                , format_desc_(format_desc)\r
-               , executor_(L"ffmpeg_consumer")\r
+               , executor_(print())\r
        {\r
-               active_ = executor_.begin_invoke([]{});\r
-\r
-               fmt_ = av_guess_format(nullptr, filename_.c_str(), nullptr);\r
-               if (!fmt_) \r
+               if (!oc_)\r
                {\r
-                       CASPAR_LOG(info) << "Could not deduce output format from ffmpeg extension: using MPEG.";\r
-                       fmt_ = av_guess_format("mpeg", nullptr, nullptr);\r
-                       filename_ = filename_ + ".avi"; \r
+                       BOOST_THROW_EXCEPTION(caspar_exception()\r
+                               << msg_info("Could not alloc format-context")                           \r
+                               << boost::errinfo_api_function("avformat_alloc_context"));\r
                }\r
-               if (!fmt_)\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not find suitable output format"));\r
+\r
+               executor_.set_capacity(CONSUMER_BUFFER_DEPTH);\r
+\r
+               oc_->oformat = av_guess_format(nullptr, filename_.c_str(), nullptr);\r
+               if (!oc_->oformat)\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not find suitable output format."));\r
                \r
-               oc_.reset(avformat_alloc_context(), av_free);\r
-               if (!oc_)\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Memory error"));\r
                std::copy_n(filename_.c_str(), filename_.size(), oc_->filename);\r
-\r
-               oc_->oformat = fmt_;\r
-               // To avoid mpeg buffer underflow (http://www.mail-archive.com/libav-user@mplayerhq.hu/msg00194.html)\r
-               oc_->preload = static_cast<int>(0.5*AV_TIME_BASE);\r
-               oc_->max_delay = static_cast<int>(0.7*AV_TIME_BASE);\r
-                       \r
+                                       \r
                //  Add the audio and video streams using the default format codecs     and initialize the codecs .\r
-               if (fmt_->video_codec != CODEC_ID_NONE)         \r
-                       video_st_ = add_video_stream(fmt_->video_codec);\r
+               if (oc_->oformat->video_codec != CODEC_ID_NONE)         \r
+                       video_st_ = add_video_stream(oc_->oformat->video_codec);\r
                \r
-               if (fmt_->audio_codec != CODEC_ID_NONE) \r
-                       audio_st_ = add_audio_stream(fmt_->audio_codec);        \r
+               //if (oc_->oformat->audio_codec != CODEC_ID_NONE) \r
+               //      audio_st_ = add_audio_stream(oc_->oformat->audio_codec);        \r
 \r
                // Set the output parameters (must be done even if no parameters).              \r
-               int errn = 0;\r
-               if ((errn = -av_set_parameters(oc_.get(), nullptr)) > 0)\r
+               int errn = av_set_parameters(oc_.get(), nullptr);\r
+               if (errn < 0)\r
+               {\r
                        BOOST_THROW_EXCEPTION(\r
                                file_read_error() << \r
                                msg_info("Invalid output format parameters") <<\r
                                boost::errinfo_api_function("avcodec_open") <<\r
-                               boost::errinfo_errno(errn) <<\r
+                               boost::errinfo_errno(AVUNERROR(errn)) <<\r
                                boost::errinfo_file_name(filename_));\r
+               }\r
                \r
                dump_format(oc_.get(), 0, filename_.c_str(), 1);\r
 \r
@@ -146,16 +138,18 @@ public:
                }\r
  \r
                // Open the output ffmpeg, if needed.\r
-               if (!(fmt_->flags & AVFMT_NOFILE)) \r
+               if (!(oc_->oformat->flags & AVFMT_NOFILE)) \r
                {\r
-                       int errn = 0;\r
-                       if ((errn = -url_fopen(&oc_->pb, filename_.c_str(), URL_WRONLY)) > 0) \r
+                       int errn = url_fopen(&oc_->pb, filename_.c_str(), URL_WRONLY);\r
+                       if (errn < 0) \r
+                       {\r
                                BOOST_THROW_EXCEPTION(\r
                                        file_not_found() << \r
                                        msg_info("Could not open file") <<\r
                                        boost::errinfo_api_function("url_fopen") <<\r
-                                       boost::errinfo_errno(errn) <<\r
+                                       boost::errinfo_errno(AVUNERROR(errn)) <<\r
                                        boost::errinfo_file_name(filename_));\r
+                       }\r
                }\r
                \r
                av_write_header(oc_.get()); // write the stream header, if any \r
@@ -165,26 +159,15 @@ public:
 \r
        ~ffmpeg_consumer()\r
        {    \r
-               executor_.invoke([]{});\r
                executor_.stop();\r
+               executor_.join();\r
 \r
-               av_write_trailer(oc_.get());\r
+               audio_st_.reset();\r
+               video_st_.reset();\r
 \r
-               // Close each codec.\r
-               if (video_st_)          \r
-                       avcodec_close(video_st_->codec);\r
+               av_write_trailer(oc_.get());\r
                \r
-               if (audio_st_)\r
-                       avcodec_close(audio_st_->codec);\r
-                               \r
-               // Free the streams.\r
-               for(size_t i = 0; i < oc_->nb_streams; ++i) \r
-               {\r
-                       av_freep(&oc_->streams[i]->codec);\r
-                       av_freep(&oc_->streams[i]);\r
-               }\r
-\r
-               if (!(fmt_->flags & AVFMT_NOFILE)) \r
+               if (!(oc_->oformat->flags & AVFMT_NOFILE)) \r
                        url_fclose(oc_->pb); // Close the output ffmpeg.\r
        }\r
 \r
@@ -198,47 +181,89 @@ public:
                return L"ffmpeg[" + widen(filename_) + L"]";\r
        }\r
 \r
-       AVStream* add_video_stream(enum CodecID codec_id)\r
+       std::shared_ptr<AVStream> add_video_stream(enum CodecID codec_id)\r
        { \r
                auto st = av_new_stream(oc_.get(), 0);\r
                if (!st) \r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not alloc stream"));\r
\r
-               auto c = st->codec;\r
-               c->codec_id = codec_id;\r
-               c->codec_type = AVMEDIA_TYPE_VIDEO;\r
\r
-               // Put sample parameters.\r
-               c->bit_rate = static_cast<int>(static_cast<double>(format_desc_.size)*format_desc_.fps*0.1326);\r
-               c->width = format_desc_.width;\r
-               c->height = format_desc_.height;\r
-               c->time_base.den = static_cast<int>(format_desc_.fps);\r
-               c->time_base.num = 1;\r
-               c->pix_fmt = c->pix_fmt == -1 ? PIX_FMT_YUV420P : c->pix_fmt;\r
-\r
-               // Some formats want stream headers to be separate.\r
-               if(oc_->oformat->flags & AVFMT_GLOBALHEADER)\r
-                       c->flags |= CODEC_FLAG_GLOBAL_HEADER;\r
+               {\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                               << msg_info("Could not alloc video-stream")                             \r
+                               << boost::errinfo_api_function("av_new_stream"));\r
+               }\r
+\r
+               st->codec->codec_id                     = codec_id;\r
+               st->codec->codec_type           = AVMEDIA_TYPE_VIDEO;\r
+               st->codec->bit_rate                     = bitrate_;\r
+               st->codec->width                        = format_desc_.width;\r
+               st->codec->height                       = format_desc_.height;\r
+               st->codec->time_base.den        = format_desc_.time_scale;\r
+               st->codec->time_base.num        = format_desc_.duration;\r
+               st->codec->pix_fmt                      = st->codec->pix_fmt == -1 ? PIX_FMT_YUV420P : st->codec->pix_fmt;\r
  \r
-               return st;\r
+               return std::shared_ptr<AVStream>(st, [](AVStream* st)\r
+               {\r
+                       avcodec_close(st->codec);\r
+                       //av_freep(st);\r
+               });\r
+       }\r
+       \r
+       std::shared_ptr<AVStream> add_audio_stream(enum CodecID codec_id)\r
+       {\r
+               auto st = av_new_stream(oc_.get(), 1);\r
+               if (!st) \r
+               {\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() \r
+                               << msg_info("Could not alloc audio-stream")                             \r
+                               << boost::errinfo_api_function("av_new_stream"));\r
+               }\r
+\r
+               st->codec->codec_id             = codec_id;\r
+               st->codec->codec_type   = AVMEDIA_TYPE_AUDIO;\r
+               st->codec->sample_rate  = 48000;\r
+               st->codec->channels             = 2;\r
+               st->codec->sample_fmt   = SAMPLE_FMT_S16;\r
+               \r
+               return std::shared_ptr<AVStream>(st, [](AVStream* st)\r
+               {\r
+                       avcodec_close(st->codec);\r
+                       //av_freep(st);\r
+               });\r
        }\r
         \r
-       void open_video(AVStream* st)\r
-       { \r
-               auto c = st->codec;\r
\r
-               auto codec = avcodec_find_encoder(c->codec_id);\r
+       void open_video(std::shared_ptr<AVStream>& st)\r
+       {  \r
+               auto codec = avcodec_find_encoder(st->codec->codec_id);\r
                if (!codec)\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found"));\r
                \r
-               int errn = 0;\r
-               if ((errn = -avcodec_open(c, codec)) > 0)\r
+               int errn = avcodec_open(st->codec, codec);\r
+               if (errn < 0)\r
+               {\r
                        BOOST_THROW_EXCEPTION(\r
                                file_read_error() << \r
                                msg_info("Could not open video codec.") <<\r
                                boost::errinfo_api_function("avcodec_open") <<\r
-                               boost::errinfo_errno(errn) <<\r
-                               boost::errinfo_file_name(filename_));            \r
+                               boost::errinfo_errno(AVUNERROR(errn)) <<\r
+                               boost::errinfo_file_name(filename_));           \r
+               }\r
+       }\r
+\r
+       void open_audio(std::shared_ptr<AVStream>& st)\r
+       {\r
+               auto codec = avcodec_find_encoder(st->codec->codec_id);\r
+               if (!codec) \r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found"));\r
+               \r
+               int errn = avcodec_open(st->codec, codec);\r
+               if (errn < 0)\r
+               {\r
+                       BOOST_THROW_EXCEPTION(\r
+                               file_read_error() << \r
+                               msg_info("Could not open audio codec") <<\r
+                               boost::errinfo_api_function("avcodec_open") <<\r
+                               boost::errinfo_errno(AVUNERROR(errn)) <<\r
+                               boost::errinfo_file_name(filename_));\r
+               }\r
        }\r
   \r
        void encode_video_frame(const safe_ptr<const core::read_frame>& frame)\r
@@ -248,9 +273,9 @@ public:
 \r
                AVCodecContext* c = video_st_->codec;\r
  \r
-               if (img_convert_ctx_ == nullptr\r
+               if(!img_convert_ctx_\r
                {\r
-                       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);\r
+                       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);\r
                        if (img_convert_ctx_ == nullptr) \r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Cannot initialize the conversion context"));\r
                }\r
@@ -262,84 +287,45 @@ public:
                picture_buf_.resize(avpicture_get_size(c->pix_fmt, format_desc_.width, format_desc_.height));\r
                avpicture_fill(reinterpret_cast<AVPicture*>(local_av_frame.get()), picture_buf_.data(), c->pix_fmt, format_desc_.width, format_desc_.height);\r
 \r
-               sws_scale(img_convert_ctx_, av_frame->data, av_frame->linesize, 0, c->height, local_av_frame->data, local_av_frame->linesize);\r
-                               \r
-               int ret = avcodec_encode_video(c, video_outbuf_.data(), video_outbuf_.size(), local_av_frame.get());\r
+               sws_scale(img_convert_ctx_.get(), av_frame->data, av_frame->linesize, 0, c->height, local_av_frame->data, local_av_frame->linesize);\r
                                \r
-               int errn = -ret;\r
-               if (errn > 0) \r
+               int errn = avcodec_encode_video(c, video_outbuf_.data(), video_outbuf_.size(), local_av_frame.get());\r
+               if (errn < 0) \r
+               {\r
                        BOOST_THROW_EXCEPTION(\r
                                invalid_operation() << \r
                                msg_info("Could not encode video frame.") <<\r
                                boost::errinfo_api_function("avcodec_encode_video") <<\r
-                               boost::errinfo_errno(errn) <<\r
+                               boost::errinfo_errno(AVUNERROR(errn)) <<\r
                                boost::errinfo_file_name(filename_));\r
+               }\r
 \r
-               auto out_size = ret;\r
                AVPacket pkt;\r
                av_init_packet(&pkt);\r
-               pkt.size = out_size;\r
+               pkt.size = errn;\r
 \r
                // If zero size, it means the image was buffered.\r
-               if (out_size > 0) \r
+               if (errn > 0) \r
                { \r
                        if (c->coded_frame->pts != AV_NOPTS_VALUE)\r
                                pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st_->time_base);\r
+                       \r
                        if(c->coded_frame->key_frame)\r
                                pkt.flags |= AV_PKT_FLAG_KEY;\r
 \r
                        pkt.stream_index = video_st_->index;\r
-                       pkt.data = video_outbuf_.data();\r
+                       pkt.data             = video_outbuf_.data();\r
 \r
                        if (av_interleaved_write_frame(oc_.get(), &pkt) != 0)\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Error while writing video frame"));\r
                }               \r
        }\r
-\r
-       AVStream* add_audio_stream(enum CodecID codec_id)\r
-       {\r
-               audio_st_ = av_new_stream(oc_.get(), 1);\r
-               if (!audio_st_)\r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not alloc stream"));\r
-\r
-               auto c = audio_st_->codec;\r
-               c->codec_id = codec_id;\r
-               c->codec_type = AVMEDIA_TYPE_AUDIO;\r
-\r
-               // Put sample parameters.\r
-               c->bit_rate = 192000;\r
-               c->sample_rate = 48000;\r
-               c->channels = 2;\r
-\r
-               // Some formats want stream headers to be separate.\r
-               if(oc_->oformat->flags & AVFMT_GLOBALHEADER)\r
-                       c->flags |= CODEC_FLAG_GLOBAL_HEADER;\r
-\r
-               return audio_st_;\r
-       }\r
-\r
-       void open_audio(AVStream* st)\r
-       {\r
-               auto c = st->codec;\r
-\r
-               // Find the audio encoder.\r
-               auto codec = avcodec_find_encoder(c->codec_id);\r
-               if (!codec) \r
-                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found"));\r
                \r
-               // Open it.\r
-               int errn = 0;\r
-               if ((errn = -avcodec_open(c, codec)) > 0)\r
-                       BOOST_THROW_EXCEPTION(\r
-                               file_read_error() << \r
-                               msg_info("Could not open audio codec") <<\r
-                               boost::errinfo_api_function("avcodec_open") <<\r
-                               boost::errinfo_errno(errn) <<\r
-                               boost::errinfo_file_name(filename_));\r
-       }\r
-       \r
        void encode_audio_frame(const safe_ptr<const core::read_frame>& frame)\r
        {       \r
+               if(!audio_st_)\r
+                       return;\r
+\r
                if(!frame->audio_data().empty())\r
                        audio_input_buffer_.insert(audio_input_buffer_.end(), frame->audio_data().begin(), frame->audio_data().end());\r
                else\r
@@ -350,9 +336,6 @@ public:
 \r
        bool encode_audio_packet()\r
        {               \r
-               if(!audio_st_)\r
-                       return false;\r
-\r
                auto c = audio_st_->codec;\r
 \r
                auto frame_bytes = c->frame_size * 2 * 2; // samples per frame * 2 channels * 2 bytes per sample\r
@@ -362,25 +345,26 @@ public:
                AVPacket pkt;\r
                av_init_packet(&pkt);\r
                \r
-               int ret = avcodec_encode_audio(c, audio_outbuf_.data(), audio_outbuf_.size(), audio_input_buffer_.data());\r
-               \r
-               int errn = -ret;\r
-               if (errn > 0) \r
+               int errn = avcodec_encode_audio(c, audio_outbuf_.data(), audio_outbuf_.size(), audio_input_buffer_.data());\r
+               if (errn < 0) \r
+               {\r
                        BOOST_THROW_EXCEPTION(\r
                                invalid_operation() << \r
                                msg_info("Could not encode audio samples.") <<\r
                                boost::errinfo_api_function("avcodec_encode_audio") <<\r
-                               boost::errinfo_errno(errn) <<\r
+                               boost::errinfo_errno(AVUNERROR(errn)) <<\r
                                boost::errinfo_file_name(filename_));\r
+               }\r
 \r
-               pkt.size = ret;\r
-               audio_input_buffer_ = std::vector<short, tbb::cache_aligned_allocator<short>>(audio_input_buffer_.begin() + frame_bytes/2, audio_input_buffer_.end());\r
+               pkt.size = errn;\r
+               audio_input_buffer_ = std::vector<int16_t>(audio_input_buffer_.begin() + frame_bytes/2, audio_input_buffer_.end());\r
 \r
                if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)\r
                        pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_st_->time_base);\r
-               pkt.flags |= AV_PKT_FLAG_KEY;\r
+\r
+               pkt.flags                |= AV_PKT_FLAG_KEY;\r
                pkt.stream_index = audio_st_->index;\r
-               pkt.data = audio_outbuf_.data();\r
+               pkt.data                 = audio_outbuf_.data();\r
                \r
                if (av_interleaved_write_frame(oc_.get(), &pkt) != 0)\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Error while writing audio frame"));\r
@@ -390,12 +374,10 @@ public:
         \r
        void send(const safe_ptr<const core::read_frame>& frame)\r
        {\r
-               active_.get();\r
-               active_ = executor_.begin_invoke([=]\r
+               executor_.begin_invoke([=]\r
                {                               \r
-                       auto my_frame = frame;\r
-                       encode_video_frame(my_frame);\r
-                       encode_audio_frame(my_frame);\r
+                       encode_video_frame(frame);\r
+                       encode_audio_frame(frame);\r
                });\r
        }\r
 \r
@@ -406,18 +388,20 @@ struct ffmpeg_consumer_proxy : public core::frame_consumer
 {\r
        const std::wstring filename_;\r
        const bool key_only_;\r
+       const size_t bitrate_;\r
 \r
        std::unique_ptr<ffmpeg_consumer> consumer_;\r
 \r
 public:\r
 \r
-       ffmpeg_consumer_proxy(const std::wstring& filename, bool key_only)\r
+       ffmpeg_consumer_proxy(const std::wstring& filename, bool key_only, size_t bitrate)\r
                : filename_(filename)\r
-               , key_only_(key_only){}\r
+               , key_only_(key_only)\r
+               , bitrate_(bitrate){}\r
        \r
        virtual void initialize(const core::video_format_desc& format_desc)\r
        {\r
-               consumer_.reset(new ffmpeg_consumer(narrow(filename_), format_desc));\r
+               consumer_.reset(new ffmpeg_consumer(narrow(filename_), format_desc, bitrate_));\r
        }\r
        \r
        virtual void send(const safe_ptr<const core::read_frame>& frame)\r
@@ -434,6 +418,11 @@ public:
        {\r
                return key_only_;\r
        }\r
+       \r
+       virtual bool has_synchronization_clock() const \r
+       {\r
+               return false;\r
+       }\r
 \r
        virtual const core::video_format_desc& get_video_format_desc() const\r
        {\r
@@ -450,15 +439,16 @@ safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const std::vector<std::wst
        boost::filesystem::remove(boost::filesystem::wpath(env::media_folder() + params[1])); // Delete the file if it exists\r
        bool key_only = std::find(params.begin(), params.end(), L"KEY_ONLY") != params.end();\r
 \r
-       return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + params[1], key_only);\r
+       return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + params[1], key_only, 100000000);\r
 }\r
 \r
 safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const boost::property_tree::ptree& ptree)\r
 {\r
-       std::string filename = ptree.get<std::string>("filename");\r
+       std::string filename = ptree.get<std::string>("path");\r
        bool key_only            = ptree.get("key-only", false);\r
+       size_t bitrate           = ptree.get("bitrate", 100000000);\r
        \r
-       return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + widen(filename), key_only);\r
+       return make_safe<ffmpeg_consumer_proxy>(env::media_folder() + widen(filename), key_only, bitrate);\r
 }\r
 \r
 }\r
index 3cc9c75625a300386b03fd39992a116b8e97c97a..decc821a88210a00da6236466c98b614d2333496 100644 (file)
@@ -29,7 +29,7 @@
 \r
 namespace caspar { \r
        \r
-//safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const std::vector<std::wstring>& params);\r
-//safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const boost::property_tree::ptree& ptree);\r
+safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const std::vector<std::wstring>& params);\r
+safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const boost::property_tree::ptree& ptree);\r
 \r
 }
\ No newline at end of file
index b4727512347988a5a4e85e466c74c8f78a855b21..21490a92d500eab86a191e7e7ffa527e76ccbd3c 100644 (file)
@@ -46,7 +46,7 @@ void init_ffmpeg()
        av_register_all();\r
        avcodec_init();\r
        \r
-       //core::register_consumer_factory([](const std::vector<std::wstring>& params){return create_ffmpeg_consumer(params);});\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
 }\r
 \r
index 5b27feb4748f7e74c9129f6ccbcbadfde4535611..623f7065b259524b6e4f5d07224a9d7ae206bdae 100644 (file)
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../StdAfx.h</PrecompiledHeaderFile>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="ffmpeg.cpp" />\r
     <ClCompile Include="producer\audio\audio_decoder.cpp">\r
index 1eb540b125ead5ebcda2607fb1c4d88112f585ad..a89c0fb94083d35c3194bcbaf11a2438d65c0d88 100644 (file)
@@ -36,7 +36,6 @@
 \r
 #include <windows.h>\r
 #include <atlbase.h>\r
-#include <conio.h>\r
 \r
 #include <core/mixer/gpu/ogl_device.h>\r
 \r
@@ -242,7 +241,6 @@ int main(int argc, wchar_t* argv[])
        \r
        CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";\r
        Sleep(100); // CAPSAR_LOG is asynchronous. Try to get text in correct order.\r
-       std::wcout << L"Press Any Key To Exit.\n";\r
-       _getwch();\r
+       system("pause");\r
        return 0;\r
 }
\ No newline at end of file
index 52ac618a5b14fdece040e54a5930ff21c708399a..d094fdf8dfb7b84d7ab3af754d69994099c5d498 100644 (file)
@@ -112,8 +112,8 @@ struct server::implementation : boost::noncopyable
                                                channels_.back()->output()->add(index++, create_bluefish_consumer(xml_consumer.second));                                        \r
                                        else if(name == "decklink")                                     \r
                                                channels_.back()->output()->add(index++, create_decklink_consumer(xml_consumer.second));                                \r
-                                       //else if(name == "file")                                       \r
-                                       //      channels_.back()->output()->add(index++, create_ffmpeg_consumer(xml_consumer.second));                                          \r
+                                       else if(name == "file")                                 \r
+                                               channels_.back()->output()->add(index++, create_ffmpeg_consumer(xml_consumer.second));                                          \r
                                        else if(name == "audio")\r
                                                channels_.back()->output()->add(index++, make_safe<oal_consumer>());            \r
                                        else if(name != "<xmlcomment>")\r