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.
This commit is contained in:
wm4 2013-07-08 01:26:13 +02:00
parent 50808bab8d
commit 05ae5afd62
12 changed files with 45 additions and 134 deletions

View File

@ -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: {

View File

@ -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);

View File

@ -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;
demuxer->ds[type]->gsh = stream;
// 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();
}
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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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++) {

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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: