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 }