[Ffmpeg-devel] Probing mpeg media file length with libavformat.
Lennart Andre Rolland
lennart
Thu Mar 30 10:01:56 CEST 2006
Hi
I want to use libavformat to find the length of a mediafile, but I am
having some trouble, and I could use some help or atleast hints!
My naive first attempt so far has been to open the file with libavformat
and seek throught the entire file, looking for the first and last PTS
values. Finally the duration will be the last PTS minus the first.
I based my code on this snippet from ffplay.c from latest CVS:
/* if seeking requested, we execute it */
if (start_time != AV_NOPTS_VALUE) {
int64_t timestamp;
timestamp = start_time;
/* add the stream start time */
if (ic->start_time != AV_NOPTS_VALUE)
timestamp += ic->start_time;
ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
if (ret < 0) {
fprintf(stderr, "%s: could not seek to position %0.3f\n",
is->filename, (double)timestamp / AV_TIME_BASE);
}
}
The important part being this:
ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
I have figured out that "ic" is an open AVFormatContext, "-1" means "use
default stream of this container", "timestamp" is where we want to seek to
in AV_TIME_BASE units and "AVSEEK_FLAG_BACKWARD" means that we want the
seek to end at the last frame BEFORE the timestamp we give.
Since none of the media files I will probe are 6 hours or longer, I set
timestamp to 6 * 60 * 60 * AV_TIME_BASE and started a av_seek_frame()
call. My assumption is that this will seek to the last seekable point in
the file, then stop. I would then simply read out the last timestamp using
the read_timestamp() call from AVInputFormat.
My adapted code:
//Try seeking to the very end (6 hours should be past any clip ever.)
const int64_t start_time = 6LL * 60LL * 60LL * AV_TIME_BASE;
msg("Seeking to %0.3f:\n", (double)start_time / AV_TIME_BASE);
//Do the seek
if (start_time != AV_NOPTS_VALUE) {
int64_t timestamp=start_time;
//Add the stream start time
if(ic->start_time != AV_NOPTS_VALUE)timestamp += ic->start_time;
int ret=av_seek_frame(ic, -1,
timestamp,AVSEEK_FLAG_BACKWARD);//AVSEEK_FLAG_BACKWARD
if(ret<0){
msg("Could not seek to position %0.3f\n", (double)timestamp /
AV_TIME_BASE);
exit(0);
}
else{
int64_t ppos=0;
int64_t ts=ic->iformat->read_timestamp(ic, -1, &ppos, 0);
msg("Seeked to position %0.3f\n", (double)ts/ AV_TIME_BASE);
//msg("Seeked to da position %0.3f\n", (double)ic->timestamp/
AV_TIME_BASE);
}
}
This does not work. The seek call returns without error, but timestamps
come out as 0 no matter what I tweak.
Any clues?
--
http://www.rollandsoftware.com
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
More information about the ffmpeg-devel
mailing list