当前位置:网站首页>ffmpeg -sources分析
ffmpeg -sources分析
2022-08-05 03:08:00 【hjjdebug】
ffmpeg -sources分析
----------------------------------------
author:hjjdebug
date: 2022年 08月 03日 星期三 16:42:27 CST
----------------------------------------
先看一下它的输出:
$ ffmpeg -sources
Device name is not provided.
You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.
Auto-detected sources for alsa:
* default [Playback/recording through the PulseAudio sound server]
surround21 [2.1 Surround output to Front and Subwoofer speakers]
surround40 [4.0 Surround output to Front and Rear speakers]
surround41 [4.1 Surround output to Front, Rear and Subwoofer speakers]
surround50 [5.0 Surround output to Front, Center and Rear speakers]
surround51 [5.1 Surround output to Front, Center, Rear and Subwoofer speakers]
surround71 [7.1 Surround output to Front, Center, Side, Rear and Woofer speakers]
null [Discard all samples (playback) or generate zero samples (capture)]
samplerate [Rate Converter Plugin Using Samplerate Library]
speexrate [Rate Converter Plugin Using Speex Resampler]
jack [JACK Audio Connection Kit]
oss [Open Sound System]
pulse [PulseAudio Sound Server]
upmix [Plugin for channel upmix (4,6,8)]
vdownmix [Plugin for channel downmix (stereo) with a simple spacialization]
sysdefault:CARD=PCH [Default Audio Device]
front:CARD=PCH,DEV=0 [Front speakers]
dmix:CARD=PCH,DEV=0 [Direct sample mixing device]
dmix:CARD=PCH,DEV=2 [Direct sample mixing device]
dsnoop:CARD=PCH,DEV=0 [Direct sample snooping device]
dsnoop:CARD=PCH,DEV=2 [Direct sample snooping device]
hw:CARD=PCH,DEV=0 [Direct hardware device without any conversions]
hw:CARD=PCH,DEV=2 [Direct hardware device without any conversions]
plughw:CARD=PCH,DEV=0 [Hardware device with all software conversions]
plughw:CARD=PCH,DEV=2 [Hardware device with all software conversions]
usbstream:CARD=PCH [USB Stream Output]
usbstream:CARD=NVidia [USB Stream Output]
Auto-detected sources for oss:
Cannot list sources. Not implemented.
Auto-detected sources for sndio:
Cannot list sources. Not implemented.
Auto-detected sources for fbdev:
Could not open framebuffer device '/dev/fb0': Permission denied
Auto-detected sources for lavfi:
Cannot list sources. Not implemented.
Auto-detected sources for video4linux2,v4l2:
Auto-detected sources for x11grab:
Cannot list sources. Not implemented.
下面分析代码:
ffmpeg 分析选项之后,调用了show_sources() 函数,关键代码如下:
fmt = 0;
do {
fmt = av_input_audio_device_next(fmt);
if (fmt) {
print_device_sources(fmt, opts);
}
} while (fmt);
do {
fmt = av_input_video_device_next(fmt);
if (fmt) {
print_device_sources(fmt, opts);
}
} while (fmt);
可见是2个循环.
先看看如何得到fmt. ,由上一个format 可得到下一个format.
int i = 0;
while (prev && (fmt = indev_list[i])) {
i++;
if (prev == fmt) // fmt 与前一个相等了就停下来。
break;
}
do {
fmt = indev_list[i++];
if (!fmt)
break;
category = pc->category;
} while (category != c1 && category != c2); //找到下一个符合要求的,c1,c2是条件
return (AVInputFormat *)fmt;
原来核心是有一个indev_list[]数组, 查找之为:
static const AVInputFormat * const indev_list[] = {
&ff_alsa_demuxer,
&ff_fbdev_demuxer,
&ff_lavfi_demuxer,
&ff_oss_demuxer,
&ff_sndio_demuxer,
&ff_v4l2_demuxer,
&ff_xcbgrab_demuxer,
NULL };
这样我们就知道了,就这么多AVInputFormat. 这是收获1
下面看看每一种AVInputFormat 中具体的项又是怎么得到的?
这要看下面print函数, opts为NULL,fmt 是上面获取的
print_device_sources(fmt, opts);
fmt 的结构比较复杂,相当于一个类。
type = struct AVInputFormat {
const char *name;
const char *long_name;
int flags;
const char *extensions;
const struct AVCodecTag * const *codec_tag;
const AVClass *priv_class;
const char *mime_type;
struct AVInputFormat *next;
int raw_codec_id;
int priv_data_size;
int (*read_probe)(const AVProbeData *);
int (*read_header)(struct AVFormatContext *);
int (*read_packet)(struct AVFormatContext *, AVPacket *);
int (*read_close)(struct AVFormatContext *);
int (*read_seek)(struct AVFormatContext *, int, int64_t, int);
int64_t (*read_timestamp)(struct AVFormatContext *, int, int64_t *, int64_t);
int (*read_play)(struct AVFormatContext *);
int (*read_pause)(struct AVFormatContext *);
int (*read_seek2)(struct AVFormatContext *, int, int64_t, int64_t, int64_t, int);
int (*get_device_list)(struct AVFormatContext *, struct AVDeviceInfoList *);
int (*create_device_capabilities)(struct AVFormatContext *, struct AVDeviceCapabilitiesQuery *);
int (*free_device_capabilities)(struct AVFormatContext *, struct AVDeviceCapabilitiesQuery *);
}
好在别人都写好了,就是上面7种,(当然跟编译选项有关,还可以添加例如decklink等设备)
打印分两部分,一步是获取设备,第二步是打印。
获取设备是关键,信息存入device_list
if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
printf("Cannot list sources.\n");
goto fail;
}
打印很简单,调用printf打就是了。
for (i = 0; i < device_list->nb_devices; i++) {
printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
device_list->devices[i]->device_name, device_list->devices[i]->device_description);
}
device_list 需要讲一下,因为它储存了很多信息。数据组织是收获2
AVDeviceInfoList *device_list ;
typedef struct AVDeviceInfoList {
AVDeviceInfo **devices; /**< list of autodetected devices */
int nb_devices; /**< number of autodetected devices */
int default_device; /**< index of default device or -1 if no default */
} AVDeviceInfoList;
2层指针是什么?2层指针是指向表格的指针,这个表格是一个指针表格(一层指针),2层指针解引用是指针。
同样也可以理解3层指针是一个指向2层指针构成的表的指针。解引用就是一个2层指针。当然这里没有使用,类推一下,后面它确实用过3层指针。
因为是一个AVDeviceInfo 列表,所以有一个nb_devices
AVDeviceInfo 是如下定义的,name,description
typedef struct AVDeviceInfo {
char *device_name; /**< device name, format depends on device */
char *device_description; /**< human friendly name */
} AVDeviceInfo;
下面看看如何获取设备列表:
以 ff_alsa_demuxer,为利,抛开它的一些过程,直接来到
return ff_alsa_get_device_list(device_list, SND_PCM_STREAM_CAPTURE); //获取CAPTURE 的列表
该函数把获取到的device 组织到device_list 中,主要流程如下:
if (snd_device_name_hint(-1, "pcm", &hints) < 0) //拿到所有卡信息的hint
return AVERROR_EXTERNAL;
n = hints;
while (*n && !ret) {
name = snd_device_name_get_hint(*n, "NAME");
descr = snd_device_name_get_hint(*n, "DESC");
io = snd_device_name_get_hint(*n, "IOID");
if (!io || !strcmp(io, filter)) {
new_device = av_mallocz(sizeof(AVDeviceInfo)); // 分配内存
new_device->device_name = av_strdup(name);
new_device->device_description = av_strdup(descr);
if ((ret = av_dynarray_add_nofree(&device_list->devices, //加入数组
&device_list->nb_devices, new_device)) < 0) {
goto fail;
}
}
free(io);
free(name);
free(descr);
n++;
}
int snd_device_name_hint(int card, const char *iface, void ***hints);
card==-1, 获取所有卡的hint, hints 是3层指针。
char *snd_device_name_get_hint(const void *hint, const char *id);
根据hint和id, 拿到对应的名称。
这两个函数就不是ffmpeg 函数,而是驱动提供的函数了. 最终的数据来自驱动,这是收获3
这样把数据流程就分析完了。 结束。
边栏推荐
- 21 Days Learning Challenge (2) Use of Graphical Device Trees
- 用CH341A烧录外挂Flash (W25Q16JV)
- Syntax basics (variables, input and output, expressions and sequential statement completion)
- [In-depth study of 4G/5G/6G topic-51]: URLLC-16-"3GPP URLLC related protocols, specifications, and technical principles in-depth interpretation"-11-High reliability technology-2-Link adaptive enhancem
- 使用二维码传输文件的小工具 - QFileTrans 1.2.0.1
- The linear table lookup
- 百日刷题计划 ———— DAY2
- 语法基础(变量、输入输出、表达式与顺序语句)
- private package
- 【滤波跟踪】基于matlab无迹卡尔曼滤波惯性导航+DVL组合导航【含Matlab源码 2019期】
猜你喜欢

