]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 1 Dec 2011 11:39:31 +0000 (11:39 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 1 Dec 2011 11:39:31 +0000 (11:39 +0000)
modules/ffmpeg/consumer/ffmpeg_consumer.cpp

index 674c7720af3c1e69469882b8d704136ea460faa3..66bc664cfe16c5bcecacbdf99c1f60fdebc39afd 100644 (file)
@@ -53,7 +53,8 @@ extern "C"
        #define __STDC_CONSTANT_MACROS\r
        #define __STDC_LIMIT_MACROS\r
        #include <libavformat/avformat.h>\r
-       #include <libswscale/swscale.h>\r
+       #include <libswscale/swscale.h>
+       #include <libavutil/opt.h>\r
 }\r
 #if defined(_MSC_VER)\r
 #pragma warning (pop)\r
@@ -87,6 +88,8 @@ struct ffmpeg_consumer : boost::noncopyable
 \r
        std::vector<uint8_t>                                    picture_buf_;\r
        std::shared_ptr<SwsContext>                             img_convert_ctx_;\r
+\r
+       int64_t                                                                 frame_number_;\r
        \r
 public:\r
        ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc, const std::string& codec, int bitrate)\r
@@ -97,6 +100,7 @@ public:
                , format_desc_(format_desc)\r
                , executor_(print())\r
                , file_write_executor_(print() + L"/output")\r
+               , frame_number_(0)\r
        {\r
                graph_->add_guide("frame-time", 0.5);\r
                graph_->set_color("frame-time", diagnostics::color(0.1f, 1.0f, 0.1f));\r
@@ -182,56 +186,56 @@ public:
                                << boost::errinfo_api_function("av_new_stream"));\r
                }\r
 \r
+               auto encoder = avcodec_find_encoder(codec_id);\r
+               if (!encoder)\r
+                       BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("codec not found"));\r
+\r
+               auto c = st->codec;\r
+\r
+               avcodec_get_context_defaults3(c, encoder);\r
+\r
                bitrate *= 1000000;\r
                \r
-               st->codec->codec_id                     = codec_id;\r
-               st->codec->bit_rate                     = bitrate > 0 ? bitrate : format_desc_.width < 1280 ? 63*1000000 : 220*1000000;\r
-               st->codec->codec_type           = AVMEDIA_TYPE_VIDEO;\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
-\r
-               if(st->codec->codec_id == CODEC_ID_PRORES)\r
+               c->codec_id                     = codec_id;\r
+               c->bit_rate                     = bitrate > 0 ? bitrate : format_desc_.width < 1280 ? 63*1000000 : 220*1000000;\r
+               c->codec_type           = AVMEDIA_TYPE_VIDEO;\r
+               c->width                        = format_desc_.width;\r
+               c->height                       = format_desc_.height;\r
+               c->time_base.den        = format_desc_.time_scale;\r
+               c->time_base.num        = format_desc_.duration;\r
+               c->gop_size                     = 25;\r
+\r
+               if(c->codec_id == CODEC_ID_PRORES)\r
                {                       \r
-                       st->codec->bit_rate     = bitrate > 0 ? bitrate : format_desc_.width < 1280 ? 42*1000000 : 147*1000000;\r
-                       st->codec->pix_fmt      = PIX_FMT_YUV422P10;\r
+                       c->bit_rate     = bitrate > 0 ? bitrate : format_desc_.width < 1280 ? 42*1000000 : 147*1000000;\r
+                       c->pix_fmt      = PIX_FMT_YUV422P10;\r
                }\r
-               else if(st->codec->codec_id == CODEC_ID_DNXHD)\r
+               else if(c->codec_id == CODEC_ID_DNXHD)\r
                {\r
                        if(format_desc_.width < 1280 || format_desc_.height < 720)\r
                                BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("unsupported dimension"));\r
 \r
