【问题标题】:Video Trimming via ffmpeg twice crash通过ffmpeg进行视频修剪两次崩溃
【发布时间】:2013-09-16 17:16:51
【问题描述】:

我正在尝试使用 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 行时出错 --

Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), (IntentService[V) 

请帮助我消除此崩溃。

提前致谢。

【问题讨论】:

  • 您的代码丢失。
  • 对不起,现在添加代码。
  • 任何人都找到了解决方案。请帮助我

标签: android android-ndk ffmpeg java-native-interface


【解决方案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) -&gt; ffmpeg_opt#ffmpeg_parse_options -&gt; 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;
}

【讨论】:

【解决方案2】:

问题在于 ffmpeg 使用了在第一次运行完成时未重新初始化的静态变量。在第二次运行时,它们仍然具有它们的值,因此 ffmpeg 无法自行初始化并崩溃。

您有两种可能:在每次运行之间卸载/重新加载您的库,或者修改 ffmpeg 源代码以重置这些变量。

【讨论】:

    【解决方案3】:

    只需在你的 ffmpeg.c 中创建一个看起来像这样的方法

    void exitmycode(){
           ffmpeg_exit(0);
    
    }
    

    ffmpeg_exit(0) 方法已经存在于ffmpeg.c 中,您只需在完成视频修剪后从主 C 文件中调用 exitmycode();

    现在发生的情况是,当您使用 ffmpeg 修剪视频或其他任何内容时,它不会完全退出,因此下次运行该命令时它会退出,但它也不会运行您的修剪命令.再一次,如果你第三次运行,命令会完美执行。所以,我所做的是在处理完成时手动调用ffmpeg_exit(0)

    【讨论】:

      【解决方案4】:

      您的问题可能与讨论here

      有关

      链接的线程很旧,但症状是 android/JNI 调用 ffmpeg 第一次有效,但第二次无效。

      如线程中所述,解决方案是在对 ffmpeg 的连续调用之间显式卸载/加载库。

      你可以试试。

      【讨论】:

        猜你喜欢
        • 2022-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-27
        • 2023-04-02
        • 2023-02-02
        • 2016-10-31
        相关资源
        最近更新 更多