Mercurial > mplayer.hg
comparison libmpdemux/demux_mov.c @ 6664:b802dd0812f1
edit-list support for video - fixes various A-V sync problems (TODO: seeking)
author | arpi |
---|---|
date | Sun, 07 Jul 2002 15:21:30 +0000 |
parents | 9eefcaf88e56 |
children | 872235b50330 |
comparison
equal
deleted
inserted
replaced
6663:5790a2576505 | 6664:b802dd0812f1 |
---|---|
80 | 80 |
81 typedef struct { | 81 typedef struct { |
82 unsigned int num; | 82 unsigned int num; |
83 unsigned int dur; | 83 unsigned int dur; |
84 } mov_durmap_t; | 84 } mov_durmap_t; |
85 | |
86 typedef struct { | |
87 unsigned int dur; | |
88 unsigned int pos; | |
89 int speed; | |
90 // | |
91 int frames; | |
92 int start_sample; | |
93 int start_frame; | |
94 int pts_offset; | |
95 } mov_editlist_t; | |
85 | 96 |
86 #define MOV_TRAK_UNKNOWN 0 | 97 #define MOV_TRAK_UNKNOWN 0 |
87 #define MOV_TRAK_VIDEO 1 | 98 #define MOV_TRAK_VIDEO 1 |
88 #define MOV_TRAK_AUDIO 2 | 99 #define MOV_TRAK_AUDIO 2 |
89 #define MOV_TRAK_FLASH 3 | 100 #define MOV_TRAK_FLASH 3 |
118 mov_chunkmap_t* chunkmap; | 129 mov_chunkmap_t* chunkmap; |
119 int durmap_size; | 130 int durmap_size; |
120 mov_durmap_t* durmap; | 131 mov_durmap_t* durmap; |
121 int keyframes_size; | 132 int keyframes_size; |
122 unsigned int* keyframes; | 133 unsigned int* keyframes; |
134 int editlist_size; | |
135 mov_editlist_t* editlist; | |
136 int editlist_pos; | |
123 // | 137 // |
124 void* desc; // image/sound/etc description (pointer to ImageDescription etc) | 138 void* desc; // image/sound/etc description (pointer to ImageDescription etc) |
125 } mov_track_t; | 139 } mov_track_t; |
126 | 140 |
127 void mov_build_index(mov_track_t* trak){ | 141 void mov_build_index(mov_track_t* trak){ |
163 if (trak->chunks[i].pos == -1) | 177 if (trak->chunks[i].pos == -1) |
164 if (i > 0) | 178 if (i > 0) |
165 trak->chunks[i].pos = trak->chunks[i-1].pos + trak->chunks[i-1].size; | 179 trak->chunks[i].pos = trak->chunks[i-1].pos + trak->chunks[i-1].size; |
166 else | 180 else |
167 trak->chunks[i].pos = 0; /* FIXME: set initial pos */ | 181 trak->chunks[i].pos = 0; /* FIXME: set initial pos */ |
168 } | |
169 #endif | 182 #endif |
170 | 183 |
171 // calc pts of chunks: | 184 // calc pts of chunks: |
172 s=0; | 185 s=0; |
173 for(j=0;j<trak->chunks_size;j++){ | 186 for(j=0;j<trak->chunks_size;j++){ |
212 trak->samples[s].pts, | 225 trak->samples[s].pts, |
213 (int)trak->samples[s].pos, | 226 (int)trak->samples[s].pos, |
214 trak->samples[s].size); | 227 trak->samples[s].size); |
215 pos+=trak->samples[s].size; | 228 pos+=trak->samples[s].size; |
216 ++s; | 229 ++s; |
230 } | |
231 } | |
232 | |
233 // precalc editlist entries | |
234 if(trak->editlist_size>0){ | |
235 int frame=0; | |
236 int e_pts=0; | |
237 for(i=0;i<trak->editlist_size;i++){ | |
238 mov_editlist_t* el=&trak->editlist[i]; | |
239 int sample=0; | |
240 int pts=el->pos; | |
241 el->start_frame=frame; | |
242 if(pts<0){ | |
243 // skip! | |
244 el->frames=0; continue; | |
245 } | |
246 // find start sample | |
247 for(;sample<trak->samples_size;sample++){ | |
248 if(pts<=trak->samples[sample].pts) break; | |
249 } | |
250 el->start_sample=sample; | |
251 el->pts_offset=e_pts-trak->samples[sample].pts; | |
252 pts+=el->dur; | |
253 e_pts+=el->dur; | |
254 // find end sample | |
255 for(;sample<trak->samples_size;sample++){ | |
256 if(pts<=trak->samples[sample].pts) break; | |
257 } | |
258 el->frames=sample-el->start_sample; | |
259 frame+=el->frames; | |
217 } | 260 } |
218 } | 261 } |
219 | 262 |
220 } | 263 } |
221 | 264 |
584 int i; | 627 int i; |
585 | 628 |
586 mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sEdit list table (%d entries) (ver:%d,flags:%ld)\n", | 629 mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sEdit list table (%d entries) (ver:%d,flags:%ld)\n", |
587 level, "",entries, ver, flags); | 630 level, "",entries, ver, flags); |
588 #if 1 | 631 #if 1 |
632 trak->editlist_size=entries; | |
633 trak->editlist=malloc(trak->editlist_size*sizeof(mov_editlist_t)); | |
589 for (i=0;i<entries;i++) | 634 for (i=0;i<entries;i++) |
590 { | 635 { |
591 int dur=stream_read_dword(demuxer->stream); | 636 int dur=stream_read_dword(demuxer->stream); |
592 int mt=stream_read_dword(demuxer->stream); | 637 int mt=stream_read_dword(demuxer->stream); |
593 int mr=stream_read_dword(demuxer->stream); // 16.16fp | 638 int mr=stream_read_dword(demuxer->stream); // 16.16fp |
639 trak->editlist[i].dur=dur; | |
640 trak->editlist[i].pos=mt; | |
641 trak->editlist[i].speed=mr; | |
594 mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*s entry#%d: duration: %d start time: %d speed: %3.1fx\n",level,"", | 642 mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*s entry#%d: duration: %d start time: %d speed: %3.1fx\n",level,"", |
595 i, | 643 i, |
596 dur,mt,(float)mr/65536.0f); | 644 dur,mt,(float)mr/65536.0f); |
597 } | 645 } |
598 #endif | 646 #endif |
1320 } | 1368 } |
1321 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Audio sample %d bytes pts %5.3f\n",trak->chunks[trak->pos].size*trak->samplesize,pts); | 1369 mp_msg(MSGT_DEMUX, MSGL_DBG2, "Audio sample %d bytes pts %5.3f\n",trak->chunks[trak->pos].size*trak->samplesize,pts); |
1322 } /* MOV_TRAK_AUDIO */ | 1370 } /* MOV_TRAK_AUDIO */ |
1323 pos=trak->chunks[trak->pos].pos; | 1371 pos=trak->chunks[trak->pos].pos; |
1324 } else { | 1372 } else { |
1373 int frame=trak->pos; | |
1374 // editlist support: | |
1375 if(trak->type == MOV_TRAK_VIDEO && trak->editlist_size>=1){ | |
1376 int t; | |
1377 // find the right editlist entry: | |
1378 if(frame<trak->editlist[trak->editlist_pos].start_frame) | |
1379 trak->editlist_pos=0; | |
1380 while(trak->editlist_pos<trak->editlist_size-1 && | |
1381 frame>=trak->editlist[trak->editlist_pos+1].start_frame) | |
1382 ++trak->editlist_pos; | |
1383 if(frame>=trak->editlist[trak->editlist_pos].start_frame+ | |
1384 trak->editlist[trak->editlist_pos].frames) return 0; // EOF | |
1385 // calc real frame index: | |
1386 frame-=trak->editlist[trak->editlist_pos].start_frame; | |
1387 frame+=trak->editlist[trak->editlist_pos].start_sample; | |
1388 // calc pts: | |
1389 pts=(float)(trak->samples[frame].pts+ | |
1390 trak->editlist[trak->editlist_pos].pts_offset)/(float)trak->timescale; | |
1391 } else { | |
1392 if(frame>=trak->samples_size) return 0; // EOF | |
1393 pts=(float)trak->samples[frame].pts/(float)trak->timescale; | |
1394 } | |
1325 // read sample: | 1395 // read sample: |
1326 if(trak->pos>=trak->samples_size) return 0; // EOF | 1396 stream_seek(demuxer->stream,trak->samples[frame].pos); |
1327 stream_seek(demuxer->stream,trak->samples[trak->pos].pos); | 1397 x=trak->samples[frame].size; |
1328 pts=(float)trak->samples[trak->pos].pts/(float)trak->timescale; | 1398 pos=trak->samples[frame].pos; |
1329 x=trak->samples[trak->pos].size; | |
1330 pos=trak->samples[trak->pos].pos; | |
1331 } | 1399 } |
1332 if(trak->pos==0 && trak->stream_header_len>0){ | 1400 if(trak->pos==0 && trak->stream_header_len>0){ |
1333 // we have to append the stream header... | 1401 // we have to append the stream header... |
1334 demux_packet_t* dp=new_demux_packet(x+trak->stream_header_len); | 1402 demux_packet_t* dp=new_demux_packet(x+trak->stream_header_len); |
1335 memcpy(dp->buffer,trak->stream_header,trak->stream_header_len); | 1403 memcpy(dp->buffer,trak->stream_header,trak->stream_header_len); |