FFmpeg源码:#define IMAGEAUTO_DEMUXER(imgname, codecid) 宏定义分析

在FFmpeg源码(以5.0.3版本为例)目录下的libavformat/img2dec.c中存在如下宏定义

#define IMAGEAUTO_DEMUXER(imgname, codecid)\
const AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
    .name           = AV_STRINGIFY(imgname) "_pipe",\
    .long_name      = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
    .priv_data_size = sizeof(VideoDemuxData),\
    .read_probe     = imgname ## _probe,\
    .read_header    = ff_img_read_header,\
    .read_packet    = ff_img_read_packet,\
    .priv_class     = &imagepipe_class,\
    .flags          = AVFMT_GENERIC_INDEX, \
    .raw_codec_id   = codecid,\
};

IMAGEAUTO_DEMUXER(bmp,     AV_CODEC_ID_BMP)
IMAGEAUTO_DEMUXER(cri,     AV_CODEC_ID_CRI)
IMAGEAUTO_DEMUXER(dds,     AV_CODEC_ID_DDS)
IMAGEAUTO_DEMUXER(dpx,     AV_CODEC_ID_DPX)
IMAGEAUTO_DEMUXER(exr,     AV_CODEC_ID_EXR)
IMAGEAUTO_DEMUXER(gem,     AV_CODEC_ID_GEM)
IMAGEAUTO_DEMUXER(gif,     AV_CODEC_ID_GIF)
IMAGEAUTO_DEMUXER(j2k,     AV_CODEC_ID_JPEG2000)
IMAGEAUTO_DEMUXER(jpeg,    AV_CODEC_ID_MJPEG)
IMAGEAUTO_DEMUXER(jpegls,  AV_CODEC_ID_JPEGLS)
IMAGEAUTO_DEMUXER(pam,     AV_CODEC_ID_PAM)
IMAGEAUTO_DEMUXER(pbm,     AV_CODEC_ID_PBM)
IMAGEAUTO_DEMUXER(pcx,     AV_CODEC_ID_PCX)
IMAGEAUTO_DEMUXER(pgm,     AV_CODEC_ID_PGM)
IMAGEAUTO_DEMUXER(pgmyuv,  AV_CODEC_ID_PGMYUV)
IMAGEAUTO_DEMUXER(pgx,     AV_CODEC_ID_PGX)
IMAGEAUTO_DEMUXER(photocd, AV_CODEC_ID_PHOTOCD)
IMAGEAUTO_DEMUXER(pictor,  AV_CODEC_ID_PICTOR)
IMAGEAUTO_DEMUXER(png,     AV_CODEC_ID_PNG)
IMAGEAUTO_DEMUXER(ppm,     AV_CODEC_ID_PPM)
IMAGEAUTO_DEMUXER(psd,     AV_CODEC_ID_PSD)
IMAGEAUTO_DEMUXER(qdraw,   AV_CODEC_ID_QDRAW)
IMAGEAUTO_DEMUXER(sgi,     AV_CODEC_ID_SGI)
IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST)
IMAGEAUTO_DEMUXER(svg,     AV_CODEC_ID_SVG)
IMAGEAUTO_DEMUXER(tiff,    AV_CODEC_ID_TIFF)
IMAGEAUTO_DEMUXER(webp,    AV_CODEC_ID_WEBP)
IMAGEAUTO_DEMUXER(xbm,     AV_CODEC_ID_XBM)
IMAGEAUTO_DEMUXER(xpm,     AV_CODEC_ID_XPM)
IMAGEAUTO_DEMUXER(xwd,     AV_CODEC_ID_XWD)

上述代码

const AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\

中的##是 宏定义中的操作连接符,具体参考:《define的一些骚操作:##操作连接符、#@字符化操作符、#字符串化操作符、\行继续操作》。

这里用到了C语言的设计艺术:使用##简化函数或变量的名称。

宏定义

#define IMAGEAUTO_DEMUXER(imgname, codecid)\

 实现的是定义全局const变量,该变量类型为AVInputFormat 。AVInputFormat是FFmpeg中的解复用器结构体,每种作为输入的封装格式(例如BMP、FLV、MP4、TS等)都对应一种AVInputFormat 结构。

以BMP这种图片的封装格式为例,它对应的AVInputFormat 结构为:

IMAGEAUTO_DEMUXER(bmp,     AV_CODEC_ID_BMP)

将该宏定义展开即为:

const AVInputFormat ff_image_bmp_pipe_demuxer = {
.name           = "bmp_pipe",
.long_name      = "piped bmp sequence",
.priv_data_size = 1208,
.read_probe     = bmp_probe,
.read_header    = ff_img_read_header,
.read_packet    = ff_img_read_packet,
.priv_class     = &imagepipe_class,
.flags          = 256,
.raw_codec_id   = AV_CODEC_ID_BMP,
};

