summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2011-01-24 00:29:01 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2011-01-26 20:39:04 +0200
commit304cafd31dfaeee853e138a460b7ba82e65ed420 (patch)
tree8c5945cccb2dfc34424f56f941120e4375108354
parenta248c2c7a137517061e6271f22b84d43bcd7191d (diff)
downloadmpv-304cafd31dfaeee853e138a460b7ba82e65ed420.tar.bz2
mpv-304cafd31dfaeee853e138a460b7ba82e65ed420.tar.xz
demux_mkv, chapters: change millisecond arithmetic to ns
demux_mkv kept various integer timestamps in millisecond units. Matroska timestamp arithmetic is however specified in nanoseconds (even though files typically use 1 ms precision), and using ms units instead of that only made things more complex. Based on the demux_mkv example the general demuxer-level chapter structure also used ms units. Change the demux_mkv arithmetic and demuxer chapter structures to use nanoseconds instead. This also fixes a seeking problem in demux_mkv with files using a TimecodeScale other than the usual 1000000 (confusion between ms and TimecodeScale*ns units).
-rw-r--r--libmpdemux/demux_lavf.c4
-rw-r--r--libmpdemux/demux_mkv.c58
-rw-r--r--libmpdemux/demuxer.c12
-rw-r--r--mplayer.c13
4 files changed, 42 insertions, 45 deletions
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c
index 03ffa17c43..c84a17e4e3 100644
--- a/libmpdemux/demux_lavf.c
+++ b/libmpdemux/demux_lavf.c
@@ -588,8 +588,8 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
for(i=0; i < avfc->nb_chapters; i++) {
AVChapter *c = avfc->chapters[i];
- uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
- uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
+ uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000000000});
+ uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000000000});
t = av_metadata_get(c->metadata, "title", NULL, 0);
demuxer_add_chapter(demuxer, t ? BSTR(t->value) : BSTR(NULL), start, end);
}
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index b75f07fd67..499c664360 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -184,7 +184,7 @@ typedef struct mkv_demuxer {
} *cluster_positions;
int num_cluster_pos;
- int64_t skip_to_timecode;
+ uint64_t skip_to_timecode;
int v_skip_to_keyframe, a_skip_to_keyframe;
int num_audio_tracks;
@@ -786,8 +786,8 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
if (!ca->n_chapter_time_start)
mp_msg(MSGT_DEMUX, warn_level,
"[mkv] Chapter lacks start time\n");
- chapter.start = ca->chapter_time_start / 1000000;
- chapter.end = ca->chapter_time_end / 1000000;
+ chapter.start = ca->chapter_time_start;
+ chapter.end = ca->chapter_time_end;
if (ca->n_chapter_display) {
if (ca->n_chapter_display > 1)
@@ -824,14 +824,14 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
mp_msg(MSGT_DEMUX, MSGL_V,
"[mkv] Chapter %u from %02d:%02d:%02d.%03d "
"to %02d:%02d:%02d.%03d, %.*s\n", i,
- (int) (chapter.start / 60 / 60 / 1000),
- (int) ((chapter.start / 60 / 1000) % 60),
- (int) ((chapter.start / 1000) % 60),
- (int) (chapter.start % 1000),
- (int) (chapter.end / 60 / 60 / 1000),
- (int) ((chapter.end / 60 / 1000) % 60),
- (int) ((chapter.end / 1000) % 60),
- (int) (chapter.end % 1000),
+ (int) (chapter.start / 60 / 60 / 1000000000),
+ (int) ((chapter.start / 60 / 1000000000) % 60),
+ (int) ((chapter.start / 1000000000) % 60),
+ (int) (chapter.start % 1000000000),
+ (int) (chapter.end / 60 / 60 / 1000000000),
+ (int) ((chapter.end / 60 / 1000000000) % 60),
+ (int) ((chapter.end / 1000000000) % 60),
+ (int) (chapter.end % 1000000000),
BSTR_P(name));
if (idx == selected_edition){
@@ -1883,13 +1883,13 @@ static void handle_subtitles(demuxer_t *demuxer, mkv_track_t *track,
sub_utf8 = 1;
dp = new_demux_packet(size);
memcpy(dp->buffer, block, size);
- dp->pts = timecode / 1000.0;
- dp->duration = block_duration / 1000.0;
+ dp->pts = timecode / 1e9;
+ dp->duration = block_duration / 1e9;
ds_add_packet(demuxer->sub, dp);
}
static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
- uint8_t *buffer, uint32_t size, int block_bref)
+ uint8_t *buffer, uint32_t size, int64_t block_bref)
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
demux_packet_t *dp;
@@ -1915,7 +1915,7 @@ static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
}
static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
- uint8_t *buffer, uint32_t size, int block_bref)
+ uint8_t *buffer, uint32_t size, int64_t block_bref)
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
int sps = track->sub_packet_size;
@@ -2028,7 +2028,7 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
mkv_track_t *track = NULL;
demux_stream_t *ds = NULL;
uint64_t old_length;
- int64_t tc;
+ uint64_t tc;
uint32_t *lace_size;
uint8_t laces, flags;
int i, num, tmp, use_this_block = 1;
@@ -2048,10 +2048,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
return 0;
block += old_length - length;
- tc = (time * mkv_d->tc_scale + mkv_d->cluster_tc) / 1000000.0 + 0.5;
- if (tc < 0)
- tc = 0;
- current_pts = tc / 1000.0;
+ tc = time * mkv_d->tc_scale + mkv_d->cluster_tc;
+ current_pts = tc / 1e9;
for (i = 0; i < mkv_d->num_tracks; i++)
if (mkv_d->tracks[i]->tnum == num) {
@@ -2080,7 +2078,7 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
sh_audio_t *sh = (sh_audio_t *) ds->sh;
if (block_duration != 0) {
- sh->i_bps = length * 1000 / block_duration;
+ sh->i_bps = length * 1e9 / block_duration;
track->fix_i_bps = 0;
} else if (track->qt_last_a_pts == 0.0)
track->qt_last_a_pts = current_pts;
@@ -2186,8 +2184,7 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
free(block);
return 0;
}
- block_duration =
- block_duration * mkv_d->tc_scale / 1000000.0 + 0.5;
+ block_duration *= mkv_d->tc_scale;
break;
case MATROSKA_ID_BLOCK:
@@ -2387,7 +2384,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
* target time after the last entry - then still seek to the first/last
* entry if that's further in the direction wanted than mkv_d->last_pts.
*/
- int64_t min_diff = target_timecode - mkv_d->last_pts * 1000;
+ int64_t min_diff = target_timecode - (int64_t)(mkv_d->last_pts * 1e9 + 0.5);
if (flags & SEEK_BACKWARD)
min_diff = -min_diff;
min_diff = FFMAX(min_diff, 1);
@@ -2395,8 +2392,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
if (seek_id < 0 || mkv_d->indexes[i].tnum == seek_id) {
int64_t diff =
target_timecode -
- (int64_t) (mkv_d->indexes[i].timecode *
- mkv_d->tc_scale / 1000000.0 + 0.5);
+ (int64_t) (mkv_d->indexes[i].timecode * mkv_d->tc_scale);
if (flags & SEEK_BACKWARD)
diff = -diff;
if (diff <= 0) {
@@ -2442,9 +2438,8 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
if (!(flags & SEEK_ABSOLUTE)) /* relative seek */
rel_seek_secs += mkv_d->last_pts;
- int64_t target_timecode = rel_seek_secs * 1000.0;
- if (target_timecode < 0)
- target_timecode = 0;
+ rel_seek_secs = FFMAX(rel_seek_secs, 0);
+ int64_t target_timecode = rel_seek_secs * 1e9 + 0.5;
if (mkv_d->indexes == NULL) { /* no index was found */
if (seek_creating_index(demuxer, rel_seek_secs, flags) < 0)
@@ -2462,7 +2457,8 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
if (flags & SEEK_FORWARD)
mkv_d->skip_to_timecode = target_timecode;
else
- mkv_d->skip_to_timecode = index ? index->timecode : 0;
+ mkv_d->skip_to_timecode = index ? index->timecode * mkv_d->tc_scale
+ : 0;
mkv_d->a_skip_to_keyframe = 1;
demux_mkv_fill_buffer(demuxer, NULL);
@@ -2496,7 +2492,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
if (demuxer->video->id >= 0)
mkv_d->v_skip_to_keyframe = 1;
- mkv_d->skip_to_timecode = index->timecode;
+ mkv_d->skip_to_timecode = index->timecode * mkv_d->tc_scale;
mkv_d->a_skip_to_keyframe = 1;
demux_mkv_fill_buffer(demuxer, NULL);
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index eb548d4614..098c631631 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -1316,9 +1316,9 @@ int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
talloc_strdup(demuxer->chapters, mp_gtext("unknown"));
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_ID=%d\n", demuxer->num_chapters);
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_START=%"PRIu64"\n", demuxer->num_chapters, start);
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_START=%"PRIu64"\n", demuxer->num_chapters, start / 1000000);
if (end)
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_END=%"PRIu64"\n", demuxer->num_chapters, end);
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_END=%"PRIu64"\n", demuxer->num_chapters, end / 1000000);
if (name.start)
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_NAME=%.*s\n", demuxer->num_chapters, BSTR_P(name));
@@ -1371,7 +1371,7 @@ int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts,
if (chapter < 0)
chapter = 0;
- *seek_pts = demuxer->chapters[chapter].start / 1000.0;
+ *seek_pts = demuxer->chapters[chapter].start / 1e9;
if (chapter_name)
*chapter_name = talloc_strdup(NULL, demuxer->chapters[chapter].name);
@@ -1388,7 +1388,7 @@ int demuxer_get_current_chapter(demuxer_t *demuxer, double time_now)
&chapter) == STREAM_UNSUPPORTED)
chapter = -2;
} else {
- uint64_t now = time_now * 1000 + 0.5;
+ uint64_t now = time_now * 1e9 + 0.5;
for (chapter = demuxer->num_chapters - 1; chapter >= 0; --chapter) {
if (demuxer->chapters[chapter].start <= now)
break;
@@ -1431,8 +1431,8 @@ float demuxer_chapter_time(demuxer_t *demuxer, int chapter, float *end)
if (demuxer->num_chapters && demuxer->chapters && chapter >= 0
&& chapter < demuxer->num_chapters) {
if (end)
- *end = demuxer->chapters[chapter].end / 1000.0;
- return demuxer->chapters[chapter].start / 1000.0;
+ *end = demuxer->chapters[chapter].end / 1e9;
+ return demuxer->chapters[chapter].start / 1e9;
}
return -1.0;
}
diff --git a/mplayer.c b/mplayer.c
index a72b014349..1d8b74892c 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3734,11 +3734,12 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
* specify chapter end times that are one frame too early;
* we don't want to try seeking over a one frame gap. */
int64_t join_diff = c->start - starttime - prev_part_offset;
- if (part_count == 0 || FFABS(join_diff) > opts->chapter_merge_threshold
+ 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;
- timeline[part_count].start = starttime / 1000.;
- timeline[part_count].source_start = c->start / 1000.;
+ timeline[part_count].start = starttime / 1e9;
+ timeline[part_count].source_start = c->start / 1e9;
prev_part_offset = c->start - starttime;
part_count++;
} else if (part_count > 0 && join_diff) {
@@ -3748,12 +3749,12 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
"offset %d ms.\n", i, (int) join_diff);
starttime += join_diff;
}
- chapters[num_chapters].start = starttime / 1000.;
+ chapters[num_chapters].start = starttime / 1e9;
chapters[num_chapters].name = talloc_strdup(chapters, c->name);
starttime += c->end - c->start;
num_chapters++;
}
- timeline[part_count].start = starttime / 1000.;
+ timeline[part_count].start = starttime / 1e9;
if (!part_count) {
// None of the parts come from the file itself???
@@ -3768,7 +3769,7 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
timeline[part_count].start);
if (missing_time)
mp_msg(MSGT_CPLAYER, MSGL_ERR, "There are %.3f seconds missing "
- "from the timeline!\n", missing_time / 1000.);
+ "from the timeline!\n", missing_time / 1e9);
mp_msg(MSGT_CPLAYER, MSGL_V, "Source files:\n");
for (int i = 0; i < num_sources; i++)
mp_msg(MSGT_CPLAYER, MSGL_V, "%d: %s\n", i,