Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FFmpeg] avformat_find_stream_info crashes with two log callback set successively #683

Closed
yescallop opened this issue Feb 3, 2019 · 13 comments

Comments

@yescallop
Copy link

Platform: windows-x86_64
Version: 4.1-1.4.4

Codes:

https://github.com/yescallop/Aid/tree/71165f5577e3105d3178f3c3640455b09746f800/AidBase_Video/src/main/java/cn/yescallop/aid/video/Main.java

Expected result:

Input device: Lenovo EasyCamera (@device_pnp_\\?\usb#vid_13d3&pid_5741&mi_00#6&801b1b8&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global)
Successfully opened input
0

Process finished with exit code 0

Actual result:

Input device: Lenovo EasyCamera (@device_pnp_\\?\usb#vid_13d3&pid_5741&mi_00#6&801b1b8&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global)
Successfully opened input

Process finished with exit code -1073741819 (0xC0000005)

Debug stack info:

image

Some tests after some modifications:

  1. If I comment out this line: https://github.com/yescallop/Aid/blob/71165f5577e3105d3178f3c3640455b09746f800/AidBase_Video/src/main/java/cn/yescallop/aid/video/device/dshow/DshowDeviceListHelper.java#L85
    In other words, DshowDeviceListHelper.CALLBACK_POINTER is referenced from nowhere,
    DshowDeviceListHelper.CALLBACK_POINTER.call is still being called.
    It seems that when a new Callback_Pointer_int_BytePointer_Pointer instance is created, if there was another instance, the memory of the two instances would be messed up (Sorry for confusions since I've no much knowlegde about jni and C++).

  2. If I don't call listDevices() and directly use a self-typed DeviceInfo for opening input and finding stream info, all will be fine.

@saudet
Copy link
Member

saudet commented Feb 3, 2019 via email

@yescallop
Copy link
Author

No, I just need to replace the previous log function pointer with a new one.

@saudet
Copy link
Member

saudet commented Feb 3, 2019

What happens if you call FFmpegLogCallback.set() instead? Does that one work properly?

Could you also attach the hs_err_pid*.log file that you get?

@yescallop
Copy link
Author

@saudet That implementation can't meet my need well because I need to handle logs without prefixes.
Actually I didn't get any error log file, even any error message. The program just exited with exit code -1073741819 (0xC0000005). The debug stack info attached was got by a tool called WinDbg.

@saudet
Copy link
Member

saudet commented Feb 3, 2019

I just want to know if FFmpegLogCallback.set() works. If it works, it's a problem with your callback, and has nothing to do with JavaCPP or FFmpeg.

@yescallop
Copy link
Author

Thanks for help. I'll check it later and try writing simple codes to reproduce this issue.

@yescallop
Copy link
Author

yescallop commented Feb 3, 2019

Callback_Pointer_int_BytePointer_Pointer c1 = new Callback_Pointer_int_BytePointer_Pointer() {
    @Override
    public void call(Pointer avcl, int level, BytePointer fmt, Pointer vl) {
        System.out.println("callback1");
    }
};
av_log_set_callback(c1);
Callback_Pointer_int_BytePointer_Pointer c2 = new Callback_Pointer_int_BytePointer_Pointer() {
    @Override
    public void call(Pointer avcl, int level, BytePointer fmt, Pointer vl) {
        System.out.println("callback2");
    }
};
av_log(null, AV_LOG_INFO, "test");

The output is "callback2", why is this happening?

@saudet
Copy link
Member

saudet commented Feb 3, 2019

Like I said, that's a current limitation of FunctionPointer. Don't define more than one of them.

@yescallop
Copy link
Author

I think the issue is caused by this limitation. I think I have to define only one FunctionPointer which calls a outside callback function. What is this limitation caused by and can it be fixed?

@saudet
Copy link
Member

saudet commented Feb 3, 2019

It could be fixed, but it wouldn't be that easy, and you're like the second person to have asked about this in maybe 5 years, so it's not something that a lot of people need. Details are in the code here:

   // XXX: Here, we should actually allocate new trampolines on the heap somehow...
   // For now it just bumps out from the global variable the last object that called this method

https://github.com/bytedeco/javacpp/blob/master/src/main/java/org/bytedeco/javacpp/tools/Generator.java#L3058
Another way to work around this is to declare more than one native call() method in different FunctionPointer subclasses, but then your code has to track which subclass gets used so it doesn't really solve anything, unless it's part of your application, but if you do that you'll need to build a native library using JavaCPP, and that's not easy either. In any case, we can't have 2 callback functions for the log anyway, so in this case I really don't see this as an issue.

@yescallop
Copy link
Author

I understand the difficulty. A walk-around by defining a fixed callback method should be useful. Anyway, thanks for your help.

@saudet
Copy link
Member

saudet commented May 11, 2019

Since this issue is a severe limitation for CPython, I've fixed it in commit bytedeco/javacpp@86e4f2e!
Please give it a try with the snapshots: http://bytedeco.org/builds/

saudet added a commit to bytedeco/javacpp that referenced this issue May 12, 2019
saudet added a commit to bytedeco/javacpp that referenced this issue May 12, 2019
@saudet
Copy link
Member

saudet commented Jul 9, 2019

Fix included in version 1.5.1. Thanks for reporting!

@saudet saudet closed this as completed Jul 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants