Repository: opencv
Issue: Video reader can't read new frames after reaching the end of continuously written video
Labels: priority: low,category: videoio

##### System information (version)

- OpenCV => 3.4.1
- Operating System / Platform => Linux Ubuntu 16.04 x86_64
- Compiler => gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

##### Detailed description

It is currently possible to read and write the same video file if container and codec supports reading of incomplete files.

Consider having continuously generated .MKV file, for example captured from remote stream with ``ffmpeg`` - so, we can have video file continuously written.

And we also can read and process it with OpenCV. And while we're reading slower than writing everything is OK, we can read and process video continuously.

But once we reach end of video by reading the last frame on the moment of reading, we can't continue reading regardless of video is still being written. And if we wait before reading last frame (we need to know that upfront!) we can continue reading as long as new frames are written.

##### Steps to reproduce

1. Start generating video file, i.e. by capturing from remote video stream to .MKV

```bash
ffmpeg -i https://bitdash-a.akamaihd.net/content/sintel/hls/video/1500kbit.m3u8 \
    -vcodec libx264 capture.mkv
```

2. After several seconds start reading captured video with OpenCV

```bash
./testread -f=capture.mkv
```

```.cpp
// testread.cpp
#include <iostream>
#include <string>
#include <unistd.h>
#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/video.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;

int main(int argc, const char** argv)
{
    cv::CommandLineParser cmd(argc, argv,
        "{ c camera |                    | use camera }"
        "{ f file   | ../data/vtest.avi  | input video file }"
        "{ m method | mog                | method (mog, mog2, gmg, fgd) }"
        "{ h help   |                    | print help message }");

    if (cmd.has("help") || !cmd.check())
    {
        cmd.printMessage();
        cmd.printErrors();
        return 0;
    }

    bool useCamera = cmd.has("camera");
    string file = cmd.get<string>("file");
    string method = cmd.get<string>("method");

    VideoCapture cap;

    if (useCamera)
        cap.open(0);
    else
        cap.open(file);

    if (!cap.isOpened())
    {
        cerr << "Can not open camera or video file" << endl;
        return -1;
    }

    Mat frame;

    int frameNumber = 0;
    for(;;)
    {
        int64 start = cv::getTickCount();

        cap >> frame;

        if (frame.empty()) {
            std::cout << (cap.isOpened() ? "opened " : "closed ")
                << "Wait for 1s... "
                << "(frameNumber=" << frameNumber << ")"
                << std::endl;
            
            usleep(1000000);
            continue;
        }

        if (frameNumber % 100 == 0) {
            double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
            std::cout << "FPS : " << fps << std::endl;
        }

        frameNumber++;
    }

    return 0;
}
```

Output will look like that:

```
...
FPS : 321.997
FPS : 320.36
FPS : 363.244
FPS : 226.603
opened Wait for 1s... (frameNumber=1063)
opened Wait for 1s... (frameNumber=1063)
opened Wait for 1s... (frameNumber=1063)
...
```

##### Expected behaviour

We should be able to continue reading frames after delay because video is still being written.