[Ffmpeg-devel] Probing mpeg media file length with libavformat.

Lennart Andre Rolland lennart
Thu Mar 30 10:01:56 CEST 2006


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,  
				msg("Could not seek to position %0.3f\n", (double)timestamp /  
				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/  

This does not work. The seek call returns without error, but timestamps  
come out as 0 no matter what I tweak.

Any clues?		

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

More information about the ffmpeg-devel mailing list