]> git.sesse.net Git - casparcg/commitdiff
2.0. ffmpeg_producer: Fixed looping issue in filter.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 21 Jun 2011 07:05:30 +0000 (07:05 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 21 Jun 2011 07:05:30 +0000 (07:05 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@931 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/ffmpeg/producer/filter/filter.cpp
modules/ffmpeg/producer/filter/filter.h
modules/ffmpeg/producer/video/video_decoder.cpp

index 04abf815818ab402a91e0e0c57945f0c8de31615..20c8f4f56bf3b574a2d7eb25b77d8d8f704d34e1 100644 (file)
@@ -34,9 +34,13 @@ struct filter::implementation
        std::shared_ptr<AVFilterGraph>                  graph_;\r
        AVFilterContext*                                                video_in_filter_;\r
        AVFilterContext*                                                video_out_filter_;\r
+       size_t                                                                  delay_;\r
+       size_t                                                                  count_;\r
 \r
        implementation(const std::string& filters) \r
                : filters_(filters)\r
+               , delay_(0)\r
+               , count_(0)\r
        {\r
                std::transform(filters_.begin(), filters_.end(), filters_.begin(), ::tolower);\r
        }\r
@@ -104,10 +108,16 @@ struct filter::implementation
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(av_error_str(errn)) <<\r
                                boost::errinfo_api_function("av_vsrc_buffer_add_frame") << boost::errinfo_errno(AVUNERROR(errn)));\r
                }\r
+               ++count_;\r
        }\r
 \r
        std::vector<safe_ptr<AVFrame>> poll()\r
        {\r
+               std::vector<safe_ptr<AVFrame>> result;\r
+\r
+               if(!graph_)\r
+                       return result;\r
+\r
                int errn = avfilter_poll_frame(video_out_filter_->inputs[0]);\r
                if(errn < 0)\r
                {\r
@@ -115,8 +125,13 @@ struct filter::implementation
                                boost::errinfo_api_function("avfilter_poll_frame") << boost::errinfo_errno(AVUNERROR(errn)));\r
                }\r
 \r
-               std::vector<safe_ptr<AVFrame>> result;\r
-\r
+               if(count_ > 0)\r
+               {\r
+                       --count_;\r
+                       if(errn == 0)\r
+                               ++delay_;\r
+               }\r
+               \r
                std::generate_n(std::back_inserter(result), errn, [&]{return request_frame();});\r
 \r
                return result;\r
@@ -164,6 +179,5 @@ struct filter::implementation
 filter::filter(const std::string& filters) : impl_(new implementation(filters)){}\r
 void filter::push(const safe_ptr<AVFrame>& frame) {impl_->push(frame);}\r
 std::vector<safe_ptr<AVFrame>> filter::poll() {return impl_->poll();}\r
-bool filter::is_ready() const{return impl_->graph_ != nullptr;}\r
-\r
+size_t filter::delay() const{return impl_->delay_;}\r
 }
\ No newline at end of file
index d2084fcf45b6cf044871c84cc42de4432783e5f7..c132675c1bc5950849a43cbc83f5366df5b6b4b2 100644 (file)
@@ -15,7 +15,7 @@ public:
 \r
        void push(const safe_ptr<AVFrame>& frame);\r
        std::vector<safe_ptr<AVFrame>> poll();\r
-       bool is_ready() const;\r
+       size_t delay() const;\r
 \r
 private:\r
        struct implementation;\r
index e78fe8619be72faec4a8a02aaa31c6deb5ac2f68..7f5610daf7530d3205c712f99fbdef316c282968 100644 (file)
@@ -62,7 +62,6 @@ struct video_decoder::implementation : boost::noncopyable
        size_t                                                                  frame_number_;\r
 \r
        std::shared_ptr<filter>                                 filter_;\r
-       size_t                                                                  filter_delay_;\r
        int                                                                             eof_count_;\r
 \r
        std::string                                                             filter_str_;\r
@@ -74,7 +73,6 @@ public:
                , codec_context_(*input_.get_video_codec_context())\r
                , frame_number_(0)\r
                , filter_(filter_str.empty() ? nullptr : new filter(filter_str))\r
-               , filter_delay_(1)\r
                , filter_str_(filter_str)\r
                , eof_count_(std::numeric_limits<int>::max())\r
        {\r
@@ -97,7 +95,7 @@ public:
 \r
                if(!video_packet) // eof\r
                {\r
-                       eof_count_ = frame_number_ + (filter_ ? filter_delay_ : 0);\r
+                       eof_count_ = frame_number_ + (filter_ ? filter_->delay()+1 : 0);\r
                        avcodec_flush_buffers(&codec_context_);\r
                        return result;\r
                }               \r
@@ -116,19 +114,14 @@ public:
                                frame = decode_frame(video_packet);\r
                        },\r
                        [&]\r
-                       {\r
-                               if(filter_->is_ready())\r
-                               {                               \r
-                                       boost::range::transform(filter_->poll(), std::back_inserter(result), [&](const safe_ptr<AVFrame>& frame)\r
-                                       {\r
-                                               return std::make_pair(frame_number_, make_write_frame(tag, frame, frame_factory_));\r
-                                       });\r
+                       {               \r
+                               boost::range::transform(filter_->poll(), std::back_inserter(result), [&](const safe_ptr<AVFrame>& frame)\r
+                               {\r
+                                       return std::make_pair(frame_number_, make_write_frame(tag, frame, frame_factory_));\r
+                               });\r
                \r
-                                       if(!result.empty())\r
-                                               ++frame_number_;\r
-                                       else            \r
-                                               ++filter_delay_;\r
-                               }\r
+                               if(!result.empty())\r
+                                       ++frame_number_;\r
                        });             \r
 \r
                        if(frame)\r
@@ -163,7 +156,7 @@ public:
 \r
                if(frame_finished == 0)         \r
                        decoded_frame = nullptr;\r
-\r
+               \r
                return decoded_frame;\r
        }\r
 };\r