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

FFmpegFrameGrabber casue jvm crash when loading .swf file. #1113

Open
zxdispd opened this issue Dec 28, 2018 · 18 comments
Open

FFmpegFrameGrabber casue jvm crash when loading .swf file. #1113

zxdispd opened this issue Dec 28, 2018 · 18 comments

Comments

@zxdispd
Copy link

zxdispd commented Dec 28, 2018

I use FFmpegFrameGrabber to get image frame from videos. Everything was fine until I load some .swf file in my app. And the jvm is crash.
I already try
#1055
#605
but it doesn't work for me.

I use maven to manage my project, and the related javacv config is:

        <!-- JavaCV start -->
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg</artifactId>
            <version>4.0.2-1.4.3</version>
            <classifier>linux-x86_64</classifier>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg</artifactId>
            <version>4.0.2-1.4.3</version>
            <classifier>windows-x86_64</classifier>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.3</version>
        </dependency>
        <!-- JavaCV end -->

My system is:Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.78-1 x86_64 GNU/Linux

My java code is:

@Override
public void run() {
    FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoPath);
    frameGrabber.setOption("RW_TIMEOUT".toLowerCase(), "3000000");
    frameGrabber.setOption("threads", "1");
    avutil.av_log_set_level(avutil.AV_LOG_ERROR);
    int frameNumber = 0;
    finished = false;
    try {
        frameGrabber.start();
        Frame frame;
        long lastTimeStamp = 0L;
        while ((frame = frameGrabber.grabImage()) != null) {
            long currentTimeStamp = frameGrabber.getTimestamp();
            if ((currentTimeStamp - lastTimeStamp) > screenShotFrequency * 1000000) {
                //Add the frame to a List.
                lastTimeStamp = currentTimeStamp;
            }
        }
        frameGrabber.close();
    } catch (Exception e) {
        log.info("Exception = {}", e);
    } finally {
        //some extra logic
    }
}

And here is a swf file:

@saudet
Copy link
Member

saudet commented Dec 28, 2018

Does it do that with any other video file? It just looks like that SWF file is corrupted...

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

Does it do that with any other video file? It just looks like that SWF file is corrupted...

@saudet
I use FFmpeg instead of FFmpegFrameGrabber to loading the same swf file(in Java program), and it works. And other video file doesn't have the problem.

@saudet
Copy link
Member

saudet commented Dec 29, 2018 via email

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

Does it also crash with FFmpeg 4.1 and JavaCV 1.4.4-SNAPSHOT?

https://mvnrepository.com/artifact/org.bytedeco/javacv
https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg

Where can I find FFmpeg 4.1 and JavaCV 1.4.4-SNAPSHOT? Clone the project and build in local?

@saudet
Copy link
Member

saudet commented Dec 29, 2018

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

http://bytedeco.org/builds/

I tried with the new snapshot version, the jvm still crash.
Here are some log info.

the fisrt time:
java: malloc.c:3524: _int_malloc: Assertion `(bck->bk->size & 0x4) == 0' failed.

the second and the third time:
*** Error in `/home/nisp/.ndp/base/jdk/jdk1.8.0_101/jre/bin/java': double free or corruption (!prev): 0x00007efda00aa140 ***

@saudet
Copy link
Member

saudet commented Dec 29, 2018

It looks like the size of the images change on each frame, must be related to something with that, but it's working just fine with this code here for me:

        OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("/tmp/df170e9a-7720-48b7-bf29-4b645c256eba.swf");
        grabber.start();

        int count = 0;
        Frame frame;
        while ((frame = grabber.grab()) != null) {
            System.out.println(count++);
            if (frame.image != null)
            imwrite(count + ".jpg", converter.convert(frame));
        }
    }

It's decoding up to 5028 without any apparent issues.

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

@saudet
I think I found the problem, I download the swf file on local, and rename it to ***.mp4, and then I use FFmpegFrameGrabber to get image frame with it's local path, and then jvm crash. I will do extra test for this ease, If I confirm the problem, I will close this issue. Thanks for your help.

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

