VideoCapture does not change CAP_PROP_FOURCC property

3,223 views
Skip to first unread message
Message has been deleted

aymeric

unread,
Mar 5, 2019, 9:30:20 AM3/5/19
to javacv
Hi,

I am using JavaCV 1.4.4 on Windows 10 (64-bits) and I'm trying to use the camera ELP-USB500W05G-L60 (http://www.webcamerausb.com/elpusb500w05gl60-p-69.html) with the MJPG video format.

Below is my code, which successfully set the image width, but fails to set the CAP_PROP_FOURCC property:

VideoCapture cap = new opencv_videoio.VideoCapture(0);
int mjpg = VideoWriter.fourcc((byte)'M', (byte)'J', (byte)'P', (byte)'G');
 
boolean fourccChanged = cap.set(CAP_PROP_FOURCC, mjpg); // fourccChanged = false
       
boolean widthChanged = cap.set(CAP_PROP_FRAME_WIDTH, w); // widthChanged = true    
               
System.out.println(cap.get(CAP_PROP_FOURCC)); // prints "8.42094158E8", corresponding to the fourcc "NV12"

The value of the CAP_PROP_FOURCC property is the one corresponding to the fourcc "NV12" with 2 different cameras, and corresponds to "YUY2" when I try with my webcam.

I got the same results using OpenCVFrameGrabber and FFmpegFrameGrabber, but the Python code below works as expected:

cam = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
cam.set(cv2.CAP_PROP_FOURCC, fourcc)

print("apres", cam.get(cv2.CAP_PROP_FOURCC)) # prints "1196444237.0", corresponding to the fourcc "MJPG"

What am I doing wrong to make the video format change in JavaCV?

Thanks!

Samuel Audet

unread,
Mar 5, 2019, 7:51:44 PM3/5/19
to jav...@googlegroups.com, aymeric
OpenCV probably relies on FFmpeg to decode MJPEG images, but the presets don't link with FFmpeg by default, because of potential licensing issues and because we can use FFmpegFrameGrabber instead anyway.

On Windows, there is also another option: VideoInputFrameGrabber. Could you give that one a try as well? If that doesn't work either, please let me know! Thanks

Samuel

aymeric

unread,
Mar 6, 2019, 11:39:37 AM3/6/19
to javacv
Thanks for your reply.
I tried calling the setFormat() method of VideoInputFrameGrabber, without any improvement (see the code snippet below)

VideoInputFrameGrabber grabber = new VideoInputFrameGrabber(0);
grabber
.setFormat("MJPG");
// grabber.setImageWidth(w);
// grabber.setImageHeight(h);
grabber
.start();


I also created a copy of VideoInputFrameGrabber and added the line

myVideoInput.setRequestedMediaSubType(VI_MEDIASUBTYPE_MJPG)

in the start() method, but nothing changed, either using "VI_MEDIASUBTYPE_MJPG" or an other media subtype constant.

I get those logs when I don't set the image dimensions, or when I set it to "correct" resolutions (e.g. 1920*1080 or 1280*720):

***** VIDEOINPUT LIBRARY - 0.2000 - TFW2013 *****
SETUP
: Setting up device 0
SETUP
: HD USB Camera
SETUP
: Couldn't find preview pin using SmartTee
SETUP: Default Format is set to 1600 by 1200
SETUP: trying requested format RGB24 @ 1920 by 1080
SETUP: trying format RGB24 @ 1920 by 1080
SETUP: trying format RGB32 @ 1920 by 1080
SETUP: trying format RGB555 @ 1920 by 1080
SETUP: trying format RGB565 @ 1920 by 1080
SETUP: trying format YUY2 @ 1920 by 1080
SETUP: Capture callback set
SETUP: Device is setup and ready to capture.

The format seems here to be YUY2, which would be consistant with the low frame rate I get (5fps at 1920*1080), but neither a call to setFormat("MJPG") nor a call to setRequestedMediaSubType() change that. With "incorrect" dimensions, I get 30fps and I have the following:


***** VIDEOINPUT LIBRARY - 0.2000 - TFW2013 *****
...
SETUP
: trying format RGB565 @ 800 by 800
SETUP
: trying format YUY2 @ 800 by 800
SETUP
: trying format YVYU @ 800 by 800
SETUP
: trying format YUYV @ 800 by 800
SETUP
: trying format IYUV @ 800 by 800
SETUP
: trying format UYVY @ 800 by 800
SETUP
: trying format YV12 @ 800 by 800
SETUP
: trying format YVU9 @ 800 by 800
SETUP
: trying format Y411 @ 800 by 800
SETUP
: trying format Y41P @ 800 by 800
SETUP
: trying format Y211 @ 800 by 800
SETUP
: trying format AYUV @ 800 by 800
SETUP
: trying format Y800 @ 800 by 800
SETUP
: trying format Y8 @ 800 by 800
SETUP
: trying format GREY @ 800 by 800
SETUP
: trying format OTHER @ 800 by 800
SETUP
: couldn't find requested size - searching for closest matching size
SETUP: closest supported size is OTHER @ 800 600
SETUP: Capture callback set
SETUP: Device is setup and ready to capture.

A also tried calling grabber.setVideoCodec(avcodec.AV_CODEC_ID_MJPEG) instead of setFormat(), but it's still does nothing, and I'm a bit confused about the differences between setFormat(), setVideoCodec(), and setPixelFormat().

Samuel Audet

unread,
Mar 6, 2019, 8:20:08 PM3/6/19
to jav...@googlegroups.com, aymeric
FFmpeg apparently supports MJPEG with DirectShow:

So something like this should work with FFmpegFrameGrabber:
FrameGrabber grabber = new FFmpegFrameGrabber("video=Integrated Camera");
grabber.setFormat("dshow");
grabber.setVideoCodecName("mjpeg");
grabber.start();
You'll need to replace the name with the one for your camera though.

Samuel

aymeric

unread,
Mar 7, 2019, 5:54:09 PM3/7/19
to javacv
It's working with DirectShow, thank you very much!
Reply all
Reply to author
Forward
0 new messages