diff options
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index a5b71c089a..fec032a35c 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c @@ -178,6 +178,8 @@ typedef struct size_t guard_bytes; /* Number of bytes in guardbuf used */ size_t buffer_remaining; /* How much data is left in the buffer */ + uint32_t first_pts; + uint32_t curr_pts; int id; } Stream; @@ -464,6 +466,12 @@ static void get_next_data( Stream* str ) pts = (((header[9] >> 1) << 30) | (header[10] << 22) | ((header[11] >> 1) << 15) | (header[12] << 7) | (header[13] >> 1)); + + if (str->first_pts==0) + str->first_pts = pts; + + str->curr_pts = pts; + dts = (!(header[7] & 0x40) ? pts : ((uint32_t)(((header[14] >> 1) << 30) | (header[15] << 22) | @@ -558,6 +566,7 @@ static volatile int16_t* pcmbuf_head IBSS_ATTR; static volatile int16_t* pcmbuf_tail IBSS_ATTR; static volatile uint32_t samplesplayed IBSS_ATTR; +static volatile int delay IBSS_ATTR; static void init_pcmbuf(void) { @@ -599,6 +608,10 @@ static void audio_thread(void) size_t len; int file_end = 0; /* A count of the errors in each frame */ int framelength; + int found_avdelay = 0; + int avdelay = 0; /* Number of audio samples difference between first audio and video PTS values. */ + int64_t apts_samples; + uint32_t samplesdecoded = 0; /* We need this here to init the EMAC for Coldfire targets */ mad_synth_init(&synth); @@ -609,6 +622,14 @@ static void audio_thread(void) for (;;) { button_loop(); + if (!found_avdelay) { + if ((audio_str.first_pts != 0) && (video_str.first_pts != 0)) { + avdelay = ((audio_str.first_pts - video_str.first_pts)*44100)/90000; + found_avdelay = 1; + DEBUGF("First Audio PTS = %lu, First Video PTS=%lu, A-V=%d samples\n",audio_str.first_pts,video_str.first_pts,avdelay); + } + } + if (audiostatus == PLEASE_STOP) { goto done; } @@ -620,6 +641,7 @@ static void audio_thread(void) while (pcmbuf_len > 0) { rb->sleep(HZ/10); } goto done; } + len = audio_str.curr_packet_end - audio_str.curr_packet; if (n + len > mpa_buffer_size) { rb->splash( 30, "Audio buffer overflow" ); @@ -689,6 +711,14 @@ static void audio_thread(void) #endif framelength = synth.pcm.length; + samplesdecoded += framelength; + + if (found_avdelay) { + apts_samples = (audio_str.curr_pts-audio_str.first_pts); + apts_samples *= 44100; + apts_samples /= 90000; + delay=(int)(avdelay+apts_samples-samplesdecoded); + } if (framelength > 0) { /* Leave at least 32KB free (this will be the currently playing chunk) */ @@ -863,6 +893,8 @@ static void video_thread(void) /* Convert eta (in 27MHz ticks) into audio samples */ eta2 =(eta * 44100) / 27000000; + eta2 -= delay; + s = samplesplayed - (rb->pcm_get_bytes_waiting() >> 2); if (settings.limitfps) { if (eta2 > s) { @@ -1042,6 +1074,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) file_remaining -= disk_buf_len; video_str.guard_bytes = audio_str.guard_bytes = 0; + video_str.first_pts = audio_str.first_pts = 0; video_str.prev_packet = disk_buf; audio_str.prev_packet = disk_buf; video_str.buffer_remaining = disk_buf_len; |