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. --- core/command.c | 8 ++--- core/mplayer.c | 15 ++++---- 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 -- stream/tv.c | 12 ------- 12 files changed, 45 insertions(+), 134 deletions(-) diff --git a/core/command.c b/core/command.c index 80f6f5d9d2..fb21d7bc41 100644 --- a/core/command.c +++ b/core/command.c @@ -566,13 +566,13 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg, case M_PROPERTY_SET: angle = demuxer_set_angle(demuxer, *(int *)arg); if (angle >= 0) { - struct sh_video *sh_video = demuxer->video->sh; + struct sh_stream *sh_video = demuxer->video->gsh; if (sh_video) - resync_video_stream(sh_video); + resync_video_stream(sh_video->video); - struct sh_audio *sh_audio = demuxer->audio->sh; + struct sh_stream *sh_audio = demuxer->audio->gsh; if (sh_audio) - resync_audio_stream(sh_audio); + resync_audio_stream(sh_audio->audio); } return M_PROPERTY_OK; case M_PROPERTY_GET_TYPE: { diff --git a/core/mplayer.c b/core/mplayer.c index 16277d2e60..78fb8c9a8e 100644 --- a/core/mplayer.c +++ b/core/mplayer.c @@ -375,7 +375,7 @@ static double get_main_demux_pts(struct MPContext *mpctx) if (mpctx->demuxer) { for (int type = 0; type < STREAM_TYPE_COUNT; type++) { struct demux_stream *ds = mpctx->demuxer->ds[type]; - if (ds->sh && main_new_pos == MP_NOPTS_VALUE) { + if (ds->gsh && main_new_pos == MP_NOPTS_VALUE) { demux_fill_buffer(mpctx->demuxer, ds); if (ds->first) main_new_pos = ds->first->pts; @@ -445,11 +445,11 @@ static void preselect_demux_streams(struct MPContext *mpctx) static void uninit_subs(struct demuxer *demuxer) { - for (int i = 0; i < MAX_S_STREAMS; i++) { - struct sh_sub *sh = demuxer->s_streams[i]; - if (sh) { - sub_destroy(sh->dec_sub); - sh->dec_sub = NULL; + for (int i = 0; i < demuxer->num_streams; i++) { + struct sh_stream *sh = demuxer->streams[i]; + if (sh->sub) { + sub_destroy(sh->sub->dec_sub); + sh->sub->dec_sub = NULL; } } } @@ -1938,9 +1938,6 @@ static void reinit_subs(struct MPContext *mpctx) // which makes the demuxer create the sh_stream, and contains the first // subtitle event. - // demux_mpg - maps IDs directly to the logical stream number - track->demuxer->sub->id = track->demuxer_id; - // demux_lavf - IDs are essentially random, have to use MPEG IDs int id = map_id_to_demuxer(track->demuxer, track->type, track->demuxer_id); 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; diff --git a/stream/tv.c b/stream/tv.c index 83a0052563..e5768a350a 100644 --- a/stream/tv.c +++ b/stream/tv.c @@ -739,20 +739,12 @@ static demuxer_t* demux_open_tv(demuxer_t *demuxer) tvh->tv_param->noaudio = 1; } - /* disable TV audio if -nosound is present */ - if (!demuxer->audio || demuxer->audio->id == -2) { - tvh->tv_param->noaudio = 1; - } - /* set width */ funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); /* set height */ funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h); - demuxer->video->sh = sh_video; - sh_video->ds = demuxer->video; - demuxer->video->id = 0; demuxer->seekable = 0; /* here comes audio init */ @@ -818,10 +810,6 @@ static demuxer_t* demux_open_tv(demuxer_t *demuxer) mp_tmsg(MSGT_DECVIDEO, MSGL_V, " TV audio: %d channels, %d bits, %d Hz\n", sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample, sh_audio->wf->nSamplesPerSec); - - demuxer->audio->sh = sh_audio; - sh_audio->ds = demuxer->audio; - demuxer->audio->id = 0; } no_audio: -- cgit v1.2.3