// seek seems to work, so we don't need the filename,
// but we still need to seek back to filestart
filename=NULL;
- av_seek_frame(ic, video_stream, 0, 0);
+ int64_t ts = video_st->first_dts;
+ int flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD;
+ av_seek_frame(ic, video_stream, ts, flags);
}
exit_func:
// if( !capture || !video_st || !picture->data[0] ) return 0;
if( !video_st ) return 0;
-
+ double frameScale = av_q2d (video_st->time_base) * av_q2d (video_st->r_frame_rate);
int64_t timestamp;
timestamp = picture_pts;
if(video_st->parser && video_st->parser->dts != AV_NOPTS_VALUE_)
return (((double)video_st->parser->dts-1) *1000.0f) * av_q2d (video_st->time_base);
if(video_st->cur_dts != AV_NOPTS_VALUE_)
- return (((double)video_st->cur_dts-1) *1000.0f * av_q2d (video_st->time_base));
- // return (((double)video_st->cur_dts-1) *1000) / av_q2d (video_st->r_frame_rate);
+ return ((video_st->cur_dts-video_st->first_dts) * 1000.0 * av_q2d (video_st->time_base));
break;
case CV_CAP_PROP_POS_FRAMES:
if(video_st->parser && video_st->parser->dts != AV_NOPTS_VALUE_)
return (double)video_st->parser->dts-1;
if(video_st->cur_dts != AV_NOPTS_VALUE_)
- return (double)video_st->cur_dts-1;
+ return((video_st->cur_dts-video_st->first_dts) * frameScale);
break;
case CV_CAP_PROP_POS_AVI_RATIO:
if(video_st->parser && video_st->parser->dts != AV_NOPTS_VALUE_)
return (double)(video_st->parser->dts-1)/(double)video_st->duration;
if(video_st->cur_dts != AV_NOPTS_VALUE_ && video_st->duration != AV_NOPTS_VALUE_)
- return (double)(video_st->cur_dts-1)/(double)video_st->duration;
+ return(((video_st->cur_dts-video_st->first_dts)+(1.0/frameScale)) / (double)video_st->duration);
break;
case CV_CAP_PROP_FRAME_COUNT:
if(video_st->duration != AV_NOPTS_VALUE_)
- return (double)video_st->duration;
+ return (double)video_st->duration * frameScale;
break;
case CV_CAP_PROP_FRAME_WIDTH:
return (double)frame.width;
case CV_CAP_PROP_POS_FRAMES:
case CV_CAP_PROP_POS_AVI_RATIO:
{
- int64_t timestamp = 0;
- AVRational time_base;
+ int64_t timestamp = ic->streams[video_stream]->first_dts;
+ AVRational time_base = ic->streams[video_stream]->time_base;
+ AVRational frame_base = ic->streams[video_stream]->r_frame_rate;
+ double timeScale = (time_base.den / (double)time_base.num) / (frame_base.num / frame_base.den);
switch( property_id )
{
case CV_CAP_PROP_POS_FRAMES:
- timestamp=(int64_t)value;
+ timestamp += (int64_t)(value * timeScale);
if(ic->start_time != AV_NOPTS_VALUE_)
timestamp += ic->start_time;
break;
case CV_CAP_PROP_POS_MSEC:
- time_base=ic->streams[video_stream]->time_base;
- timestamp=(int64_t)(value*(float(time_base.den)/float(time_base.num))/1000);
+ timestamp +=(int64_t)(value*(float(time_base.den)/float(time_base.num))/1000);
if(ic->start_time != AV_NOPTS_VALUE_)
timestamp += ic->start_time;
break;
case CV_CAP_PROP_POS_AVI_RATIO:
- timestamp=(int64_t)(value*ic->duration);
+ timestamp += (int64_t)(value*ic->duration);
if(ic->start_time != AV_NOPTS_VALUE_ && ic->duration != AV_NOPTS_VALUE_)
timestamp += ic->start_time;
break;
}
else
{
- int ret = av_seek_frame(ic, video_stream, timestamp, 0);
+ int flags = AVSEEK_FLAG_FRAME;
+ if (timestamp < ic->streams[video_stream]->cur_dts)
+ flags |= AVSEEK_FLAG_BACKWARD;
+ int ret = av_seek_frame(ic, video_stream, timestamp, flags);
if (ret < 0)
{
fprintf(stderr, "HIGHGUI ERROR: AVI: could not seek to position %0.3f\n",