summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-01-07 05:17:28 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-01-07 05:17:28 +0000
commit39107956ab680b37ade979e5379cf98a06604b13 (patch)
tree156c4197b5ad0d99c165e07d81da7a3e1d3671b1
parentb1a1831a17b17574b8a201dfcb348714772068b8 (diff)
downloadrockbox-39107956ab680b37ade979e5379cf98a06604b13.tar.gz
rockbox-39107956ab680b37ade979e5379cf98a06604b13.zip
MPEGPlyaer: A bit of audio mutation. Remove a useless thread state. Take some control over the buffer away from the audio thread itself. Some atomicity corrections.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28984 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c57
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.h7
-rw-r--r--apps/plugins/mpegplayer/pcm_output.c150
-rw-r--r--apps/plugins/mpegplayer/pcm_output.h10
-rw-r--r--apps/plugins/mpegplayer/stream_thread.h1
5 files changed, 141 insertions, 84 deletions
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index 9e3968007f..ecb8b1ffae 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -112,7 +112,7 @@ static inline void audiodesc_queue_add_tail(void)
112 audio_queue.write++; 112 audio_queue.write++;
113} 113}
114 114
115/* Increments the queue tail position - leaves one slot as current */ 115/* Increments the queue head position - leaves one slot as current */
116static inline bool audiodesc_queue_remove_head(void) 116static inline bool audiodesc_queue_remove_head(void)
117{ 117{
118 if (audio_queue.write == audio_queue.read) 118 if (audio_queue.write == audio_queue.read)
@@ -375,8 +375,6 @@ static void audio_thread_msg(struct audio_thread_data *td)
375 case TSTATE_INIT: 375 case TSTATE_INIT:
376 td->state = TSTATE_DECODE; 376 td->state = TSTATE_DECODE;
377 case TSTATE_DECODE: 377 case TSTATE_DECODE:
378 case TSTATE_RENDER_WAIT:
379 case TSTATE_RENDER_WAIT_END:
380 break; 378 break;
381 379
382 case TSTATE_EOS: 380 case TSTATE_EOS:
@@ -455,7 +453,6 @@ static void audio_thread_msg(struct audio_thread_data *td)
455 { 453 {
456 case TSTATE_DECODE: 454 case TSTATE_DECODE:
457 case TSTATE_RENDER_WAIT: 455 case TSTATE_RENDER_WAIT:
458 case TSTATE_RENDER_WAIT_END:
459 /* These return when in playing state */ 456 /* These return when in playing state */
460 return; 457 return;
461 } 458 }
@@ -512,7 +509,6 @@ static void audio_thread(void)
512 /* These states are the only ones that should return */ 509 /* These states are the only ones that should return */
513 case TSTATE_DECODE: goto audio_decode; 510 case TSTATE_DECODE: goto audio_decode;
514 case TSTATE_RENDER_WAIT: goto render_wait; 511 case TSTATE_RENDER_WAIT: goto render_wait;
515 case TSTATE_RENDER_WAIT_END: goto render_wait_end;
516 /* Anything else is interpreted as an exit */ 512 /* Anything else is interpreted as an exit */
517 default: 513 default:
518 { 514 {
@@ -538,29 +534,28 @@ static void audio_thread(void)
538 case STREAM_DATA_END: 534 case STREAM_DATA_END:
539 { 535 {
540 if (audio_queue.used > MAD_BUFFER_GUARD) 536 if (audio_queue.used > MAD_BUFFER_GUARD)
541 break; 537 break; /* Still have frames to decode */
542 538
543 /* Used up remainder of compressed audio buffer. 539 /* Used up remainder of compressed audio buffer. Wait for
544 * Force any residue to play if audio ended before 540 * samples on PCM buffer to finish playing. */
545 * reaching the threshold */
546 td.state = TSTATE_RENDER_WAIT_END;
547 audio_queue_reset(); 541 audio_queue_reset();
548 542
549 render_wait_end: 543 while (1)
550 pcm_output_drain();
551
552 while (pcm_output_used() > (ssize_t)PCMOUT_LOW_WM)
553 { 544 {
545 if (pcm_output_empty())
546 {
547 td.state = TSTATE_EOS;
548 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
549 break;
550 }
551
552 pcm_output_drain();
554 str_get_msg_w_tmo(&audio_str, &td.ev, 1); 553 str_get_msg_w_tmo(&audio_str, &td.ev, 1);
554
555 if (td.ev.id != SYS_TIMEOUT) 555 if (td.ev.id != SYS_TIMEOUT)
556 goto message_process; 556 break;
557 } 557 }
558 558
559 td.state = TSTATE_EOS;
560 if (td.status == STREAM_PLAYING)
561 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
562
563 rb->yield();
564 goto message_wait; 559 goto message_wait;
565 } /* STREAM_DATA_END: */ 560 } /* STREAM_DATA_END: */
566 } 561 }
@@ -606,11 +601,9 @@ static void audio_thread(void)
606 601
607 /* This is too hard - bail out */ 602 /* This is too hard - bail out */
608 td.state = TSTATE_EOS; 603 td.state = TSTATE_EOS;
609
610 if (td.status == STREAM_PLAYING)
611 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
612
613 td.status = STREAM_ERROR; 604 td.status = STREAM_ERROR;
605 stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
606
614 goto message_wait; 607 goto message_wait;
615 } 608 }
616 609
@@ -643,15 +636,15 @@ static void audio_thread(void)
643 render_wait: 636 render_wait:
644 if (synth.pcm.length > 0) 637 if (synth.pcm.length > 0)
645 { 638 {
646 struct pcm_frame_header *dst_hdr = pcm_output_get_buffer();
647 const char *src[2] = 639 const char *src[2] =
648 { (char *)synth.pcm.samples[0], (char *)synth.pcm.samples[1] }; 640 { (char *)synth.pcm.samples[0], (char *)synth.pcm.samples[1] };
649 int out_count = (synth.pcm.length * CLOCK_RATE 641 int out_count = (synth.pcm.length * CLOCK_RATE
650 + (td.samplerate - 1)) / td.samplerate; 642 + (td.samplerate - 1)) / td.samplerate;
651 ssize_t size = sizeof(*dst_hdr) + out_count*4; 643 unsigned char *out_buf;
644 ssize_t size = out_count*4;
652 645
653 /* Wait for required amount of free buffer space */ 646 /* Wait for required amount of free buffer space */
654 while (pcm_output_free() < size) 647 while ((out_buf = pcm_output_get_buffer(&size)) == NULL)
655 { 648 {
656 /* Wait one frame */ 649 /* Wait one frame */
657 int timeout = out_count*HZ / td.samplerate; 650 int timeout = out_count*HZ / td.samplerate;
@@ -660,21 +653,17 @@ static void audio_thread(void)
660 goto message_process; 653 goto message_process;
661 } 654 }
662 655
663 out_count = rb->dsp_process(td.dsp, dst_hdr->data, src, 656 out_count = rb->dsp_process(td.dsp, out_buf, src, synth.pcm.length);
664 synth.pcm.length);
665 657
666 if (out_count <= 0) 658 if (out_count <= 0)
667 break; 659 break;
668 660
669 dst_hdr->size = sizeof(*dst_hdr) + out_count*4; 661 /* Make this data available to DMA */
670 dst_hdr->time = audio_queue.curr->time; 662 pcm_output_commit_data(out_count*4, audio_queue.curr->time);
671 663
672 /* As long as we're on this timestamp, the time is just 664 /* As long as we're on this timestamp, the time is just
673 incremented by the number of samples */ 665 incremented by the number of samples */
674 audio_queue.curr->time += out_count; 666 audio_queue.curr->time += out_count;
675
676 /* Make this data available to DMA */
677 pcm_output_add_data();
678 } 667 }
679 668
680 rb->yield(); 669 rb->yield();
diff --git a/apps/plugins/mpegplayer/mpegplayer.h b/apps/plugins/mpegplayer/mpegplayer.h
index 79c25f6109..7333d87d6e 100644
--- a/apps/plugins/mpegplayer/mpegplayer.h
+++ b/apps/plugins/mpegplayer/mpegplayer.h
@@ -51,14 +51,13 @@
51/* Define this as "1" to have a test tone instead of silence clip */ 51/* Define this as "1" to have a test tone instead of silence clip */
52#define SILENCE_TEST_TONE 0 52#define SILENCE_TEST_TONE 0
53 53
54/* NOTE: Sizes make no frame header allowance when considering duration */
54#define PCMOUT_BUFSIZE (CLOCK_RATE/2*4) /* 1/2s */ 55#define PCMOUT_BUFSIZE (CLOCK_RATE/2*4) /* 1/2s */
55#define PCMOUT_GUARD_SAMPLES ((CLOCK_RATE*576+7999)/8000) /* Worst upsampling case */ 56#define PCMOUT_GUARD_SIZE (PCMOUT_BUFSIZE) /* guarantee contiguous sizes */
56#define PCMOUT_GUARD_SIZE (PCMOUT_GUARD_SAMPLES*4 + sizeof (struct pcm_frame_header))
57#define PCMOUT_ALLOC_SIZE (PCMOUT_BUFSIZE + PCMOUT_GUARD_SIZE) 57#define PCMOUT_ALLOC_SIZE (PCMOUT_BUFSIZE + PCMOUT_GUARD_SIZE)
58 /* Start pcm playback @ 25% full */ 58 /* Start pcm playback @ 25% full */
59#define PCMOUT_PLAY_WM (PCMOUT_BUFSIZE/4) 59#define PCMOUT_PLAY_WM (PCMOUT_BUFSIZE/4)
60 /* No valid audio frame is smaller */ 60#define PCMOUT_LOW_WM (0)
61#define PCMOUT_LOW_WM (sizeof (struct pcm_frame_header))
62 61
63/** disk buffer **/ 62/** disk buffer **/
64#define DISK_BUF_LOW_WATERMARK (1024*1024) 63#define DISK_BUF_LOW_WATERMARK (1024*1024)
diff --git a/apps/plugins/mpegplayer/pcm_output.c b/apps/plugins/mpegplayer/pcm_output.c
index a5d8f86e5b..0b8ad7701a 100644
--- a/apps/plugins/mpegplayer/pcm_output.c
+++ b/apps/plugins/mpegplayer/pcm_output.c
@@ -36,21 +36,30 @@ static struct pcm_frame_header * ALIGNED_ATTR(4) pcmbuf_tail IBSS_ATTR;
36 36
37/* Bytes */ 37/* Bytes */
38static ssize_t pcmbuf_curr_size IBSS_ATTR; /* Size of currently playing frame */ 38static ssize_t pcmbuf_curr_size IBSS_ATTR; /* Size of currently playing frame */
39static uint64_t pcmbuf_read IBSS_ATTR; /* Number of bytes read by DMA */ 39static ssize_t pcmbuf_read IBSS_ATTR; /* Number of bytes read by DMA */
40static uint64_t pcmbuf_written IBSS_ATTR; /* Number of bytes written by source */ 40static ssize_t pcmbuf_written IBSS_ATTR; /* Number of bytes written by source */
41static ssize_t pcmbuf_threshold IBSS_ATTR; /* Non-silence threshold */ 41static ssize_t pcmbuf_threshold IBSS_ATTR; /* Non-silence threshold */
42 42
43/* Clock */ 43/* Clock */
44static uint32_t clock_base IBSS_ATTR; /* Our base clock */
45static uint32_t clock_start IBSS_ATTR; /* Clock at playback start */ 44static uint32_t clock_start IBSS_ATTR; /* Clock at playback start */
46static int32_t clock_adjust IBSS_ATTR; /* Clock drift adjustment */ 45static uint32_t volatile clock_tick IBSS_ATTR; /* Our base clock */
46static uint32_t volatile clock_time IBSS_ATTR; /* Timestamp adjusted */
47 47
48int pcm_skipped = 0; 48static int pcm_skipped = 0;
49int pcm_underruns = 0; 49static int pcm_underruns = 0;
50 50
51/* Small silence clip. ~5.80ms @ 44.1kHz */ 51/* Small silence clip. ~5.80ms @ 44.1kHz */
52static int16_t silence[256*2] ALIGNED_ATTR(4) = { 0 }; 52static int16_t silence[256*2] ALIGNED_ATTR(4) = { 0 };
53 53
54/* Delete all buffer contents */
55static void pcm_reset_buffer(void)
56{
57 pcmbuf_threshold = PCMOUT_PLAY_WM;
58 pcmbuf_curr_size = pcmbuf_read = pcmbuf_written = 0;
59 pcmbuf_head = pcmbuf_tail = pcm_buffer;
60 pcm_skipped = pcm_underruns = 0;
61}
62
54/* Advance a PCM buffer pointer by size bytes circularly */ 63/* Advance a PCM buffer pointer by size bytes circularly */
55static inline void pcm_advance_buffer(struct pcm_frame_header **p, 64static inline void pcm_advance_buffer(struct pcm_frame_header **p,
56 size_t size) 65 size_t size)
@@ -60,15 +69,16 @@ static inline void pcm_advance_buffer(struct pcm_frame_header **p,
60 *p = SKIPBYTES(*p, -PCMOUT_BUFSIZE); 69 *p = SKIPBYTES(*p, -PCMOUT_BUFSIZE);
61} 70}
62 71
63/* Inline internally but not externally */ 72/* Return physical space used */
64inline ssize_t pcm_output_used(void) 73static inline ssize_t pcm_output_bytes_used(void)
65{ 74{
66 return (ssize_t)(pcmbuf_written - pcmbuf_read); 75 return pcmbuf_written - pcmbuf_read; /* wrap-safe */
67} 76}
68 77
69inline ssize_t pcm_output_free(void) 78/* Return physical space free */
79static inline ssize_t pcm_output_bytes_free(void)
70{ 80{
71 return (ssize_t)(PCMOUT_BUFSIZE - pcmbuf_written + pcmbuf_read); 81 return PCMOUT_BUFSIZE - pcm_output_bytes_used();
72} 82}
73 83
74/* Audio DMA handler */ 84/* Audio DMA handler */
@@ -80,7 +90,7 @@ static void get_more(unsigned char **start, size_t *size)
80 pcmbuf_read += pcmbuf_curr_size; 90 pcmbuf_read += pcmbuf_curr_size;
81 pcmbuf_curr_size = 0; 91 pcmbuf_curr_size = 0;
82 92
83 sz = pcm_output_used(); 93 sz = pcm_output_bytes_used();
84 94
85 if (sz > pcmbuf_threshold) 95 if (sz > pcmbuf_threshold)
86 { 96 {
@@ -89,16 +99,15 @@ static void get_more(unsigned char **start, size_t *size)
89 while (1) 99 while (1)
90 { 100 {
91 uint32_t time = pcmbuf_head->time; 101 uint32_t time = pcmbuf_head->time;
92 int32_t offset = time - (clock_base + clock_adjust); 102 int32_t offset = time - clock_time;
93 103
94 sz = pcmbuf_head->size; 104 sz = pcmbuf_head->size;
95 105
96 if (sz < (ssize_t)(sizeof(pcmbuf_head) + 4) || 106 if (sz < (ssize_t)(PCM_HDR_SIZE + 4) ||
97 (sz & 3) != 0) 107 (sz & 3) != 0)
98 { 108 {
99 /* Just show a warning about this - will never happen 109 /* Just show a warning about this - will never happen
100 * without a bug in the audio thread code or a clobbered 110 * without a corrupted buffer */
101 * buffer */
102 DEBUGF("get_more: invalid size (%ld)\n", (long)sz); 111 DEBUGF("get_more: invalid size (%ld)\n", (long)sz);
103 } 112 }
104 113
@@ -108,11 +117,12 @@ static void get_more(unsigned char **start, size_t *size)
108 pcm_advance_buffer(&pcmbuf_head, sz); 117 pcm_advance_buffer(&pcmbuf_head, sz);
109 pcmbuf_read += sz; 118 pcmbuf_read += sz;
110 pcm_skipped++; 119 pcm_skipped++;
111 if (pcmbuf_read < pcmbuf_written) 120 if (pcm_output_bytes_used() > 0)
112 continue; 121 continue;
113 122
114 /* Ran out so revert to default watermark */ 123 /* Ran out so revert to default watermark */
115 pcmbuf_threshold = PCMOUT_PLAY_WM; 124 pcmbuf_threshold = PCMOUT_PLAY_WM;
125 pcm_underruns++;
116 } 126 }
117 else if (offset < 100*CLOCK_RATE/1000) 127 else if (offset < 100*CLOCK_RATE/1000)
118 { 128 {
@@ -122,15 +132,15 @@ static void get_more(unsigned char **start, size_t *size)
122 pcm_advance_buffer(&pcmbuf_head, sz); 132 pcm_advance_buffer(&pcmbuf_head, sz);
123 pcmbuf_curr_size = sz; 133 pcmbuf_curr_size = sz;
124 134
125 sz -= sizeof (struct pcm_frame_header); 135 sz -= PCM_HDR_SIZE;
126 136
127 *size = sz; 137 *size = sz;
128 138
129 /* Audio is time master - keep clock synchronized */ 139 /* Audio is time master - keep clock synchronized */
130 clock_adjust = time - clock_base; 140 clock_time = time + (sz >> 2);
131 141
132 /* Update base clock */ 142 /* Update base clock */
133 clock_base += sz >> 2; 143 clock_tick += sz >> 2;
134 return; 144 return;
135 } 145 }
136 /* Frame will be dropped - play silence clip */ 146 /* Frame will be dropped - play silence clip */
@@ -150,22 +160,57 @@ static void get_more(unsigned char **start, size_t *size)
150 *start = (unsigned char *)silence; 160 *start = (unsigned char *)silence;
151 *size = sizeof (silence); 161 *size = sizeof (silence);
152 162
153 clock_base += sizeof (silence) / 4; 163 clock_tick += sizeof (silence) / 4;
164 clock_time += sizeof (silence) / 4;
154 165
155 if (pcmbuf_read > pcmbuf_written) 166 if (sz < 0)
156 pcmbuf_read = pcmbuf_written; 167 pcmbuf_read = pcmbuf_written;
157} 168}
158 169
159struct pcm_frame_header * pcm_output_get_buffer(void) 170/** Public interface **/
171
172/* Return a buffer pointer if at least size bytes are available and if so,
173 * give the actual free space */
174unsigned char * pcm_output_get_buffer(ssize_t *size)
160{ 175{
161 return pcmbuf_tail; 176 ssize_t sz = *size;
177 ssize_t free = pcm_output_bytes_free() - PCM_HDR_SIZE;
178
179 if (sz >= 0 && free >= sz)
180 {
181 *size = free; /* return actual free space (- header) */
182 return pcmbuf_tail->data;
183 }
184
185 /* Leave *size alone so caller doesn't have to reinit */
186 return NULL;
162} 187}
163 188
164void pcm_output_add_data(void) 189/* Commit the buffer returned by pcm_ouput_get_buffer; timestamp is PCM
190 * clock time units, not video format time units */
191bool pcm_output_commit_data(ssize_t size, uint32_t timestamp)
165{ 192{
166 size_t size = pcmbuf_tail->size; 193 if (size <= 0 || (size & 3))
194 return false; /* invalid */
195
196 size += PCM_HDR_SIZE;
197
198 if (size > pcm_output_bytes_free())
199 return false; /* too big */
200
201 pcmbuf_tail->size = size;
202 pcmbuf_tail->time = timestamp;
203
167 pcm_advance_buffer(&pcmbuf_tail, size); 204 pcm_advance_buffer(&pcmbuf_tail, size);
168 pcmbuf_written += size; 205 pcmbuf_written += size;
206
207 return true;
208}
209
210/* Returns 'true' if the buffer is completely empty */
211bool pcm_output_empty(void)
212{
213 return pcm_output_bytes_used() <= 0;
169} 214}
170 215
171/* Flushes the buffer - clock keeps counting */ 216/* Flushes the buffer - clock keeps counting */
@@ -182,10 +227,7 @@ void pcm_output_flush(void)
182 if (playing) 227 if (playing)
183 rb->pcm_play_stop(); 228 rb->pcm_play_stop();
184 229
185 pcmbuf_threshold = PCMOUT_PLAY_WM; 230 pcm_reset_buffer();
186 pcmbuf_curr_size = pcmbuf_read = pcmbuf_written = 0;
187 pcmbuf_head = pcmbuf_tail = pcm_buffer;
188 pcm_skipped = pcm_underruns = 0;
189 231
190 /* Restart if playing state was current */ 232 /* Restart if playing state was current */
191 if (playing && !paused) 233 if (playing && !paused)
@@ -201,25 +243,54 @@ void pcm_output_set_clock(uint32_t time)
201{ 243{
202 rb->pcm_play_lock(); 244 rb->pcm_play_lock();
203 245
204 clock_base = time;
205 clock_start = time; 246 clock_start = time;
206 clock_adjust = 0; 247 clock_tick = time;
248 clock_time = time;
207 249
208 rb->pcm_play_unlock(); 250 rb->pcm_play_unlock();
209} 251}
210 252
253/* Return the clock as synchronized by audio frame timestamps */
211uint32_t pcm_output_get_clock(void) 254uint32_t pcm_output_get_clock(void)
212{ 255{
213 return clock_base + clock_adjust 256 uint32_t time, rem;
214 - (rb->pcm_get_bytes_waiting() >> 2); 257
258 /* Reread if data race detected - rem will be 0 if driver hasn't yet
259 * updated to the new buffer size. Also be sure pcm state doesn't
260 * cause indefinite loop.
261 *
262 * FYI: NOT scrutinized for rd/wr reordering on different cores. */
263 do
264 {
265 time = clock_time;
266 rem = rb->pcm_get_bytes_waiting() >> 2;
267 }
268 while (UNLIKELY(time != clock_time ||
269 (rem == 0 && rb->pcm_is_playing() && !rb->pcm_is_paused())));
270
271 return time - rem;
272
215} 273}
216 274
275/* Return the raw clock as counted from the last pcm_output_set_clock
276 * call */
217uint32_t pcm_output_get_ticks(uint32_t *start) 277uint32_t pcm_output_get_ticks(uint32_t *start)
218{ 278{
279 uint32_t tick, rem;
280
281 /* Same procedure as pcm_output_get_clock */
282 do
283 {
284 tick = clock_tick;
285 rem = rb->pcm_get_bytes_waiting() >> 2;
286 }
287 while (UNLIKELY(tick != clock_tick ||
288 (rem == 0 && rb->pcm_is_playing() && !rb->pcm_is_paused())));
289
219 if (start) 290 if (start)
220 *start = clock_start; 291 *start = clock_start;
221 292
222 return clock_base - (rb->pcm_get_bytes_waiting() >> 2); 293 return tick - rem;
223} 294}
224 295
225/* Pauses/Starts pcm playback - and the clock */ 296/* Pauses/Starts pcm playback - and the clock */
@@ -267,12 +338,13 @@ bool pcm_output_init(void)
267 if (pcm_buffer == NULL) 338 if (pcm_buffer == NULL)
268 return false; 339 return false;
269 340
270 pcmbuf_threshold = PCMOUT_PLAY_WM;
271 pcmbuf_head = pcm_buffer;
272 pcmbuf_tail = pcm_buffer;
273 pcmbuf_end = SKIPBYTES(pcm_buffer, PCMOUT_BUFSIZE); 341 pcmbuf_end = SKIPBYTES(pcm_buffer, PCMOUT_BUFSIZE);
274 pcmbuf_curr_size = pcmbuf_read = pcmbuf_written = 0;
275 342
343 pcm_reset_buffer();
344
345 /* Some targets could play at the movie frequency without resampling but
346 * as of now DSP assumes a certain frequency (always 44100Hz) so
347 * resampling will be needed for other movie audio rates. */
276 rb->pcm_set_frequency(NATIVE_FREQUENCY); 348 rb->pcm_set_frequency(NATIVE_FREQUENCY);
277 349
278#if INPUT_SRC_CAPS != 0 350#if INPUT_SRC_CAPS != 0
diff --git a/apps/plugins/mpegplayer/pcm_output.h b/apps/plugins/mpegplayer/pcm_output.h
index 9335235daa..1a00ac48e6 100644
--- a/apps/plugins/mpegplayer/pcm_output.h
+++ b/apps/plugins/mpegplayer/pcm_output.h
@@ -23,6 +23,7 @@
23#ifndef PCM_OUTPUT_H 23#ifndef PCM_OUTPUT_H
24#define PCM_OUTPUT_H 24#define PCM_OUTPUT_H
25 25
26#define PCM_HDR_SIZE (sizeof (struct pcm_frame_header))
26struct pcm_frame_header /* Header added to pcm data every time a decoded 27struct pcm_frame_header /* Header added to pcm data every time a decoded
27 audio frame is sent out */ 28 audio frame is sent out */
28{ 29{
@@ -31,8 +32,6 @@ struct pcm_frame_header /* Header added to pcm data every time a decoded
31 unsigned char data[]; /* open array of audio data */ 32 unsigned char data[]; /* open array of audio data */
32} ALIGNED_ATTR(4); 33} ALIGNED_ATTR(4);
33 34
34extern int pcm_skipped, pcm_underruns;
35
36bool pcm_output_init(void); 35bool pcm_output_init(void);
37void pcm_output_exit(void); 36void pcm_output_exit(void);
38void pcm_output_flush(void); 37void pcm_output_flush(void);
@@ -42,9 +41,8 @@ uint32_t pcm_output_get_ticks(uint32_t *start);
42void pcm_output_play_pause(bool play); 41void pcm_output_play_pause(bool play);
43void pcm_output_stop(void); 42void pcm_output_stop(void);
44void pcm_output_drain(void); 43void pcm_output_drain(void);
45struct pcm_frame_header * pcm_output_get_buffer(void); 44unsigned char * pcm_output_get_buffer(ssize_t *size);
46void pcm_output_add_data(void); 45bool pcm_output_commit_data(ssize_t size, uint32_t timestamp);
47ssize_t pcm_output_used(void); 46bool pcm_output_empty(void);
48ssize_t pcm_output_free(void);
49 47
50#endif /* PCM_OUTPUT_H */ 48#endif /* PCM_OUTPUT_H */
diff --git a/apps/plugins/mpegplayer/stream_thread.h b/apps/plugins/mpegplayer/stream_thread.h
index 5791a49e7f..dfa6e8c9a1 100644
--- a/apps/plugins/mpegplayer/stream_thread.h
+++ b/apps/plugins/mpegplayer/stream_thread.h
@@ -73,7 +73,6 @@ enum thread_states
73 TSTATE_DECODE, /* is in a decoding state */ 73 TSTATE_DECODE, /* is in a decoding state */
74 TSTATE_RENDER, /* is in a rendering state */ 74 TSTATE_RENDER, /* is in a rendering state */
75 TSTATE_RENDER_WAIT, /* is waiting to render */ 75 TSTATE_RENDER_WAIT, /* is waiting to render */
76 TSTATE_RENDER_WAIT_END, /* is waiting on remaining data */
77}; 76};
78 77
79/* Commands that streams respond to */ 78/* Commands that streams respond to */