00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026
00027
00028 #include "float.h"
00029
00030 #include "libavutil/log.h"
00031 #include "libavutil/mem.h"
00032 #include "libavutil/opt.h"
00033 #include "libavutil/parseutils.h"
00034 #include "libavutil/pixdesc.h"
00035 #include "libavutil/audioconvert.h"
00036 #include "libavfilter/avfilter.h"
00037 #include "libavfilter/avfiltergraph.h"
00038 #include "libavfilter/buffersink.h"
00039 #include "libavformat/internal.h"
00040 #include "avdevice.h"
00041
00042 typedef struct {
00043 AVClass *class;
00044 char *graph_str;
00045 char *dump_graph;
00046 AVFilterGraph *graph;
00047 AVFilterContext **sinks;
00048 int *sink_stream_map;
00049 int *sink_eof;
00050 int *stream_sink_map;
00051 } LavfiContext;
00052
00053 static int *create_all_formats(int n)
00054 {
00055 int i, j, *fmts, count = 0;
00056
00057 for (i = 0; i < n; i++)
00058 if (!(av_pix_fmt_descriptors[i].flags & PIX_FMT_HWACCEL))
00059 count++;
00060
00061 if (!(fmts = av_malloc((count+1) * sizeof(int))))
00062 return NULL;
00063 for (j = 0, i = 0; i < n; i++) {
00064 if (!(av_pix_fmt_descriptors[i].flags & PIX_FMT_HWACCEL))
00065 fmts[j++] = i;
00066 }
00067 fmts[j] = -1;
00068 return fmts;
00069 }
00070
00071 av_cold static int lavfi_read_close(AVFormatContext *avctx)
00072 {
00073 LavfiContext *lavfi = avctx->priv_data;
00074
00075 av_freep(&lavfi->sink_stream_map);
00076 av_freep(&lavfi->sink_eof);
00077 av_freep(&lavfi->stream_sink_map);
00078 av_freep(&lavfi->sinks);
00079 avfilter_graph_free(&lavfi->graph);
00080
00081 return 0;
00082 }
00083
00084 av_cold static int lavfi_read_header(AVFormatContext *avctx)
00085 {
00086 LavfiContext *lavfi = avctx->priv_data;
00087 AVFilterInOut *input_links = NULL, *output_links = NULL, *inout;
00088 AVFilter *buffersink, *abuffersink;
00089 int *pix_fmts = create_all_formats(PIX_FMT_NB);
00090 enum AVMediaType type;
00091 int ret = 0, i, n;
00092
00093 #define FAIL(ERR) { ret = ERR; goto end; }
00094
00095 if (!pix_fmts)
00096 FAIL(AVERROR(ENOMEM));
00097
00098 avfilter_register_all();
00099
00100 buffersink = avfilter_get_by_name("ffbuffersink");
00101 abuffersink = avfilter_get_by_name("ffabuffersink");
00102
00103 if (!lavfi->graph_str)
00104 lavfi->graph_str = av_strdup(avctx->filename);
00105
00106
00107 if (!(lavfi->graph = avfilter_graph_alloc()))
00108 FAIL(AVERROR(ENOMEM));
00109
00110 if ((ret = avfilter_graph_parse(lavfi->graph, lavfi->graph_str,
00111 &input_links, &output_links, avctx)) < 0)
00112 FAIL(ret);
00113
00114 if (input_links) {
00115 av_log(avctx, AV_LOG_ERROR,
00116 "Open inputs in the filtergraph are not acceptable\n");
00117 FAIL(AVERROR(EINVAL));
00118 }
00119
00120
00121 for (n = 0, inout = output_links; inout; n++, inout = inout->next);
00122
00123 if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n)))
00124 FAIL(AVERROR(ENOMEM));
00125 if (!(lavfi->sink_eof = av_mallocz(sizeof(int) * n)))
00126 FAIL(AVERROR(ENOMEM));
00127 if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
00128 FAIL(AVERROR(ENOMEM));
00129
00130 for (i = 0; i < n; i++)
00131 lavfi->stream_sink_map[i] = -1;
00132
00133
00134
00135 for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
00136 int stream_idx;
00137 if (!strcmp(inout->name, "out"))
00138 stream_idx = 0;
00139 else if (sscanf(inout->name, "out%d\n", &stream_idx) != 1) {
00140 av_log(avctx, AV_LOG_ERROR,
00141 "Invalid outpad name '%s'\n", inout->name);
00142 FAIL(AVERROR(EINVAL));
00143 }
00144
00145 if ((unsigned)stream_idx >= n) {
00146 av_log(avctx, AV_LOG_ERROR,
00147 "Invalid index was specified in output '%s', "
00148 "must be a non-negative value < %d\n",
00149 inout->name, n);
00150 FAIL(AVERROR(EINVAL));
00151 }
00152
00153
00154 type = inout->filter_ctx->output_pads[inout->pad_idx].type;
00155 if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
00156 av_log(avctx, AV_LOG_ERROR,
00157 "Output '%s' is not a video or audio output, not yet supported\n", inout->name);
00158 FAIL(AVERROR(EINVAL));
00159 }
00160
00161 if (lavfi->stream_sink_map[stream_idx] != -1) {
00162 av_log(avctx, AV_LOG_ERROR,
00163 "An output with stream index %d was already specified\n",
00164 stream_idx);
00165 FAIL(AVERROR(EINVAL));
00166 }
00167 lavfi->sink_stream_map[i] = stream_idx;
00168 lavfi->stream_sink_map[stream_idx] = i;
00169 }
00170
00171
00172 for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
00173 AVStream *st;
00174 if (!(st = avformat_new_stream(avctx, NULL)))
00175 FAIL(AVERROR(ENOMEM));
00176 st->id = i;
00177 }
00178
00179
00180 lavfi->sinks = av_malloc(sizeof(AVFilterContext *) * avctx->nb_streams);
00181 if (!lavfi->sinks)
00182 FAIL(AVERROR(ENOMEM));
00183
00184 for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
00185 AVFilterContext *sink;
00186
00187 type = inout->filter_ctx->output_pads[inout->pad_idx].type;
00188
00189 if (type == AVMEDIA_TYPE_VIDEO && ! buffersink ||
00190 type == AVMEDIA_TYPE_AUDIO && ! abuffersink) {
00191 av_log(avctx, AV_LOG_ERROR, "Missing required buffersink filter, aborting.\n");
00192 FAIL(AVERROR_FILTER_NOT_FOUND);
00193 }
00194
00195 if (type == AVMEDIA_TYPE_VIDEO) {
00196 AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
00197
00198 buffersink_params->pixel_fmts = pix_fmts;
00199 ret = avfilter_graph_create_filter(&sink, buffersink,
00200 inout->name, NULL,
00201 buffersink_params, lavfi->graph);
00202 av_freep(&buffersink_params);
00203
00204 if (ret < 0)
00205 goto end;
00206 } else if (type == AVMEDIA_TYPE_AUDIO) {
00207 enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_U8,
00208 AV_SAMPLE_FMT_S16,
00209 AV_SAMPLE_FMT_S32,
00210 AV_SAMPLE_FMT_FLT,
00211 AV_SAMPLE_FMT_DBL, -1 };
00212 AVABufferSinkParams *abuffersink_params = av_abuffersink_params_alloc();
00213 abuffersink_params->sample_fmts = sample_fmts;
00214
00215 ret = avfilter_graph_create_filter(&sink, abuffersink,
00216 inout->name, NULL,
00217 abuffersink_params, lavfi->graph);
00218 av_free(abuffersink_params);
00219 if (ret < 0)
00220 goto end;
00221 }
00222
00223 lavfi->sinks[i] = sink;
00224 if ((ret = avfilter_link(inout->filter_ctx, inout->pad_idx, sink, 0)) < 0)
00225 FAIL(ret);
00226 }
00227
00228
00229 if ((ret = avfilter_graph_config(lavfi->graph, avctx)) < 0)
00230 FAIL(ret);
00231
00232 if (lavfi->dump_graph) {
00233 char *dump = avfilter_graph_dump(lavfi->graph, lavfi->dump_graph);
00234 fputs(dump, stderr);
00235 fflush(stderr);
00236 av_free(dump);
00237 }
00238
00239
00240 for (i = 0; i < avctx->nb_streams; i++) {
00241 AVFilterLink *link = lavfi->sinks[lavfi->stream_sink_map[i]]->inputs[0];
00242 AVStream *st = avctx->streams[i];
00243 st->codec->codec_type = link->type;
00244 avpriv_set_pts_info(st, 64, link->time_base.num, link->time_base.den);
00245 if (link->type == AVMEDIA_TYPE_VIDEO) {
00246 st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
00247 st->codec->pix_fmt = link->format;
00248 st->codec->time_base = link->time_base;
00249 st->codec->width = link->w;
00250 st->codec->height = link->h;
00251 st ->sample_aspect_ratio =
00252 st->codec->sample_aspect_ratio = link->sample_aspect_ratio;
00253 } else if (link->type == AVMEDIA_TYPE_AUDIO) {
00254 st->codec->codec_id = av_get_pcm_codec(link->format, -1);
00255 st->codec->channels = av_get_channel_layout_nb_channels(link->channel_layout);
00256 st->codec->sample_fmt = link->format;
00257 st->codec->sample_rate = link->sample_rate;
00258 st->codec->time_base = link->time_base;
00259 st->codec->channel_layout = link->channel_layout;
00260 if (st->codec->codec_id == AV_CODEC_ID_NONE)
00261 av_log(avctx, AV_LOG_ERROR,
00262 "Could not find PCM codec for sample format %s.\n",
00263 av_get_sample_fmt_name(link->format));
00264 }
00265 }
00266
00267 end:
00268 av_free(pix_fmts);
00269 avfilter_inout_free(&input_links);
00270 avfilter_inout_free(&output_links);
00271 if (ret < 0)
00272 lavfi_read_close(avctx);
00273 return ret;
00274 }
00275
00276 static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
00277 {
00278 LavfiContext *lavfi = avctx->priv_data;
00279 double min_pts = DBL_MAX;
00280 int stream_idx, min_pts_sink_idx = 0;
00281 AVFilterBufferRef *ref;
00282 AVPicture pict;
00283 int ret, i;
00284 int size = 0;
00285
00286
00287
00288 for (i = 0; i < avctx->nb_streams; i++) {
00289 AVRational tb = lavfi->sinks[i]->inputs[0]->time_base;
00290 double d;
00291 int ret;
00292
00293 if (lavfi->sink_eof[i])
00294 continue;
00295
00296 ret = av_buffersink_get_buffer_ref(lavfi->sinks[i],
00297 &ref, AV_BUFFERSINK_FLAG_PEEK);
00298 if (ret == AVERROR_EOF) {
00299 av_dlog(avctx, "EOF sink_idx:%d\n", i);
00300 lavfi->sink_eof[i] = 1;
00301 continue;
00302 } else if (ret < 0)
00303 return ret;
00304 d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q);
00305 av_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
00306
00307 if (d < min_pts) {
00308 min_pts = d;
00309 min_pts_sink_idx = i;
00310 }
00311 }
00312 if (min_pts == DBL_MAX)
00313 return AVERROR_EOF;
00314
00315 av_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx);
00316
00317 av_buffersink_get_buffer_ref(lavfi->sinks[min_pts_sink_idx], &ref, 0);
00318 stream_idx = lavfi->sink_stream_map[min_pts_sink_idx];
00319
00320 if (ref->video) {
00321 size = avpicture_get_size(ref->format, ref->video->w, ref->video->h);
00322 if ((ret = av_new_packet(pkt, size)) < 0)
00323 return ret;
00324
00325 memcpy(pict.data, ref->data, 4*sizeof(ref->data[0]));
00326 memcpy(pict.linesize, ref->linesize, 4*sizeof(ref->linesize[0]));
00327
00328 avpicture_layout(&pict, ref->format, ref->video->w,
00329 ref->video->h, pkt->data, size);
00330 } else if (ref->audio) {
00331 size = ref->audio->nb_samples *
00332 av_get_bytes_per_sample(ref->format) *
00333 av_get_channel_layout_nb_channels(ref->audio->channel_layout);
00334 if ((ret = av_new_packet(pkt, size)) < 0)
00335 return ret;
00336 memcpy(pkt->data, ref->data[0], size);
00337 }
00338
00339 pkt->stream_index = stream_idx;
00340 pkt->pts = ref->pts;
00341 pkt->pos = ref->pos;
00342 pkt->size = size;
00343 avfilter_unref_buffer(ref);
00344 return size;
00345 }
00346
00347 #define OFFSET(x) offsetof(LavfiContext, x)
00348
00349 #define DEC AV_OPT_FLAG_DECODING_PARAM
00350
00351 static const AVOption options[] = {
00352 { "graph", "set libavfilter graph", OFFSET(graph_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00353 { "dumpgraph", "dump graph to stderr", OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00354 { NULL },
00355 };
00356
00357 static const AVClass lavfi_class = {
00358 .class_name = "lavfi indev",
00359 .item_name = av_default_item_name,
00360 .option = options,
00361 .version = LIBAVUTIL_VERSION_INT,
00362 };
00363
00364 AVInputFormat ff_lavfi_demuxer = {
00365 .name = "lavfi",
00366 .long_name = NULL_IF_CONFIG_SMALL("Libavfilter virtual input device"),
00367 .priv_data_size = sizeof(LavfiContext),
00368 .read_header = lavfi_read_header,
00369 .read_packet = lavfi_read_packet,
00370 .read_close = lavfi_read_close,
00371 .flags = AVFMT_NOFILE,
00372 .priv_class = &lavfi_class,
00373 };