The functions gst_buffer_map and gst_buffer_unmap has giving us problems. Sporadically, after using them a several times the software crashes when it engages the unammaping. If I remove the unmapping instruction (removed for testing, I know the documentation specify that is needed) then after some number of iterations it crashes on the mapping.
I have tried with gst 1.22.11 and gst 1.24, both of them fail at some point after a lot of iterations. I have tried to ensure that the variables used on those calls are verified and exists to prevent errors, but so far, I had not been able to catch an error on those, so its likely something happening inside the function.
Variables:
map_info
*Manually initialized on zeros
*Verified data field (NULL)
*Verified size field (0)
Used then on: gst_buffer_map(buf, &map_info, GST_MAP_READ)
*Verification of Buffering error
Verification of invalid data in map_info
Used then on: t_frame = Mat(cv::Size(width, height), CV_8UC4, (char)map_info.data, Mat::AUTO_STEP).clone();
Used then on: gst_buffer_unmap(buf, &map_info);
buf
*Initialized pointing to nullptr
Used then on: buf = gst_sample_get_buffer(from_sample);
*Verification of failed to retrieve buffer from the sample
*Verification of still buf pointing to nullptr
Used then on gst_buffer_map(buf, &map_info, GST_MAP_READ)
*Verification of Buffering error
Used then on gst_buffer_unmap(buf, &map_info);
I add the code of where these are implement for reference.
bool GstVideoSource::takeScreenShot(Mat &t_frame)
{
GstCaps *caps= nullptr;
GstSample *from_sample = nullptr;
GError *err = nullptr;
GstBuffer *buf = nullptr;
GstMapInfo map_info;
memset(&map_info, 0, sizeof(GstMapInfo));//Initialize on zeros
Functions::writeLog(fInfo, "Checking Map_info initializartion");
assert(map_info.data == NULL); // Verify data field
assert(map_info.size == 0); // Verify size field
Functions::writeLog(fInfo, "Sink initialization");
GstElement *sink = gst_bin_get_by_name( GST_BIN(mData->pipeline), "sink");
if (!sink) {
Functions::writeLog(fInfo, "Error: Unable to get sink element from the pipeline");
return false;
}
g_object_get (sink, "last-sample", &from_sample, nullptr);
if (!from_sample) {
Functions::writeLog(fInfo, "Error getting last sample form sink");
return false;
}
caps = gst_sample_get_caps(from_sample);
if (!caps) {
Functions::writeLog(fInfo, "Error: Failed to retrieve sample capabilities");
return false;
}
buf = gst_sample_get_buffer(from_sample);
if (!buf) {
Functions::writeLog(fInfo, "Error: Failed to retrieve buffer from the sample");
return false;
}
GstStructure *structure = gst_caps_get_structure(caps, 0);
const int width = g_value_get_int(gst_structure_get_value(structure, "width"));
const int height = g_value_get_int(gst_structure_get_value(structure, "height"));
Functions::writeLog(fInfo, "caps filter of the img to save: "+ QString::fromStdString( gst_caps_to_string(caps)));
Functions::writeLog(fInfo, "Checking Mapping buffer");
buf = gst_sample_get_buffer(from_sample);
Functions::writeLog(fInfo, "Verifying buffer - Retrieve");
if (!buf) {
Functions::writeLog(fInfo, "Error: Failed to retrieve buffer from the sample");
return false;
}
Functions::writeLog(fInfo, "Verifying buffer - NULL");
if(buf == nullptr){
Functions::writeLog(fInfo, "Error: Pointer to buff is still NULL");
return false;
}
Functions::writeLog(fInfo, "Buffering map");
if (!gst_buffer_map(buf, &map_info, GST_MAP_READ)) { //Line that sometimes crash
Functions::writeLog(fInfo, "Buffering Error: Failed to map the buffer");
return false;
}
Functions::writeLog(fInfo, "Checking info on map");
if (!map_info.data) {
Functions::writeLog(fInfo, "Error: Invalid data in map_info");
gst_buffer_unmap (buf, &map_info);
return false;
}
Functions::writeLog(fInfo, "Checking valid image dimensions");
if (width <= 0 || height <= 0) {
Functions::writeLog(fInfo, "Error: Invalid image dimensions");
gst_buffer_unmap (buf, &map_info);
return false;
}
Functions::writeLog(fInfo, "Creating Mat with dimensions: " + QString::number(width) + ", " + QString::number(height));
t_frame = Mat(cv::Size(width, height), CV_8UC4, (char*)map_info.data, Mat::AUTO_STEP).clone();
Functions::writeLog(fInfo, "Converting Mat Color");
cv::cvtColor(t_frame, t_frame, COLOR_RGB2BGR);
Functions::writeLog(fInfo, "Unammping");
gst_buffer_unmap(buf, &map_info); //Line that sometimes crash
Functions::delay(100);
Functions::writeLog(fInfo, "Succesfully screenshot taken");
return true;
}