From patchwork Sat Jan 28 10:51:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40154 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3ca3:b0:b9:1511:ac2c with SMTP id b35csp2026229pzj; Sat, 28 Jan 2023 02:53:13 -0800 (PST) X-Google-Smtp-Source: AK7set9m6JM4idCNNfTsYD8uvh6VFlO+uQgAhA6bGFg9yZSE53yJMAgtCyoj09X1GjDcr6oEk4nt X-Received: by 2002:a17:907:e90:b0:87b:daf7:cf3b with SMTP id ho16-20020a1709070e9000b0087bdaf7cf3bmr6443513ejc.47.1674903193442; Sat, 28 Jan 2023 02:53:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674903193; cv=none; d=google.com; s=arc-20160816; b=SJ0utvVmD1cAu5+aA/aPsna8EkwboFD3+M2vG7Tj3TJE8kKcpDmkFX+Mk8IdHMet50 QN05dHi9vqRt1d7CEV6JJzacIUr0GFHdQoh14/5najs0FvIm/DV43sFKJMhay016uBoU sCq5GjRksBGXR8uRu10mIiSJt8bf9nMfcpRGMVyePhZCTjjfK6TW1TQY7chgIsweFd84 Pu3Ehn2izlSOZfvCjrVUVnbIyZHCii1NVJhoJi5O4QPNckDMGuU+ZjToOwMymCPc7q94 X7LUnpuWJpbmuaCqMUc+iEx57E02Kepa5+EJxCA9FVrFialF7ghJ1wll/N1nhSd9SWyO oXMg== 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:message-id:date:to:from :delivered-to; bh=O/I6BIM6RiphuaQIIetGYxYOh9uX4+/LW3I6BoYWRXA=; b=WeWzv6i0IpeN2nBGHUR5uNgfAv842gvol/gMzR2M7zKjtTJ7GlzLpAYxYHekrtxEVd XY/hXj50hdnRwdaxRkY4BvVlJnMPBn+XAq7QMjjr95BXVFR2EqqgjEIXtEnw1vVWb2AU eeWtEoitV3Noev6067XOA3yAL58egzviY9U81yOpORmlHklagsGVFNUDeXMaEZaNcVaI zQzcJWBoO/Wx04nxKdAYfJ6QzhaDo5VUhv5xtlOy3zp96LzhCe9389+SWN3B3eVB6znM bha1aVlo6CluDmAx7GszFgR2ZxLC2xtejap+wbAo3pL37yrkxQ3RdG4kNImaP5MsX0GJ mSdw== 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 j20-20020a170906535400b00871d0c97cc3si9058017ejo.856.2023.01.28.02.53.13; Sat, 28 Jan 2023 02:53:13 -0800 (PST) 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 33E6D68BE16; Sat, 28 Jan 2023 12:52:50 +0200 (EET) 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 9508868BDBC for ; Sat, 28 Jan 2023 12:52:40 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 011812404F5 for ; Sat, 28 Jan 2023 11:52:39 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id YaSHDddpaVNO for ; Sat, 28 Jan 2023 11:52:37 +0100 (CET) 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 CDDD2240178 for ; Sat, 28 Jan 2023 11:52:37 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 8BCE73A0101 for ; Sat, 28 Jan 2023 11:52:37 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 28 Jan 2023 11:51:40 +0100 Message-Id: <20230128105142.12476-1-anton@khirnov.net> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/3] fftools/ffmpeg: add an AVClass to Muxer/OutputFile 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: U/KCqwlhTL2x Use it for logging. This makes log messages related to this output file more consistent. --- fftools/ffmpeg.h | 2 + fftools/ffmpeg_mux.c | 26 +++----- fftools/ffmpeg_mux.h | 3 + fftools/ffmpeg_mux_init.c | 133 +++++++++++++++++++++++--------------- 4 files changed, 96 insertions(+), 68 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 5527dbe49b..b1876f7788 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -628,6 +628,8 @@ typedef struct OutputStream { } OutputStream; typedef struct OutputFile { + const AVClass *class; + int index; const AVOutputFormat *format; diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 20524e5a28..96d6747749 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -207,8 +207,7 @@ static void *muxer_thread(void *arg) ret = tq_receive(mux->tq, &stream_idx, pkt); if (stream_idx < 0) { - av_log(NULL, AV_LOG_VERBOSE, - "All streams finished for output file #%d\n", of->index); + av_log(mux, AV_LOG_VERBOSE, "All streams finished\n"); ret = 0; break; } @@ -219,8 +218,7 @@ static void *muxer_thread(void *arg) if (ret == AVERROR_EOF) tq_receive_finish(mux->tq, stream_idx); else if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, - "Error muxing a packet for output file #%d\n", of->index); + av_log(mux, AV_LOG_ERROR, "Error muxing a packet\n"); break; } } @@ -231,7 +229,7 @@ finish: for (unsigned int i = 0; i < mux->fc->nb_streams; i++) tq_receive_finish(mux->tq, i); - av_log(NULL, AV_LOG_VERBOSE, "Terminating muxer thread %d\n", of->index); + av_log(mux, AV_LOG_VERBOSE, "Terminating muxer thread\n"); return (void*)(intptr_t)ret; } @@ -511,10 +509,8 @@ int mux_check_init(Muxer *mux) ret = avformat_write_header(fc, &mux->opts); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, - "Could not write header for output file #%d " - "(incorrect codec parameters ?): %s\n", - of->index, av_err2str(ret)); + av_log(mux, AV_LOG_ERROR, "Could not write header (incorrect codec " + "parameters ?): %s\n", av_err2str(ret)); return ret; } //assert_avoptions(of->opts); @@ -604,10 +600,9 @@ int of_write_trailer(OutputFile *of) int ret; if (!mux->tq) { - av_log(NULL, AV_LOG_ERROR, - "Nothing was written into output file %d (%s), because " - "at least one of its streams received no packets.\n", - of->index, fc->url); + av_log(mux, AV_LOG_ERROR, + "Nothing was written into output file, because " + "at least one of its streams received no packets.\n"); return AVERROR(EINVAL); } @@ -617,7 +612,7 @@ int of_write_trailer(OutputFile *of) ret = av_write_trailer(fc); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", fc->url, av_err2str(ret)); + av_log(mux, AV_LOG_ERROR, "Error writing trailer: %s\n", av_err2str(ret)); return ret; } @@ -626,8 +621,7 @@ int of_write_trailer(OutputFile *of) if (!(of->format->flags & AVFMT_NOFILE)) { ret = avio_closep(&fc->pb); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error closing file %s: %s\n", - fc->url, av_err2str(ret)); + av_log(mux, AV_LOG_ERROR, "Error closing file: %s\n", av_err2str(ret)); return ret; } } diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index 6a72b9dc91..8a90cc56c6 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -63,6 +63,9 @@ typedef struct MuxStream { typedef struct Muxer { OutputFile of; + // name used for logging + char log_name[32]; + AVFormatContext *fc; pthread_t thread; diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 9eea8639dc..f543438b18 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -818,7 +818,7 @@ static void init_output_filter(OutputFilter *ofilter, const OptionsContext *o, case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(mux, o, NULL); break; case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(mux, o, NULL); break; default: - av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported " + av_log(mux, AV_LOG_FATAL, "Only video and audio filters are supported " "currently.\n"); exit_program(1); } @@ -1023,7 +1023,7 @@ static void map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map } loop_end: if (!ofilter) { - av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist " + av_log(mux, AV_LOG_FATAL, "Output with label '%s' does not exist " "in any defined filter graph, or was already used elsewhere.\n", map->linklabel); exit_program(1); } @@ -1031,7 +1031,7 @@ loop_end: } else { ist = input_files[map->file_index]->streams[map->stream_index]; if (ist->user_set_discard == AVDISCARD_ALL) { - av_log(NULL, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n", + av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n", map->file_index, map->stream_index); exit_program(1); } @@ -1056,11 +1056,11 @@ loop_end: break; } default: - av_log(NULL, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL, + av_log(mux, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n", map->file_index, map->stream_index); if (!ignore_unknown_streams) { - av_log(NULL, AV_LOG_FATAL, + av_log(mux, AV_LOG_FATAL, "If you want unsupported types ignored instead " "of failing, please use the -ignore_unknown option\n" "If you want them copied, please use -copy_unknown\n"); @@ -1082,18 +1082,18 @@ static void of_add_attachments(Muxer *mux, const OptionsContext *o) int64_t len; if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) { - av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n", + av_log(mux, AV_LOG_FATAL, "Could not open attachment file %s.\n", o->attachments[i]); exit_program(1); } if ((len = avio_size(pb)) <= 0) { - av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n", + av_log(mux, AV_LOG_FATAL, "Could not get size of the attachment %s.\n", o->attachments[i]); exit_program(1); } if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE || !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) { - av_log(NULL, AV_LOG_FATAL, "Attachment %s too large.\n", + av_log(mux, AV_LOG_FATAL, "Attachment %s too large.\n", o->attachments[i]); exit_program(1); } @@ -1156,7 +1156,7 @@ static void create_streams(Muxer *mux, const OptionsContext *o) if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) { av_dump_format(oc, nb_output_files - 1, oc->url, 1); - av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1); + av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n"); exit_program(1); } } @@ -1255,8 +1255,9 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u return 0; } -static void of_add_programs(AVFormatContext *oc, const OptionsContext *o) +static void of_add_programs(Muxer *mux, const OptionsContext *o) { + AVFormatContext *oc = mux->fc; /* process manually set programs */ for (int i = 0; i < o->nb_program; i++) { const char *p = o->program[i].u.str; @@ -1301,7 +1302,7 @@ static void of_add_programs(AVFormatContext *oc, const OptionsContext *o) key = av_get_token(&p2, "="); if (!key) { - av_log(NULL, AV_LOG_FATAL, + av_log(mux, AV_LOG_FATAL, "No '=' character in program string %s.\n", p2); exit_program(1); @@ -1317,7 +1318,7 @@ static void of_add_programs(AVFormatContext *oc, const OptionsContext *o) int st_num = strtol(p2, NULL, 0); av_program_add_stream_index(oc, progid, st_num); } else { - av_log(NULL, AV_LOG_FATAL, "Unknown program key %s.\n", key); + av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", key); exit_program(1); } av_freep(&to_dealloc); @@ -1333,7 +1334,8 @@ static void of_add_programs(AVFormatContext *oc, const OptionsContext *o) * @param index for type c/p, chapter/program index is written here * @param stream_spec for type s, the stream specifier is written here */ -static void parse_meta_type(const char *arg, char *type, int *index, const char **stream_spec) +static void parse_meta_type(void *logctx, const char *arg, + char *type, int *index, const char **stream_spec) { if (*arg) { *type = *arg; @@ -1342,7 +1344,7 @@ static void parse_meta_type(const char *arg, char *type, int *index, const char break; case 's': if (*(++arg) && *arg != ':') { - av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg); + av_log(logctx, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg); exit_program(1); } *stream_spec = *arg == ':' ? arg + 1 : ""; @@ -1353,7 +1355,7 @@ static void parse_meta_type(const char *arg, char *type, int *index, const char *index = strtol(++arg, NULL, 0); break; default: - av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg); + av_log(logctx, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg); exit_program(1); } } else @@ -1371,13 +1373,13 @@ static void of_add_metadata(OutputFile *of, AVFormatContext *oc, val = strchr(o->metadata[i].u.str, '='); if (!val) { - av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n", + av_log(of, AV_LOG_FATAL, "No '=' character in metadata string %s.\n", o->metadata[i].u.str); exit_program(1); } *val++ = 0; - parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec); + parse_meta_type(of, o->metadata[i].specifier, &type, &index, &stream_spec); if (type == 's') { for (int j = 0; j < oc->nb_streams; j++) { OutputStream *ost = of->streams[j]; @@ -1412,20 +1414,20 @@ static void of_add_metadata(OutputFile *of, AVFormatContext *oc, break; case 'c': if (index < 0 || index >= oc->nb_chapters) { - av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + av_log(of, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); exit_program(1); } m = &oc->chapters[index]->metadata; break; case 'p': if (index < 0 || index >= oc->nb_programs) { - av_log(NULL, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index); + av_log(of, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index); exit_program(1); } m = &oc->programs[index]->metadata; break; default: - av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); + av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); exit_program(1); } av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); @@ -1514,11 +1516,12 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *o return 0; } -static int copy_metadata(const char *outspec, const char *inspec, - AVFormatContext *oc, AVFormatContext *ic, +static int copy_metadata(Muxer *mux, AVFormatContext *ic, + const char *outspec, const char *inspec, int *metadata_global_manual, int *metadata_streams_manual, int *metadata_chapters_manual, const OptionsContext *o) { + AVFormatContext *oc = mux->fc; AVDictionary **meta_in = NULL; AVDictionary **meta_out = NULL; int i, ret = 0; @@ -1526,8 +1529,8 @@ static int copy_metadata(const char *outspec, const char *inspec, const char *istream_spec = NULL, *ostream_spec = NULL; int idx_in = 0, idx_out = 0; - parse_meta_type(inspec, &type_in, &idx_in, &istream_spec); - parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec); + parse_meta_type(mux, inspec, &type_in, &idx_in, &istream_spec); + parse_meta_type(mux, outspec, &type_out, &idx_out, &ostream_spec); if (type_in == 'g' || type_out == 'g') *metadata_global_manual = 1; @@ -1542,7 +1545,7 @@ static int copy_metadata(const char *outspec, const char *inspec, #define METADATA_CHECK_INDEX(index, nb_elems, desc)\ if ((index) < 0 || (index) >= (nb_elems)) {\ - av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\ + av_log(mux, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\ (desc), (index));\ exit_program(1);\ } @@ -1578,7 +1581,7 @@ static int copy_metadata(const char *outspec, const char *inspec, exit_program(1); } if (!meta_in) { - av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec); + av_log(mux, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec); exit_program(1); } } @@ -1612,12 +1615,13 @@ static void copy_meta(Muxer *mux, const OptionsContext *o) int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0); if (in_file_index >= nb_input_files) { - av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index); + av_log(mux, AV_LOG_FATAL, "Invalid input file index %d while " + "processing metadata maps\n", in_file_index); exit_program(1); } - copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, - in_file_index >= 0 ? - input_files[in_file_index]->ctx : NULL, + copy_metadata(mux, + in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL, + o->metadata_map[i].specifier, *p ? p + 1 : p, &metadata_global_manual, &metadata_streams_manual, &metadata_chapters_manual, o); } @@ -1633,7 +1637,7 @@ static void copy_meta(Muxer *mux, const OptionsContext *o) break; } } else { - av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n", + av_log(mux, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n", chapters_input_file); exit_program(1); } @@ -1854,7 +1858,7 @@ static int process_forced_keyframes(Muxer *mux, const OptionsContext *o) return 0; } -static void validate_enc_avopt(const Muxer *mux, const AVDictionary *codec_avopt) +static void validate_enc_avopt(Muxer *mux, const AVDictionary *codec_avopt) { const AVClass *class = avcodec_get_class(); const AVClass *fclass = avformat_get_class(); @@ -1880,10 +1884,8 @@ static void validate_enc_avopt(const Muxer *mux, const AVDictionary *codec_avopt continue; if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) { - av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for " - "output file #%d (%s) is not an encoding option.\n", e->key, - option->help ? option->help : "", nb_output_files - 1, - mux->fc->url); + av_log(mux, AV_LOG_ERROR, "Codec AVOption %s (%s) is not an " + "encoding option.\n", e->key, option->help ? option->help : ""); exit_program(1); } @@ -1891,16 +1893,41 @@ static void validate_enc_avopt(const Muxer *mux, const AVDictionary *codec_avopt if (!strcmp(e->key, "gop_timecode")) continue; - av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for " - "output file #%d (%s) has not been used for any stream. The most " - "likely reason is either wrong type (e.g. a video option with " - "no video streams) or that it is a private option of some encoder " - "which was not actually used for any stream.\n", e->key, - option->help ? option->help : "", nb_output_files - 1, mux->fc->url); + av_log(mux, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used " + "for any stream. The most likely reason is either wrong type " + "(e.g. a video option with no video streams) or that it is a " + "private option of some encoder which was not actually used for " + "any stream.\n", e->key, option->help ? option->help : ""); } av_dict_free(&unused_opts); } +static const char *output_file_item_name(void *obj) +{ + const Muxer *mux = obj; + + return mux->log_name; +} + +static const AVClass output_file_class = { + .class_name = "OutputFile", + .version = LIBAVUTIL_VERSION_INT, + .item_name = output_file_item_name, + .category = AV_CLASS_CATEGORY_MUXER, +}; + +static Muxer *mux_alloc(void) +{ + Muxer *mux = allocate_array_elem(&output_files, sizeof(*mux), &nb_output_files); + + mux->of.class = &output_file_class; + mux->of.index = nb_output_files - 1; + + snprintf(mux->log_name, sizeof(mux->log_name), "out#%d", mux->of.index); + + return mux; +} + int of_open(const OptionsContext *o, const char *filename) { Muxer *mux; @@ -1911,25 +1938,24 @@ int of_open(const OptionsContext *o, const char *filename) int64_t recording_time = o->recording_time; int64_t stop_time = o->stop_time; + mux = mux_alloc(); + of = &mux->of; + if (stop_time != INT64_MAX && recording_time != INT64_MAX) { stop_time = INT64_MAX; - av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n"); + av_log(mux, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n"); } if (stop_time != INT64_MAX && recording_time == INT64_MAX) { int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time; if (stop_time <= start_time) { - av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n"); + av_log(mux, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n"); exit_program(1); } else { recording_time = stop_time - start_time; } } - mux = allocate_array_elem(&output_files, sizeof(Muxer), &nb_output_files); - of = &mux->of; - - of->index = nb_output_files - 1; of->recording_time = recording_time; of->start_time = o->start_time; of->shortest = o->shortest; @@ -1948,6 +1974,9 @@ int of_open(const OptionsContext *o, const char *filename) } mux->fc = oc; + av_strlcat(mux->log_name, "/", sizeof(mux->log_name)); + av_strlcat(mux->log_name, oc->oformat->name, sizeof(mux->log_name)); + if (strcmp(oc->oformat->name, "rtp")) want_sdp = 0; @@ -2061,12 +2090,12 @@ int of_open(const OptionsContext *o, const char *filename) /* copy metadata and chapters from input files */ copy_meta(mux, o); - of_add_programs(oc, o); + of_add_programs(mux, o); of_add_metadata(of, oc, o); err = set_dispositions(mux, o); if (err < 0) { - av_log(NULL, AV_LOG_FATAL, "Error setting output stream dispositions\n"); + av_log(mux, AV_LOG_FATAL, "Error setting output stream dispositions\n"); exit_program(1); } @@ -2074,13 +2103,13 @@ int of_open(const OptionsContext *o, const char *filename) // must be done after chapters are created err = process_forced_keyframes(mux, o); if (err < 0) { - av_log(NULL, AV_LOG_FATAL, "Error processing forced keyframes\n"); + av_log(mux, AV_LOG_FATAL, "Error processing forced keyframes\n"); exit_program(1); } err = setup_sync_queues(mux, oc, o->shortest_buf_duration * AV_TIME_BASE); if (err < 0) { - av_log(NULL, AV_LOG_FATAL, "Error setting up output sync queues\n"); + av_log(mux, AV_LOG_FATAL, "Error setting up output sync queues\n"); exit_program(1); }