I test the case, and now I'm sure the swf file cause jvm crash.

    public void run() {
        long currentTimeStamp = 0L;
        long lastTimeStamp = 0L;
        int frameNumber = 1;
        boolean first = true;
        Frame frame;
        log.info("run: JavaCV start, uuid={}, videoPath={}, screenShotFrequency={}", uuid, videoPath, screenShotFrequency);
        try (FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoPath)) {
            frameGrabber.setOption("RW_TIMEOUT".toLowerCase(), "3000000");
            frameGrabber.setOption("threads", "1");
            avutil.av_log_set_level(avutil.AV_LOG_ERROR);
            frameGrabber.start();
            while ((frame = frameGrabber.grab()) != null) {
                currentTimeStamp = frameGrabber.getTimestamp();
                int count = 0;
                if (frame.image != null) {
                    log.info("this is a test from roomy, count = {} success = {}", count);
                    count++;
                }
        } catch (Exception e) {
            log.error("run: exception! uuid={}", uuid, e);
        } finally {
        }
    }

Here is the app.err.log info

Input #0, swf, from 'http://nos.netease.com/vod0vwkapu4/8972f46c-6add-498f-8ca7-872b90ae3809.swf':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 1024x740 [SAR 96:96 DAR 256:185], 15 fps, 15 tbr, 15 tbn
    Stream #0:1: Audio: mp3, 22050 Hz, mono, fltp, 32 kb/s
    Stream #0:2: Video: rawvideo (ARGB / 0x42475241), argb, 72x20, 15 fps, 15 tbr, 15 tbn

Here is the app.log:

 A fatal error has been detected by the Java Runtime Environment:

  SIGSEGV (0xb) at pc=0x00007ff13b1e94d8, pid=51860, tid=0x00007ff104128700

 JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
 Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode linux-amd64 compressed oops)
 Problematic frame:
 C  [libc.so.6+0x794d8][thread 140673327015680 also had an error]
 [ timer expired, abort... ]

@saudet
Copy link
Member

saudet commented Dec 29, 2018

I see, it's currently guessing the file format based on the file extension, but since ffplay doesn't appear to have this issue, maybe there's a safer way to do it now? Anyway, let's leave this issue opened, but marked as enhancement.

@saudet
Copy link
Member

saudet commented Dec 29, 2018

Nope, I just get this error when I try to open it as an "mp4" file:

Exception in thread "main" org.bytedeco.javacv.FrameGrabber$Exception: avformat_open_input() error -1094995529: Could not open input

In any case, I will not be able to fix this until I can reproduce this issue.
It's working just fine for me on Linux (Fedora 27).

@saudet
Copy link
Member

saudet commented Dec 29, 2018

Ah, here's something interesting. It's only happening when using the HTTP protocol. It doesn't happen when reading from a file locally. There's probably some HTTP settings that ffplay sets by default that we'd need to set manually... Comparing the verbose log of both ffplay and FFmpegFrameGrabber might give us a clue about what is different.

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

My system is Debian 3.16.43-2 (2017-04-30) x86_64 GNU/Linux. And I will try other system tonight. It's see if the system casue the problem.

@saudet
Copy link
Member

saudet commented Dec 29, 2018

Actually, with http://nos.netease.com/vod0vwkapu4/8972f46c-6add-498f-8ca7-872b90ae3809.swf it crashes even when reading it locally. Well, avcodec_decode_video2() is a deprecated function. We'll need to switch over to the new API soon or later. Would you like to give it a try? It might very well fix this.

@saudet saudet added bug and removed enhancement labels Dec 29, 2018
@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

Actually, with http://nos.netease.com/vod0vwkapu4/8972f46c-6add-498f-8ca7-872b90ae3809.swf it crashes even when reading it locally. Well, avcodec_decode_video2() is a deprecated function. We'll need to switch over to the new API soon or later. Would you like to give it a try? It might very well fix this.

Thanks! I will change my version after you fix this bug. Thanks again.

@saudet
Copy link
Member

saudet commented Dec 29, 2018

I will not be able to look into this anytime soon, so if you have some time, please give it a try yourself. Thanks

@zxdispd
Copy link
Author

zxdispd commented Dec 29, 2018

I will not be able to look into this anytime soon, so if you have some time, please give it a try yourself. Thanks

Of course, I will test more cases for the problem.

@saudet
Copy link
Member

saudet commented Nov 26, 2021

JavaCV 1.5.6 does not use the deprecated API anymore. Please give it a try and let me know if it fixes this issue or not. Thanks!

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