2 * mpegplayer.c - based on :
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
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
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
81 In libmpeg2, info->sequence->frame_period contains the frame_period.
83 Working with Rockbox's 100Hz tick, the common frame rates would need
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"
110 #include "mpeg_settings.h"
111 #include "video_out.h"
112 #include "../../codecs/libmad/mad.h"
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 #elif CONFIG_KEYPAD == SANSA_C200_PAD
164 #define MPEG_MENU BUTTON_SELECT
165 #define MPEG_STOP BUTTON_POWER
166 #define MPEG_PAUSE BUTTON_UP
167 #define MPEG_VOLDOWN BUTTON_VOL_DOWN
168 #define MPEG_VOLUP BUTTON_VOL_UP
171 #error MPEGPLAYER: Unsupported keypad
174 struct plugin_api
* rb
;
176 CACHE_FUNCTION_WRAPPERS(rb
);
178 extern void *mpeg_malloc(size_t size
, mpeg2_alloc_t reason
);
179 extern size_t mpeg_alloc_init(unsigned char *buf
, size_t mallocsize
,
180 size_t libmpeg2size
);
182 static mpeg2dec_t
* mpeg2dec NOCACHEBSS_ATTR
;
183 static int total_offset NOCACHEBSS_ATTR
= 0;
184 static int num_drawn NOCACHEBSS_ATTR
= 0;
185 static int count_start NOCACHEBSS_ATTR
= 0;
190 struct thread_entry
*thread
; /* Stream's thread */
191 int status
; /* Current stream status */
192 struct event ev
; /* Event sent to steam */
193 int have_msg
; /* 1=event pending */
194 int replied
; /* 1=replied to last event */
195 int reply
; /* reply value */
196 struct mutex msg_lock
; /* serialization for event senders */
197 uint8_t* curr_packet
; /* Current stream packet beginning */
198 uint8_t* curr_packet_end
; /* Current stream packet end */
200 uint8_t* prev_packet
; /* Previous stream packet beginning */
201 size_t prev_packet_length
; /* Lenth of previous packet */
202 size_t buffer_remaining
; /* How much data is left in the buffer */
203 uint32_t curr_pts
; /* Current presentation timestamp */
204 uint32_t curr_time
; /* Current time in samples */
205 uint32_t tagged
; /* curr_pts is valid */
210 static Stream audio_str IBSS_ATTR
;
211 static Stream video_str IBSS_ATTR
;
226 STREAM_TERMINATED
= -2,
233 /* Returns true if a message is waiting */
234 static inline bool str_have_msg(Stream
*str
)
236 return str
->have_msg
!= 0;
239 /* Waits until a message is sent */
240 static void str_wait_msg(Stream
*str
)
244 while (str
->have_msg
== 0)
246 if (spin_count
< 100)
257 /* Returns a message waiting or blocks until one is available - removes the
259 static void str_get_msg(Stream
*str
, struct event
*ev
)
263 ev
->data
= str
->ev
.data
;
267 /* Peeks at the current message without blocking, returns the data but
268 does not remove the event */
269 static bool str_look_msg(Stream
*str
, struct event
*ev
)
271 if (!str_have_msg(str
))
275 ev
->data
= str
->ev
.data
;
279 /* Replies to the last message pulled - has no effect if last message has not
280 been pulled or already replied */
281 static void str_reply_msg(Stream
*str
, int reply
)
283 if (str
->replied
== 1 || str
->have_msg
!= 0)
290 /* Sends a message to a stream and waits for a reply */
291 static intptr_t str_send_msg(Stream
*str
, int id
, intptr_t data
)
297 if (str
->thread
== rb
->thread_get_current())
298 return str
->dispatch_fn(str
, msg
);
301 /* Only one thread at a time, please */
302 rb
->spinlock_lock(&str
->msg_lock
);
310 while (str
->replied
== 0 && str
->status
!= STREAM_TERMINATED
)
312 if (spin_count
< 100)
324 rb
->spinlock_unlock(&str
->msg_lock
);
329 /* NOTE: Putting the following variables in IRAM cause audio corruption
330 on the ipod (reason unknown)
332 static uint8_t *disk_buf_start IBSS_ATTR
; /* Start pointer */
333 static uint8_t *disk_buf_end IBSS_ATTR
; /* End of buffer pointer less
334 MPEG_GUARDBUF_SIZE. The
335 guard space is used to wrap
336 data at the buffer start to
339 static uint8_t *disk_buf_tail IBSS_ATTR
; /* Location of last data + 1
340 filled into the buffer */
341 static size_t disk_buf_size IBSS_ATTR
; /* The total buffer length
344 static size_t file_remaining IBSS_ATTR
;
347 /* Some stream variables are shared between cores */
348 struct mutex stream_lock IBSS_ATTR
;
349 static inline void init_stream_lock(void)
350 { rb
->spinlock_init(&stream_lock
); }
351 static inline void lock_stream(void)
352 { rb
->spinlock_lock(&stream_lock
); }
353 static inline void unlock_stream(void)
354 { rb
->spinlock_unlock(&stream_lock
); }
356 /* No RMW issue here */
357 static inline void init_stream_lock(void)
359 static inline void lock_stream(void)
361 static inline void unlock_stream(void)
365 static int audio_sync_start IBSS_ATTR
; /* If 0, the audio thread
366 yields waiting on the video
367 thread to synchronize with
369 static uint32_t audio_sync_time IBSS_ATTR
; /* The time that the video
370 thread has reached after
372 audio thread now needs
375 static int video_sync_start IBSS_ATTR
; /* While 0, the video thread
376 yields until the audio
377 thread has reached the
379 static int video_thumb_print IBSS_ATTR
; /* If 1, the video thread is
380 only decoding one frame for
381 use in the menu. If 0,
383 static int play_time IBSS_ATTR
; /* The movie time as represented by
384 the maximum audio PTS tag in the
385 stream converted to half minutes */
386 char *filename
; /* hack for resume time storage */
389 /* Various buffers */
390 /* TODO: Can we reduce the PCM buffer size? */
391 #define PCMBUFFER_SIZE ((512*1024)-PCMBUFFER_GUARD_SIZE)
392 #define PCMBUFFER_GUARD_SIZE (1152*4 + sizeof (struct pcm_frame_header))
393 #define MPA_MAX_FRAME_SIZE 1729 /* Largest frame - MPEG1, Layer II, 384kbps, 32kHz, pad */
394 #define MPABUF_SIZE (64*1024 + ALIGN_UP(MPA_MAX_FRAME_SIZE + 2*MAD_BUFFER_GUARD, 4))
395 #define LIBMPEG2BUFFER_SIZE (2*1024*1024)
397 /* 65536+6 is required since each PES has a 6 byte header with a 16 bit packet length field */
398 #define MPEG_GUARDBUF_SIZE (65*1024) /* Keep a bit extra - excessive for now */
399 #define MPEG_LOW_WATERMARK (1024*1024)
401 static void pcm_playback_play_pause(bool play
);
403 /* libmad related functions/definitions */
404 #define INPUT_CHUNK_SIZE 8192
406 struct mad_stream stream IBSS_ATTR
;
407 struct mad_frame frame IBSS_ATTR
;
408 struct mad_synth synth IBSS_ATTR
;
410 unsigned char mad_main_data
[MAD_BUFFER_MDLEN
]; /* 2567 bytes */
412 /* There isn't enough room for this in IRAM on PortalPlayer, but there
416 static mad_fixed_t mad_frame_overlap
[2][32][18] IBSS_ATTR
; /* 4608 bytes */
418 static mad_fixed_t mad_frame_overlap
[2][32][18] __attribute__((aligned(16))); /* 4608 bytes */
421 static void init_mad(void* mad_frame_overlap
)
423 rb
->memset(&stream
, 0, sizeof(struct mad_stream
));
424 rb
->memset(&frame
, 0, sizeof(struct mad_frame
));
425 rb
->memset(&synth
, 0, sizeof(struct mad_synth
));
427 mad_stream_init(&stream
);
428 mad_frame_init(&frame
);
430 /* We do this so libmad doesn't try to call codec_calloc() */
431 frame
.overlap
= mad_frame_overlap
;
433 rb
->memset(mad_main_data
, 0, sizeof(mad_main_data
));
434 stream
.main_data
= &mad_main_data
;
437 /* MPEG related headers */
439 /* Macros for comparing memory bytes to a series of constant bytes in an
440 efficient manner - evaluate to true if corresponding bytes match */
441 #if defined (CPU_ARM)
442 /* ARM must load 32-bit values at addres % 4 == 0 offsets but this data
443 isn't aligned nescessarily, so just byte compare */
444 #define CMP_3_CONST(_a, _b) \
448 "ldrb %[x], [%[a], #0] \r\n" \
449 "eors %[x], %[x], %[b0] \r\n" \
450 "ldreqb %[x], [%[a], #1] \r\n" \
451 "eoreqs %[x], %[x], %[b1] \r\n" \
452 "ldreqb %[x], [%[a], #2] \r\n" \
453 "eoreqs %[x], %[x], %[b2] \r\n" \
456 [b0]"i"((_b) >> 24), \
457 [b1]"i"((_b) << 8 >> 24), \
458 [b2]"i"((_b) << 16 >> 24) \
462 #define CMP_4_CONST(_a, _b) \
466 "ldrb %[x], [%[a], #0] \r\n" \
467 "eors %[x], %[x], %[b0] \r\n" \
468 "ldreqb %[x], [%[a], #1] \r\n" \
469 "eoreqs %[x], %[x], %[b1] \r\n" \
470 "ldreqb %[x], [%[a], #2] \r\n" \
471 "eoreqs %[x], %[x], %[b2] \r\n" \
472 "ldreqb %[x], [%[a], #3] \r\n" \
473 "eoreqs %[x], %[x], %[b3] \r\n" \
476 [b0]"i"((_b) >> 24), \
477 [b1]"i"((_b) << 8 >> 24), \
478 [b2]"i"((_b) << 16 >> 24), \
479 [b3]"i"((_b) << 24 >> 24) \
483 #elif defined (CPU_COLDFIRE)
484 /* Coldfire can just load a 32 bit value at any offset but ASM is not the best way
485 to integrate this with the C code */
486 #define CMP_3_CONST(a, b) \
487 (((*(uint32_t *)(a) >> 8) ^ ((uint32_t)(b) >> 8)) == 0)
488 #define CMP_4_CONST(a, b) \
489 ((*(uint32_t *)(a) ^ (b)) == 0)
491 /* Don't know what this is - use bytewise comparisons */
492 #define CMP_3_CONST(a, b) \
493 (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
494 ((a)[1] ^ (((b) >> 16) & 0xff)) | \
495 ((a)[2] ^ (((b) >> 8) & 0xff)) ) == 0)
496 #define CMP_4_CONST(a, b) \
497 (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
498 ((a)[1] ^ (((b) >> 16) & 0xff)) | \
499 ((a)[2] ^ (((b) >> 8) & 0xff)) | \
500 ((a)[3] ^ ((b) & 0xff)) ) == 0)
503 /* Codes for various header byte sequences - MSB represents lowest memory
505 #define PACKET_START_CODE_PREFIX 0x00000100ul
506 #define END_CODE 0x000001b9ul
507 #define PACK_START_CODE 0x000001baul
508 #define SYSTEM_HEADER_START_CODE 0x000001bbul
510 /* p = base pointer, b0 - b4 = byte offsets from p */
511 /* We only care about the MS 32 bits of the 33 and so the ticks are 45kHz */
512 #define TS_FROM_HEADER(p, b0, b1, b2, b3, b4) \
513 ((uint32_t)(((p)[b0] >> 1 << 29) | \
515 ((p)[b2] >> 1 << 14) | \
519 /* This function synchronizes the mpeg stream. The function returns
521 bool sync_data_stream(uint8_t **p
)
525 while ( !CMP_4_CONST(*p
, PACK_START_CODE
) && (*p
) < disk_buf_tail
)
527 if ( (*p
) >= disk_buf_tail
)
529 uint8_t *p_save
= (*p
);
530 if ( ((*p
)[4] & 0xc0) == 0x40 ) /* mpeg-2 */
531 (*p
) += 14 + ((*p
)[13] & 7);
532 else if ( ((*p
)[4] & 0xf0) == 0x20 ) /* mpeg-1 */
536 if ( (*p
) >= disk_buf_tail
)
538 if ( CMP_3_CONST(*p
, PACKET_START_CODE_PREFIX
) )
547 if ( (*p
) >= disk_buf_tail
)
553 /* This function demuxes the streams and gives the next stream data
554 pointer. Type 0 is normal operation. Type 1 and 2 have been added
555 for rapid seeks into the data stream. Type 1 and 2 ignore the
556 video_sync_start state (a signal to yield for refilling the
557 buffer). Type 1 will append more data to the buffer tail (minumal
558 bufer size reads that are increased only as needed). */
559 static int get_next_data( Stream
* str
, uint8_t type
)
565 static int mpeg1_skip_table
[16] =
566 { 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
568 if ( (p
=str
->curr_packet_end
) == NULL
)
575 /* Yield for buffer filling */
576 if ( (type
== 0) && (str
->buffer_remaining
< 120*1024) && (file_remaining
> 0) )
577 while ( (str
->buffer_remaining
< 512*1024) && (file_remaining
> 0) )
580 /* The packet start position (plus an arbitrary header length)
581 has exceeded the amount of data in the buffer */
582 if ( type
== 1 && (p
+50) >= disk_buf_tail
)
584 DEBUGF("disk buffer overflow\n");
588 /* are we at the end of file? */
591 if (p
< str
->prev_packet
)
592 tmp_length
= (disk_buf_end
- str
->prev_packet
) +
593 (p
- disk_buf_start
);
595 tmp_length
= (p
- str
->prev_packet
);
596 if (0 == str
->buffer_remaining
-tmp_length
-str
->prev_packet_length
)
598 str
->curr_packet_end
= str
->curr_packet
= NULL
;
603 /* wrap the disk buffer */
604 if (p
>= disk_buf_end
)
605 p
= disk_buf_start
+ (p
- disk_buf_end
);
607 /* wrap packet header if needed */
608 if ( (p
+50) >= disk_buf_end
)
609 rb
->memcpy(disk_buf_end
, disk_buf_start
, 50);
611 /* Pack header, skip it */
612 if (CMP_4_CONST(p
, PACK_START_CODE
))
614 if ((p
[4] & 0xc0) == 0x40) /* mpeg-2 */
616 p
+= 14 + (p
[13] & 7);
618 else if ((p
[4] & 0xf0) == 0x20) /* mpeg-1 */
624 rb
->splash( 30, "Weird Pack header!" );
629 /* System header, parse and skip it - four bytes */
630 if (CMP_4_CONST(p
, SYSTEM_HEADER_START_CODE
))
634 p
+= 4; /*skip start code*/
635 header_length
= *p
++ << 8;
636 header_length
+= *p
++;
640 if ( p
>= disk_buf_end
)
641 p
= disk_buf_start
+ (p
- disk_buf_end
);
644 /* Packet header, parse it */
645 if (!CMP_3_CONST(p
, PACKET_START_CODE_PREFIX
))
648 rb
->splash( HZ
*3, "missing packet start code prefix : %X%X at %lX",
649 *p
, *(p
+2), (long unsigned int)(p
-disk_buf_start
) );
652 DEBUGF("end diff: %X,%X,%X,%X,%X,%X\n",(int)str->curr_packet_end,
653 (int)audio_str.curr_packet_end,(int)video_str.curr_packet_end,
654 (int)disk_buf_start,(int)disk_buf_end,(int)disk_buf_tail);
657 str
->curr_packet_end
= str
->curr_packet
= NULL
;
661 /* We retrieve basic infos */
663 length
= (p
[4] << 8) | p
[5];
665 if (stream
!= str
->id
)
667 /* End of stream ? */
670 str
->curr_packet_end
= str
->curr_packet
= NULL
;
674 /* It's not the packet we're looking for, skip it */
679 /* Ok, it's our packet */
680 str
->curr_packet_end
= p
+ length
+6;
683 if ((header
[6] & 0xc0) == 0x80) /* mpeg2 */
685 length
= 9 + header
[8];
687 /* header points to the mpeg2 pes header */
688 if (header
[7] & 0x80)
690 /* header has a pts */
691 uint32_t pts
= TS_FROM_HEADER(header
, 9, 10, 11, 12, 13);
695 /* video stream - header may have a dts as well */
696 uint32_t dts
= (header
[7] & 0x40) == 0 ?
697 pts
: TS_FROM_HEADER(header
, 14, 15, 16, 17, 18);
699 mpeg2_tag_picture (mpeg2dec
, pts
, dts
);
715 while (header
[length
- 1] == 0xff)
720 rb
->splash( 30, "Too much stuffing" );
721 DEBUGF("Too much stuffing" );
726 if ( (header
[length
- 1] & 0xc0) == 0x40 )
730 length
+= mpeg1_skip_table
[header
[length
- 1] >> 4];
732 /* header points to the mpeg1 pes header */
733 ptsbuf
= header
+ len_skip
;
735 if ((ptsbuf
[-1] & 0xe0) == 0x20)
737 /* header has a pts */
738 uint32_t pts
= TS_FROM_HEADER(ptsbuf
, -1, 0, 1, 2, 3);
742 /* video stream - header may have a dts as well */
743 uint32_t dts
= (ptsbuf
[-1] & 0xf0) != 0x30 ?
744 pts
: TS_FROM_HEADER(ptsbuf
, 4, 5, 6, 7, 18);
746 mpeg2_tag_picture (mpeg2dec
, pts
, dts
);
757 bytes
= 6 + (header
[4] << 8) + header
[5] - length
;
761 str
->curr_packet_end
= p
+ bytes
;
763 if (str
->curr_packet
!= NULL
)
767 str
->buffer_remaining
-= str
->prev_packet_length
;
768 if (str
->curr_packet
< str
->prev_packet
)
769 str
->prev_packet_length
= (disk_buf_end
- str
->prev_packet
) +
770 (str
->curr_packet
- disk_buf_start
);
772 str
->prev_packet_length
= (str
->curr_packet
- str
->prev_packet
);
776 str
->prev_packet
= str
->curr_packet
;
779 str
->curr_packet
= p
;
781 if (str
->curr_packet_end
> disk_buf_end
)
782 rb
->memcpy(disk_buf_end
, disk_buf_start
,
783 str
->curr_packet_end
- disk_buf_end
);
791 /* Our clock rate in ticks/second - this won't be a constant for long */
792 #define CLOCK_RATE 44100
794 /* For simple lowpass filtering of sync variables */
795 #define AVERAGE(var, x, count) (((var) * (count-1) + (x)) / (count))
796 /* Convert 45kHz PTS/DTS ticks to our clock ticks */
797 #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / 45000)
798 /* Convert 27MHz ticks to our clock ticks */
799 #define TIME_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / 27000000)
801 /** MPEG audio stream buffer */
802 uint8_t* mpa_buffer NOCACHEBSS_ATTR
;
804 static bool init_mpabuf(void)
806 mpa_buffer
= mpeg_malloc(MPABUF_SIZE
,-2);
807 return mpa_buffer
!= NULL
;
810 #define PTS_QUEUE_LEN (1 << 5) /* 32 should be way more than sufficient -
811 if not, the case is handled */
812 #define PTS_QUEUE_MASK (PTS_QUEUE_LEN-1)
813 struct pts_queue_slot
815 uint32_t pts
; /* Time stamp for packet */
816 ssize_t size
; /* Number of bytes left in packet */
817 } pts_queue
[PTS_QUEUE_LEN
] __attribute__((aligned(16)));
819 /* This starts out wr == rd but will never be emptied to zero during
820 streaming again in order to support initializing the first packet's
821 pts value without a special case */
822 static unsigned pts_queue_rd NOCACHEBSS_ATTR
;
823 static unsigned pts_queue_wr NOCACHEBSS_ATTR
;
825 /* Increments the queue head postion - should be used to preincrement */
826 static bool pts_queue_add_head(void)
828 if (pts_queue_wr
- pts_queue_rd
>= PTS_QUEUE_LEN
-1)
835 /* Increments the queue tail position - leaves one slot as current */
836 static bool pts_queue_remove_tail(void)
838 if (pts_queue_wr
- pts_queue_rd
<= 1u)
845 /* Returns the "head" at the index just behind the write index */
846 static struct pts_queue_slot
* pts_queue_head(void)
848 return &pts_queue
[(pts_queue_wr
- 1) & PTS_QUEUE_MASK
];
851 /* Returns a pointer to the current tail */
852 static struct pts_queue_slot
* pts_queue_tail(void)
854 return &pts_queue
[pts_queue_rd
& PTS_QUEUE_MASK
];
857 /* Resets the pts queue - call when starting and seeking */
858 static void pts_queue_reset(void)
860 struct pts_queue_slot
*pts
;
861 pts_queue_rd
= pts_queue_wr
;
862 pts
= pts_queue_tail();
867 struct pcm_frame_header
/* Header added to pcm data every time a decoded
868 mpa frame is sent out */
870 uint32_t size
; /* size of this frame - including header */
871 uint32_t time
; /* timestamp for this frame - derived from PTS */
872 unsigned char data
[]; /* open array of audio data */
875 #define PCMBUF_PLAY_ALL 1l /* Forces buffer to play back all data */
876 #define PCMBUF_PLAY_NONE LONG_MAX /* Keeps buffer from playing any data */
877 static volatile uint64_t pcmbuf_read IBSS_ATTR
;
878 static volatile uint64_t pcmbuf_written IBSS_ATTR
;
879 static volatile ssize_t pcmbuf_threshold IBSS_ATTR
;
880 static struct pcm_frame_header
*pcm_buffer IBSS_ATTR
;
881 static struct pcm_frame_header
*pcmbuf_end IBSS_ATTR
;
882 static struct pcm_frame_header
* volatile pcmbuf_head IBSS_ATTR
;
883 static struct pcm_frame_header
* volatile pcmbuf_tail IBSS_ATTR
;
885 static volatile uint32_t samplesplayed IBSS_ATTR
; /* Our base clock */
886 static volatile uint32_t samplestart IBSS_ATTR
; /* Clock at playback start */
887 static volatile int32_t sampleadjust IBSS_ATTR
; /* Clock drift adjustment */
889 static ssize_t
pcmbuf_used(void)
891 return (ssize_t
)(pcmbuf_written
- pcmbuf_read
);
894 static bool init_pcmbuf(void)
896 pcm_buffer
= mpeg_malloc(PCMBUFFER_SIZE
+ PCMBUFFER_GUARD_SIZE
, -2);
898 if (pcm_buffer
== NULL
)
901 pcmbuf_head
= pcm_buffer
;
902 pcmbuf_tail
= pcm_buffer
;
903 pcmbuf_end
= SKIPBYTES(pcm_buffer
, PCMBUFFER_SIZE
);
910 /* Advance a PCM buffer pointer by size bytes circularly */
911 static inline void pcm_advance_buffer(struct pcm_frame_header
* volatile *p
,
914 *p
= SKIPBYTES(*p
, size
);
915 if (*p
>= pcmbuf_end
)
919 static void get_more(unsigned char** start
, size_t* size
)
922 static unsigned char silence
[4412] __attribute__((aligned (4))) = { 0 };
925 if (pcmbuf_used() >= pcmbuf_threshold
)
927 uint32_t time
= pcmbuf_tail
->time
;
928 sz
= pcmbuf_tail
->size
;
930 *start
= (unsigned char *)pcmbuf_tail
->data
;
932 pcm_advance_buffer(&pcmbuf_tail
, sz
);
936 sz
-= sizeof (*pcmbuf_tail
);
940 /* Drift the clock towards the audio timestamp values */
941 sampleadjust
= AVERAGE(sampleadjust
, (int32_t)(time
- samplesplayed
), 8);
943 /* Update master clock */
944 samplesplayed
+= sz
>> 2;
948 /* Keep clock going at all times */
949 sz
= sizeof (silence
);
953 samplesplayed
+= sz
>> 2;
955 if (pcmbuf_read
> pcmbuf_written
)
956 pcmbuf_read
= pcmbuf_written
;
959 /* Flushes the buffer - clock keeps counting */
960 static void pcm_playback_flush(void)
962 bool was_playing
= rb
->pcm_is_playing();
969 pcmbuf_head
= pcmbuf_tail
;
972 rb
->pcm_play_data(get_more
, NULL
, 0);
975 /* Seek the reference clock to the specified time - next audio data ready to
976 go to DMA should be on the buffer with the same time index or else the PCM
977 buffer should be empty */
978 static void pcm_playback_seek_time(uint32_t time
)
980 bool was_playing
= rb
->pcm_is_playing();
985 samplesplayed
= time
;
990 rb
->pcm_play_data(get_more
, NULL
, 0);
993 /* Start pcm playback with the reference clock set to the specified time */
994 static void pcm_playback_play(uint32_t time
)
996 pcm_playback_seek_time(time
);
998 if (!rb
->pcm_is_playing())
999 rb
->pcm_play_data(get_more
, NULL
, 0);
1002 /* Pauses playback - and the clock */
1003 static void pcm_playback_play_pause(bool play
)
1005 rb
->pcm_play_pause(play
);
1008 /* Stops all playback and resets the clock */
1009 static void pcm_playback_stop(void)
1011 if (rb
->pcm_is_playing())
1012 rb
->pcm_play_stop();
1014 pcm_playback_flush();
1021 static uint32_t get_stream_time(void)
1023 return samplesplayed
+ sampleadjust
- (rb
->pcm_get_bytes_waiting() >> 2);
1026 static uint32_t get_playback_time(void)
1028 return samplesplayed
+ sampleadjust
-
1029 samplestart
- (rb
->pcm_get_bytes_waiting() >> 2);
1032 static inline int32_t clip_sample(int32_t sample
)
1034 if ((int16_t)sample
!= sample
)
1035 sample
= 0x7fff ^ (sample
>> 31);
1040 static int button_loop(void)
1043 int vol
, minvol
, maxvol
;
1046 if (video_sync_start
==1) {
1048 if (str_have_msg(&audio_str
))
1051 str_get_msg(&audio_str
, &ev
);
1053 if (ev
.id
== STREAM_QUIT
)
1055 audio_str
.status
= STREAM_STOPPED
;
1060 str_reply_msg(&audio_str
, 0);
1064 button
= rb
->button_get(false);
1069 case MPEG_VOLUP
|BUTTON_REPEAT
:
1072 case MPEG_VOLUP2
|BUTTON_REPEAT
:
1074 vol
= rb
->global_settings
->volume
;
1075 maxvol
= rb
->sound_max(SOUND_VOLUME
);
1079 rb
->sound_set(SOUND_VOLUME
, vol
);
1080 rb
->global_settings
->volume
= vol
;
1085 case MPEG_VOLDOWN
|BUTTON_REPEAT
:
1086 #ifdef MPEG_VOLDOWN2
1088 case MPEG_VOLDOWN2
|BUTTON_REPEAT
:
1090 vol
= rb
->global_settings
->volume
;
1091 minvol
= rb
->sound_min(SOUND_VOLUME
);
1095 rb
->sound_set(SOUND_VOLUME
, vol
);
1096 rb
->global_settings
->volume
= vol
;
1101 pcm_playback_play_pause(false);
1102 audio_str
.status
= STREAM_PAUSED
;
1103 str_send_msg(&video_str
, STREAM_PAUSE
, 0);
1104 #ifndef HAVE_LCD_COLOR
1107 result
= mpeg_menu();
1108 count_start
= get_playback_time();
1111 #ifndef HAVE_LCD_COLOR
1115 /* The menu can change the font, so restore */
1116 rb
->lcd_setfont(FONT_SYSFIXED
);
1119 settings
.resume_time
= (int)(get_stream_time()/44100/30);
1120 str_send_msg(&video_str
, STREAM_QUIT
, 0);
1121 audio_str
.status
= STREAM_STOPPED
;
1123 audio_str
.status
= STREAM_PLAYING
;
1124 str_send_msg(&video_str
, STREAM_PLAY
, 0);
1125 pcm_playback_play_pause(true);
1130 settings
.resume_time
= (int)(get_stream_time()/44100/30);
1131 str_send_msg(&video_str
, STREAM_QUIT
, 0);
1132 audio_str
.status
= STREAM_STOPPED
;
1136 str_send_msg(&video_str
, STREAM_PAUSE
, 0);
1137 audio_str
.status
= STREAM_PAUSED
;
1138 pcm_playback_play_pause(false);
1140 button
= BUTTON_NONE
;
1141 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1142 rb
->cpu_boost(false);
1145 button
= rb
->button_get(true);
1146 if (button
== MPEG_STOP
) {
1147 str_send_msg(&video_str
, STREAM_QUIT
, 0);
1148 audio_str
.status
= STREAM_STOPPED
;
1151 } while (button
!= MPEG_PAUSE
);
1153 str_send_msg(&video_str
, STREAM_PLAY
, 0);
1154 audio_str
.status
= STREAM_PLAYING
;
1155 pcm_playback_play_pause(true);
1156 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
1157 rb
->cpu_boost(true);
1162 if(rb
->default_event_handler(button
) == SYS_USB_CONNECTED
) {
1163 str_send_msg(&video_str
, STREAM_QUIT
, 0);
1164 audio_str
.status
= STREAM_STOPPED
;
1169 return audio_str
.status
;
1172 static void audio_thread(void)
1174 uint8_t *mpabuf
= mpa_buffer
;
1175 ssize_t mpabuf_used
= 0;
1176 int mad_errors
= 0; /* A count of the errors in each frame */
1177 struct pts_queue_slot
*pts
;
1179 /* We need this here to init the EMAC for Coldfire targets */
1180 mad_synth_init(&synth
);
1182 /* Init pts queue */
1184 pts
= pts_queue_tail();
1186 /* Keep buffer from playing */
1187 pcmbuf_threshold
= PCMBUF_PLAY_NONE
;
1190 pcm_playback_play(0);
1192 /* Get first packet */
1193 get_next_data(&audio_str
, 0 );
1195 /* skip audio packets here */
1196 while (audio_sync_start
==0)
1198 audio_str
.status
= STREAM_PLAYING
;
1202 if (audio_sync_time
>10000)
1204 while (TS_TO_TICKS(audio_str
.curr_pts
) < audio_sync_time
- 10000)
1206 get_next_data(&audio_str
, 0 );
1207 rb
->priority_yield();
1211 if (audio_str
.curr_packet
== NULL
)
1214 /* This is the decoding loop. */
1220 if (button_loop() == STREAM_STOPPED
)
1221 goto audio_thread_quit
;
1225 /* Carry any overshoot to the next size since we're technically
1226 -pts->size bytes into it already. If size is negative an audio
1227 frame was split accross packets. Old has to be saved before
1229 if (pts_queue_remove_tail())
1231 struct pts_queue_slot
*old
= pts
;
1232 pts
= pts_queue_tail();
1233 pts
->size
+= old
->size
;
1239 if (mpabuf_used
>= MPA_MAX_FRAME_SIZE
+ MAD_BUFFER_GUARD
)
1241 /* Above low watermark - do nothing */
1243 else if (audio_str
.curr_packet
!= NULL
)
1247 /* Get data from next audio packet */
1248 len
= audio_str
.curr_packet_end
- audio_str
.curr_packet
;
1250 if (audio_str
.tagged
)
1252 struct pts_queue_slot
*stamp
= pts
;
1254 if (pts_queue_add_head())
1256 stamp
= pts_queue_head();
1257 stamp
->pts
= TS_TO_TICKS(audio_str
.curr_pts
);
1258 /* pts->size should have been zeroed when slot was
1261 /* else queue full - just count up from the last to make
1262 it look like more data in the same packet */
1264 audio_str
.tagged
= 0;
1268 /* Add to the one just behind the head - this may be the
1269 tail or the previouly added head - whether or not we'll
1270 ever reach this is quite in question since audio always
1271 seems to have every packet timestamped */
1272 pts_queue_head()->size
+= len
;
1275 /* Slide any remainder over to beginning - avoid function
1276 call overhead if no data remaining as well */
1277 if (mpabuf
> mpa_buffer
&& mpabuf_used
> 0)
1278 rb
->memmove(mpa_buffer
, mpabuf
, mpabuf_used
);
1280 /* Splice this packet onto any remainder */
1281 rb
->memcpy(mpa_buffer
+ mpabuf_used
, audio_str
.curr_packet
,
1285 mpabuf
= mpa_buffer
;
1287 /* Get data from next audio packet */
1288 get_next_data(&audio_str
, 0 );
1290 while (audio_str
.curr_packet
!= NULL
&&
1291 mpabuf_used
< MPA_MAX_FRAME_SIZE
+ MAD_BUFFER_GUARD
);
1293 else if (mpabuf_used
<= 0)
1295 /* Used up remainder of mpa buffer so quit */
1300 mad_stream_buffer(&stream
, mpabuf
, mpabuf_used
);
1302 mad_stat
= mad_frame_decode(&frame
, &stream
);
1304 if (stream
.next_frame
== NULL
)
1306 /* What to do here? (This really is fatal) */
1307 DEBUGF("/* What to do here? */\n");
1311 /* Next mad stream buffer is the next frame postion */
1312 mpabuf
= (uint8_t *)stream
.next_frame
;
1314 /* Adjust sizes by the frame size */
1315 len
= stream
.next_frame
- stream
.this_frame
;
1321 if (stream
.error
== MAD_FLAG_INCOMPLETE
1322 || stream
.error
== MAD_ERROR_BUFLEN
)
1324 /* This makes the codec support partially corrupted files */
1325 if (++mad_errors
> 30)
1329 rb
->priority_yield();
1332 else if (MAD_RECOVERABLE(stream
.error
))
1335 rb
->priority_yield();
1340 /* Some other unrecoverable error */
1341 DEBUGF("Unrecoverable error\n");
1347 mad_errors
= 0; /* Clear errors */
1349 /* Generate the pcm samples */
1350 mad_synth_frame(&synth
, &frame
);
1354 /* TODO: Output through core dsp. We'll still use our own PCM buffer
1355 since the core pcm buffer has no timestamping or clock facilities */
1357 /* Add a frame of audio to the pcm buffer. Maximum is 1152 samples. */
1358 if (synth
.pcm
.length
> 0)
1360 int16_t *audio_data
= (int16_t *)pcmbuf_head
->data
;
1361 size_t size
= sizeof (*pcmbuf_head
) + synth
.pcm
.length
*4;
1362 size_t wait_for
= size
+ 32*1024;
1364 /* Leave at least 32KB free (this will be the currently
1366 while (pcmbuf_used() + wait_for
> PCMBUFFER_SIZE
)
1368 if (str_have_msg(&audio_str
))
1371 str_look_msg(&audio_str
, &ev
);
1373 if (ev
.id
== STREAM_QUIT
)
1374 goto audio_thread_quit
;
1377 rb
->priority_yield();
1380 if (video_sync_start
== 0 &&
1381 pts
->pts
+(uint32_t)synth
.pcm
.length
<audio_sync_time
) {
1382 synth
.pcm
.length
= 0;
1387 /* TODO: This part will be replaced with dsp calls soon */
1388 if (MAD_NCHANNELS(&frame
.header
) == 2)
1390 int32_t *left
= &synth
.pcm
.samples
[0][0];
1391 int32_t *right
= &synth
.pcm
.samples
[1][0];
1392 int i
= synth
.pcm
.length
;
1396 /* libmad outputs s3.28 */
1397 *audio_data
++ = clip_sample(*left
++ >> 13);
1398 *audio_data
++ = clip_sample(*right
++ >> 13);
1404 int32_t *mono
= &synth
.pcm
.samples
[0][0];
1405 int i
= synth
.pcm
.length
;
1409 int32_t s
= clip_sample(*mono
++ >> 13);
1417 pcmbuf_head
->time
= pts
->pts
;
1418 pcmbuf_head
->size
= size
;
1420 /* As long as we're on this timestamp, the time is just incremented
1421 by the number of samples */
1422 pts
->pts
+= synth
.pcm
.length
;
1424 pcm_advance_buffer(&pcmbuf_head
, size
);
1426 if (pcmbuf_threshold
!= PCMBUF_PLAY_ALL
&& pcmbuf_used() >= 64*1024)
1428 /* We've reached our size treshold so start playing back the
1429 audio in the buffer and set the buffer to play all data */
1430 audio_str
.status
= STREAM_PLAYING
;
1431 pcmbuf_threshold
= PCMBUF_PLAY_ALL
;
1432 pcm_playback_seek_time(pcmbuf_tail
->time
);
1433 video_sync_start
= 1;
1436 /* Make this data available to DMA */
1437 pcmbuf_written
+= size
;
1441 } /* end decoding loop */
1444 if (audio_str
.status
== STREAM_STOPPED
)
1445 goto audio_thread_quit
;
1447 /* Force any residue to play if audio ended before reaching the
1449 if (pcmbuf_threshold
!= PCMBUF_PLAY_ALL
&& pcmbuf_used() > 0)
1451 pcm_playback_play(pcmbuf_tail
->time
);
1452 pcmbuf_threshold
= PCMBUF_PLAY_ALL
;
1455 if (rb
->pcm_is_playing() && !rb
->pcm_is_paused())
1457 /* Wait for audio to finish */
1458 while (pcmbuf_used() > 0)
1460 if (button_loop() == STREAM_STOPPED
)
1461 goto audio_thread_quit
;
1466 audio_str
.status
= STREAM_DONE
;
1468 /* Process events until finished */
1469 while (button_loop() != STREAM_STOPPED
)
1473 pcm_playback_stop();
1475 audio_str
.status
= STREAM_TERMINATED
;
1478 /* End of libmad stuff */
1480 /* TODO: Running in the main thread, libmad needs 8.25KB of stack.
1481 The codec thread uses a 9KB stack. So we can probable reduce this a
1482 little, but leave at 9KB for now to be safe. */
1483 #define AUDIO_STACKSIZE (9*1024)
1484 uint32_t audio_stack
[AUDIO_STACKSIZE
/ sizeof(uint32_t)] IBSS_ATTR
;
1486 /* TODO: Check if 4KB is appropriate - it works for my test streams,
1487 so maybe we can reduce it. */
1488 #define VIDEO_STACKSIZE (4*1024)
1489 static uint32_t video_stack
[VIDEO_STACKSIZE
/ sizeof(uint32_t)] IBSS_ATTR
;
1491 static void video_thread(void)
1494 const mpeg2_info_t
* info
;
1495 mpeg2_state_t state
;
1497 uint32_t curr_time
= 0;
1498 uint32_t period
= 0; /* Frame period in clock ticks */
1499 uint32_t eta_audio
= UINT_MAX
, eta_video
= 0;
1500 int32_t eta_early
= 0, eta_late
= 0;
1501 int frame_drop_level
= 0;
1503 int num_skipped
= 0;
1504 /* Used to decide when to display FPS */
1505 unsigned long last_showfps
= *rb
->current_tick
- HZ
;
1506 /* Used to decide whether or not to force a frame update */
1507 unsigned long last_render
= last_showfps
;
1509 mpeg2dec
= mpeg2_init();
1510 if (mpeg2dec
== NULL
)
1512 rb
->splash(0, "mpeg2_init failed");
1513 /* Commit suicide */
1514 video_str
.status
= STREAM_TERMINATED
;
1518 /* Clear the display - this is mainly just to indicate that the
1519 video thread has started successfully. */
1520 if (!video_thumb_print
)
1522 rb
->lcd_clear_display();
1526 /* Request the first packet data */
1527 get_next_data( &video_str
, 0 );
1529 if (video_str
.curr_packet
== NULL
)
1530 goto video_thread_quit
;
1532 mpeg2_buffer (mpeg2dec
, video_str
.curr_packet
, video_str
.curr_packet_end
);
1533 total_offset
+= video_str
.curr_packet_end
- video_str
.curr_packet
;
1535 info
= mpeg2_info (mpeg2dec
);
1539 /* quickly check mailbox first */
1540 if (video_thumb_print
)
1542 if (video_str
.status
== STREAM_STOPPED
)
1545 else if (str_have_msg(&video_str
))
1549 str_get_msg(&video_str
, &ev
);
1554 video_str
.status
= STREAM_STOPPED
;
1555 goto video_thread_quit
;
1560 video_str
.status
= STREAM_PAUSED
;
1561 str_reply_msg(&video_str
, 1);
1568 video_str
.status
= STREAM_PLAYING
;
1569 str_reply_msg(&video_str
, 1);
1572 state
= mpeg2_parse (mpeg2dec
);
1575 /* Prevent idle poweroff */
1576 rb
->reset_poweroff_timer();
1581 /* Request next packet data */
1582 get_next_data( &video_str
, 0 );
1584 mpeg2_buffer (mpeg2dec
, video_str
.curr_packet
, video_str
.curr_packet_end
);
1585 total_offset
+= video_str
.curr_packet_end
- video_str
.curr_packet
;
1586 info
= mpeg2_info (mpeg2dec
);
1588 if (video_str
.curr_packet
== NULL
)
1591 goto video_thread_quit
;
1595 case STATE_SEQUENCE
:
1596 /* New GOP, inform output of any changes */
1597 vo_setup(info
->sequence
);
1602 int skip
= 0; /* Assume no skip */
1604 if (frame_drop_level
>= 1 || skip_level
> 0)
1606 /* A frame will be dropped in the decoder */
1608 /* Frame type: I/P/B/D */
1609 int type
= info
->current_picture
->flags
& PIC_MASK_CODING_TYPE
;
1613 case PIC_FLAG_CODING_TYPE_I
:
1614 case PIC_FLAG_CODING_TYPE_D
:
1615 /* Level 5: Things are extremely late and all frames will be
1616 dropped until the next key frame */
1617 if (frame_drop_level
>= 1)
1618 frame_drop_level
= 0; /* Key frame - reset drop level */
1619 if (skip_level
>= 5)
1621 frame_drop_level
= 1;
1622 skip_level
= 0; /* reset */
1625 case PIC_FLAG_CODING_TYPE_P
:
1626 /* Level 4: Things are very late and all frames will be
1627 dropped until the next key frame */
1628 if (skip_level
>= 4)
1630 frame_drop_level
= 1;
1631 skip_level
= 0; /* reset */
1634 case PIC_FLAG_CODING_TYPE_B
:
1635 /* We want to drop something, so this B frame won't even
1636 be decoded. Drawing can happen on the next frame if so
1637 desired. Bring the level down as skips are done. */
1643 skip
|= frame_drop_level
;
1646 mpeg2_skip(mpeg2dec
, skip
);
1652 case STATE_INVALID_END
:
1654 int32_t offset
; /* Tick adjustment to keep sync */
1656 /* draw current picture */
1657 if (!info
->display_fbuf
)
1660 /* No limiting => no dropping - draw this frame */
1661 if (!settings
.limitfps
&& (video_thumb_print
== 0))
1663 audio_sync_start
= 1;
1664 video_sync_start
= 1;
1668 /* Get presentation times in audio samples - quite accurate
1669 enough - add previous frame duration if not stamped */
1670 curr_time
= (info
->display_picture
->flags
& PIC_FLAG_TAGS
) ?
1671 TS_TO_TICKS(info
->display_picture
->tag
) : (curr_time
+ period
);
1673 period
= TIME_TO_TICKS(info
->sequence
->frame_period
);
1675 if ( (video_thumb_print
== 1 || video_sync_start
== 0) &&
1676 ((int)(info
->current_picture
->flags
& PIC_MASK_CODING_TYPE
)
1677 == PIC_FLAG_CODING_TYPE_B
))
1680 eta_video
= curr_time
;
1682 audio_sync_time
= eta_video
;
1683 audio_sync_start
= 1;
1685 while (video_sync_start
== 0)
1688 eta_audio
= get_stream_time();
1690 /* How early/late are we? > 0 = late, < 0 early */
1691 offset
= eta_audio
- eta_video
;
1693 if (!settings
.skipframes
)
1695 /* Make no effort to determine whether this frame should be
1696 drawn or not since no action can be taken to correct the
1697 situation. We'll just wait if we're early and correct for
1698 lateness as much as possible. */
1702 eta_late
= AVERAGE(eta_late
, offset
, 4);
1705 if ((uint32_t)offset
> eta_video
)
1708 eta_video
-= offset
;
1712 /** Possibly skip this frame **/
1714 /* Frameskipping has the following order of preference:
1716 * Frame Type Who Notes/Rationale
1717 * B decoder arbitrarily drop - no decode or draw
1718 * Any renderer arbitrarily drop - will be I/D/P
1719 * P decoder must wait for I/D-frame - choppy
1720 * I/D decoder must wait for I/D-frame - choppy
1722 * If a frame can be drawn and it has been at least 1/2 second,
1723 * the image will be updated no matter how late it is just to
1724 * avoid looking stuck.
1727 /* If we're late, set the eta to play the frame early so
1728 we may catch up. If early, especially because of a drop,
1729 mitigate a "snap" by moving back gradually. */
1730 if (offset
>= 0) /* late or on time */
1732 eta_early
= 0; /* Not early now :( */
1734 eta_late
= AVERAGE(eta_late
, offset
, 4);
1737 if ((uint32_t)offset
> eta_video
)
1740 eta_video
-= offset
;
1744 eta_late
= 0; /* Not late now :) */
1746 if (offset
> eta_early
)
1748 /* Just dropped a frame and we're now early or we're
1749 coming back from being early */
1751 if ((uint32_t)-offset
> eta_video
)
1752 offset
= -eta_video
;
1754 eta_video
+= offset
;
1758 /* Just early with an offset, do exponential drift back */
1761 eta_early
= AVERAGE(eta_early
, 0, 8);
1762 eta_video
= ((uint32_t)-eta_early
> eta_video
) ?
1763 0 : (eta_video
+ eta_early
);
1770 if (info
->display_picture
->flags
& PIC_FLAG_SKIP
)
1772 /* This frame was set to skip so skip it after having updated
1773 timing information */
1775 eta_early
= INT32_MIN
;
1779 if (skip_level
== 3 && TIME_BEFORE(*rb
->current_tick
, last_render
+ HZ
/2))
1781 /* Render drop was set previously but nothing was dropped in the
1782 decoder or it's been to long since drawing the last frame. */
1785 eta_early
= INT32_MIN
;
1789 /* At this point a frame _will_ be drawn - a skip may happen on
1793 if (offset
> CLOCK_RATE
*110/1000)
1795 /* Decide which skip level is needed in order to catch up */
1797 /* TODO: Calculate this rather than if...else - this is rather
1798 exponential though */
1799 if (offset
> CLOCK_RATE
*367/1000)
1800 skip_level
= 5; /* Decoder skip: I/D */
1801 if (offset
> CLOCK_RATE
*233/1000)
1802 skip_level
= 4; /* Decoder skip: P */
1803 else if (offset
> CLOCK_RATE
*167/1000)
1804 skip_level
= 3; /* Render skip */
1805 else if (offset
> CLOCK_RATE
*133/1000)
1806 skip_level
= 2; /* Decoder skip: B */
1808 skip_level
= 1; /* Decoder skip: B */
1812 /* Wait until audio catches up */
1813 if (video_thumb_print
)
1814 video_str
.status
= STREAM_STOPPED
;
1816 while (eta_video
> eta_audio
)
1818 rb
->priority_yield();
1820 /* Make sure not to get stuck waiting here forever */
1821 if (str_have_msg(&video_str
))
1823 str_look_msg(&video_str
, &ev
);
1825 /* If not to play, process up top */
1826 if (ev
.id
!= STREAM_PLAY
)
1827 goto rendering_finished
;
1829 /* Told to play but already playing */
1830 str_get_msg(&video_str
, &ev
);
1831 str_reply_msg(&video_str
, 1);
1834 eta_audio
= get_stream_time();
1838 /* Record last frame time */
1839 last_render
= *rb
->current_tick
;
1841 if (video_thumb_print
)
1842 vo_draw_frame_thumb(info
->display_fbuf
->buf
);
1844 vo_draw_frame(info
->display_fbuf
->buf
);
1849 if (!settings
.showfps
)
1852 /* Calculate and display fps */
1853 if (TIME_AFTER(*rb
->current_tick
, last_showfps
+ HZ
))
1855 uint32_t clock_ticks
= get_playback_time() - count_start
;
1858 if (clock_ticks
!= 0)
1859 fps
= num_drawn
*CLOCK_RATE
*10ll / clock_ticks
;
1861 rb
->snprintf(str
, sizeof(str
), "%d.%d %d %d ",
1862 fps
/ 10, fps
% 10, num_skipped
,
1863 info
->display_picture
->temporal_reference
);
1864 rb
->lcd_putsxy(0, 0, str
);
1865 rb
->lcd_update_rect(0, 0, LCD_WIDTH
, 8);
1867 last_showfps
= *rb
->current_tick
;
1881 /* if video ends before time sync'd,
1882 besure the audio thread is closed */
1883 if (video_sync_start
== 0)
1885 audio_str
.status
= STREAM_STOPPED
;
1886 audio_sync_start
= 1;
1893 mpeg2_close (mpeg2dec
);
1895 /* Commit suicide */
1896 video_str
.status
= STREAM_TERMINATED
;
1899 void initialize_stream( Stream
*str
, uint8_t *buffer_start
, size_t disk_buf_len
, int id
)
1901 str
->curr_packet_end
= str
->curr_packet
= NULL
;
1902 str
->prev_packet_length
= 0;
1903 str
->prev_packet
= str
->curr_packet_end
= buffer_start
;
1904 str
->buffer_remaining
= disk_buf_len
;
1908 void display_thumb(int in_file
)
1910 size_t disk_buf_len
;
1912 video_thumb_print
= 1;
1913 audio_sync_start
= 1;
1914 video_sync_start
= 1;
1916 disk_buf_len
= rb
->read (in_file
, disk_buf_start
, disk_buf_size
- MPEG_GUARDBUF_SIZE
);
1917 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
1919 initialize_stream(&video_str
,disk_buf_start
,disk_buf_len
,0xe0);
1921 video_str
.status
= STREAM_PLAYING
;
1923 if ((video_str
.thread
= rb
->create_thread(video_thread
,
1924 (uint8_t*)video_stack
,VIDEO_STACKSIZE
,"mpgvideo"
1925 IF_PRIO(,PRIORITY_PLAYBACK
)
1926 IF_COP(, COP
, true))) == NULL
)
1928 rb
->splash(HZ
, "Cannot create video thread!");
1932 while (video_str
.status
!= STREAM_TERMINATED
)
1936 if ( video_str
.curr_packet_end
== video_str
.curr_packet
)
1937 rb
->splash(0, "frame not available");
1940 int find_length( int in_file
)
1943 size_t read_length
= 60*1024;
1944 size_t disk_buf_len
;
1948 /* temporary read buffer size cannot exceed buffer size */
1949 if ( read_length
> disk_buf_size
)
1950 read_length
= disk_buf_size
;
1952 /* read tail of file */
1953 rb
->lseek( in_file
, -1*read_length
, SEEK_END
);
1954 disk_buf_len
= rb
->read( in_file
, disk_buf_start
, read_length
);
1955 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
1957 /* sync reader to this segment of the stream */
1959 if (sync_data_stream(&p
))
1961 DEBUGF("Could not sync stream\n");
1962 return PLUGIN_ERROR
;
1965 /* find last PTS in audio stream; will movie always have audio? if
1966 the play time can not be determined, set play_time to 0 */
1967 audio_sync_start
= 0;
1968 audio_sync_time
= 0;
1969 video_sync_start
= 0;
1972 initialize_stream(&tmp
,p
,disk_buf_len
-(disk_buf_start
-p
),0xc0);
1976 get_next_data(&tmp
, 2);
1977 if (tmp
.tagged
== 1)
1978 /* 10 sec less to insure the video frame exist */
1979 play_time
= (int)((tmp
.curr_pts
/45000-10)/30);
1981 while (tmp
.curr_packet_end
!= NULL
);
1986 ssize_t
seek_PTS( int in_file
, int start_time
, int accept_button
)
1988 static ssize_t last_seek_pos
= 0;
1989 static int last_start_time
= 0;
1991 size_t disk_buf_len
;
1993 size_t read_length
= 60*1024;
1995 /* temporary read buffer size cannot exceed buffer size */
1996 if ( read_length
> disk_buf_size
)
1997 read_length
= disk_buf_size
;
1999 if ( start_time
== last_start_time
)
2001 seek_pos
= last_seek_pos
;
2002 rb
->lseek(in_file
,seek_pos
,SEEK_SET
);
2004 else if ( start_time
!= 0 )
2006 seek_pos
= rb
->filesize(in_file
)*start_time
/play_time
;
2007 int seek_pos_sec_inc
= rb
->filesize(in_file
)/play_time
/30;
2011 if ((size_t)seek_pos
> rb
->filesize(in_file
) - read_length
)
2012 seek_pos
= rb
->filesize(in_file
) - read_length
;
2013 rb
->lseek( in_file
, seek_pos
, SEEK_SET
);
2014 disk_buf_len
= rb
->read( in_file
, disk_buf_start
, read_length
);
2015 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
2017 /* sync reader to this segment of the stream */
2019 if (sync_data_stream(&p
))
2021 DEBUGF("Could not sync stream\n");
2022 return PLUGIN_ERROR
;
2025 /* find PTS >= start_time */
2026 audio_sync_start
= 0;
2027 audio_sync_time
= 0;
2028 video_sync_start
= 0;
2031 initialize_stream(&tmp
,p
,disk_buf_len
-(disk_buf_start
-p
),0xc0);
2032 int cont_seek_loop
= 1;
2033 int coarse_seek
= 1;
2036 if ( accept_button
)
2039 if (rb
->button_queue_count())
2043 while ( get_next_data(&tmp
, 1) == 1 )
2045 if ( tmp
.curr_packet_end
== disk_buf_start
)
2046 seek_pos
+= disk_buf_tail
- disk_buf_start
;
2048 seek_pos
+= tmp
.curr_packet_end
- disk_buf_start
;
2049 if ((size_t)seek_pos
> rb
->filesize(in_file
) - read_length
)
2050 seek_pos
= rb
->filesize(in_file
) - read_length
;
2051 rb
->lseek( in_file
, seek_pos
, SEEK_SET
);
2052 disk_buf_len
= rb
->read ( in_file
, disk_buf_start
, read_length
);
2053 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
2055 /* sync reader to this segment of the stream */
2057 initialize_stream(&tmp
,p
,disk_buf_len
,0xc0);
2060 /* are we after start_time in the stream? */
2061 if ( coarse_seek
&& (int)(tmp
.curr_pts
/45000) >= start_time
*30 )
2063 int time_to_backup
= (int)(tmp
.curr_pts
/45000) - start_time
*30;
2064 if (time_to_backup
== 0)
2066 seek_pos
-= seek_pos_sec_inc
* time_to_backup
;
2067 seek_pos_sec_inc
-= seek_pos_sec_inc
/20; /* for stability */
2070 if ((size_t)seek_pos
> rb
->filesize(in_file
) - read_length
)
2071 seek_pos
= rb
->filesize(in_file
) - read_length
;
2072 rb
->lseek( in_file
, seek_pos
, SEEK_SET
);
2073 disk_buf_len
= rb
->read( in_file
, disk_buf_start
, read_length
);
2074 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
2076 /* sync reader to this segment of the stream */
2078 if (sync_data_stream(&p
))
2080 DEBUGF("Could not sync stream\n");
2081 return PLUGIN_ERROR
;
2083 initialize_stream(&tmp
,p
,disk_buf_len
-(disk_buf_start
-p
),0xc0);
2087 /* are we well before start_time in the stream? */
2088 if ( coarse_seek
&& start_time
*30 - (int)(tmp
.curr_pts
/45000) > 2 )
2090 int time_to_advance
= start_time
*30 - (int)(tmp
.curr_pts
/45000) - 2;
2091 if (time_to_advance
<= 0)
2092 time_to_advance
= 1;
2093 seek_pos
+= seek_pos_sec_inc
* time_to_advance
;
2096 if ((size_t)seek_pos
> rb
->filesize(in_file
) - read_length
)
2097 seek_pos
= rb
->filesize(in_file
) - read_length
;
2098 rb
->lseek( in_file
, seek_pos
, SEEK_SET
);
2099 disk_buf_len
= rb
->read ( in_file
, disk_buf_start
, read_length
);
2100 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
2102 /* sync reader to this segment of the stream */
2104 if (sync_data_stream(&p
))
2106 DEBUGF("Could not sync stream\n");
2107 return PLUGIN_ERROR
;
2109 initialize_stream(&tmp
,p
,disk_buf_len
-(disk_buf_start
-p
),0xc0);
2115 /* are we at start_time in the stream? */
2116 if ( (int)(tmp
.curr_pts
/45000) >= start_time
*30 )
2120 while ( cont_seek_loop
);
2123 DEBUGF("start diff: %u %u\n",(unsigned int)(tmp
.curr_pts
/45000),start_time
*30);
2124 seek_pos
+=tmp
.curr_packet_end
-disk_buf_start
;
2126 last_seek_pos
= seek_pos
;
2127 last_start_time
= start_time
;
2129 rb
->lseek(in_file
,seek_pos
,SEEK_SET
);
2135 rb
->lseek(in_file
,0,SEEK_SET
);
2136 last_seek_pos
= seek_pos
;
2137 last_start_time
= start_time
;
2142 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
2144 int status
= PLUGIN_ERROR
; /* assume failure */
2149 size_t disk_buf_len
;
2151 #ifndef HAVE_LCD_COLOR
2156 audio_sync_start
= 0;
2157 audio_sync_time
= 0;
2158 video_sync_start
= 0;
2160 if (parameter
== NULL
)
2162 api
->splash(HZ
*2, "No File");
2163 return PLUGIN_ERROR
;
2166 /* Initialize IRAM - stops audio and voice as well */
2167 PLUGIN_IRAM_INIT(api
)
2170 rb
->splash(0, "loading ...");
2172 /* sets audiosize and returns buffer pointer */
2173 audiobuf
= rb
->plugin_get_audio_buffer(&audiosize
);
2175 #if INPUT_SRC_CAPS != 0
2176 /* Select playback */
2177 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
2178 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
2181 rb
->pcm_set_frequency(SAMPR_44
);
2183 #ifndef HAVE_LCD_COLOR
2184 /* initialize the grayscale buffer: 32 bitplanes for 33 shades of gray. */
2185 grayscales
= gray_init(rb
, audiobuf
, audiosize
, false, LCD_WIDTH
, LCD_HEIGHT
,
2186 32, 2<<8, &graysize
) + 1;
2187 audiobuf
+= graysize
;
2188 audiosize
-= graysize
;
2189 if (grayscales
< 33 || audiosize
<= 0)
2191 rb
->splash(HZ
, "gray buf error");
2192 return PLUGIN_ERROR
;
2196 /* Initialise our malloc buffer */
2197 audiosize
= mpeg_alloc_init(audiobuf
,audiosize
, LIBMPEG2BUFFER_SIZE
);
2199 return PLUGIN_ERROR
;
2201 /* Set disk pointers to NULL */
2202 disk_buf_end
= disk_buf_start
= NULL
;
2204 /* Grab most of the buffer for the compressed video - leave some for
2205 PCM audio data and some for libmpeg2 malloc use. */
2206 disk_buf_size
= audiosize
- (PCMBUFFER_SIZE
+PCMBUFFER_GUARD_SIZE
+
2209 DEBUGF("audiosize=%ld, disk_buf_size=%ld\n",audiosize
,disk_buf_size
);
2210 disk_buf_start
= mpeg_malloc(disk_buf_size
,-1);
2212 if (disk_buf_start
== NULL
)
2213 return PLUGIN_ERROR
;
2216 return PLUGIN_ERROR
;
2219 return PLUGIN_ERROR
;
2221 /* The remaining buffer is for use by libmpeg2 */
2223 /* Open the video file */
2224 in_file
= rb
->open((char*)parameter
,O_RDONLY
);
2227 DEBUGF("Could not open %s\n",(char*)parameter
);
2228 return PLUGIN_ERROR
;
2230 filename
= (char*)parameter
;
2232 #ifdef HAVE_LCD_COLOR
2233 rb
->lcd_set_backdrop(NULL
);
2234 rb
->lcd_set_foreground(LCD_WHITE
);
2235 rb
->lcd_set_background(LCD_BLACK
);
2237 rb
->lcd_clear_display();
2240 /* Turn off backlight timeout */
2241 backlight_force_on(rb
); /* backlight control in lib/helper.c */
2242 rb
->talk_disable_menus();
2244 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2245 rb
->cpu_boost(true);
2248 /* From this point on we've altered settings, colors, cpu_boost, etc. and
2249 cannot just return PLUGIN_ERROR - instead drop though to cleanup code
2252 init_settings((char*)parameter
);
2254 /* Initialise libmad */
2255 rb
->memset(mad_frame_overlap
, 0, sizeof(mad_frame_overlap
));
2256 init_mad(mad_frame_overlap
);
2258 disk_buf_end
= disk_buf_start
+ disk_buf_size
-MPEG_GUARDBUF_SIZE
;
2260 /* initalize play_time with the length (in half minutes) of the movie
2261 zero if the time could not be determined */
2262 find_length( in_file
);
2265 start_time
= mpeg_start_menu(play_time
, in_file
);
2266 if ( start_time
== -1 )
2268 else if ( start_time
< 0 )
2270 else if ( start_time
> play_time
)
2271 start_time
= play_time
;
2273 rb
->splash(0, "loading ...");
2275 /* seek start time */
2276 seek_pos
= seek_PTS( in_file
, start_time
, 0 );
2278 rb
->lseek(in_file
,seek_pos
,SEEK_SET
);
2279 video_thumb_print
= 0;
2280 audio_sync_start
= 0;
2281 audio_sync_time
= 0;
2282 video_sync_start
= 0;
2284 /* Read some stream data */
2285 disk_buf_len
= rb
->read (in_file
, disk_buf_start
, disk_buf_size
- MPEG_GUARDBUF_SIZE
);
2287 disk_buf_tail
= disk_buf_start
+ disk_buf_len
;
2288 file_remaining
= rb
->filesize(in_file
);
2289 file_remaining
-= disk_buf_len
+ seek_pos
;
2291 initialize_stream( &video_str
, disk_buf_start
, disk_buf_len
, 0xe0 );
2292 initialize_stream( &audio_str
, disk_buf_start
, disk_buf_len
, 0xc0 );
2294 rb
->spinlock_init(&audio_str
.msg_lock
);
2295 rb
->spinlock_init(&video_str
.msg_lock
);
2297 audio_str
.status
= STREAM_BUFFERING
;
2298 video_str
.status
= STREAM_PLAYING
;
2300 #ifndef HAVE_LCD_COLOR
2310 /* We put the video thread on the second processor for multi-core targets. */
2311 if ((video_str
.thread
= rb
->create_thread(video_thread
,
2312 (uint8_t*)video_stack
,VIDEO_STACKSIZE
,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK
)
2313 IF_COP(, COP
, true))) == NULL
)
2315 rb
->splash(HZ
, "Cannot create video thread!");
2317 else if ((audio_str
.thread
= rb
->create_thread(audio_thread
,
2318 (uint8_t*)audio_stack
,AUDIO_STACKSIZE
,"mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK
)
2319 IF_COP(, CPU
, false))) == NULL
)
2321 rb
->splash(HZ
, "Cannot create audio thread!");
2325 rb
->lcd_setfont(FONT_SYSFIXED
);
2327 /* Wait until both threads have finished their work */
2328 while ((audio_str
.status
>= 0) || (video_str
.status
>= 0))
2330 size_t audio_remaining
= audio_str
.buffer_remaining
;
2331 size_t video_remaining
= video_str
.buffer_remaining
;
2333 if (MIN(audio_remaining
,video_remaining
) < MPEG_LOW_WATERMARK
)
2336 size_t bytes_to_read
= disk_buf_size
- MPEG_GUARDBUF_SIZE
-
2337 MAX(audio_remaining
,video_remaining
);
2339 bytes_to_read
= MIN(bytes_to_read
,(size_t)(disk_buf_end
-disk_buf_tail
));
2341 while (( bytes_to_read
> 0) && (file_remaining
> 0) &&
2342 ((audio_str
.status
!= STREAM_DONE
) || (video_str
.status
!= STREAM_DONE
)))
2346 if ( video_sync_start
!= 0 )
2347 n
= rb
->read(in_file
, disk_buf_tail
, MIN(32*1024,bytes_to_read
));
2350 n
= rb
->read(in_file
, disk_buf_tail
,bytes_to_read
);
2352 rb
->splash(30,"buffer fill error");
2357 file_remaining
-= n
;
2360 audio_str
.buffer_remaining
+= n
;
2361 video_str
.buffer_remaining
+= n
;
2369 if (disk_buf_tail
== disk_buf_end
)
2370 disk_buf_tail
= disk_buf_start
;
2376 rb
->lcd_setfont(FONT_UI
);
2380 /* Stop the threads and wait for them to terminate */
2381 if (video_str
.thread
!= NULL
)
2382 str_send_msg(&video_str
, STREAM_QUIT
, 0);
2384 if (audio_str
.thread
!= NULL
)
2385 str_send_msg(&audio_str
, STREAM_QUIT
, 0);
2390 invalidate_icache();
2395 #ifndef HAVE_LCD_COLOR
2399 rb
->lcd_clear_display();
2402 mpeg2_close (mpeg2dec
);
2404 rb
->close (in_file
);
2406 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
2407 rb
->cpu_boost(false);
2410 save_settings(); /* Save settings (if they have changed) */
2412 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
2414 /* Turn on backlight timeout (revert to settings) */
2415 backlight_use_settings(rb
); /* backlight control in lib/helper.c */
2416 rb
->talk_enable_menus();