我已经成功为 android 编译了 ffmpeg。我写了一个简单的应用程序,它只打开 mp4 文件:
int main(int argc, char * argv[])
{
av_register_all();
__android_log_write(ANDROID_LOG_INFO, "NDK", "Opening file: /sdcard/test.mp4...");
if (avformat_open_input(&pFormatCtx, "/sdcard/test.mp4", NULL, NULL) != 0) {
__android_log_write(ANDROID_LOG_INFO, "NDK", "file not opened\n");
return -1;
}
__android_log_write(ANDROID_LOG_INFO, "NDK", "file opened\n");
}
当我运行此代码时,C 代码在此处崩溃:
06-06 18:22:42.629: I/DEBUG(31): #00 pc 00159804 /data/data libffmpeg.so
06-06 18:22:42.629: I/DEBUG(31): #01 lr 809465dc /data/data libffmpeg.so
ndk 堆栈写入:
Stack frame #00 pc 00159804 /data/data/.../lib/libffmpeg.so: Routine av_opt_set_dict in libavutil/opt.c:552
这是 av_opt_set_dict 函数:
int av_opt_set_dict(void *obj, AVDictionary **options)
{
AVDictionaryEntry *t = NULL;
AVDictionary *tmp = NULL;
int ret = 0;
while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
ret = av_set_string3(obj, t->key, t->value, 1, NULL);
if (ret == AVERROR_OPTION_NOT_FOUND)
av_dict_set(&tmp, t->key, t->value, 0);
else if (ret < 0) {
av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
break;
}
ret = 0;
}
av_dict_free(options);
*options = tmp;
return ret;
}
552行是:
while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
这段代码在我的 linux 机器上工作(当然对于 linux 使用 .so,对于 android,我使用 ndk 构建的 .so 文件),但不在 android 下。
此外,它在我有根的 HTC Desire Z 上工作,但不适用于模拟器或无根设备。
在这里我找到了需要更改 libavformat/file.c file_check 函数的帖子:
static int file_check(URLContext *h, int mask)
{
struct stat st;
int ret = stat(h->filename, &st);
if (ret < 0)
return AVERROR(errno);
ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0;
ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0;
return ret;
}
至
static int file_check(URLContext *h, int mask)
{
struct stat st;
int ret = stat(h->filename, &st);
if (ret < 0)
return AVERROR(errno);
ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0;
ret |= st.st_mode&S_IRGRP ? mask&AVIO_FLAG_READ : 0;
ret |= st.st_mode&S_IROTH ? mask&AVIO_FLAG_READ : 0;
ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0;
ret |= st.st_mode&S_IWGRP ? mask&AVIO_FLAG_WRITE : 0;
ret |= st.st_mode&S_IWOTH ? mask&AVIO_FLAG_WRITE : 0;
return ret;
}
但这没有帮助。
有什么建议么?
谢谢