YUV buffer pstride and rstride clarification needed
foreverneilyoung at googlemail.com
Tue Jul 16 08:32:31 UTC 2019
In order to finalise this discussion with the proper answer here the solution, so that everybody (who is interested) can benefit:
I need to feed OpenCV with the frame delivered by GStreamer (in native code). The OpenCV::Mat constructor is using a parameter called "step", which was set to AUTO_STEP before (which is NOT, what you would suppose an automatic calculation of the padding, but NO_PADDING as documented). Up to now we were in luck and did only meet devices, which gave frames with a padding of zero, so that AUTO_STEP did work.
Except the connection with a DJI drone via Android _and_ on Ubuntu _and_ GStreamer 1.14.4 (right, these were the corner conditions): This came up with an NV12, 720 x 540 frame with a buffer size of 622080, which is not exactly 3/2*w*h.
So the "step" parameter, which describes the "number of bytes each matrix row occupies, including the padding bytes" is now calculated outside the constructor, like so
step = buffer_length * 2 / 3 / height;
which in the documented case gave a step of 768. So this means, the row consists of 740 "real" pixel bytes plus 48 padding bytes, in other words the frame including padding is 768 * 540.
The proper OpenCV constructor call is now:
inputFrame = cv::Mat(height * 3/2, width, CV_8U, ucBuffer, step);
BTW: The same Android device with the same DJI drone behind, but in front of GStreamer 1.16.0 and macOS Mojave (and the same Java app utilising the GStreamer WebRTCBin plugin) came up with an I420 frame of 720 x 540 and a buffer size of 583200. The step in this case is 720, which is exactly the announced width, so there is no padding and it worked with AUTO_STEP...So it was more or less accidentally, that we came across this padding issue...
Somehow brainsick :)
Thanks for the pointers, which made this solution finally possible.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the gstreamer-devel