diff -urN main/libmpdemux/demux_ogg.c main_newogg4/libmpdemux/demux_ogg.c --- main/libmpdemux/demux_ogg.c 2005-11-06 01:28:28.814454848 +0100 +++ main_newogg4/libmpdemux/demux_ogg.c 2005-11-10 20:00:42.212851816 +0100 @@ -33,6 +33,11 @@ #define BLOCK_SIZE 4096 +// track types +#define OGG_TRACK_VIDEO 0x01 +#define OGG_TRACK_AUDIO 0x02 +#define OGG_TRACK_SUBTITLE 0x03 + /// Vorbis decoder context : we need the vorbis_info for vorbis timestamping /// Shall we put this struct def in a common header ? typedef struct ov_struct_st { @@ -113,6 +118,11 @@ int64_t lastpos; int32_t lastsize; + // type of track (video/audio/subtitle) + int type; + + unsigned int format; + // Logical stream state ogg_stream_state stream; int hdr_packets; @@ -436,7 +446,7 @@ return 0; } -static int demux_ogg_sub_reverse_id(demuxer_t *demuxer, int id); +static int demux_ogg_reverse_id(demuxer_t *demuxer, int num, int type); /// Try to print out comments and also check for LANGUAGE= tag static void demux_ogg_check_comments(demuxer_t *d, ogg_stream_t *os, int id, vorbis_comment *vc) @@ -477,7 +487,7 @@ if (ogg_d->subs[id].text) mp_msg(MSGT_DEMUX, MSGL_INFO, "[Ogg] Language for -sid %d is '-slang \"%s\"'\n", ogg_d->subs[id].id, val); // copy this language name into the array - index = demux_ogg_sub_reverse_id(d, id); + index = demux_ogg_reverse_id(d, id, OGG_TRACK_SUBTITLE); if (index >= 0) { // in case of malicious files with more than one lang per track: if (ogg_d->text_langs[index]) free(ogg_d->text_langs[index]); @@ -733,15 +743,21 @@ return (index < 0) ? index : (index >= ogg_d->n_text) ? -1 : ogg_d->text_ids[index]; } -/** \brief Translate the ogg track number into the subtitle number. - * \param demuxer The demuxer about whose subtitles we are inquiring. - * \param id The ogg track number of the subtitle track. +/** \brief Translate the ogg track number into the subtitle or audio number. + * \param demuxer The demuxer about whose tracks we are inquiring. + * \param id The ogg track number of the subtitle/audio track. */ -static int demux_ogg_sub_reverse_id(demuxer_t *demuxer, int id) { +static int demux_ogg_reverse_id(demuxer_t *demuxer, int num, int type) { ogg_demuxer_t *ogg_d = (ogg_demuxer_t *)demuxer->priv; - int i; - for (i = 0; i < ogg_d->n_text; i++) - if (ogg_d->text_ids[i] == id) return i; + int i, id; + for (i=0, id=0; i < ogg_d->num_sub; i++) + if (&ogg_d->subs[i] != NULL && ogg_d->subs[i].type == type) { + if (type == OGG_TRACK_SUBTITLE) + if (ogg_d->text_ids[i] == num) return i; + else + if (ogg_d->subs[i].id == num) return i; + id++; + } return -1; } @@ -921,10 +937,12 @@ if(pack.bytes >= 7 && ! strncmp(&pack.packet[1],"vorbis", 6) ) { sh_a = new_sh_audio(demuxer,ogg_d->num_sub); sh_a->format = FOURCC_VORBIS; + ogg_d->subs[ogg_d->num_sub].format = sh_a->format; ogg_d->subs[ogg_d->num_sub].vorbis = 1; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio); ogg_d->subs[ogg_d->num_sub].id = n_audio; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_AUDIO; n_audio++; mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: audio (Vorbis), -aid %d\n",ogg_d->num_sub,n_audio-1); } else if (pack.bytes >= 80 && !strncmp(pack.packet,"Speex", 5)) { @@ -941,8 +959,10 @@ sh_a->wf->cbSize = pack.bytes; memcpy(&sh_a->wf[1], pack.packet, pack.bytes); + ogg_d->subs[ogg_d->num_sub].format = sh_a->format; ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; ogg_d->subs[ogg_d->num_sub].speex = 1; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_AUDIO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio); ogg_d->subs[ogg_d->num_sub].id = n_audio; @@ -983,6 +1003,7 @@ sh_v->bih->biWidth*sh_v->bih->biHeight); ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps; ogg_d->subs[ogg_d->num_sub].theora = 1; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_VIDEO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", n_video); ogg_d->subs[ogg_d->num_sub].id = n_video; @@ -1001,6 +1022,8 @@ } else if (pack.bytes >= 4 && !strncmp (&pack.packet[0], "fLaC", 4)) { sh_a = new_sh_audio(demuxer,ogg_d->num_sub); sh_a->format = mmioFOURCC('f', 'L', 'a', 'C'); + ogg_d->subs[ogg_d->num_sub].format = sh_a->format; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_AUDIO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio); ogg_d->subs[ogg_d->num_sub].id = n_audio; @@ -1031,6 +1054,7 @@ sh_v->bih->biSizeImage=(sh_v->bih->biBitCount>>3)*sh_v->bih->biWidth*sh_v->bih->biHeight; ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_VIDEO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", n_video); ogg_d->subs[ogg_d->num_sub].id = n_video; @@ -1055,7 +1079,9 @@ if(extra_size > 0) memcpy(((char *)sh_a->wf)+sizeof(WAVEFORMATEX),pack.packet+142,extra_size); + ogg_d->subs[ogg_d->num_sub].format = sh_a->format; ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_AUDIO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio); ogg_d->subs[ogg_d->num_sub].id = n_audio; @@ -1087,6 +1113,7 @@ sh_v->bih->biSizeImage=(sh_v->bih->biBitCount>>3)*sh_v->bih->biWidth*sh_v->bih->biHeight; ogg_d->subs[ogg_d->num_sub].samplerate= sh_v->fps; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_VIDEO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", n_video); ogg_d->subs[ogg_d->num_sub].id = n_video; @@ -1126,7 +1153,9 @@ if(extra_size) memcpy(((char *)sh_a->wf)+sizeof(WAVEFORMATEX),((char *)(st+1))+extra_offset,extra_size); + ogg_d->subs[ogg_d->num_sub].format = sh_a->format; ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_AUDIO; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio); ogg_d->subs[ogg_d->num_sub].id = n_audio; @@ -1138,6 +1167,7 @@ } else if (strncmp(st->streamtype, "text", 4) == 0) { mp_msg(MSGT_DEMUX, MSGL_INFO, "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n", ogg_d->num_sub, ogg_d->n_text); ogg_d->subs[ogg_d->num_sub].samplerate= get_uint64(&st->time_unit)/10; + ogg_d->subs[ogg_d->num_sub].type = OGG_TRACK_SUBTITLE; ogg_d->subs[ogg_d->num_sub].text = 1; if (identify) mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", ogg_d->n_text); @@ -1653,6 +1683,39 @@ *((int *)arg)=(int)( (os->lastpos*100) / ogg_d->final_granulepos); return DEMUXER_CTRL_OK; + case DEMUXER_CTRL_SWITCH_AUDIO: + if (demuxer->audio && demuxer->audio->sh) { + int i; + demux_stream_t *d_audio = demuxer->audio; + int idx = d_audio->id; + int num = ogg_d->num_sub; + ogg_stream_t *otrack = &ogg_d->subs[idx]; + ogg_stream_t *track = 0; + if (*((int*)arg) < 0) + for (i = 1; i <= num; i++) { + track = &ogg_d->subs[(idx+i)%num]; + if (track->type == OGG_TRACK_AUDIO && + track->samplerate == otrack->samplerate && + track->format == otrack->format ) { + break; + } + } + else { + track = demux_ogg_sub_id (demuxer, *((int*)arg)); + if (track == NULL || + track->type != OGG_TRACK_AUDIO || + track->samplerate != otrack->samplerate || + track->format != otrack->format ) + track = otrack; + } + if (track != otrack) { + d_audio->id = track->id + 1; + ds_free_packs(d_audio); + } + } + *((int*)arg) = demux_ogg_reverse_id (demuxer, demuxer->audio->id, OGG_TRACK_AUDIO); + return DEMUXER_CTRL_OK; + default: return DEMUXER_CTRL_NOTIMPL; }