X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=shared%2Fmux.cpp;fp=nageru%2Fmux.cpp;h=da618e0c6bbc1066ef4c3db110f935c48c0bde45;hb=131a051c4cd3719a9be415386fdf0f4e15da7c66;hp=cb4d0bad5179786feffa919f2fbb515b701a6313;hpb=7188e3e948c60f78f5e2cd8756337f716de06d99;p=nageru diff --git a/nageru/mux.cpp b/shared/mux.cpp similarity index 88% rename from nageru/mux.cpp rename to shared/mux.cpp index cb4d0ba..da618e0 100644 --- a/nageru/mux.cpp +++ b/shared/mux.cpp @@ -1,12 +1,12 @@ -#include "mux.h" +#include "shared/mux.h" +#include #include +#include #include #include #include #include -#include -#include #include #include #include @@ -21,9 +21,8 @@ extern "C" { #include } -#include "defs.h" -#include "flags.h" -#include "metrics.h" +#include "shared/metrics.h" +#include "shared/mux_opts.h" #include "shared/timebase.h" using namespace std; @@ -48,7 +47,7 @@ struct PacketBefore { const AVFormatContext * const ctx; }; -Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const string &video_extradata, const AVCodecParameters *audio_codecpar, int time_base, std::function write_callback, WriteStrategy write_strategy, const vector &metrics) +Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const string &video_extradata, const AVCodecParameters *audio_codecpar, AVColorSpace color_space, WithAudio with_audio, int time_base, function write_callback, WriteStrategy write_strategy, const vector &metrics) : write_strategy(write_strategy), avctx(avctx), write_callback(write_callback), metrics(metrics) { avstream_video = avformat_new_stream(avctx, nullptr); @@ -60,10 +59,12 @@ Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const avstream_video->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; if (video_codec == CODEC_H264) { avstream_video->codecpar->codec_id = AV_CODEC_ID_H264; - } else { - assert(video_codec == CODEC_NV12); + } else if (video_codec == CODEC_NV12) { avstream_video->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; avstream_video->codecpar->codec_tag = avcodec_pix_fmt_to_codec_tag(AV_PIX_FMT_NV12); + } else { + assert(video_codec == CODEC_MJPEG); + avstream_video->codecpar->codec_id = AV_CODEC_ID_MJPEG; } avstream_video->codecpar->width = width; avstream_video->codecpar->height = height; @@ -77,11 +78,7 @@ Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const avstream_video->codecpar->color_primaries = AVCOL_PRI_BT709; // RGB colorspace (inout_format.color_space). avstream_video->codecpar->color_trc = AVCOL_TRC_IEC61966_2_1; // Gamma curve (inout_format.gamma_curve). // YUV colorspace (output_ycbcr_format.luma_coefficients). - if (global_flags.ycbcr_rec709_coefficients) { - avstream_video->codecpar->color_space = AVCOL_SPC_BT709; - } else { - avstream_video->codecpar->color_space = AVCOL_SPC_SMPTE170M; - } + avstream_video->codecpar->color_space = color_space; avstream_video->codecpar->color_range = AVCOL_RANGE_MPEG; // Full vs. limited range (output_ycbcr_format.full_range). avstream_video->codecpar->chroma_location = AVCHROMA_LOC_LEFT; // Chroma sample location. See chroma_offset_0[] in Mixer::subsample_chroma(). avstream_video->codecpar->field_order = AV_FIELD_PROGRESSIVE; @@ -92,15 +89,20 @@ Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const memcpy(avstream_video->codecpar->extradata, video_extradata.data(), video_extradata.size()); } - avstream_audio = avformat_new_stream(avctx, nullptr); - if (avstream_audio == nullptr) { - fprintf(stderr, "avformat_new_stream() failed\n"); - exit(1); - } - avstream_audio->time_base = AVRational{1, time_base}; - if (avcodec_parameters_copy(avstream_audio->codecpar, audio_codecpar) < 0) { - fprintf(stderr, "avcodec_parameters_copy() failed\n"); - exit(1); + if (with_audio == WITH_AUDIO) { + avstream_audio = avformat_new_stream(avctx, nullptr); + if (avstream_audio == nullptr) { + fprintf(stderr, "avformat_new_stream() failed\n"); + exit(1); + } + avstream_audio->time_base = AVRational{1, time_base}; + if (avcodec_parameters_copy(avstream_audio->codecpar, audio_codecpar) < 0) { + fprintf(stderr, "avcodec_parameters_copy() failed\n"); + exit(1); + } + } else { + assert(with_audio == WITHOUT_AUDIO); + avstream_audio = nullptr; } AVDictionary *options = NULL; @@ -172,7 +174,8 @@ void Mux::add_packet(const AVPacket &pkt, int64_t pts, int64_t dts, AVRational t lock_guard lock(mu); if (write_strategy == WriteStrategy::WRITE_BACKGROUND) { packet_queue.push_back(QueuedPacket{ av_packet_clone(&pkt_copy), pts }); - if (plug_count == 0) packet_queue_ready.notify_all(); + if (plug_count == 0) + packet_queue_ready.notify_all(); } else if (plug_count > 0) { packet_queue.push_back(QueuedPacket{ av_packet_clone(&pkt_copy), pts }); } else { @@ -197,7 +200,7 @@ void Mux::write_packet_or_die(const AVPacket &pkt, int64_t unscaled_pts) int64_t old_pos = avctx->pb->pos; if (av_interleaved_write_frame(avctx, const_cast(&pkt)) < 0) { fprintf(stderr, "av_interleaved_write_frame() failed\n"); - exit(1); + abort(); } avio_flush(avctx->pb); for (MuxMetrics *metric : metrics) { @@ -238,6 +241,8 @@ void Mux::unplug() void Mux::thread_func() { + pthread_setname_np(pthread_self(), "Mux"); + unique_lock lock(mu); for ( ;; ) { packet_queue_ready.wait(lock, [this]() {