I do not have time to look at the code in details right now, and I do not know when I will have time, but here are a few remarks.
Paul B Mahol (2017-12-11): > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > > This is with color range negotiation. > To be applied on top of previous patch set. > It fixes issue Michael found. > This needs more work as every filter needs its query_formats() changed. This is annoying. Could you not get the framework set a reasonable value (all supported) when the list is not set? > > --- > fftools/ffmpeg_filter.c | 13 +++------- > libavfilter/avfilter.c | 9 ++++--- > libavfilter/avfilter.h | 4 ++- > libavfilter/avfiltergraph.c | 34 ++++++++++++++++++++++++ > libavfilter/buffersink.c | 16 ++++++++++++ > libavfilter/buffersink.h | 1 + > libavfilter/buffersrc.c | 4 +++ > libavfilter/formats.c | 63 > +++++++++++++++++++++++++++++++++++++++++++++ > libavfilter/formats.h | 31 ++++++++++++++++++++++ > libavfilter/internal.h | 11 ++++++++ > libavfilter/vf_format.c | 46 ++++++++++++++++++++++++++++++++- > libavfilter/vf_noise.c | 6 ++++- > libavfilter/vf_scale.c | 19 +++++++++++--- > libavfilter/vsrc_testsrc.c | 15 +++++++++-- > 14 files changed, 251 insertions(+), 21 deletions(-) > > diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c > index 3aad564b81..a8fbcdecfb 100644 > --- a/fftools/ffmpeg_filter.c > +++ b/fftools/ffmpeg_filter.c > @@ -144,6 +144,8 @@ static char *choose_pix_fmts(OutputFilter *ofilter) > const char *name = av_get_pix_fmt_name(*p); > avio_printf(s, "%s|", name); > } > + if (av_color_range_name(ost->enc->color_range)) > + avio_printf(s, ":color_ranges=%s|", > av_color_range_name(ost->enc->color_range)); > len = avio_close_dyn_buf(s, &ret); > ret[len - 1] = 0; > return ret; > @@ -447,7 +449,6 @@ static int configure_output_video_filter(FilterGraph *fg, > OutputFilter *ofilter, > OutputStream *ost = ofilter->ost; > OutputFile *of = output_files[ost->file_index]; > AVFilterContext *last_filter = out->filter_ctx; > - AVDictionaryEntry *cre = NULL; > int pad_idx = out->pad_idx; > int ret; > char name[255]; > @@ -460,9 +461,7 @@ static int configure_output_video_filter(FilterGraph *fg, > OutputFilter *ofilter, > if (ret < 0) > return ret; > > - cre = av_dict_get(ost->encoder_opts, "color_range", NULL, 0); > - > - if (ofilter->width || ofilter->height || (cre && cre->value) || > ost->enc->color_range) { > + if (ofilter->width || ofilter->height) { > char args[255]; > AVFilterContext *filter; > AVDictionaryEntry *e = NULL; > @@ -475,12 +474,6 @@ static int configure_output_video_filter(FilterGraph > *fg, OutputFilter *ofilter, > av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value); > } > > - if (cre && cre->value) { > - av_strlcatf(args, sizeof(args), ":out_range=%s", cre->value); > - } else if (ost->enc->color_range) { > - av_strlcatf(args, sizeof(args), ":out_range=%s", > av_color_range_name(ost->enc->color_range)); > - } > - > snprintf(name, sizeof(name), "scaler_out_%d_%d", > ost->file_index, ost->index); > if ((ret = avfilter_graph_create_filter(&filter, > avfilter_get_by_name("scale"), > diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c > index 4a579bb49d..c3a19d100c 100644 > --- a/libavfilter/avfilter.c > +++ b/libavfilter/avfilter.c > @@ -262,6 +262,9 @@ int avfilter_insert_filter(AVFilterLink *link, > AVFilterContext *filt, > if (link->out_formats) > ff_formats_changeref(&link->out_formats, > &filt->outputs[filt_dstpad_idx]->out_formats); > + if (link->out_color_ranges) > + ff_formats_changeref(&link->out_color_ranges, > + > &filt->outputs[filt_dstpad_idx]->out_color_ranges); > if (link->out_samplerates) > ff_formats_changeref(&link->out_samplerates, > > &filt->outputs[filt_dstpad_idx]->out_samplerates); > @@ -785,6 +788,8 @@ static void free_link(AVFilterLink *link) > > ff_formats_unref(&link->in_formats); > ff_formats_unref(&link->out_formats); > + ff_formats_unref(&link->in_color_ranges); > + ff_formats_unref(&link->out_color_ranges); > ff_formats_unref(&link->in_samplerates); > ff_formats_unref(&link->out_samplerates); > ff_channel_layouts_unref(&link->in_channel_layouts); > @@ -970,9 +975,7 @@ int avfilter_init_str(AVFilterContext *filter, const char > *args) > } > > #if FF_API_OLD_FILTER_OPTS_ERROR > - if ( !strcmp(filter->filter->name, "format") || > - !strcmp(filter->filter->name, "noformat") || > - !strcmp(filter->filter->name, "frei0r") || > + if ( !strcmp(filter->filter->name, "frei0r") || > !strcmp(filter->filter->name, "frei0r_src") || > !strcmp(filter->filter->name, "ocv") || > !strcmp(filter->filter->name, "pan") || > diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h > index 40ad28ffd8..138bdeb5c9 100644 > --- a/libavfilter/avfilter.h > +++ b/libavfilter/avfilter.h > @@ -456,7 +456,7 @@ struct AVFilterLink { > ***************************************************************** > */ > /** > - * Lists of formats and channel layouts supported by the input and output > + * Lists of formats, color_ranges and channel layouts supported by the > input and output > * filters respectively. These lists are used for negotiating the format > * to actually be used, which will be loaded into the format and > * channel_layout members, above, when chosen. > @@ -464,6 +464,8 @@ struct AVFilterLink { > */ > AVFilterFormats *in_formats; > AVFilterFormats *out_formats; > + AVFilterFormats *in_color_ranges; > + AVFilterFormats *out_color_ranges; > > /** > * Lists of channel layouts and sample rates used for automatic > diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c > index a959a9ef3f..ee5ddebe22 100644 > --- a/libavfilter/avfiltergraph.c > +++ b/libavfilter/avfiltergraph.c > @@ -360,6 +360,9 @@ static int formats_declared(AVFilterContext *f) > !(f->inputs[i]->out_samplerates && > f->inputs[i]->out_channel_layouts)) > return 0; > + if (f->inputs[i]->type == AVMEDIA_TYPE_VIDEO && > + !(f->inputs[i]->out_color_ranges)) > + return 0; > } > for (i = 0; i < f->nb_outputs; i++) { > if (!f->outputs[i]->in_formats) > @@ -368,6 +371,9 @@ static int formats_declared(AVFilterContext *f) > !(f->outputs[i]->in_samplerates && > f->outputs[i]->in_channel_layouts)) > return 0; > + if (f->outputs[i]->type == AVMEDIA_TYPE_VIDEO && > + !(f->outputs[i]->in_color_ranges)) > + return 0; > } > return 1; > } > @@ -485,6 +491,15 @@ static int query_formats(AVFilterGraph *graph, AVClass > *log_ctx) > convert_needed = 1; > } > > + if (link->type == AVMEDIA_TYPE_VIDEO) { > + if (link->in_color_ranges != link->out_color_ranges > + && link->in_color_ranges && link->out_color_ranges) > + if (!can_merge_formats(link->in_color_ranges, > + link->out_color_ranges, > + 0, 1)) > + convert_needed = 1; > + } > + > #define MERGE_DISPATCH(field, statement) > \ > if (!(link->in_ ## field && link->out_ ## field)) { > \ > count_delayed++; > \ > @@ -507,6 +522,13 @@ static int query_formats(AVFilterGraph *graph, AVClass > *log_ctx) > convert_needed = 1; > ) > } > + if (link->type == AVMEDIA_TYPE_VIDEO) { > + MERGE_DISPATCH(color_ranges, > + if (!ff_merge_samplerates(link->in_color_ranges, > + link->out_color_ranges)) Did you use ff_merge_samplerates() instead of ff_merge_formats on purpose? IIRC, ff_merge_samplerates() makes a special case. > + convert_needed = 1; > + ) > + } > MERGE_DISPATCH(formats, > if (!ff_merge_formats(link->in_formats, link->out_formats, > link->type)) > @@ -580,6 +602,12 @@ static int query_formats(AVFilterGraph *graph, AVClass > *log_ctx) > av_assert0( inlink->out_formats->refcount > 0); > av_assert0(outlink-> in_formats->refcount > 0); > av_assert0(outlink->out_formats->refcount > 0); > + if (outlink->type == AVMEDIA_TYPE_VIDEO) { > + av_assert0( inlink-> in_color_ranges->refcount > 0); > + av_assert0( inlink->out_color_ranges->refcount > 0); > + av_assert0(outlink-> in_color_ranges->refcount > 0); > + av_assert0(outlink->out_color_ranges->refcount > 0); > + } > if (outlink->type == AVMEDIA_TYPE_AUDIO) { > av_assert0( inlink-> in_samplerates->refcount > 0); > av_assert0( inlink->out_samplerates->refcount > 0); > @@ -593,6 +621,12 @@ static int query_formats(AVFilterGraph *graph, AVClass > *log_ctx) > if (!ff_merge_formats( inlink->in_formats, > inlink->out_formats, inlink->type) || > !ff_merge_formats(outlink->in_formats, > outlink->out_formats, outlink->type)) > ret = AVERROR(ENOSYS); > + if (inlink->type == AVMEDIA_TYPE_VIDEO && > + (!ff_merge_samplerates(inlink->in_color_ranges, > inlink->out_color_ranges))) > + ret = AVERROR(ENOSYS); > + if (outlink->type == AVMEDIA_TYPE_VIDEO && > + (!ff_merge_samplerates(outlink->in_color_ranges, > outlink->out_color_ranges))) > + ret = AVERROR(ENOSYS); > if (inlink->type == AVMEDIA_TYPE_AUDIO && > (!ff_merge_samplerates(inlink->in_samplerates, > inlink->out_samplerates) || > diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c > index 897396cac4..8fe109106b 100644 > --- a/libavfilter/buffersink.c > +++ b/libavfilter/buffersink.c > @@ -45,6 +45,8 @@ typedef struct BufferSinkContext { > /* only used for video */ > enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel > formats, must be terminated with -1 > int pixel_fmts_size; > + enum AVColorRange *color_ranges; ///< list of accepted color > ranges, must be terminated with 0 > + int color_ranges_size; > > /* only used for audio */ > enum AVSampleFormat *sample_fmts; ///< list of accepted sample > formats, terminated by AV_SAMPLE_FMT_NONE > @@ -130,11 +132,13 @@ int attribute_align_arg > av_buffersink_get_samples(AVFilterContext *ctx, > AVBufferSinkParams *av_buffersink_params_alloc(void) > { > static const int pixel_fmts[] = { AV_PIX_FMT_NONE }; > + static const int color_ranges[] = { -1}; > AVBufferSinkParams *params = av_malloc(sizeof(AVBufferSinkParams)); > if (!params) > return NULL; > > params->pixel_fmts = pixel_fmts; > + params->color_ranges = color_ranges; > return params; > } > > @@ -211,6 +215,8 @@ static av_cold int vsink_init(AVFilterContext *ctx, void > *opaque) > if (params) { > if ((ret = av_opt_set_int_list(buf, "pix_fmts", params->pixel_fmts, > AV_PIX_FMT_NONE, 0)) < 0) > return ret; > + if ((ret = av_opt_set_int_list(buf, "color_ranges", > params->color_ranges, -1, 0)) < 0) > + return ret; > } > > return common_init(ctx); > @@ -227,16 +233,25 @@ static int vsink_query_formats(AVFilterContext *ctx) > { > BufferSinkContext *buf = ctx->priv; > AVFilterFormats *formats = NULL; > + AVFilterFormats *color_ranges = NULL; > unsigned i; > int ret; > > CHECK_LIST_SIZE(pixel_fmts) > + CHECK_LIST_SIZE(color_ranges) > if (buf->pixel_fmts_size) { > for (i = 0; i < NB_ITEMS(buf->pixel_fmts); i++) > if ((ret = ff_add_format(&formats, buf->pixel_fmts[i])) < 0) > return ret; > if ((ret = ff_set_common_formats(ctx, formats)) < 0) > return ret; > + } > + if (buf->color_ranges_size) { > + for (i = 0; i < NB_ITEMS(buf->color_ranges); i++) > + if ((ret = ff_add_format(&color_ranges, buf->color_ranges[i])) < > 0) > + return ret; > + if ((ret = ff_set_common_color_ranges(ctx, color_ranges)) < 0) > + return ret; > } else { > if ((ret = ff_default_query_formats(ctx)) < 0) > return ret; > @@ -318,6 +333,7 @@ static int asink_query_formats(AVFilterContext *ctx) > #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM > static const AVOption buffersink_options[] = { > { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), > AV_OPT_TYPE_BINARY, .flags = FLAGS }, > + { "color_ranges", "set the supported color ranges", > OFFSET(color_ranges), AV_OPT_TYPE_BINARY, .flags = FLAGS }, > { NULL }, > }; > #undef FLAGS > diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h > index e6d6504832..3a74a039a2 100644 > --- a/libavfilter/buffersink.h > +++ b/libavfilter/buffersink.h > @@ -64,6 +64,7 @@ int av_buffersink_get_frame_flags(AVFilterContext *ctx, > AVFrame *frame, int flag > */ > typedef struct AVBufferSinkParams { > const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel > formats, terminated by AV_PIX_FMT_NONE > + const enum AVPixelFormat *color_ranges; ///< list of allowed color > ranges, terminated by AVCOL_RANGE_UNSPECIFIED > } AVBufferSinkParams; > > /** > diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c > index 51a1a9fb49..e450a2bca7 100644 > --- a/libavfilter/buffersrc.c > +++ b/libavfilter/buffersrc.c > @@ -412,6 +412,7 @@ static int query_formats(AVFilterContext *ctx) > BufferSourceContext *c = ctx->priv; > AVFilterChannelLayouts *channel_layouts = NULL; > AVFilterFormats *formats = NULL; > + AVFilterFormats *color_ranges = NULL; > AVFilterFormats *samplerates = NULL; > int ret; > > @@ -420,6 +421,9 @@ static int query_formats(AVFilterContext *ctx) > if ((ret = ff_add_format (&formats, c->pix_fmt)) < 0 || > (ret = ff_set_common_formats (ctx , formats )) < 0) > return ret; > + if ((ret = ff_add_format (&color_ranges, c->color_range)) < > 0 || > + (ret = ff_set_common_color_ranges(ctx, color_ranges)) < 0) > + return ret; > break; > case AVMEDIA_TYPE_AUDIO: > if ((ret = ff_add_format (&formats , c->sample_fmt )) > < 0 || > diff --git a/libavfilter/formats.c b/libavfilter/formats.c > index d4de862237..560b348524 100644 > --- a/libavfilter/formats.c > +++ b/libavfilter/formats.c > @@ -289,6 +289,15 @@ AVFilterFormats *ff_make_format_list(const int *fmts) > return formats; > } > > +AVFilterFormats *ff_make_color_range_list(const int *fmts) Looks strange. It seems you are aiming for type safety, but the parameter is still int. > +{ > + MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats); > + while (count--) > + formats->formats[count] = fmts[count]; > + > + return formats; > +} > + > AVFilterChannelLayouts *ff_make_formatu64_list(const uint64_t *fmts) > { > MAKE_FORMAT_LIST(AVFilterChannelLayouts, > @@ -398,6 +407,37 @@ AVFilterFormats *ff_all_samplerates(void) > return ret; > } > > +AVFilterFormats *ff_jpeg_color_ranges(void) > +{ > + AVFilterFormats *ret = NULL; > + > + if (ff_add_format(&ret, AVCOL_RANGE_JPEG) < 0) > + return NULL; > + > + return ret; > +} > + > +AVFilterFormats *ff_mpeg_color_ranges(void) > +{ > + AVFilterFormats *ret = NULL; > + > + if (ff_add_format(&ret, AVCOL_RANGE_MPEG) < 0) > + return NULL; > + > + return ret; I think one function to return a list with a single element would be more convenient. Do we not already have that? > +} > + > +AVFilterFormats *ff_all_color_ranges(void) > +{ > + AVFilterFormats *fmts = NULL; > + int ret; > + > + ret = ff_add_format(&fmts, AVCOL_RANGE_UNSPECIFIED); > + ret = ff_add_format(&fmts, AVCOL_RANGE_MPEG); > + ret = ff_add_format(&fmts, AVCOL_RANGE_JPEG); > + return fmts; > +} > + > AVFilterChannelLayouts *ff_all_channel_layouts(void) > { > AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); > @@ -560,6 +600,13 @@ int ff_set_common_samplerates(AVFilterContext *ctx, > ff_formats_ref, ff_formats_unref, formats); > } > > +int ff_set_common_color_ranges(AVFilterContext *ctx, > + AVFilterFormats *color_ranges) > +{ > + SET_COMMON_FORMATS(ctx, color_ranges, in_color_ranges, out_color_ranges, > + ff_formats_ref, ff_formats_unref, formats); > +} > + > /** > * A helper for query_formats() which sets all links to the same list of > * formats. If there are no links hooked to this filter, the list of formats > is > @@ -590,6 +637,11 @@ static int default_query_formats_common(AVFilterContext > *ctx, > if (ret < 0) > return ret; > } > + if (type == AVMEDIA_TYPE_VIDEO) { > + ret = ff_set_common_color_ranges(ctx, ff_all_color_ranges()); > + if (ret < 0) > + return ret; > + } > > return 0; > } > @@ -659,6 +711,17 @@ int ff_parse_sample_rate(int *ret, const char *arg, void > *log_ctx) > return 0; > } > > +int ff_parse_color_range(int *ret, const char *arg, void *log_ctx) > +{ > + int color_range = av_color_range_from_name(arg); > + if (color_range < 0) { > + av_log(log_ctx, AV_LOG_ERROR, "Invalid color range '%s'\n", arg); > + return AVERROR(EINVAL); > + } > + *ret = color_range; > + return 0; > +} > + > int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, > void *log_ctx) > { > diff --git a/libavfilter/formats.h b/libavfilter/formats.h > index 870809b5a0..6706f76dce 100644 > --- a/libavfilter/formats.h > +++ b/libavfilter/formats.h > @@ -166,6 +166,9 @@ av_warn_unused_result > int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); > > av_warn_unused_result > +int ff_set_common_color_ranges(AVFilterContext *ctx, AVFilterFormats > *color_ranges); > + > +av_warn_unused_result > int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t > channel_layout); > > /** > @@ -205,6 +208,16 @@ av_warn_unused_result > AVFilterFormats *ff_make_format_list(const int *fmts); > > /** > + * Create a list of supported color ranges. This is intended for use in > + * AVFilter->query_formats(). > + * > + * @param fmts list of color ranges, terminated by -1 > + * @return the format list, with no existing references > + */ > +av_warn_unused_result > +AVFilterFormats *ff_make_color_range_list(const int *color_ranges); > + > +/** > * Add fmt to the list of media formats contained in *avff. > * If *avff is NULL the function allocates the filter formats struct > * and puts its pointer in *avff. > @@ -222,6 +235,24 @@ av_warn_unused_result > AVFilterFormats *ff_all_formats(enum AVMediaType type); > > /** > + * Return a list of all color ranges supported by FFmpeg. > + */ > +av_warn_unused_result > +AVFilterFormats *ff_all_color_ranges(void); > + > +/** > + * Return a list of all mpeg color ranges supported by FFmpeg. > + */ > +av_warn_unused_result > +AVFilterFormats *ff_mpeg_color_ranges(void); > + > +/** > + * Return a list of all jpeg color ranges supported by FFmpeg. > + */ > +av_warn_unused_result > +AVFilterFormats *ff_jpeg_color_ranges(void); > + > +/** > * Construct a formats list containing all planar sample formats. > */ > av_warn_unused_result > diff --git a/libavfilter/internal.h b/libavfilter/internal.h > index f9679ed1d7..ca806d9443 100644 > --- a/libavfilter/internal.h > +++ b/libavfilter/internal.h > @@ -191,6 +191,17 @@ av_warn_unused_result > int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx); > > /** > + * Parse a color range. > + * > + * @param ret unsigned enum pointer to where the value should be written > + * @param arg string to parse > + * @param log_ctx log context > + * @return >= 0 in case of success, a negative AVERROR code on error > + */ > +av_warn_unused_result > +int ff_parse_color_range(int *ret, const char *arg, void *log_ctx); > + > +/** > * Parse a time base. > * > * @param ret unsigned AVRational pointer to where the value should be > written > diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c > index a57c99d797..067c03aa5a 100644 > --- a/libavfilter/vf_format.c > +++ b/libavfilter/vf_format.c > @@ -38,18 +38,21 @@ > typedef struct FormatContext { > const AVClass *class; > char *pix_fmts; > + char *color_ranges_str; > > /** > * pix_fmts parsed into AVPixelFormats and terminated with > * AV_PIX_FMT_NONE > */ > enum AVPixelFormat *formats; > + int *color_ranges; > } FormatContext; > > static av_cold void uninit(AVFilterContext *ctx) > { > FormatContext *s = ctx->priv; > av_freep(&s->formats); > + av_freep(&s->color_ranges); > } > > static av_cold int init(AVFilterContext *ctx) > @@ -57,6 +60,7 @@ static av_cold int init(AVFilterContext *ctx) > FormatContext *s = ctx->priv; > char *cur, *sep; > int nb_formats = 1; > + int nb_color_ranges = 1; > int i; > int ret; > > @@ -91,6 +95,37 @@ static av_cold int init(AVFilterContext *ctx) > } > s->formats[nb_formats] = AV_PIX_FMT_NONE; > > + if (!s->color_ranges_str) { > + av_log(ctx, AV_LOG_ERROR, "Empty output color range string.\n"); > + return AVERROR(EINVAL); > + } > + > + /* count the color ranges */ > + cur = s->color_ranges_str; > + while ((cur = strchr(cur, '|'))) { > + nb_color_ranges++; > + if (*cur) > + cur++; > + } > + > + s->color_ranges = av_malloc_array(nb_color_ranges + 1, > sizeof(*s->color_ranges)); > + if (!s->color_ranges) > + return AVERROR(ENOMEM); > + > + /* parse the list of formats */ > + cur = s->color_ranges_str; > + for (i = 0; i < nb_color_ranges; i++) { > + sep = strchr(cur, '|'); > + if (sep) > + *sep++ = 0; > + > + if ((ret = ff_parse_color_range(&s->color_ranges[i], cur, ctx)) < 0) > + return ret; > + > + cur = sep; > + } > + s->color_ranges[nb_color_ranges] = -1; > + > if (!strcmp(ctx->filter->name, "noformat")) { > const AVPixFmtDescriptor *desc = NULL; > enum AVPixelFormat *formats_allowed; > @@ -130,17 +165,26 @@ static int query_formats(AVFilterContext *ctx) > { > FormatContext *s = ctx->priv; > AVFilterFormats *formats = ff_make_format_list(s->formats); > + AVFilterFormats *color_ranges = > ff_make_color_range_list(s->color_ranges); > + int ret; > > if (!formats) > return AVERROR(ENOMEM); > > - return ff_set_common_formats(ctx, formats); > + ret = ff_set_common_formats(ctx, formats); > + if (ret < 0) > + return ret; > + > + if (!color_ranges) > + return AVERROR(ENOMEM); > + return ff_set_common_color_ranges(ctx, color_ranges); > } > > > #define OFFSET(x) offsetof(FormatContext, x) > static const AVOption options[] = { > { "pix_fmts", "A '|'-separated list of pixel formats", OFFSET(pix_fmts), > AV_OPT_TYPE_STRING, .flags = AV_OPT_FLAG_VIDEO_PARAM | > AV_OPT_FLAG_FILTERING_PARAM }, > + { "color_ranges", "A '|'-separated list of color ranges", > OFFSET(color_ranges_str), AV_OPT_TYPE_STRING, .flags = > AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM }, > { NULL } > }; > > diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c > index abdf04708b..c7af77b669 100644 > --- a/libavfilter/vf_noise.c > +++ b/libavfilter/vf_noise.c > @@ -142,7 +142,11 @@ static int query_formats(AVFilterContext *ctx) > return ret; > } > > - return ff_set_common_formats(ctx, formats); > + ret = ff_set_common_formats(ctx, formats); > + if (ret < 0) > + return ret; > + > + return ff_set_common_color_ranges(ctx, ff_all_color_ranges()); > } > > static int config_input(AVFilterLink *inlink) > diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c > index 802f841cc3..a571673b37 100644 > --- a/libavfilter/vf_scale.c > +++ b/libavfilter/vf_scale.c > @@ -157,7 +157,9 @@ static av_cold void uninit(AVFilterContext *ctx) > > static int query_formats(AVFilterContext *ctx) > { > + ScaleContext *scale = ctx->priv; > AVFilterFormats *formats; > + AVFilterFormats *color_ranges; > enum AVPixelFormat pix_fmt; > int ret; > > @@ -174,10 +176,14 @@ static int query_formats(AVFilterContext *ctx) > } > if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->out_formats)) < > 0) > return ret; > + color_ranges = ff_all_color_ranges(); > + if ((ret = ff_formats_ref(color_ranges, > &ctx->inputs[0]->out_color_ranges)) < 0) > + return ret; > } > if (ctx->outputs[0]) { > const AVPixFmtDescriptor *desc = NULL; > formats = NULL; > + color_ranges = NULL; > while ((desc = av_pix_fmt_desc_next(desc))) { > pix_fmt = av_pix_fmt_desc_get_id(desc); > if ((sws_isSupportedOutput(pix_fmt) || pix_fmt == > AV_PIX_FMT_PAL8 || > @@ -188,6 +194,12 @@ static int query_formats(AVFilterContext *ctx) > } > if ((ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < > 0) > return ret; > + > + ret = ff_add_format(&color_ranges, scale->out_range ? > scale->out_range : AVCOL_RANGE_MPEG); > + if (ret < 0) > + return ret; > + if ((ret = ff_formats_ref(color_ranges, > &ctx->outputs[0]->in_color_ranges)) < 0) > + return ret; > } > > return 0; > @@ -276,6 +288,7 @@ static int config_props(AVFilterLink *outlink) > scale->isws[0] = scale->isws[1] = scale->sws = NULL; > if (inlink0->w == outlink->w && > inlink0->h == outlink->h && > + inlink0->color_range == outlink->color_range && > !scale->out_color_matrix && > scale->in_range == scale->out_range && > inlink0->format == outlink->format) > @@ -348,11 +361,11 @@ static int config_props(AVFilterLink *outlink) > } else > outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio; > > - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d > fmt:%s sar:%d/%d flags:0x%0x\n", > + av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d cr:%d -> w:%d > h:%d fmt:%s sar:%d/%d cr:%d flags:0x%0x\n", > inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format), > - inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, > + inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, > inlink->color_range, > outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format), > - outlink->sample_aspect_ratio.num, > outlink->sample_aspect_ratio.den, > + outlink->sample_aspect_ratio.num, > outlink->sample_aspect_ratio.den, outlink->color_range, > scale->flags); > return 0; > > diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c > index eb12335472..a531e76f06 100644 > --- a/libavfilter/vsrc_testsrc.c > +++ b/libavfilter/vsrc_testsrc.c > @@ -207,7 +207,13 @@ static av_cold int color_init(AVFilterContext *ctx) > > static int color_query_formats(AVFilterContext *ctx) > { > - return ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); > + int ret; > + > + ret = ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); > + if (ret < 0) > + return ret; > + > + return ff_set_common_color_ranges(ctx, ff_mpeg_color_ranges()); > } > > static int color_config_props(AVFilterLink *inlink) > @@ -653,11 +659,16 @@ static int test_query_formats(AVFilterContext *ctx) > static const enum AVPixelFormat pix_fmts[] = { > AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE > }; > + int ret; > > AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); > if (!fmts_list) > return AVERROR(ENOMEM); > - return ff_set_common_formats(ctx, fmts_list); > + ret = ff_set_common_formats(ctx, fmts_list); > + if (ret < 0) > + return ret; > + > + return ff_set_common_color_ranges(ctx, ff_jpeg_color_ranges()); > } > > static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = { Regards, -- Nicolas George
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel