nareshmlx/opencv-pr huggingface dataset:
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines
**Review Line:** 1591

**Code Changes:**
```diff
             CV_Assert(convert);
             CV_Assert(resample);
             CV_Assert(audiosink);
 
-            gst_bin_add_many (GST_BIN (pipeline.get()), uridecodebin.get(), convert.get(), resample.get(), audiosink.get(), NULL);
+            gst_bin_add_many (GST_BIN (pipeline.get()), queue.get(), uridecodebin.get(), convert.get(), resample.get(), audiosink.get(), NULL);
             if (!gst_element_link_many (convert.get(), resample.get(), audiosink.get(), NULL))
             {
                 CV_WARN("GStreamer(audio): cannot link convert -> resample -> sink");
@@ -1646,21 +1661,25 @@ bool GStreamerCapture::open(const String &filename_, const cv::VideoCaptureParam
     }
```

Review comment:
The same for audio queue?
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
the timestamp has been updated on grabXXXFrame. Looks like it's duplicate and may be removed.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines
**Review Line:** 1591

**Code Changes:**
```diff
             CV_Assert(convert);
             CV_Assert(resample);
             CV_Assert(audiosink);
 
-            gst_bin_add_many (GST_BIN (pipeline.get()), uridecodebin.get(), convert.get(), resample.get(), audiosink.get(), NULL);
+            gst_bin_add_many (GST_BIN (pipeline.get()), queue.get(), uridecodebin.get(), convert.get(), resample.get(), audiosink.get(), NULL);
             if (!gst_element_link_many (convert.get(), resample.get(), audiosink.get(), NULL))
             {
                 CV_WARN("GStreamer(audio): cannot link convert -> resample -> sink");
@@ -1646,21 +1661,25 @@ bool GStreamerCapture::open(const String &filename_, const cv::VideoCaptureParam
     }
```

Review comment:
Most of the time, it is not necessary and a placebo, but we encountered some files from time to time that were not processed correctly without this GStreamer element.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
I would be good to have simple RAII wrapper class for this object.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
Shouldn't `duration` be set to `-1` in case of error?
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
What aboud VFR videos? How will it work?
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
Shouldn't we stop pipeline for POS_MSEC property? Or POS_AVI_RATIO? Or WIDTH/HEIGHT?
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
Now I changed it and made it clear in the commit message. VFR does not calculate frame count and return 0 for fps. If the fps query fails fps equals -1.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines
**Review Line:** 1866

**Code Changes:**
```diff
-            handleMessage(pipeline);
-            CV_WARN("GStreamer: unable to query position of stream");
-            return 0;
-        }
-        return value * 1e-6; // nano seconds to milli seconds
+        return double(timestamp) / GST_MSECOND;
     case CV_CAP_PROP_POS_FRAMES:
         if (!isPosFramesSupported)
         {
@@ -1859,7 +1895,7 @@ double GStreamerCapture::getProperty(int propId) const
     case CV_CAP_PROP_FPS:
```

Review comment:
Will this work after seeking to different position? As I can see `timstamp` is being updated only during frame reading.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
Could you please reformat this block (curly braces) to be consistent with the whole function.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
I checked earlier and stopping-restarting was an old implementation in the sources. When I checked GStreamer docs, I found no reference to why the pipeline should be stopped for any seeking or other setting behavior. The latest version stops the pipeline for fps-image width and image height changes. I also found mov and mp4 files where a temporal pipeline stop is needed. It is added with a comment. POS_AVI_RATIO: It is basically not supported in GStreamer. I added a new OpenCV warning and comment to the source code about it. CV_CAP_PROP_POS_FRAMES: I could not make it work. Feel free to reopen this discussion if needed.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines
**Review Line:** 1866

**Code Changes:**
```diff
-            handleMessage(pipeline);
-            CV_WARN("GStreamer: unable to query position of stream");
-            return 0;
-        }
-        return value * 1e-6; // nano seconds to milli seconds
+        return double(timestamp) / GST_MSECOND;
     case CV_CAP_PROP_POS_FRAMES:
         if (!isPosFramesSupported)
         {
@@ -1859,7 +1895,7 @@ double GStreamerCapture::getProperty(int propId) const
     case CV_CAP_PROP_FPS:
```

