Index: mplayer.c =================================================================== --- mplayer.c (revision 18722) +++ mplayer.c (working copy) @@ -922,6 +922,7 @@ } } + fprintf(stderr, "PTS: %f\n", sh_video->pts); // Video time if (sh_video) saddf(line, &pos, width, "V:%6.1f ", sh_video->pts); Index: libmpdemux/demux_mov.c =================================================================== --- libmpdemux/demux_mov.c (revision 18722) +++ libmpdemux/demux_mov.c (working copy) @@ -86,6 +86,11 @@ } mov_durmap_t; typedef struct { + unsigned int count; + unsigned int offset; +} mov_cts_t; + +typedef struct { unsigned int dur; unsigned int pos; int speed; @@ -141,6 +146,8 @@ int editlist_size; mov_editlist_t* editlist; int editlist_pos; + int cts_size; + mov_cts_t* cts; // void* desc; // image/sound/etc description (pointer to ImageDescription etc) } mov_track_t; @@ -304,6 +311,22 @@ #define MOV_FOURCC(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d)) +static inline unsigned int get_cts_offset(mov_track_t *trak, unsigned int frame) +{ + unsigned int ctsOffset = 0; + unsigned int cpos = 0; + int i; + + for (i=1; i < trak->cts_size; ++i) { + cpos += trak->cts[i].count; + if (frame < cpos) { + return trak->cts[i].offset; + } + } + + return 0; +} + static int mov_check_file(demuxer_t* demuxer){ int flags=0; int no=0; @@ -1663,6 +1686,21 @@ pts, trak->length); break; } + case MOV_FOURCC('c','t','t','s'): { + int temp = stream_read_dword(demuxer->stream); + int count = stream_read_dword(demuxer->stream); + int i; + mp_msg(MSGT_DEMUX, MSGL_V, + "MOV: %*sComposition timestamps table! (%d blocks)\n", level, "", + count); + trak->cts = calloc(count, sizeof(mov_cts_t)); + trak->cts_size = count; + for (i = 0; i < count; i++) { + trak->cts[i].count = stream_read_dword(demuxer->stream); + trak->cts[i].offset = stream_read_dword(demuxer->stream); + } + break; + } case MOV_FOURCC('s','t','s','c'): { int temp = stream_read_dword(demuxer->stream); int len = stream_read_dword(demuxer->stream); @@ -1974,7 +2012,8 @@ // read chunk: if(trak->pos>=trak->chunks_size) return 0; // EOF stream_seek(demuxer->stream,trak->chunks[trak->pos].pos); - pts=(float)(trak->chunks[trak->pos].sample*trak->duration)/(float)trak->timescale; + pts=(float)(trak->chunks[trak->pos].sample*trak->duration + + get_cts_offset(trak, trak->pos))/(float)trak->timescale; if(trak->samplesize!=1) { mp_msg(MSGT_DEMUX, MSGL_DBG2, "WARNING! Samplesize(%d) != 1\n", @@ -2023,11 +2062,12 @@ frame-=trak->editlist[trak->editlist_pos].start_frame; frame+=trak->editlist[trak->editlist_pos].start_sample; // calc pts: - pts=(float)(trak->samples[frame].pts+ - trak->editlist[trak->editlist_pos].pts_offset)/(float)trak->timescale; + pts=(float)(trak->samples[frame].pts + + trak->editlist[trak->editlist_pos].pts_offset + + get_cts_offset(trak, frame))/(float)trak->timescale; } else { if(frame>=trak->samples_size) return 0; // EOF - pts=(float)trak->samples[frame].pts/(float)trak->timescale; + pts=(float)(trak->samples[frame].pts + get_cts_offset(trak, frame))/(float)trak->timescale; } // read sample: stream_seek(demuxer->stream,trak->samples[frame].pos);