vf_format.c 4.9 KB
Newer Older
1
/*
2
 * Copyright (c) 2007 Bobby Bingham
3
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav is free software; you can redistribute it and/or
7 8 9 10
 * 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.
 *
11
 * Libav is distributed in the hope that it will be useful,
12 13 14 15 16
 * 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
17
 * License along with Libav; if not, write to the Free Software
18 19 20 21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
22
 * @file
S
Stefano Sabatini 已提交
23
 * format and noformat video filters
24 25
 */

26
#include "libavutil/pixdesc.h"
27
#include "avfilter.h"
28
#include "video.h"
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

typedef struct {
    /**
     * List of flags telling if a given image format has been listed
     * as argument to the filter.
     */
    int listed_pix_fmt_flags[PIX_FMT_NB];
} FormatContext;

#define PIX_FMT_NAME_MAXSIZE 32

static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
    FormatContext *format = ctx->priv;
    const char *cur, *sep;
    char             pix_fmt_name[PIX_FMT_NAME_MAXSIZE];
    int              pix_fmt_name_len;
    enum PixelFormat pix_fmt;

    /* parse the list of formats */
    for (cur = args; cur; cur = sep ? sep+1 : NULL) {
        if (!(sep = strchr(cur, ':')))
            pix_fmt_name_len = strlen(cur);
        else
            pix_fmt_name_len = sep - cur;
        if (pix_fmt_name_len >= PIX_FMT_NAME_MAXSIZE) {
            av_log(ctx, AV_LOG_ERROR, "Format name too long\n");
            return -1;
        }

        memcpy(pix_fmt_name, cur, pix_fmt_name_len);
        pix_fmt_name[pix_fmt_name_len] = 0;
61
        pix_fmt = av_get_pix_fmt(pix_fmt_name);
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

        if (pix_fmt == PIX_FMT_NONE) {
            av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: %s\n", pix_fmt_name);
            return -1;
        }

        format->listed_pix_fmt_flags[pix_fmt] = 1;
    }

    return 0;
}

static AVFilterFormats *make_format_list(FormatContext *format, int flag)
{
    AVFilterFormats *formats;
    enum PixelFormat pix_fmt;

    formats = av_mallocz(sizeof(AVFilterFormats));
    formats->formats = av_malloc(sizeof(enum PixelFormat) * PIX_FMT_NB);

    for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++)
        if (format->listed_pix_fmt_flags[pix_fmt] == flag)
            formats->formats[formats->format_count++] = pix_fmt;

    return formats;
}

89
#if CONFIG_FORMAT_FILTER
90 91 92 93 94 95
static int query_formats_format(AVFilterContext *ctx)
{
    avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1));
    return 0;
}

96 97
AVFilter avfilter_vf_format = {
    .name      = "format",
98
    .description = NULL_IF_CONFIG_SMALL("Convert the input video to one of the specified pixel formats."),
99 100 101 102 103 104 105 106

    .init      = init,

    .query_formats = query_formats_format,

    .priv_size = sizeof(FormatContext),

    .inputs    = (AVFilterPad[]) {{ .name            = "default",
107
                                    .type            = AVMEDIA_TYPE_VIDEO,
108 109 110 111
                                    .get_video_buffer= ff_null_get_video_buffer,
                                    .start_frame     = ff_null_start_frame,
                                    .draw_slice      = ff_null_draw_slice,
                                    .end_frame       = ff_null_end_frame, },
112 113
                                  { .name = NULL}},
    .outputs   = (AVFilterPad[]) {{ .name            = "default",
114
                                    .type            = AVMEDIA_TYPE_VIDEO },
115 116
                                  { .name = NULL}},
};
117
#endif /* CONFIG_FORMAT_FILTER */
118

119
#if CONFIG_NOFORMAT_FILTER
120 121 122 123 124 125
static int query_formats_noformat(AVFilterContext *ctx)
{
    avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0));
    return 0;
}

126 127
AVFilter avfilter_vf_noformat = {
    .name      = "noformat",
128
    .description = NULL_IF_CONFIG_SMALL("Force libavfilter not to use any of the specified pixel formats for the input to the next filter."),
129 130 131 132 133 134 135 136

    .init      = init,

    .query_formats = query_formats_noformat,

    .priv_size = sizeof(FormatContext),

    .inputs    = (AVFilterPad[]) {{ .name            = "default",
137
                                    .type            = AVMEDIA_TYPE_VIDEO,
138 139 140 141
                                    .get_video_buffer= ff_null_get_video_buffer,
                                    .start_frame     = ff_null_start_frame,
                                    .draw_slice      = ff_null_draw_slice,
                                    .end_frame       = ff_null_end_frame, },
142 143
                                  { .name = NULL}},
    .outputs   = (AVFilterPad[]) {{ .name            = "default",
144
                                    .type            = AVMEDIA_TYPE_VIDEO },
145 146
                                  { .name = NULL}},
};
147
#endif /* CONFIG_NOFORMAT_FILTER */