在ffmpeg中,这个文件被很多其他的文件所包含。该文件中定义了一些gcc中支持的语言扩展的宏,

例如强制内联,外部内联,pure函数等。并根据是否使用了GCC,以及GCC的版本,把宏转换为

相应的编译器扩展 选项。某些选项也支持msvc。

关键点:

  1.__GNUC__:是GCC编译器预定义的标志,值是GCC的主版本。

  2.__GNUC_MINOR__:是GCC编译器预定义的标志,值是GCC的小版本

  3.AV_GCC_VERSION_AT_LEAST(x,y):当编译器是GCC,且版本大于x.y时返回true

  4.__attribute__是GCC的编译器扩展属性定义的关键字 语法:__attribute__((attr))

  5.__attribute__((always_inline))表示GCC强制内联

  6.__forceinline是msvc的编译器扩展,表示强制内联

  7.__attribute__((noinline))避免编译器进行内联优化。

/*
* copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ /**
* @file
* Macro definitions for various function/variable attributes
*/ #ifndef AVUTIL_ATTRIBUTES_H
#define AVUTIL_ATTRIBUTES_H

/*鉴别GCC,并保证的最低版本*/
#ifdef __GNUC__
# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
#else
# define AV_GCC_VERSION_AT_LEAST(x,y)
#endif

/*定义强制内联,支持msvc编译器*/
#ifndef av_always_inline
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_always_inline __attribute__((always_inline)) inline
#elif defined(_MSC_VER)
# define av_always_inline __forceinline
#else
# define av_always_inline inline
#endif
#endif

/* __ICL: 鉴别Intel 编译器
* __GNUC_STDC_INLINE__ 鉴别GCC把C99 inline作为默认机制
* 

* 大家一定对C语言 inline 关键字不陌生,甚至经常用到 static inline 的函数。可能感到陌生的是 extern inline。C11 标准在6.7.4 p7 中对此进行了描述,不过比较生涩难读。简单地讲,static line 和 extern inline 的区别,从名字上也能看得出来,就是编译单元之外    * 可见性的问题。把一个普通函数给内联掉之后,一个显著的区别就是外部可见性没了,怎么能同时既能内联又能保留外部的可见性呢?为了解决这个问题就有了extern inline。


* static inline 是说这个函数就这么一个,而且没有外部可见性,在所有的编译单元中大家必须共用这么一个定义,这也是为什么 static inline 通常要放到头文件中的原因;而 extern inline 就不一样了,它是说这个函数虽然只有一个定义,但是既有内联的版本,也有非内联的版    * 本,如果你能看得到它的定义。即在同一个编译单元中,那么你就可以用它的内联版本;看不到的话,你就可以用非内联版本,即和其它普通函数一模一样。


* 而如果既不带 static 也不带 extern 的话,含义又不同了:前面的 extern inline 只需要定义一次,只是不同的地方看到的版本不同,有的地方看到的是内联的版本,而有的地方看到的只是个 external reference。而仅用 inline 的话,就变成了要定义两次,带 inline 关键    * 字的这个定义就是内联版本,在这个编译单元中都用这个版本,而在外部,还是使用普通的非内联定义。换句话说,带 inline 的定义遮盖住了外部的定义。既然有两个不同的版本,那么也就需要保持这两个版本的定义相同,否则就会有问题。

 */
#ifndef av_extern_inline
#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__)
# define av_extern_inline extern inline
#else
# define av_extern_inline inline
#endif
#endif

/*禁止内联*/
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_noinline __attribute__((noinline))
#else
# define av_noinline
#endif

/*声明pure函数
*很多函数除了返回值外没有作用,而且它们的返回值只取决于参数和/或全局变量。这样的一个函数可能依附于普通的子表达式的消除和循环的优化,就像一个算术操作符那样。这些函数应该用属性pure来声明。  
*/
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_pure __attribute__((pure))
#else
# define av_pure
#endif

