Updated by Andrey Kamaev almost 13 years ago
It seems the new ffmpeg wrapper solved the frame positioning bug. However, it introduces a new bug.
The function @VideoCapture::get(CV_CAP_PROP_POS_FRAMES)@ VideoCapture::get(CV_CAP_PROP_POS_FRAMES) gives wrong results.
Here's the code producing the problem:
<pre><code class="cpp"> <pre>
capture.set(CV_CAP_PROP_POS_FRAMES, i);
capture >> frame;
int j = capture.get(CV_CAP_PROP_POS_FRAMES);
cout<< "get =" << j << "| set:" << i<<endl;
</code></pre> </pre>
The output is:
<pre>
get =8| set:2000
get =10| set:1998
get =12| set:1996
get =14| set:1994
get =16| set:1992
get =18| set:1990
get =20| set:1988
get =28| set:1986
get =30| set:1984
get =32| set:1982
get =34| set:1980
get =36| set:1978
get =38| set:1976
get =40| set:1974
get =46| set:1972
get =48| set:1970
get =50| set:1968
get =52| set:1966
get =54| set:1964
get =56| set:1962
</pre>
The problem could lie in following code. frame_number is also a member of @CvCapture@. CvCapture.
<pre><code class="cpp">
void CvCapture_FFMPEG::seek(int64_t frame_number)
{
frame_number = std::min(frame_number, get_total_frames());
int64_t dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
if (abs(dts - 2 - frame_number) > 16)
{
double sec = static_cast<double>(frame_number) / static_cast<double>(get_fps());
int64_t time_stamp = ic->streams[video_stream]->start_time;
double time_base = r2d(ic->streams[video_stream]->time_base);
time_stamp += static_cast<int64_t>(sec / time_base);
av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD);
}
while(dts - 2 < frame_number)
{
/* cv::Mat imag = read(); */
if (!grabFrame()) break;
dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
}
}
</code></pre>
The function @VideoCapture::get(CV_CAP_PROP_POS_FRAMES)@ VideoCapture::get(CV_CAP_PROP_POS_FRAMES) gives wrong results.
Here's the code producing the problem:
<pre><code class="cpp"> <pre>
capture.set(CV_CAP_PROP_POS_FRAMES, i);
capture >> frame;
int j = capture.get(CV_CAP_PROP_POS_FRAMES);
cout<< "get =" << j << "| set:" << i<<endl;
</code></pre> </pre>
The output is:
<pre>
get =8| set:2000
get =10| set:1998
get =12| set:1996
get =14| set:1994
get =16| set:1992
get =18| set:1990
get =20| set:1988
get =28| set:1986
get =30| set:1984
get =32| set:1982
get =34| set:1980
get =36| set:1978
get =38| set:1976
get =40| set:1974
get =46| set:1972
get =48| set:1970
get =50| set:1968
get =52| set:1966
get =54| set:1964
get =56| set:1962
</pre>
The problem could lie in following code. frame_number is also a member of @CvCapture@. CvCapture.
<pre><code class="cpp">
void CvCapture_FFMPEG::seek(int64_t frame_number)
{
frame_number = std::min(frame_number, get_total_frames());
int64_t dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
if (abs(dts - 2 - frame_number) > 16)
{
double sec = static_cast<double>(frame_number) / static_cast<double>(get_fps());
int64_t time_stamp = ic->streams[video_stream]->start_time;
double time_base = r2d(ic->streams[video_stream]->time_base);
time_stamp += static_cast<int64_t>(sec / time_base);
av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD);
}
while(dts - 2 < frame_number)
{
/* cv::Mat imag = read(); */
if (!grabFrame()) break;
dts = dts_to_frame_number(ic->streams[video_stream]->cur_dts);
}
}
</code></pre>