Mercurial > mplayer.hg
comparison libmpdemux/demux_real.c @ 35891:dd02819472cc
Real demuxer seeking fixes.
Audio should seek to video keyframe position to minimize
initial desync.
Also, reset EOF if we know there will be more data.
author | reimar |
---|---|
date | Sun, 17 Mar 2013 09:32:11 +0000 |
parents | 57bb464310a7 |
children | 139f2b064ef9 |
comparison
equal
deleted
inserted
replaced
35890:3be8afb83629 | 35891:dd02819472cc |
---|---|
589 | 589 |
590 while(!stream_eof(demuxer->stream)){ | 590 while(!stream_eof(demuxer->stream)){ |
591 | 591 |
592 /* Handle audio/video demxing switch for multirate files (non-interleaved) */ | 592 /* Handle audio/video demxing switch for multirate files (non-interleaved) */ |
593 if (priv->is_multirate && priv->stream_switch) { | 593 if (priv->is_multirate && priv->stream_switch) { |
594 if (priv->current_apacket >= priv->index_table_size[demuxer->audio->id]) | 594 demuxer->audio->eof = priv->current_apacket >= priv->index_table_size[demuxer->audio->id]; |
595 demuxer->audio->eof = 1; | 595 demuxer->video->eof = priv->current_vpacket >= priv->index_table_size[demuxer->video->id]; |
596 if (priv->current_vpacket >= priv->index_table_size[demuxer->video->id]) | |
597 demuxer->video->eof = 1; | |
598 if (demuxer->audio->eof && demuxer->video->eof) | 596 if (demuxer->audio->eof && demuxer->video->eof) |
599 return 0; | 597 return 0; |
600 else if (!demuxer->audio->eof && demuxer->video->eof) | 598 else if (!demuxer->audio->eof && demuxer->video->eof) |
601 stream_seek(demuxer->stream, priv->audio_curpos); // Get audio | 599 stream_seek(demuxer->stream, priv->audio_curpos); // Get audio |
602 else if (demuxer->audio->eof && !demuxer->video->eof) | 600 else if (demuxer->audio->eof && !demuxer->video->eof) |
1802 demux_stream_t *d_video = demuxer->video; | 1800 demux_stream_t *d_video = demuxer->video; |
1803 sh_audio_t *sh_audio = d_audio->sh; | 1801 sh_audio_t *sh_audio = d_audio->sh; |
1804 sh_video_t *sh_video = d_video->sh; | 1802 sh_video_t *sh_video = d_video->sh; |
1805 int vid = d_video->id, aid = d_audio->id; | 1803 int vid = d_video->id, aid = d_audio->id; |
1806 int next_offset = 0; | 1804 int next_offset = 0; |
1807 int64_t cur_timestamp = 0; | 1805 int64_t target_timestamp = 0; |
1808 int streams = 0; | 1806 int streams = 0; |
1809 int retried = 0; | 1807 int retried = 0; |
1810 | 1808 |
1811 | 1809 |
1812 if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid]) | 1810 if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid]) |
1829 if ((streams & 2) && priv->current_apacket >= priv->index_table_size[aid]) | 1827 if ((streams & 2) && priv->current_apacket >= priv->index_table_size[aid]) |
1830 priv->current_apacket = priv->index_table_size[aid] - 1; | 1828 priv->current_apacket = priv->index_table_size[aid] - 1; |
1831 | 1829 |
1832 // if (index_mode == 1 || index_mode == 2) { | 1830 // if (index_mode == 1 || index_mode == 2) { |
1833 if (streams & 1) {// use the video index if we have one | 1831 if (streams & 1) {// use the video index if we have one |
1834 cur_timestamp = priv->index_table[vid][priv->current_vpacket].timestamp; | 1832 target_timestamp = priv->index_table[vid][priv->current_vpacket].timestamp; |
1833 target_timestamp += rel_seek_secs * 1000; | |
1835 if (rel_seek_secs > 0) | 1834 if (rel_seek_secs > 0) |
1836 while ((priv->index_table[vid][priv->current_vpacket].timestamp - cur_timestamp) < rel_seek_secs * 1000){ | 1835 while (priv->index_table[vid][priv->current_vpacket].timestamp < target_timestamp){ |
1837 priv->current_vpacket += 1; | 1836 priv->current_vpacket += 1; |
1838 if (priv->current_vpacket >= priv->index_table_size[vid]) { | 1837 if (priv->current_vpacket >= priv->index_table_size[vid]) { |
1839 priv->current_vpacket = priv->index_table_size[vid] - 1; | 1838 priv->current_vpacket = priv->index_table_size[vid] - 1; |
1840 if (!retried) { | 1839 if (!retried) { |
1841 stream_seek(demuxer->stream, priv->index_table[vid][priv->current_vpacket].offset); | 1840 stream_seek(demuxer->stream, priv->index_table[vid][priv->current_vpacket].offset); |
1842 add_index_segment(demuxer, vid, cur_timestamp + rel_seek_secs * 1000); | 1841 add_index_segment(demuxer, vid, target_timestamp); |
1843 retried = 1; | 1842 retried = 1; |
1844 } | 1843 } |
1845 else | 1844 else |
1846 break; | 1845 break; |
1847 } | 1846 } |
1848 } | 1847 } |
1849 else if (rel_seek_secs < 0) { | 1848 else if (rel_seek_secs < 0) { |
1850 while ((cur_timestamp - priv->index_table[vid][priv->current_vpacket].timestamp) < - rel_seek_secs * 1000){ | 1849 while (priv->index_table[vid][priv->current_vpacket].timestamp > target_timestamp){ |
1851 priv->current_vpacket -= 1; | 1850 priv->current_vpacket -= 1; |
1852 if (priv->current_vpacket < 0) { | 1851 if (priv->current_vpacket < 0) { |
1853 priv->current_vpacket = 0; | 1852 priv->current_vpacket = 0; |
1854 break; | 1853 break; |
1855 } | 1854 } |
1856 } | 1855 } |
1857 } | 1856 } |
1858 priv->video_curpos = priv->index_table[vid][priv->current_vpacket].offset; | 1857 priv->video_curpos = priv->index_table[vid][priv->current_vpacket].offset; |
1859 priv->audio_need_keyframe = !priv->is_multirate; | 1858 priv->audio_need_keyframe = !priv->is_multirate; |
1860 priv->video_after_seek = 1; | 1859 priv->video_after_seek = 1; |
1860 } else { | |
1861 target_timestamp = priv->index_table[aid][priv->current_apacket].timestamp; | |
1862 target_timestamp += rel_seek_secs * 1000; | |
1861 } | 1863 } |
1862 if (streams & 2) { | 1864 if (streams & 2) { |
1863 if (!(streams & 1)) { | |
1864 cur_timestamp = | |
1865 priv->index_table[aid][priv->current_apacket].timestamp; | |
1866 } | |
1867 if (rel_seek_secs > 0) | 1865 if (rel_seek_secs > 0) |
1868 while ((priv->index_table[aid][priv->current_apacket].timestamp - cur_timestamp) < rel_seek_secs * 1000){ | 1866 while (priv->index_table[aid][priv->current_apacket].timestamp < target_timestamp){ |
1869 priv->current_apacket += 1; | 1867 priv->current_apacket += 1; |
1870 if (priv->current_apacket >= priv->index_table_size[aid]) { | 1868 if (priv->current_apacket >= priv->index_table_size[aid]) { |
1871 priv->current_apacket = priv->index_table_size[aid] - 1; | 1869 priv->current_apacket = priv->index_table_size[aid] - 1; |
1872 break; | 1870 break; |
1873 } | 1871 } |
1874 } | 1872 } |
1875 else if (rel_seek_secs < 0) | 1873 else if (rel_seek_secs < 0) |
1876 while ((cur_timestamp - priv->index_table[aid][priv->current_apacket].timestamp) < - rel_seek_secs * 1000){ | 1874 while (priv->index_table[aid][priv->current_apacket].timestamp > target_timestamp){ |
1877 priv->current_apacket -= 1; | 1875 priv->current_apacket -= 1; |
1878 if (priv->current_apacket < 0) { | 1876 if (priv->current_apacket < 0) { |
1879 priv->current_apacket = 0; | 1877 priv->current_apacket = 0; |
1880 break; | 1878 break; |
1881 } | 1879 } |