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 * 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 * Libav 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 Libav; 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 23 * format and noformat video filters 24 */ 25 26#include "libavutil/pixdesc.h" 27#include "avfilter.h" 28 29typedef struct { 30 /** 31 * List of flags telling if a given image format has been listed 32 * as argument to the filter. 33 */ 34 int listed_pix_fmt_flags[PIX_FMT_NB]; 35} FormatContext; 36 37#define PIX_FMT_NAME_MAXSIZE 32 38 39static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) 40{ 41 FormatContext *format = ctx->priv; 42 const char *cur, *sep; 43 char pix_fmt_name[PIX_FMT_NAME_MAXSIZE]; 44 int pix_fmt_name_len; 45 enum PixelFormat pix_fmt; 46 47 /* parse the list of formats */ 48 for (cur = args; cur; cur = sep ? sep+1 : NULL) { 49 if (!(sep = strchr(cur, ':'))) 50 pix_fmt_name_len = strlen(cur); 51 else 52 pix_fmt_name_len = sep - cur; 53 if (pix_fmt_name_len >= PIX_FMT_NAME_MAXSIZE) { 54 av_log(ctx, AV_LOG_ERROR, "Format name too long\n"); 55 return -1; 56 } 57 58 memcpy(pix_fmt_name, cur, pix_fmt_name_len); 59 pix_fmt_name[pix_fmt_name_len] = 0; 60 pix_fmt = av_get_pix_fmt(pix_fmt_name); 61 62 if (pix_fmt == PIX_FMT_NONE) { 63 av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: %s\n", pix_fmt_name); 64 return -1; 65 } 66 67 format->listed_pix_fmt_flags[pix_fmt] = 1; 68 } 69 70 return 0; 71} 72 73static AVFilterFormats *make_format_list(FormatContext *format, int flag) 74{ 75 AVFilterFormats *formats; 76 enum PixelFormat pix_fmt; 77 78 formats = av_mallocz(sizeof(AVFilterFormats)); 79 formats->formats = av_malloc(sizeof(enum PixelFormat) * PIX_FMT_NB); 80 81 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) 82 if (format->listed_pix_fmt_flags[pix_fmt] == flag) 83 formats->formats[formats->format_count++] = pix_fmt; 84 85 return formats; 86} 87 88#if CONFIG_FORMAT_FILTER 89static int query_formats_format(AVFilterContext *ctx) 90{ 91 avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); 92 return 0; 93} 94 95AVFilter avfilter_vf_format = { 96 .name = "format", 97 .description = NULL_IF_CONFIG_SMALL("Convert the input video to one of the specified pixel formats."), 98 99 .init = init, 100 101 .query_formats = query_formats_format, 102 103 .priv_size = sizeof(FormatContext), 104 105 .inputs = (AVFilterPad[]) {{ .name = "default", 106 .type = AVMEDIA_TYPE_VIDEO, 107 .get_video_buffer= avfilter_null_get_video_buffer, 108 .start_frame = avfilter_null_start_frame, 109 .draw_slice = avfilter_null_draw_slice, 110 .end_frame = avfilter_null_end_frame, }, 111 { .name = NULL}}, 112 .outputs = (AVFilterPad[]) {{ .name = "default", 113 .type = AVMEDIA_TYPE_VIDEO }, 114 { .name = NULL}}, 115}; 116#endif /* CONFIG_FORMAT_FILTER */ 117 118#if CONFIG_NOFORMAT_FILTER 119static int query_formats_noformat(AVFilterContext *ctx) 120{ 121 avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); 122 return 0; 123} 124 125AVFilter avfilter_vf_noformat = { 126 .name = "noformat", 127 .description = NULL_IF_CONFIG_SMALL("Force libavfilter not to use any of the specified pixel formats for the input to the next filter."), 128 129 .init = init, 130 131 .query_formats = query_formats_noformat, 132 133 .priv_size = sizeof(FormatContext), 134 135 .inputs = (AVFilterPad[]) {{ .name = "default", 136 .type = AVMEDIA_TYPE_VIDEO, 137 .get_video_buffer= avfilter_null_get_video_buffer, 138 .start_frame = avfilter_null_start_frame, 139 .draw_slice = avfilter_null_draw_slice, 140 .end_frame = avfilter_null_end_frame, }, 141 { .name = NULL}}, 142 .outputs = (AVFilterPad[]) {{ .name = "default", 143 .type = AVMEDIA_TYPE_VIDEO }, 144 { .name = NULL}}, 145}; 146#endif /* CONFIG_NOFORMAT_FILTER */ 147 148