]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/asrc_anullsrc.c
Make PAL8 pcx images opaque.
[ffmpeg] / libavfilter / asrc_anullsrc.c
index 4f49c3f1868639dd48a1fc146c2c27268896318e..1bcc3eb9a6b5aafd263f4436e80a8730dc22734c 100644 (file)
  * null audio source
  */
 
-#include "avfilter.h"
 #include "libavutil/audioconvert.h"
+#include "libavutil/opt.h"
+
+#include "avfilter.h"
+#include "internal.h"
 
 typedef struct {
+    const AVClass *class;
+    char   *channel_layout_str;
     int64_t channel_layout;
-    int64_t sample_rate;
+    char   *sample_rate_str;
+    int     sample_rate;
+    int nb_samples;             ///< number of samples per requested frame
+    int64_t pts;
 } ANullContext;
 
-static int init(AVFilterContext *ctx, const char *args, void *opaque)
+#define OFFSET(x) offsetof(ANullContext, x)
+
+static const AVOption anullsrc_options[]= {
+    { "channel_layout", "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0 },
+    { "cl",             "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0 },
+    { "sample_rate",    "set sample rate",    OFFSET(sample_rate_str)   , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0 },
+    { "r",              "set sample rate",    OFFSET(sample_rate_str)   , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0 },
+    { "nb_samples",     "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.dbl = 1024}, 0, INT_MAX },
+    { "n",              "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.dbl = 1024}, 0, INT_MAX },
+    { NULL },
+};
+
+static const char *anullsrc_get_name(void *ctx)
 {
-    ANullContext *priv = ctx->priv;
-    char channel_layout_str[128] = "";
+    return "anullsrc";
+}
 
-    priv->sample_rate = 44100;
-    priv->channel_layout = AV_CH_LAYOUT_STEREO;
+static const AVClass anullsrc_class = {
+    "ANullSrcContext",
+    anullsrc_get_name,
+    anullsrc_options
+};
 
-    if (args)
-        sscanf(args, "%"PRId64":%s", &priv->sample_rate, channel_layout_str);
+static int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+    ANullContext *null = ctx->priv;
+    int ret;
 
-    if (priv->sample_rate < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid negative sample rate: %"PRId64"\n", priv->sample_rate);
-        return AVERROR(EINVAL);
+    null->class = &anullsrc_class;
+    av_opt_set_defaults(null);
+
+    if ((ret = (av_set_options_string(null, args, "=", ":"))) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+        return ret;
     }
 
-    if (*channel_layout_str)
-        if (!(priv->channel_layout = av_get_channel_layout(channel_layout_str))
-            && sscanf(channel_layout_str, "%"PRId64, &priv->channel_layout) != 1) {
-            av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for channel layout\n",
-                   channel_layout_str);
-            return AVERROR(EINVAL);
-        }
+    if ((ret = ff_parse_sample_rate(&null->sample_rate,
+                                     null->sample_rate_str, ctx)) < 0)
+        return ret;
+
+    if ((ret = ff_parse_channel_layout(&null->channel_layout,
+                                        null->channel_layout_str, ctx)) < 0)
+        return ret;
 
     return 0;
 }
 
 static int config_props(AVFilterLink *outlink)
 {
-    ANullContext *priv = outlink->src->priv;
+    ANullContext *null = outlink->src->priv;
     char buf[128];
     int chans_nb;
 
-    outlink->sample_rate = priv->sample_rate;
-    outlink->channel_layout = priv->channel_layout;
+    outlink->sample_rate = null->sample_rate;
+    outlink->channel_layout = null->channel_layout;
 
-    chans_nb = av_get_channel_layout_nb_channels(priv->channel_layout);
-    av_get_channel_layout_string(buf, sizeof(buf), chans_nb, priv->channel_layout);
+    chans_nb = av_get_channel_layout_nb_channels(null->channel_layout);
+    av_get_channel_layout_string(buf, sizeof(buf), chans_nb, null->channel_layout);
     av_log(outlink->src, AV_LOG_INFO,
-           "sample_rate:%"PRId64 " channel_layout:%"PRId64 " channel_layout_description:'%s'\n",
-           priv->sample_rate, priv->channel_layout, buf);
+           "sample_rate:%d channel_layout:'%s' nb_samples:%d\n",
+           null->sample_rate, buf, null->nb_samples);
 
     return 0;
 }
 
-static int request_frame(AVFilterLink *link)
+static int request_frame(AVFilterLink *outlink)
 {
-    return -1;
+    ANullContext *null = outlink->src->priv;
+    AVFilterBufferRef *samplesref;
+
+    samplesref =
+        avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, null->nb_samples);
+    samplesref->pts = null->pts;
+    samplesref->pos = -1;
+    samplesref->audio->channel_layout = null->channel_layout;
+    samplesref->audio->sample_rate = outlink->sample_rate;
+
+    avfilter_filter_samples(outlink, avfilter_ref_buffer(samplesref, ~0));
+    avfilter_unref_buffer(samplesref);
+
+    null->pts += null->nb_samples;
+    return 0;
 }
 
 AVFilter avfilter_asrc_anullsrc = {
     .name        = "anullsrc",
-    .description = NULL_IF_CONFIG_SMALL("Null audio source, never return audio frames."),
+    .description = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."),
 
     .init        = init,
     .priv_size   = sizeof(ANullContext),
 
-    .inputs      = (AVFilterPad[]) {{ .name = NULL}},
+    .inputs      = (const AVFilterPad[]) {{ .name = NULL}},
 
-    .outputs     = (AVFilterPad[]) {{ .name = "default",
+    .outputs     = (const AVFilterPad[]) {{ .name = "default",
                                       .type = AVMEDIA_TYPE_AUDIO,
                                       .config_props = config_props,
                                       .request_frame = request_frame, },