Consider video meta on GStreamer video capture#22018
Consider video meta on GStreamer video capture#22018opencv-pushbot merged 1 commit intoopencv:4.xfrom
Conversation
Some GStreamer elements may produce buffers with very non standard strides, offsets and/or even transport each plane in different, non-contiguous pointers. This non-standard layout is communicated via GstVideoMeta structures attached to the buffers. Given this, when a GstVideoMeta is available, one should parse the layout from it instead of generating a generic one from the caps. The GstVideoFrame utility does precisely this: if the buffer contains a video meta, it uses that to fill the format and memory layout. If there is no meta available, the layout is inferred from the caps.
|
Thanks for the contribution! Could you point me the case where per-frame memory layout differs from the video one. Is it specific to GStreamer version or some codec/camera ? |
|
Hey @asmorkalov. I just experienced this with a proprietary camera that gave odd widths and no padding. GStreamer, if not explicitly indicated otherwise, assumes the stride will be a multiple of 4 bytes, which wasn't true for this camera. So the way I communicated the correct stride was using the video meta. I created a dirty mock element that causes this same effect. Consider the following video capture app: #include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv )
{
cv::VideoCapture cap(
"oddsrc ! video/x-raw,width=321,height=240,format=BGR ! appsink", cv::CAP_GSTREAMER);
cv::namedWindow("Display Image", WINDOW_AUTOSIZE );
while(1){
cv::Mat frame;
cap >> frame;
imshow("Display Image", frame);
waitKey(33);
}
cap.release();
return 0;
}The On the other hand, if one uses video_frame_map (as in the PR), the correct stride is considered and the image is properly displayed: To verify this yourself, you can build the gcc gstoddsrc.c `pkg-config --cflags --libs gstreamer-1.0 gstreamer-base-1.0 gstreamer-video-1.0` -shared -o libgstoddsrc.so |
|
Thanks a lot for the contribution. The patch works for me and looks very reasonable. 5 cents from my side:
|
|
Test system: Ubuntu 18.04. GStreamer 1.14.5. OpenCV cannot convert YUV with odd width. All branches tested manually. |
alalek
left a comment
There was a problem hiding this comment.
LGTM 👍 Thank you for contribution!
Some GStreamer elements may produce buffers with very non
standard strides, offsets and/or even transport each plane
in different, non-contiguous pointers. This non-standard
layout is communicated via GstVideoMeta structures attached
to the buffers. Given this, when a GstVideoMeta is available,
one should parse the layout from it instead of generating
a generic one from the caps.
The GstVideoFrame utility does precisely this: if the buffer
contains a video meta, it uses that to fill the format and
memory layout. If there is no meta available, the layout is
inferred from the caps.
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.