Javacv: A problem with the setTimeout method of FFmpegFrameGrabber

Created on 11 Apr 2019  路  6Comments  路  Source: bytedeco/javacv

I found that after I used the setTimeout method of FFmpegFrameGrabber, the program is running a frequent crash, and it appears at any stage, including start, grab, stop.

question

All 6 comments

That property isn't currently even used by FFmpegFrameGrabber, so it can't be the cause of the crashes.

This is my code

public class Stream {

    private static Logger logger = LoggerFactory.getLogger(Stream.class);

    private FFmpegFrameGrabber grabber = null;
    private FFmpegFrameRecorder recorder = null;
    private int width;
    private int height;
    private String sourceUrl;
    private String outputUrl;
    private int videoBitrate;
    private boolean isRun = false;
    private int restartTime = 0;


    public int getInterrupted() {
        return interrupted;
    }

    public void setInterrupted(int interrupted) {
        this.interrupted = interrupted;
    }

    private volatile int interrupted = 0;

    private int audioRecord;


    public String getOutputUrl() {
        return outputUrl;
    }

    public Stream(String sourceUrl, String outputUrl, int width, int height, int audioRecord, int videoBitrate) {
        this.width = width;
        this.height = height;
        this.sourceUrl = sourceUrl;
        this.outputUrl = outputUrl;
        this.audioRecord = audioRecord;
        this.videoBitrate = videoBitrate;
    }

    public Stream pull() throws CommonException {
        grabber = new FFmpegFrameGrabber(sourceUrl);
        grabber.setOption("rtsp_transport", "tcp");
        grabber.setAudioStream(Integer.MAX_VALUE);
        //grabber.setTimeout(3 * 1000000);
        avutil.av_log_set_level(avutil.AV_LOG_ERROR);
        int pullTime = 0;
        for (; pullTime <= 3; pullTime++) {
            try {
                logger.info("try pull from " + sourceUrl);
                grabber.start();
                break;
            } catch (FrameGrabber.Exception e) {
                logger.error(sourceUrl + " pull fail,try pull again");
                e.printStackTrace();
                try {
                    grabber.stop();
                } catch (FrameGrabber.Exception e1) {
                    e1.printStackTrace();
                    logger.error(sourceUrl + " pull fail and grabber stop failed in restart");
                }
                if (pullTime == 3)
                    throw new CommonException("2001", Result.getMessage("2001"));
            }
        }
        logger.info("pull success from " + sourceUrl);
        return this;
    }

    public Stream push() throws CommonException {
        recorder = new FFmpegFrameRecorder(outputUrl, width, height, audioRecord);
        recorder.setFormat("flv");
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //recorder.setAudioCodecName("acc");
        //recorder.setAudioChannels(audioRecord);
        //recorder.setSampleRate(44100);
        //recorder.setVideoBitrate(videoBitrate);
        recorder.setVideoOption("vprofile", "baseline");
        recorder.setVideoOption("tune", "zerolatency");
        recorder.setFrameRate(25);
        recorder.setGopSize(50);
        int pushTime = 0;
        for (; pushTime <= 3; pushTime++) {
            try {
                logger.info("try push to " + outputUrl);
                recorder.start();
                break;
            } catch (FrameRecorder.Exception e) {
                logger.error(outputUrl + " push fail");
                e.printStackTrace();
                try {
                    recorder.stop();
                } catch (FrameRecorder.Exception e1) {
                    e1.printStackTrace();
                    logger.error(outputUrl + " push fail and recorder stop failed in restart");
                }
                if (pushTime == 3)
                    throw new CommonException("2002", Result.getMessage("2002"));
            }
        }
        logger.info("push success to " + outputUrl);
        return this;
    }

    public void start() throws CommonException {
        long startTime = 0;
        int errorIndex = 0;
        Frame frame;
        isRun = true;
        for (int noFrameIndex = 0; interrupted == 0 && (noFrameIndex < 5 || errorIndex > 1); ) {
            try {
                if (startTime == 0)
                    startTime = System.currentTimeMillis();
                long time = System.currentTimeMillis() - startTime;
                recorder.setTimestamp(1000 * time);
                frame = grabber.grab();
                if (frame == null || frame.image == null) {
                    noFrameIndex++;
                    continue;
                }
                recorder.record(frame);
                noFrameIndex = 0;
            } catch (FrameRecorder.Exception e) {
                e.printStackTrace();
                errorIndex++;
            } catch (FrameGrabber.Exception e) {
                e.printStackTrace();
                errorIndex++;
            }
        }
        if (interrupted == 0 && restartTime < 100)
            restart();
        else
            stop();
    }


