[FFmpeg-devel] [PATCH] OGG seeking and timestamp

Stefano Sabatini stefano.sabatini-lala
Wed Nov 19 11:45:03 CET 2008


On date Wednesday 2008-11-19 10:43:23 +0100, Yvan Labadie encoded:
> Hi again,
>
> I needed to recover exact packets, so on the first read I save all  
> packets with available timestamp value, then when I need I make an  
> av_seek_frame to these values in order to recover the corresponding  
> packet, but sometimes it worked and sometimes it sent me an other packet  
> (which is the next packet in fact).
>
> and worst, sometimes it was simply impossible to seek to this same  
> timestamp, it returned the packet of the next timestamp :s
>
> So I digg in... and I made a modification so when we make a seek to a  
> saved timestamp we always recover the same packet as the one which  
> generated this timestamp!
>
> I join a patch if it can help!
>
> NB : Sorry for the mail in libav* user I had some problems with my email  
> and  ffmpeg-devel subscription...

> diff -cr ffmpeg-export-2008-10-10/libavformat/oggdec.c ffmpeg-export-2008-10-10_modif/libavformat/oggdec.c

Ouch! Use diff -u patches, as used by svn diff, also you should use
just that to ease your work.

> *** ffmpeg-export-2008-10-10/libavformat/oggdec.c	2008-10-03 12:16:29.000000000 +0200
> --- ffmpeg-export-2008-10-10_modif/libavformat/oggdec.c	2008-11-18 17:36:37.000000000 +0100
> ***************
> *** 119,124 ****
> --- 119,125 ----
>           os->lastgp = -1;
>           os->nsegs = 0;
>           os->segp = 0;
> + 		os->timeStamped = 0;

Weird indent, timeStamped doesn't look like a good name, also
use_time_stamp style is preferred.

>       }
>   
>       ogg->curidx = -1;
> ***************
> *** 291,297 ****
>       os->lastgp = os->granule;
>       os->bufpos += size;
>       os->granule = gp;
> !     os->flags = flags;
>   
>       if (str)
>           *str = idx;
> --- 292,299 ----
>       os->lastgp = os->granule;
>       os->bufpos += size;
>       os->granule = gp;
> !     os->flags = flags;;
> ! 	os->timeStamped=-1; //not yet timestamped, waiting for first full packet
>   
>       if (str)
>           *str = idx;
> ***************
> *** 320,326 ****
>                   return -1;
>           }
>   
> !         os = ogg->streams + idx;
>   
>   #if 0
>           av_log (s, AV_LOG_DEBUG,
> --- 322,331 ----
>                   return -1;
>           }
>   
> !         os = ogg->streams + idx;;
> ! 		if ((os->timeStamped==-1) && (!(os->flags&0x01) || (os->flags&0x01 && os->segp > 0) ) ){
> ! 			os->timeStamped=0; //this is the packet wich need to be timestamped!
> ! 		}		

Weird indent.
   
>   #if 0
>           av_log (s, AV_LOG_DEBUG,
> ***************
> *** 513,521 ****
>           return AVERROR(EIO);
>       pkt->stream_index = idx;
>       memcpy (pkt->data, os->buf + pstart, psize);
> !     if (os->lastgp != -1LL){
>           pkt->pts = ogg_gptopts (s, idx, os->lastgp);
> !         os->lastgp = -1;
>       }
>   
>       pkt->flags = os->pflags;
> --- 518,526 ----
>           return AVERROR(EIO);
>       pkt->stream_index = idx;
>       memcpy (pkt->data, os->buf + pstart, psize);
> ! 	if (os->timeStamped == 0){
>           pkt->pts = ogg_gptopts (s, idx, os->lastgp);
> !         os->timeStamped = 1; //page timestamped
>       }
>   
>       pkt->flags = os->pflags;
> ***************
> *** 552,559 ****
>           if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
>               ogg->streams[i].codec && i == stream_index) {
>               pts = ogg_gptopts(s, i, ogg->streams[i].granule);
> !             // FIXME: this is the position of the packet after the one with above
> !             // pts.
>               *pos_arg = url_ftell(bc);
>               break;
>           }
> --- 557,584 ----
>           if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
>               ogg->streams[i].codec && i == stream_index) {
>               pts = ogg_gptopts(s, i, ogg->streams[i].granule);
> !             // FIXME: this is the position of the packet after the one with above pts.
> ! 			// 		==> if we got a page type "fresh packet" so the firts packet is full (I mean present from its begining) then we will have the real first packet of this page sequence
> ! 			//		==> but if we have a page type "continued packet" then we will have the second packet (because it's too complicated to go recover the begining of the first packet in the previous page)
> ! 			// 	
> ! 			//	Problem is:
> ! 			//		we read a packet with a timestamp, we save this timestamp for future seek
> ! 			//		we want to recover the packet, so we make a seek->timestamp
> ! 			//	  first case:
> ! 			//		it was a packet with the begining on this frame ("fresh packet") 
> ! 			//		then it will return the first FULL packet which is the real first packet of the frame
> ! 			//	  second case:
> ! 			//		it was a packet with the begining on the previous frame ("continued packet") 
> ! 			//		then we cannot recover the begining in the previous frame 
> ! 			//		so it will return the first FULL packet in that frame which is the second packet of the frame!
> ! 			//		And so we will not recover the same packet than the one which gave us the timestamp!
> ! 			// 
> ! 			//	To manage this problem, we always apply a timestamp to the second packet 
> ! 			//	and av_seek_frame->timestamp always put the pointer on the second packet
> ! 			//	so we have a predictible behaviour 
> ! 			//		=> 	when av_read_frame return a timestamp it is the second packet for sure 
> ! 			//			and av_seek_frame will always return the same packet as the one which gave us the timestamp!
> ! 			

Again weird indent.

Regards.
-- 
FFmpeg = Fiendish & Forgiving Minimal Portentous Encoding/decoding Gadget




More information about the ffmpeg-devel mailing list