MpegPlayer: Add a simple messaging scheme for sending stream commands. Remove the...
[Rockbox.git] / apps / plugins / mpegplayer / mpegplayer.c
blobcbd4999655aa9f60b04367227578b6e0ccd1b063
1 /*
2 * mpegplayer.c - based on :
3 * - mpeg2dec.c
4 * - m2psd.c (http://www.brouhaha.com/~eric/software/m2psd/)
6 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
7 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
9 * m2psd: MPEG 2 Program Stream Demultiplexer
10 * Copyright (C) 2003 Eric Smith <eric@brouhaha.com>
12 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
13 * See http://libmpeg2.sourceforge.net/ for updates.
15 * mpeg2dec is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * mpeg2dec is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 NOTES:
34 mpegplayer is structured as follows:
36 1) Video thread (running on the COP for PortalPlayer targets).
37 2) Audio thread (running on the main CPU to maintain consistency with
38 the audio FIQ hander on PP).
39 3) The main thread which takes care of buffering.
41 Using the main thread for buffering wastes the 8KB main stack which is
42 in IRAM. However, 8KB is not enough for the audio thread to run (it
43 needs somewhere between 8KB and 9KB), so we create a new thread in
44 order to`give it a larger stack.
46 We use 4.5KB of the main stack for a libmad buffer (making use of
47 otherwise unused IRAM). There is also the possiblity of stealing the
48 main Rockbox codec thread's 9KB of IRAM stack and using that for
49 mpegplayer's audio thread - but we should only implement that if we
50 can put the IRAM to good use.
52 The button loop (and hence pause/resume, main menu and, in the future,
53 seeking) is placed in the audio thread. This keeps it on the main CPU
54 in PP targets and also allows buffering to continue in the background
55 whilst the main thread is filling the buffer.
57 A/V sync is not yet implemented but is planned to be achieved by
58 syncing the master clock with the audio, and then (as is currently
59 implemented), syncing video with the master clock. This can happen in
60 the audio thread, along with resyncing after pause.
62 Seeking should probably happen in the main thread, as that's where the
63 buffering happens.
65 On PortalPlayer targets, the main CPU is not being fully utilised -
66 the bottleneck is the video decoding on the COP. One way to improve
67 that might be to move the rendering of the frames (i.e. the
68 lcd_yuv_blit() call) from the COP back to the main CPU. Ideas and
69 patches for that are welcome!
71 Notes about MPEG files:
73 MPEG System Clock is 27MHz - i.e. 27000000 ticks/second.
75 FPS is represented in terms of a frame period - this is always an
76 integer number of 27MHz ticks.
78 e.g. 29.97fps (30000/1001) NTSC video has an exact frame period of
79 900900 27MHz ticks.
81 In libmpeg2, info->sequence->frame_period contains the frame_period.
83 Working with Rockbox's 100Hz tick, the common frame rates would need
84 to be as follows:
86 FPS | 27Mhz | 100Hz | 44.1KHz | 48KHz
87 --------|-----------------------------------------------------------
88 10* | 2700000 | 10 | 4410 | 4800
89 12* | 2250000 | 8.3333 | 3675 | 4000
90 15* | 1800000 | 6.6667 | 2940 | 3200
91 23.9760 | 1126125 | 4.170833333 | 1839.3375 | 2002
92 24 | 1125000 | 4.166667 | 1837.5 | 2000
93 25 | 1080000 | 4 | 1764 | 1920
94 29.9700 | 900900 | 3.336667 | 1471,47 | 1601.6
95 30 | 900000 | 3.333333 | 1470 | 1600
98 *Unofficial framerates
103 #include "mpeg2dec_config.h"
105 #include "plugin.h"
106 #include "gray.h"
108 #include "mpeg2.h"
109 #include "mpeg_settings.h"
110 #include "video_out.h"
111 #include "../../codecs/libmad/mad.h"
113 PLUGIN_HEADER
114 PLUGIN_IRAM_DECLARE
116 /* button definitions */
117 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
118 #define MPEG_MENU BUTTON_MODE
119 #define MPEG_STOP BUTTON_OFF
120 #define MPEG_PAUSE BUTTON_ON
121 #define MPEG_VOLDOWN BUTTON_DOWN
122 #define MPEG_VOLUP BUTTON_UP
124 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
125 #define MPEG_MENU BUTTON_MENU
126 #define MPEG_PAUSE (BUTTON_PLAY | BUTTON_REL)
127 #define MPEG_STOP (BUTTON_PLAY | BUTTON_REPEAT)
128 #define MPEG_VOLDOWN BUTTON_SCROLL_BACK
129 #define MPEG_VOLUP BUTTON_SCROLL_FWD
131 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
132 #define MPEG_MENU (BUTTON_REC | BUTTON_REL)
133 #define MPEG_STOP BUTTON_POWER
134 #define MPEG_PAUSE BUTTON_PLAY
135 #define MPEG_VOLDOWN BUTTON_DOWN
136 #define MPEG_VOLUP BUTTON_UP
138 #elif CONFIG_KEYPAD == GIGABEAT_PAD
139 #define MPEG_MENU BUTTON_MENU
140 #define MPEG_STOP BUTTON_POWER
141 #define MPEG_PAUSE BUTTON_SELECT
142 #define MPEG_VOLDOWN BUTTON_LEFT
143 #define MPEG_VOLUP BUTTON_RIGHT
144 #define MPEG_VOLDOWN2 BUTTON_VOL_DOWN
145 #define MPEG_VOLUP2 BUTTON_VOL_UP
147 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
148 #define MPEG_MENU (BUTTON_REW | BUTTON_REL)
149 #define MPEG_STOP BUTTON_POWER
150 #define MPEG_PAUSE BUTTON_PLAY
151 #define MPEG_VOLDOWN BUTTON_SCROLL_DOWN
152 #define MPEG_VOLUP BUTTON_SCROLL_UP
154 #elif CONFIG_KEYPAD == SANSA_E200_PAD
155 #define MPEG_MENU BUTTON_SELECT
156 #define MPEG_STOP BUTTON_POWER
157 #define MPEG_PAUSE BUTTON_UP
158 #define MPEG_VOLDOWN BUTTON_SCROLL_UP
159 #define MPEG_VOLUP BUTTON_SCROLL_DOWN
161 #else
162 #error MPEGPLAYER: Unsupported keypad
163 #endif
165 struct plugin_api* rb;
167 static mpeg2dec_t * mpeg2dec;
168 static int total_offset = 0;
169 static int num_drawn = 0;
170 static int count_start = 0;
172 /* Streams */
173 typedef struct
175 struct thread_entry *thread; /* Stream's thread */
176 int status; /* Current stream status */
177 struct event ev; /* Event sent to steam */
178 int have_msg; /* 1=event pending */
179 int replied; /* 1=replied to last event */
180 int reply; /* reply value */
181 struct mutex msg_lock; /* serialization for event senders */
182 uint8_t* curr_packet; /* Current stream packet beginning */
183 uint8_t* curr_packet_end; /* Current stream packet end */
185 uint8_t* prev_packet; /* Previous stream packet beginning */
186 uint8_t* next_packet; /* Next stream packet beginning */
188 size_t guard_bytes; /* Number of bytes in guardbuf used */
189 size_t buffer_remaining; /* How much data is left in the buffer */
190 uint32_t curr_pts; /* Current presentation timestamp */
191 uint32_t curr_time; /* Current time in samples */
192 uint32_t tagged; /* curr_pts is valid */
194 int id;
195 } Stream;
197 static Stream audio_str IBSS_ATTR;
198 static Stream video_str IBSS_ATTR;
200 /* Messages */
201 enum
203 STREAM_STOP,
204 STREAM_PLAY,
205 STREAM_PAUSE,
208 /* Status */
209 enum
211 STREAM_ERROR = -4,
212 STREAM_STOPPED = -3,
213 STREAM_TERMINATED = -2,
214 STREAM_DONE = -1,
215 STREAM_PLAYING = 0,
216 STREAM_PAUSED,
217 STREAM_BUFFERING
220 /* Returns true if a message is waiting */
221 static inline bool str_have_msg(Stream *str)
223 return str->have_msg != 0;
226 /* Waits until a message is sent */
227 static void str_wait_msg(Stream *str)
229 /* NOTE: sleep(0) caused a prefectch abort at C0EDBABE on e200 -
230 will look into this oddness */
231 #if 0
232 int spin_count = 0;
233 #endif
235 while (str->have_msg == 0)
237 #if 0
238 if (spin_count < 100)
240 rb->yield();
241 spin_count++;
242 continue;
245 rb->sleep(0);
246 #endif
247 rb->yield();
251 /* Returns a message waiting or blocks until one is available - removes the
252 event */
253 static bool str_get_msg(Stream *str, struct event *ev)
255 str_wait_msg(str);
256 ev->id = str->ev.id;
257 ev->data = str->ev.data;
258 str->have_msg = 0;
259 return true;
262 /* Peeks at the current message without blocking, returns the data but
263 does not remove the event */
264 static bool str_look_msg(Stream *str, struct event *ev)
266 if (!str_have_msg(str))
267 return false;
269 ev->id = str->ev.id;
270 ev->data = str->ev.data;
271 return true;
274 /* Replies to the last message pulled - has no effect if last message has not
275 been pulled or already replied */
276 static void str_reply_msg(Stream *str, int reply)
278 if (str->replied == 1 || str->have_msg != 0)
279 return;
281 str->reply = reply;
282 str->replied = 1;
285 /* Sends a message to a stream and waits for a reply */
286 static intptr_t str_send_msg(Stream *str, int id, intptr_t data)
288 /* NOTE: sleep(0) caused a prefectch abort at C0EDBABE on e200 -
289 will look into this oddness */
290 #if 0
291 int spin_count = 0;
292 #endif
294 intptr_t reply;
296 #if 0
297 if (str->thread == rb->thread_get_current())
298 return str->dispatch_fn(str, msg);
299 #endif
301 /* Only one thread at a time, please */
302 rb->spinlock_lock(&str->msg_lock);
304 str->ev.id = id;
305 str->ev.data = data;
306 str->reply = 0;
307 str->replied = 0;
308 str->have_msg = 1;
310 while (str->replied == 0 && str->status != STREAM_TERMINATED)
312 #if 0
313 if (spin_count < 100)
315 rb->yield();
316 spin_count++;
317 continue;
320 rb->sleep(0);
321 #endif
322 rb->yield();
325 reply = str->reply;
327 rb->spinlock_unlock(&str->msg_lock);
329 return reply;
332 /* NOTE: Putting the following variables in IRAM cause audio corruption
333 on the ipod (reason unknown)
335 static uint8_t *disk_buf IBSS_ATTR;
336 static uint8_t *disk_buf_end IBSS_ATTR;
337 static uint8_t *disk_buf_tail IBSS_ATTR;
338 static size_t buffer_size IBSS_ATTR;
339 #if NUM_CORES > 1
340 /* Some stream variables are shared between cores */
341 struct mutex stream_lock IBSS_ATTR;
342 static inline void init_stream_lock(void)
343 { rb->spinlock_init(&stream_lock); }
344 static inline void lock_stream(void)
345 { rb->spinlock_lock(&stream_lock); }
346 static inline void unlock_stream(void)
347 { rb->spinlock_unlock(&stream_lock); }
348 #else
349 /* No RMW issue here */
350 static inline void init_stream_lock(void)
352 static inline void lock_stream(void)
354 static inline void unlock_stream(void)
356 #endif
358 /* Events */
359 static struct event_queue msg_queue IBSS_ATTR;
361 #define MSG_BUFFER_NEARLY_EMPTY 1
362 #define MSG_EXIT_REQUESTED 2
364 /* Various buffers */
365 /* TODO: Can we reduce the PCM buffer size? */
366 #define PCMBUFFER_SIZE ((512*1024)-PCMBUFFER_GUARD_SIZE)
367 #define PCMBUFFER_GUARD_SIZE (1152*4 + sizeof (struct pcm_frame_header))
368 #define MPA_MAX_FRAME_SIZE 1729 /* Largest frame - MPEG1, Layer II, 384kbps, 32kHz, pad */
369 #define MPABUF_SIZE (64*1024 + ALIGN_UP(MPA_MAX_FRAME_SIZE + 2*MAD_BUFFER_GUARD, 4))
370 #define LIBMPEG2BUFFER_SIZE (2*1024*1024)
372 /* 65536+6 is required since each PES has a 6 byte header with a 16 bit packet length field */
373 #define MPEG_GUARDBUF_SIZE (64*1024+1024) /* Keep a bit extra - excessive for now */
374 #define MPEG_LOW_WATERMARK (1024*1024)
376 static void pcm_playback_play_pause(bool play);
378 /* libmad related functions/definitions */
379 #define INPUT_CHUNK_SIZE 8192
381 struct mad_stream stream IBSS_ATTR;
382 struct mad_frame frame IBSS_ATTR;
383 struct mad_synth synth IBSS_ATTR;
385 unsigned char mad_main_data[MAD_BUFFER_MDLEN]; /* 2567 bytes */
387 static void init_mad(void* mad_frame_overlap)
389 rb->memset(&stream, 0, sizeof(struct mad_stream));
390 rb->memset(&frame, 0, sizeof(struct mad_frame));
391 rb->memset(&synth, 0, sizeof(struct mad_synth));
393 mad_stream_init(&stream);
394 mad_frame_init(&frame);
396 /* We do this so libmad doesn't try to call codec_calloc() */
397 frame.overlap = mad_frame_overlap;
399 rb->memset(mad_main_data, 0, sizeof(mad_main_data));
400 stream.main_data = &mad_main_data;
403 /* MPEG related headers */
405 /* Macros for comparing memory bytes to a series of constant bytes in an
406 efficient manner - evaluate to true if corresponding bytes match */
407 #if defined (CPU_ARM)
408 /* ARM must load 32-bit values at addres % 4 == 0 offsets but this data
409 isn't aligned nescessarily, so just byte compare */
410 #define CMP_3_CONST(_a, _b) \
411 ({ \
412 int _x; \
413 asm volatile ( \
414 "ldrb %[x], [%[a], #0] \r\n" \
415 "eors %[x], %[x], %[b0] \r\n" \
416 "ldreqb %[x], [%[a], #1] \r\n" \
417 "eoreqs %[x], %[x], %[b1] \r\n" \
418 "ldreqb %[x], [%[a], #2] \r\n" \
419 "eoreqs %[x], %[x], %[b2] \r\n" \
420 : [x]"=&r"(_x) \
421 : [a]"r"(_a), \
422 [b0]"i"((_b) >> 24), \
423 [b1]"i"((_b) << 8 >> 24), \
424 [b2]"i"((_b) << 16 >> 24) \
425 ); \
426 _x == 0; \
428 #define CMP_4_CONST(_a, _b) \
429 ({ \
430 int _x; \
431 asm volatile ( \
432 "ldrb %[x], [%[a], #0] \r\n" \
433 "eors %[x], %[x], %[b0] \r\n" \
434 "ldreqb %[x], [%[a], #1] \r\n" \
435 "eoreqs %[x], %[x], %[b1] \r\n" \
436 "ldreqb %[x], [%[a], #2] \r\n" \
437 "eoreqs %[x], %[x], %[b2] \r\n" \
438 "ldreqb %[x], [%[a], #3] \r\n" \
439 "eoreqs %[x], %[x], %[b3] \r\n" \
440 : [x]"=&r"(_x) \
441 : [a]"r"(_a), \
442 [b0]"i"((_b) >> 24), \
443 [b1]"i"((_b) << 8 >> 24), \
444 [b2]"i"((_b) << 16 >> 24), \
445 [b3]"i"((_b) << 24 >> 24) \
446 ); \
447 _x == 0; \
449 #elif defined (CPU_COLDFIRE)
450 /* Coldfire can just load a 32 bit value at any offset but ASM is not the best way
451 to integrate this with the C code */
452 #define CMP_3_CONST(a, b) \
453 (((*(uint32_t *)(a) >> 8) ^ ((uint32_t)(b) >> 8)) == 0)
454 #define CMP_4_CONST(a, b) \
455 ((*(uint32_t *)(a) ^ (b)) == 0)
456 #else
457 /* Don't know what this is - use bytewise comparisons */
458 #define CMP_3_CONST(a, b) \
459 (( ((a)[0] ^ ((b) >> 24)) | \
460 ((a)[1] ^ ((b) << 8 >> 24)) | \
461 ((a)[2] ^ ((b) << 16 >> 24)) ) == 0)
462 #define CMP_4_CONST(a, b) \
463 (( ((a)[0] ^ ((b) >> 24)) | \
464 ((a)[1] ^ ((b) << 8 >> 24)) | \
465 ((a)[2] ^ ((b) << 16 >> 24)) | \
466 ((a)[3] ^ ((b) << 24 >> 24)) ) == 0)
467 #endif
469 /* Codes for various header byte sequences - MSB represents lowest memory
470 address */
471 #define PACKET_START_CODE_PREFIX 0x00000100ul
472 #define END_CODE 0x000001b9ul
473 #define PACK_START_CODE 0x000001baul
474 #define SYSTEM_HEADER_START_CODE 0x000001bbul
476 /* p = base pointer, b0 - b4 = byte offsets from p */
477 /* We only care about the MS 32 bits of the 33 and so the ticks are 45kHz */
478 #define TS_FROM_HEADER(p, b0, b1, b2, b3, b4) \
479 ((uint32_t)(((p)[b0] >> 1 << 29) | \
480 ((p)[b1] << 21) | \
481 ((p)[b2] >> 1 << 14) | \
482 ((p)[b3] << 6) | \
483 ((p)[b4] >> 2 )))
485 /* This function demuxes the streams and gives the next stream data pointer */
486 static void get_next_data( Stream* str )
488 uint8_t *p;
489 uint8_t *header;
490 int stream;
492 static int mpeg1_skip_table[16] =
493 { 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
495 if (str->curr_packet_end == NULL)
497 /* What does this do? */
498 while ((p = disk_buf) == NULL)
500 rb->lcd_putsxy(0,LCD_HEIGHT-10,"FREEZE!");
501 rb->lcd_update();
502 rb->sleep(HZ);
505 else
507 p = str->curr_packet_end;
510 while (1)
512 int length, bytes;
514 if (p >= disk_buf_end)
516 p = disk_buf + (p - disk_buf_end);
519 /* Pack header, skip it */
520 if (CMP_4_CONST(p, PACK_START_CODE))
522 if ((p[4] & 0xc0) == 0x40) /* mpeg-2 */
524 p += 14 + (p[13] & 7);
526 else if ((p[4] & 0xf0) == 0x20) /* mpeg-1 */
528 p += 12;
530 else
532 rb->splash( 30, "Weird Pack header!" );
533 p += 5;
535 /*rb->splash( 30, "Pack header" );*/
538 /* System header, parse and skip it - four bytes */
539 if (CMP_4_CONST(p, SYSTEM_HEADER_START_CODE))
541 int header_length;
543 p += 4; /*skip start code*/
544 header_length = *p++ << 8;
545 header_length += *p++;
547 p += header_length;
549 if (p >= disk_buf_end)
551 p = disk_buf + (p - disk_buf_end);
553 /*rb->splash( 30, "System header" );*/
556 /* Packet header, parse it */
557 if (!CMP_3_CONST(p, PACKET_START_CODE_PREFIX))
559 /* Problem */
560 //rb->splash( HZ*3, "missing packet start code prefix : %X%X at %X", *p, *(p+2), p-disk_buf );
561 str->curr_packet_end = str->curr_packet = NULL;
562 break;
563 //++p;
564 //break;
567 /* We retrieve basic infos */
568 stream = p[3];
569 length = (p[4] << 8) | p[5];
571 /*rb->splash( 100, "Stream : %X", stream );*/
572 if (stream != str->id)
574 /* End of stream ? */
575 if (stream == 0xB9)
577 str->curr_packet_end = str->curr_packet = NULL;
578 break;
581 /* It's not the packet we're looking for, skip it */
582 p += length + 6;
583 continue;
586 /* Ok, it's our packet */
587 str->curr_packet_end = p + length+6;
588 header = p;
590 if ((header[6] & 0xc0) == 0x80) /* mpeg2 */
592 length = 9 + header[8];
594 /* header points to the mpeg2 pes header */
595 if (header[7] & 0x80)
597 /* header has a pts */
598 uint32_t pts = TS_FROM_HEADER(header, 9, 10, 11, 12, 13);
600 if (stream >= 0xe0)
602 /* video stream - header may have a dts as well */
603 uint32_t dts = (header[7] & 0x40) == 0 ?
604 pts : TS_FROM_HEADER(header, 14, 15, 16, 17, 18);
606 mpeg2_tag_picture (mpeg2dec, pts, dts);
608 else
610 str->curr_pts = pts;
611 str->tagged = 1;
615 else /* mpeg1 */
617 int len_skip;
618 uint8_t * ptsbuf;
620 length = 7;
622 while (header[length - 1] == 0xff)
624 length++;
625 if (length > 23)
627 rb->splash( 30, "Too much stuffing" );
628 DEBUGF("Too much stuffing" );
629 break;
633 if ((header[length - 1] & 0xc0) == 0x40)
635 length += 2;
638 len_skip = length;
639 length += mpeg1_skip_table[header[length - 1] >> 4];
641 /* header points to the mpeg1 pes header */
642 ptsbuf = header + len_skip;
644 if ((ptsbuf[-1] & 0xe0) == 0x20)
646 /* header has a pts */
647 uint32_t pts = TS_FROM_HEADER(ptsbuf, -1, 0, 1, 2, 3);
649 if (stream >= 0xe0)
651 /* video stream - header may have a dts as well */
652 uint32_t dts = (ptsbuf[-1] & 0xf0) != 0x30 ?
653 pts : TS_FROM_HEADER(ptsbuf, 4, 5, 6, 7, 18);
655 mpeg2_tag_picture (mpeg2dec, pts, dts);
657 else
659 str->curr_pts = pts;
660 str->tagged = 1;
665 p += length;
666 bytes = 6 + (header[4] << 8) + header[5] - length;
668 if (bytes > 0)
670 str->curr_packet_end = p + bytes;
671 //DEBUGF("prev = %d, curr = %d\n",str->prev_packet,str->curr_packet);
673 if (str->curr_packet != NULL)
675 lock_stream();
677 if (str->curr_packet < str->prev_packet)
679 str->buffer_remaining -= (disk_buf_end - str->prev_packet) +
680 (str->curr_packet - disk_buf);
681 str->buffer_remaining -= str->guard_bytes;
682 str->guard_bytes = 0;
684 else
686 str->buffer_remaining -= (str->curr_packet - str->prev_packet);
689 unlock_stream();
691 str->prev_packet = str->curr_packet;
694 str->curr_packet = p;
696 if (str->curr_packet_end > disk_buf_end)
698 str->guard_bytes = str->curr_packet_end - disk_buf_end;
699 rb->memcpy(disk_buf_end, disk_buf, str->guard_bytes);
703 break;
704 } /* end while */
707 /* Our clock rate in ticks/second - this won't be a constant for long */
708 #define CLOCK_RATE 44100
710 /* For simple lowpass filtering of sync variables */
711 #define AVERAGE(var, x, count) (((var) * (count-1) + (x)) / (count))
712 /* Convert 45kHz PTS/DTS ticks to our clock ticks */
713 #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / 45000)
714 /* Convert 27MHz ticks to our clock ticks */
715 #define TIME_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / 27000000)
717 /** MPEG audio stream buffer */
718 uint8_t* mpa_buffer;
720 static bool init_mpabuf(void)
722 mpa_buffer = mpeg2_malloc(MPABUF_SIZE,-2);
723 return mpa_buffer != NULL;
726 #define PTS_QUEUE_LEN (1 << 5) /* 32 should be way more than sufficient -
727 if not, the case is handled */
728 #define PTS_QUEUE_MASK (PTS_QUEUE_LEN-1)
729 struct pts_queue_slot
731 uint32_t pts; /* Time stamp for packet */
732 ssize_t size; /* Number of bytes left in packet */
733 } pts_queue[PTS_QUEUE_LEN];
735 /* This starts out wr == rd but will never be emptied to zero during
736 streaming again in order to support initializing the first packet's
737 pts value without a special case */
738 static unsigned pts_queue_rd;
739 static unsigned pts_queue_wr;
741 /* Increments the queue head postion - should be used to preincrement */
742 static bool pts_queue_add_head(void)
744 if (pts_queue_wr - pts_queue_rd >= PTS_QUEUE_LEN-1)
745 return false;
747 pts_queue_wr++;
748 return true;
751 /* Increments the queue tail position - leaves one slot as current */
752 static bool pts_queue_remove_tail(void)
754 if (pts_queue_wr - pts_queue_rd <= 1u)
755 return false;
757 pts_queue_rd++;
758 return true;
761 /* Returns the "head" at the index just behind the write index */
762 static struct pts_queue_slot * pts_queue_head(void)
764 return &pts_queue[(pts_queue_wr - 1) & PTS_QUEUE_MASK];
767 /* Returns a pointer to the current tail */
768 static struct pts_queue_slot * pts_queue_tail(void)
770 return &pts_queue[pts_queue_rd & PTS_QUEUE_MASK];
773 /* Resets the pts queue - call when starting and seeking */
774 static void pts_queue_reset(void)
776 struct pts_queue_slot *pts;
777 pts_queue_rd = pts_queue_wr;
778 pts = pts_queue_tail();
779 pts->pts = 0;
780 pts->size = 0;
783 struct pcm_frame_header /* Header added to pcm data every time a decoded
784 mpa frame is sent out */
786 uint32_t size; /* size of this frame - including header */
787 uint32_t time; /* timestamp for this frame - derived from PTS */
788 unsigned char data[]; /* open array of audio data */
791 #define PCMBUF_PLAY_ALL 1l /* Forces buffer to play back all data */
792 #define PCMBUF_PLAY_NONE LONG_MAX /* Keeps buffer from playing any data */
793 static volatile uint64_t pcmbuf_read IBSS_ATTR;
794 static volatile uint64_t pcmbuf_written IBSS_ATTR;
795 static volatile ssize_t pcmbuf_threshold IBSS_ATTR;
796 static struct pcm_frame_header *pcm_buffer IBSS_ATTR;
797 static struct pcm_frame_header *pcmbuf_end IBSS_ATTR;
798 static struct pcm_frame_header * volatile pcmbuf_head IBSS_ATTR;
799 static struct pcm_frame_header * volatile pcmbuf_tail IBSS_ATTR;
801 static volatile uint32_t samplesplayed IBSS_ATTR; /* Our base clock */
802 static volatile uint32_t samplestart IBSS_ATTR; /* Clock at playback start */
803 static volatile int32_t sampleadjust IBSS_ATTR; /* Clock drift adjustment */
805 static ssize_t pcmbuf_used(void)
807 return (ssize_t)(pcmbuf_written - pcmbuf_read);
810 static bool init_pcmbuf(void)
812 pcm_buffer = mpeg2_malloc(PCMBUFFER_SIZE + PCMBUFFER_GUARD_SIZE, -2);
814 if (pcm_buffer == NULL)
815 return false;
817 pcmbuf_head = pcm_buffer;
818 pcmbuf_tail = pcm_buffer;
819 pcmbuf_end = SKIPBYTES(pcm_buffer, PCMBUFFER_SIZE);
820 pcmbuf_read = 0;
821 pcmbuf_written = 0;
823 return true;
826 /* Advance a PCM buffer pointer by size bytes circularly */
827 static inline void pcm_advance_buffer(struct pcm_frame_header * volatile *p,
828 size_t size)
830 *p = SKIPBYTES(*p, size);
831 if (*p >= pcmbuf_end)
832 *p = pcm_buffer;
835 static void get_more(unsigned char** start, size_t* size)
837 /* 25ms @ 44.1kHz */
838 static unsigned char silence[4412] __attribute__((aligned (4))) = { 0 };
839 size_t sz;
841 if (pcmbuf_used() >= pcmbuf_threshold)
843 uint32_t time = pcmbuf_tail->time;
844 sz = pcmbuf_tail->size;
846 *start = (unsigned char *)pcmbuf_tail->data;
848 pcm_advance_buffer(&pcmbuf_tail, sz);
850 pcmbuf_read += sz;
852 sz -= sizeof (*pcmbuf_tail);
854 *size = sz;
856 /* Drift the clock towards the audio timestamp values */
857 sampleadjust = AVERAGE(sampleadjust, (int32_t)(time - samplesplayed), 8);
859 /* Update master clock */
860 samplesplayed += sz >> 2;
861 return;
864 /* Keep clock going at all times */
865 sz = sizeof (silence);
866 *start = silence;
867 *size = sz;
869 samplesplayed += sz >> 2;
871 if (pcmbuf_read > pcmbuf_written)
872 pcmbuf_read = pcmbuf_written;
875 /* Flushes the buffer - clock keeps counting */
876 static void pcm_playback_flush(void)
878 bool was_playing = rb->pcm_is_playing();
880 if (was_playing)
881 rb->pcm_play_stop();
883 pcmbuf_read = 0;
884 pcmbuf_written = 0;
885 pcmbuf_head = pcmbuf_tail;
887 if (was_playing)
888 rb->pcm_play_data(get_more, NULL, 0);
891 /* Seek the reference clock to the specified time - next audio data ready to
892 go to DMA should be on the buffer with the same time index or else the PCM
893 buffer should be empty */
894 static void pcm_playback_seek_time(uint32_t time)
896 bool was_playing = rb->pcm_is_playing();
898 if (was_playing)
899 rb->pcm_play_stop();
901 samplesplayed = time;
902 samplestart = time;
903 sampleadjust = 0;
905 if (was_playing)
906 rb->pcm_play_data(get_more, NULL, 0);
909 /* Start pcm playback with the reference clock set to the specified time */
910 static void pcm_playback_play(uint32_t time)
912 pcm_playback_seek_time(time);
914 if (!rb->pcm_is_playing())
915 rb->pcm_play_data(get_more, NULL, 0);
918 /* Pauses playback - and the clock */
919 static void pcm_playback_play_pause(bool play)
921 rb->pcm_play_pause(play);
924 /* Stops all playback and resets the clock */
925 static void pcm_playback_stop(void)
927 if (rb->pcm_is_playing())
928 rb->pcm_play_stop();
930 pcm_playback_flush();
932 sampleadjust =
933 samplestart =
934 samplesplayed = 0;
937 static uint32_t get_stream_time(void)
939 return samplesplayed + sampleadjust - (rb->pcm_get_bytes_waiting() >> 2);
942 static uint32_t get_playback_time(void)
944 return samplesplayed + sampleadjust -
945 samplestart - (rb->pcm_get_bytes_waiting() >> 2);
948 static inline int32_t clip_sample(int32_t sample)
950 if ((int16_t)sample != sample)
951 sample = 0x7fff ^ (sample >> 31);
953 return sample;
956 static int button_loop(void)
958 bool result;
959 int vol, minvol, maxvol;
960 int button;
962 if (str_have_msg(&audio_str))
964 struct event ev;
965 str_get_msg(&audio_str, &ev);
967 if (ev.id == STREAM_STOP)
969 audio_str.status = STREAM_STOPPED;
970 str_reply_msg(&audio_str, 1);
971 goto quit;
973 else
975 str_reply_msg(&audio_str, 0);
979 button = rb->button_get(false);
981 switch (button)
983 case MPEG_VOLUP:
984 case MPEG_VOLUP|BUTTON_REPEAT:
985 #ifdef MPEG_VOLUP2
986 case MPEG_VOLUP2:
987 case MPEG_VOLUP2|BUTTON_REPEAT:
988 #endif
989 vol = rb->global_settings->volume;
990 maxvol = rb->sound_max(SOUND_VOLUME);
992 if (vol < maxvol) {
993 vol++;
994 rb->sound_set(SOUND_VOLUME, vol);
995 rb->global_settings->volume = vol;
997 break;
999 case MPEG_VOLDOWN:
1000 case MPEG_VOLDOWN|BUTTON_REPEAT:
1001 #ifdef MPEG_VOLDOWN2
1002 case MPEG_VOLDOWN2:
1003 case MPEG_VOLDOWN2|BUTTON_REPEAT:
1004 #endif
1005 vol = rb->global_settings->volume;
1006 minvol = rb->sound_min(SOUND_VOLUME);
1008 if (vol > minvol) {
1009 vol--;
1010 rb->sound_set(SOUND_VOLUME, vol);
1011 rb->global_settings->volume = vol;
1013 break;
1015 case MPEG_MENU:
1016 pcm_playback_play_pause(false);
1017 audio_str.status = STREAM_PAUSED;
1018 str_send_msg(&video_str, STREAM_PAUSE, 0);
1019 #ifndef HAVE_LCD_COLOR
1020 gray_show(false);
1021 #endif
1022 result = mpeg_menu();
1023 count_start = get_playback_time();
1024 num_drawn = 0;
1026 #ifndef HAVE_LCD_COLOR
1027 gray_show(true);
1028 #endif
1030 /* The menu can change the font, so restore */
1031 rb->lcd_setfont(FONT_SYSFIXED);
1033 if (result) {
1034 str_send_msg(&video_str, STREAM_STOP, 0);
1035 audio_str.status = STREAM_STOPPED;
1036 } else {
1037 audio_str.status = STREAM_PLAYING;
1038 str_send_msg(&video_str, STREAM_PLAY, 0);
1039 pcm_playback_play_pause(true);
1041 break;
1043 case MPEG_STOP:
1044 str_send_msg(&video_str, STREAM_STOP, 0);
1045 audio_str.status = STREAM_STOPPED;
1046 break;
1048 case MPEG_PAUSE:
1049 str_send_msg(&video_str, STREAM_PAUSE, 0);
1050 audio_str.status = STREAM_PAUSED;
1051 pcm_playback_play_pause(false);
1053 button = BUTTON_NONE;
1054 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1055 rb->cpu_boost(false);
1056 #endif
1057 do {
1058 button = rb->button_get(true);
1059 if (button == MPEG_STOP) {
1060 str_send_msg(&video_str, STREAM_STOP, 0);
1061 audio_str.status = STREAM_STOPPED;
1062 goto quit;
1064 } while (button != MPEG_PAUSE);
1066 str_send_msg(&video_str, STREAM_PLAY, 0);
1067 audio_str.status = STREAM_PLAYING;
1068 pcm_playback_play_pause(true);
1069 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1070 rb->cpu_boost(true);
1071 #endif
1072 break;
1074 default:
1075 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) {
1076 str_send_msg(&video_str, STREAM_STOP, 0);
1077 audio_str.status = STREAM_STOPPED;
1081 quit:
1082 return audio_str.status;
1085 static void audio_thread(void)
1087 uint8_t *mpabuf = mpa_buffer;
1088 ssize_t mpabuf_used = 0;
1089 int mad_errors = 0; /* A count of the errors in each frame */
1090 struct pts_queue_slot *pts;
1092 /* We need this here to init the EMAC for Coldfire targets */
1093 mad_synth_init(&synth);
1095 /* Init pts queue */
1096 pts_queue_reset();
1097 pts = pts_queue_tail();
1099 /* Keep buffer from playing */
1100 pcmbuf_threshold = PCMBUF_PLAY_NONE;
1102 /* Start clock */
1103 pcm_playback_play(0);
1105 /* Get first packet */
1106 get_next_data(&audio_str);
1108 if (audio_str.curr_packet == NULL)
1109 goto done;
1111 /* This is the decoding loop. */
1112 while (1)
1114 int mad_stat;
1115 size_t len;
1117 if (button_loop() < 0)
1118 goto done;
1120 if (pts->size <= 0)
1122 /* Carry any overshoot to the next size since we're technically
1123 -pts->size bytes into it already. If size is negative an audio
1124 frame was split accross packets. Old has to be saved before
1125 moving the tail. */
1126 if (pts_queue_remove_tail())
1128 struct pts_queue_slot *old = pts;
1129 pts = pts_queue_tail();
1130 pts->size += old->size;
1131 old->size = 0;
1135 /** Buffering **/
1136 if (mpabuf_used >= MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD)
1138 /* Above low watermark - do nothing */
1140 else if (audio_str.curr_packet != NULL)
1144 /* Get data from next audio packet */
1145 len = audio_str.curr_packet_end - audio_str.curr_packet;
1147 if (audio_str.tagged)
1149 struct pts_queue_slot *stamp = pts;
1151 if (pts_queue_add_head())
1153 stamp = pts_queue_head();
1154 stamp->pts = TS_TO_TICKS(audio_str.curr_pts);
1155 /* pts->size should have been zeroed when slot was
1156 freed */
1158 /* else queue full - just count up from the last to make
1159 it look like more data in the same packet */
1160 stamp->size += len;
1161 audio_str.tagged = 0;
1163 else
1165 /* Add to the one just behind the head - this may be the
1166 tail or the previouly added head - whether or not we'll
1167 ever reach this is quite in question since audio always
1168 seems to have every packet timestamped */
1169 pts_queue_head()->size += len;
1172 /* Slide any remainder over to beginning - avoid function
1173 call overhead if no data remaining as well */
1174 if (mpabuf > mpa_buffer && mpabuf_used > 0)
1175 rb->memmove(mpa_buffer, mpabuf, mpabuf_used);
1177 /* Splice this packet onto any remainder */
1178 rb->memcpy(mpa_buffer + mpabuf_used, audio_str.curr_packet,
1179 len);
1181 mpabuf_used += len;
1182 mpabuf = mpa_buffer;
1184 /* Get data from next audio packet */
1185 get_next_data(&audio_str);
1187 while (audio_str.curr_packet != NULL &&
1188 mpabuf_used < MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD);
1190 else if (mpabuf_used <= 0)
1192 /* Used up remainder of mpa buffer so quit */
1193 break;
1196 /** Decoding **/
1197 mad_stream_buffer(&stream, mpabuf, mpabuf_used);
1199 mad_stat = mad_frame_decode(&frame, &stream);
1201 if (stream.next_frame == NULL)
1203 /* What to do here? (This really is fatal) */
1204 DEBUGF("/* What to do here? */\n");
1205 break;
1208 /* Next mad stream buffer is the next frame postion */
1209 mpabuf = (uint8_t *)stream.next_frame;
1211 /* Adjust sizes by the frame size */
1212 len = stream.next_frame - stream.this_frame;
1213 mpabuf_used -= len;
1214 pts->size -= len;
1216 if (mad_stat != 0)
1218 DEBUGF("Audio stream error - %d\n", stream.error);
1220 if (stream.error == MAD_FLAG_INCOMPLETE
1221 || stream.error == MAD_ERROR_BUFLEN)
1223 /* This makes the codec support partially corrupted files */
1224 if (++mad_errors > 30)
1225 break;
1227 stream.error = 0;
1228 rb->priority_yield();
1229 continue;
1231 else if (MAD_RECOVERABLE(stream.error))
1233 stream.error = 0;
1234 rb->priority_yield();
1235 continue;
1237 else
1239 /* Some other unrecoverable error */
1240 DEBUGF("Unrecoverable error\n");
1243 break;
1246 mad_errors = 0; /* Clear errors */
1248 /* Generate the pcm samples */
1249 mad_synth_frame(&synth, &frame);
1251 /** Output **/
1253 /* TODO: Output through core dsp. We'll still use our own PCM buffer
1254 since the core pcm buffer has no timestamping or clock facilities */
1256 /* Add a frame of audio to the pcm buffer. Maximum is 1152 samples. */
1257 if (synth.pcm.length > 0)
1259 int16_t *audio_data = (int16_t *)pcmbuf_head->data;
1260 size_t size = sizeof (*pcmbuf_head) + synth.pcm.length*4;
1261 size_t wait_for = size + 32*1024;
1263 /* Leave at least 32KB free (this will be the currently
1264 playing chunk) */
1265 while (pcmbuf_used() + wait_for > PCMBUFFER_SIZE)
1267 if (str_have_msg(&audio_str))
1269 struct event ev;
1270 str_look_msg(&audio_str, &ev);
1272 if (ev.id == STREAM_STOP)
1274 str_get_msg(&audio_str, &ev);
1275 str_reply_msg(&audio_str, 1);
1276 goto stop_and_wait;
1280 rb->priority_yield();
1283 /* TODO: This part will be replaced with dsp calls soon */
1284 if (MAD_NCHANNELS(&frame.header) == 2)
1286 int32_t *left = &synth.pcm.samples[0][0];
1287 int32_t *right = &synth.pcm.samples[1][0];
1288 int i = synth.pcm.length;
1292 /* libmad outputs s3.28 */
1293 *audio_data++ = clip_sample(*left++ >> 13);
1294 *audio_data++ = clip_sample(*right++ >> 13);
1296 while (--i > 0);
1298 else /* mono */
1300 int32_t *mono = &synth.pcm.samples[0][0];
1301 int i = synth.pcm.length;
1305 int32_t s = clip_sample(*mono++ >> 13);
1306 *audio_data++ = s;
1307 *audio_data++ = s;
1309 while (--i > 0);
1311 /**/
1313 pcmbuf_head->time = pts->pts;
1314 pcmbuf_head->size = size;
1316 /* As long as we're on this timestamp, the time is just incremented
1317 by the number of samples */
1318 pts->pts += synth.pcm.length;
1320 pcm_advance_buffer(&pcmbuf_head, size);
1322 if (pcmbuf_threshold != PCMBUF_PLAY_ALL && pcmbuf_used() >= 64*1024)
1324 /* We've reached our size treshold so start playing back the
1325 audio in the buffer and set the buffer to play all data */
1326 audio_str.status = STREAM_PLAYING;
1327 pcmbuf_threshold = PCMBUF_PLAY_ALL;
1328 pcm_playback_seek_time(pcmbuf_tail->time);
1331 /* Make this data available to DMA */
1332 pcmbuf_written += size;
1335 rb->yield();
1336 } /* end decoding loop */
1338 done:
1339 if (audio_str.status == STREAM_STOPPED)
1340 goto stop_and_wait;
1342 /* Force any residue to play if audio ended before reaching the
1343 threshold */
1344 if (pcmbuf_threshold != PCMBUF_PLAY_ALL && pcmbuf_used() > 0)
1346 pcm_playback_play(pcmbuf_tail->time);
1347 pcmbuf_threshold = PCMBUF_PLAY_ALL;
1350 if (rb->pcm_is_playing() && !rb->pcm_is_paused())
1352 /* Wait for audio to finish */
1353 while (pcmbuf_used() > 0)
1355 if (button_loop() == STREAM_STOPPED)
1356 break;
1357 rb->sleep(HZ/10);
1361 stop_and_wait:
1363 audio_str.status = STREAM_DONE;
1365 /* Process events until finished */
1366 while (button_loop() != STREAM_STOPPED)
1367 rb->sleep(HZ/4);
1369 pcm_playback_stop();
1371 audio_str.status = STREAM_TERMINATED;
1372 rb->remove_thread(NULL);
1375 /* End of libmad stuff */
1377 /* TODO: Running in the main thread, libmad needs 8.25KB of stack.
1378 The codec thread uses a 9KB stack. So we can probable reduce this a
1379 little, but leave at 9KB for now to be safe. */
1380 #define AUDIO_STACKSIZE (9*1024)
1381 uint32_t audio_stack[AUDIO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR;
1383 /* TODO: Check if 4KB is appropriate - it works for my test streams,
1384 so maybe we can reduce it. */
1385 #define VIDEO_STACKSIZE (4*1024)
1386 static uint32_t video_stack[VIDEO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR;
1388 static void video_thread(void)
1390 struct event ev;
1391 const mpeg2_info_t * info;
1392 mpeg2_state_t state;
1393 char str[80];
1394 uint32_t curr_time = 0;
1395 uint32_t period = 0; /* Frame period in clock ticks */
1396 uint32_t eta_audio = UINT_MAX, eta_video = 0;
1397 int32_t eta_early = 0, eta_late = 0;
1398 int frame_drop_level = 0;
1399 int skip_level = 0;
1400 int num_skipped = 0;
1401 /* Used to decide when to display FPS */
1402 unsigned long last_showfps = *rb->current_tick - HZ;
1403 /* Used to decide whether or not to force a frame update */
1404 unsigned long last_render = last_showfps;
1406 mpeg2dec = mpeg2_init();
1407 if (mpeg2dec == NULL)
1409 rb->splash(0, "mpeg2_init failed");
1410 /* Commit suicide */
1411 video_str.status = STREAM_TERMINATED;
1412 rb->remove_thread(NULL);
1415 /* Clear the display - this is mainly just to indicate that the
1416 video thread has started successfully. */
1417 rb->lcd_clear_display();
1418 rb->lcd_update();
1420 /* Request the first packet data */
1421 get_next_data( &video_str );
1423 if (video_str.curr_packet == NULL)
1424 goto done;
1426 mpeg2_buffer (mpeg2dec, video_str.curr_packet, video_str.curr_packet_end);
1427 total_offset += video_str.curr_packet_end - video_str.curr_packet;
1429 info = mpeg2_info (mpeg2dec);
1431 /* Wait if the audio thread is buffering - i.e. before
1432 the first frames are decoded */
1433 while (audio_str.status == STREAM_BUFFERING)
1434 rb->priority_yield();
1436 while (1)
1438 /* quickly check mailbox first */
1439 if (str_have_msg(&video_str))
1441 while (1)
1443 str_get_msg(&video_str, &ev);
1445 switch (ev.id)
1447 case STREAM_STOP:
1448 video_str.status = STREAM_STOPPED;
1449 str_reply_msg(&video_str, 1);
1450 goto done;
1451 case STREAM_PAUSE:
1452 flush_icache();
1453 video_str.status = STREAM_PAUSED;
1454 str_reply_msg(&video_str, 1);
1455 continue;
1458 break;
1461 video_str.status = STREAM_PLAYING;
1462 str_reply_msg(&video_str, 1);
1465 state = mpeg2_parse (mpeg2dec);
1466 rb->yield();
1468 /* Prevent idle poweroff */
1469 rb->reset_poweroff_timer();
1471 switch (state)
1473 case STATE_BUFFER:
1474 /* Request next packet data */
1475 get_next_data( &video_str );
1476 mpeg2_buffer (mpeg2dec, video_str.curr_packet, video_str.curr_packet_end);
1477 total_offset += video_str.curr_packet_end - video_str.curr_packet;
1478 info = mpeg2_info (mpeg2dec);
1480 if (video_str.curr_packet == NULL)
1482 /* No more data. */
1483 goto done;
1485 continue;
1487 case STATE_SEQUENCE:
1488 /* New GOP, inform output of any changes */
1489 vo_setup(info->sequence);
1490 break;
1492 case STATE_PICTURE:
1494 int skip = 0; /* Assume no skip */
1496 if (frame_drop_level >= 1 || skip_level > 0)
1498 /* A frame will be dropped in the decoder */
1500 /* Frame type: I/P/B/D */
1501 int type = info->current_picture->flags & PIC_MASK_CODING_TYPE;
1503 switch (type)
1505 case PIC_FLAG_CODING_TYPE_I:
1506 case PIC_FLAG_CODING_TYPE_D:
1507 /* Level 5: Things are extremely late and all frames will be
1508 dropped until the next key frame */
1509 if (frame_drop_level >= 1)
1510 frame_drop_level = 0; /* Key frame - reset drop level */
1511 if (skip_level >= 5)
1513 frame_drop_level = 1;
1514 skip_level = 0; /* reset */
1516 break;
1517 case PIC_FLAG_CODING_TYPE_P:
1518 /* Level 4: Things are very late and all frames will be
1519 dropped until the next key frame */
1520 if (skip_level >= 4)
1522 frame_drop_level = 1;
1523 skip_level = 0; /* reset */
1525 break;
1526 case PIC_FLAG_CODING_TYPE_B:
1527 /* We want to drop something, so this B frame won't even
1528 be decoded. Drawing can happen on the next frame if so
1529 desired. Bring the level down as skips are done. */
1530 skip = 1;
1531 if (skip_level > 0)
1532 skip_level--;
1535 skip |= frame_drop_level;
1538 mpeg2_skip(mpeg2dec, skip);
1539 break;
1542 case STATE_SLICE:
1543 case STATE_END:
1544 case STATE_INVALID_END:
1546 int32_t offset; /* Tick adjustment to keep sync */
1548 /* draw current picture */
1549 if (!info->display_fbuf)
1550 break;
1552 /* No limiting => no dropping - draw this frame */
1553 if (!settings.limitfps)
1554 goto picture_draw;
1556 /* Get presentation times in audio samples - quite accurate
1557 enough - add previous frame duration if not stamped */
1558 curr_time = (info->display_picture->flags & PIC_FLAG_TAGS) ?
1559 TS_TO_TICKS(info->display_picture->tag) : (curr_time + period);
1561 period = TIME_TO_TICKS(info->sequence->frame_period);
1563 eta_video = curr_time;
1564 eta_audio = get_stream_time();
1566 /* How early/late are we? > 0 = late, < 0 early */
1567 offset = eta_audio - eta_video;
1569 if (!settings.skipframes)
1571 /* Make no effort to determine whether this frame should be
1572 drawn or not since no action can be taken to correct the
1573 situation. We'll just wait if we're early and correct for
1574 lateness as much as possible. */
1575 if (offset < 0)
1576 offset = 0;
1578 eta_late = AVERAGE(eta_late, offset, 4);
1579 offset = eta_late;
1581 if ((uint32_t)offset > eta_video)
1582 offset = eta_video;
1584 eta_video -= offset;
1585 goto picture_wait;
1588 /** Possibly skip this frame **/
1590 /* Frameskipping has the following order of preference:
1592 * Frame Type Who Notes/Rationale
1593 * B decoder arbitrarily drop - no decode or draw
1594 * Any renderer arbitrarily drop - will be I/D/P
1595 * P decoder must wait for I/D-frame - choppy
1596 * I/D decoder must wait for I/D-frame - choppy
1598 * If a frame can be drawn and it has been at least 1/2 second,
1599 * the image will be updated no matter how late it is just to
1600 * avoid looking stuck.
1603 /* If we're late, set the eta to play the frame early so
1604 we may catch up. If early, especially because of a drop,
1605 mitigate a "snap" by moving back gradually. */
1606 if (offset >= 0) /* late or on time */
1608 eta_early = 0; /* Not early now :( */
1610 eta_late = AVERAGE(eta_late, offset, 4);
1611 offset = eta_late;
1613 if ((uint32_t)offset > eta_video)
1614 offset = eta_video;
1616 eta_video -= offset;
1618 else
1620 eta_late = 0; /* Not late now :) */
1622 if (offset > eta_early)
1624 /* Just dropped a frame and we're now early or we're
1625 coming back from being early */
1626 eta_early = offset;
1627 if ((uint32_t)-offset > eta_video)
1628 offset = -eta_video;
1630 eta_video += offset;
1632 else
1634 /* Just early with an offset, do exponential drift back */
1635 if (eta_early != 0)
1637 eta_early = AVERAGE(eta_early, 0, 8);
1638 eta_video = ((uint32_t)-eta_early > eta_video) ?
1639 0 : (eta_video + eta_early);
1642 offset = eta_early;
1646 if (info->display_picture->flags & PIC_FLAG_SKIP)
1648 /* This frame was set to skip so skip it after having updated
1649 timing information */
1650 num_skipped++;
1651 eta_early = INT32_MIN;
1652 goto picture_skip;
1655 if (skip_level == 3 && TIME_BEFORE(*rb->current_tick, last_render + HZ/2))
1657 /* Render drop was set previously but nothing was dropped in the
1658 decoder or it's been to long since drawing the last frame. */
1659 skip_level = 0;
1660 num_skipped++;
1661 eta_early = INT32_MIN;
1662 goto picture_skip;
1665 /* At this point a frame _will_ be drawn - a skip may happen on
1666 the next however */
1667 skip_level = 0;
1669 if (offset > CLOCK_RATE*110/1000)
1671 /* Decide which skip level is needed in order to catch up */
1673 /* TODO: Calculate this rather than if...else - this is rather
1674 exponential though */
1675 if (offset > CLOCK_RATE*367/1000)
1676 skip_level = 5; /* Decoder skip: I/D */
1677 if (offset > CLOCK_RATE*233/1000)
1678 skip_level = 4; /* Decoder skip: P */
1679 else if (offset > CLOCK_RATE*167/1000)
1680 skip_level = 3; /* Render skip */
1681 else if (offset > CLOCK_RATE*133/1000)
1682 skip_level = 2; /* Decoder skip: B */
1683 else
1684 skip_level = 1; /* Decoder skip: B */
1687 picture_wait:
1688 /* Wait until audio catches up */
1689 while (eta_video > eta_audio)
1691 rb->priority_yield();
1693 /* Make sure not to get stuck waiting here forever */
1694 if (str_have_msg(&video_str))
1696 str_look_msg(&video_str, &ev);
1698 if (ev.id != STREAM_PLAY)
1699 goto rendering_finished;
1701 str_get_msg(&video_str, &ev);
1702 str_reply_msg(&video_str, 1);
1705 eta_audio = get_stream_time();
1708 picture_draw:
1709 /* Record last frame time */
1710 last_render = *rb->current_tick;
1712 vo_draw_frame(info->display_fbuf->buf);
1713 num_drawn++;
1715 picture_skip:
1716 if (!settings.showfps)
1717 break;
1719 /* Calculate and display fps */
1720 if (TIME_AFTER(*rb->current_tick, last_showfps + HZ))
1722 uint32_t clock_ticks = get_playback_time() - count_start;
1723 int fps = 0;
1725 if (clock_ticks != 0)
1726 fps = num_drawn*CLOCK_RATE*10ll / clock_ticks;
1728 rb->snprintf(str, sizeof(str), "%d.%d %d %d ",
1729 fps / 10, fps % 10, num_skipped,
1730 info->display_picture->temporal_reference);
1731 rb->lcd_putsxy(0, 0, str);
1732 rb->lcd_update_rect(0, 0, LCD_WIDTH, 8);
1734 last_showfps = *rb->current_tick;
1736 break;
1739 default:
1740 break;
1742 rendering_finished:
1744 rb->yield();
1747 done:
1748 flush_icache();
1750 video_str.status = STREAM_DONE;
1752 while (1)
1754 str_get_msg(&video_str, &ev);
1756 if (ev.id == STREAM_STOP)
1757 break;
1759 str_reply_msg(&video_str, 0);
1762 /* Commit suicide */
1763 str_reply_msg(&video_str, 1);
1764 video_str.status = STREAM_TERMINATED;
1765 rb->remove_thread(NULL);
1768 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1770 int status = PLUGIN_ERROR; /* assume failure */
1771 void* audiobuf;
1772 ssize_t audiosize;
1773 int in_file;
1774 uint8_t* buffer;
1775 size_t file_remaining;
1776 size_t disk_buf_len;
1777 #ifndef HAVE_LCD_COLOR
1778 long graysize;
1779 int grayscales;
1780 #endif
1782 /* We define this here so it is on the main stack (in IRAM) */
1783 mad_fixed_t mad_frame_overlap[2][32][18]; /* 4608 bytes */
1785 if (parameter == NULL)
1787 api->splash(HZ*2, "No File");
1788 return PLUGIN_ERROR;
1791 /* Initialize IRAM - stops audio and voice as well */
1792 PLUGIN_IRAM_INIT(api)
1794 rb = api;
1796 audiobuf = rb->plugin_get_audio_buffer(&audiosize);
1798 #if INPUT_SRC_CAPS != 0
1799 /* Select playback */
1800 rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
1801 rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
1802 #endif
1804 rb->pcm_set_frequency(SAMPR_44);
1806 /* Set disk pointers to NULL */
1807 disk_buf_end = disk_buf = NULL;
1809 /* Stream construction */
1810 /* We take the first stream of each (audio and video) */
1811 /* TODO : Search for these in the file first */
1812 audio_str.curr_packet_end = audio_str.curr_packet = audio_str.next_packet = NULL;
1813 video_str = audio_str;
1814 video_str.id = 0xe0;
1815 audio_str.id = 0xc0;
1817 /* Initialise our malloc buffer */
1818 mpeg2_alloc_init(audiobuf,audiosize);
1820 /* Grab most of the buffer for the compressed video - leave some for
1821 PCM audio data and some for libmpeg2 malloc use. */
1822 buffer_size = audiosize - (PCMBUFFER_SIZE+PCMBUFFER_GUARD_SIZE+
1823 MPABUF_SIZE+LIBMPEG2BUFFER_SIZE);
1825 DEBUGF("audiosize=%ld, buffer_size=%ld\n",audiosize,buffer_size);
1826 buffer = mpeg2_malloc(buffer_size,-1);
1828 if (buffer == NULL)
1829 return PLUGIN_ERROR;
1831 #ifndef HAVE_LCD_COLOR
1832 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
1833 grayscales = gray_init(rb, buffer, buffer_size, false, LCD_WIDTH, LCD_HEIGHT,
1834 32, 2<<8, &graysize) + 1;
1835 buffer += graysize;
1836 buffer_size -= graysize;
1837 if (grayscales < 33 || buffer_size <= 0)
1839 rb->splash(HZ, "gray buf error");
1840 return PLUGIN_ERROR;
1842 #endif
1844 buffer_size &= ~(0x7ff); /* Round buffer down to nearest 2KB */
1845 DEBUGF("audiosize=%ld, buffer_size=%ld\n",audiosize,buffer_size);
1847 if (!init_mpabuf())
1848 return PLUGIN_ERROR;
1850 if (!init_pcmbuf())
1851 return PLUGIN_ERROR;
1853 /* The remaining buffer is for use by libmpeg2 */
1855 /* Open the video file */
1856 in_file = rb->open((char*)parameter,O_RDONLY);
1858 if (in_file < 0){
1859 //fprintf(stderr,"Could not open %s\n",argv[1]);
1860 return PLUGIN_ERROR;
1863 #ifdef HAVE_LCD_COLOR
1864 rb->lcd_set_backdrop(NULL);
1865 rb->lcd_set_foreground(LCD_WHITE);
1866 rb->lcd_set_background(LCD_BLACK);
1867 #endif
1868 rb->lcd_clear_display();
1869 rb->lcd_update();
1871 /* make sure the backlight is always on when viewing video
1872 (actually it should also set the timeout when plugged in,
1873 but the function backlight_set_timeout_plugged is not
1874 available in plugins) */
1875 #ifdef HAVE_BACKLIGHT
1876 if (rb->global_settings->backlight_timeout > 0)
1877 rb->backlight_set_timeout(1);
1878 #endif
1880 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1881 rb->cpu_boost(true);
1882 #endif
1884 /* From this point on we've altered settings, colors, cpu_boost, etc. and
1885 cannot just return PLUGIN_ERROR - instead drop though to cleanup code
1888 init_settings();
1890 /* Msg queue init - no need for queue_remove since it's not a registered
1891 queue */
1892 rb->queue_init( &msg_queue, false );
1894 /* Initialise libmad */
1895 rb->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
1896 init_mad(mad_frame_overlap);
1898 file_remaining = rb->filesize(in_file);
1899 disk_buf_end = buffer + buffer_size-MPEG_GUARDBUF_SIZE;
1901 /* Read some stream data */
1902 disk_buf_len = rb->read (in_file, buffer, MPEG_LOW_WATERMARK);
1904 DEBUGF("Initial Buffering - %d bytes\n",(int)disk_buf_len);
1905 disk_buf = buffer;
1906 disk_buf_tail = buffer+disk_buf_len;
1907 file_remaining -= disk_buf_len;
1909 video_str.guard_bytes = audio_str.guard_bytes = 0;
1910 video_str.prev_packet = disk_buf;
1911 audio_str.prev_packet = disk_buf;
1912 video_str.buffer_remaining = disk_buf_len;
1913 audio_str.buffer_remaining = disk_buf_len;
1915 rb->spinlock_init(&audio_str.msg_lock);
1916 rb->spinlock_init(&video_str.msg_lock);
1917 audio_str.status = STREAM_BUFFERING;
1918 video_str.status = STREAM_PLAYING;
1920 #ifndef HAVE_LCD_COLOR
1921 gray_show(true);
1922 #endif
1924 init_stream_lock();
1926 /* We put the video thread on the second processor for multi-core targets. */
1927 if ((video_str.thread = rb->create_thread(video_thread,
1928 (uint8_t*)video_stack,VIDEO_STACKSIZE,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK)
1929 IF_COP(, COP, true))) == NULL)
1931 rb->splash(HZ, "Cannot create video thread!");
1933 else if ((audio_str.thread = rb->create_thread(audio_thread,
1934 (uint8_t*)audio_stack,AUDIO_STACKSIZE,"mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK)
1935 IF_COP(, CPU, false))) == NULL)
1937 rb->splash(HZ, "Cannot create audio thread!");
1939 else
1941 //DEBUGF("START: video = %d, audio = %d\n",audio_str.buffer_remaining,video_str.buffer_remaining);
1942 rb->lcd_setfont(FONT_SYSFIXED);
1944 /* Wait until both threads have finished their work */
1945 while ((audio_str.status >= 0) || (video_str.status >= 0))
1947 size_t audio_remaining = audio_str.buffer_remaining;
1948 size_t video_remaining = video_str.buffer_remaining;
1950 if (MIN(audio_remaining,video_remaining) < MPEG_LOW_WATERMARK) {
1952 size_t bytes_to_read = buffer_size - MPEG_GUARDBUF_SIZE -
1953 MAX(audio_remaining,video_remaining);
1955 bytes_to_read = MIN(bytes_to_read,(size_t)(disk_buf_end-disk_buf_tail));
1957 while (( bytes_to_read > 0) && (file_remaining > 0) &&
1958 ((audio_str.status >= 0) || (video_str.status >= 0))) {
1959 size_t n = rb->read(in_file, disk_buf_tail, MIN(32*1024,bytes_to_read));
1961 bytes_to_read -= n;
1962 file_remaining -= n;
1964 lock_stream();
1965 audio_str.buffer_remaining += n;
1966 video_str.buffer_remaining += n;
1967 unlock_stream();
1969 disk_buf_tail += n;
1971 rb->yield();
1974 if (disk_buf_tail == disk_buf_end)
1975 disk_buf_tail = buffer;
1978 rb->sleep(HZ/10);
1981 rb->lcd_setfont(FONT_UI);
1982 status = PLUGIN_OK;
1985 /* Stop the threads and wait for them to terminate */
1986 if (video_str.thread != NULL)
1987 str_send_msg(&video_str, STREAM_STOP, 0);
1989 if (audio_str.thread != NULL)
1990 str_send_msg(&audio_str, STREAM_STOP, 0);
1992 rb->sleep(HZ/10);
1994 #ifndef HAVE_LCD_COLOR
1995 gray_release();
1996 #endif
1998 rb->lcd_clear_display();
1999 rb->lcd_update();
2001 mpeg2_close (mpeg2dec);
2003 rb->close (in_file);
2005 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2006 rb->cpu_boost(false);
2007 #endif
2009 save_settings(); /* Save settings (if they have changed) */
2011 rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
2013 #ifdef HAVE_BACKLIGHT
2014 /* reset backlight settings */
2015 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
2016 #endif
2018 return status;