| 1 | --- libmpdemux/demux_ogg.c (revision 29770)
|
|---|
| 2 | +++ libmpdemux/demux_ogg.c (working copy)
|
|---|
| 3 | @@ -145,7 +145,9 @@
|
|---|
| 4 | ogg_syncpoint_t* syncpoints;
|
|---|
| 5 | int num_syncpoint;
|
|---|
| 6 | off_t pos, last_size;
|
|---|
| 7 | + int64_t initial_granulepos;
|
|---|
| 8 | int64_t final_granulepos;
|
|---|
| 9 | + int64_t duration;
|
|---|
| 10 |
|
|---|
| 11 | /* Used for subtitle switching. */
|
|---|
| 12 | int n_text;
|
|---|
| 13 | @@ -263,20 +265,23 @@
|
|---|
| 14 | if(os->vorbis) {
|
|---|
| 15 | if(*pack->packet & PACKET_TYPE_HEADER)
|
|---|
| 16 | os->hdr_packets++;
|
|---|
| 17 | - else if (os->vi_initialized)
|
|---|
| 18 | + else
|
|---|
| 19 | {
|
|---|
| 20 | vorbis_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)
|
|---|
| 28 | blocksize = vorbis_packet_blocksize(vi,pack) / samplesize;
|
|---|
| 29 | // Calculate the timestamp if the packet don't have any
|
|---|
| 30 | if(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;
|
|---|
| 39 | os->lastsize = blocksize;
|
|---|
| 40 | os->lastpos = pack->granulepos;
|
|---|
| 41 | @@ -521,12 +526,7 @@
|
|---|
| 42 | pos = last_pos = demuxer->movi_start;
|
|---|
| 43 |
|
|---|
| 44 | // Reset the stream
|
|---|
| 45 | - if(index_mode == 2) {
|
|---|
| 46 | stream_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 | - }
|
|---|
| 51 | ogg_sync_reset(sync);
|
|---|
| 52 |
|
|---|
| 53 | // Get the serial number of the stream we use
|
|---|
| 54 | @@ -574,7 +574,18 @@
|
|---|
| 55 | float pts;
|
|---|
| 56 | int flags;
|
|---|
| 57 | demux_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 | + }
|
|---|
| 71 | if(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 |
|
|---|
| 77 | ogg_d->final_granulepos=0;
|
|---|
| 78 | + ogg_d->initial_granulepos = MP_NOPTS_VALUE;
|
|---|
| 79 | if(!s->end_pos)
|
|---|
| 80 | demuxer->seekable = 0;
|
|---|
| 81 | else {
|
|---|
| 82 | @@ -1130,6 +1142,9 @@
|
|---|
| 83 | demuxer->seekable = 1;
|
|---|
| 84 | demux_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 |
|
|---|
| 90 | mp_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 @@
|
|---|
| 93 | old_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;
|
|---|
| 98 | if(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;
|
|---|
| 103 | else
|
|---|
| 104 | gp += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * os->lastpos / ogg_d->pos;
|
|---|
| 105 | } else
|
|---|
| 106 | @@ -1391,8 +1406,8 @@
|
|---|
| 107 | if(flags & SEEK_FACTOR)
|
|---|
| 108 | pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs;
|
|---|
| 109 | else {
|
|---|
| 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) {
|
|---|
| 115 | pos += rel_seek_secs * ogg_d->pos / (os->lastpos / rate);
|
|---|
| 116 | }
|
|---|
| 117 | @@ -1547,13 +1562,13 @@
|
|---|
| 118 |
|
|---|
| 119 | switch(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 |
|
|---|