[FFmpeg-devel] [PATCH] add fieldorder video filter
Mark Himsley
mark at mdsh.com
Sun Apr 3 23:21:30 CEST 2011
On 03/04/2011 15:21, Stefano Sabatini wrote:
> On date Friday 2011-04-01 19:31:41 +0100, Mark Himsley encoded:
>> On 31/03/11 15:15, Stefano Sabatini wrote:
>> >On date Thursday 2011-03-31 08:47:38 +0100, Mark Himsley encoded:
>> >>Second version of this filter. Renamed and updated from the
>> >>suggestions given for the first version.
[...]
>> diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
>> new file mode 100644
>> index 0000000..01ad315
>> --- /dev/null
>> +++ b/libavfilter/vf_fieldorder.c
>> @@ -0,0 +1,231 @@
>> +/*
>> + * video field order filter
>> + * copyright (c) 2011 Mark Himsley
>> + * Heavily influenced by vf_pad.c
>> + *
>> + * This file is part of FFmpeg.
>> + *
>> + * FFmpeg is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * FFmpeg is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + */
>> +
>> +/* #define DEBUG */
>> +
>> +#include "libavutil/pixdesc.h"
>> +#include "avfilter.h"
>> +#include "libavutil/imgutils.h"
Just realised that libavutil/imgutils.h isn't used.
>> +
>> +typedef struct
>> +{
>> + unsigned int dst_tff; ///< output bff/tff
>> + int line_step[4]; ///< bytes per pixel per each plane
>> + int hsub; ///< chroma subsampling value
>> +} FieldOrderContext;
>> +
>> +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
>> +{
>> + FieldOrderContext *fieldorder = ctx->priv;
>> +
>> + if (!args || !sscanf(args, "%u", &fieldorder->dst_tff) == 1) {
>> + av_log(ctx, AV_LOG_ERROR,
>> + "Expected 1 argument '#':'%s'\n", args);
>
> Usability nit:
>
> Expected 1 argument '#':'(null)'
>
> I suggest:
> One argument expected, none found in '%s'.
>
> Alternatively: assumes a default value (whatever is most likely to be
> the default).
>
>> + return AVERROR(EINVAL);
>> + }
>> + fieldorder->dst_tff = !!fieldorder->dst_tff;
>> +
>> + av_log(ctx, AV_LOG_INFO, "ttf:%d\n", fieldorder->dst_tff);
>
> typo: ttf -> tff
>
> Nit: maybe more useful when debugging:
> field:tff
> field:bff
>
> Also maybe we could support accepting string values in input, e.g.
> fieldorder=tff|bff
>
> which should be easier on the reader if she hasn't the manual at her
> hand.
Yes. That sounds like a nice feature.
>> +
>> + return 0;
>> +}
>> +
>> +static int query_formats(AVFilterContext *ctx)
>> +{
>> + AVFilterFormats *formats;
>> + enum PixelFormat pix_fmt;
>> + int ret;
>> +
>> + /** accept any input pixel format that is not hardware accelerated
>> + * and does not have vertically sub-sampled chroma */
>> + if (ctx->inputs[0]) {
>> + formats = NULL;
>> + for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++)
>> + if ( !(av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL)
>> + && av_pix_fmt_descriptors[pix_fmt].nb_components
>> + && !av_pix_fmt_descriptors[pix_fmt].log2_chroma_h
>> + && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) {
>> + avfilter_formats_unref(&formats);
>> + return ret;
>> + }
>> + avfilter_formats_ref(formats, &ctx->inputs[0]->out_formats);
>> + avfilter_formats_ref(formats, &ctx->outputs[0]->in_formats);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int config_input(AVFilterLink *inlink)
>> +{
>> + AVFilterContext *ctx = inlink->dst;
>> + FieldOrderContext *fieldorder = ctx->priv;
>> +
>> + int is_packed, component, plane;
>> +
>> + /** discover if the pixel format is packed or planar */
>> + is_packed = 1;
>> + for (component = 0; component < av_pix_fmt_descriptors[inlink->format].nb_components; component++) {
>> + if (av_pix_fmt_descriptors[inlink->format].comp[component].plane != 0) {
>> + is_packed = 0;
>> + }
>> + }
>> +
>> + /** discover the bytes per pixel for each plane */
>> + if (is_packed) {
>> + fieldorder->line_step[0] = av_get_bits_per_pixel(&av_pix_fmt_descriptors[inlink->format])>>3;
>> + } else {
>
>> + for (plane = 0; plane < 4; plane++) {
>> + fieldorder->line_step[plane] = 1 + (av_pix_fmt_descriptors[inlink->format].comp->depth_minus1 >> 3 );
>
> Uhm, just checked with the command:
>
> $ tools/lavfi-showfiltfmts fieldorder 1
> [fieldorder @ 0xaa30d20] ttf:1
> INPUT[0] default: yuyv422
> INPUT[0] default: rgb24
> INPUT[0] default: bgr24
> INPUT[0] default: yuv422p
> INPUT[0] default: yuv444p
> INPUT[0] default: yuv411p
> INPUT[0] default: gray
> INPUT[0] default: monow
> INPUT[0] default: monob
> INPUT[0] default: pal8
> INPUT[0] default: yuvj422p
> INPUT[0] default: yuvj444p
> INPUT[0] default: uyvy422
> INPUT[0] default: uyyvyy411
> INPUT[0] default: bgr8
> INPUT[0] default: bgr4
> INPUT[0] default: bgr4_byte
> INPUT[0] default: rgb8
> INPUT[0] default: rgb4
> INPUT[0] default: rgb4_byte
> INPUT[0] default: argb
> INPUT[0] default: rgba
> INPUT[0] default: abgr
> INPUT[0] default: bgra
> INPUT[0] default: gray16be
> INPUT[0] default: gray16le
> INPUT[0] default: rgb48be
> INPUT[0] default: rgb48le
> INPUT[0] default: rgb565be
> INPUT[0] default: rgb565le
> INPUT[0] default: rgb555be
> INPUT[0] default: rgb555le
> INPUT[0] default: bgr565be
> INPUT[0] default: bgr565le
> INPUT[0] default: bgr555be
> INPUT[0] default: bgr555le
> INPUT[0] default: yuv422p16le
> INPUT[0] default: yuv422p16be
> INPUT[0] default: yuv444p16le
> INPUT[0] default: yuv444p16be
> INPUT[0] default: rgb444be
> INPUT[0] default: rgb444le
> INPUT[0] default: bgr444be
> INPUT[0] default: bgr444le
> INPUT[0] default: y400a
> INPUT[0] default: bgr48le
> INPUT[0] default: bgr48be
> [...]
>
> I see that this should work with all the listed formats, but may break
> if we add support for formats of the kind:
> * bitstream formats with components on plane 2/3
> * formats which have more than one component on planes 2/3 with log2_chroma_h != 0
> (e.g. a freak variant of NV12, maybe Bayer formats?)
I hadn't thought about bitstream formats. Perhaps this filter should
also not accept PIX_FMT_BITSTREAM formats as well as PIX_FMT_HWACCEL
formats?
Personally, I prefer the programmatic determining if allowed formats
than having a fixed table that can get out of date - but I do see the
issues that could lead to if bad assumptions are made in the determining
logic. But I'm just a rookie around here.
Oh - and thanks for pointing out lavfi-showfiltfmts.
> On the other hand I see that it is not very likely to happen, but I'd
> still prefer to explicitely list the formats in query_formats().
> Other opinions, Michael?
>
> [...]
>
> Apart from this, no other comments from me, I can fix the usability
> issues myself with further commits, but I'm still a bit uneasy with
> the formats issue.
I can send a new version on Monday evening (GMT) removing the extra
include, tidying up init() and removing the bitstream formats from the
allowed formats.
--
Mark
More information about the ffmpeg-devel
mailing list