Repository: opencv
Issue: opencv videocapture  memory  leakage   when it has a bad internet connection
Labels: bug,priority: low,category: videoio,incomplete,needs investigation

##### System information (version)
<!-- Example
- OpenCV => 4.4
- Operating System / Platform => Windows 64 Bit
- Compiler => pycharm
-->

- OpenCV => :grey_question:4.4
- Operating System / Platform => :grey_question: ubuntu 18.04  arm nvidia jetson nano arm ， x86 ubuntu18.04 
- Compiler => :grey_question: exist in builtin

##### Detailed description

i opened a http or other cam stream, it works well when the connection looks pretty well . when the connection goes
to bad , the rate of getting image(cam.read()) become slow (i time the read() funtion's cost 0.002----->0.01 or worse),meantime,
the memory and even swap increase  ,the whole process become stucked. the bad connection only exists randomly, so i plug out the Ethernet cable to simulate the case, the momory dont increase when it lose the connnection because capture doesn't  work at that time, once i plug in the ethnet cable , capture starts work (a daemon thread to watch and reload the capture when it is not _alive())  and the read() cost  and memory increase  (0.002----->0.01seconds or worse) .

based on this , once the connection goes to bad temporaryly, it always goes to crash and be killed by system.

so , hope you can notice the problem and solve it .

thanks for watching

#20201205 update

i implement a small Repetition code for this issue as follows

##### Steps to reproduce

```.py
```.py
from collections import deque
import numpy as np
import time
import random
import cv2
import sys
from threading import Thread


def openimg(cam):
    t = 0
    temp = np.random.random((2,3))#init a random array for attr of shape
    _, img = cam.cap.read()
    print(img.dtype)
    while cam.threadrunning:
        _, img = cam.cap.read()
        if _ is False :
            break
        if cam.shape[0] == 0:  # find a stable image shape
            if img.shape == temp.shape:
                t += 1
            temp = img
            if t > 100:
                cam.shape[0] = img.shape
        if cam.shape[0] != 0 and img.shape != cam.shape[0]:  # found the stable shape and keep same image shape in deque
            break  # cuz there will be some warning frame typing 'connection fail'
        cam.deque.append(img)
    while False:  # True: #simulation for ndarray instead of  ''_, np.array = VideoCapture.read()''   no memleak
        cam.deque.append(np.random.randint(0,255,(random.randint(500,576),random.randint(600,704),3), dtype=np.uint8))
        time.sleep(0.04)  # almost the same shape of image from capture   25frams/s


class Cam(object):
    def __init__(self, cap, deque, shape):
        self.cap = cv2.VideoCapture(cap)
        self.deque = deque
        self.threadrunning = True
        self.thread = None
        self.shape = shape
        self._read()

    def _read(self):
        self.thread = Thread(target=openimg, args=(self,))
        self.thread.start()

    def _stop(self):
        if self.threadrunning:
            self.threadrunning = False
            if self.thread.is_alive():
                self.thread.join()

    def release(self):
        self._stop()
        try:
            self.cap.release()
        except Exception as e:
            print(e)

    def __del__(self):
        self.release()


def main():
    a = deque(maxlen=600)
    aa = deque(maxlen=600)
    c = 0
    shape = [0]
    cap = Cam('web cam address', a, shape)  # my address like http://*********.m3u8
    caps = Cam('web cam address', aa, shape)
    time.sleep(3)  # fill some deque
    while True:
        c += 1
        if c == 200:  # when False this block = no re-open the VideoCapture ----- no memleak
            time.sleep(0.5)
            cap.release()
            caps.release()
            cap = Cam('web cam address', a, shape)
            # simulation for bad collection and re-open the VideoCapture
            caps = Cam('web cam address', aa, shape)
            c = 0
        print(len(a), sys.getrefcount(aa[10]), sys.getrefcount(a[10]), aa[-1].shape, shape)  # frame from capture also has 2refcounts
        time.sleep(0.04)   # just memleak on ubuntu (arm and x86 both) , works well on windows10   based on same env cpython3.8
        # and opencv 4.4.0 lastime i test on 4.1.0  python 3.6  ,still memleak after i upgrade my opencv and python
        # i doubt that  if windows helps clear the leak mem...... so opencv seems no bug on windows....


if __name__ == "__main__":
    print(cv2.__version__)  #4.4.0
    main()
 ```


##### Issue submission checklist

 - [ ] I report the issue, it's not a question
   <!--
   OpenCV team works with answers.opencv.org, Stack Overflow and other communities
   to discuss problems. Tickets with question without real issue statement will be
   closed.
   -->
 - [ ] I checked the problem with documentation, FAQ, open issues,
       answers.opencv.org, Stack Overflow, etc and have not found solution
   <!--
   Places to check:
   * OpenCV documentation: https://docs.opencv.org
   * FAQ page: https://github.com/opencv/opencv/wiki/FAQ
   * OpenCV forum: https://answers.opencv.org
   * OpenCV issue tracker: https://github.com/opencv/opencv/issues?q=is%3Aissue
   * Stack Overflow branch: https://stackoverflow.com/questions/tagged/opencv
   -->
 - [ ] I updated to latest OpenCV version and the issue is still there
   <!--
   master branch for OpenCV 4.x and 3.4 branch for OpenCV 3.x releases.
   OpenCV team supports only latest release for each branch.
   The ticket is closed, if the problem is not reproduced with modern version.
   -->
 - [ ] There is reproducer code and related data files: videos, images, onnx, etc
   <!--
   The best reproducer -- test case for OpenCV that we can add to the library.
   Recommendations for media files and binary files:
   * Try to reproduce the issue with images and videos in opencv_extra repository
     to reduce attachment size
   * Use PNG for images, if you report some CV related bug, but not image reader
     issue
   * Attach the image as archive to the ticket, if you report some reader issue.
     Image hosting services compress images and it breaks the repro code.
   * Provide ONNX file for some public model or ONNX file with with random weights,
     if you report ONNX parsing or handling issue. Architecture details diagram
     from netron tool can be very useful too. See https://lutzroeder.github.io/netron/
   -->