Ask Your Question
0

how can i play video

asked 2017-02-19 00:52:58 -0600

Hi all, I want to play four fullhd videos and i'm using a sample and grab frame in each iterate in loop and show it four times in a concatenate way in just one imshow. i have a problem with speed. it is faster than its real. how can i play it in exact frame rate that it has? i am using C++. if there is a better solution in C# please let me know it. i have found some but there is error in opening file in all of them. Thank you

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
0

answered 2017-02-20 05:02:02 -0600

pi-null-mezon gravatar image

updated 2017-02-21 00:53:21 -0600

Playback video in the window with the fps from the file metainfo, filename passed as 2'nd cmd argument:

#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char *argv[])
{
    if(argc > 1) { // application will wait videofilename as the second cmd argument

        VideoCapture _vc;
        if(_vc.open(argv[1]) == false)
            return -2; // Indicates that file could not be opened for the some reasons

        double fps = _vc.get(CV_CAP_PROP_FPS); // get fps from the file's metainfo
        int delayms = static_cast<int>(1000.0/fps); // get delay between the frames in milliseconds

        Mat matframe;
        while(_vc.read(matframe)){
            imshow("viewport", matframe);
            if(waitKey(delayms) == 27) { // 27 is ESCAPE code, so if the user press escape then while will be breaked
                break;
            }
        }
        return 0;
    } else {
        return -1; // means that the user did not provide videofilename
    }
}

You want take into account processing time? So, let's slightly change the code:

#include <opencv2/opencv.hpp>

using namespace cv;

double measureframetimems(VideoCapture &_vc, cv::Mat(*_functionpointer)(const Mat &_mat), unsigned int _n) {
    if(_vc.isOpened() == false) {
        return -1.0;
    }
    cv::Mat _framemat;
    double _totalprocctime = 0.0;
    double _timemark;
    unsigned int _frames = 0;
    for(unsigned int i = 0; i < _n; ++i) {
        if(_vc.read(_framemat)) {
            _functionpointer(_framemat);
            if(i > 0) { // let's drop first frame from the time count
                _totalprocctime += (getTickCount() - _timemark)/getTickFrequency();
                _frames++;
            }
            _timemark = getTickCount();
        } else {
            break; // for the instance all frames in the video file could be finished before _n
        }
    }
    return 1000.0*_totalprocctime/_frames; // in milliseconds
}

cv::Mat processframe(const Mat &_mat) {
    // Paste target processing code
    return _mat;
}

int main(int argc, char *argv[])
{
    if(argc > 1) { // application will wait videofilename as the second cmd argument

        VideoCapture _vc;
        if(_vc.open(argv[1]) == false)
            return -2; // Indicates that file could not be opened for the some reasons              

        double fps = _vc.get(CV_CAP_PROP_FPS); // get fps from the file's metainfo       
        int delayms = static_cast<int>(1000.0/fps); // get delay between the frames in milliseconds

        delayms -= measureframetimems(_vc, *processframe, 100); // adjust delay
        // Reopen video file if first frames are necessary
        if(_vc.open(argv[1]) == false)
            return -2; // Indicates that file could not be opened for the some reasons

        Mat matframe;
        while(_vc.read(matframe)){
            matframe = processframe(matframe);
            imshow("viewport", matframe);
            if(waitKey(delayms) == 27) { // 27 is ESCAPE code, so if the user press escape then while will be breaked
                break;
            }
        }
        return 0;
    } else {
        return -1; // means that the user did not provide videofilename
    }
}
edit flag offensive delete link more

Comments

thank you man, but it makes it slower than original

Farshadhn gravatar imageFarshadhn ( 2017-02-20 13:06:24 -0600 )edit

Yes, this is only approximate frame rate, as I said in my answer. It will be slightly slower than expected because it does not take into account the time to read and decode a frame. So if you need more exact timing, you need to calculate a delay for each frame. You want to display frame N at (playback_start_time_in_ms + (N * 1000 / fps)). So on each frame, you need to subtract current system time in ms from expected display time in ms, and wait that number of ms.

Netsai Chibuku gravatar imageNetsai Chibuku ( 2017-02-20 16:44:03 -0600 )edit
0

answered 2017-02-19 01:35:46 -0600

LBerger gravatar image

updated 2017-02-19 01:40:46 -0600

opencv is an image processing library. It is not vlc, ffmpeg, gstreamer ..... If you don't need to process image frame by frame I'm sure that you can find a better answer elsewhere.

You can use this post too

edit flag offensive delete link more

Comments

So what is the way to play for example for video using just one source. i dont want to process all frames for all videos. these for video are playing same thing and i just need one processing not multiple

Farshadhn gravatar imageFarshadhn ( 2017-02-19 02:26:21 -0600 )edit
0

answered 2017-02-19 18:56:00 -0600

Netsai Chibuku gravatar image

If the playback rate is faster than you want, you need to put a sleep in between displaying frames.

Are you using cv::VideoCapture class? I think when you call grab() to get frames from a video file, it gives you the next frame immediately. It does not care what the framerate in the video file is. (From memory, maybe I am wrong.)

The easiest way is to call cv::VideoCapture::get(CAP_PROP_FPS) to get the frames-per-second of the file. Then just add a call to sleep for (1000 / fps) milliseconds after displaying each frame. If you need really exact playback rate for synchronisation, there are better ways, but this simple way is probably enough.

edit flag offensive delete link more

Comments

sleeping is not helping me. do you have a sample code for that?maybe mine is incorrect. it's frames are jumping and faster that its real.could you please show me that loop?

Farshadhn gravatar imageFarshadhn ( 2017-02-19 23:50:20 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-02-19 00:52:58 -0600

Seen: 523 times

Last updated: Feb 21 '17