    public void stop() {
        try {
            logger.info(outputUrl + " is closing");
            grabber.stop();
            recorder.stop();
            isRun = false;
            logger.info(outputUrl + " has been closed");
        } catch (FrameGrabber.Exception e) {
            logger.error(sourceUrl + " pull stream close failed");
            e.printStackTrace();
        } catch (FrameRecorder.Exception e) {
            logger.error(outputUrl + " push stream close failed");
            e.printStackTrace();
        }

    }

    public void restart() throws CommonException {
        logger.info(outputUrl + "is restarting");
        stop();
        restartTime++;
        this.pull().push().start();
    }

    public boolean isRun() {
        return isRun;
    }
}

When I enable this code

grabber.setTimeout(3 * 1000000);

Java crash occurred four times a day, and the program could not run for a long time.
Here is some information about java crash.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffaf26d3b46, pid=892, tid=0x0000000000002de4
#
# JRE version: Java(TM) SE Runtime Environment (8.0_102-b14) (build 1.8.0_102-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.102-b14 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [avformat-58.dll+0x43b46]
#
# Core dump written. Default location: D:\streamTest\hs_err_pid892.mdmp
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
...
Stack: [0x0000000032e20000,0x0000000032f20000],  sp=0x0000000032f1ebf0,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.bytedeco.javacpp.avformat.av_dump_format(Lorg/bytedeco/javacpp/avformat$AVFormatContext;ILjava/lang/String;I)V+0
j  org.bytedeco.javacv.FFmpegFrameGrabber.startUnsafe()V+787
j  org.bytedeco.javacv.FFmpegFrameGrabber.start()V+1
j  com.zzx.smarttown.stream.Stream.pull()Lcom/zzx/smarttown/stream/Stream;+67
j  com.zzx.smarttown.stream.StreamOperate$1.run()V+4
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffaf2958b83, pid=9572, tid=0x00000000000013e0
#
# JRE version: Java(TM) SE Runtime Environment (8.0_102-b14) (build 1.8.0_102-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.102-b14 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [avutil-56.dll+0x28b83]
#
# Core dump written. Default location: D:\streamTest\hs_err_pid9572.mdmp
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
...
Stack: [0x000000002af80000,0x000000002b080000],  sp=0x000000002b07cec8,  free space=1011k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [avutil-56.dll+0x28b83]
C  [avcodec-58.dll+0x28ec30]
C  [avcodec-58.dll+0x50803c]
C  [avformat-58.dll+0x16b4f0]
C  [avformat-58.dll+0x16c415]
C  [avformat-58.dll+0x17907b]
C  [jniavformat.dll+0x2e4b6]
C  0x0000000002487f54

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.bytedeco.javacpp.avformat.avformat_close_input(Lorg/bytedeco/javacpp/avformat$AVFormatContext;)V+0
j  org.bytedeco.javacv.FFmpegFrameGrabber.releaseUnsafe()V+202
j  org.bytedeco.javacv.FFmpegFrameGrabber.release()V+1
j  org.bytedeco.javacv.FFmpegFrameGrabber.stop()V+1
j  com.zzx.smarttown.stream.Stream.stop()V+34
j  com.zzx.smarttown.stream.Stream.restart()V+31
j  com.zzx.smarttown.stream.StreamOperate.getLiveUrl(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+213
j  com.zzx.smarttown.service.StreamService.getLiveStream(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+6
j  com.zzx.smarttown.controller.StreamController.getLiveStream(Ljava/lang/String;Ljava/lang/String;)Lcom/zzx/smarttown/exception/Result;+13
j  sun.reflect.GeneratedMethodAccessor32.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+48
J 3926 C2 java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (62 bytes) @ 0x0000000003449cc8 [0x0000000003449c20+0xa8]
j  org.springframework.web.method.support.InvocableHandlerMethod.doInvoke([Ljava/lang/Object;)Ljava/lang/Object;+16
j  org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(Lorg/springframework/web/context/request/NativeWebRequest;Lorg/springframework/web/method/support/ModelAndViewContainer;[Ljava/lang/Object;)Ljava/lang/Object;+75
j  org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(Lorg/springframework/web/context/request/ServletWebRequest;Lorg/springframework/web/method/support/ModelAndViewContainer;[Ljava/lang/Object;)V+4
j  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;+276
j  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Lorg/springframework/web/method/HandlerMethod;)Lorg/springframework/web/servlet/ModelAndView;+81
j  org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljava/lang/Object;)Lorg/springframework/web/servlet/ModelAndView;+7
j  org.springframework.web.servlet.DispatcherServlet.doDispatch(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V+310
j  org.springframework.web.servlet.DispatcherServlet.doService(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V+308
j  org.springframework.web.servlet.FrameworkServlet.processRequest(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V+71
j  org.springframework.web.servlet.FrameworkServlet.doGet(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V+3
j  javax.servlet.http.HttpServlet.service(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V+35
j  org.springframework.web.servlet.FrameworkServlet.service(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V+33
j  javax.servlet.http.HttpServlet.service(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V+30
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c968c [0x00000000032c8ba0+0xaec]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  org.apache.tomcat.websocket.server.WsFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V+21
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c9134 [0x00000000032c8ba0+0x594]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  com.zzx.smarttown.config.CorsFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V+80
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c9134 [0x00000000032c8ba0+0x594]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  org.springframework.web.filter.RequestContextFilter.doFilterInternal(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V+21
j  org.springframework.web.filter.OncePerRequestFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V+111
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c9134 [0x00000000032c8ba0+0x594]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V+95
j  org.springframework.web.filter.OncePerRequestFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V+111
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c9134 [0x00000000032c8ba0+0x594]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V+87
j  org.springframework.web.filter.OncePerRequestFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V+111
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c9134 [0x00000000032c8ba0+0x594]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;Ljavax/servlet/FilterChain;)V+53
j  org.springframework.web.filter.OncePerRequestFilter.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljavax/servlet/FilterChain;)V+111
J 5491 C1 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (388 bytes) @ 0x00000000032c9134 [0x00000000032c8ba0+0x594]
J 5490 C1 org.apache.catalina.core.ApplicationFilterChain.doFilter(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V (105 bytes) @ 0x0000000002d69a4c [0x0000000002d699c0+0x8c]
j  org.apache.catalina.core.StandardWrapperValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V+688
j  org.apache.catalina.core.StandardContextValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V+166
j  org.apache.catalina.authenticator.AuthenticatorBase.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V+260
j  org.apache.catalina.core.StandardHostValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V+138
j  org.apache.catalina.valves.ErrorReportValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V+6
j  org.apache.catalina.core.StandardEngineValve.invoke(Lorg/apache/catalina/connector/Request;Lorg/apache/catalina/connector/Response;)V+71
j  org.apache.catalina.connector.CoyoteAdapter.service(Lorg/apache/coyote/Request;Lorg/apache/coyote/Response;)V+199
j  org.apache.coyote.http11.Http11Processor.service(Lorg/apache/tomcat/util/net/SocketWrapperBase;)Lorg/apache/tomcat/util/net/AbstractEndpoint$Handler$SocketState;+806
j  org.apache.coyote.AbstractProcessorLight.process(Lorg/apache/tomcat/util/net/SocketWrapperBase;Lorg/apache/tomcat/util/net/SocketEvent;)Lorg/apache/tomcat/util/net/AbstractEndpoint$Handler$SocketState;+113
j  org.apache.coyote.AbstractProtocol$ConnectionHandler.process(Lorg/apache/tomcat/util/net/SocketWrapperBase;Lorg/apache/tomcat/util/net/SocketEvent;)Lorg/apache/tomcat/util/net/AbstractEndpoint$Handler$SocketState;+414
j  org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun()V+191
j  org.apache.tomcat.util.net.SocketProcessorBase.run()V+21
j  java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+95
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5
j  org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run()V+4
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub

This is two of them.I used google search to find a similar error about setting the timeout result. Although his problem is different from mine, I think I should try it, and it works successfully.

Like I said, this is not related to setTimeout(). It might be related to some of the issues with threads fixed in JavaCV 1.5 though. Could you please try again with that version? Also try to call the following:

        grabber.setOption("threads", "1");
        grabber.setVideoOption("threads", "1");
        grabber.setAudioOption("threads", "1");
        recorder.setOption("threads", "1");
        recorder.setVideoOption("threads", "1");
        recorder.setAudioOption("threads", "1");

That often helps to avoid threading issues in many codecs.

The version I'm using is 1.4.4,I will test the program according to your instructions.

After switching the version to 1.5, no similar error occurred. Adding the configuration is the same, but the previous version of the program does not have the same error again during the running, so I think this may be related to the running environment or the running status of the program at the time. Related, I will try to reproduce this problem, which may take a long time to test.

Good! It's probably something that's been fixed upstream.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bahramudin picture Bahramudin  路  3Comments

chrisliu12345 picture chrisliu12345  路  4Comments

SenudaJayalath picture SenudaJayalath  路  3Comments

kongqw picture kongqw  路  4Comments

ahmedaomda picture ahmedaomda  路  4Comments