Ok I tried to fix this but still no love.
I got the GstVideoInfo this way:
GstPad* pad = gst_element_get_static_pad(getSink(), "sink");
GstCaps *caps = gst_pad_get_current_caps (GST_PAD (pad));
GstVideoInfo vinfo;
gst_video_info_init (&vinfo);
gst_video_info_from_caps (&vinfo, caps);
GstVideoFrame f;
gst_video_frame_map(&f,&vinfo,_buffer,GST_MAP_READ);
cout << "INFO ----------------------------------------------------" << endl;
cout << "Width=" << f.info.width << " Height=" << f.info.height << endl;
cout << "interlace=" << f.info.interlace_mode << " size="<< f.info.size << endl;
cout << "stride=" << f.info.stride[0] << " offset="<< f.info.offset[0] << endl;
cout << "flags=" << f.info.flags << " views="<< f.info.views << endl;
cout << "pixel stride =" << f.info.finfo->pixel_stride[0] << " format flags = " << f.info.finfo->flags << endl;
cout << "video format=" << f.info.finfo->format << " n_components=" << f.info.finfo->n_components << endl;
cout << "shift=" << f.info.finfo->shift[0] << " depth" << f.info.finfo->depth[0] << " plane=" << f.info.finfo->plane[0] << " poffset=" << f.info.finfo->poffset[0] << endl;
cout << "w_sub=" << f.info.finfo->w_sub[0] << " h_sub=" << f.info.finfo->h_sub[0] << " pack_lines=" << f.info.finfo->pack_lines << " unpack format=" << f.info.finfo->unpack_format << endl;
Basically GStreamer rounds up the stride of a buffer to be divisible by 4. So in the case of a 270x360 image, the stride (i.e.each row of pixels in the buffer) will be 812, not 270x3 = 810. So there are 2 extra bytes used for padding it seems.
However I can’t fix this, I’ve tried to push the pixels in all sorts of ways but still the image is broken (I can see the video but it’s distorted).
For example I’ve tried this (assuming that there is a byte either side of each line of pixels from the image:
int h = f.info.height;
int w = f.info.width;
int stride = f.info.stride[0];
ofPixels newpixels;
newpixels.allocate(w,h,3);
for(int i=0; i < h;i++) {
memcpy(mapinfo.data+1+i*stride,newpixels.getPixels()+i*w*3,w*3);
}
Instead of the memcopy, I found this function and tried to use it to replace the memcopy but it didn’t work either:
f.info.finfo->unpack_func(f.info.finfo,GST_VIDEO_PACK_FLAG_NONE,newpixels.getPixels(), f.data ,f.info.stride,0,i,w);
Here’s an example of the output I get if I don’t return prematurely from the ofGstVideoUtils::buffer_cb() and display the image instead:
