FFmpegFrameGrabber: Unable to destroy and re-create grabber

412 views
Skip to first unread message

Jose Gómez

unread,
Mar 9, 2013, 9:15:16 PM3/9/13
to jav...@googlegroups.com
I want to use a FFmpegFrameGrabber when possible, but if something fails (the user doesn't have the ffmpeg libraries, or any other initialization problem, I would like to release the reserved resources, and create an OpenCVFrameGrabber:

FrameGrabber grabber = new FFmpegFrameGrabber(new java.io.File("/dev/video0"));
grabber.setFormat("video4linux2");
 
try {
    grabber.start();
}
catch (Exception e)
{
    grabber.stop();
    grabber.release();
    grabber = null;

    grabber = FrameGrabber.createDefault(0);    // Lowest common denominator
    grabber.start();
}

However, on the second grabber.start(), I get the following error:

libv4l2: error setting pixformat: Device or resource busy
HIGHGUI ERROR: libv4l unable to ioctl S_FMT
libv4l2: error setting pixformat: Device or resource busy
libv4l1: error setting pixformat: Device or resource busy
HIGHGUI ERROR: libv4l unable to ioctl VIDIOCSPICT

*** glibc detected *** /usr/lib/jvm/java-7-oracle/bin/java: double free or corruption (fasttop): 0x00007f68c4199dd0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f68cb6d8b96]
/tmp/javacpp42478226030754/libopencv_highgui.so.2.4(_ZN20CvCaptureCAM_V4L_CPP4openEi+0x6ca)[0x7f688e52312a]
/tmp/javacpp42478226030754/libopencv_highgui.so.2.4(_Z25cvCreateCameraCapture_V4Li+0x3d)[0x7f688e52459d]
/tmp/javacpp42478226030754/libopencv_highgui.so.2.4(cvCreateCameraCapture+0x7a)[0x7f688e5125ca]
/tmp/javacpp42478226030754/libjniopencv_highgui.so(Java_com_googlecode_javacv_cpp_opencv_1highgui_cvCreateCameraCapture+0x1d)[0x7f688901ce0d]
[0x7f68c1011f90]
======= Memory map: ========

I have tried using/commenting out several combinations of grabber.stop/release, but so far I haven't been able to create an OpenCVFrameGrabber after a failed attempt to build a FFmpegFrameGrabber.

However, if I create an OpenCVFrameGrabber, destroy it, and create a new one, that is fine. The problem is only trying to create first a FFmpegFrameGrabber and afterwards a OpenCVFrameGrabber.

Samuel Audet

unread,
Mar 10, 2013, 8:09:29 AM3/10/13
to jav...@googlegroups.com
According to FFmpeg's documentation, there's nothing to do done when
avformat_open_input() fails, but to abort, give up. So I guess there is
a bug in FFmpeg and it fails to release some resources before
deallocating its memory. You should report that to them so they can fix
it :)

Samuel

On 03/10/2013 11:15 AM, Jose G�mez wrote:
> I want to use a FFmpegFrameGrabber when possible, but if something fails
> (the user doesn't have the ffmpeg libraries, or any other initialization
> problem <// https://groups.google.com/forum/#!topic/javacv/Nwp2Vd4Rz8I>,

Jose Gómez

unread,
Mar 10, 2013, 3:54:28 PM3/10/13
to jav...@googlegroups.com
Where can I find that documentation?

This is what I have found online:


int avformat_open_input(AVFormatContext ** ps,
const char * filename,
AVInputFormat * fmt,
AVDictionary ** options 
)

Open an input stream and read the header.

The codecs are not opened. The stream must be closed with av_close_input_file().

Parameters
psPointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). May be a pointer to NULL, in which case an AVFormatContext is allocated by this function and written into ps. Note that a user-supplied AVFormatContextwill be freed on failure.
filenameName of the stream to open.
fmtIf non-NULL, this parameter forces a specific input format. Otherwise the format is autodetected.
optionsA dictionary filled with AVFormatContext and demuxer-private options. On return this parameter will be destroyed and replaced with a dict containing options that were not found. May be NULL.
Returns
0 on success, a negative AVERROR on failure.
Note
If you want to use custom IO, preallocate the format context and set its pb field.

Note that a user-supplied AVFormatContextwill be freed on failure.

Is this what you are referring to? That seems to be the case with FFmpegFrameRecorder, where the invocation is:

oc              = new AVFormatContext(null);
... 
avformat_open_input(oc, filename, f, options)

On the other hand, there is a close function that we may want to try, just in case the bug was in the FFmpeg documentation, and closing the input was actually required:


void avformat_close_input(AVFormatContext ** s)

Close an opened input AVFormatContext.

Free it and all its contents and set *s to NULL.


Regards,

Jose Gómez.

On Sunday, March 10, 2013 12:09:29 PM UTC, Samuel Audet wrote:
According to FFmpeg's documentation, there's nothing to do done when
avformat_open_input() fails, but to abort, give up. So I guess there is
a bug in FFmpeg and it fails to release some resources before
deallocating its memory. You should report that to them so they can fix
it :)

Samuel

Jose Gómez

unread,
Mar 10, 2013, 5:56:46 PM3/10/13
to jav...@googlegroups.com
In FFmpegFrameGrabber.java, I have tried to add a call to avformat_close_input in the exception after avformat_open_input, but I get an error like:

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f1db5e398a2, pid=25944, tid=139766481565440
#
# JRE version: 7.0_17-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.7-b01 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [libavformat.so.54.59.106+0xff8a2]  avformat_close_input+0x12

So, it is probably not a good solution... :)

I have also tried adding the following before throwing the exception:

            release();
            av_dict_free(options);
            oc = null;

No improvement so far...
Reply all
Reply to author
Forward
0 new messages