| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of FFmpeg. | 2  * This file is part of FFmpeg. | 
| 3  * | 3  * | 
| 4  * FFmpeg is free software; you can redistribute it and/or | 4  * FFmpeg is free software; you can redistribute it and/or | 
| 5  * modify it under the terms of the GNU Lesser General Public | 5  * modify it under the terms of the GNU Lesser General Public | 
| 6  * License as published by the Free Software Foundation; either | 6  * License as published by the Free Software Foundation; either | 
| 7  * version 2.1 of the License, or (at your option) any later version. | 7  * version 2.1 of the License, or (at your option) any later version. | 
| 8  * | 8  * | 
| 9  * FFmpeg is distributed in the hope that it will be useful, | 9  * FFmpeg is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 12  * Lesser General Public License for more details. | 12  * Lesser General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU Lesser General Public | 14  * You should have received a copy of the GNU Lesser General Public | 
| 15  * License along with FFmpeg; if not, write to the Free Software | 15  * License along with FFmpeg; if not, write to the Free Software | 
| 16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 
| 17  */ | 17  */ | 
| 18 | 18 | 
| 19 /** | 19 /** | 
| 20  * @file | 20  * @file | 
| 21  * null video source | 21  * null video source | 
| 22  */ | 22  */ | 
| 23 | 23 | 
|  | 24 #include "libavutil/avstring.h" | 
|  | 25 #include "libavutil/eval.h" | 
|  | 26 #include "libavcore/parseutils.h" | 
| 24 #include "avfilter.h" | 27 #include "avfilter.h" | 
| 25 | 28 | 
|  | 29 static const char *var_names[] = { | 
|  | 30     "E", | 
|  | 31     "PHI", | 
|  | 32     "PI", | 
|  | 33     "AVTB",   /* default timebase 1/AV_TIME_BASE */ | 
|  | 34     NULL | 
|  | 35 }; | 
|  | 36 | 
|  | 37 enum var_name { | 
|  | 38     VAR_E, | 
|  | 39     VAR_PHI, | 
|  | 40     VAR_PI, | 
|  | 41     VAR_AVTB, | 
|  | 42     VAR_VARS_NB | 
|  | 43 }; | 
|  | 44 | 
| 26 typedef struct { | 45 typedef struct { | 
| 27     int w, h; | 46     int w, h; | 
|  | 47     char tb_expr[256]; | 
|  | 48     double var_values[VAR_VARS_NB]; | 
| 28 } NullContext; | 49 } NullContext; | 
| 29 | 50 | 
| 30 static int init(AVFilterContext *ctx, const char *args, void *opaque) | 51 static int init(AVFilterContext *ctx, const char *args, void *opaque) | 
| 31 { | 52 { | 
| 32     NullContext *priv = ctx->priv; | 53     NullContext *priv = ctx->priv; | 
| 33 | 54 | 
| 34     priv->w = 352; | 55     priv->w = 352; | 
| 35     priv->h = 288; | 56     priv->h = 288; | 
|  | 57     av_strlcpy(priv->tb_expr, "AVTB", sizeof(priv->tb_expr)); | 
| 36 | 58 | 
| 37     if (args) | 59     if (args) | 
| 38         sscanf(args, "%d:%d", &priv->w, &priv->h); | 60         sscanf(args, "%d:%d:%255[^:]", &priv->w, &priv->h, priv->tb_expr); | 
| 39 | 61 | 
| 40     if (priv->w <= 0 || priv->h <= 0) { | 62     if (priv->w <= 0 || priv->h <= 0) { | 
| 41         av_log(ctx, AV_LOG_ERROR, "Non-positive size values are not acceptable.\
     n"); | 63         av_log(ctx, AV_LOG_ERROR, "Non-positive size values are not acceptable.\
     n"); | 
| 42         return AVERROR(EINVAL); | 64         return AVERROR(EINVAL); | 
| 43     } | 65     } | 
| 44 | 66 | 
| 45     return 0; | 67     return 0; | 
| 46 } | 68 } | 
| 47 | 69 | 
| 48 static int config_props(AVFilterLink *outlink) | 70 static int config_props(AVFilterLink *outlink) | 
| 49 { | 71 { | 
| 50     NullContext *priv = outlink->src->priv; | 72     AVFilterContext *ctx = outlink->src; | 
|  | 73     NullContext *priv = ctx->priv; | 
|  | 74     AVRational tb; | 
|  | 75     int ret; | 
|  | 76     double res; | 
|  | 77 | 
|  | 78     priv->var_values[VAR_E]    = M_E; | 
|  | 79     priv->var_values[VAR_PHI]  = M_PHI; | 
|  | 80     priv->var_values[VAR_PI]   = M_PI; | 
|  | 81     priv->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q); | 
|  | 82 | 
|  | 83     if ((ret = av_parse_and_eval_expr(&res, priv->tb_expr, var_names, priv->var_
     values, | 
|  | 84                                       NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 
     0) { | 
|  | 85         av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", pri
     v->tb_expr); | 
|  | 86         return ret; | 
|  | 87     } | 
|  | 88     tb = av_d2q(res, INT_MAX); | 
|  | 89     if (tb.num <= 0 || tb.den <= 0) { | 
|  | 90         av_log(ctx, AV_LOG_ERROR, | 
|  | 91                "Invalid non-positive value for the timebase %d/%d.\n", | 
|  | 92                tb.num, tb.den); | 
|  | 93         return AVERROR(EINVAL); | 
|  | 94     } | 
| 51 | 95 | 
| 52     outlink->w = priv->w; | 96     outlink->w = priv->w; | 
| 53     outlink->h = priv->h; | 97     outlink->h = priv->h; | 
|  | 98     outlink->time_base = tb; | 
| 54 | 99 | 
| 55     av_log(outlink->src, AV_LOG_INFO, "w:%d h:%d\n", priv->w, priv->h); | 100     av_log(outlink->src, AV_LOG_INFO, "w:%d h:%d tb:%d/%d\n", priv->w, priv->h, | 
|  | 101            tb.num, tb.den); | 
| 56 | 102 | 
| 57     return 0; | 103     return 0; | 
| 58 } | 104 } | 
| 59 | 105 | 
| 60 static int request_frame(AVFilterLink *link) | 106 static int request_frame(AVFilterLink *link) | 
| 61 { | 107 { | 
| 62     return -1; | 108     return -1; | 
| 63 } | 109 } | 
| 64 | 110 | 
| 65 AVFilter avfilter_vsrc_nullsrc = { | 111 AVFilter avfilter_vsrc_nullsrc = { | 
| 66     .name        = "nullsrc", | 112     .name        = "nullsrc", | 
| 67     .description = NULL_IF_CONFIG_SMALL("Null video source, never return images.
     "), | 113     .description = NULL_IF_CONFIG_SMALL("Null video source, never return images.
     "), | 
| 68 | 114 | 
| 69     .init       = init, | 115     .init       = init, | 
| 70     .priv_size = sizeof(NullContext), | 116     .priv_size = sizeof(NullContext), | 
| 71 | 117 | 
| 72     .inputs    = (AVFilterPad[]) {{ .name = NULL}}, | 118     .inputs    = (AVFilterPad[]) {{ .name = NULL}}, | 
| 73 | 119 | 
| 74     .outputs   = (AVFilterPad[]) { | 120     .outputs   = (AVFilterPad[]) { | 
| 75         { | 121         { | 
| 76             .name            = "default", | 122             .name            = "default", | 
| 77             .type            = AVMEDIA_TYPE_VIDEO, | 123             .type            = AVMEDIA_TYPE_VIDEO, | 
| 78             .config_props    = config_props, | 124             .config_props    = config_props, | 
| 79             .request_frame   = request_frame, | 125             .request_frame   = request_frame, | 
| 80         }, | 126         }, | 
| 81         { .name = NULL} | 127         { .name = NULL} | 
| 82     }, | 128     }, | 
| 83 }; | 129 }; | 
| OLD | NEW | 
|---|