ffmpeg4.4 avdevice

编程入门 行业动态 更新时间:2024-10-16 02:30:11

ffmpeg4.4 avdevice

ffmpeg4.4 avdevice

疑惑

最近阅读ffmpeg4.4代码的时候发现了一个个人认为设计非常巧妙的地方,特此记录,如下面的代码片段:
// code block
#include "config.h"
#include "libavutil/thread.h"
#include "libavformat/internal.h"
#include "avdevice.h"/* devices */
extern AVInputFormat  ff_alsa_demuxer;
extern AVOutputFormat ff_alsa_muxer;
...
extern AVInputFormat  ff_vfwcap_demuxer;
extern AVInputFormat  ff_xcbgrab_demuxer;
extern AVOutputFormat ff_xv_muxer;/* external libraries */
extern AVInputFormat  ff_libcdio_demuxer;
extern AVInputFormat  ff_libdc1394_demuxer;#include "libavdevice/outdev_list.c"
#include "libavdevice/indev_list.c"void avdevice_register_all(void)
{avpriv_register_devices(outdev_list, indev_list);
}

仔细阅读会发现avdevice_register_all调用的avpriv_register_devices注册输入和输出设备,但是avpriv_register_devices的入参outdev_list和indev_list在原本的代码中为NULL,代码如下:

// ffmpeg-4.4\libavdevice\outdev_list.c
static const AVOutputFormat * const outdev_list[] = {NULL };//ffmpeg-4.4\libavdevice\indev_list.c
static const AVInputFormat * const indev_list[] = {NULL };

开始阅读的时候感觉很疑惑。

个人分析:

我开始注意到有很多的extern,如:extern AVInputFormat ff_alsa_demuxer;然后我就在configure中法发现了端倪,如下:

// 编译时候的日志config.log

OUTDEV_LIST='alsa_outdev
audiotoolbox_outdev
caca_outdev
decklink_outdev
fbdev_outdev
opengl_outdev
oss_outdev

//OUTDEV_LIST的值又传给了print_enabled_components,
//最终从这里拼接成了 “static const $struct_name * const KaTeX parse error: Expected '}', got 'EOF' at end of input: …] = {" , //我们将struct_name 和 $name换成入参的实际值正好为 " static const AVOutputFormat * const outdev_list [] = {”,再将拼接的代码输出到临时.c文件中用于编译库文件。

# generate the lists of enabled components
print_enabled_components(){file=$1struct_name=$2name=$3shift 3echo "static const $struct_name * const $name[] = {" > $TMPHfor c in $*; doif enabled $c; thencase $name infilter_list)eval c=\$full_filter_name_${c%_filter};;indev_list)c=${c%_indev}_demuxer;;outdev_list)c=${c%_outdev}_muxer;;esacprintf "    &ff_%s,\n" $c >> $TMPHfidoneif [ "$name" = "filter_list" ]; thenfor c in asrc_abuffer vsrc_buffer asink_abuffer vsink_buffer; doprintf "    &ff_%s,\n" $c >> $TMPHdonefiecho "    NULL };" >> $TMPHcp_if_changed $TMPH $file
}print_enabled_components libavdevice/outdev_list.c AVOutputFormat outdev_list $OUTDEV_LIST

那么OUTDEV_LIST又是怎么生成的呢?
答案就是和各个.c文件中extern的符号有关,如下:

find_things_extern(){thing=$1pattern=$2file=$source_path/$3out=${4:-$thing}sed -n "s/^[^#]*extern.*$pattern *ff_\([^ ]*\)_$thing;/\1_$out/p" "$file"
}find_filters_extern(){file=$source_path/$1sed -n 's/^extern AVFilter ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\);/\1_filter/p' $file
}OUTDEV_LIST=$(find_things_extern muxer AVOutputFormat libavdevice/alldevices.c outdev)

更多推荐

ffmpeg4.4 avdevice

本文发布于:2024-03-11 23:53:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1730221.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:avdevice

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!