summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-07-07 15:21:30 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-07-07 15:21:30 +0000
commit192e0f0fb675cf9418c76ef27ddeef5ce533c3d5 (patch)
treee3a03afff7c205c6da807c2c8e3acea1dab65c0d /libmpdemux
parent4e7bb9dd22907ea5f64968045e43c1801fb7d292 (diff)
downloadmpv-192e0f0fb675cf9418c76ef27ddeef5ce533c3d5.tar.bz2
mpv-192e0f0fb675cf9418c76ef27ddeef5ce533c3d5.tar.xz
edit-list support for video - fixes various A-V sync problems (TODO: seeking)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6665 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_mov.c80
1 files changed, 74 insertions, 6 deletions
diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c
index 40a8542e27..6424b382f1 100644
--- a/libmpdemux/demux_mov.c
+++ b/libmpdemux/demux_mov.c
@@ -83,6 +83,17 @@ typedef struct {
unsigned int dur;
} mov_durmap_t;
+typedef struct {
+ unsigned int dur;
+ unsigned int pos;
+ int speed;
+ //
+ int frames;
+ int start_sample;
+ int start_frame;
+ int pts_offset;
+} mov_editlist_t;
+
#define MOV_TRAK_UNKNOWN 0
#define MOV_TRAK_VIDEO 1
#define MOV_TRAK_AUDIO 2
@@ -120,6 +131,9 @@ typedef struct {
mov_durmap_t* durmap;
int keyframes_size;
unsigned int* keyframes;
+ int editlist_size;
+ mov_editlist_t* editlist;
+ int editlist_pos;
//
void* desc; // image/sound/etc description (pointer to ImageDescription etc)
} mov_track_t;
@@ -165,7 +179,6 @@ void mov_build_index(mov_track_t* trak){
trak->chunks[i].pos = trak->chunks[i-1].pos + trak->chunks[i-1].size;
else
trak->chunks[i].pos = 0; /* FIXME: set initial pos */
- }
#endif
// calc pts of chunks:
@@ -217,6 +230,36 @@ void mov_build_index(mov_track_t* trak){
}
}
+ // precalc editlist entries
+ if(trak->editlist_size>0){
+ int frame=0;
+ int e_pts=0;
+ for(i=0;i<trak->editlist_size;i++){
+ mov_editlist_t* el=&trak->editlist[i];
+ int sample=0;
+ int pts=el->pos;
+ el->start_frame=frame;
+ if(pts<0){
+ // skip!
+ el->frames=0; continue;
+ }
+ // find start sample
+ for(;sample<trak->samples_size;sample++){
+ if(pts<=trak->samples[sample].pts) break;
+ }
+ el->start_sample=sample;
+ el->pts_offset=e_pts-trak->samples[sample].pts;
+ pts+=el->dur;
+ e_pts+=el->dur;
+ // find end sample
+ for(;sample<trak->samples_size;sample++){
+ if(pts<=trak->samples[sample].pts) break;
+ }
+ el->frames=sample-el->start_sample;
+ frame+=el->frames;
+ }
+ }
+
}
#define MOV_MAX_TRACKS 256
@@ -586,11 +629,16 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sEdit list table (%d entries) (ver:%d,flags:%ld)\n",
level, "",entries, ver, flags);
#if 1
+ trak->editlist_size=entries;
+ trak->editlist=malloc(trak->editlist_size*sizeof(mov_editlist_t));
for (i=0;i<entries;i++)
{
int dur=stream_read_dword(demuxer->stream);
int mt=stream_read_dword(demuxer->stream);
int mr=stream_read_dword(demuxer->stream); // 16.16fp
+ trak->editlist[i].dur=dur;
+ trak->editlist[i].pos=mt;
+ trak->editlist[i].speed=mr;
mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*s entry#%d: duration: %d start time: %d speed: %3.1fx\n",level,"",
i,
dur,mt,(float)mr/65536.0f);
@@ -1322,12 +1370,32 @@ if(trak->samplesize){
} /* MOV_TRAK_AUDIO */
pos=trak->chunks[trak->pos].pos;
} else {
+ int frame=trak->pos;
+ // editlist support:
+ if(trak->type == MOV_TRAK_VIDEO && trak->editlist_size>=1){
+ int t;
+ // find the right editlist entry:
+ if(frame<trak->editlist[trak->editlist_pos].start_frame)
+ trak->editlist_pos=0;
+ while(trak->editlist_pos<trak->editlist_size-1 &&
+ frame>=trak->editlist[trak->editlist_pos+1].start_frame)
+ ++trak->editlist_pos;
+ if(frame>=trak->editlist[trak->editlist_pos].start_frame+
+ trak->editlist[trak->editlist_pos].frames) return 0; // EOF
+ // calc real frame index:
+ 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;
+ } else {
+ if(frame>=trak->samples_size) return 0; // EOF
+ pts=(float)trak->samples[frame].pts/(float)trak->timescale;
+ }
// read sample:
- if(trak->pos>=trak->samples_size) return 0; // EOF
- stream_seek(demuxer->stream,trak->samples[trak->pos].pos);
- pts=(float)trak->samples[trak->pos].pts/(float)trak->timescale;
- x=trak->samples[trak->pos].size;
- pos=trak->samples[trak->pos].pos;
+ stream_seek(demuxer->stream,trak->samples[frame].pos);
+ x=trak->samples[frame].size;
+ pos=trak->samples[frame].pos;
}
if(trak->pos==0 && trak->stream_header_len>0){
// we have to append the stream header...