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