| @@ -0,0 +1,154 @@ |
| 1 | +/* |
| 2 | + * copyright (c) 2007 Bobby Bingham |
| 3 | + * |
| 4 | + * This file is part of FFmpeg. |
| 5 | + * |
| 6 | + * FFmpeg is free software; you can redistribute it and/or |
| 7 | + * modify it under the terms of the GNU Lesser General Public |
| 8 | + * License as published by the Free Software Foundation; either |
| 9 | + * version 2.1 of the License, or (at your option) any later version. |
| 10 | + * |
| 11 | + * FFmpeg is distributed in the hope that it will be useful, |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | + * Lesser General Public License for more details. |
| 15 | + * |
| 16 | + * You should have received a copy of the GNU Lesser General Public |
| 17 | + * License along with FFmpeg; if not, write to the Free Software |
| 18 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | + */ |
| 20 | + |
| 21 | +/** |
| 22 | + * @file libavfilter/vf_format.c |
| 23 | + * video format and noformat filters |
| 24 | + */ |
| 25 | + |
| 26 | +#include "avfilter.h" |
| 27 | + |
| 28 | +typedef struct { |
| 29 | + /** |
| 30 | + * List of flags telling if a given image format has been listed |
| 31 | + * as argument to the filter. |
| 32 | + */ |
| 33 | + int listed_pix_fmt_flags[PIX_FMT_NB]; |
| 34 | +} FormatContext; |
| 35 | + |
| 36 | +#define PIX_FMT_NAME_MAXSIZE 32 |
| 37 | + |
| 38 | +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 39 | +{ |
| 40 | + FormatContext *format = ctx->priv; |
| 41 | + const char *cur, *sep; |
| 42 | + char pix_fmt_name[PIX_FMT_NAME_MAXSIZE]; |
| 43 | + int pix_fmt_name_len; |
| 44 | + enum PixelFormat pix_fmt; |
| 45 | + |
| 46 | + /* parse the list of formats */ |
| 47 | + for (cur = args; cur; cur = sep ? sep+1 : NULL) { |
| 48 | + if (!(sep = strchr(cur, ':'))) |
| 49 | + pix_fmt_name_len = strlen(cur); |
| 50 | + else |
| 51 | + pix_fmt_name_len = sep - cur; |
| 52 | + if (pix_fmt_name_len >= PIX_FMT_NAME_MAXSIZE) { |
| 53 | + av_log(ctx, AV_LOG_ERROR, "Format name too long\n"); |
| 54 | + return -1; |
| 55 | + } |
| 56 | + |
| 57 | + memcpy(pix_fmt_name, cur, pix_fmt_name_len); |
| 58 | + pix_fmt_name[pix_fmt_name_len] = 0; |
| 59 | + pix_fmt = avcodec_get_pix_fmt(pix_fmt_name); |
| 60 | + |
| 61 | + if (pix_fmt == PIX_FMT_NONE) { |
| 62 | + av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: %s\n", pix_fmt_name); |
| 63 | + return -1; |
| 64 | + } |
| 65 | + |
| 66 | + format->listed_pix_fmt_flags[pix_fmt] = 1; |
| 67 | + } |
| 68 | + |
| 69 | + return 0; |
| 70 | +} |
| 71 | + |
| 72 | +static AVFilterFormats *make_format_list(FormatContext *format, int flag) |
| 73 | +{ |
| 74 | + AVFilterFormats *formats; |
| 75 | + enum PixelFormat pix_fmt; |
| 76 | + |
| 77 | + formats = av_mallocz(sizeof(AVFilterFormats)); |
| 78 | + formats->formats = av_malloc(sizeof(enum PixelFormat) * PIX_FMT_NB); |
| 79 | + |
| 80 | + for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) |
| 81 | + if (format->listed_pix_fmt_flags[pix_fmt] == flag) |
| 82 | + formats->formats[formats->format_count++] = pix_fmt; |
| 83 | + |
| 84 | + return formats; |
| 85 | +} |
| 86 | + |
| 87 | +static int query_formats_format(AVFilterContext *ctx) |
| 88 | +{ |
| 89 | + avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); |
| 90 | + return 0; |
| 91 | +} |
| 92 | + |
| 93 | +static int query_formats_noformat(AVFilterContext *ctx) |
| 94 | +{ |
| 95 | + avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); |
| 96 | + return 0; |
| 97 | +} |
| 98 | + |
| 99 | +static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) |
| 100 | +{ |
| 101 | + avfilter_start_frame(link->dst->outputs[0], picref); |
| 102 | +} |
| 103 | + |
| 104 | +static void end_frame(AVFilterLink *link) |
| 105 | +{ |
| 106 | + avfilter_end_frame(link->dst->outputs[0]); |
| 107 | +} |
| 108 | + |
| 109 | +static void draw_slice(AVFilterLink *link, int y, int h) |
| 110 | +{ |
| 111 | + avfilter_draw_slice(link->dst->outputs[0], y, h); |
| 112 | +} |
| 113 | + |
| 114 | +AVFilter avfilter_vf_format = { |
| 115 | + .name = "format", |
| 116 | + .description = "Convert the input video to one of the specified pixel formats.", |
| 117 | + |
| 118 | + .init = init, |
| 119 | + |
| 120 | + .query_formats = query_formats_format, |
| 121 | + |
| 122 | + .priv_size = sizeof(FormatContext), |
| 123 | + |
| 124 | + .inputs = (AVFilterPad[]) {{ .name = "default", |
| 125 | + .type = CODEC_TYPE_VIDEO, |
| 126 | + .start_frame = start_frame, |
| 127 | + .draw_slice = draw_slice, |
| 128 | + .end_frame = end_frame, }, |
| 129 | + { .name = NULL}}, |
| 130 | + .outputs = (AVFilterPad[]) {{ .name = "default", |
| 131 | + .type = CODEC_TYPE_VIDEO }, |
| 132 | + { .name = NULL}}, |
| 133 | +}; |
| 134 | + |
| 135 | +AVFilter avfilter_vf_noformat = { |
| 136 | + .name = "noformat", |
| 137 | + .description = "Force libavfilter not to use any of the specified pixel formats as the input to the next filter.", |
| 138 | + |
| 139 | + .init = init, |
| 140 | + |
| 141 | + .query_formats = query_formats_noformat, |
| 142 | + |
| 143 | + .priv_size = sizeof(FormatContext), |
| 144 | + |
| 145 | + .inputs = (AVFilterPad[]) {{ .name = "default", |
| 146 | + .type = CODEC_TYPE_VIDEO, |
| 147 | + .start_frame = start_frame, |
| 148 | + .draw_slice = draw_slice, |
| 149 | + .end_frame = end_frame, }, |
| 150 | + { .name = NULL}}, |
| 151 | + .outputs = (AVFilterPad[]) {{ .name = "default", |
| 152 | + .type = CODEC_TYPE_VIDEO }, |
| 153 | + { .name = NULL}}, |
| 154 | +}; |