这篇文章是19年在实习时候写的。
简单来说,其实ffmpeg是有相应的接口的,如avdevice_list_input_sources可以查询设备名,甚至在avdevice.h的注释里可以看到,还有可以根据设备名获取设备支持的分辨率、格式等信息的API。
但是在网上的方法里面,一个是通过
AVFormatContext *pFormatCtx = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options, "list_devices", "true", 0);
AVInputFormat *iformat = av_find_input_format("dshow");
puts("Device Option Info======");
avformat_open_input(&pFormatCtx, "video=dummy", iformat, &options);
他们的本质都是通过COM接口来获取信息,ffmpeg也是调用的同样的函数,只是没提供返回的接口,而是打印了出来,也就说ffmpeg由于dshow部分的一些函数官方还没写完,所以就只能用这种蛋疼的方法。
那么怎么做才能完美呢?
当然是自己实现对应的接口了……
从dshow.c可以看出:
AVInputFormat ff_dshow_demuxer = {
.name = "dshow",
.long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"),
.priv_data_size = sizeof(struct dshow_ctx),
.read_header = dshow_read_header,
.read_packet = dshow_read_packet,
.read_close = dshow_read_close,
.flags = AVFMT_NOFILE,
.priv_class = &dshow_class,
};
里面只有这些实现了,而AVInputFormat 完整的接口呢?
typedef struct AVInputFormat {
/**
* A comma separated list of short names for the format. New names
* may be appended with a minor bump.
*/
const char *name;
/**
* Descriptive name for the format, meant to be more human-readable
* than name. You should use the NULL_IF_CONFIG_SMALL() macro
* to define it.
*/
const char *long_name;
/**
* Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
* AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
* AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
*/
int flags;
/**
* If extensions are defined, then no probe is done. You should
* usually not use extension format guessing because it is not
* reliable enough
*/
const char *extensions;
const struct AVCodecTag * const *codec_tag;
const AVClass *priv_class; ///< AVClass for the private context
/**
* Comma-separated list of mime types.
* It is used check for