/*restrict用于限定指针,表明该指针所指向的内存只能通过该指针进行访问,有助于编译器优化*/
#ifndef av_restrict
#define av_restrict restrict
#endif

/*定义const函数 有助于编译器优化*/
#if AV_GCC_VERSION_AT_LEAST(2,6)
# define av_const __attribute__((const))
#else
# define av_const
#endif

/*与hot相反,这个属性表示该函数不常用,可以避免被分支预测预读*/
#if AV_GCC_VERSION_AT_LEAST(4,3)
# define av_cold __attribute__((cold))
#else
# define av_cold
#endif

/*被修饰函数中的所有函数调用将被按照内联展开,具体是否可以被展开取决于函数的尺寸等*/
#if AV_GCC_VERSION_AT_LEAST(4,1)
# define av_flatten __attribute__((flatten))
#else
# define av_flatten
#endif

/*用于标记不推荐使用的变量,函数等。如果使用,则会产生警告*/
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define attribute_deprecated __attribute__((deprecated))
#else
# define attribute_deprecated
#endif /**
* Disable warnings about deprecated features
* This is useful for sections of code kept for backward compatibility and
* scheduled for removal.
*/ /**
* 关闭一段已经设置为不推荐使用的代码的编译警告
*/
#ifndef AV_NOWARN_DEPRECATED
#if AV_GCC_VERSION_AT_LEAST(4,6)
# define AV_NOWARN_DEPRECATED(code) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
code \
_Pragma("GCC diagnostic pop")
#else
# define AV_NOWARN_DEPRECATED(code) code
#endif
#endif #if defined(__GNUC__)
# define av_unused __attribute__((unused))
#else
# define av_unused
#endif /**
* Mark a variable as used and prevent the compiler from optimizing it
* away. This is useful for variables accessed only from inline
* assembler without the compiler being aware.
* 标记该符号被使用,以免被优化掉,在使用内联汇编时需要使用。
*/
#if AV_GCC_VERSION_AT_LEAST(3,1)
# define av_used __attribute__((used))
#else
# define av_used
#endif

/*在使用-fstrict-aliasing选项(-02的默认选项)编译时,对于指向相关内存地址的变量会产生编译错误。使用may_alias可以避免这个编译错误。*/
#if AV_GCC_VERSION_AT_LEAST(3,3)
# define av_alias __attribute__((may_alias))
#else
# define av_alias
#endif

/*处理未初始化的量*/
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
# define av_uninit(x) x=x
#else
# define av_uninit(x) x
#endif

/*为带format串的函数提供编译时的类型检查*/
#ifdef __GNUC__
# define av_builtin_constant_p __builtin_constant_p
# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos)))
#else
# define av_builtin_constant_p(x)
# define av_printf_format(fmtpos, attrpos)
#endif #if AV_GCC_VERSION_AT_LEAST(2,5)
# define av_noreturn __attribute__((noreturn))
#else
# define av_noreturn
#endif #endif /* AVUTIL_ATTRIBUTES_H */

