ffmpeg wrapper (Bug #1788)
Description
Hi,
This issue has been lingering for a while and seems to be only partially resolved now. I even tried the most recent update r7970 to the repository but the setProperty() routine to set frame position of video stream still seems to be broken. The routine works fine if the input frame number is ahead of the cur_dts (current frame?) but it fails to seek to the right position if the supplied frame number is behind the current position. I am supplying the code below that I'm using. I use r7970 built on VS 2008 with GPU (4.0), IPP (5.3), TBB (4.0) and QT (4.0). Two of the videos are also attached. Use 'n' to move forward and 'p' to move backward. Step is set to 200 frames.
1int main(int argc, char* argv[])
2{
3 char buffer[1024] = "";
4 char vname[512] = "inp.mov";
5
6 VideoCapture video(vname);
7 if(!video.isOpened()) {
8 cout << "Can't open video: " << vname << endl;
9 return 0;
10 }
11 int nFrames = video.get(CV_CAP_PROP_FRAME_COUNT);
12 int fWidth = video.get(CV_CAP_PROP_FRAME_WIDTH);
13 int fHeight = video.get(CV_CAP_PROP_FRAME_HEIGHT);
14
15 bool done = false;
16 bool next = false;
17 int key;
18
19 Mat display(fHeight + 200, fWidth, CV_8UC3);
20 display(Rect(0,fHeight,fWidth,200)) = 0;
21
22 namedWindow("Display");
23
24 int fNum = 0;
25 Mat currFrame;
26 while(!done) {
27 bool val = video.set(CV_CAP_PROP_POS_FRAMES, fNum);
28 video >> currFrame;
29 if(currFrame.empty()) {
30 cout << "Frame not found" << endl;
31 }
32 currFrame.copyTo(display(Rect(0, 0, fWidth, fHeight)));
33 sprintf(buffer,"%d",fNum);
34 putText(display, buffer, Point(fWidth - 50, 30), FONT_HERSHEY_PLAIN, 1, CV_RGB(0, 155, 0));
35 imshow("Display", display);
36
37 next = false;
38 while(!next) {
39 key = waitKey(0);
40 switch(key) {
41 case 'n':
42 case 'N':
43 case ' ':
44 fNum += 20;
45 display(Rect(0, fHeight+100, fWidth, 100)) = 0;
46 if(fNum >= nFrames) {
47 putText(display, "Reached end of the video!", Point(fWidth/2 - 100, fHeight + 180), FONT_HERSHEY_PLAIN, 1, CV_RGB(255,0,0));
48 fNum -= 20;
49 }
50 else
51 next = true;
52 break;
53 case 'p':
54 case 'P':
55 fNum -= 20;
56 display(Rect(0, fHeight+100, fWidth, 100)) = 0;
57 if(fNum < 0) {
58 putText(display, "Reached start of the video!", Point(fWidth/2 - 100, fHeight + 180), FONT_HERSHEY_PLAIN, 1, CV_RGB(255,0,0));
59 fNum += 20;
60 }
61 else {
62 //video.set(CV_CAP_PROP_POS_FRAMES, 0);
63 next = true;
64 }
65 break;
66 case 'q':
67 next = true;
68 done = true;
69 break;
70 }
71 }
72 }
73 return 0;
74}
Associated revisions
Merge pull request #1788 from alalek:perf_test_skip
History
Updated by Andrey Kamaev almost 13 years ago
- Description changed from Hi, This issue has been lingering for a while and seems to be only partial... to Hi, This issue has been lingering for a while and seems to be only partial... More
- Category set to highgui-images
- Assignee set to Alexander Reshetnikov
Updated by Jack Tan almost 13 years ago
Hi,
I have solved this issue by rewritting some functions in the opencv_ffmpeg module using the ffmpeg-frame-accurate-seeking extension. more specifically, I created a cpp file (cap_ffmpeg_impl_v3.hpp) which re-implemented the APIs that the struct CvCapture_FFMPEG requires. I have slightly modified and extended the ffmpeg-fas library to make it compile with ffmpeg-0.8.11.
My cursory test using the above videos and samples shows it works. I have attached my code below. Wish you guys could find it useful.
NOTE:
since the ffmpeg-fas extension needs to build a seek_table for every video it opens, it could be rather slow to load a big video.
Jack
- File opencv-ffmpeg-fas.7z added
Updated by Furqan Khan almost 13 years ago
Hi Jack,
It works! :) Although, it asked me for ffmpeg .dll files, which I downloaded from zeranoe's website.
Updated by Furqan Khan almost 13 years ago
I forgot to thank you for that.
Thanks Jack!
Updated by Philipp Werner over 12 years ago
Frame accurate seeking is very important for me as well. I would appreciate the integration of ffmpeg-fas into OpenCV. If you think it's to much runtime overhead, you may make it optional by providing a boolean CV_CAP_PROP_FRAME_ACCURATE_SEEKING option.
At least I would expect a hint in the documentation that set(CV_CAP_PROP_POS_FRAMES, ...) may be not frame accurate. I also would expect that get(CV_CAP_PROP_POS_FRAMES) will return the correct frame position to allow to compensate for the lack of frame accurate seeking at the application level (be grabbing and discarding).
Updated by Philipp Werner over 12 years ago
Frame accurate seeking is very important for me as well. I would appreciate the inclusion of ffmpeg-fas into OpenCV. It may be an optional feature (boolean VideoCapture property) which can be disabled by default if it is considered to be to much overhead.
Anyway, if there is no frame accurate seeking, it should be mentioned in the docs and get(CV_CAP_PROP_POS_FRAMES) should return the correct frame ID (which so differs from the ID set) to allow for an application level workaround.
PS: Thank you for your work on OpenCV. It is a great library.
Updated by Andrey Kamaev over 12 years ago
- Category changed from highgui-images to highgui-video
Updated by Vadim Pisarevsky over 12 years ago
integrating ffmpeg-fas into opencv is impossible, because ffmpeg-fas is LGPL code, whereas opencv is BSD. We can only wait while ffmpeg integrates fas, so that we can use it.
- Assignee deleted (
Alexander Reshetnikov)
Updated by Philipp Werner over 12 years ago
I have fixed some issues that I had with Jack Tan's code. The modified version is attached. I have also updated the ffmpeg_fas code included in this file to work properly with libav-0.8.4. My version also saves the seek index after building it and tries to load it when opening the video again.
- File opencv_ffmpeg_fas_121113.7z added
Updated by Philipp Werner over 12 years ago
If someone is working on improving the seek accuracy in OpenCV, the attached file might be useful, because the frame images contain a frame counter. Seeking is not frame accurate behind frame ~270 in OpenCV 2.4.3 for this file.
I also thought, it might be a good idea to rewrite the primary seek function to seek for a timestamp instead of a frame number in cap_ffmpeg_impl.hpp, because it seems more general to me. Seeking by frame number than would be a secondary function calling the timestamp seek. I think, this way at least seeking by timestamp would become more accurate.
- File counter6.mp4 added
Updated by Vadim Pisarevsky almost 10 years ago
let's cancel very old bugs; if they are still valid, please, reopen
- Status changed from Open to Cancelled
- HW Platform set to Any
- Operating System set to Any
- Affected version set to 2.4.0 - 2.4.8