X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fffmpeg%2Fconsumer%2Fffmpeg_consumer.cpp;h=20a30cd839cf7c76aac537cce9d4b041b9604b04;hb=9e4b08cde6c6de9e83a3fff42d90affc3cd8e5bc;hp=eff99a64a26057e8bed0d0cdb2e69bddf4a3601c;hpb=8c61df76c4b35ab58316f35b6a09a3f977efd596;p=casparcg diff --git a/modules/ffmpeg/consumer/ffmpeg_consumer.cpp b/modules/ffmpeg/consumer/ffmpeg_consumer.cpp index eff99a64a..20a30cd83 100644 --- a/modules/ffmpeg/consumer/ffmpeg_consumer.cpp +++ b/modules/ffmpeg/consumer/ffmpeg_consumer.cpp @@ -18,7 +18,7 @@ * * Author: Robert Nagy, ronag89@gmail.com */ - + #include "../StdAfx.h" #include "../ffmpeg_error.h" @@ -26,25 +26,32 @@ #include "ffmpeg_consumer.h" #include "../producer/tbb_avcodec.h" +#include "../producer/util/util.h" #include +#include #include #include #include +#include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include +#include +#include #include -#include #include #include #include @@ -54,12 +61,13 @@ #include #include +#include #if defined(_MSC_VER) #pragma warning (push) #pragma warning (disable : 4244) #endif -extern "C" +extern "C" { #define __STDC_CONSTANT_MACROS #define __STDC_LIMIT_MACROS @@ -76,23 +84,23 @@ extern "C" #endif namespace caspar { namespace ffmpeg { - + int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { AVClass* av_class = *(AVClass**)obj; if((strcmp(name, "pix_fmt") == 0 || strcmp(name, "pixel_format") == 0) && strcmp(av_class->class_name, "AVCodecContext") == 0) { - AVCodecContext* c = (AVCodecContext*)obj; + AVCodecContext* c = (AVCodecContext*)obj; auto pix_fmt = av_get_pix_fmt(val); if(pix_fmt == PIX_FMT_NONE) - return -1; + return -1; c->pix_fmt = pix_fmt; return 0; } //if((strcmp(name, "r") == 0 || strcmp(name, "frame_rate") == 0) && strcmp(av_class->class_name, "AVCodecContext") == 0) //{ - // AVCodecContext* c = (AVCodecContext*)obj; + // AVCodecContext* c = (AVCodecContext*)obj; // if(c->codec_type != AVMEDIA_TYPE_VIDEO) // return -1; @@ -121,14 +129,14 @@ struct option { } }; - + struct output_format { AVOutputFormat* format; int width; int height; - CodecID vcodec; - CodecID acodec; + AVCodecID vcodec; + AVCodecID acodec; int croptop; int cropbot; @@ -148,26 +156,26 @@ struct output_format { return set_opt(o.name, o.value); }); - + if(vcodec == CODEC_ID_NONE && format) vcodec = format->video_codec; if(acodec == CODEC_ID_NONE && format) acodec = format->audio_codec; - + if(vcodec == CODEC_ID_NONE) vcodec = CODEC_ID_H264; - + if(acodec == CODEC_ID_NONE) acodec = CODEC_ID_PCM_S16LE; } - + bool set_opt(const std::string& name, const std::string& value) { //if(name == "target") - //{ + //{ // enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN; - // + // // if(name.find("pal-") != std::string::npos) // norm = PAL; // else if(name.find("ntsc-") != std::string::npos) @@ -175,8 +183,8 @@ struct output_format // if(norm == UNKNOWN) // CASPAR_THROW_EXCEPTION(invalid_argument() << arg_name_info("target")); - // - // if (name.find("-dv") != std::string::npos) + // + // if (name.find("-dv") != std::string::npos) // { // set_opt("f", "dv"); // if(norm == PAL) @@ -193,17 +201,17 @@ struct output_format // } // } // set_opt("s", norm == PAL ? "720x576" : "720x480"); - // } + // } // return true; //} - //else + //else if(name == "f") { format = av_guess_format(value.c_str(), nullptr, nullptr); if(format == nullptr) - CASPAR_THROW_EXCEPTION(invalid_argument() << arg_name_info("f")); + CASPAR_THROW_EXCEPTION(user_error() << msg_info("Unknown format " + value)); return true; } @@ -211,7 +219,7 @@ struct output_format { auto c = avcodec_find_encoder_by_name(value.c_str()); if(c == nullptr) - CASPAR_THROW_EXCEPTION(invalid_argument() << arg_name_info("vcodec")); + CASPAR_THROW_EXCEPTION(user_error() << msg_info("Unknown video codec " + value)); vcodec = avcodec_find_encoder_by_name(value.c_str())->id; return true; @@ -221,7 +229,7 @@ struct output_format { auto c = avcodec_find_encoder_by_name(value.c_str()); if(c == nullptr) - CASPAR_THROW_EXCEPTION(invalid_argument() << arg_name_info("acodec")); + CASPAR_THROW_EXCEPTION(user_error() << msg_info("Unknown audio codec " + value)); acodec = avcodec_find_encoder_by_name(value.c_str())->id; @@ -230,8 +238,8 @@ struct output_format else if(name == "s") { if(av_parse_video_size(&width, &height, value.c_str()) < 0) - CASPAR_THROW_EXCEPTION(invalid_argument() << arg_name_info("s")); - + CASPAR_THROW_EXCEPTION(user_error() << msg_info("Unknown video size " + value)); + return true; } else if(name == "croptop") @@ -246,85 +254,97 @@ struct output_format return true; } - + return false; } }; -typedef std::vector> byte_vector; +typedef cache_aligned_vector byte_vector; struct ffmpeg_consumer : boost::noncopyable -{ +{ const spl::shared_ptr graph_; - const std::string filename_; - const std::shared_ptr oc_; - const core::video_format_desc format_desc_; + const std::string filename_; + const std::string full_filename_ = u8(env::media_folder()) + filename_; + const std::shared_ptr oc_ { avformat_alloc_context(), avformat_free_context }; + const core::video_format_desc format_desc_; + const core::audio_channel_layout channel_layout_; + + core::monitor::subject monitor_subject_; - monitor::basic_subject event_subject_; - tbb::spin_mutex exception_mutex_; std::exception_ptr exception_; - + std::shared_ptr audio_st_; std::shared_ptr video_st_; - + byte_vector picture_buffer_; + byte_vector key_picture_buf_; byte_vector audio_buffer_; std::shared_ptr swr_; std::shared_ptr sws_; - int64_t frame_number_; + int64_t frame_number_ = 0; output_format output_format_; - + bool key_only_; + tbb::atomic current_encoding_delay_; + executor executor_; public: - ffmpeg_consumer(const std::string& filename, const core::video_format_desc& format_desc, std::vector