所以通过这种宏定义的设计艺术,可以巧妙地把类型为AVInputFormat的结构体变量的名称中的“ff_image_” 和 “_pipe_demuxer”去掉,这样最后编写的代码非常整洁,具有简化结构体变量名,避免冗余代码的作用,下面的宏定义中每一行都相当于 定义了一种AVInputFormat 结构,也就是封装格式结构。

IMAGEAUTO_DEMUXER(bmp,     AV_CODEC_ID_BMP)
IMAGEAUTO_DEMUXER(cri,     AV_CODEC_ID_CRI)
IMAGEAUTO_DEMUXER(dds,     AV_CODEC_ID_DDS)
IMAGEAUTO_DEMUXER(dpx,     AV_CODEC_ID_DPX)
IMAGEAUTO_DEMUXER(exr,     AV_CODEC_ID_EXR)
IMAGEAUTO_DEMUXER(gem,     AV_CODEC_ID_GEM)
IMAGEAUTO_DEMUXER(gif,     AV_CODEC_ID_GIF)
IMAGEAUTO_DEMUXER(j2k,     AV_CODEC_ID_JPEG2000)
IMAGEAUTO_DEMUXER(jpeg,    AV_CODEC_ID_MJPEG)
IMAGEAUTO_DEMUXER(jpegls,  AV_CODEC_ID_JPEGLS)
IMAGEAUTO_DEMUXER(pam,     AV_CODEC_ID_PAM)
IMAGEAUTO_DEMUXER(pbm,     AV_CODEC_ID_PBM)
IMAGEAUTO_DEMUXER(pcx,     AV_CODEC_ID_PCX)
IMAGEAUTO_DEMUXER(pgm,     AV_CODEC_ID_PGM)
IMAGEAUTO_DEMUXER(pgmyuv,  AV_CODEC_ID_PGMYUV)
IMAGEAUTO_DEMUXER(pgx,     AV_CODEC_ID_PGX)
IMAGEAUTO_DEMUXER(photocd, AV_CODEC_ID_PHOTOCD)
IMAGEAUTO_DEMUXER(pictor,  AV_CODEC_ID_PICTOR)
IMAGEAUTO_DEMUXER(png,     AV_CODEC_ID_PNG)
IMAGEAUTO_DEMUXER(ppm,     AV_CODEC_ID_PPM)
IMAGEAUTO_DEMUXER(psd,     AV_CODEC_ID_PSD)
IMAGEAUTO_DEMUXER(qdraw,   AV_CODEC_ID_QDRAW)
IMAGEAUTO_DEMUXER(sgi,     AV_CODEC_ID_SGI)
IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST)
IMAGEAUTO_DEMUXER(svg,     AV_CODEC_ID_SVG)
IMAGEAUTO_DEMUXER(tiff,    AV_CODEC_ID_TIFF)
IMAGEAUTO_DEMUXER(webp,    AV_CODEC_ID_WEBP)
IMAGEAUTO_DEMUXER(xbm,     AV_CODEC_ID_XBM)
IMAGEAUTO_DEMUXER(xpm,     AV_CODEC_ID_XPM)
IMAGEAUTO_DEMUXER(xwd,     AV_CODEC_ID_XWD)

上述宏定义被demuxer_list数组使用。在FFmpeg源码目录下的libavformat/demuxer_list.c中,定义了demuxer_list数组,该数组定义了FFmpeg当前支持的媒体和图片的解封装协议,每个元素都指向了一种AVInputFormat 结构:

static const AVInputFormat * const demuxer_list[] = {
  //...
    &ff_image_bmp_pipe_demuxer,
    &ff_image_cri_pipe_demuxer,
    &ff_image_dds_pipe_demuxer,
    &ff_image_dpx_pipe_demuxer,
    &ff_image_exr_pipe_demuxer,
    &ff_image_gem_pipe_demuxer,
    &ff_image_gif_pipe_demuxer,
    &ff_image_j2k_pipe_demuxer,
    &ff_image_jpeg_pipe_demuxer,
    &ff_image_jpegls_pipe_demuxer,
    &ff_image_pam_pipe_demuxer,
    &ff_image_pbm_pipe_demuxer,
    &ff_image_pcx_pipe_demuxer,
    &ff_image_pgmyuv_pipe_demuxer,
    &ff_image_pgm_pipe_demuxer,
    &ff_image_pgx_pipe_demuxer,
    &ff_image_photocd_pipe_demuxer,
    &ff_image_pictor_pipe_demuxer,
    &ff_image_png_pipe_demuxer,
    &ff_image_ppm_pipe_demuxer,
    &ff_image_psd_pipe_demuxer,
    &ff_image_qdraw_pipe_demuxer,
    &ff_image_sgi_pipe_demuxer,
    &ff_image_svg_pipe_demuxer,
    &ff_image_sunrast_pipe_demuxer,
    &ff_image_tiff_pipe_demuxer,
    &ff_image_webp_pipe_demuxer,
    &ff_image_xbm_pipe_demuxer,
    &ff_image_xpm_pipe_demuxer,
    &ff_image_xwd_pipe_demuxer,
    NULL };

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值