Review comment:
Now it is cached in setProp() event with optimism if it will be successful.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
Formatting of this block is still not consistent with the function, it should have [Allman style](https://en.wikipedia.org/wiki/Indentation_style#Allman_style): ```.cpp if (...) { //... } else if (...) { if (...) { //... } else { //... } } else { //... } ```
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines
**Review Line:** 2027

**Code Changes:**
```diff
             CV_WARN("unable to seek");
+            return false;
         }
+        // Certain mov and mp4 files seek incorrectly if the pipeline is not stopped before.
+        if (this->isPipelinePlaying()) {
+            this->stopPipeline();
+        }
+
         if(!gst_element_seek_simple(GST_ELEMENT(pipeline.get()), GST_FORMAT_DEFAULT,
                                     flags, (gint64) value)) {
             handleMessage(pipeline);
```

Review comment:
Will the pipeline be started again? This function returns without restarting in this branch.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
This line can be removed because `fps` will be rewritten after this block.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
It would be better to reduce repetition: ```.cpp const bool needRestart = this->isPipelinePlaying() && (propId == ... || propId == ... || ...); if (needRestart) this->stopPipeline(); //... some code ... if (needRestart) this->startPipeline(); ``` I'm still wondering whether or not pipeline stop/start is needed for certain properties, we do not have tests for this. Wouldn't it be safer to keep original behavior?
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
Why has this variable been created? Is it necessary?
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
```suggestion duration = static_cast<gint64>((float)duration / GST_SECOND * fps); ```
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines

**Code Changes:**
```diff
@@ -114,6 +114,7 @@ template<> inline void GSafePtr_release<GstBuffer>(GstBuffer** pPtr) { if (pPtr)
 template<> inline void GSafePtr_release<GstSample>(GstSample** pPtr) { if (pPtr) { gst_sample_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstBus>(GstBus** pPtr) { if (pPtr) { gst_object_unref(G_OBJECT(*pPtr)); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GstMessage>(GstMessage** pPtr) { if (pPtr) { gst_message_unref(*pPtr); *pPtr = NULL; } }
+template<> inline void GSafePtr_release<GstQuery>(GstQuery** pPtr) { if (pPtr) { gst_query_unref(*pPtr); *pPtr = NULL; } }
 template<> inline void GSafePtr_release<GMainLoop>(GMainLoop** pPtr) { if (pPtr) { g_main_loop_unref(*pPtr); *pPtr = NULL; } }
 
 template<> inline void GSafePtr_release<GstEncodingVideoProfile>(GstEncodingVideoProfile** pPtr) { if (pPtr) { gst_encoding_profile_unref(*pPtr); *pPtr = NULL; } }
@@ -367,6 +368,7 @@ class GStreamerCapture CV_FINAL : public IVideoCapture
     gint          audioBitPerFrame;
```

Review comment:
I applied `needRestart`. If you check other properties, all return in the switch statement except those I check by `propId`. It does not make any sense to stop the pipeline for the other. Especially it was a bug to stop the pipeline and return for other properties.
**File:** modules/videoio/src/cap_gstreamer.cpp
**Change Type:** modified
**Context:** PR #24243: Fix gstreamer backend with manual pipelines
**Review Line:** 2027

**Code Changes:**
```diff
             CV_WARN("unable to seek");
+            return false;
         }
+        // Certain mov and mp4 files seek incorrectly if the pipeline is not stopped before.
+        if (this->isPipelinePlaying()) {
+            this->stopPipeline();
+        }
+
         if(!gst_element_seek_simple(GST_ELEMENT(pipeline.get()), GST_FORMAT_DEFAULT,
                                     flags, (gint64) value)) {
             handleMessage(pipeline);
```

Review comment:
It is not necessary. When I test with those files, the pipeline works without explicit restart. And you can check the old source version and my other comment: CV_CAP_PROP_POS_FRAMES branch returned without restart before my changes.