core, timeline: don't keep separate stream field

The timeline code kept pairs of stream and demuxer references around.
The reference to the stream is redundant, because it can be accessed
through the demuxer.

Simplify the code by removing the redundant stream reference.

Also, set mpctx->stream to the current segment when using timeline.
Fix a small memory leak in tl_matroska.c introduced earlier.
This commit is contained in:
wm4 2012-08-19 17:58:58 +02:00
parent c5e2120e15
commit 83f68f725d
5 changed files with 41 additions and 60 deletions

View File

@ -64,15 +64,10 @@ enum exit_reason {
EXIT_ERROR
};
struct content_source {
struct stream *stream;
struct demuxer *demuxer;
};
struct timeline_part {
double start;
double source_start;
struct content_source *source;
struct demuxer *source;
};
struct chapter {
@ -104,7 +99,7 @@ typedef struct MPContext {
// Return code to use with PT_QUIT
int quit_player_rc;
struct content_source *sources;
struct demuxer **sources;
int num_sources;
struct timeline_part *timeline;
int num_timeline_parts;

View File

@ -564,11 +564,12 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_DEMUXER) {
mpctx->initialized_flags &= ~INITIALIZED_DEMUXER;
if (mpctx->num_sources) {
mpctx->demuxer = mpctx->sources[0].demuxer;
mpctx->demuxer = mpctx->sources[0];
for (int i = 1; i < mpctx->num_sources; i++) {
uninit_subs(mpctx->sources[i].demuxer);
free_stream(mpctx->sources[i].stream);
free_demuxer(mpctx->sources[i].demuxer);
struct demuxer *demuxer = mpctx->sources[i];
uninit_subs(demuxer);
free_stream(demuxer->stream);
free_demuxer(demuxer);
}
}
talloc_free(mpctx->sources);
@ -2455,12 +2456,13 @@ static bool timeline_set_part(struct MPContext *mpctx, int i)
mpctx->stop_play = AT_END_OF_FILE; // let audio uninit drain data
uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts.fixed_vo ? 0 : INITIALIZED_VO) | (mpctx->opts.gapless_audio ? 0 : INITIALIZED_AO) | INITIALIZED_ACODEC | INITIALIZED_SUB);
mpctx->stop_play = orig_stop_play;
mpctx->demuxer = n->source->demuxer;
mpctx->demuxer = n->source;
mpctx->d_video = mpctx->demuxer->video;
mpctx->d_audio = mpctx->demuxer->audio;
mpctx->d_sub = mpctx->demuxer->sub;
mpctx->sh_video = mpctx->d_video->sh;
mpctx->sh_audio = mpctx->d_audio->sh;
mpctx->stream = mpctx->demuxer->stream;
return true;
}
@ -3250,13 +3252,13 @@ static void print_timeline(struct MPContext *mpctx)
mp_msg(MSGT_CPLAYER, MSGL_V, "Source files:\n");
for (int i = 0; i < mpctx->num_sources; i++)
mp_msg(MSGT_CPLAYER, MSGL_V, "%d: %s\n", i,
mpctx->sources[i].demuxer->filename);
mpctx->sources[i]->filename);
mp_msg(MSGT_CPLAYER, MSGL_V, "Timeline parts: (number, start, "
"source_start, source):\n");
for (int i = 0; i < part_count; i++) {
struct timeline_part *p = mpctx->timeline + i;
mp_msg(MSGT_CPLAYER, MSGL_V, "%3d %9.3f %9.3f %3td\n", i, p->start,
p->source_start, p->source - mpctx->sources);
mp_msg(MSGT_CPLAYER, MSGL_V, "%3d %9.3f %9.3f %p/%s\n", i, p->start,
p->source_start, p->source, p->source->filename);
}
mp_msg(MSGT_CPLAYER, MSGL_V, "END %9.3f\n",
mpctx->timeline[part_count].start);
@ -3268,7 +3270,7 @@ static void add_subtitle_fonts_from_sources(struct MPContext *mpctx)
#ifdef CONFIG_ASS
if (mpctx->opts.ass_enabled && mpctx->ass_library) {
for (int j = 0; j < mpctx->num_sources; j++) {
struct demuxer *d = mpctx->sources[j].demuxer;
struct demuxer *d = mpctx->sources[j];
for (int i = 0; i < d->num_attachments; i++) {
struct demux_attachment *att = d->attachments + i;
if (mpctx->opts.use_embedded_fonts && attachment_is_font(att))
@ -3452,17 +3454,13 @@ goto_enable_cache:
if (mpctx->timeline) {
mpctx->timeline_part = 0;
mpctx->demuxer = mpctx->timeline[0].source->demuxer;
mpctx->demuxer = mpctx->timeline[0].source;
}
print_timeline(mpctx);
if (!mpctx->sources) {
mpctx->sources = talloc_ptrtype(NULL, mpctx->sources);
*mpctx->sources = (struct content_source){
.stream = mpctx->stream,
.demuxer = mpctx->demuxer
};
mpctx->num_sources = 1;
if (!mpctx->num_sources) {
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources,
mpctx->demuxer);
}
mpctx->initialized_flags |= INITIALIZED_DEMUXER;
@ -3475,7 +3473,7 @@ goto_enable_cache:
// select audio stream
for (int i = 0; i < mpctx->num_sources; i++)
select_audio(mpctx->sources[i].demuxer->audio->demuxer, opts->audio_id,
select_audio(mpctx->sources[i]->audio->demuxer, opts->audio_id,
opts->audio_lang);
mpctx->sh_audio = mpctx->d_audio->sh;

View File

@ -173,16 +173,9 @@ bool mp_probe_cue(struct bstr data)
return valid;
}
static void add_source(struct MPContext *mpctx, struct stream *s,
struct demuxer *d)
static void add_source(struct MPContext *mpctx, struct demuxer *d)
{
mpctx->num_sources++;
mpctx->sources = talloc_realloc(NULL, mpctx->sources, struct content_source,
mpctx->num_sources);
mpctx->sources[mpctx->num_sources - 1] = (struct content_source) {
.stream = s,
.demuxer = d,
};
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, d);
}
static bool try_open(struct MPContext *mpctx, char *filename)
@ -219,7 +212,7 @@ static bool try_open(struct MPContext *mpctx, char *filename)
filename);
}
if (d) {
add_source(mpctx, s, d);
add_source(mpctx, d);
return true;
}
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Could not open source '%s'!\n", filename);
@ -281,9 +274,8 @@ out:
}
// return length of the source in seconds, or -1 if unknown
static double source_get_length(struct content_source *source)
static double source_get_length(struct demuxer *demuxer)
{
struct demuxer *demuxer = source->demuxer;
double get_time_ans;
// <= 0 means DEMUXER_CTRL_NOTIMPL or DEMUXER_CTRL_DONTKNOW
if (demuxer && demux_control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH,
@ -373,7 +365,7 @@ void build_cue_timeline(struct MPContext *mpctx)
}
}
add_source(mpctx, mpctx->stream, mpctx->demuxer);
add_source(mpctx, mpctx->demuxer);
for (size_t i = 0; i < file_count; i++) {
if (!open_source(mpctx, files[i]))
@ -386,7 +378,7 @@ void build_cue_timeline(struct MPContext *mpctx)
track_count);
double starttime = 0;
for (int i = 0; i < track_count; i++) {
struct content_source *source = mpctx->sources + 1 + tracks[i].source;
struct demuxer *source = mpctx->sources[1 + tracks[i].source];
double duration;
if (i + 1 < track_count && tracks[i].source == tracks[i + 1].source) {
duration = tracks[i + 1].start - tracks[i].start;

View File

@ -346,11 +346,10 @@ void build_edl_timeline(struct MPContext *mpctx)
// Open source files
struct content_source *sources = talloc_array_ptrtype(NULL, sources,
num_sources + 1);
struct demuxer **sources = talloc_array_ptrtype(NULL, sources,
num_sources + 1);
mpctx->sources = sources;
sources[0].stream = mpctx->stream;
sources[0].demuxer = mpctx->demuxer;
sources[0] = mpctx->demuxer;
mpctx->num_sources = 1;
for (int i = 0; i < num_sources; i++) {
@ -371,8 +370,7 @@ void build_edl_timeline(struct MPContext *mpctx)
"file on line %d!\n", edl_ids[i].lineno);
goto out;
}
sources[mpctx->num_sources].stream = s;
sources[mpctx->num_sources].demuxer = d;
sources[mpctx->num_sources] = d;
mpctx->num_sources++;
}
@ -385,7 +383,7 @@ void build_edl_timeline(struct MPContext *mpctx)
timeline[i].start = starttime / 1e9;
starttime += parts[i].duration;
timeline[i].source_start = parts[i].src.start / 1e9;
timeline[i].source = sources + parts[i].id + 1;
timeline[i].source = sources[parts[i].id + 1];
}
if (parts[num_parts - 1].id != -1) {
timeline[num_parts].start = starttime / 1e9;

View File

@ -96,7 +96,7 @@ static char **find_files(const char *original_file, const char *suffix)
continue;
off_t size = statbuf.st_size;
entries = talloc_realloc(entries, entries, struct find_entry,
entries = talloc_realloc(tmpmem, entries, struct find_entry,
num_results + 1);
entries[num_results] = (struct find_entry) { name, matchlen, size };
num_results++;
@ -113,7 +113,7 @@ static char **find_files(const char *original_file, const char *suffix)
}
static int find_ordered_chapter_sources(struct MPContext *mpctx,
struct content_source *sources,
struct demuxer **sources,
int num_sources,
unsigned char uid_map[][16])
{
@ -122,7 +122,7 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
if (num_sources > 1) {
mp_msg(MSGT_CPLAYER, MSGL_INFO, "This file references data from "
"other sources.\n");
if (mpctx->stream->type != STREAMTYPE_FILE) {
if (mpctx->demuxer->stream->type != STREAMTYPE_FILE) {
mp_msg(MSGT_CPLAYER, MSGL_WARN, "Playback source is not a "
"normal disk file. Will not search for related files.\n");
} else {
@ -152,13 +152,12 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
}
if (d->file_format == DEMUXER_TYPE_MATROSKA) {
for (int i = 1; i < num_sources; i++) {
if (sources[i].demuxer)
if (sources[i])
continue;
if (!memcmp(uid_map[i], d->matroska_data.segment_uid, 16)) {
mp_msg(MSGT_CPLAYER, MSGL_INFO,"Match for source %d: %s\n",
i, d->filename);
sources[i].stream = s;
sources[i].demuxer = d;
sources[i] = d;
num_left--;
goto match;
}
@ -175,7 +174,7 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Failed to find ordered chapter part!\n"
"There will be parts MISSING from the video!\n");
for (int i = 1, j = 1; i < num_sources; i++)
if (sources[i].demuxer) {
if (sources[i]) {
sources[j] = sources[i];
memcpy(uid_map[j], uid_map[i], 16);
j++;
@ -202,10 +201,9 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx)
// +1 because sources/uid_map[0] is original file even if all chapters
// actually use other sources and need separate entries
struct content_source *sources = talloc_array_ptrtype(NULL, sources,
m->num_ordered_chapters+1);
sources[0].stream = mpctx->stream;
sources[0].demuxer = mpctx->demuxer;
struct demuxer **sources = talloc_array_ptrtype(NULL, sources,
m->num_ordered_chapters+1);
sources[0] = mpctx->demuxer;
unsigned char (*uid_map)[16] = talloc_array_ptrtype(NULL, uid_map,
m->num_ordered_chapters + 1);
int num_sources = 1;
@ -220,7 +218,7 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx)
if (!memcmp(c->segment_uid, uid_map[j], 16))
goto found1;
memcpy(uid_map[num_sources], c->segment_uid, 16);
sources[num_sources] = (struct content_source){};
sources[num_sources] = NULL;
num_sources++;
found1:
;
@ -262,8 +260,8 @@ void build_ordered_chapter_timeline(struct MPContext *mpctx)
int64_t join_diff = c->start - starttime - prev_part_offset;
if (part_count == 0
|| FFABS(join_diff) > opts->chapter_merge_threshold * 1000000
|| sources + j != timeline[part_count - 1].source) {
timeline[part_count].source = sources + j;
|| sources[j] != timeline[part_count - 1].source) {
timeline[part_count].source = sources[j];
timeline[part_count].start = starttime / 1e9;
timeline[part_count].source_start = c->start / 1e9;
prev_part_offset = c->start - starttime;