-                       st->codec->bit_rate     = bitrate > 0 ? bitrate : 220*1000000;\r
-                       st->codec->pix_fmt      = PIX_FMT_YUV422P;\r
+                       c->bit_rate     = bitrate > 0 ? bitrate : 220*1000000;\r
+                       c->pix_fmt      = PIX_FMT_YUV422P;\r
                }\r
-               else if(st->codec->codec_id == CODEC_ID_DVVIDEO)\r
+               else if(c->codec_id == CODEC_ID_DVVIDEO)\r
                {\r
-                       st->codec->bit_rate     = bitrate > 0 ? bitrate : format_desc_.width < 1280 ? 50*1000000 : 100*1000000;\r
-                       st->codec->pix_fmt      = PIX_FMT_YUV422P;\r
+                       c->bit_rate     = bitrate > 0 ? bitrate : format_desc_.width < 1280 ? 50*1000000 : 100*1000000;\r
+                       c->pix_fmt      = PIX_FMT_YUV422P;\r
                }\r
                //else if(st->codec->codec_id == CODEC_ID_H264)\r
-               //{                     \r
-               //      st->codec->pix_fmt              = PIX_FMT_YUV422P;\r
-               //      st->codec->me_range             = 16;\r
-               //      st->codec->max_qdiff    = 4;\r
-               //      st->codec->qmin                 = 10;\r
-               //      st->codec->qmax                 = 51;\r
-               //      st->codec->qcompress    = 0.6;\r
-               //      st->codec->gop_size             = 25;\r
+               //{                        \r
+               //      c->pix_fmt = PIX_FMT_YUV422P;    
+               //      THROW_ON_ERROR2(av_opt_set(c->priv_data, "preset", "slow", 0), "[ffmpeg_consumer]");\r
                //}\r
                else\r
                        BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("unsupported codec"));\r
                \r
                if(oc_->oformat->flags & AVFMT_GLOBALHEADER)\r
-                       st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;\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
-               st->codec->thread_count = boost::thread::hardware_concurrency();\r
-               THROW_ON_ERROR2(avcodec_open(st->codec, codec), "[ffmpeg_consumer]");\r
+                       c->flags |= CODEC_FLAG_GLOBAL_HEADER;\r
+               \r
+               c->thread_count = boost::thread::hardware_concurrency();\r
+               THROW_ON_ERROR2(avcodec_open(c, encoder), "[ffmpeg_consumer]");\r
 \r
                return std::shared_ptr<AVStream>(st, [](AVStream* st)\r
                {\r
@@ -287,6 +291,7 @@ public:
                std::shared_ptr<AVFrame> local_av_frame(avcodec_alloc_frame(), av_free);\r
                local_av_frame->interlaced_frame = format_desc_.field_mode != core::field_mode::progressive;\r
                local_av_frame->top_field_first  = format_desc_.field_mode == core::field_mode::upper;\r
+               local_av_frame->pts                              = (frame_number_ * video_st_->time_base.den) * video_st_->time_base.num;\r
 \r
                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
@@ -360,6 +365,7 @@ public:
                                        av_write_frame(oc_.get(), video.get());\r
                                if(audio)\r
                                        av_write_frame(oc_.get(), audio.get());\r
+                               ++frame_number_;\r
                                graph_->update_value("write-time", write_timer_.elapsed()*format_desc_.fps*0.5);\r
                        });\r
                });\r
@@ -427,6 +433,9 @@ safe_ptr<core::frame_consumer> create_ffmpeg_consumer(const std::vector<std::wst
        if(codec_it != params.end() && codec_it++ != params.end())\r
                codec = narrow(*codec_it);\r
 \r
+       if(codec == "H264" || codec == "h264")\r
+               codec = "libx264";\r
+\r
        int bitrate = 0;        \r
        auto bitrate_it = std::find(params.begin(), params.end(), L"BITRATE");\r
        if(bitrate_it != params.end() && bitrate_it++ != params.end())\r