mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
d722f8fe61
commit
9c02ae7e95
99
command.c
99
command.c
|
@ -944,13 +944,13 @@ static int mp_property_audio(m_option_t *prop, int action, void *arg,
|
|||
if (!sh || current_id < 0)
|
||||
*(char **) arg = talloc_strdup(NULL, mp_gtext("disabled"));
|
||||
else {
|
||||
char *lang = demuxer_audio_lang(mpctx->demuxer, current_id);
|
||||
char *lang = demuxer_stream_lang(mpctx->demuxer, sh->gsh);
|
||||
if (!lang)
|
||||
lang = talloc_strdup(NULL, mp_gtext("unknown"));
|
||||
|
||||
if (sh->title)
|
||||
if (sh->gsh->title)
|
||||
*(char **)arg = talloc_asprintf(NULL, "(%d) %s (\"%s\")",
|
||||
current_id, lang, sh->title);
|
||||
current_id, lang, sh->gsh->title);
|
||||
else
|
||||
*(char **)arg = talloc_asprintf(NULL, "(%d) %s", current_id,
|
||||
lang);
|
||||
|
@ -1566,8 +1566,9 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
|
|||
vobsub_id, language ? language : mp_gtext("unknown"));
|
||||
return M_PROPERTY_OK;
|
||||
}
|
||||
if (opts->sub_id >= 0) {
|
||||
char *lang = demuxer_sub_lang(mpctx->demuxer, opts->sub_id);
|
||||
if (opts->sub_id >= 0 && mpctx->d_sub && mpctx->d_sub->sh) {
|
||||
struct sh_stream *sh = mpctx->d_sub->sh;
|
||||
char *lang = demuxer_stream_lang(mpctx->demuxer, sh);
|
||||
if (!lang)
|
||||
lang = talloc_strdup(NULL, mp_gtext("unknown"));
|
||||
*(char **) arg = talloc_asprintf(NULL, "(%d) %s", opts->sub_id,
|
||||
|
@ -2641,79 +2642,47 @@ static void show_chapters_on_osd(MPContext *mpctx)
|
|||
static void show_tracks_on_osd(MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
char *res = NULL;
|
||||
const char *IND = "";
|
||||
int n;
|
||||
int cnt = 0;
|
||||
struct sh_audio *cur_a;
|
||||
struct sh_sub *cur_s;
|
||||
demux_stream_t *d_sub;
|
||||
demuxer_t *demuxer = mpctx->demuxer;
|
||||
char *res = NULL;
|
||||
|
||||
if (!demuxer)
|
||||
return;
|
||||
|
||||
cur_a = mpctx->sh_audio;
|
||||
d_sub = mpctx->d_sub;
|
||||
cur_s = d_sub && opts->sub_id >= 0 ? d_sub->sh : NULL;
|
||||
struct sh_stream *cur_a = mpctx->sh_audio ? mpctx->sh_audio->gsh : NULL;
|
||||
struct sh_stream *cur_s = NULL;
|
||||
if (opts->sub_id >= 0 && mpctx->d_sub && mpctx->d_sub->sh)
|
||||
cur_s = ((struct sh_sub *)mpctx->d_sub->sh)->gsh;
|
||||
|
||||
for (n = 0; n < MAX_V_STREAMS; n++) {
|
||||
struct sh_video *v = demuxer->v_streams[n];
|
||||
if (v) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt > 1)
|
||||
res = talloc_asprintf_append(res, "(Warning: more than one video stream.)\n");
|
||||
int v_count = 0;
|
||||
enum stream_type t = STREAM_AUDIO;
|
||||
|
||||
#define STD_TRACK_HDR(st, id, lang) \
|
||||
res = talloc_asprintf_append(res, "%s(%d) ", IND, st->id); \
|
||||
if (st->title) { \
|
||||
res = talloc_asprintf_append(res, "'%s' ", st->title); \
|
||||
} \
|
||||
if (lang) { \
|
||||
res = talloc_asprintf_append(res, "(%s) ", lang); \
|
||||
for (int n = 0; n < demuxer->num_streams; n++) {
|
||||
struct sh_stream *sh = demuxer->streams[n];
|
||||
if (sh->type == STREAM_VIDEO) {
|
||||
v_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (n = 0; n < MAX_A_STREAMS; n++) {
|
||||
struct sh_audio *a = demuxer->a_streams[n];
|
||||
if (a) {
|
||||
cnt++;
|
||||
if (a == cur_a)
|
||||
if (t != sh->type)
|
||||
res = talloc_asprintf_append(res, "\n");
|
||||
bool selected = sh == cur_a || sh == cur_s;
|
||||
res = talloc_asprintf_append(res, "%s: ",
|
||||
sh->type == STREAM_AUDIO ? "Audio" : "Sub");
|
||||
if (selected)
|
||||
res = talloc_asprintf_append(res, "> ");
|
||||
char *lang = demuxer_audio_lang(mpctx->demuxer, a->index);
|
||||
STD_TRACK_HDR(a, aid, lang)
|
||||
if (a == cur_a)
|
||||
res = talloc_asprintf_append(res, "(%d) ", sh->tid);
|
||||
if (sh->title)
|
||||
res = talloc_asprintf_append(res, "'%s' ", sh->title);
|
||||
char *lang = demuxer_stream_lang(mpctx->demuxer, sh);
|
||||
if (lang)
|
||||
res = talloc_asprintf_append(res, "(%s) ", lang);
|
||||
if (selected)
|
||||
res = talloc_asprintf_append(res, "<");
|
||||
res = talloc_asprintf_append(res, "\n");
|
||||
}
|
||||
t = sh->type;
|
||||
}
|
||||
|
||||
res = talloc_asprintf_append(res, "\n");
|
||||
|
||||
for (n = 0; n < MAX_S_STREAMS; n++) {
|
||||
struct sh_sub *s = demuxer->s_streams[n];
|
||||
if (s) {
|
||||
cnt++;
|
||||
if (s == cur_s)
|
||||
res = talloc_asprintf_append(res, "> ");
|
||||
char *lang = demuxer_sub_lang(mpctx->demuxer, s->index);
|
||||
STD_TRACK_HDR(s, sid, lang)
|
||||
char *type = "?";
|
||||
switch (s->type) {
|
||||
case 't': type = "SRT"; break;
|
||||
case 'v': type = "VOB"; break;
|
||||
case 'a': type = NULL; break; //"ASS/SSA";
|
||||
}
|
||||
if (type)
|
||||
res = talloc_asprintf_append(res, " [%s]", type);
|
||||
if (s == cur_s)
|
||||
res = talloc_asprintf_append(res, "<");
|
||||
res = talloc_asprintf_append(res, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
#undef STD_TRACK_HDR
|
||||
if (v_count > 1)
|
||||
res = talloc_asprintf_append(res, "\n(Warning: more than one video stream.)\n");
|
||||
|
||||
set_osd_msg(OSD_MSG_TEXT, 1, opts->osd_duration, "%s", res);
|
||||
talloc_free(res);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
48
mplayer.c
48
mplayer.c
|
@ -383,29 +383,25 @@ char *get_metadata(struct MPContext *mpctx, metadata_t type)
|
|||
return talloc_strdup(NULL, "");
|
||||
}
|
||||
|
||||
static void print_stream(struct MPContext *mpctx, sh_common_t *s)
|
||||
static void print_stream(struct MPContext *mpctx, struct sh_stream *s)
|
||||
{
|
||||
const char *tname = "?";
|
||||
const char *selopt = "?";
|
||||
const char *langopt = "?";
|
||||
switch (s->stream_type) {
|
||||
switch (s->type) {
|
||||
case STREAM_VIDEO:
|
||||
tname = "video"; selopt = "vid"; langopt = "vlang";
|
||||
break;
|
||||
case STREAM_AUDIO:
|
||||
tname = "audio"; selopt = "aid"; langopt = "alang";
|
||||
break;
|
||||
case STREAM_SUBTITLE:
|
||||
case STREAM_SUB:
|
||||
tname = "subtitle"; selopt = "sid"; langopt = "slang";
|
||||
break;
|
||||
}
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "[stream] ID %d: %s", s->demuxer_id, tname);
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, " --%s=%d", selopt, s->id);
|
||||
char *lang = NULL;
|
||||
if (s->stream_type == STREAM_AUDIO)
|
||||
lang = demuxer_audio_lang(mpctx->demuxer, s->index);
|
||||
if (s->stream_type == STREAM_SUBTITLE)
|
||||
lang = demuxer_sub_lang(mpctx->demuxer, s->index);
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, " --%s=%d", selopt, s->tid);
|
||||
char *lang = demuxer_stream_lang(mpctx->demuxer, s);
|
||||
if (lang)
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, " --%s=%s", langopt, lang);
|
||||
if (s->default_track)
|
||||
|
@ -413,10 +409,11 @@ static void print_stream(struct MPContext *mpctx, sh_common_t *s)
|
|||
if (s->title)
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, " '%s'", s->title);
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, " (");
|
||||
if (s->format) {
|
||||
if (s->common_header->format) {
|
||||
int format = s->common_header->format;
|
||||
// not sure about endian crap
|
||||
char name[sizeof(s->format) + 1] = {0};
|
||||
memcpy(name, &s->format, sizeof(s->format));
|
||||
char name[sizeof(format) + 1] = {0};
|
||||
memcpy(name, &format, sizeof(format));
|
||||
bool ok = true;
|
||||
for (int n = 0; name[n]; n++) {
|
||||
if ((name[n] < 32 || name[n] >= 128) && name[n] != 0)
|
||||
|
@ -425,9 +422,9 @@ static void print_stream(struct MPContext *mpctx, sh_common_t *s)
|
|||
if (ok && strlen(name) > 0) {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s", name);
|
||||
} else {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "%#x", s->format);
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "%#x", format);
|
||||
}
|
||||
} else if (s->stream_type == STREAM_SUBTITLE) {
|
||||
} else if (s->type == STREAM_SUB) {
|
||||
char t = ((sh_sub_t*)s)->type;
|
||||
const char *name = NULL;
|
||||
switch (t) {
|
||||
|
@ -439,8 +436,8 @@ static void print_stream(struct MPContext *mpctx, sh_common_t *s)
|
|||
name = (char[2]){t, '\0'};
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s", name);
|
||||
}
|
||||
if (s->demuxer_codecname)
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "/%s", s->demuxer_codecname);
|
||||
if (s->common_header->demuxer_codecname)
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "/%s", s->common_header->demuxer_codecname);
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, ")");
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "\n");
|
||||
}
|
||||
|
@ -520,23 +517,8 @@ static void print_file_properties(struct MPContext *mpctx, const char *filename)
|
|||
}
|
||||
}
|
||||
}
|
||||
// xxx I think this might be invalid C
|
||||
// should resolve the crapmess in stheader.h
|
||||
for (int n = 0; n < MAX_V_STREAMS; n++) {
|
||||
sh_common_t *s = (sh_common_t*)mpctx->demuxer->v_streams[n];
|
||||
if (s)
|
||||
print_stream(mpctx, s);
|
||||
}
|
||||
for (int n = 0; n < MAX_A_STREAMS; n++) {
|
||||
sh_common_t *s = (sh_common_t*)mpctx->demuxer->a_streams[n];
|
||||
if (s)
|
||||
print_stream(mpctx, s);
|
||||
}
|
||||
for (int n = 0; n < MAX_S_STREAMS; n++) {
|
||||
sh_common_t *s = (sh_common_t*)mpctx->demuxer->s_streams[n];
|
||||
if (s)
|
||||
print_stream(mpctx, s);
|
||||
}
|
||||
for (int n = 0; n < mpctx->demuxer->num_streams; n++)
|
||||
print_stream(mpctx, mpctx->demuxer->streams[n]);
|
||||
}
|
||||
|
||||
/// step size of mixer changes
|
||||
|
|
Loading…
Reference in New Issue