腾讯云【Hiflow】新时代自动化工具

J9 Digital Currency: What is the creator economy of web3?

Matlab drawing 3

How OpenGL works

.NET应用程序--Helloworld(C#)

2022-08-04 第六小组 瞒春 学习笔记

2022 High-level installation, maintenance, and removal of exam questions mock exam question bank and online mock exam

为什么pca分量没有关联

The Tanabata copywriting you want has been sorted out for you!

The linear table lookup
随机推荐
论治理与创新,2022 开放原子全球开源峰会 OpenAnolis 分论坛圆满落幕
QT: The Magical QVarient
Beidou no. 3 short message terminal high slope in open-pit mine monitoring programme
VSCode Change Default Terminal how to modify the Default Terminal VSCode
Linux下常见的开源数据库,你知道几个?
(十一)元类
Intersection of Boolean Operations in SuperMap iDesktop.Net - Repairing Complex Models with Topological Errors
Countdown to 2 days|Cloud native Meetup Guangzhou Station, waiting for you!
2022高处安装、维护、拆除考试题模拟考试题库及在线模拟考试
Native js realizes the effect of selecting and canceling all the multi-select boxes
HDU 1114:Piggy-Bank ← 完全背包问题
CPDA|How Operators Learn Data Analysis (SQL) from Negative Foundations
private package
[Storage] Dawning Storage DS800-G35 ISCSI maps each LUN to the server
Matlab drawing 3
【七夕节】浪漫七夕,代码传情。将爱意变成绚烂的立体场景,给她(他)一个惊喜!(送代码)
QT MV\MVC structure
Flink 1.15.1 Cluster Construction (StandaloneSession)
北斗三号短报文终端露天矿山高边坡监测方案
Physical backup issues caused by soft links