From patchwork Fri Oct 14 10:15:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 38734 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:4a86:b0:9d:28a3:170e with SMTP id fn6csp244351pzb; Fri, 14 Oct 2022 03:19:03 -0700 (PDT) X-Google-Smtp-Source: AMsMyM57uFsZyUwpfD6djPh0Hk48qxbC5Vh9B5AHbM9Ho2suKKiBTyTERPsGVLQMOfTFpXzZKPpe X-Received: by 2002:a05:6402:3552:b0:45c:e4c:e6db with SMTP id f18-20020a056402355200b0045c0e4ce6dbmr3515865edd.403.1665742743205; Fri, 14 Oct 2022 03:19:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665742743; cv=none; d=google.com; s=arc-20160816; b=uCPL+M83+PGWfXdaYhT7kQEIeCEa56iS5pHH9rpZ4TMeZWDg0qn4lO9lKwgk6gPzKB 2KCDXoTbrxIjlpltXD67FQYButILt/3W83rpDmkVyVXDwVmVwJJHFNcD8PTNysdibTSJ YZzWlFLZxBIwDc4TkKhsZbBC4uFPG4p2byCTolF+9oFfraudNbru8ywlPKTBLbU7BoGf KG6KB9uxr0ENKSc44x0VI80LkH5Ymg3L1K3eJeueTXHWuIYbQWSrgYKlC6SGzBm0ZA1O i71FX8uMMfEFSxpjt6szvN4kNSPLBfplyB6WvobtIKOcoXv4h3PXf/MlDpmDo91JuCo2 TxsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:delivered-to; bh=ESG9sqF9ITz9RPYjEQdYFRIZwSRloVn4BZ1TM0hXWIo=; b=bot1XWm01bGR/BmPLGX4axzPIR9zQ3Sb28SkmcC089Jep3RYL9/LLAiT7RrmuzQTUa bTW+bDvK5fLpv1SXfdei0+EZO0Wb5deNrHbW4cZ5lInUNGtBM+Pyqyw9inVVzzjIvqqY RSoM47Mgd0Hoa2ya7FhxcmxtHoxNpfdb4zXpakbve675CyUb5sZGRiLMozIhUf3y5M4P e2yQs2/z+8LTNt2WOPfH8Nx8EPdwVc3TIchZASwbB28vO78QnqoKSnv8r5UfGbOINg4n TJXhShjDWcwmoSBsFLkDHe0ptsQsh9Rgf5CAo/e0qYuX645UtwAWcF6M56jFP83fXhRl ScsQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hc35-20020a17090716a300b0073ce34d1a13si2316030ejc.499.2022.10.14.03.19.01; Fri, 14 Oct 2022 03:19:03 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6938068BDBB; Fri, 14 Oct 2022 13:18:36 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A0BE568BD71 for ; Fri, 14 Oct 2022 13:18:27 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 581BC2404F7 for ; Fri, 14 Oct 2022 12:18:27 +0200 (CEST) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id LCHx8BkG7cJV for ; Fri, 14 Oct 2022 12:18:25 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail0.khirnov.net (Postfix) with ESMTPS id DE9FA2404E4 for ; Fri, 14 Oct 2022 12:18:24 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 1C19E3A13E9 for ; Fri, 14 Oct 2022 12:18:24 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 14 Oct 2022 12:15:43 +0200 Message-Id: <20221014101548.3486-4-anton@khirnov.net> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221014101548.3486-1-anton@khirnov.net> References: <20221013134904.10104-1-anton@khirnov.net> <20221014101548.3486-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 17/22] fftools/ffmpeg: remove the output_streams global X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: VB83ZvoGAe0h Replace it with an array of streams in each OutputFile. This is a more accurate reflection of the actual relationship between OutputStream and OutputFile. This is easier to handle and will allow further simplifications in future commits. --- fftools/ffmpeg.c | 121 ++++++++++++++++++-------------------- fftools/ffmpeg.h | 7 +-- fftools/ffmpeg_filter.c | 2 +- fftools/ffmpeg_mux.c | 10 ++-- fftools/ffmpeg_mux.h | 1 + fftools/ffmpeg_mux_init.c | 54 +++++++++-------- 6 files changed, 97 insertions(+), 98 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index f426dbc80f..b98065d2a0 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -146,8 +146,6 @@ int nb_input_streams = 0; InputFile **input_files = NULL; int nb_input_files = 0; -OutputStream **output_streams = NULL; -int nb_output_streams = 0; OutputFile **output_files = NULL; int nb_output_files = 0; @@ -589,11 +587,15 @@ static void ffmpeg_cleanup(int ret) av_freep(&filtergraphs); /* close files */ - for (i = 0; i < nb_output_files; i++) - of_close(&output_files[i]); + for (i = 0; i < nb_output_files; i++) { + OutputFile *of = output_files[i]; + + for (int j = 0; j < of->nb_streams; j++) + ost_free(&of->streams[j]); + av_freep(&of->streams); - for (i = 0; i < nb_output_streams; i++) - ost_free(&output_streams[i]); + of_close(&output_files[i]); + } free_input_threads(); for (i = 0; i < nb_input_files; i++) { @@ -629,7 +631,6 @@ static void ffmpeg_cleanup(int ret) av_freep(&input_streams); av_freep(&input_files); - av_freep(&output_streams); av_freep(&output_files); uninit_opts(); @@ -646,6 +647,24 @@ static void ffmpeg_cleanup(int ret) ffmpeg_exited = 1; } +/* iterate over all output streams in all output files; + * pass NULL to start iteration */ +static OutputStream *ost_iter(OutputStream *prev) +{ + int of_idx = prev ? prev->file_index : 0; + int ost_idx = prev ? prev->index + 1 : 0; + + for (; of_idx < nb_output_files; of_idx++) { + OutputFile *of = output_files[of_idx]; + for (; ost_idx < of->nb_streams; ost_idx++) + return of->streams[ost_idx]; + + ost_idx = 0; + } + + return NULL; +} + void remove_avoptions(AVDictionary **a, AVDictionary *b) { const AVDictionaryEntry *t = NULL; @@ -1308,11 +1327,9 @@ static void do_video_out(OutputFile *of, static int reap_filters(int flush) { AVFrame *filtered_frame = NULL; - int i; /* Reap all buffers present in the buffer sinks */ - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { OutputFile *of = output_files[ost->file_index]; AVFilterContext *filter; AVCodecContext *enc = ost->enc_ctx; @@ -1397,8 +1414,7 @@ static void print_final_stats(int64_t total_size) int i, j; int pass1_used = 1; - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { AVCodecParameters *par = ost->st->codecpar; const uint64_t s = ost->data_size_mux; @@ -1474,7 +1490,7 @@ static void print_final_stats(int64_t total_size) i, of->url); for (j = 0; j < of->nb_streams; j++) { - OutputStream *ost = output_streams[of->ost_index + j]; + OutputStream *ost = of->streams[j]; enum AVMediaType type = ost->st->codecpar->codec_type; total_size += ost->data_size_mux; @@ -1513,7 +1529,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti { AVBPrint buf, buf_script; int64_t total_size = of_filesize(output_files[0]); - int vid, i; + int vid; double bitrate; double speed; int64_t pts = INT64_MIN + 1; @@ -1543,8 +1559,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti vid = 0; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC); - for (i = 0; i < nb_output_streams; i++) { - OutputStream * const ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { const AVCodecContext * const enc = ost->enc_ctx; const float q = enc ? ost->quality / (float) FF_QP2LAMBDA : -1; @@ -1727,17 +1742,15 @@ static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParamet static void flush_encoders(void) { - int i, ret; + int ret; - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { OutputFile *of = output_files[ost->file_index]; if (ost->sq_idx_encode >= 0) sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); } - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { AVCodecContext *enc = ost->enc_ctx; OutputFile *of = output_files[ost->file_index]; @@ -2250,8 +2263,8 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, { AVSubtitle subtitle; int free_sub = 1; - int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, - &subtitle, got_output, pkt); + int ret = avcodec_decode_subtitle2(ist->dec_ctx, + &subtitle, got_output, pkt); check_decode_result(NULL, got_output, ret); @@ -2304,9 +2317,7 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output, ist->frames_decoded++; - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; - + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { if (!check_output_constraints(ist, ost) || !ost->enc_ctx || ost->enc_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) continue; @@ -2339,7 +2350,7 @@ static int send_filter_eof(InputStream *ist) static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eof) { const AVCodecParameters *par = ist->par; - int ret = 0, i; + int ret = 0; int repeating = 0; int eof_reached = 0; @@ -2517,9 +2528,7 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo } else if (!ist->decoding_needed) eof_reached = 1; - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; - + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { if (!check_output_constraints(ist, ost) || ost->enc_ctx || (!pkt && no_eof)) continue; @@ -3261,13 +3270,13 @@ static int transcode_init(void) * to be configured with the correct audio frame size, which is only * known after the encoder is initialized. */ - for (i = 0; i < nb_output_streams; i++) { - if (output_streams[i]->enc_ctx && - (output_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || - output_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)) + for (ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { + if (ost->enc_ctx && + (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || + ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)) continue; - ret = init_output_stream_wrapper(output_streams[i], NULL, 0); + ret = init_output_stream_wrapper(ost, NULL, 0); if (ret < 0) goto dump_format; } @@ -3306,9 +3315,7 @@ static int transcode_init(void) } } - for (i = 0; i < nb_output_streams; i++) { - ost = output_streams[i]; - + for (ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { if (ost->attachment_filename) { /* an attached file */ av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n", @@ -3380,11 +3387,7 @@ static int transcode_init(void) /* Return 1 if there remain streams where more output is wanted, 0 otherwise. */ static int need_output(void) { - int i; - - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; - + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { if (ost->finished) continue; @@ -3401,12 +3404,10 @@ static int need_output(void) */ static OutputStream *choose_output(void) { - int i; int64_t opts_min = INT64_MAX; OutputStream *ost_min = NULL; - for (i = 0; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { int64_t opts; if (ost->filter && ost->last_filter_pts != AV_NOPTS_VALUE) { @@ -3526,8 +3527,7 @@ static int check_keyboard_interaction(int64_t cur_time) for(i=0;idec_ctx->debug = debug; } - for(i=0;ienc_ctx) ost->enc_ctx->debug = debug; } @@ -3552,9 +3552,8 @@ static int check_keyboard_interaction(int64_t cur_time) static int got_eagain(void) { - int i; - for (i = 0; i < nb_output_streams; i++) - if (output_streams[i]->unavailable) + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) + if (ost->unavailable) return 1; return 0; } @@ -3564,8 +3563,8 @@ static void reset_eagain(void) int i; for (i = 0; i < nb_input_files; i++) input_files[i]->eagain = 0; - for (i = 0; i < nb_output_streams; i++) - output_streams[i]->unavailable = 0; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) + ost->unavailable = 0; } static void decode_flush(InputFile *ifile) @@ -3696,7 +3695,7 @@ static int process_input(int file_index) AVFormatContext *is; InputStream *ist; AVPacket *pkt; - int ret, i, j; + int ret, i; is = ifile->ctx; ret = ifile_get_packet(ifile, &pkt); @@ -3726,9 +3725,7 @@ static int process_input(int file_index) } /* mark all outputs that don't go through lavfi as finished */ - for (j = 0; j < nb_output_streams; j++) { - OutputStream *ost = output_streams[j]; - + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { if (ost->source_index == ifile->ist_index + i && (!ost->enc_ctx || ost->enc_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE)) { OutputFile *of = output_files[ost->file_index]; @@ -3941,7 +3938,6 @@ static int transcode_step(void) static int transcode(void) { int ret, i; - OutputStream *ost; InputStream *ist; int64_t timer_start; int64_t total_packets_written = 0; @@ -4006,9 +4002,8 @@ static int transcode(void) print_report(1, timer_start, av_gettime_relative()); /* close each encoder */ - for (i = 0; i < nb_output_streams; i++) { + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { uint64_t packets_written; - ost = output_streams[i]; packets_written = atomic_load(&ost->packets_written); total_packets_written += packets_written; if (!packets_written && (abort_on_flags & ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM)) { @@ -4038,9 +4033,7 @@ static int transcode(void) fail: free_input_threads(); - if (output_streams) { - for (i = 0; i < nb_output_streams; i++) { - ost = output_streams[i]; + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { if (ost) { if (ost->logfile) { if (fclose(ost->logfile)) @@ -4057,7 +4050,7 @@ static int transcode(void) av_dict_free(&ost->swr_opts); } } - } + return ret; } diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 20eb6e2aa9..0af824b9b9 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -619,10 +619,11 @@ typedef struct OutputFile { const AVOutputFormat *format; const char *url; + OutputStream **streams; + int nb_streams; + SyncQueue *sq_encode; - int nb_streams; - int ost_index; /* index of the first stream in output_streams */ int64_t recording_time; ///< desired length of the resulting file in microseconds == AV_TIME_BASE units int64_t start_time; ///< start time in microseconds == AV_TIME_BASE units @@ -635,8 +636,6 @@ extern int nb_input_streams; extern InputFile **input_files; extern int nb_input_files; -extern OutputStream **output_streams; -extern int nb_output_streams; extern OutputFile **output_files; extern int nb_output_files; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 82abb38a93..718826a485 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -609,7 +609,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, int i; for (i = 0; i < of->nb_streams; i++) - if (output_streams[of->ost_index + i]->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + if (of->streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) break; if (i < of->nb_streams) { diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 5418cd3000..a110691f6a 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -168,7 +168,7 @@ static int sync_queue_process(Muxer *mux, OutputStream *ost, AVPacket *pkt) if (ret < 0) return (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ? 0 : ret; - ret = write_packet(mux, output_streams[of->ost_index + ret], + ret = write_packet(mux, of->streams[ret], mux->sq_pkt); if (ret < 0) return ret; @@ -204,7 +204,7 @@ static void *muxer_thread(void *arg) break; } - ost = output_streams[of->ost_index + stream_idx]; + ost = of->streams[stream_idx]; ret = sync_queue_process(mux, ost, ret < 0 ? NULL : pkt); av_packet_unref(pkt); if (ret == AVERROR_EOF) @@ -410,7 +410,7 @@ static int thread_start(Muxer *mux) /* flush the muxing queues */ for (int i = 0; i < fc->nb_streams; i++) { MuxStream *ms = &mux->streams[i]; - OutputStream *ost = output_streams[mux->of.ost_index + i]; + OutputStream *ost = mux->of.streams[i]; AVPacket *pkt; /* try to improve muxing time_base (only possible if nothing has been written yet) */ @@ -494,7 +494,7 @@ int mux_check_init(Muxer *mux) int ret, i; for (i = 0; i < fc->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; if (!ost->initialized) return 0; } @@ -651,7 +651,7 @@ void of_close(OutputFile **pof) sq_free(&of->sq_encode); sq_free(&mux->sq_mux); - for (int i = 0; i < mux->of.nb_streams; i++) { + for (int i = 0; i < mux->nb_streams; i++) { MuxStream *ms = &mux->streams[i]; AVPacket *pkt; diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index 7cb1337b49..b73b6c628b 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -58,6 +58,7 @@ typedef struct Muxer { ThreadQueue *tq; MuxStream *streams; + int nb_streams; AVDictionary *opts; diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 222519f5ce..6909a017d8 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -183,7 +183,7 @@ static OutputStream *new_output_stream(Muxer *mux, OptionsContext *o, if (oc->nb_streams - 1 < o->nb_streamid_map) st->id = o->streamid_map[oc->nb_streams - 1]; - ost = ALLOC_ARRAY_ELEM(output_streams, nb_output_streams); + ost = ALLOC_ARRAY_ELEM(mux->of.streams, mux->of.nb_streams); ost->file_index = nb_output_files - 1; ost->index = idx; @@ -555,13 +555,18 @@ static OutputStream *new_video_stream(Muxer *mux, OptionsContext *o, int source_ report_and_exit(AVERROR(ENOMEM)); if (do_pass) { + int ost_idx = -1; char logfilename[1024]; FILE *f; + /* compute this stream's global index */ + for (int i = 0; i <= ost->file_index; i++) + ost_idx += output_files[i]->nb_streams; + snprintf(logfilename, sizeof(logfilename), "%s-%d.log", ost->logfile_prefix ? ost->logfile_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX, - nb_output_streams - 1); + ost_idx); if (!strcmp(ost->enc_ctx->codec->name, "libx264")) { av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE); } else { @@ -1054,7 +1059,7 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u #define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT) for (int i = 0; i < oc->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; enum AVMediaType type = ost->st->codecpar->codec_type; ost->sq_idx_encode = -1; @@ -1080,7 +1085,7 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u return AVERROR(ENOMEM); for (int i = 0; i < oc->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; enum AVMediaType type = ost->st->codecpar->codec_type; if (!IS_AV_ENC(ost, type)) @@ -1112,7 +1117,7 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u return AVERROR(ENOMEM); for (int i = 0; i < oc->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; enum AVMediaType type = ost->st->codecpar->codec_type; if (!IS_INTERLEAVED(type)) @@ -1280,7 +1285,8 @@ static void parse_meta_type(char *arg, char *type, int *index, const char **stre *type = 'g'; } -static void of_add_metadata(AVFormatContext *oc, const OptionsContext *o) +static void of_add_metadata(OutputFile *of, AVFormatContext *oc, + const OptionsContext *o) { for (int i = 0; i < o->nb_metadata; i++) { AVDictionary **m; @@ -1299,7 +1305,7 @@ static void of_add_metadata(AVFormatContext *oc, const OptionsContext *o) parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec); if (type == 's') { for (int j = 0; j < oc->nb_streams; j++) { - OutputStream *ost = output_streams[nb_output_streams - oc->nb_streams + j]; + OutputStream *ost = of->streams[j]; if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { if (!strcmp(o->metadata[i].u.str, "rotate")) { char *tail; @@ -1521,7 +1527,7 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) // first, copy the input dispositions for (int i = 0; i < ctx->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; nb_streams[ost->st->codecpar->codec_type]++; @@ -1538,7 +1544,7 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) if (have_manual) { // process manually set dispositions - they override the above copy for (int i = 0; i < ctx->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; int ret; if (!ost->disposition) @@ -1564,7 +1570,7 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) // mark as default, unless one is already marked default. // "Suitable" means the first of that type, skipping attached pictures. for (int i = 0; i < ctx->nb_streams; i++) { - OutputStream *ost = output_streams[of->ost_index + i]; + OutputStream *ost = of->streams[i]; enum AVMediaType type = ost->st->codecpar->codec_type; if (nb_streams[type] < 2 || have_default[type] || @@ -1607,7 +1613,6 @@ int of_open(OptionsContext *o, const char *filename) of = &mux->of; of->index = nb_output_files - 1; - of->ost_index = nb_output_streams; of->recording_time = o->recording_time; of->start_time = o->start_time; of->shortest = o->shortest; @@ -1686,9 +1691,9 @@ int of_open(OptionsContext *o, const char *filename) /* check if all codec options have been used */ unused_opts = strip_specifiers(o->g->codec_opts); - for (i = of->ost_index; i < nb_output_streams; i++) { + for (int i = 0; i < of->nb_streams; i++) { e = NULL; - while ((e = av_dict_get(output_streams[i]->encoder_opts, "", e, + while ((e = av_dict_get(of->streams[i]->encoder_opts, "", e, AV_DICT_IGNORE_SUFFIX))) av_dict_set(&unused_opts, e->key, NULL, 0); } @@ -1727,8 +1732,8 @@ int of_open(OptionsContext *o, const char *filename) av_dict_free(&unused_opts); /* set the decoding_needed flags and create simple filtergraphs */ - for (i = of->ost_index; i < nb_output_streams; i++) { - OutputStream *ost = output_streams[i]; + for (int i = 0; i < of->nb_streams; i++) { + OutputStream *ost = of->streams[i]; if (ost->enc_ctx && ost->source_index >= 0) { InputStream *ist = input_streams[ost->source_index]; @@ -1866,19 +1871,20 @@ int of_open(OptionsContext *o, const char *filename) av_dict_set(&oc->metadata, "product_version", NULL, 0); } if (!o->metadata_streams_manual) - for (i = of->ost_index; i < nb_output_streams; i++) { + for (int i = 0; i < of->nb_streams; i++) { + OutputStream *ost = of->streams[i]; InputStream *ist; - if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */ + if (ost->source_index < 0) /* this is true e.g. for attached files */ continue; - ist = input_streams[output_streams[i]->source_index]; - av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE); - if (output_streams[i]->enc_ctx) { - av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0); + ist = input_streams[ost->source_index]; + av_dict_copy(&ost->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE); + if (ost->enc_ctx) { + av_dict_set(&ost->st->metadata, "encoder", NULL, 0); } } of_add_programs(oc, o); - of_add_metadata(oc, o); + of_add_metadata(of, oc, o); err = set_dispositions(of, oc); if (err < 0) { @@ -1897,9 +1903,9 @@ int of_open(OptionsContext *o, const char *filename) mux->streams = av_calloc(oc->nb_streams, sizeof(*mux->streams)); if (!mux->streams) return AVERROR(ENOMEM); - of->nb_streams = oc->nb_streams; + mux->nb_streams = oc->nb_streams; - for (int i = 0; i < oc->nb_streams; i++) { + for (int i = 0; i < mux->nb_streams; i++) { MuxStream *ms = &mux->streams[i]; ms->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0); if (!ms->muxing_queue)