ffmpeg - libavutil/attribute.h的更多相关文章

  1. ffmpeg(1)之libavutil/common.h:30:2: error: missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS

    说明 编译环境: mac osx 10.14 + cmake + clang++ 写了一个简单c++的范例调用ffmpeg函数完成音频采集 出错提示 [build] /usr/local/ffmpeg ...

  2. Qt基于FFmpeg播放本地 H.264(H264)文件(灿哥哥的博客)

    最近在弄H264的硬件编解码,基于DM3730,但是为了调试方便,在小红帽上用FFmpeg实现了H264的软件编解码.现在弄了一个Windows的例子,给需要的同学参考一下,如果大家觉得有帮助,可以小 ...

  3. FFmpeg libavutil主要功能概述

    [时间:2017-08] [状态:Open] [关键词:ffmpeg,avutil,avrational,avlog,avbuffer,avoptoin] 0 引言 FFmpeg使用很久了,一直没有认 ...

  4. 树莓派编译安装 FFmpeg(添加 H.264 硬件编解码器支持)

    说明 FFmpeg 是一套开源的音视频编解码库,有非常强大的功能,包括视频采集功能.视频格式转换等.众所周知视频编解码是一个非常消耗系统资源的过程,而树莓派自带了 H.264 的硬件编解码器,因此本文 ...

  5. ffmpeg遇到inttypes.h和UINT64_C

    http://blog.csdn.net/cll131421/article/details/7763657 编译过程:错误一:无法打开包括文件:“inttypes.h”: No such file ...

  6. 调用ffmpeg库编译时出现common.h:175:47: error: 'UINT64_C' was not declared in this scope

    解决办法 出现错误:jni/ffmpeg/libavutil/common.h:175:47: error: 'UINT64_C' was not declared in this scope 解决: ...

  7. linux下编译安卓ffmpeg

    本次编译属于2013年6月项目的一部分,重新修改使用. 为统一工程版本 ffmpeg版本为1.2.1 本次的目录结构为 工程目录/jni/Android.mk 工程目录/jni/Application ...

  8. FFMpeg笔记(三) 音频处理基本概念及音频重采样

    Android放音的采样率固定为44.1KHz,录音的采样率固定为8KHz,因此底层的音频设备驱动需要设置好这两个固定的采样率.如果上层传过来的采样率不符的话,需要进行resample重采样处理. 几 ...

  9. Android本地视频播放器开发--视频解码

    在上一章Android本地视频播放器开发--SDL编译编译中编译出sdl的支持库,当时我们使用的2.0,但是有些api被更改了,所以在以下的使用者中我们使用SDL1.3的库,这个库我会传上源码以及编译 ...

随机推荐

  1. Maven安装本地jar

    应用场景: 有时候一些jar包(比如oracle 的 ojdbc.jar)由于种种原因,比如版权等,导致maven中央库没有该jar文件,但是却有该jar的pom文件. 这个时候,如果私服也没这jar ...

  2. ACE - Reactor模式源码剖析及具体实现(大量源码慎入)

    原文出自http://www.cnblogs.com/binchen-china,禁止转载. 在之前的文章中提到过Reactor模式和Preactor模式,现在利用ACE的Reactor来实现一个基于 ...

  3. [转]LUA元表

    lua元表和元方法 <lua程序设计> 13章 读书笔记 lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在 ...

  4. D - Half of and a Half 大数

    D - Half of and a Half Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I ...

  5. RPM卸载软件包

    如何卸载rpm包 首先:通过  rpm -q <关键字> 可以查询到rpm包的名字 然后:调用 rpm -e <包的名字> 删除特定rpm包 如果遇到依赖,无法删除,使用 rp ...

  6. CF 628C --- Bear and String Distance --- 简单贪心

    CF 628C 题目大意:给定一个长度为n(n < 10^5)的只含小写字母的字符串,以及一个数d,定义字符的dis--dis(ch1, ch2)为两个字符之差, 两个串的dis为各个位置上字符 ...

  7. 【转载】ANSYS的APDL与C语言混合编程(实例)

    原文地址:http://www.cnblogs.com/lyq105/archive/2010/05/04/1727557.html 本文讨论的不是利用C语言为ANSYS写扩展(或者说是用户子程序), ...

  8. 在笔记本电脑开通无线WIFI

    1.Windows + R启动运行,输入services.msc进入服务 2.在服务中将Security Center服务从自动启动转为禁止启动 3.在服务中将Windows Firewall的启动类 ...

  9. world machine, 输出lightmap

    一,输出黑白lightmap: 二,输出彩色lightmap: 需要注意的是:当输出黑白lightmap时,输出设备要用Height Output:当输出彩色lightmap时,输出设备要用Bitma ...

  10. CAD的API们

    AutoCAD有4种API,.net,lisp,activex和ObjectARX(C++).它们都是用来给cad写插件什么的,依赖cad运行. 另有一个RealDWG SDK,这是用来读写dwg或d ...