diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 3296762..165da39 100644
|
a
|
b
|
static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track)
|
| 1316 | 1316 | return update_size(pb, pos); |
| 1317 | 1317 | } |
| 1318 | 1318 | |
| | 1319 | static int compute_track_delay(MOVTrack *track) { |
| | 1320 | int i; |
| | 1321 | int64_t first_pts, key_frame_pts; |
| | 1322 | MOVIentry *key_frame = NULL; |
| | 1323 | |
| | 1324 | // search for the first keyframe within this track |
| | 1325 | for (i = 0; i < track->entry; i++) { |
| | 1326 | if (track->cluster[i].flags & (MOV_SYNC_SAMPLE|MOV_PARTIAL_SYNC_SAMPLE)) { |
| | 1327 | key_frame = &track->cluster[i]; |
| | 1328 | break; |
| | 1329 | } |
| | 1330 | } |
| | 1331 | if (!key_frame) { |
| | 1332 | // no keyframe found |
| | 1333 | return 0; |
| | 1334 | } |
| | 1335 | |
| | 1336 | // check if after this first keyframe are entries with 'earlier' pts, |
| | 1337 | // which means entries are reordered |
| | 1338 | // we assume entries to be in decoding order |
| | 1339 | first_pts = key_frame_pts = key_frame->dts + key_frame->cts; |
| | 1340 | for (i++; i < track->entry; i++) { |
| | 1341 | int64_t pts = track->cluster[i].dts + track->cluster[i].cts; |
| | 1342 | if (pts >= key_frame_pts) |
| | 1343 | break; |
| | 1344 | first_pts = FFMIN(pts, first_pts); |
| | 1345 | } |
| | 1346 | // diff between pts of the first shown frame and the dts of the first decoded |
| | 1347 | // frame (which is not necessarily equal to 0) is the delay of this track |
| | 1348 | return first_pts - key_frame->dts; |
| | 1349 | } |
| | 1350 | |
| | 1351 | |
| 1319 | 1352 | static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) |
| 1320 | 1353 | { |
| 1321 | 1354 | MOVStts *ctts_entries; |
| 1322 | 1355 | uint32_t entries = 0; |
| 1323 | 1356 | uint32_t atom_size; |
| 1324 | | int i; |
| | 1357 | int i, track_delay = 0; |
| | 1358 | |
| | 1359 | if(track->mode == MODE_MOV) |
| | 1360 | track_delay = compute_track_delay(track); |
| 1325 | 1361 | |
| 1326 | 1362 | ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */ |
| 1327 | 1363 | ctts_entries[0].count = 1; |
| … |
… |
static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
|
| 1343 | 1379 | avio_wb32(pb, entries); /* entry count */ |
| 1344 | 1380 | for (i = 0; i < entries; i++) { |
| 1345 | 1381 | avio_wb32(pb, ctts_entries[i].count); |
| 1346 | | avio_wb32(pb, ctts_entries[i].duration); |
| | 1382 | avio_wb32(pb, ctts_entries[i].duration - track_delay); |
| 1347 | 1383 | } |
| 1348 | 1384 | av_free(ctts_entries); |
| 1349 | 1385 | return atom_size; |
| … |
… |
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
|
| 1810 | 1846 | int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE, |
| 1811 | 1847 | track->timescale, AV_ROUND_UP); |
| 1812 | 1848 | int version = duration < INT32_MAX ? 0 : 1; |
| 1813 | | int entry_size, entry_count, size; |
| | 1849 | int entry_size, entry_count, size, idx = 0; |
| 1814 | 1850 | int64_t delay, start_ct = track->cluster[0].cts; |
| 1815 | | delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE, |
| | 1851 | |
| | 1852 | // compute delay, which is the pts of the first shown frame (not necessarily 0) |
| | 1853 | // as frames might be reordered, we have to iterate |
| | 1854 | delay = track->cluster[0].dts + track->cluster[0].cts; |
| | 1855 | for(int i = 1; i < track->entry; i++) { |
| | 1856 | int64_t pts = track->cluster[i].dts + track->cluster[i].cts; |
| | 1857 | if(pts >= track->cluster[0].dts + track->cluster[0].cts) |
| | 1858 | break; |
| | 1859 | if(pts < delay) { |
| | 1860 | delay = pts; |
| | 1861 | start_ct = pts; |
| | 1862 | idx = i; |
| | 1863 | } |
| | 1864 | } |
| | 1865 | |
| | 1866 | delay = av_rescale_rnd(delay, MOV_TIMESCALE, |
| 1816 | 1867 | track->timescale, AV_ROUND_DOWN); |
| 1817 | 1868 | version |= delay < INT32_MAX ? 0 : 1; |
| 1818 | 1869 | |
| … |
… |
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
|
| 1829 | 1880 | avio_wb24(pb, 0); /* flags */ |
| 1830 | 1881 | |
| 1831 | 1882 | avio_wb32(pb, entry_count); |
| | 1883 | |
| 1832 | 1884 | if (delay > 0) { /* add an empty edit to delay presentation */ |
| 1833 | 1885 | if (version == 1) { |
| 1834 | 1886 | avio_wb64(pb, delay); |
| … |
… |
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
|
| 1839 | 1891 | } |
| 1840 | 1892 | avio_wb32(pb, 0x00010000); |
| 1841 | 1893 | } else { |
| 1842 | | av_assert0(av_rescale_rnd(track->cluster[0].dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0); |
| 1843 | | start_ct = -FFMIN(track->cluster[0].dts, 0); //FFMIN needed due to rounding |
| | 1894 | av_assert0(av_rescale_rnd(track->cluster[idx].dts + track->cluster[idx].cts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0); |
| | 1895 | start_ct = -FFMIN(track->cluster[idx].dts + track->cluster[idx].cts, 0); //FFMIN needed due to rounding |
| 1844 | 1896 | duration += delay; |
| 1845 | 1897 | } |
| 1846 | 1898 | |