Bring mpegplayer backlight fix to the other plugins, this also fixes some wrongly...
[Rockbox.git] / apps / plugins / mpegplayer / mpegplayer.c
blobdc1b753569eb7caed9a41252b70f1a7e88561dc0
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"
107 #include "helper.h"
109 #include "mpeg2.h"
110 #include "mpeg_settings.h"
111 #include "video_out.h"
112 #include "../../codecs/libmad/mad.h"
114 PLUGIN_HEADER
115 PLUGIN_IRAM_DECLARE
117 /* button definitions */
118 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
119 #define MPEG_MENU BUTTON_MODE
120 #define MPEG_STOP BUTTON_OFF
121 #define MPEG_PAUSE BUTTON_ON
122 #define MPEG_VOLDOWN BUTTON_DOWN
123 #define MPEG_VOLUP BUTTON_UP
125 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
126 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
127 #define MPEG_MENU BUTTON_MENU
128 #define MPEG_PAUSE (BUTTON_PLAY | BUTTON_REL)
129 #define MPEG_STOP (BUTTON_PLAY | BUTTON_REPEAT)
130 #define MPEG_VOLDOWN BUTTON_SCROLL_BACK
131 #define MPEG_VOLUP BUTTON_SCROLL_FWD
133 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
134 #define MPEG_MENU (BUTTON_REC | BUTTON_REL)
135 #define MPEG_STOP BUTTON_POWER
136 #define MPEG_PAUSE BUTTON_PLAY
137 #define MPEG_VOLDOWN BUTTON_DOWN
138 #define MPEG_VOLUP BUTTON_UP
140 #elif CONFIG_KEYPAD == GIGABEAT_PAD
141 #define MPEG_MENU BUTTON_MENU
142 #define MPEG_STOP BUTTON_POWER
143 #define MPEG_PAUSE BUTTON_SELECT
144 #define MPEG_VOLDOWN BUTTON_LEFT
145 #define MPEG_VOLUP BUTTON_RIGHT
146 #define MPEG_VOLDOWN2 BUTTON_VOL_DOWN
147 #define MPEG_VOLUP2 BUTTON_VOL_UP
149 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
150 #define MPEG_MENU (BUTTON_REW | BUTTON_REL)
151 #define MPEG_STOP BUTTON_POWER
152 #define MPEG_PAUSE BUTTON_PLAY
153 #define MPEG_VOLDOWN BUTTON_SCROLL_DOWN
154 #define MPEG_VOLUP BUTTON_SCROLL_UP
156 #elif CONFIG_KEYPAD == SANSA_E200_PAD
157 #define MPEG_MENU BUTTON_SELECT
158 #define MPEG_STOP BUTTON_POWER
159 #define MPEG_PAUSE BUTTON_UP
160 #define MPEG_VOLDOWN BUTTON_SCROLL_UP
161 #define MPEG_VOLUP BUTTON_SCROLL_DOWN
163 #else
164 #error MPEGPLAYER: Unsupported keypad
165 #endif
167 struct plugin_api* rb;
169 static mpeg2dec_t * mpeg2dec;
170 static int total_offset = 0;
171 static int num_drawn = 0;
172 static int count_start = 0;
174 /* Streams */
175 typedef struct
177 struct thread_entry *thread; /* Stream's thread */
178 int status; /* Current stream status */
179 struct event ev; /* Event sent to steam */
180 int have_msg; /* 1=event pending */
181 int replied; /* 1=replied to last event */
182 int reply; /* reply value */
183 struct mutex msg_lock; /* serialization for event senders */
184 uint8_t* curr_packet; /* Current stream packet beginning */
185 uint8_t* curr_packet_end; /* Current stream packet end */
187 uint8_t* prev_packet; /* Previous stream packet beginning */
188 uint8_t* next_packet; /* Next stream packet beginning */
190 size_t guard_bytes; /* Number of bytes in guardbuf used */
191 size_t buffer_remaining; /* How much data is left in the buffer */
192 uint32_t curr_pts; /* Current presentation timestamp */
193 uint32_t curr_time; /* Current time in samples */
194 uint32_t tagged; /* curr_pts is valid */
196 int id;
197 } Stream;
199 static Stream audio_str IBSS_ATTR;
200 static Stream video_str IBSS_ATTR;
202 /* Messages */
203 enum
205 STREAM_PLAY,
206 STREAM_PAUSE,
207 STREAM_QUIT
210 /* Status */
211 enum
213 STREAM_ERROR = -4,
214 STREAM_STOPPED = -3,
215 STREAM_TERMINATED = -2,
216 STREAM_DONE = -1,
217 STREAM_PLAYING = 0,
218 STREAM_PAUSED,
219 STREAM_BUFFERING
222 /* Returns true if a message is waiting */
223 static inline bool str_have_msg(Stream *str)
225 return str->have_msg != 0;
228 /* Waits until a message is sent */
229 static void str_wait_msg(Stream *str)
231 int spin_count = 0;
233 while (str->have_msg == 0)
235 if (spin_count < 100)
237 rb->yield();
238 spin_count++;
239 continue;
242 rb->sleep(0);
246 /* Returns a message waiting or blocks until one is available - removes the
247 event */
248 static void str_get_msg(Stream *str, struct event *ev)
250 str_wait_msg(str);
251 ev->id = str->ev.id;
252 ev->data = str->ev.data;
253 str->have_msg = 0;
256 /* Peeks at the current message without blocking, returns the data but
257 does not remove the event */
258 static bool str_look_msg(Stream *str, struct event *ev)
260 if (!str_have_msg(str))
261 return false;
263 ev->id = str->ev.id;
264 ev->data = str->ev.data;
265 return true;
268 /* Replies to the last message pulled - has no effect if last message has not
269 been pulled or already replied */
270 static void str_reply_msg(Stream *str, int reply)
272 if (str->replied == 1 || str->have_msg != 0)
273 return;
275 str->reply = reply;
276 str->replied = 1;
279 /* Sends a message to a stream and waits for a reply */
280 static intptr_t str_send_msg(Stream *str, int id, intptr_t data)
282 int spin_count = 0;
283 intptr_t reply;
285 #if 0
286 if (str->thread == rb->thread_get_current())
287 return str->dispatch_fn(str, msg);
288 #endif
290 /* Only one thread at a time, please */
291 rb->spinlock_lock(&str->msg_lock);
293 str->ev.id = id;
294 str->ev.data = data;
295 str->reply = 0;
296 str->replied = 0;
297 str->have_msg = 1;
299 while (str->replied == 0 && str->status != STREAM_TERMINATED)
301 if (spin_count < 100)
303 rb->yield();
304 spin_count++;
305 continue;
308 rb->sleep(0);
311 reply = str->reply;
313 rb->spinlock_unlock(&str->msg_lock);
315 return reply;
318 /* NOTE: Putting the following variables in IRAM cause audio corruption
319 on the ipod (reason unknown)
321 static uint8_t *disk_buf IBSS_ATTR;
322 static uint8_t *disk_buf_end IBSS_ATTR;
323 static uint8_t *disk_buf_tail IBSS_ATTR;
324 static size_t buffer_size IBSS_ATTR;
325 #if NUM_CORES > 1
326 /* Some stream variables are shared between cores */
327 struct mutex stream_lock IBSS_ATTR;
328 static inline void init_stream_lock(void)
329 { rb->spinlock_init(&stream_lock); }
330 static inline void lock_stream(void)
331 { rb->spinlock_lock(&stream_lock); }
332 static inline void unlock_stream(void)
333 { rb->spinlock_unlock(&stream_lock); }
334 #else
335 /* No RMW issue here */
336 static inline void init_stream_lock(void)
338 static inline void lock_stream(void)
340 static inline void unlock_stream(void)
342 #endif
344 /* Events */
345 static struct event_queue msg_queue IBSS_ATTR;
347 #define MSG_BUFFER_NEARLY_EMPTY 1
348 #define MSG_EXIT_REQUESTED 2
350 /* Various buffers */
351 /* TODO: Can we reduce the PCM buffer size? */
352 #define PCMBUFFER_SIZE ((512*1024)-PCMBUFFER_GUARD_SIZE)
353 #define PCMBUFFER_GUARD_SIZE (1152*4 + sizeof (struct pcm_frame_header))
354 #define MPA_MAX_FRAME_SIZE 1729 /* Largest frame - MPEG1, Layer II, 384kbps, 32kHz, pad */
355 #define MPABUF_SIZE (64*1024 + ALIGN_UP(MPA_MAX_FRAME_SIZE + 2*MAD_BUFFER_GUARD, 4))
356 #define LIBMPEG2BUFFER_SIZE (2*1024*1024)
358 /* 65536+6 is required since each PES has a 6 byte header with a 16 bit packet length field */
359 #define MPEG_GUARDBUF_SIZE (64*1024+1024) /* Keep a bit extra - excessive for now */
360 #define MPEG_LOW_WATERMARK (1024*1024)
362 static void pcm_playback_play_pause(bool play);
364 /* libmad related functions/definitions */
365 #define INPUT_CHUNK_SIZE 8192
367 struct mad_stream stream IBSS_ATTR;
368 struct mad_frame frame IBSS_ATTR;
369 struct mad_synth synth IBSS_ATTR;
371 unsigned char mad_main_data[MAD_BUFFER_MDLEN]; /* 2567 bytes */
373 /* There isn't enough room for this in IRAM on PortalPlayer, but there
374 is for Coldfire. */
376 #ifdef CPU_COLDFIRE
377 static mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR; /* 4608 bytes */
378 #else
379 static mad_fixed_t mad_frame_overlap[2][32][18]; /* 4608 bytes */
380 #endif
382 static void init_mad(void* mad_frame_overlap)
384 rb->memset(&stream, 0, sizeof(struct mad_stream));
385 rb->memset(&frame, 0, sizeof(struct mad_frame));
386 rb->memset(&synth, 0, sizeof(struct mad_synth));
388 mad_stream_init(&stream);
389 mad_frame_init(&frame);
391 /* We do this so libmad doesn't try to call codec_calloc() */
392 frame.overlap = mad_frame_overlap;
394 rb->memset(mad_main_data, 0, sizeof(mad_main_data));
395 stream.main_data = &mad_main_data;
398 /* MPEG related headers */
400 /* Macros for comparing memory bytes to a series of constant bytes in an
401 efficient manner - evaluate to true if corresponding bytes match */
402 #if defined (CPU_ARM)
403 /* ARM must load 32-bit values at addres % 4 == 0 offsets but this data
404 isn't aligned nescessarily, so just byte compare */
405 #define CMP_3_CONST(_a, _b) \
406 ({ \
407 int _x; \
408 asm volatile ( \
409 "ldrb %[x], [%[a], #0] \r\n" \
410 "eors %[x], %[x], %[b0] \r\n" \
411 "ldreqb %[x], [%[a], #1] \r\n" \
412 "eoreqs %[x], %[x], %[b1] \r\n" \
413 "ldreqb %[x], [%[a], #2] \r\n" \
414 "eoreqs %[x], %[x], %[b2] \r\n" \
415 : [x]"=&r"(_x) \
416 : [a]"r"(_a), \
417 [b0]"i"((_b) >> 24), \
418 [b1]"i"((_b) << 8 >> 24), \
419 [b2]"i"((_b) << 16 >> 24) \
420 ); \
421 _x == 0; \
423 #define CMP_4_CONST(_a, _b) \
424 ({ \
425 int _x; \
426 asm volatile ( \
427 "ldrb %[x], [%[a], #0] \r\n" \
428 "eors %[x], %[x], %[b0] \r\n" \
429 "ldreqb %[x], [%[a], #1] \r\n" \
430 "eoreqs %[x], %[x], %[b1] \r\n" \
431 "ldreqb %[x], [%[a], #2] \r\n" \
432 "eoreqs %[x], %[x], %[b2] \r\n" \
433 "ldreqb %[x], [%[a], #3] \r\n" \
434 "eoreqs %[x], %[x], %[b3] \r\n" \
435 : [x]"=&r"(_x) \
436 : [a]"r"(_a), \
437 [b0]"i"((_b) >> 24), \
438 [b1]"i"((_b) << 8 >> 24), \
439 [b2]"i"((_b) << 16 >> 24), \
440 [b3]"i"((_b) << 24 >> 24) \
441 ); \
442 _x == 0; \
444 #elif defined (CPU_COLDFIRE)
445 /* Coldfire can just load a 32 bit value at any offset but ASM is not the best way
446 to integrate this with the C code */
447 #define CMP_3_CONST(a, b) \
448 (((*(uint32_t *)(a) >> 8) ^ ((uint32_t)(b) >> 8)) == 0)
449 #define CMP_4_CONST(a, b) \
450 ((*(uint32_t *)(a) ^ (b)) == 0)
451 #else
452 /* Don't know what this is - use bytewise comparisons */
453 #define CMP_3_CONST(a, b) \
454 (( ((a)[0] ^ ((b) >> 24)) | \
455 ((a)[1] ^ ((b) << 8 >> 24)) | \
456 ((a)[2] ^ ((b) << 16 >> 24)) ) == 0)
457 #define CMP_4_CONST(a, b) \
458 (( ((a)[0] ^ ((b) >> 24)) | \
459 ((a)[1] ^ ((b) << 8 >> 24)) | \
460 ((a)[2] ^ ((b) << 16 >> 24)) | \
461 ((a)[3] ^ ((b) << 24 >> 24)) ) == 0)
462 #endif
464 /* Codes for various header byte sequences - MSB represents lowest memory
465 address */
466 #define PACKET_START_CODE_PREFIX 0x00000100ul
467 #define END_CODE 0x000001b9ul
468 #define PACK_START_CODE 0x000001baul
469 #define SYSTEM_HEADER_START_CODE 0x000001bbul
471 /* p = base pointer, b0 - b4 = byte offsets from p */
472 /* We only care about the MS 32 bits of the 33 and so the ticks are 45kHz */
473 #define TS_FROM_HEADER(p, b0, b1, b2, b3, b4) \
474 ((uint32_t)(((p)[b0] >> 1 << 29) | \
475 ((p)[b1] << 21) | \
476 ((p)[b2] >> 1 << 14) | \
477 ((p)[b3] << 6) | \
478 ((p)[b4] >> 2 )))
480 /* This function demuxes the streams and gives the next stream data pointer */
481 static void get_next_data( Stream* str )
483 uint8_t *p;
484 uint8_t *header;
485 int stream;
487 static int mpeg1_skip_table[16] =
488 { 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
490 if (str->curr_packet_end == NULL)
492 /* What does this do? */
493 while ((p = disk_buf) == NULL)
495 rb->lcd_putsxy(0,LCD_HEIGHT-10,"FREEZE!");
496 rb->lcd_update();
497 rb->sleep(HZ);
500 else
502 p = str->curr_packet_end;
505 while (1)
507 int length, bytes;
509 if (p >= disk_buf_end)
511 p = disk_buf + (p - disk_buf_end);
514 /* Pack header, skip it */
515 if (CMP_4_CONST(p, PACK_START_CODE))
517 if ((p[4] & 0xc0) == 0x40) /* mpeg-2 */
519 p += 14 + (p[13] & 7);
521 else if ((p[4] & 0xf0) == 0x20) /* mpeg-1 */
523 p += 12;
525 else
527 rb->splash( 30, "Weird Pack header!" );
528 p += 5;
530 /*rb->splash( 30, "Pack header" );*/
533 /* System header, parse and skip it - four bytes */
534 if (CMP_4_CONST(p, SYSTEM_HEADER_START_CODE))
536 int header_length;
538 p += 4; /*skip start code*/
539 header_length = *p++ << 8;
540 header_length += *p++;
542 p += header_length;
544 if (p >= disk_buf_end)
546 p = disk_buf + (p - disk_buf_end);
548 /*rb->splash( 30, "System header" );*/
551 /* Packet header, parse it */
552 if (!CMP_3_CONST(p, PACKET_START_CODE_PREFIX))
554 /* Problem */
555 //rb->splash( HZ*3, "missing packet start code prefix : %X%X at %X", *p, *(p+2), p-disk_buf );
556 str->curr_packet_end = str->curr_packet = NULL;
557 break;
558 //++p;
559 //break;
562 /* We retrieve basic infos */
563 stream = p[3];
564 length = (p[4] << 8) | p[5];
566 /*rb->splash( 100, "Stream : %X", stream );*/
567 if (stream != str->id)
569 /* End of stream ? */
570 if (stream == 0xB9)
572 str->curr_packet_end = str->curr_packet = NULL;
573 break;
576 /* It's not the packet we're looking for, skip it */
577 p += length + 6;
578 continue;
581 /* Ok, it's our packet */
582 str->curr_packet_end = p + length+6;
583 header = p;
585 if ((header[6] & 0xc0) == 0x80) /* mpeg2 */
587 length = 9 + header[8];
589 /* header points to the mpeg2 pes header */
590 if (header[7] & 0x80)
592 /* header has a pts */
593 uint32_t pts = TS_FROM_HEADER(header, 9, 10, 11, 12, 13);
595 if (stream >= 0xe0)
597 /* video stream - header may have a dts as well */
598 uint32_t dts = (header[7] & 0x40) == 0 ?
599 pts : TS_FROM_HEADER(header, 14, 15, 16, 17, 18);
601 mpeg2_tag_picture (mpeg2dec, pts, dts);
603 else
605 str->curr_pts = pts;
606 str->tagged = 1;
610 else /* mpeg1 */
612 int len_skip;
613 uint8_t * ptsbuf;
615 length = 7;
617 while (header[length - 1] == 0xff)
619 length++;
620 if (length > 23)
622 rb->splash( 30, "Too much stuffing" );
623 DEBUGF("Too much stuffing" );
624 break;
628 if ((header[length - 1] & 0xc0) == 0x40)
630 length += 2;
633 len_skip = length;
634 length += mpeg1_skip_table[header[length - 1] >> 4];
636 /* header points to the mpeg1 pes header */
637 ptsbuf = header + len_skip;
639 if ((ptsbuf[-1] & 0xe0) == 0x20)
641 /* header has a pts */
642 uint32_t pts = TS_FROM_HEADER(ptsbuf, -1, 0, 1, 2, 3);
644 if (stream >= 0xe0)
646 /* video stream - header may have a dts as well */
647 uint32_t dts = (ptsbuf[-1] & 0xf0) != 0x30 ?
648 pts : TS_FROM_HEADER(ptsbuf, 4, 5, 6, 7, 18);
650 mpeg2_tag_picture (mpeg2dec, pts, dts);
652 else
654 str->curr_pts = pts;
655 str->tagged = 1;
660 p += length;
661 bytes = 6 + (header[4] << 8) + header[5] - length;
663 if (bytes > 0)
665 str->curr_packet_end = p + bytes;
666 //DEBUGF("prev = %d, curr = %d\n",str->prev_packet,str->curr_packet);
668 if (str->curr_packet != NULL)
670 lock_stream();
672 if (str->curr_packet < str->prev_packet)
674 str->buffer_remaining -= (disk_buf_end - str->prev_packet) +
675 (str->curr_packet - disk_buf);
676 str->buffer_remaining -= str->guard_bytes;
677 str->guard_bytes = 0;
679 else
681 str->buffer_remaining -= (str->curr_packet - str->prev_packet);
684 unlock_stream();
686 str->prev_packet = str->curr_packet;
689 str->curr_packet = p;
691 if (str->curr_packet_end > disk_buf_end)
693 str->guard_bytes = str->curr_packet_end - disk_buf_end;
694 rb->memcpy(disk_buf_end, disk_buf, str->guard_bytes);
698 break;
699 } /* end while */
702 /* Our clock rate in ticks/second - this won't be a constant for long */
703 #define CLOCK_RATE 44100
705 /* For simple lowpass filtering of sync variables */
706 #define AVERAGE(var, x, count) (((var) * (count-1) + (x)) / (count))
707 /* Convert 45kHz PTS/DTS ticks to our clock ticks */
708 #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / 45000)
709 /* Convert 27MHz ticks to our clock ticks */
710 #define TIME_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / 27000000)
712 /** MPEG audio stream buffer */
713 uint8_t* mpa_buffer;
715 static bool init_mpabuf(void)
717 mpa_buffer = mpeg2_malloc(MPABUF_SIZE,-2);
718 return mpa_buffer != NULL;
721 #define PTS_QUEUE_LEN (1 << 5) /* 32 should be way more than sufficient -
722 if not, the case is handled */
723 #define PTS_QUEUE_MASK (PTS_QUEUE_LEN-1)
724 struct pts_queue_slot
726 uint32_t pts; /* Time stamp for packet */
727 ssize_t size; /* Number of bytes left in packet */
728 } pts_queue[PTS_QUEUE_LEN];
730 /* This starts out wr == rd but will never be emptied to zero during
731 streaming again in order to support initializing the first packet's
732 pts value without a special case */
733 static unsigned pts_queue_rd;
734 static unsigned pts_queue_wr;
736 /* Increments the queue head postion - should be used to preincrement */
737 static bool pts_queue_add_head(void)
739 if (pts_queue_wr - pts_queue_rd >= PTS_QUEUE_LEN-1)
740 return false;
742 pts_queue_wr++;
743 return true;
746 /* Increments the queue tail position - leaves one slot as current */
747 static bool pts_queue_remove_tail(void)
749 if (pts_queue_wr - pts_queue_rd <= 1u)
750 return false;
752 pts_queue_rd++;
753 return true;
756 /* Returns the "head" at the index just behind the write index */
757 static struct pts_queue_slot * pts_queue_head(void)
759 return &pts_queue[(pts_queue_wr - 1) & PTS_QUEUE_MASK];
762 /* Returns a pointer to the current tail */
763 static struct pts_queue_slot * pts_queue_tail(void)
765 return &pts_queue[pts_queue_rd & PTS_QUEUE_MASK];
768 /* Resets the pts queue - call when starting and seeking */
769 static void pts_queue_reset(void)
771 struct pts_queue_slot *pts;
772 pts_queue_rd = pts_queue_wr;
773 pts = pts_queue_tail();
774 pts->pts = 0;
775 pts->size = 0;
778 struct pcm_frame_header /* Header added to pcm data every time a decoded
779 mpa frame is sent out */
781 uint32_t size; /* size of this frame - including header */
782 uint32_t time; /* timestamp for this frame - derived from PTS */
783 unsigned char data[]; /* open array of audio data */
786 #define PCMBUF_PLAY_ALL 1l /* Forces buffer to play back all data */
787 #define PCMBUF_PLAY_NONE LONG_MAX /* Keeps buffer from playing any data */
788 static volatile uint64_t pcmbuf_read IBSS_ATTR;
789 static volatile uint64_t pcmbuf_written IBSS_ATTR;
790 static volatile ssize_t pcmbuf_threshold IBSS_ATTR;
791 static struct pcm_frame_header *pcm_buffer IBSS_ATTR;
792 static struct pcm_frame_header *pcmbuf_end IBSS_ATTR;
793 static struct pcm_frame_header * volatile pcmbuf_head IBSS_ATTR;
794 static struct pcm_frame_header * volatile pcmbuf_tail IBSS_ATTR;
796 static volatile uint32_t samplesplayed IBSS_ATTR; /* Our base clock */
797 static volatile uint32_t samplestart IBSS_ATTR; /* Clock at playback start */
798 static volatile int32_t sampleadjust IBSS_ATTR; /* Clock drift adjustment */
800 static ssize_t pcmbuf_used(void)
802 return (ssize_t)(pcmbuf_written - pcmbuf_read);
805 static bool init_pcmbuf(void)
807 pcm_buffer = mpeg2_malloc(PCMBUFFER_SIZE + PCMBUFFER_GUARD_SIZE, -2);
809 if (pcm_buffer == NULL)
810 return false;
812 pcmbuf_head = pcm_buffer;
813 pcmbuf_tail = pcm_buffer;
814 pcmbuf_end = SKIPBYTES(pcm_buffer, PCMBUFFER_SIZE);
815 pcmbuf_read = 0;
816 pcmbuf_written = 0;
818 return true;
821 /* Advance a PCM buffer pointer by size bytes circularly */
822 static inline void pcm_advance_buffer(struct pcm_frame_header * volatile *p,
823 size_t size)
825 *p = SKIPBYTES(*p, size);
826 if (*p >= pcmbuf_end)
827 *p = pcm_buffer;
830 static void get_more(unsigned char** start, size_t* size)
832 /* 25ms @ 44.1kHz */
833 static unsigned char silence[4412] __attribute__((aligned (4))) = { 0 };
834 size_t sz;
836 if (pcmbuf_used() >= pcmbuf_threshold)
838 uint32_t time = pcmbuf_tail->time;
839 sz = pcmbuf_tail->size;
841 *start = (unsigned char *)pcmbuf_tail->data;
843 pcm_advance_buffer(&pcmbuf_tail, sz);
845 pcmbuf_read += sz;
847 sz -= sizeof (*pcmbuf_tail);
849 *size = sz;
851 /* Drift the clock towards the audio timestamp values */
852 sampleadjust = AVERAGE(sampleadjust, (int32_t)(time - samplesplayed), 8);
854 /* Update master clock */
855 samplesplayed += sz >> 2;
856 return;
859 /* Keep clock going at all times */
860 sz = sizeof (silence);
861 *start = silence;
862 *size = sz;
864 samplesplayed += sz >> 2;
866 if (pcmbuf_read > pcmbuf_written)
867 pcmbuf_read = pcmbuf_written;
870 /* Flushes the buffer - clock keeps counting */
871 static void pcm_playback_flush(void)
873 bool was_playing = rb->pcm_is_playing();
875 if (was_playing)
876 rb->pcm_play_stop();
878 pcmbuf_read = 0;
879 pcmbuf_written = 0;
880 pcmbuf_head = pcmbuf_tail;
882 if (was_playing)
883 rb->pcm_play_data(get_more, NULL, 0);
886 /* Seek the reference clock to the specified time - next audio data ready to
887 go to DMA should be on the buffer with the same time index or else the PCM
888 buffer should be empty */
889 static void pcm_playback_seek_time(uint32_t time)
891 bool was_playing = rb->pcm_is_playing();
893 if (was_playing)
894 rb->pcm_play_stop();
896 samplesplayed = time;
897 samplestart = time;
898 sampleadjust = 0;
900 if (was_playing)
901 rb->pcm_play_data(get_more, NULL, 0);
904 /* Start pcm playback with the reference clock set to the specified time */
905 static void pcm_playback_play(uint32_t time)
907 pcm_playback_seek_time(time);
909 if (!rb->pcm_is_playing())
910 rb->pcm_play_data(get_more, NULL, 0);
913 /* Pauses playback - and the clock */
914 static void pcm_playback_play_pause(bool play)
916 rb->pcm_play_pause(play);
919 /* Stops all playback and resets the clock */
920 static void pcm_playback_stop(void)
922 if (rb->pcm_is_playing())
923 rb->pcm_play_stop();
925 pcm_playback_flush();
927 sampleadjust =
928 samplestart =
929 samplesplayed = 0;
932 static uint32_t get_stream_time(void)
934 return samplesplayed + sampleadjust - (rb->pcm_get_bytes_waiting() >> 2);
937 static uint32_t get_playback_time(void)
939 return samplesplayed + sampleadjust -
940 samplestart - (rb->pcm_get_bytes_waiting() >> 2);
943 static inline int32_t clip_sample(int32_t sample)
945 if ((int16_t)sample != sample)
946 sample = 0x7fff ^ (sample >> 31);
948 return sample;
951 static int button_loop(void)
953 bool result;
954 int vol, minvol, maxvol;
955 int button;
957 if (str_have_msg(&audio_str))
959 struct event ev;
960 str_get_msg(&audio_str, &ev);
962 if (ev.id == STREAM_QUIT)
964 audio_str.status = STREAM_STOPPED;
965 goto quit;
967 else
969 str_reply_msg(&audio_str, 0);
973 button = rb->button_get(false);
975 switch (button)
977 case MPEG_VOLUP:
978 case MPEG_VOLUP|BUTTON_REPEAT:
979 #ifdef MPEG_VOLUP2
980 case MPEG_VOLUP2:
981 case MPEG_VOLUP2|BUTTON_REPEAT:
982 #endif
983 vol = rb->global_settings->volume;
984 maxvol = rb->sound_max(SOUND_VOLUME);
986 if (vol < maxvol) {
987 vol++;
988 rb->sound_set(SOUND_VOLUME, vol);
989 rb->global_settings->volume = vol;
991 break;
993 case MPEG_VOLDOWN:
994 case MPEG_VOLDOWN|BUTTON_REPEAT:
995 #ifdef MPEG_VOLDOWN2
996 case MPEG_VOLDOWN2:
997 case MPEG_VOLDOWN2|BUTTON_REPEAT:
998 #endif
999 vol = rb->global_settings->volume;
1000 minvol = rb->sound_min(SOUND_VOLUME);
1002 if (vol > minvol) {
1003 vol--;
1004 rb->sound_set(SOUND_VOLUME, vol);
1005 rb->global_settings->volume = vol;
1007 break;
1009 case MPEG_MENU:
1010 pcm_playback_play_pause(false);
1011 audio_str.status = STREAM_PAUSED;
1012 str_send_msg(&video_str, STREAM_PAUSE, 0);
1013 #ifndef HAVE_LCD_COLOR
1014 gray_show(false);
1015 #endif
1016 result = mpeg_menu();
1017 count_start = get_playback_time();
1018 num_drawn = 0;
1020 #ifndef HAVE_LCD_COLOR
1021 gray_show(true);
1022 #endif
1024 /* The menu can change the font, so restore */
1025 rb->lcd_setfont(FONT_SYSFIXED);
1027 if (result) {
1028 str_send_msg(&video_str, STREAM_QUIT, 0);
1029 audio_str.status = STREAM_STOPPED;
1030 } else {
1031 audio_str.status = STREAM_PLAYING;
1032 str_send_msg(&video_str, STREAM_PLAY, 0);
1033 pcm_playback_play_pause(true);
1035 break;
1037 case MPEG_STOP:
1038 str_send_msg(&video_str, STREAM_QUIT, 0);
1039 audio_str.status = STREAM_STOPPED;
1040 break;
1042 case MPEG_PAUSE:
1043 str_send_msg(&video_str, STREAM_PAUSE, 0);
1044 audio_str.status = STREAM_PAUSED;
1045 pcm_playback_play_pause(false);
1047 button = BUTTON_NONE;
1048 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1049 rb->cpu_boost(false);
1050 #endif
1051 do {
1052 button = rb->button_get(true);
1053 if (button == MPEG_STOP) {
1054 str_send_msg(&video_str, STREAM_QUIT, 0);
1055 audio_str.status = STREAM_STOPPED;
1056 goto quit;
1058 } while (button != MPEG_PAUSE);
1060 str_send_msg(&video_str, STREAM_PLAY, 0);
1061 audio_str.status = STREAM_PLAYING;
1062 pcm_playback_play_pause(true);
1063 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1064 rb->cpu_boost(true);
1065 #endif
1066 break;
1068 default:
1069 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) {
1070 str_send_msg(&video_str, STREAM_QUIT, 0);
1071 audio_str.status = STREAM_STOPPED;
1075 quit:
1076 return audio_str.status;
1079 static void audio_thread(void)
1081 uint8_t *mpabuf = mpa_buffer;
1082 ssize_t mpabuf_used = 0;
1083 int mad_errors = 0; /* A count of the errors in each frame */
1084 struct pts_queue_slot *pts;
1086 /* We need this here to init the EMAC for Coldfire targets */
1087 mad_synth_init(&synth);
1089 /* Init pts queue */
1090 pts_queue_reset();
1091 pts = pts_queue_tail();
1093 /* Keep buffer from playing */
1094 pcmbuf_threshold = PCMBUF_PLAY_NONE;
1096 /* Start clock */
1097 pcm_playback_play(0);
1099 /* Get first packet */
1100 get_next_data(&audio_str);
1102 if (audio_str.curr_packet == NULL)
1103 goto done;
1105 /* This is the decoding loop. */
1106 while (1)
1108 int mad_stat;
1109 size_t len;
1111 if (button_loop() == STREAM_STOPPED)
1112 goto audio_thread_quit;
1114 if (pts->size <= 0)
1116 /* Carry any overshoot to the next size since we're technically
1117 -pts->size bytes into it already. If size is negative an audio
1118 frame was split accross packets. Old has to be saved before
1119 moving the tail. */
1120 if (pts_queue_remove_tail())
1122 struct pts_queue_slot *old = pts;
1123 pts = pts_queue_tail();
1124 pts->size += old->size;
1125 old->size = 0;
1129 /** Buffering **/
1130 if (mpabuf_used >= MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD)
1132 /* Above low watermark - do nothing */
1134 else if (audio_str.curr_packet != NULL)
1138 /* Get data from next audio packet */
1139 len = audio_str.curr_packet_end - audio_str.curr_packet;
1141 if (audio_str.tagged)
1143 struct pts_queue_slot *stamp = pts;
1145 if (pts_queue_add_head())
1147 stamp = pts_queue_head();
1148 stamp->pts = TS_TO_TICKS(audio_str.curr_pts);
1149 /* pts->size should have been zeroed when slot was
1150 freed */
1152 /* else queue full - just count up from the last to make
1153 it look like more data in the same packet */
1154 stamp->size += len;
1155 audio_str.tagged = 0;
1157 else
1159 /* Add to the one just behind the head - this may be the
1160 tail or the previouly added head - whether or not we'll
1161 ever reach this is quite in question since audio always
1162 seems to have every packet timestamped */
1163 pts_queue_head()->size += len;
1166 /* Slide any remainder over to beginning - avoid function
1167 call overhead if no data remaining as well */
1168 if (mpabuf > mpa_buffer && mpabuf_used > 0)
1169 rb->memmove(mpa_buffer, mpabuf, mpabuf_used);
1171 /* Splice this packet onto any remainder */
1172 rb->memcpy(mpa_buffer + mpabuf_used, audio_str.curr_packet,
1173 len);
1175 mpabuf_used += len;
1176 mpabuf = mpa_buffer;
1178 /* Get data from next audio packet */
1179 get_next_data(&audio_str);
1181 while (audio_str.curr_packet != NULL &&
1182 mpabuf_used < MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD);
1184 else if (mpabuf_used <= 0)
1186 /* Used up remainder of mpa buffer so quit */
1187 break;
1190 /** Decoding **/
1191 mad_stream_buffer(&stream, mpabuf, mpabuf_used);
1193 mad_stat = mad_frame_decode(&frame, &stream);
1195 if (stream.next_frame == NULL)
1197 /* What to do here? (This really is fatal) */
1198 DEBUGF("/* What to do here? */\n");
1199 break;
1202 /* Next mad stream buffer is the next frame postion */
1203 mpabuf = (uint8_t *)stream.next_frame;
1205 /* Adjust sizes by the frame size */
1206 len = stream.next_frame - stream.this_frame;
1207 mpabuf_used -= len;
1208 pts->size -= len;
1210 if (mad_stat != 0)
1212 DEBUGF("Audio stream error - %d\n", stream.error);
1214 if (stream.error == MAD_FLAG_INCOMPLETE
1215 || stream.error == MAD_ERROR_BUFLEN)
1217 /* This makes the codec support partially corrupted files */
1218 if (++mad_errors > 30)
1219 break;
1221 stream.error = 0;
1222 rb->priority_yield();
1223 continue;
1225 else if (MAD_RECOVERABLE(stream.error))
1227 stream.error = 0;
1228 rb->priority_yield();
1229 continue;
1231 else
1233 /* Some other unrecoverable error */
1234 DEBUGF("Unrecoverable error\n");
1237 break;
1240 mad_errors = 0; /* Clear errors */
1242 /* Generate the pcm samples */
1243 mad_synth_frame(&synth, &frame);
1245 /** Output **/
1247 /* TODO: Output through core dsp. We'll still use our own PCM buffer
1248 since the core pcm buffer has no timestamping or clock facilities */
1250 /* Add a frame of audio to the pcm buffer. Maximum is 1152 samples. */
1251 if (synth.pcm.length > 0)
1253 int16_t *audio_data = (int16_t *)pcmbuf_head->data;
1254 size_t size = sizeof (*pcmbuf_head) + synth.pcm.length*4;
1255 size_t wait_for = size + 32*1024;
1257 /* Leave at least 32KB free (this will be the currently
1258 playing chunk) */
1259 while (pcmbuf_used() + wait_for > PCMBUFFER_SIZE)
1261 if (str_have_msg(&audio_str))
1263 struct event ev;
1264 str_look_msg(&audio_str, &ev);
1266 if (ev.id == STREAM_QUIT)
1267 goto audio_thread_quit;
1270 rb->priority_yield();
1273 /* TODO: This part will be replaced with dsp calls soon */
1274 if (MAD_NCHANNELS(&frame.header) == 2)
1276 int32_t *left = &synth.pcm.samples[0][0];
1277 int32_t *right = &synth.pcm.samples[1][0];
1278 int i = synth.pcm.length;
1282 /* libmad outputs s3.28 */
1283 *audio_data++ = clip_sample(*left++ >> 13);
1284 *audio_data++ = clip_sample(*right++ >> 13);
1286 while (--i > 0);
1288 else /* mono */
1290 int32_t *mono = &synth.pcm.samples[0][0];
1291 int i = synth.pcm.length;
1295 int32_t s = clip_sample(*mono++ >> 13);
1296 *audio_data++ = s;
1297 *audio_data++ = s;
1299 while (--i > 0);
1301 /**/
1303 pcmbuf_head->time = pts->pts;
1304 pcmbuf_head->size = size;
1306 /* As long as we're on this timestamp, the time is just incremented
1307 by the number of samples */
1308 pts->pts += synth.pcm.length;
1310 pcm_advance_buffer(&pcmbuf_head, size);
1312 if (pcmbuf_threshold != PCMBUF_PLAY_ALL && pcmbuf_used() >= 64*1024)
1314 /* We've reached our size treshold so start playing back the
1315 audio in the buffer and set the buffer to play all data */
1316 audio_str.status = STREAM_PLAYING;
1317 pcmbuf_threshold = PCMBUF_PLAY_ALL;
1318 pcm_playback_seek_time(pcmbuf_tail->time);
1321 /* Make this data available to DMA */
1322 pcmbuf_written += size;
1325 rb->yield();
1326 } /* end decoding loop */
1328 done:
1329 if (audio_str.status == STREAM_STOPPED)
1330 goto audio_thread_quit;
1332 /* Force any residue to play if audio ended before reaching the
1333 threshold */
1334 if (pcmbuf_threshold != PCMBUF_PLAY_ALL && pcmbuf_used() > 0)
1336 pcm_playback_play(pcmbuf_tail->time);
1337 pcmbuf_threshold = PCMBUF_PLAY_ALL;
1340 if (rb->pcm_is_playing() && !rb->pcm_is_paused())
1342 /* Wait for audio to finish */
1343 while (pcmbuf_used() > 0)
1345 if (button_loop() == STREAM_STOPPED)
1346 goto audio_thread_quit;
1347 rb->sleep(HZ/10);
1351 audio_str.status = STREAM_DONE;
1353 /* Process events until finished */
1354 while (button_loop() != STREAM_STOPPED)
1355 rb->sleep(HZ/4);
1357 audio_thread_quit:
1358 pcm_playback_stop();
1360 audio_str.status = STREAM_TERMINATED;
1361 rb->remove_thread(NULL);
1364 /* End of libmad stuff */
1366 /* TODO: Running in the main thread, libmad needs 8.25KB of stack.
1367 The codec thread uses a 9KB stack. So we can probable reduce this a
1368 little, but leave at 9KB for now to be safe. */
1369 #define AUDIO_STACKSIZE (9*1024)
1370 uint32_t audio_stack[AUDIO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR;
1372 /* TODO: Check if 4KB is appropriate - it works for my test streams,
1373 so maybe we can reduce it. */
1374 #define VIDEO_STACKSIZE (4*1024)
1375 static uint32_t video_stack[VIDEO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR;
1377 static void video_thread(void)
1379 struct event ev;
1380 const mpeg2_info_t * info;
1381 mpeg2_state_t state;
1382 char str[80];
1383 uint32_t curr_time = 0;
1384 uint32_t period = 0; /* Frame period in clock ticks */
1385 uint32_t eta_audio = UINT_MAX, eta_video = 0;
1386 int32_t eta_early = 0, eta_late = 0;
1387 int frame_drop_level = 0;
1388 int skip_level = 0;
1389 int num_skipped = 0;
1390 /* Used to decide when to display FPS */
1391 unsigned long last_showfps = *rb->current_tick - HZ;
1392 /* Used to decide whether or not to force a frame update */
1393 unsigned long last_render = last_showfps;
1395 mpeg2dec = mpeg2_init();
1396 if (mpeg2dec == NULL)
1398 rb->splash(0, "mpeg2_init failed");
1399 /* Commit suicide */
1400 video_str.status = STREAM_TERMINATED;
1401 rb->remove_thread(NULL);
1404 /* Clear the display - this is mainly just to indicate that the
1405 video thread has started successfully. */
1406 rb->lcd_clear_display();
1407 rb->lcd_update();
1409 /* Request the first packet data */
1410 get_next_data( &video_str );
1412 if (video_str.curr_packet == NULL)
1413 goto done;
1415 mpeg2_buffer (mpeg2dec, video_str.curr_packet, video_str.curr_packet_end);
1416 total_offset += video_str.curr_packet_end - video_str.curr_packet;
1418 info = mpeg2_info (mpeg2dec);
1420 /* Wait if the audio thread is buffering - i.e. before
1421 the first frames are decoded */
1422 while (audio_str.status == STREAM_BUFFERING)
1423 rb->priority_yield();
1425 while (1)
1427 /* quickly check mailbox first */
1428 if (str_have_msg(&video_str))
1430 while (1)
1432 str_get_msg(&video_str, &ev);
1434 switch (ev.id)
1436 case STREAM_QUIT:
1437 video_str.status = STREAM_STOPPED;
1438 goto video_thread_quit;
1439 case STREAM_PAUSE:
1440 flush_icache();
1441 video_str.status = STREAM_PAUSED;
1442 str_reply_msg(&video_str, 1);
1443 continue;
1446 break;
1449 video_str.status = STREAM_PLAYING;
1450 str_reply_msg(&video_str, 1);
1453 state = mpeg2_parse (mpeg2dec);
1454 rb->yield();
1456 /* Prevent idle poweroff */
1457 rb->reset_poweroff_timer();
1459 switch (state)
1461 case STATE_BUFFER:
1462 /* Request next packet data */
1463 get_next_data( &video_str );
1464 mpeg2_buffer (mpeg2dec, video_str.curr_packet, video_str.curr_packet_end);
1465 total_offset += video_str.curr_packet_end - video_str.curr_packet;
1466 info = mpeg2_info (mpeg2dec);
1468 if (video_str.curr_packet == NULL)
1470 /* No more data. */
1471 goto done;
1473 continue;
1475 case STATE_SEQUENCE:
1476 /* New GOP, inform output of any changes */
1477 vo_setup(info->sequence);
1478 break;
1480 case STATE_PICTURE:
1482 int skip = 0; /* Assume no skip */
1484 if (frame_drop_level >= 1 || skip_level > 0)
1486 /* A frame will be dropped in the decoder */
1488 /* Frame type: I/P/B/D */
1489 int type = info->current_picture->flags & PIC_MASK_CODING_TYPE;
1491 switch (type)
1493 case PIC_FLAG_CODING_TYPE_I:
1494 case PIC_FLAG_CODING_TYPE_D:
1495 /* Level 5: Things are extremely late and all frames will be
1496 dropped until the next key frame */
1497 if (frame_drop_level >= 1)
1498 frame_drop_level = 0; /* Key frame - reset drop level */
1499 if (skip_level >= 5)
1501 frame_drop_level = 1;
1502 skip_level = 0; /* reset */
1504 break;
1505 case PIC_FLAG_CODING_TYPE_P:
1506 /* Level 4: Things are very late and all frames will be
1507 dropped until the next key frame */
1508 if (skip_level >= 4)
1510 frame_drop_level = 1;
1511 skip_level = 0; /* reset */
1513 break;
1514 case PIC_FLAG_CODING_TYPE_B:
1515 /* We want to drop something, so this B frame won't even
1516 be decoded. Drawing can happen on the next frame if so
1517 desired. Bring the level down as skips are done. */
1518 skip = 1;
1519 if (skip_level > 0)
1520 skip_level--;
1523 skip |= frame_drop_level;
1526 mpeg2_skip(mpeg2dec, skip);
1527 break;
1530 case STATE_SLICE:
1531 case STATE_END:
1532 case STATE_INVALID_END:
1534 int32_t offset; /* Tick adjustment to keep sync */
1536 /* draw current picture */
1537 if (!info->display_fbuf)
1538 break;
1540 /* No limiting => no dropping - draw this frame */
1541 if (!settings.limitfps)
1542 goto picture_draw;
1544 /* Get presentation times in audio samples - quite accurate
1545 enough - add previous frame duration if not stamped */
1546 curr_time = (info->display_picture->flags & PIC_FLAG_TAGS) ?
1547 TS_TO_TICKS(info->display_picture->tag) : (curr_time + period);
1549 period = TIME_TO_TICKS(info->sequence->frame_period);
1551 eta_video = curr_time;
1552 eta_audio = get_stream_time();
1554 /* How early/late are we? > 0 = late, < 0 early */
1555 offset = eta_audio - eta_video;
1557 if (!settings.skipframes)
1559 /* Make no effort to determine whether this frame should be
1560 drawn or not since no action can be taken to correct the
1561 situation. We'll just wait if we're early and correct for
1562 lateness as much as possible. */
1563 if (offset < 0)
1564 offset = 0;
1566 eta_late = AVERAGE(eta_late, offset, 4);
1567 offset = eta_late;
1569 if ((uint32_t)offset > eta_video)
1570 offset = eta_video;
1572 eta_video -= offset;
1573 goto picture_wait;
1576 /** Possibly skip this frame **/
1578 /* Frameskipping has the following order of preference:
1580 * Frame Type Who Notes/Rationale
1581 * B decoder arbitrarily drop - no decode or draw
1582 * Any renderer arbitrarily drop - will be I/D/P
1583 * P decoder must wait for I/D-frame - choppy
1584 * I/D decoder must wait for I/D-frame - choppy
1586 * If a frame can be drawn and it has been at least 1/2 second,
1587 * the image will be updated no matter how late it is just to
1588 * avoid looking stuck.
1591 /* If we're late, set the eta to play the frame early so
1592 we may catch up. If early, especially because of a drop,
1593 mitigate a "snap" by moving back gradually. */
1594 if (offset >= 0) /* late or on time */
1596 eta_early = 0; /* Not early now :( */
1598 eta_late = AVERAGE(eta_late, offset, 4);
1599 offset = eta_late;
1601 if ((uint32_t)offset > eta_video)
1602 offset = eta_video;
1604 eta_video -= offset;
1606 else
1608 eta_late = 0; /* Not late now :) */
1610 if (offset > eta_early)
1612 /* Just dropped a frame and we're now early or we're
1613 coming back from being early */
1614 eta_early = offset;
1615 if ((uint32_t)-offset > eta_video)
1616 offset = -eta_video;
1618 eta_video += offset;
1620 else
1622 /* Just early with an offset, do exponential drift back */
1623 if (eta_early != 0)
1625 eta_early = AVERAGE(eta_early, 0, 8);
1626 eta_video = ((uint32_t)-eta_early > eta_video) ?
1627 0 : (eta_video + eta_early);
1630 offset = eta_early;
1634 if (info->display_picture->flags & PIC_FLAG_SKIP)
1636 /* This frame was set to skip so skip it after having updated
1637 timing information */
1638 num_skipped++;
1639 eta_early = INT32_MIN;
1640 goto picture_skip;
1643 if (skip_level == 3 && TIME_BEFORE(*rb->current_tick, last_render + HZ/2))
1645 /* Render drop was set previously but nothing was dropped in the
1646 decoder or it's been to long since drawing the last frame. */
1647 skip_level = 0;
1648 num_skipped++;
1649 eta_early = INT32_MIN;
1650 goto picture_skip;
1653 /* At this point a frame _will_ be drawn - a skip may happen on
1654 the next however */
1655 skip_level = 0;
1657 if (offset > CLOCK_RATE*110/1000)
1659 /* Decide which skip level is needed in order to catch up */
1661 /* TODO: Calculate this rather than if...else - this is rather
1662 exponential though */
1663 if (offset > CLOCK_RATE*367/1000)
1664 skip_level = 5; /* Decoder skip: I/D */
1665 if (offset > CLOCK_RATE*233/1000)
1666 skip_level = 4; /* Decoder skip: P */
1667 else if (offset > CLOCK_RATE*167/1000)
1668 skip_level = 3; /* Render skip */
1669 else if (offset > CLOCK_RATE*133/1000)
1670 skip_level = 2; /* Decoder skip: B */
1671 else
1672 skip_level = 1; /* Decoder skip: B */
1675 picture_wait:
1676 /* Wait until audio catches up */
1677 while (eta_video > eta_audio)
1679 rb->priority_yield();
1681 /* Make sure not to get stuck waiting here forever */
1682 if (str_have_msg(&video_str))
1684 str_look_msg(&video_str, &ev);
1686 /* If not to play, process up top */
1687 if (ev.id != STREAM_PLAY)
1688 goto rendering_finished;
1690 /* Told to play but already playing */
1691 str_get_msg(&video_str, &ev);
1692 str_reply_msg(&video_str, 1);
1695 eta_audio = get_stream_time();
1698 picture_draw:
1699 /* Record last frame time */
1700 last_render = *rb->current_tick;
1702 vo_draw_frame(info->display_fbuf->buf);
1703 num_drawn++;
1705 picture_skip:
1706 if (!settings.showfps)
1707 break;
1709 /* Calculate and display fps */
1710 if (TIME_AFTER(*rb->current_tick, last_showfps + HZ))
1712 uint32_t clock_ticks = get_playback_time() - count_start;
1713 int fps = 0;
1715 if (clock_ticks != 0)
1716 fps = num_drawn*CLOCK_RATE*10ll / clock_ticks;
1718 rb->snprintf(str, sizeof(str), "%d.%d %d %d ",
1719 fps / 10, fps % 10, num_skipped,
1720 info->display_picture->temporal_reference);
1721 rb->lcd_putsxy(0, 0, str);
1722 rb->lcd_update_rect(0, 0, LCD_WIDTH, 8);
1724 last_showfps = *rb->current_tick;
1726 break;
1729 default:
1730 break;
1732 rendering_finished:
1734 rb->yield();
1737 done:
1738 flush_icache();
1740 video_str.status = STREAM_DONE;
1742 while (1)
1744 str_get_msg(&video_str, &ev);
1746 if (ev.id == STREAM_QUIT)
1747 break;
1749 str_reply_msg(&video_str, 0);
1752 video_thread_quit:
1753 flush_icache();
1755 /* Commit suicide */
1756 video_str.status = STREAM_TERMINATED;
1757 rb->remove_thread(NULL);
1760 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1762 int status = PLUGIN_ERROR; /* assume failure */
1763 void* audiobuf;
1764 ssize_t audiosize;
1765 int in_file;
1766 uint8_t* buffer;
1767 size_t file_remaining;
1768 size_t disk_buf_len;
1769 #ifndef HAVE_LCD_COLOR
1770 long graysize;
1771 int grayscales;
1772 #endif
1774 if (parameter == NULL)
1776 api->splash(HZ*2, "No File");
1777 return PLUGIN_ERROR;
1780 /* Initialize IRAM - stops audio and voice as well */
1781 PLUGIN_IRAM_INIT(api)
1783 rb = api;
1785 audiobuf = rb->plugin_get_audio_buffer(&audiosize);
1787 #if INPUT_SRC_CAPS != 0
1788 /* Select playback */
1789 rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
1790 rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
1791 #endif
1793 rb->pcm_set_frequency(SAMPR_44);
1795 /* Set disk pointers to NULL */
1796 disk_buf_end = disk_buf = NULL;
1798 /* Stream construction */
1799 /* We take the first stream of each (audio and video) */
1800 /* TODO : Search for these in the file first */
1801 audio_str.curr_packet_end = audio_str.curr_packet = audio_str.next_packet = NULL;
1802 video_str = audio_str;
1803 video_str.id = 0xe0;
1804 audio_str.id = 0xc0;
1806 /* Initialise our malloc buffer */
1807 mpeg2_alloc_init(audiobuf,audiosize);
1809 /* Grab most of the buffer for the compressed video - leave some for
1810 PCM audio data and some for libmpeg2 malloc use. */
1811 buffer_size = audiosize - (PCMBUFFER_SIZE+PCMBUFFER_GUARD_SIZE+
1812 MPABUF_SIZE+LIBMPEG2BUFFER_SIZE);
1814 DEBUGF("audiosize=%ld, buffer_size=%ld\n",audiosize,buffer_size);
1815 buffer = mpeg2_malloc(buffer_size,-1);
1817 if (buffer == NULL)
1818 return PLUGIN_ERROR;
1820 #ifndef HAVE_LCD_COLOR
1821 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
1822 grayscales = gray_init(rb, buffer, buffer_size, false, LCD_WIDTH, LCD_HEIGHT,
1823 32, 2<<8, &graysize) + 1;
1824 buffer += graysize;
1825 buffer_size -= graysize;
1826 if (grayscales < 33 || buffer_size <= 0)
1828 rb->splash(HZ, "gray buf error");
1829 return PLUGIN_ERROR;
1831 #endif
1833 buffer_size &= ~(0x7ff); /* Round buffer down to nearest 2KB */
1834 DEBUGF("audiosize=%ld, buffer_size=%ld\n",audiosize,buffer_size);
1836 if (!init_mpabuf())
1837 return PLUGIN_ERROR;
1839 if (!init_pcmbuf())
1840 return PLUGIN_ERROR;
1842 /* The remaining buffer is for use by libmpeg2 */
1844 /* Open the video file */
1845 in_file = rb->open((char*)parameter,O_RDONLY);
1847 if (in_file < 0){
1848 //fprintf(stderr,"Could not open %s\n",argv[1]);
1849 return PLUGIN_ERROR;
1852 #ifdef HAVE_LCD_COLOR
1853 rb->lcd_set_backdrop(NULL);
1854 rb->lcd_set_foreground(LCD_WHITE);
1855 rb->lcd_set_background(LCD_BLACK);
1856 #endif
1857 rb->lcd_clear_display();
1858 rb->lcd_update();
1860 /* Turn off backlight timeout */
1861 backlight_force_on(); /* backlight control in lib/helper.c */
1863 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1864 rb->cpu_boost(true);
1865 #endif
1867 /* From this point on we've altered settings, colors, cpu_boost, etc. and
1868 cannot just return PLUGIN_ERROR - instead drop though to cleanup code
1871 init_settings();
1873 /* Msg queue init - no need for queue_remove since it's not a registered
1874 queue */
1875 rb->queue_init( &msg_queue, false );
1877 /* Initialise libmad */
1878 rb->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
1879 init_mad(mad_frame_overlap);
1881 file_remaining = rb->filesize(in_file);
1882 disk_buf_end = buffer + buffer_size-MPEG_GUARDBUF_SIZE;
1884 /* Read some stream data */
1885 disk_buf_len = rb->read (in_file, buffer, MPEG_LOW_WATERMARK);
1887 DEBUGF("Initial Buffering - %d bytes\n",(int)disk_buf_len);
1888 disk_buf = buffer;
1889 disk_buf_tail = buffer+disk_buf_len;
1890 file_remaining -= disk_buf_len;
1892 video_str.guard_bytes = audio_str.guard_bytes = 0;
1893 video_str.prev_packet = disk_buf;
1894 audio_str.prev_packet = disk_buf;
1895 video_str.buffer_remaining = disk_buf_len;
1896 audio_str.buffer_remaining = disk_buf_len;
1898 rb->spinlock_init(&audio_str.msg_lock);
1899 rb->spinlock_init(&video_str.msg_lock);
1900 audio_str.status = STREAM_BUFFERING;
1901 video_str.status = STREAM_PLAYING;
1903 #ifndef HAVE_LCD_COLOR
1904 gray_show(true);
1905 #endif
1907 init_stream_lock();
1909 flush_icache();
1911 /* We put the video thread on the second processor for multi-core targets. */
1912 if ((video_str.thread = rb->create_thread(video_thread,
1913 (uint8_t*)video_stack,VIDEO_STACKSIZE,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK)
1914 IF_COP(, COP, true))) == NULL)
1916 rb->splash(HZ, "Cannot create video thread!");
1918 else if ((audio_str.thread = rb->create_thread(audio_thread,
1919 (uint8_t*)audio_stack,AUDIO_STACKSIZE,"mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK)
1920 IF_COP(, CPU, false))) == NULL)
1922 rb->splash(HZ, "Cannot create audio thread!");
1924 else
1926 //DEBUGF("START: video = %d, audio = %d\n",audio_str.buffer_remaining,video_str.buffer_remaining);
1927 rb->lcd_setfont(FONT_SYSFIXED);
1929 /* Wait until both threads have finished their work */
1930 while ((audio_str.status >= 0) || (video_str.status >= 0))
1932 size_t audio_remaining = audio_str.buffer_remaining;
1933 size_t video_remaining = video_str.buffer_remaining;
1935 if (MIN(audio_remaining,video_remaining) < MPEG_LOW_WATERMARK) {
1937 size_t bytes_to_read = buffer_size - MPEG_GUARDBUF_SIZE -
1938 MAX(audio_remaining,video_remaining);
1940 bytes_to_read = MIN(bytes_to_read,(size_t)(disk_buf_end-disk_buf_tail));
1942 while (( bytes_to_read > 0) && (file_remaining > 0) &&
1943 ((audio_str.status >= 0) || (video_str.status >= 0))) {
1944 size_t n = rb->read(in_file, disk_buf_tail, MIN(32*1024,bytes_to_read));
1946 bytes_to_read -= n;
1947 file_remaining -= n;
1949 lock_stream();
1950 audio_str.buffer_remaining += n;
1951 video_str.buffer_remaining += n;
1952 unlock_stream();
1954 disk_buf_tail += n;
1956 rb->yield();
1959 if (disk_buf_tail == disk_buf_end)
1960 disk_buf_tail = buffer;
1963 rb->sleep(HZ/10);
1966 rb->lcd_setfont(FONT_UI);
1967 status = PLUGIN_OK;
1970 /* Stop the threads and wait for them to terminate */
1971 if (video_str.thread != NULL)
1972 str_send_msg(&video_str, STREAM_QUIT, 0);
1974 if (audio_str.thread != NULL)
1975 str_send_msg(&audio_str, STREAM_QUIT, 0);
1977 rb->sleep(HZ/10);
1979 #ifndef HAVE_LCD_COLOR
1980 gray_release();
1981 #endif
1983 rb->lcd_clear_display();
1984 rb->lcd_update();
1986 mpeg2_close (mpeg2dec);
1988 rb->close (in_file);
1990 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1991 rb->cpu_boost(false);
1992 #endif
1994 save_settings(); /* Save settings (if they have changed) */
1996 rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
1998 /* Turn on backlight timeout (revert to settings) */
1999 backlight_use_settings(); /* backlight control in lib/helper.c */
2001 return status;