[FFmpeg-devel] [PATCH] lavfi: add pp filter.
Clément Bœsch
ubitux at gmail.com
Wed Dec 12 20:56:02 CET 2012
On Wed, Dec 12, 2012 at 01:18:55PM +0100, Stefano Sabatini wrote:
[...]
> > + at section pp
> > +
> > +Enables the specified chain of postprocessing subfilters using libpostproc.
>
> Nit: "Enable" for overall consistency.
>
Fixed locally.
> Also mention that this needs libpostproc to be enabled (mentioning
> --enable-gpl may also avoid some user complaints).
>
Added "This library should be automatically selected with a GPL build
(@code{--enable-gpl})."
> > +Subfilters must be separated by '/' and can be disabled by prepending a '-'.
> > +Each subfilter and some options have a short and a long name that can be used
> > +interchangeably, i.e. dr/dering are the same.
>
> Missing description of how to specify options.
>
After the option list, just added: "These options can be appended after
the subfilter name, separated by a ':'."
> > +All subfilters share common options to determine their scope:
>
> I believe that libpp parameters/library deserve a dedicated document
> (for the same reason libswresample/libswscale parameters should not be
> documented in filters.texi).
>
Yes, I just merely copy pasted the filter documentation from MPlayer, I
believe it can be moved later. What's the state of the
> > +
> > + at table @option
> > + at item a/autoq
> > +Automatically switch the subfilter off if the CPU is too slow.
> > +
Note: this option needs to be documented differently; the idea is to be
able to switch the quality using commands. The CPU-too-slow trigger does
not exist in FFmpeg, so the quality never changes (unless you use the
command system).
[...]
> > + at itemize
> > + at item
> > +Horizontal and vertical deblocking, deringing and automatic brightness/contrast:
> > + at example
> > +-vf pp=hb/vb/dr/al
> > + at end example
>
> Note: we usually omit the -vf part, and for good reasons, since
> filters.texi is not meant to be bound to ff* tools syntax.
>
Yep, forgot to remove, fixed locally.
> > +
> > + at item
> > +Default filters without brightness/contrast correction:
> > + at example
> > +-vf pp=de/-al
> > + at end example
> > +
> > + at item
> > +Enable default filters & temporal denoiser:
> > + at example
> > +-vf pp=default/tmpnoise:1:2:3
> > + at end example
> > +
> > + at item
>
> > +Horizontal deblocking on luminance only and switch vertical deblocking on or
>
> The verb missing.
>
It's just like the first two example "[here is how to do] horizontal
deblock + switch vertical deblock on/off:"
[...]
> > +static av_cold int pp_init(AVFilterContext *ctx, const char *args)
> > +{
> > + int i;
> > + PPFilterContext *pp = ctx->priv;
> > +
> > + if (!args || !*args)
> > + args = "de";
> > +
> > + for (i = 0; i <= PP_QUALITY_MAX; i++) {
> > + pp->modes[i] = pp_get_mode_by_name_and_quality(args, i);
> > + if (!pp->modes[i])
> > + return AVERROR_EXTERNAL;
> > + }
> > + pp->mode_id = PP_QUALITY_MAX;
> > + return 0;
>
> Not blocking, but maybe we can think about adding support for
> options. For example it may be useful to be able to set quality.
>
Well, given that pp uses ':' separator, good luck with this without making
the usage insane. You can still change quality using the command system
for subfilters with the 'a' switch.
> > +}
> > +
> > +static int pp_process_command(AVFilterContext *ctx, const char *cmd, const char *args,
> > + char *res, int res_len, int flags)
> > +{
> > + PPFilterContext *pp = ctx->priv;
> > +
> > + if (!strcmp(cmd, "quality")) {
> > + pp->mode_id = av_clip(strtol(args, NULL, 10), 0, PP_QUALITY_MAX);
> > + return 0;
> > + }
> > + return AVERROR(ENOSYS);
> > +}
> > +
> > +static int pp_query_formats(AVFilterContext *ctx)
> > +{
> > + static const enum PixelFormat pix_fmts[] = {
> > + AV_PIX_FMT_YUV420P,
> > + AV_PIX_FMT_YUV422P,
> > + AV_PIX_FMT_YUV411P,
> > + AV_PIX_FMT_YUV444P,
> > + AV_PIX_FMT_NONE
> > + };
> > + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
> > + return 0;
> > +}
> > +
> > +static int pp_config_props(AVFilterLink *inlink)
> > +{
> > + int flags = PP_CPU_CAPS_AUTO;
> > + PPFilterContext *pp = inlink->dst->priv;
> > +
> > + switch (inlink->format) {
> > + case AV_PIX_FMT_YUV420P: flags |= PP_FORMAT_420; break;
> > + case AV_PIX_FMT_YUV422P: flags |= PP_FORMAT_422; break;
> > + case AV_PIX_FMT_YUV411P: flags |= PP_FORMAT_411; break;
> > + case AV_PIX_FMT_YUV444P: flags |= PP_FORMAT_444; break;
> > + default: av_assert0(0);
> > + }
> > +
> > + pp->pp_ctx = pp_get_context(inlink->w, inlink->h, flags);
> > + if (!pp->pp_ctx)
> > + return AVERROR(ENOMEM);
> > + return 0;
> > +}
> > +
>
> > +static int pp_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
>
> I hate too generic variable names (in... inlink? inframe? inpad?) as
> they harm readability and slow me down when reading code.
>
Renamed in/out to inbuf/outbuf.
> > +{
> > + AVFilterContext *ctx = inlink->dst;
> > + PPFilterContext *pp = ctx->priv;
> > + AVFilterLink *outlink = ctx->outputs[0];
> > + const int aligned_w = FFALIGN(outlink->w, 8);
> > + const int aligned_h = FFALIGN(outlink->h, 8);
> > + AVFilterBufferRef *out;
> > +
> > + out = ff_get_video_buffer(outlink, AV_PERM_WRITE, aligned_w, aligned_h);
> > + if (!out) {
> > + avfilter_unref_buffer(in);
> > + return AVERROR(ENOMEM);
> > + }
> > + avfilter_copy_buffer_ref_props(out, in);
> > +
> > + pp_postprocess((const uint8_t **)in->data, in->linesize,
> > + out->data, out->linesize,
> > + aligned_w, outlink->h,
> > + out->video->qp_table,
> > + out->video->qp_table_linesize,
> > + pp->modes[pp->mode_id],
> > + pp->pp_ctx,
> > + out->video->pict_type);
> > +
> > + avfilter_unref_buffer(in);
> > + return ff_filter_frame(outlink, out);
> > +}
> > +
> > +static av_cold void pp_uninit(AVFilterContext *ctx)
> > +{
> > + int i;
> > + PPFilterContext *pp = ctx->priv;
> > +
> > + for (i = 0; i <= PP_QUALITY_MAX; i++)
> > + pp_free_mode(pp->modes[i]);
> > + if (pp->pp_ctx)
> > + pp_free_context(pp->pp_ctx);
> > +}
> > +
> > +static const AVFilterPad pp_inputs[] = {
> > + {
> > + .name = "default",
> > + .type = AVMEDIA_TYPE_VIDEO,
> > + .config_props = pp_config_props,
> > + .filter_frame = pp_filter_frame,
> > + .min_perms = AV_PERM_READ,
> > + },
> > + { NULL }
> > +};
> > +
> > +static const AVFilterPad pp_outputs[] = {
> > + {
> > + .name = "default",
> > + .type = AVMEDIA_TYPE_VIDEO,
> > + },
> > + { NULL }
> > +};
> > +
> > +AVFilter avfilter_vf_pp = {
> > + .name = "pp",
>
> > + .description = NULL_IF_CONFIG_SMALL("filter video using libpostproc"),
>
> "Filter video ... libpostproc."
>
This was obviously a new attempt to check if you were still checking the
description of filters, changed locally.
[...]
Thanks for the review :)
--
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121212/5eafb0a5/attachment.asc>
More information about the ffmpeg-devel
mailing list