]> git.sesse.net Git - casparcg/commitdiff
2.0.2: frame_muxer: Fixed incorrect frame format overwrite.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 26 Nov 2011 01:47:23 +0000 (01:47 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 26 Nov 2011 01:47:23 +0000 (01:47 +0000)
       filter: Added a libavfilter frame format bug workaround.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.2@1666 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/audio/audio_mixer.cpp
modules/ffmpeg/ffmpeg.cpp
modules/ffmpeg/producer/filter/filter.cpp
modules/ffmpeg/producer/muxer/frame_muxer.cpp
modules/ffmpeg/producer/util/util.cpp

index f4e3e2463d671ccae97889eeb5fa848d1575553e..627826b052962772ea8f5d70f88e5fb38e3573a1 100644 (file)
@@ -79,8 +79,8 @@ public:
        \r
        audio_buffer mix(const video_format_desc& format_desc)\r
        {       \r
-               CASPAR_ASSERT(format_desc.audio_channels == 2);\r
-               CASPAR_ASSERT(format_desc.audio_samples_per_frame % 4 == 0);\r
+               //CASPAR_ASSERT(format_desc.audio_channels == 2);\r
+               //CASPAR_ASSERT(format_desc.audio_samples_per_frame % 4 == 0);\r
 \r
                // NOTE: auto data should be larger than format_desc_.audio_samples_per_frame to allow sse to read/write beyond size.\r
 \r
index 87e1e00833d8308f08941dcb4e6e5eeddc33b14c..cdbccb3f521a38c6d99a1902a954d4b340077027 100644 (file)
@@ -151,9 +151,49 @@ void log_callback(void* ptr, int level, const char* fmt, va_list vl)
     //colored_fputs(av_clip(level>>3, 0, 6), line);\r
 }\r
 \r
+//static int query_yadif_formats(AVFilterContext *ctx)
+//{
+//    static const int pix_fmts[] = {
+//        PIX_FMT_YUV444P,
+//        PIX_FMT_YUV422P,
+//        PIX_FMT_YUV420P,
+//        PIX_FMT_YUV410P,
+//        PIX_FMT_YUV411P,
+//        PIX_FMT_GRAY8,
+//        PIX_FMT_YUVJ444P,
+//        PIX_FMT_YUVJ422P,
+//        PIX_FMT_YUVJ420P,
+//        AV_NE( PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE ),
+//        PIX_FMT_YUV440P,
+//        PIX_FMT_YUVJ440P,
+//        AV_NE( PIX_FMT_YUV444P16BE, PIX_FMT_YUV444P16LE ),
+//        AV_NE( PIX_FMT_YUV422P16BE, PIX_FMT_YUV422P16LE ),
+//        AV_NE( PIX_FMT_YUV420P16BE, PIX_FMT_YUV420P16LE ),
+//        PIX_FMT_YUVA420P,
+//        PIX_FMT_NONE
+//    };
+//    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
+//
+//    return 0;
+//}\r
+//\r
+//#pragma warning (push)\r
+//#pragma warning (disable : 4706)\r
+//void fix_yadif_filter_format_query()\r
+//{\r
+//     AVFilter** filter = nullptr;
+//    while((filter = av_filter_next(filter)) && *filter)\r
+//     {\r
+//             if(strstr((*filter)->name, "yadif") != 0)\r
+//                     (*filter)->query_formats = query_yadif_formats;\r
+//     }\r
+//}\r
+//#pragma warning (pop)\r
+\r
 void init()\r
 {\r
     avfilter_register_all();\r
+       //fix_yadif_filter_format_query();\r
        av_register_all();\r
        avcodec_init();\r
     avcodec_register_all();\r
index c25de7db47c7550c10dec8c3bc8c1ed96dce2820..cb5ee7bec700f464a6fd7c3ad842ac0bde8c23b1 100644 (file)
@@ -42,18 +42,22 @@ struct filter::implementation
        std::shared_ptr<void>                   parallel_yadif_ctx_;\r
        std::vector<PixelFormat>                pix_fmts_;\r
        std::queue<std::shared_ptr<AVFrame>> bypass_;\r
+       int                                                             in_format_;\r
+       bool                                                    warned_;\r
                \r
        implementation(const std::wstring& filters, const std::vector<PixelFormat>& pix_fmts) \r
                : filters_(narrow(filters))\r
                , parallel_yadif_ctx_(nullptr)\r
                , pix_fmts_(pix_fmts)\r
+               , in_format_(0)\r
+               , warned_(false)\r
        {\r
                if(pix_fmts_.empty())\r
                {\r
-                       pix_fmts_.push_back(PIX_FMT_YUV420P);\r
                        pix_fmts_.push_back(PIX_FMT_YUVA420P);\r
-                       pix_fmts_.push_back(PIX_FMT_YUV422P);\r
                        pix_fmts_.push_back(PIX_FMT_YUV444P);\r
+                       pix_fmts_.push_back(PIX_FMT_YUV422P);\r
+                       pix_fmts_.push_back(PIX_FMT_YUV420P);\r
                        pix_fmts_.push_back(PIX_FMT_YUV411P);\r
                        pix_fmts_.push_back(PIX_FMT_ARGB);\r
                        pix_fmts_.push_back(PIX_FMT_RGBA);\r
@@ -87,6 +91,7 @@ struct filter::implementation
                        {\r
                                try\r
                                {\r
+                                       in_format_ = frame->format;\r
                                        graph_.reset(avfilter_graph_alloc(), [](AVFilterGraph* p){avfilter_graph_free(&p);});\r
                                                                \r
                                        // Input\r
@@ -187,6 +192,23 @@ struct filter::implementation
                                        frame->pict_type                        = picref->video->pict_type;\r
                                        frame->sample_aspect_ratio      = picref->video->sample_aspect_ratio;\r
 \r
+                                       // HACK: Workaround for missing format bug in libavfilter.\r
+                                       if(frame->format == 0)\r
+                                       {\r
+                                               if(in_format_ == PIX_FMT_YUV444P10)\r
+                                                       frame->format = PIX_FMT_YUV420P;//PIX_FMT_YUV444P;\r
+                                               else if(in_format_ == PIX_FMT_YUV422P10)\r
+                                                       frame->format = PIX_FMT_YUV420P;//PIX_FMT_YUV422P;\r
+                                               else\r
+                                                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("libavfilter bug: Mframe format == 0."));\r
+                                               \r
+                                               if(!warned_)\r
+                                               {\r
+                                                       CASPAR_LOG(warning) << "[ffmpeg] libavfilter bug workaround: frame format == 0, guessing PIX_FMT_YUV420P.";\r
+                                                       warned_ = true;\r
+                                               }\r
+                                       }\r
+\r
                                        return frame;\r
                                }\r
                        }\r
index 0335f64273daf5dd0ecf7c79d74c3c45a8bf34af..3f5deef5cbe15d10fed8e4f6962ce2278acee82a 100644 (file)
@@ -108,7 +108,9 @@ struct frame_muxer::implementation : boost::noncopyable
                        filter_.push(video_frame);\r
                        BOOST_FOREACH(auto& av_frame, filter_.poll_all())\r
                        {\r
-                               av_frame->format = format;\r
+                               if(video_frame->format == PIX_FMT_GRAY8 && format == CASPAR_PIX_FMT_LUMA)\r
+                                       av_frame->format = format;\r
+\r
                                video_streams_.back().push(make_write_frame(this, av_frame, frame_factory_, hints));\r
                                ++video_frame_count_;\r
                        }\r
index 99c7f8008daf4e9bcb0542ff08878c4788a20f15..e74fedc4b3e05be2e3cf7bc7fed91f886ed95698 100644 (file)
@@ -202,8 +202,9 @@ safe_ptr<core::write_frame> make_write_frame(const void* tag, const safe_ptr<AVF
                // Use sws_scale when provided colorspace has no hw-accel.\r
                safe_ptr<AVFrame> av_frame(avcodec_alloc_frame(), av_free);     \r
                avcodec_get_frame_defaults(av_frame.get());                     \r
-               avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), write->image_data().begin(), PIX_FMT_BGRA, width, height);\r
-                \r
+               auto size = avpicture_fill(reinterpret_cast<AVPicture*>(av_frame.get()), write->image_data().begin(), PIX_FMT_BGRA, width, height);\r
+               CASPAR_VERIFY(size == write->image_data().size()); \r
+\r
                sws_scale(sws_context.get(), decoded_frame->data, decoded_frame->linesize, 0, height, av_frame->data, av_frame->linesize);      \r
                pool.push(sws_context);\r
 \r