Part3: Overcome the ‘Access Violation Exception’ in the FFMPEG

Part3: Overcome the ‘Access Violation Exception’ in the FFMPEG

 

Part1: Overcome the ‘Access Violation Exception’ in the FFMPEG ” presents a simple solution for “Access Violation Exception”. By further analyzing the root cause, we provide a better method in “Part2: Overcome the ‘Access Violation Exception’ in the FFMPEG ”. The later improves the performance of codec to some extension, because it enables all related ASM source codes, but it needs modify the complicated ASM source codes to eliminate the aligning instructions. From the view of maintenance, it will lead to take a high cost in future.

As mentioned before, Can I find the better solution to balance between performance and correction? En…, Maybe! But it needs understand GCC deeply and find workaround in this case.

 

Step 1: What do we see in the fft.c?

 

The key block of source codes is listed in the next table, and could you tell me what you find?

DECLARE_ALIGNED_16(FFTSample, ff_cos_16[8]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_32[16]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_64[32]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_128[64]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_256[128]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_512[256]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_1024[512]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_2048[1024]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_4096[2048]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_8192[4096]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_16384[8192]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_32768[16384]);

DECLARE_ALIGNED_16(FFTSample, ff_cos_65536[32768]);

 

I guess that readers can get more than what I have. Herein, it’s my answer:

1. ff_cos_* are defined in the light of 16 bytes’ alignment.

2. ff_cos_* have not been initialized in these definitions.

 

Step 2: Which section will GCC put them into?

 

Unix C compilers have traditionally permitted multiple definitions of such variables in the different compilation units by placing the variables in a common section. To be compatible with Unix C, GCC select it as the default way in most targets. From the view of the previous investigation in Part1 and Part2, GCC takes some mistakes to align the variables’ address of common section when linking *.o built by different compilers. Following the clue, I ask myself “What will happen if I disable common section?”   The obvious result is that they will be arranged into data section. OK, it is good. What will happen in the data section, and will it be same as common section? …?

 

WOW, too many questions for this exploration. I can not answer them all! So why not to take actions to find the truth? Let’s go!

 

Step 3: Append ‘-fno-common’ compiling option for FFMPEG

 

$ ./configure --enable-memalign-hack --enable-shared --disable-static --enable-yasm --extra-cflags='-fno-common' && make && make install

 

For the detailed HOWTO, please refer to FFmpeg Understand(3. How to compile FFMPEG in Windows?) .

Let’s have a rest and take a cup of tea, and we have enough time to enjoy our life:-).

Tick, tick, tick, …

Yeah, it is done! Check it! Cross our fingers!

$ nm ./libavcodec/avcodec-52.dll | egrep 'ff_cos'

6af6305c T _ff_cos

6b3ee9f0 B _ff_cos_1024

6b3ee2f0 B _ff_cos_128

6b3ee210 B _ff_cos_16

6b3f61f0 B _ff_cos_16384

6b3ef1f0 B _ff_cos_2048

6b3ee3f0 B _ff_cos_256

6b3ee230 B _ff_cos_32

6b3fe1f0 B _ff_cos_32768

6b3f01f0 B _ff_cos_4096

6b3ee5f0 B _ff_cos_512

6b3ee270 B _ff_cos_64

6b40e1f0 B _ff_cos_65536

6b3f21f0 B _ff_cos_8192

6b1ef020 D _ff_cos_tabs

 

Cool! It has been fixed!!!

 

After pleasure, I ask my again! What will I be paid for this operation? So I must read the GCC manual to disclosure my worry. I copy a segment from the manual of GCC.

The ‘-fno-common’ option specifies that the compiler should place uninitialized

global variables in the data section of the object file, rather than generating

them as common blocks. This has the effect that if the same variable is declared

(without extern) in two different compilations, you will get a multiple-definition

error when you link them. In this case, you must compile with ‘-fcommon’

instead. Compiling with ‘-fno-common’ is useful on targets for which it provides

better performance, or if you wish to verify that the program will work on other

systems which always treat uninitialized variable declarations this way.

 

HOHO~~, no problem! I get an extra gift, performance, at the same time! HAHAHA…

 

[Summarization]

1. It should be a final solution to overcome the ‘Access Violation Exception’. All source codes of FFMPEG should not been modified and only add --extra-cflags='-fno-common' option when building them.

2. ‘-fno-common’ gives me an extra gift and take a good performance as the same time. As the mentioned by GCC, it should be a default compiling option if there are no multi-definitions of variables.

3. Both GCC4.3.0(Alpha) and GCC4.2.1 have this issue in the platform of MINGW. GCC4.4.0 has fixed this issue, but it can not work in the sharing mode of FFMPEG in the current official release.

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值