From: Niklas Haas <ffmpeg@haasn.xyz> To: ffmpeg-devel@ffmpeg.org Cc: Niklas Haas <git@haasn.dev> Subject: [FFmpeg-devel] [PATCH 3/7] fftools/ffmpeg_filter: auto-insert csp conversion filter Date: Wed, 11 Oct 2023 16:55:37 +0200 Message-ID: <20231011150848.117897-4-ffmpeg@haasn.xyz> (raw) In-Reply-To: <20231011150848.117897-1-ffmpeg@haasn.xyz> From: Niklas Haas <git@haasn.dev> To convert between color ranges/matrices, if needed by the codec properties. Swscale can't do this currently, so we fall back to using zscale. We momentarily duplicate the mjpeg strictness logic to also enfoce full range. This duplication will be cleaned up in the next commit. In theory this scaler can also handle chroma locations, but the configuration for it is non-trivial due to the split between x/y offsets, and no codec currently signals a chroma location requirement. (Though this is subject to change in the future) --- fftools/ffmpeg_filter.c | 73 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index c738fc3397..c1bedfda00 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -169,6 +169,8 @@ typedef struct OutputFilterPriv { int width, height; int sample_rate; AVChannelLayout ch_layout; + enum AVColorSpace csp; + enum AVColorRange color_range; // time base in which the output is sent to our downstream // does not need to match the filtersink's timebase @@ -184,6 +186,8 @@ typedef struct OutputFilterPriv { const int *formats; const AVChannelLayout *ch_layouts; const int *sample_rates; + const enum AVColorSpace *csps; + const enum AVColorRange *color_ranges; AVRational enc_timebase; // offset for output timestamps, in AV_TIME_BASE_Q @@ -368,6 +372,12 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats, DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0, "%d", ) +DEF_CHOOSE_FORMAT(out_color_matrix, enum AVColorSpace, csp, csps, + AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name); + +DEF_CHOOSE_FORMAT(out_range, enum AVColorRange, color_range, color_ranges, + AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name); + static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint) { if (av_channel_layout_check(&ofp->ch_layout)) { @@ -594,6 +604,7 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg) ofilter = &ofp->ofilter; ofilter->graph = fg; ofp->format = -1; + ofp->csp = AVCOL_SPC_UNSPECIFIED; ofilter->last_pts = AV_NOPTS_VALUE; return ofilter; @@ -682,6 +693,37 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost) case AVMEDIA_TYPE_VIDEO: ofp->width = ost->enc_ctx->width; ofp->height = ost->enc_ctx->height; + if (ost->enc_ctx->colorspace != AVCOL_SPC_UNSPECIFIED) { + ofp->csp = ost->enc_ctx->colorspace; + } else { + ofp->csps = c->csps; + } + if (ost->enc_ctx->color_range) { + ofp->color_range = ost->enc_ctx->color_range; + } else { + ofp->color_ranges = c->color_ranges; + + // MJPEG encoder exports a full list of supported pixel formats, + // but the full-range ones are experimental-only. + // Restrict the auto-conversion list unless -strict experimental + // has been specified. + if (!strcmp(c->name, "mjpeg")) { + static const enum AVColorRange mjpeg_ranges[] = + { AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED }; + + const AVDictionaryEntry *strict = av_dict_get(ost->encoder_opts, "strict", NULL, 0); + int strict_val = ost->enc_ctx->strict_std_compliance; + + if (strict) { + const AVOption *o = av_opt_find(ost->enc_ctx, strict->key, NULL, 0, 0); + av_assert0(o); + av_opt_eval_int(ost->enc_ctx, o, strict->value, &strict_val); + } + + if (strict_val > FF_COMPLIANCE_UNOFFICIAL) + ofp->color_ranges = mjpeg_ranges; + } + } if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) { ofp->format = ost->enc_ctx->pix_fmt; } else { @@ -1149,6 +1191,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); OutputStream *ost = ofilter->ost; OutputFile *of = output_files[ost->file_index]; + FilterGraphPriv *fgp = fgp_from_fg(fg); AVFilterContext *last_filter = out->filter_ctx; AVBPrint bprint; int pad_idx = out->pad_idx; @@ -1209,6 +1252,36 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, pad_idx = 0; } + if (!fgp->disable_conversions) { + av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED); + choose_out_color_matrix(ofp, &bprint); + choose_out_range(ofp, &bprint); + if (bprint.len) { + const AVDictionaryEntry *e = NULL; + AVFilterContext *filter; + + while ((e = av_dict_iterate(ost->sws_dict, e))) + av_bprintf(&bprint, "%s=%s:", e->key, e->value); + + if (!av_bprint_is_complete(&bprint)) + return AVERROR(ENOMEM); + + snprintf(name, sizeof(name), "conv_out_%d_%d", + ost->file_index, ost->index); + ret = avfilter_graph_create_filter(&filter, + avfilter_get_by_name("scale"), + name, bprint.str, NULL, fg->graph); + av_bprint_finalize(&bprint, NULL); + if (ret < 0) + return ret; + if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0) + return ret; + + last_filter = filter; + pad_idx = 0; + } + } + snprintf(name, sizeof(name), "trim_out_%d_%d", ost->file_index, ost->index); ret = insert_trim(of->start_time, of->recording_time, -- 2.42.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-10-11 15:09 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-10-11 14:55 [FFmpeg-devel] [RFC] [PATCH 0/7] Towards YUVJ removal, v2 Niklas Haas 2023-10-11 14:55 ` [FFmpeg-devel] [PATCH 1/7] avcodec: add extended AVCodec color metadata Niklas Haas 2023-10-11 14:55 ` [FFmpeg-devel] [PATCH 2/7] lavc/options: properly init AVCodecContext.colorspace Niklas Haas 2023-10-11 15:44 ` Andreas Rheinhardt 2023-10-11 14:55 ` Niklas Haas [this message] 2023-10-11 14:55 ` [FFmpeg-devel] [PATCH 4/7] fftools/ffmpeg_filter: auto-insert zscale filter Niklas Haas 2023-10-11 16:55 ` Michael Niedermayer 2023-10-11 17:34 ` Niklas Haas 2023-10-11 14:55 ` [FFmpeg-devel] [PATCH 5/7] avcodec/encode: enforce AVCodec capabilities at encode time Niklas Haas 2023-10-11 14:55 ` [FFmpeg-devel] [PATCH 6/7] lavc: set color_ranges for YUVJ-only codecs Niklas Haas 2023-10-11 14:55 ` [FFmpeg-devel] [PATCH 7/7] lavfi/lavu/lavc: remove YUVJ pixel formats Niklas Haas
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20231011150848.117897-4-ffmpeg@haasn.xyz \ --to=ffmpeg@haasn.xyz \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=git@haasn.dev \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git