X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=shared%2Fmux.cpp;h=e122e2bb32c998556c377291c1d1d513badd9e98;hb=4b84fc30175a4dfb56a25ba0b2f9b88ab54cfe7d;hp=4970bcea81bcd684eb019d5484586d888c757a80;hpb=539609eb56b496e6eff8a5e0a92fa0325936a5d7;p=nageru diff --git a/shared/mux.cpp b/shared/mux.cpp index 4970bce..e122e2b 100644 --- a/shared/mux.cpp +++ b/shared/mux.cpp @@ -47,10 +47,10 @@ 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, AVColorSpace color_space, WithAudio with_audio, int time_base, 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, int time_base, function write_callback, WriteStrategy write_strategy, const vector &metrics, WithSubtitles with_subtitles) : write_strategy(write_strategy), avctx(avctx), write_callback(write_callback), metrics(metrics) { - avstream_video = avformat_new_stream(avctx, nullptr); + AVStream *avstream_video = avformat_new_stream(avctx, nullptr); if (avstream_video == nullptr) { fprintf(stderr, "avformat_new_stream() failed\n"); exit(1); @@ -88,9 +88,10 @@ Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const avstream_video->codecpar->extradata_size = video_extradata.size(); memcpy(avstream_video->codecpar->extradata, video_extradata.data(), video_extradata.size()); } + streams.push_back(avstream_video); - if (with_audio == WITH_AUDIO) { - avstream_audio = avformat_new_stream(avctx, nullptr); + if (audio_codecpar != nullptr) { + AVStream *avstream_audio = avformat_new_stream(avctx, nullptr); if (avstream_audio == nullptr) { fprintf(stderr, "avformat_new_stream() failed\n"); exit(1); @@ -100,9 +101,21 @@ Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const fprintf(stderr, "avcodec_parameters_copy() failed\n"); exit(1); } - } else { - assert(with_audio == WITHOUT_AUDIO); - avstream_audio = nullptr; + streams.push_back(avstream_audio); + } + + if (with_subtitles == WITH_SUBTITLES) { + AVStream *avstream_subtitles = avformat_new_stream(avctx, nullptr); + if (avstream_subtitles == nullptr) { + fprintf(stderr, "avformat_new_stream() failed\n"); + exit(1); + } + avstream_subtitles->time_base = AVRational{1, time_base}; + avstream_subtitles->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; + avstream_subtitles->codecpar->codec_id = AV_CODEC_ID_WEBVTT; + avstream_subtitles->disposition = AV_DISPOSITION_METADATA; + streams.push_back(avstream_subtitles); + subtitle_stream_idx = streams.size() - 1; } AVDictionary *options = NULL; @@ -158,17 +171,11 @@ void Mux::add_packet(const AVPacket &pkt, int64_t pts, int64_t dts, AVRational t if (stream_index_override != -1) { pkt_copy.stream_index = stream_index_override; } - if (pkt_copy.stream_index == 0) { - pkt_copy.pts = av_rescale_q(pts, timebase, avstream_video->time_base); - pkt_copy.dts = av_rescale_q(dts, timebase, avstream_video->time_base); - pkt_copy.duration = av_rescale_q(pkt.duration, timebase, avstream_video->time_base); - } else if (pkt_copy.stream_index == 1) { - pkt_copy.pts = av_rescale_q(pts, timebase, avstream_audio->time_base); - pkt_copy.dts = av_rescale_q(dts, timebase, avstream_audio->time_base); - pkt_copy.duration = av_rescale_q(pkt.duration, timebase, avstream_audio->time_base); - } else { - assert(false); - } + assert(size_t(pkt_copy.stream_index) < streams.size()); + AVRational time_base = streams[pkt_copy.stream_index]->time_base; + pkt_copy.pts = av_rescale_q(pts, timebase, time_base); + pkt_copy.dts = av_rescale_q(dts, timebase, time_base); + pkt_copy.duration = av_rescale_q(pkt.duration, timebase, time_base); { lock_guard lock(mu);