summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-08-03 12:24:55 +0200
committerwm4 <wm4@nowhere>2012-08-03 13:25:41 +0200
commit9c02ae7e9510897826334ddf79fa3a0cf65a78a2 (patch)
tree813c9a2b757b2531d3fd29cf483ac1ba89093f7f /libmpdemux
parentd722f8fe61296e5b277ed94be055bb9ef1c99e19 (diff)
downloadmpv-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.c16
-rw-r--r--libmpdemux/demux_mkv.c16
-rw-r--r--libmpdemux/demuxer.c101
-rw-r--r--libmpdemux/demuxer.h19
-rw-r--r--libmpdemux/stheader.h38
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