Hello zadok,
Maybe you already found a solution for your problem. If it’s not the case, I share with you a tutorial I made to build the opencv_videoio_ffmpeg*.dll. It’s made to be use by anybody so don’t be mad if you found it too childish.
Tutorial to compil you own modified version of opencv_videoio_ffmpeg*.dll
Goal:
We will modify the library to change the pixel format used when writing raw video with the fourcc codec 0x00000000 which stand for BI_RGB label. There is no fourcc label to use this, you need to specify the hex code when creating the VideoWriter, example:
cv::VideoWriter outputVideo; cv::Size S = cv::Size(800, 600); outputVideo.open( "out.avi", //output file 0x00000000, //fourcc codec hex code [or use label VideoWriter::fourcc('I','4','2','0') = 0x30323449 in hex] 24, //framerate (must be greater than 6 for compatibility with most video player) S, //the video size true //boolean value to set if video is with color (which is the case here) );
In the actual repository maintained by the developper of OpenCV, the 0x000000 codec use by default yuv420p pixel, which for me is a mistake (but who am I to judge).
Note: 0x000000 can be replace by 0, of course, but I prefer the hex form since it’s the one used by the fourcc web site. And if you want to change the 0x30323449? Uuhh!!! Yeah, me too.
Prerequisites:
Before the modification, you will need a few tools:
- A linux installation on you windows system : Ubuntu for example in the Microsoft Store.
- Docker desktop
—Optional— - GitHub Desktop
From Ubuntu, you need to configure git if it’s not already done with:
git config --global user.email "You@example.com" git config --global user.name "Your Name"
Before starting to download the source code needed, you need to find the good one for your version of OpenCV. I use the 4.5.0 version released on 11th October 2020 (commit d5fd2f0). The date is important, because you need to download the good branch of opencv_3rdparty from github (at least the closer one in time).
opencv_3rdparty : GitHub - opencv/opencv_3rdparty at ffmpeg/master_20200908
opencv : GitHub - opencv/opencv at 4.5.0
For opencv_3rdparty you can download the zip archive of the branch. No need to clone the repository with git. Extract the zip archive somewhere. Inside the extracted directory (opencv_3rdparty-ffmpeg-master_20200908 or opencv_3rdparty for the remaining of this tuto), there is an empty opencv directory. We will clone opencv inside.
If you want to git clone opencv_3rdparty:
git clone https://github.com/opencv/opencv_3rdparty.git --single-branch --branch ffmpeg/master_20200908
For opencv you absolutly need to clone the repository and switch to the good branch.
So inside you opencv_3rdparty directory (not the empty opencv), do from the ubuntu command line (not the windows command line)
git clone https://github.com/opencv/opencv.git --single-branch --branch 4.5.0
this will clone to opencv_3rdparty/opencv and switch to the 4.5.0 branch
Using --single-branch can reduce the total size by two, mostly for opencv_3rdparty. Don’t try to build the dll with a different version of opencv than the targeted one, because it doesn’t work. Of course the compilation will be fine, but you will have problem when you use the dll. If you choose the wrong version of opencv_3rdparty, the compilation will probably failed.
Modification:
This part is up to you, you can modify opencv as you which but for opencv_videoio_ffmpeg*.dll, there is only three files inside opencv_3rdparty/opencv/modules/videoio/src
cap_ffmpeg_impl.hpp cap_ffmpeg_legacy_api.hpp ffmpeg_codecs.hpp
In my case, to modify the pixel format for 0x00000000 codec, the file is cap_ffmpeg_impl.hpp. The modification is:
[line 2295] case CV_CODEC(CODEC_ID_RAWVIDEO): // RGBA is the only RGB fourcc supported by AVI and MKV format if(fourcc == CV_FOURCC('R','G','B','A')) { codec_pix_fmt = AV_PIX_FMT_RGBA; } + else if(fourcc == 0x00000000) + { + codec_pix_fmt = AV_PIX_FMT_BGR24; + } else { switch(input_pix_fmt) { case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_GRAY16LE: case AV_PIX_FMT_GRAY16BE: codec_pix_fmt = input_pix_fmt; break; default: codec_pix_fmt = AV_PIX_FMT_YUV420P; break; } } [line 2314]
The four lines added (at position 2301 of the file) start with a ‘+’. As you can see, if the fourcc is not RGBA or the input is not GRAY, the pixel format used by default is AV_PIX_FMT_YUV420P. So I added AV_PIX_FMT_BGR24 for the 0x00000000.
Building:
Aaah, the most important part. First thing to do is to commit you change to the local repository of opencv. It’s realy important, if you not commit the changes, their will not apply to the build. The easiest way is to use GitHub Desktop. Or inside the opencv_3rdparty/opencv directory from ubuntu command line:
git commit -am "modify cap_ffmpeg_impl.hpp for pix_fmt"
- Start Docker Desktop if it’s not already running or you will get the following error:
The command ‘docker’ could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.
- From Ubuntu, inside the opencv_3rdparty directory :
ffmpeg/build_via_docker.sh
That’s all
The resulting dll can be found in opencv_3rdparty\ffmpeg, the previous one as been replaced.
Note : during the build, you will see that git package the three .hpp files above, at this stage you can check that inside this archive opencv_3rdparty\sources\opencv\opencv-videoio-ffmpeg.tar.xz, the files are actually modified. If it’s not the case it’s because you don’t commit you changes.
When you run ffmpeg/build_via_docker.sh, if you get ‘: wrong parameter’ or something like that, it’s because you probably clone the opencv_3rdparty from the windows console. And since it’s windows, the endline is CRLF, not LF. A solution is to run dos2unix on all the file inside opencv_3rdparty directory.
During the build you can see the below warnings:
/app/opencv_ffmpeg.rc:12: digit exceeds base /app/opencv_ffmpeg.rc:13: digit exceeds base
It’s nothing you should care about.
I hope it will help.