Ticket #1585: CorrectlyCalculateOggDuration.patch

File CorrectlyCalculateOggDuration.patch, 4.4 KB (added by playme@…, 17 years ago)

your patch attached

Line 
1--- libmpdemux/demux_ogg.c (revision 29770)
2+++ libmpdemux/demux_ogg.c (working copy)
3@@ -145,7 +145,9 @@
4ogg_syncpoint_t* syncpoints;
5int num_syncpoint;
6off_t pos, last_size;
7+ int64_t initial_granulepos;
8int64_t final_granulepos;
9+ int64_t duration;
10
11/* Used for subtitle switching. */
12int n_text;
13@@ -263,20 +265,23 @@
14if(os->vorbis) {
15if(*pack->packet & PACKET_TYPE_HEADER)
16os->hdr_packets++;
17- else if (os->vi_initialized)
18+ else
19{
20vorbis_info *vi;
21- int32_t blocksize;
22+ int32_t blocksize = 0;
23
24// When we dump the audio, there is no vi, but we don't care of timestamp in this case
25- vi = &(os->vi);
26+ vi = os->vi_initialized ? &os->vi : NULL;
27+ if (vi)
28blocksize = vorbis_packet_blocksize(vi,pack) / samplesize;
29// Calculate the timestamp if the packet don't have any
30if(pack->granulepos == -1) {
31 pack->granulepos = os->lastpos;
32 if(os->lastsize > 0)
33 pack->granulepos += os->lastsize;
34- }
35+ } else
36+ *flags = 1;
37+ if (vi)
38*pts = pack->granulepos / (float)vi->rate;
39os->lastsize = blocksize;
40os->lastpos = pack->granulepos;
41@@ -521,12 +526,7 @@
42pos = last_pos = demuxer->movi_start;
43
44// Reset the stream
45- if(index_mode == 2) {
46stream_seek(s,demuxer->movi_start);
47- } else {
48- //the 270000 are just a wild guess
49- stream_seek(s,FFMAX(ogg_d->pos,demuxer->movi_end-270000));
50- }
51ogg_sync_reset(sync);
52
53// Get the serial number of the stream we use
54@@ -574,7 +574,18 @@
55float pts;
56int flags;
57demux_ogg_read_packet(os,&op,&pts,&flags,samplesize);
58- if(op.granulepos >= 0) ogg_d->final_granulepos = op.granulepos;
59+ if(op.granulepos >= 0) {
60+ ogg_d->final_granulepos = op.granulepos;
61+ if(ogg_d->initial_granulepos == MP_NOPTS_VALUE && (flags & 1)) {
62+ ogg_d->initial_granulepos = op.granulepos;
63+ if (index_mode != 2 && ogg_d->pos < demuxer->movi_end-2*270000) {
64+ //the 270000 are just a wild guess
65+ stream_seek(s,FFMAX(ogg_d->pos,demuxer->movi_end-270000));
66+ ogg_sync_reset(sync);
67+ continue;
68+ }
69+ }
70+ }
71if(index_mode == 2 && (flags || (os->vorbis && op.granulepos >= 0))) {
72 if (ogg_d->num_syncpoint > SIZE_MAX / sizeof(ogg_syncpoint_t) - 1) break;
73 ogg_d->syncpoints = realloc_struct(ogg_d->syncpoints,(ogg_d->num_syncpoint+1), sizeof(ogg_syncpoint_t));
74@@ -1122,6 +1133,7 @@
75}
76
77ogg_d->final_granulepos=0;
78+ ogg_d->initial_granulepos = MP_NOPTS_VALUE;
79if(!s->end_pos)
80demuxer->seekable = 0;
81else {
82@@ -1130,6 +1142,9 @@
83demuxer->seekable = 1;
84demux_ogg_scan_stream(demuxer);
85}
86+ if (ogg_d->initial_granulepos == MP_NOPTS_VALUE)
87+ ogg_d->initial_granulepos = 0;
88+ ogg_d->duration = ogg_d->final_granulepos - ogg_d->initial_granulepos;
89
90mp_msg(MSGT_DEMUX,MSGL_V,"Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",n_audio,n_audio>1?"s":"",n_video,n_video>1?"s":"",ogg_d->n_text,ogg_d->n_text>1?"s":"");
91
92@@ -1361,10 +1376,10 @@
93old_pos = ogg_d->pos;
94
95//calculate the granulepos to seek to
96- gp = flags & SEEK_ABSOLUTE ? 0 : os->lastpos;
97+ gp = flags & SEEK_ABSOLUTE ? ogg_d->initial_granulepos : os->lastpos;
98if(flags & SEEK_FACTOR) {
99- if (ogg_d->final_granulepos > 0)
100- gp += ogg_d->final_granulepos * rel_seek_secs;
101+ if (ogg_d->duration > 0)
102+ gp += ogg_d->duration * rel_seek_secs;
103else
104gp += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * os->lastpos / ogg_d->pos;
105} else
106@@ -1391,8 +1406,8 @@
107if(flags & SEEK_FACTOR)
108pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs;
109else {
110- if (ogg_d->final_granulepos > 0) {
111- pos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / (ogg_d->final_granulepos / rate);
112+ if (ogg_d->duration > 0) {
113+ pos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / (ogg_d->duration / rate);
114} else if (os->lastpos > 0) {
115pos += rel_seek_secs * ogg_d->pos / (os->lastpos / rate);
116}
117@@ -1547,13 +1562,13 @@
118
119switch(cmd) {
120 case DEMUXER_CTRL_GET_TIME_LENGTH:
121- if (ogg_d->final_granulepos<=0) return DEMUXER_CTRL_DONTKNOW;
122- *(double *)arg=(double)ogg_d->final_granulepos / rate;
123+ if (ogg_d->duration<=0) return DEMUXER_CTRL_DONTKNOW;
124+ *(double *)arg=(double)(ogg_d->duration) / rate;
125 return DEMUXER_CTRL_GUESS;
126
127 case DEMUXER_CTRL_GET_PERCENT_POS:
128- if (ogg_d->final_granulepos<=0) return DEMUXER_CTRL_DONTKNOW;
129- *(int *)arg=(os->lastpos*100) / ogg_d->final_granulepos;
130+ if (ogg_d->duration<=0) return DEMUXER_CTRL_DONTKNOW;
131+ *(int *)arg=((os->lastpos - ogg_d->initial_granulepos)*100) / ogg_d->duration;
132 return DEMUXER_CTRL_OK;
133
134 default:
135