diff options
author | wm4 <wm4@nowhere> | 2012-08-03 12:24:55 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2012-08-03 13:25:41 +0200 |
commit | 9c02ae7e9510897826334ddf79fa3a0cf65a78a2 (patch) | |
tree | 813c9a2b757b2531d3fd29cf483ac1ba89093f7f /libmpdemux | |
parent | d722f8fe61296e5b277ed94be055bb9ef1c99e19 (diff) | |
download | mpv-9c02ae7e9510897826334ddf79fa3a0cf65a78a2.tar.bz2 mpv-9c02ae7e9510897826334ddf79fa3a0cf65a78a2.tar.xz |
demuxer: introduce a general stream struct
There are different C types for each stream type: sh_video for video,
sh_audio for audio, sh_sub for sub. There is no type that handles all
stream types in a generic way. Instead, there's a macro SH_COMMON, that
is used to define common fields for all 3 stream structs. Accessing
the common fields is hard if you want to be independent from the stream
type.
Introduce an actual generic stream struct (struct sh_stream), which is
supposed to unify all 3 stream types one day. Once all fields defined
by SH_COMMON have been moved into sh_stream, the transition is complete.
Move some fields into sh_stream, and rewrite osd_show_tracks to use
them.
Diffstat (limited to 'libmpdemux')
-rw-r--r-- | libmpdemux/demux_lavf.c | 16 | ||||
-rw-r--r-- | libmpdemux/demux_mkv.c | 16 | ||||
-rw-r--r-- | libmpdemux/demuxer.c | 101 | ||||
-rw-r--r-- | libmpdemux/demuxer.h | 19 | ||||
-rw-r--r-- | libmpdemux/stheader.h | 38 |
5 files changed, 123 insertions, 67 deletions
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c index 42130dd677..b7a8029927 100644 --- a/libmpdemux/demux_lavf.c +++ b/libmpdemux/demux_lavf.c @@ -309,7 +309,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) sh_audio = new_sh_audio_aid(demuxer, i, priv->audio_streams); if (!sh_audio) break; - sh_audio->demuxer_id = i; + sh_audio->gsh->demuxer_id = i; sh_audio->demuxer_codecname = codec_name; stream_type = "audio"; priv->astreams[priv->audio_streams] = i; @@ -366,7 +366,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) break; } if (title && title->value) { - sh_audio->title = talloc_strdup(sh_audio, title->value); + sh_audio->gsh->title = talloc_strdup(sh_audio, title->value); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", priv->audio_streams, title->value); } @@ -376,7 +376,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) priv->audio_streams, sh_audio->lang); } if (st->disposition & AV_DISPOSITION_DEFAULT) - sh_audio->default_track = 1; + sh_audio->gsh->default_track = 1; if (mp_msg_test(MSGT_HEADER, MSGL_V)) print_wave_header(sh_audio->wf, MSGL_V); st->discard = AVDISCARD_ALL; @@ -389,7 +389,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) sh_video = new_sh_video_vid(demuxer, i, priv->video_streams); if (!sh_video) break; - sh_video->demuxer_id = i; + sh_video->gsh->demuxer_id = i; sh_video->demuxer_codecname = codec_name; stream_type = "video"; priv->vstreams[priv->video_streams] = i; @@ -454,7 +454,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) / (float)(codec->height * codec->sample_aspect_ratio.den); sh_video->i_bps = codec->bit_rate / 8; if (title && title->value) { - sh_video->title = talloc_strdup(sh_video, title->value); + sh_video->gsh->title = talloc_strdup(sh_video, title->value); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", priv->video_streams, title->value); } @@ -502,7 +502,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams); if (!sh_sub) break; - sh_sub->demuxer_id = i; + sh_sub->gsh->demuxer_id = i; sh_sub->demuxer_codecname = codec_name; stream_type = "subtitle"; priv->sstreams[priv->sub_streams] = i; @@ -514,7 +514,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) sh_sub->extradata_len = codec->extradata_size; } if (title && title->value) { - sh_sub->title = talloc_strdup(sh_sub, title->value); + sh_sub->gsh->title = talloc_strdup(sh_sub, title->value); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", priv->sub_streams, title->value); } @@ -524,7 +524,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) priv->sub_streams, sh_sub->lang); } if (st->disposition & AV_DISPOSITION_DEFAULT) - sh_sub->default_track = 1; + sh_sub->gsh->default_track = 1; stream_id = priv->sub_streams++; break; } diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c index 49168e88e4..bf6a53a14f 100644 --- a/libmpdemux/demux_mkv.c +++ b/libmpdemux/demux_mkv.c @@ -1271,9 +1271,9 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track, } sh_v = new_sh_video(demuxer, vid); - sh_v->demuxer_id = track->tnum; + sh_v->gsh->demuxer_id = track->tnum; sh_v->demuxer_codecname = track->codec_id; - sh_v->title = talloc_strdup(sh_v, track->name); + sh_v->gsh->title = talloc_strdup(sh_v, track->name); sh_v->bih = bih; sh_v->format = sh_v->bih->biCompression; if (track->v_frate == 0.0) @@ -1344,10 +1344,10 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track, if (track->language && (strcmp(track->language, "und") != 0)) sh_a->lang = talloc_strdup(sh_a, track->language); - sh_a->demuxer_id = track->tnum; + sh_a->gsh->demuxer_id = track->tnum; sh_a->demuxer_codecname = track->codec_id; - sh_a->title = talloc_strdup(sh_a, track->name); - sh_a->default_track = track->default_track; + sh_a->gsh->title = talloc_strdup(sh_a, track->name); + sh_a->gsh->default_track = track->default_track; sh_a->ds = demuxer->audio; if (track->ms_compat) { if (track->private_size < sizeof(*sh_a->wf)) @@ -1583,7 +1583,7 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track, int size; uint8_t *buffer; sh_sub_t *sh = new_sh_sub(demuxer, sid); - sh->demuxer_id = track->tnum; + sh->gsh->demuxer_id = track->tnum; sh->demuxer_codecname = track->codec_id; track->sh_sub = sh; sh->type = track->subtitle_type; @@ -1600,8 +1600,8 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track, sh->extradata_len = track->private_size; if (track->language && (strcmp(track->language, "und") != 0)) sh->lang = talloc_strdup(sh, track->language); - sh->title = talloc_strdup(sh, track->name); - sh->default_track = track->default_track; + sh->gsh->title = talloc_strdup(sh, track->name); + sh->gsh->default_track = track->default_track; } else { mp_tmsg(MSGT_DEMUX, MSGL_ERR, "[mkv] Subtitle type '%s' is not supported.\n", diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index a9a827dd7a..078699fad7 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -284,6 +284,58 @@ const char *sh_sub_type2str(int type) return "unknown"; } +static struct sh_stream *new_sh_stream(demuxer_t *demuxer, + enum stream_type type, + int stream_index, + int tid) +{ + struct sh_stream *sh = talloc_struct(demuxer, struct sh_stream, { + .type = type, + .index = demuxer->num_streams, + .demuxer_id = demuxer->new_stream_id++, // possibly temporary value only + .tid = tid, + .stream_index = stream_index, + .opts = demuxer->opts, + }); + MP_TARRAY_APPEND(demuxer, demuxer->streams, demuxer->num_streams, sh); + switch (sh->type) { + case STREAM_VIDEO: { + struct sh_video *sht = talloc_zero(demuxer, struct sh_video); + sht->vid = sh->tid; + sht->ds = demuxer->video; + sh->video = sht; + sh->common_header = (struct sh_common *) sht; + demuxer->v_streams[sh->stream_index] = sht; + break; + } + case STREAM_AUDIO: { + struct sh_audio *sht = talloc_zero(demuxer, struct sh_audio); + sht->aid = tid; + sht->ds = demuxer->audio; + sht->samplesize = 2; + sht->sample_format = AF_FORMAT_S16_NE; + sh->audio = sht; + sh->common_header = (struct sh_common *) sht; + demuxer->a_streams[sh->stream_index] = sht; + break; + } + case STREAM_SUB: { + struct sh_sub *sht = talloc_zero(demuxer, struct sh_sub); + sht->sid = tid; + sht->ds = demuxer->sub; + sh->sub = sht; + sh->common_header = (struct sh_common *) sht; + demuxer->s_streams[sh->stream_index] = sht; + break; + } + default: assert(false); + } + sh->common_header->id = sh->tid; + sh->common_header->opts = sh->opts; + sh->common_header->gsh = sh; + return sh; +} + sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) { if (id > MAX_S_STREAMS - 1 || id < 0) { @@ -295,14 +347,7 @@ sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) if (demuxer->s_streams[id]) mp_msg(MSGT_DEMUXER, MSGL_WARN, "Sub stream %i redefined\n", id); else { - struct sh_sub *sh = talloc_zero(demuxer, struct sh_sub); - demuxer->s_streams[id] = sh; - sh->stream_type = STREAM_SUBTITLE; - sh->demuxer_id = demuxer->new_stream_id++; - sh->id = sid; - sh->index = id; - sh->sid = sid; - sh->opts = demuxer->opts; + new_sh_stream(demuxer, STREAM_SUB, id, sid); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", sid); } return demuxer->s_streams[id]; @@ -328,18 +373,7 @@ sh_audio_t *new_sh_audio_aid(demuxer_t *demuxer, int id, int aid) mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "WARNING: Audio stream header %d redefined.\n", id); } else { mp_tmsg(MSGT_DEMUXER, MSGL_V, "==> Found audio stream: %d\n", id); - struct sh_audio *sh = talloc_zero(demuxer, struct sh_audio); - demuxer->a_streams[id] = sh; - sh->stream_type = STREAM_AUDIO; - sh->demuxer_id = demuxer->new_stream_id++; - sh->id = aid; - sh->index = id; - sh->aid = aid; - sh->ds = demuxer->audio; - // set some defaults - sh->samplesize = 2; - sh->sample_format = AF_FORMAT_S16_NE; - sh->opts = demuxer->opts; + new_sh_stream(demuxer, STREAM_AUDIO, id, aid); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_ID=%d\n", aid); } return demuxer->a_streams[id]; @@ -368,15 +402,7 @@ sh_video_t *new_sh_video_vid(demuxer_t *demuxer, int id, int vid) mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "WARNING: Video stream header %d redefined.\n", id); else { mp_tmsg(MSGT_DEMUXER, MSGL_V, "==> Found video stream: %d\n", id); - struct sh_video *sh = talloc_zero(demuxer, struct sh_video); - demuxer->v_streams[id] = sh; - sh->stream_type = STREAM_VIDEO; - sh->demuxer_id = demuxer->new_stream_id++; - sh->id = vid; - sh->index = id; - sh->vid = vid; - sh->ds = demuxer->video; - sh->opts = demuxer->opts; + new_sh_stream(demuxer, STREAM_VIDEO, id, vid); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ID=%d\n", vid); } return demuxer->v_streams[id]; @@ -1452,7 +1478,7 @@ int demuxer_set_angle(demuxer_t *demuxer, int angle) return angle; } -char *demuxer_audio_lang(demuxer_t *d, int id) +static char *demuxer_audio_lang(demuxer_t *d, int id) { struct stream_lang_req req; sh_audio_t *sh; @@ -1470,7 +1496,7 @@ char *demuxer_audio_lang(demuxer_t *d, int id) return NULL; } -char *demuxer_sub_lang(demuxer_t *d, int id) +static char *demuxer_sub_lang(demuxer_t *d, int id) { struct stream_lang_req req; sh_sub_t *sh; @@ -1488,6 +1514,15 @@ char *demuxer_sub_lang(demuxer_t *d, int id) return NULL; } +char *demuxer_stream_lang(demuxer_t *d, struct sh_stream *s) +{ + switch (s->type) { + case STREAM_AUDIO: return demuxer_audio_lang(d, s->stream_index); + case STREAM_SUB: return demuxer_sub_lang(d, s->stream_index); + default: return NULL; + } +} + int demuxer_audio_track_by_lang_and_default(struct demuxer *d, char **langt) { int n = 0; @@ -1497,7 +1532,7 @@ int demuxer_audio_track_by_lang_and_default(struct demuxer *d, char **langt) for (int i = 0; i < MAX_A_STREAMS; i++) { struct sh_audio *sh = d->a_streams[i]; if (sh && (!lang || sh->lang && !strcmp(lang, sh->lang))) { - if (sh->default_track) + if (sh->gsh->default_track) return sh->aid; if (id < 0) id = sh->aid; @@ -1519,7 +1554,7 @@ int demuxer_sub_track_by_lang_and_default(struct demuxer *d, char **langt) for (int i = 0; i < MAX_S_STREAMS; i++) { struct sh_sub *sh = d->s_streams[i]; if (sh && (!lang || sh->lang && !strcmp(lang, sh->lang))) { - if (sh->default_track) + if (sh->gsh->default_track) return sh->sid; if (id < 0) id = sh->sid; diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index 285ac3a7af..9b63eb63ac 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -147,9 +147,10 @@ typedef struct demuxer_info { char *copyright; } demuxer_info_t; -#define MAX_A_STREAMS 256 -#define MAX_V_STREAMS 256 -#define MAX_S_STREAMS 256 +#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; @@ -244,9 +245,12 @@ typedef struct demuxer { struct demux_stream *sub; // dvd subtitle buffer/demuxer // stream headers: - struct sh_audio *a_streams[MAX_A_STREAMS]; - struct sh_video *v_streams[MAX_V_STREAMS]; - struct sh_sub *s_streams[MAX_S_STREAMS]; + 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; int num_titles; @@ -415,7 +419,6 @@ int demuxer_angles_count(struct demuxer *demuxer); int demuxer_audio_track_by_lang_and_default(struct demuxer *d, char **langt); int demuxer_sub_track_by_lang_and_default(struct demuxer *d, char **langt); -char *demuxer_audio_lang(demuxer_t *d, int id); -char *demuxer_sub_lang(demuxer_t *d, int id); +char *demuxer_stream_lang(demuxer_t *d, struct sh_stream *s); #endif /* MPLAYER_DEMUXER_H */ diff --git a/libmpdemux/stheader.h b/libmpdemux/stheader.h index c93bcf8185..c0bf9e4db0 100644 --- a/libmpdemux/stheader.h +++ b/libmpdemux/stheader.h @@ -26,23 +26,43 @@ struct MPOpts; struct demuxer; -enum STREAM_TYPE { +enum stream_type { STREAM_VIDEO = 1, STREAM_AUDIO, - STREAM_SUBTITLE, + STREAM_SUB, }; // Stream headers: -// id: the type specific id, e.g. aid or sid -// index: index into stream array (currently one array per type) -// demuxer_id: demuxer specific ID (-1 if unknown, otherwise >= 0) +struct sh_stream { + enum stream_type type; + // Index into demuxer->streams. + int index; + // The (possibly) type specific id, e.g. aid or sid. + int tid; + // Index into stream array (currently one array per type, e.g. a_streams). + int stream_index; + // Demuxer specific ID (-1 if unknown, otherwise >= 0). + int demuxer_id; + // Abomination. + struct sh_common *common_header; + // One of these is non-NULL, the others are NULL, depending on the stream + // type. + struct sh_audio *audio; + struct sh_video *video; + struct sh_sub *sub; + + char *title; + bool default_track; + + // shouldn't exist type of stuff + struct MPOpts *opts; +}; + #define SH_COMMON \ - enum STREAM_TYPE stream_type; \ int id; \ - int index; \ - int demuxer_id; \ + struct sh_stream *gsh; \ const char *demuxer_codecname; \ struct MPOpts *opts; \ struct demux_stream *ds; \ @@ -64,8 +84,6 @@ enum STREAM_TYPE { void *context; \ const char *codecname; \ char *lang; /* track language */ \ - char *title; /* track title */ \ - bool default_track; \ typedef struct sh_common { SH_COMMON |