我使用以下代码:
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char **argv) {
char *auyvy = malloc(640 * 480 * 2);
char *ay8 = malloc(640 * 480);
int fd = open("input.uyvy", O_RDONLY);
if (fd >= 0) {
read(fd, auyvy, 640 * 480 * 2);
close(fd);
}
__uyvy_luma_extract(640, 480, auyvy, 640 * 2, ay8, 640);
fd = open("output.y8", O_RDWR | O_CREAT);
if (fd >= 0) {
write(fd, ay8, 640 * 480);
close(fd);
}
}
附加两个文件: https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/__uyvy_luma_extract.S https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/yuv.inc
我使用&#34; gcc -g convert.c编译__uyvy_luma_extract.S -mfpu = neon&#34;
奇怪的是,程序在转换过程中崩溃了。知道我做错了吗?
*第一次编辑* 我上传了一个包含各种文件的zip文件,以便在ARM平台上轻松重现:http://www.gentil.com/tmp/convert.zip
*第二次编辑* 我更新了不正确的汇编文件链接。
*第三次编辑* gdb给出以下内容:
Starting program: /home/ai/convert/convert
Program received signal SIGSEGV, Segmentation fault.
0x00008036 in ?? ()
(gdb) bt
#0 0x00008036 in ?? ()
#1 0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38
#2 0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
答案 0 :(得分:5)
哦,这是一个很好的。
如果使用-marm构建但使用-mthumb中断,则可以正常工作。 Ubuntu和Android可能有不同的默认值。
它在Thumb模式下中断的原因是汇编函数(总是非Thumb)缺少符号的类型规范,因此链接器不知道它需要使用BLX指令来调用它拇指代码。执行程序时,因此在Thumb状态下错误地调用汇编函数。当解释为Thumb指令时,此函数的第一个半字0x47ff是BLX pc
,它对于不可预测的行为是无效的。显然,Cortex内核只是以明显的方式执行它,即切换到ARM状态,分支到PC值(Thumb状态下的当前指令+4),并将下一个(Thumb)指令地址存储在LR中,从而给出简单地忽略了STM指令的外观。
修复方法是将此行添加到程序集文件中:
.type __uyvy_luma_extract, STT_FUNC
答案 1 :(得分:0)
你给出了错误的链接。正确的是: https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/__uyvy_luma_extract.S
图书馆被窃听。或者,当您最有可能使用完全降序堆栈时,作者会假定空降序堆栈。 将第39行和第40行更改为:
ldr pY, [sp, #(11 * 4)]
ldr dstStride, [sp, #(12 * 4)]
无论如何,在性能方面,图书馆相当黯淡。非常业余的写作,将以NEON的潜在速度的一半运行。
=============================================== ========================
编辑:查看PROLOG宏,它显示该库也推动了lr。这意味着上面的部分没有被窃听。
该功能应该正常工作,尽管不是最佳的。请检查以下内容:
您的代码崩溃了什么异常?