summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormosu <mosu@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-12-08 09:47:15 +0000
committermosu <mosu@b3059339-0415-0410-9bf9-f77b7e298cf2>2003-12-08 09:47:15 +0000
commita1f615e34d6b84bbfcd504fa76d45a554485f5a1 (patch)
treea48805b10fa81cd413b90a22aa934b0560b9454d
parent791f52c526893aff1e42a55cde0475ccce38b020 (diff)
downloadmpv-a1f615e34d6b84bbfcd504fa76d45a554485f5a1.tar.bz2
mpv-a1f615e34d6b84bbfcd504fa76d45a554485f5a1.tar.xz
Get the total length for Ogg files. Patch by Michael Behrisch <behrisch@informatik.hu-berlin.de>.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@11576 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--libmpdemux/demux_ogg.c56
-rw-r--r--libmpdemux/demuxer.c5
2 files changed, 53 insertions, 8 deletions
diff --git a/libmpdemux/demux_ogg.c b/libmpdemux/demux_ogg.c
index 41bf40d481..7cfc345152 100644
--- a/libmpdemux/demux_ogg.c
+++ b/libmpdemux/demux_ogg.c
@@ -126,6 +126,7 @@ typedef struct ogg_demuxer {
ogg_syncpoint_t* syncpoints;
int num_syncpoint;
off_t pos, last_size;
+ int64_t final_granulepos;
} ogg_demuxer_t;
#define NUM_VORBIS_HDR_PACKETS 3
@@ -442,7 +443,7 @@ static int demux_ogg_add_packet(demux_stream_t* ds,ogg_stream_t* os,ogg_packet*
}
/// Build a table of all syncpoints to make seeking easier
-void demux_ogg_build_syncpoints_table(demuxer_t* demuxer) {
+void demux_ogg_scan_stream(demuxer_t* demuxer) {
ogg_demuxer_t* ogg_d = demuxer->priv;
stream_t *s = demuxer->stream;
ogg_sync_state* sync = &ogg_d->sync;
@@ -456,7 +457,12 @@ void demux_ogg_build_syncpoints_table(demuxer_t* demuxer) {
pos = last_pos = demuxer->movi_start;
// Reset the stream
+ if(index_mode == 2) {
stream_seek(s,demuxer->movi_start);
+ }
+ else {
+ stream_seek(s,demuxer->movi_end-20*BLOCK_SIZE);
+ }
ogg_sync_reset(sync);
// Get the serial number of the stream we use
@@ -478,7 +484,7 @@ void demux_ogg_build_syncpoints_table(demuxer_t* demuxer) {
while(1) {
np = ogg_sync_pageseek(sync,page);
if(np < 0) { // We had to skip some bytes
- mp_msg(MSGT_DEMUX,MSGL_ERR,"Bad page sync while building syncpoints table (%d)\n",-np);
+ if(index_mode == 2) mp_msg(MSGT_DEMUX,MSGL_ERR,"Bad page sync while building syncpoints table (%d)\n",-np);
pos += -np;
continue;
}
@@ -507,21 +513,25 @@ void demux_ogg_build_syncpoints_table(demuxer_t* demuxer) {
int flags;
demux_ogg_read_packet(os,&op,context,&pts,&flags);
if(flags || (os->vorbis && op.granulepos >= 0)) {
+ if(index_mode == 2) {
ogg_d->syncpoints = (ogg_syncpoint_t*)realloc(ogg_d->syncpoints,(ogg_d->num_syncpoint+1)*sizeof(ogg_syncpoint_t));
ogg_d->syncpoints[ogg_d->num_syncpoint].granulepos = op.granulepos;
ogg_d->syncpoints[ogg_d->num_syncpoint].page_pos = (ogg_page_continued(page) && p == 0) ? last_pos : pos;
ogg_d->num_syncpoint++;
}
+ ogg_d->final_granulepos = op.granulepos;
+ }
p++;
}
if(p > 1 || (p == 1 && ! ogg_page_continued(page)))
last_pos = pos;
pos += np;
- mp_msg(MSGT_DEMUX,MSGL_INFO,"Building syncpoint table %d%%\r",(int)(pos*100/s->end_pos));
+ if(index_mode == 2) mp_msg(MSGT_DEMUX,MSGL_INFO,"Building syncpoint table %d%%\r",(int)(pos*100/s->end_pos));
}
- mp_msg(MSGT_DEMUX,MSGL_INFO,"\n");
+ if(index_mode == 2) mp_msg(MSGT_DEMUX,MSGL_INFO,"\n");
- mp_msg(MSGT_DEMUX,MSGL_V,"Ogg syncpoints table builed: %d syncpoints\n",ogg_d->num_syncpoint);
+ if(index_mode == 2) mp_msg(MSGT_DEMUX,MSGL_V,"Ogg syncpoints table builed: %d syncpoints\n",ogg_d->num_syncpoint);
+ mp_msg(MSGT_DEMUX,MSGL_V,"Ogg stream length: %d\n",ogg_d->final_granulepos);
stream_reset(s);
stream_seek(s,demuxer->movi_start);
@@ -835,7 +845,7 @@ int demux_ogg_open(demuxer_t* demuxer) {
}
}
/// Add the header packets if the stream isn't seekable
- if(ds && (!s->end_pos || index_mode != 2)) {
+ if(ds && !s->end_pos) {
/// Finish the page, otherwise packets will be lost
do {
demux_ogg_add_packet(ds,&ogg_d->subs[ogg_d->num_sub],&pack);
@@ -855,14 +865,14 @@ int demux_ogg_open(demuxer_t* demuxer) {
if(!n_text)
demuxer->sub->id = -2;
+ ogg_d->final_granulepos=0;
if(!s->end_pos)
demuxer->seekable = 0;
else {
demuxer->movi_start = s->start_pos; // Needed for XCD (Ogg written in MODE2)
demuxer->movi_end = s->end_pos;
demuxer->seekable = 1;
- if(index_mode == 2)
- demux_ogg_build_syncpoints_table(demuxer);
+ demux_ogg_scan_stream(demuxer);
}
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":"",n_text,n_text>1?"s":"");
@@ -1199,4 +1209,34 @@ void demux_close_ogg(demuxer_t* demuxer) {
free(ogg_d);
}
+int demux_ogg_control(demuxer_t *demuxer,int cmd, void *arg){
+ ogg_demuxer_t* ogg_d = demuxer->priv;
+ ogg_stream_t* os;
+ float rate;
+ if(demuxer->video->id >= 0) {
+ os = &ogg_d->subs[demuxer->video->id];
+ rate = os->samplerate;
+ } else {
+ os = &ogg_d->subs[demuxer->audio->id];
+ rate = (float)((ov_struct_t*)((sh_audio_t*)demuxer->audio->sh)->context)->vi.rate;
+ }
+
+
+ switch(cmd) {
+ case DEMUXER_CTRL_GET_TIME_LENGTH:
+ if (ogg_d->final_granulepos<=0) return DEMUXER_CTRL_DONTKNOW;
+ unsigned long length = ogg_d->final_granulepos / rate;
+ *((unsigned long *)arg)=length;
+ return DEMUXER_CTRL_GUESS;
+
+ case DEMUXER_CTRL_GET_PERCENT_POS:
+ if (ogg_d->final_granulepos<=0) return DEMUXER_CTRL_DONTKNOW;
+ *((int *)arg)=(int)( (os->lastpos*100) / ogg_d->final_granulepos);
+ return DEMUXER_CTRL_OK;
+
+ default:
+ return DEMUXER_CTRL_NOTIMPL;
+ }
+}
+
#endif
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index 77770d90eb..1967126e7b 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -1532,6 +1532,7 @@ extern int demux_avi_control(demuxer_t *demuxer, int cmd, void *arg);
extern int demux_xmms_control(demuxer_t *demuxer, int cmd, void *arg);
extern int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg);
extern int demux_audio_control(demuxer_t *demuxer, int cmd, void *arg);
+extern int demux_ogg_control(demuxer_t *demuxer, int cmd, void *arg);
extern int demux_real_control(demuxer_t *demuxer, int cmd, void *arg);
int demux_control(demuxer_t *demuxer, int cmd, void *arg) {
@@ -1552,6 +1553,10 @@ int demux_control(demuxer_t *demuxer, int cmd, void *arg) {
return demux_avi_control(demuxer,cmd,arg);
case DEMUXER_TYPE_AUDIO:
return demux_audio_control(demuxer,cmd,arg);
+#ifdef HAVE_OGGVORBIS
+ case DEMUXER_TYPE_OGG:
+ return demux_ogg_control(demuxer,cmd,arg);
+#endif
#ifdef HAVE_XMMS
case DEMUXER_TYPE_XMMS:
return demux_xmms_control(demuxer,cmd,arg);