From 05ae5afd6249af9770eb1e55104fbd4f510c2342 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 8 Jul 2013 01:26:13 +0200 Subject: demux: remove separate arrays for audio/video/sub streams, simplify These separate arrays were used by the old demuxers and are not needed anymore. We can simplify track switching as well. One interesting thing is that stream/tv.c (which is a demuxer) won't respect --no-audio anymore. It will probably work as expected, but it will still open an audio device etc. - this is because track selection is now always done with the runtime track switching mechanism. Maybe the TV code could be updated to do proper runtime switching, but I can't test this stuff. --- demux/demux.c | 94 +++++++++++++------------------------------------- demux/demux.h | 11 +----- demux/demux_lavf.c | 6 ++-- demux/demux_mf.c | 3 -- demux/demux_mkv.c | 8 ++--- demux/demux_mng.c | 5 --- demux/demux_rawaudio.c | 8 ++--- demux/demux_rawvideo.c | 7 ++-- demux/stheader.h | 2 -- 9 files changed, 35 insertions(+), 109 deletions(-) (limited to 'demux') diff --git a/demux/demux.c b/demux/demux.c index 4068f616cf..1d91920054 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -207,12 +207,11 @@ static void free_demuxer_stream(struct demux_stream *ds) } static struct demux_stream *new_demuxer_stream(struct demuxer *demuxer, - enum stream_type type, int id) + enum stream_type type) { demux_stream_t *ds = malloc(sizeof(demux_stream_t)); *ds = (demux_stream_t) { .stream_type = type, - .id = id, .demuxer = demuxer, }; return ds; @@ -248,9 +247,9 @@ static demuxer_t *new_demuxer(struct MPOpts *opts, stream_t *stream, int type, d->seekable = 1; d->synced = 0; d->filepos = -1; - d->audio = new_demuxer_stream(d, STREAM_AUDIO, a_id); - d->video = new_demuxer_stream(d, STREAM_VIDEO, v_id); - d->sub = new_demuxer_stream(d, STREAM_SUB, s_id); + d->audio = new_demuxer_stream(d, STREAM_AUDIO); + d->video = new_demuxer_stream(d, STREAM_VIDEO); + d->sub = new_demuxer_stream(d, STREAM_SUB); d->ds[STREAM_VIDEO] = d->video; d->ds[STREAM_AUDIO] = d->audio; d->ds[STREAM_SUB] = d->sub; @@ -285,7 +284,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) .demuxer = demuxer, .index = demuxer->num_streams, .demuxer_id = demuxer_id, // may be overwritten by demuxer - .stream_index = demuxer->num_streams, .opts = demuxer->opts, }); MP_TARRAY_APPEND(demuxer, demuxer->streams, demuxer->num_streams, sh); @@ -296,7 +294,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) sht->opts = sh->opts; sht->ds = demuxer->video; sh->video = sht; - demuxer->v_streams[sh->stream_index] = sht; break; } case STREAM_AUDIO: { @@ -307,7 +304,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) sht->samplesize = 2; sht->sample_format = AF_FORMAT_S16_NE; sh->audio = sht; - demuxer->a_streams[sh->stream_index] = sht; break; } case STREAM_SUB: { @@ -316,7 +312,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) sht->opts = sh->opts; sht->ds = demuxer->sub; sh->sub = sht; - demuxer->s_streams[sh->stream_index] = sht; break; } default: assert(false); @@ -324,51 +319,41 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) return sh; } -static void free_sh_stream(struct sh_stream *sh) -{ -} - static void free_sh_sub(sh_sub_t *sh) { - mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_sub at %p\n", sh); free(sh->extradata); - free_sh_stream(sh->gsh); } -static void free_sh_audio(demuxer_t *demuxer, int id) +static void free_sh_audio(sh_audio_t *sh) { - sh_audio_t *sh = demuxer->a_streams[id]; - demuxer->a_streams[id] = NULL; - mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_audio at %p\n", sh); free(sh->wf); free(sh->codecdata); - free_sh_stream(sh->gsh); } static void free_sh_video(sh_video_t *sh) { - mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_video at %p\n", sh); free(sh->bih); - free_sh_stream(sh->gsh); +} + +static void free_sh_stream(struct sh_stream *sh) +{ + switch (sh->type) { + case STREAM_AUDIO: free_sh_audio(sh->audio); break; + case STREAM_VIDEO: free_sh_video(sh->video); break; + case STREAM_SUB: free_sh_sub(sh->sub); break; + default: abort(); + } } void free_demuxer(demuxer_t *demuxer) { - int i; mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing %s demuxer at %p\n", demuxer->desc->shortdesc, demuxer); if (demuxer->desc->close) demuxer->desc->close(demuxer); // free streams: - for (i = 0; i < MAX_A_STREAMS; i++) - if (demuxer->a_streams[i]) - free_sh_audio(demuxer, i); - for (i = 0; i < MAX_V_STREAMS; i++) - if (demuxer->v_streams[i]) - free_sh_video(demuxer->v_streams[i]); - for (i = 0; i < MAX_S_STREAMS; i++) - if (demuxer->s_streams[i]) - free_sh_sub(demuxer->s_streams[i]); + for (int n = 0; n < demuxer->num_streams; n++) + free_sh_stream(demuxer->streams[n]); // free demuxers: free_demuxer_stream(demuxer->audio); free_demuxer_stream(demuxer->video); @@ -535,9 +520,7 @@ int ds_fill_buffer(demux_stream_t *ds) break; // EOF } - struct sh_video *sh_video = demux->video->sh; - - if (sh_video && sh_video->gsh->attached_picture) { + if (demux->video->gsh && demux->video->gsh->attached_picture) { if (demux->audio) ds->fill_count += demux->audio->packs - apacks; if (demux->video && demux->video->packs > vpacks) @@ -1015,48 +998,19 @@ void demuxer_switch_track(struct demuxer *demuxer, enum stream_type type, { assert(!stream || stream->type == type); - // don't flush buffers if stream is already selected - if (stream && demuxer_stream_is_selected(demuxer, stream)) + // don't flush buffers if stream is already selected / none are selected + if (demuxer->ds[type]->gsh == stream) return; - int old_id = demuxer->ds[type]->id; - - // legacy - int index = stream ? stream->stream_index : -2; - if (type == STREAM_AUDIO) { - if (demux_control(demuxer, DEMUXER_CTRL_SWITCH_AUDIO, &index) - == DEMUXER_CTRL_NOTIMPL) - demuxer->audio->id = index; - } else if (type == STREAM_VIDEO) { - if (demux_control(demuxer, DEMUXER_CTRL_SWITCH_VIDEO, &index) - == DEMUXER_CTRL_NOTIMPL) - demuxer->video->id = index; - } else if (type == STREAM_SUB) { - demuxer->ds[type]->id = index; - } else { - abort(); - } + demuxer->ds[type]->gsh = stream; - int new_id = demuxer->ds[type]->id; - void *new = NULL; - if (new_id >= 0) { - switch (type) { - case STREAM_VIDEO: new = demuxer->v_streams[new_id]; break; - case STREAM_AUDIO: new = demuxer->a_streams[new_id]; break; - case STREAM_SUB: new = demuxer->s_streams[new_id]; break; - } - } - demuxer->ds[type]->sh = new; - - if (old_id != new_id) { - ds_free_packs(demuxer->ds[type]); - demux_control(demuxer, DEMUXER_CTRL_SWITCHED_TRACKS, NULL); - } + ds_free_packs(demuxer->ds[type]); + demux_control(demuxer, DEMUXER_CTRL_SWITCHED_TRACKS, NULL); } bool demuxer_stream_is_selected(struct demuxer *d, struct sh_stream *stream) { - return stream && d->ds[stream->type]->id == stream->stream_index; + return stream && d->ds[stream->type]->gsh == stream; } int demuxer_add_attachment(demuxer_t *demuxer, struct bstr name, diff --git a/demux/demux.h b/demux/demux.h index 3d632a92c6..93cf680bae 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -107,16 +107,12 @@ typedef struct demux_stream { demux_packet_t *first; // read to current buffer from here demux_packet_t *last; // append new packets from input stream to here demux_packet_t *current; // needed for refcounting of the buffer - int id; // stream ID (for multiple audio/video streams) struct demuxer *demuxer; // parent demuxer structure (stream handler) // ---- stream header ---- - void *sh; // points to sh_audio or sh_video + struct sh_stream *gsh; } demux_stream_t; #define MAX_SH_STREAMS 256 -#define MAX_A_STREAMS MAX_SH_STREAMS -#define MAX_V_STREAMS MAX_SH_STREAMS -#define MAX_S_STREAMS MAX_SH_STREAMS struct demuxer; @@ -220,11 +216,6 @@ typedef struct demuxer { struct demux_stream *video; // video buffer/demuxer struct demux_stream *sub; // dvd subtitle buffer/demuxer - // stream headers: - struct sh_audio *a_streams[MAX_SH_STREAMS]; - struct sh_video *v_streams[MAX_SH_STREAMS]; - struct sh_sub *s_streams[MAX_SH_STREAMS]; - struct sh_stream **streams; int num_streams; diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 466ab7537b..aad1edfcde 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -658,11 +658,11 @@ static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds) AVStream *st = priv->avfc->streams[pkt->stream_index]; struct sh_stream *stream = priv->streams[pkt->stream_index]; - if (stream && stream->type == STREAM_SUB && demux->sub->id < 0 && + if (stream && stream->type == STREAM_SUB && !demux->sub->gsh && stream->demuxer_id == priv->autoselect_sub) { priv->autoselect_sub = -1; - demux->sub->id = stream->stream_index; + demux->sub->gsh = stream; } if (!demuxer_stream_is_selected(demux, stream)) { @@ -809,7 +809,7 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg) } case DEMUXER_CTRL_AUTOSELECT_SUBTITLE: { - demuxer->sub->id = -1; + demuxer->sub->gsh = NULL; priv->autoselect_sub = *((int *)arg); return DEMUXER_CTRL_OK; } diff --git a/demux/demux_mf.c b/demux/demux_mf.c index 7e2757e155..8435c36f37 100644 --- a/demux/demux_mf.c +++ b/demux/demux_mf.c @@ -208,9 +208,6 @@ static demuxer_t* demux_open_mf(demuxer_t* demuxer){ // create a new video stream header struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO); sh_video = sh->video; - // make sure the demuxer knows about the new video stream header - // (even though new_sh_video() ought to take care of it) - demuxer->video->sh = sh_video; sh_video->gsh->codec = probe_format(mf); if (!sh_video->gsh->codec) { diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 724bf6255b..b00c115ef2 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -1962,9 +1962,8 @@ static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track, } else dp->pts = real_fix_timestamp(dp->buffer, timestamp, - ((sh_video_t *) demuxer->video->sh)->bih-> - biCompression, &track->rv_kf_base, - &track->rv_kf_pts, NULL); + demuxer->video->gsh->video->bih->biCompression, + &track->rv_kf_base, &track->rv_kf_pts, NULL); dp->pos = demuxer->filepos; dp->keyframe = keyframe; @@ -2047,8 +2046,7 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track, if (track->sub_packet_cnt == 0) track->audio_filepos = demuxer->filepos; if (++(track->sub_packet_cnt) == sph) { - int apk_usize = - ((sh_audio_t *) demuxer->audio->sh)->wf->nBlockAlign; + int apk_usize = demuxer->audio->gsh->audio->wf->nBlockAlign; track->sub_packet_cnt = 0; // Release all the audio packets for (x = 0; x < sph * w / apk_usize; x++) { diff --git a/demux/demux_mng.c b/demux/demux_mng.c index 4b2077d31f..1f73399902 100644 --- a/demux/demux_mng.c +++ b/demux/demux_mng.c @@ -426,11 +426,6 @@ static demuxer_t * demux_mng_open(demuxer_t * demuxer) struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO); sh_video = sh->video; - // Make sure the demuxer knows about the new video stream header - // (even though new_sh_video() ought to take care of it). - // (Thanks to demux_gif.c for this.) - demuxer->video->sh = sh_video; - // Make sure that the video demuxer stream header knows about its // parent video demuxer stream (this is getting wacky), or else // video_read_properties() will choke. diff --git a/demux/demux_rawaudio.c b/demux/demux_rawaudio.c index 5f47efe936..50e4e4a68b 100644 --- a/demux/demux_rawaudio.c +++ b/demux/demux_rawaudio.c @@ -69,15 +69,11 @@ static demuxer_t* demux_rawaudio_open(demuxer_t* demuxer) { demuxer->movi_start = demuxer->stream->start_pos; demuxer->movi_end = demuxer->stream->end_pos; - demuxer->audio->id = 0; - demuxer->audio->sh = sh_audio; - sh_audio->ds = demuxer->audio; - return demuxer; } static int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { - sh_audio_t* sh_audio = demuxer->audio->sh; + sh_audio_t* sh_audio = demuxer->audio->gsh->audio; int l = sh_audio->wf->nAvgBytesPerSec; int64_t spos = stream_tell(demuxer->stream); demux_packet_t* dp; @@ -98,7 +94,7 @@ static int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { static void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ stream_t* s = demuxer->stream; - sh_audio_t* sh_audio = demuxer->audio->sh; + sh_audio_t* sh_audio = demuxer->audio->gsh->audio; int64_t base,pos; base = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s); diff --git a/demux/demux_rawvideo.c b/demux/demux_rawvideo.c index c0b3b1980d..6834bfb23a 100644 --- a/demux/demux_rawvideo.c +++ b/demux/demux_rawvideo.c @@ -127,14 +127,11 @@ static demuxer_t* demux_rawvideo_open(demuxer_t* demuxer) { demuxer->movi_start = demuxer->stream->start_pos; demuxer->movi_end = demuxer->stream->end_pos; - demuxer->video->sh = sh_video; - sh_video->ds = demuxer->video; - return demuxer; } static int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { - sh_video_t* sh = demuxer->video->sh; + sh_video_t* sh = demuxer->video->gsh->video; int64_t pos; if(demuxer->stream->eof) return 0; if(ds!=demuxer->video) return 0; @@ -145,7 +142,7 @@ static int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { static void demux_rawvideo_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ stream_t* s = demuxer->stream; - sh_video_t* sh_video = demuxer->video->sh; + sh_video_t* sh_video = demuxer->video->gsh->video; int64_t pos; pos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s); diff --git a/demux/stheader.h b/demux/stheader.h index a4ae0b28bb..b2dc2018d2 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -42,8 +42,6 @@ struct sh_stream { struct demuxer *demuxer; // Index into demuxer->streams. int index; - // Index into stream array (currently one array per type, e.g. a_streams). - int stream_index; // Demuxer/format specific ID. Corresponds to the stream IDs as encoded in // some file formats (e.g. MPEG), or an index chosen by demux.c. int demuxer_id; -- cgit v1.2.3