我正在尝试使用 ffmpeg lib 修剪视频。视频修剪第一次成功但第二次崩溃。
为了解决这个崩溃,我搜索它并使用dlopen()和dlclose()来动态加载ffmpeg lib。
我的代码是 -
const char* path;
void* handle;
void* handle1;
const char *in, *out;
int close;
__android_log_write(ANDROID_LOG_ERROR, "VideoTrimmer Invoke", "Video Trimmer Invoke");
in = (*env)->GetStringUTFChars(env, inputFile, 0);
out = (*env)->GetStringUTFChars(env, outFile, 0);
int *(*Java_com_videotrimmingwithnativesample_VideoTrimmer_trim)(JNIEnv*, jclass ,jstring inputFile, jstring outFile, jint startTime, jint length);
path = (*env)->GetStringUTFChars(env, libffmpegPath, 0);
handle = dlopen(path, RTLD_LAZY);
if(!handle)
{
__android_log_write(ANDROID_LOG_ERROR, "VideoTrimmer Invoke HAndle false", dlerror());
}
else
{
__android_log_write(ANDROID_LOG_ERROR, "VideoTrimmer Invoke HAndle True", dlerror());
}
Java_com_videotrimmingwithnativesample_VideoTrimmer_trim = dlsym(handle, "Java_com_example_videotrimmingwithnativesample_VideoTrimmer_trim");
if(!Java_com_videotrimmingwithnativesample_VideoTrimmer_trim)
{
__android_log_write(ANDROID_LOG_ERROR, "VideoTrimmer Invoke dlsym false",dlerror());
}
else
{
__android_log_write(ANDROID_LOG_ERROR, "VideoTrimmer Invoke dlsym true","Video TrimmerInvoke dlsym true");
}
int i=(*Java_com_videotrimmingwithnativesample_VideoTrimmer_trim)(env, obj, inputFile,outFile,startTime,length);
if(dlclose(handle)==0)
{
(*env)->ReleaseStringUTFChars(env, libffmpegPath, path);
__android_log_write(ANDROID_LOG_ERROR, "VideoTrimmer Invoke close true","Video TrimmerInvoke close true");
}
在dlopen线上第二次使用show时出错 -
Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), (IntentService[V)
请帮我删除此次崩溃。
提前致谢。
答案 0 :(得分:1)
我正在使用FFmpeg 3.6.6构建我的应用程序并遇到同样的问题。根据我的调试经验,它发生是因为变量“nb_filtergraphs”不再是初始值,而是变量“filtergraphs”,当执行此方法时,它将使系统崩溃
static int init_complex_filters(void){
int i, ret = 0;
for (i = 0; i < nb_filtergraphs; i++) {
ret = init_complex_filtergraph(filtergraphs[i] //crash here);
if (ret < 0)
return ret;
}
return 0;}
原始呼叫链是ffmpeg#main(you might change this function name) -> ffmpeg_opt#ffmpeg_parse_options -> ffmpeg_opt#init_complex_filters
我的解决方案是在执行main方法后调用以下代码
ffmpeg.c
int main(int argc, char **argv)//you might change the name {
//.....
ffmpeg_cleanup(received_nb_signals ? 255 : main_return_code);
nb_filtergraphs = 0;
progress_avio = NULL;
input_streams = NULL;
nb_input_streams = 0;
input_files = NULL;
nb_input_files = 0;
output_streams = NULL;
nb_output_streams = 0;
output_files = NULL;
nb_output_files = 0;
exit_program(received_nb_signals ? 255 : main_return_code);
return main_return_code;
}
答案 1 :(得分:0)
您的问题可能与讨论here
有关链接的线程是旧的,但症状是有ffmpeg的android / JNI调用第一次工作但不是第二次。
如线程所述,解决方案是在连续调用ffmpeg之间显式卸载/加载库。
你可以尝试一下。答案 2 :(得分:0)
只需在你的ffmpeg.c中创建一个类似于
的方法void exitmycode(){
ffmpeg_exit(0);
}
ffmpeg_exit(0)
方法已在ffmpeg.c
中,您只需在完成视频修剪后从主C文件中调用exitmycode();
。
现在发生的事情是,当您使用ffmpeg修剪视频或其他任何内容时,它不会完全退出,因此下次运行命令时它会退出,但它也不会运行修剪命令如果你第三次运行,命令就会完美执行。所以,我所做的就是在完成处理结束时手动调用ffmpeg_exit(0)
。
答案 3 :(得分:0)
问题是ffmpeg使用的静态变量在第一次运行完成时没有重新初始化。在第二次运行时,它们仍然具有它们的值,因此ffmpeg无法初始化并崩溃。
您有两种可能性:在每次运行之间卸载/重新加载库,或者修改ffmpeg源代码以重置这些变量。