diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index e8d646b258..990bc9fbcd 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -14263,128 +14263,9 @@
*: "View Played Games"
-
- id: LANG_MENU_AUDIO_OPTIONS
- desc: in mpegplayer menus
- user: core
-
-
- *: "Audio Options"
- lowmem: none
-
-
- *: "Audio Options"
- lowmem: none
-
-
-
- id: LANG_MENU_RESUME_OPTIONS
- desc: in mpegplayer menus
- user: core
-
-
- *: "Resume Options"
- lowmem: none
-
-
- *: "Resume Options"
- lowmem: none
-
-
-
- id: LANG_MENU_PLAY_MODE
- desc: in mpegplayer menus
- user: core
-
-
- *: "Play Mode"
- lowmem: none
-
-
- *: "Play Mode"
- lowmem: none
-
-
-
- id: LANG_SINGLE
- desc: in mpegplayer menus
- user: core
-
-
- *: "Single"
- lowmem: none
-
-
- *: "Single"
- lowmem: none
-
-
-
- id: LANG_USE_SOUND_SETTING
- desc: in mpegplayer menus
- user: core
-
-
- *: "Use sound setting"
- lowmem: none
-
-
- *: "Use sound setting"
- lowmem: none
-
-
-
- id: LANG_RESTART_PLAYBACK
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Play from beginning"
- lowmem: none
-
-
- *: "Play from beginning"
- lowmem: none
-
-
-
- id: LANG_SET_RESUME_TIME
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Set resume time (min)"
- lowmem: none
-
-
- *: "Set resume time"
- lowmem: none
-
-
id: LANG_DISPLAY_FPS
- desc: in the mpegplayer and pictureflow settings menus
+ desc: in the pictureflow settings menus
user: core
-
- id: LANG_LIMIT_FPS
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Limit FPS"
- lowmem: none
-
-
- *: "Limit FPS"
- lowmem: none
-
-
-
- id: LANG_SKIP_FRAMES
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Skip frames"
- lowmem: none
-
-
- *: "Skip frames"
- lowmem: none
-
-
-
- id: LANG_BACKLIGHT_BRIGHTNESS
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Backlight brightness"
- lowmem: none
-
-
- *: "Backlight brightness"
- lowmem: none
-
-
-
- id: LANG_USE_COMMON_SETTING
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Use common setting"
- lowmem: none
-
-
- *: "Use common setting"
- lowmem: none
-
-
-
- id: LANG_TONE_CONTROLS
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Tone controls"
- lowmem: none
-
-
- *: "Tone controls"
- lowmem: none
-
-
-
- id: LANG_FORCE_START_MENU
- desc: in mpegplayer menus
- user: core
-
-
- *: "Start menu"
- lowmem: none
-
-
- *: "Start menu"
- lowmem: none
-
-
-
- id: LANG_CONDITIONAL_START_MENU
- desc: in mpegplayer menus
- user: core
-
-
- *: "Start menu if not completed"
- lowmem: none
-
-
- *: "Start menu if not completed"
- lowmem: none
-
-
-
- id: LANG_AUTO_RESUME
- desc: in mpegplayer menus
- user: core
-
-
- *: "Resume automatically"
- lowmem: none
-
-
- *: "Resume automatically"
- lowmem: none
-
-
-
- id: LANG_CLEAR_ALL_RESUMES
- desc: in the mpegplayer settings menu
- user: core
-
-
- *: "Clear all resumes"
- lowmem: none
-
-
- *: "Clear all resumes"
- lowmem: none
-
-
-
- id: LANG_UNAVAILABLE
- desc: in mpegplayer settings
- user: core
-
-
- *: "Unavailable"
- lowmem: none
-
-
- *: "Unavailable"
- lowmem: none
-
-
id: LANG_TOGGLE_ITEM
desc: in main_menu_config
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES
index f2ab4843c2..13db81f004 100644
--- a/apps/plugins/CATEGORIES
+++ b/apps/plugins/CATEGORIES
@@ -68,7 +68,6 @@ mikmod,viewers
minesweeper,games
mosaique,demos
mp3_encoder,apps
-mpegplayer,viewers
multiboot_select,apps
nim,games
open_plugins,viewers
diff --git a/apps/plugins/SUBDIRS b/apps/plugins/SUBDIRS
index 4cb57edb1b..23cd029ccc 100644
--- a/apps/plugins/SUBDIRS
+++ b/apps/plugins/SUBDIRS
@@ -78,10 +78,6 @@ mikmod
pdbox
#endif
-#if !defined(RB_PROFILE) && MEMORYSIZE > 2 /* mpegplayer allocates at least 2MB of RAM */
-mpegplayer
-#endif
-
/* Lua needs at least 160 KB to work in */
#if PLUGIN_BUFFER_SIZE >= 0x80000
lua
diff --git a/apps/plugins/bitmaps/mono/SOURCES b/apps/plugins/bitmaps/mono/SOURCES
index eb00bd9e8a..df8521dd0a 100644
--- a/apps/plugins/bitmaps/mono/SOURCES
+++ b/apps/plugins/bitmaps/mono/SOURCES
@@ -49,11 +49,6 @@ invadrox_fire.6x6x1.bmp
#endif
#endif
-/* MPEGplayer */
-mpegplayer_status_icons_8x8x1.bmp
-mpegplayer_status_icons_12x12x1.bmp
-mpegplayer_status_icons_16x16x1.bmp
-
#if LCD_WIDTH == 160 && LCD_HEIGHT == 128 && LCD_DEPTH < 16
superdom_boarditems.160x128x1.bmp
#endif
diff --git a/apps/plugins/bitmaps/mono/mpegplayer_status_icons_12x12x1.bmp b/apps/plugins/bitmaps/mono/mpegplayer_status_icons_12x12x1.bmp
deleted file mode 100644
index 61f6a52fbc..0000000000
Binary files a/apps/plugins/bitmaps/mono/mpegplayer_status_icons_12x12x1.bmp and /dev/null differ
diff --git a/apps/plugins/bitmaps/mono/mpegplayer_status_icons_16x16x1.bmp b/apps/plugins/bitmaps/mono/mpegplayer_status_icons_16x16x1.bmp
deleted file mode 100644
index 944bd5132e..0000000000
Binary files a/apps/plugins/bitmaps/mono/mpegplayer_status_icons_16x16x1.bmp and /dev/null differ
diff --git a/apps/plugins/bitmaps/mono/mpegplayer_status_icons_8x8x1.bmp b/apps/plugins/bitmaps/mono/mpegplayer_status_icons_8x8x1.bmp
deleted file mode 100644
index d4b71fe1e0..0000000000
Binary files a/apps/plugins/bitmaps/mono/mpegplayer_status_icons_8x8x1.bmp and /dev/null differ
diff --git a/apps/plugins/mpegplayer/SOURCES b/apps/plugins/mpegplayer/SOURCES
deleted file mode 100644
index 3fc079dfbd..0000000000
--- a/apps/plugins/mpegplayer/SOURCES
+++ /dev/null
@@ -1,35 +0,0 @@
-libmpeg2/decode.c
-libmpeg2/header.c
-libmpeg2/idct.c
-libmpeg2/motion_comp.c
-libmpeg2/slice.c
-
-#ifdef CPU_COLDFIRE
-libmpeg2/idct_coldfire.S
-libmpeg2/motion_comp_coldfire_c.c
-libmpeg2/motion_comp_coldfire_s.S
-#elif defined CPU_ARM
-#if ARM_ARCH >= 6
-libmpeg2/idct_armv6.S
-#else
-libmpeg2/idct_arm.S
-#endif
-libmpeg2/motion_comp_arm_c.c
-libmpeg2/motion_comp_arm_s.S
-#else /* other CPU or SIM */
-libmpeg2/motion_comp_c.c
-#endif /* CPU_* */
-
-
-
-alloc.c
-video_out_rockbox.c
-video_thread.c
-pcm_output.c
-audio_thread.c
-disk_buf.c
-mpeg_settings.c
-stream_mgr.c
-mpegplayer.c
-mpeg_parser.c
-mpeg_misc.c
diff --git a/apps/plugins/mpegplayer/alloc.c b/apps/plugins/mpegplayer/alloc.c
deleted file mode 100644
index cbf930a7eb..0000000000
--- a/apps/plugins/mpegplayer/alloc.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * alloc.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.13
- */
-
-#include "plugin.h"
-#include "mpegplayer.h"
-#include
-
-/* Main allocator */
-static off_t mem_ptr;
-static size_t bufsize;
-static unsigned char* mallocbuf;
-
-/* libmpeg2 allocator */
-static off_t mpeg2_mem_ptr SHAREDBSS_ATTR;
-static size_t mpeg2_bufsize SHAREDBSS_ATTR;
-static unsigned char *mpeg2_mallocbuf SHAREDBSS_ATTR;
-static unsigned char *mpeg2_bufallocbuf SHAREDBSS_ATTR;
-
-#if defined(DEBUG) || defined(SIMULATOR)
-const char * mpeg_get_reason_str(int reason)
-{
- const char *str;
-
- switch (reason)
- {
- case MPEG2_ALLOC_MPEG2DEC:
- str = "MPEG2_ALLOC_MPEG2DEC";
- break;
- case MPEG2_ALLOC_CHUNK:
- str = "MPEG2_ALLOC_CHUNK";
- break;
- case MPEG2_ALLOC_YUV:
- str = "MPEG2_ALLOC_YUV";
- break;
- case MPEG2_ALLOC_CONVERT_ID:
- str = "MPEG2_ALLOC_CONVERT_ID";
- break;
- case MPEG2_ALLOC_CONVERTED:
- str = "MPEG2_ALLOC_CONVERTED";
- break;
- case MPEG_ALLOC_MPEG2_BUFFER:
- str = "MPEG_ALLOC_MPEG2_BUFFER";
- break;
- case MPEG_ALLOC_AUDIOBUF:
- str = "MPEG_ALLOC_AUDIOBUF";
- break;
- case MPEG_ALLOC_PCMOUT:
- str = "MPEG_ALLOC_PCMOUT";
- break;
- case MPEG_ALLOC_DISKBUF:
- str = "MPEG_ALLOC_DISKBUF";
- break;
- case MPEG_ALLOC_CODEC_MALLOC:
- str = "MPEG_ALLOC_CODEC_MALLOC";
- break;
- case MPEG_ALLOC_CODEC_CALLOC:
- str = "MPEG_ALLOC_CODEC_CALLOC";
- break;
- default:
- str = "Unknown";
- }
-
- return str;
-}
-#endif
-
-static void * mpeg_malloc_internal (unsigned char *mallocbuf,
- off_t *mem_ptr,
- size_t bufsize,
- unsigned size,
- int reason)
-{
- void *x;
-
- DEBUGF("mpeg_alloc_internal: bs:%lu s:%u reason:%s (%d)\n",
- (unsigned long)bufsize, size, mpeg_get_reason_str(reason), reason);
-
- if ((size_t) (*mem_ptr + size) > bufsize)
- {
- DEBUGF("OUT OF MEMORY\n");
- return NULL;
- }
-
- x = &mallocbuf[*mem_ptr];
- *mem_ptr += (size + 3) & ~3; /* Keep memory 32-bit aligned */
-
- return x;
- (void)reason;
-}
-
-void *mpeg_malloc(size_t size, mpeg2_alloc_t reason)
-{
- return mpeg_malloc_internal(mallocbuf, &mem_ptr, bufsize, size,
- reason);
-}
-
-void *mpeg_malloc_all(size_t *size_out, mpeg2_alloc_t reason)
-{
- /* Can steal all but MIN_MEMMARGIN */
- if (bufsize - mem_ptr < MIN_MEMMARGIN)
- return NULL;
-
- *size_out = bufsize - mem_ptr - MIN_MEMMARGIN;
- return mpeg_malloc(*size_out, reason);
-}
-
-bool mpeg_alloc_init(unsigned char *buf, size_t mallocsize)
-{
- mem_ptr = 0;
- /* Cache-align buffer or 4-byte align */
- mallocbuf = buf;
- bufsize = mallocsize;
- ALIGN_BUFFER(mallocbuf, bufsize, CACHEALIGN_UP(4));
-
- /* Separate allocator for video */
- mpeg2_mem_ptr = 0;
- mpeg2_mallocbuf = mallocbuf;
- mpeg2_bufallocbuf = mallocbuf;
- mpeg2_bufsize = CACHEALIGN_UP(LIBMPEG2_ALLOC_SIZE);
-
- if (mpeg_malloc_internal(mallocbuf, &mem_ptr,
- bufsize, mpeg2_bufsize,
- MPEG_ALLOC_MPEG2_BUFFER) == NULL)
- {
- return false;
- }
-
- IF_COP(rb->commit_discard_dcache());
- return true;
-}
-
-/* allocate non-dedicated buffer space which mpeg2_mem_reset will free */
-void * mpeg2_malloc(unsigned size, mpeg2_alloc_t reason)
-{
- void *ptr = mpeg_malloc_internal(mpeg2_mallocbuf, &mpeg2_mem_ptr,
- mpeg2_bufsize, size, reason);
- /* libmpeg2 expects zero-initialized allocations */
- if (ptr)
- rb->memset(ptr, 0, size);
-
- return ptr;
-}
-
-/* allocate dedicated buffer - memory behind buffer pointer becomes dedicated
- so order is important */
-void * mpeg2_bufalloc(unsigned size, mpeg2_alloc_t reason)
-{
- void *buf = mpeg2_malloc(size, reason);
-
- if (buf == NULL)
- return NULL;
-
- mpeg2_bufallocbuf = &mpeg2_mallocbuf[mpeg2_mem_ptr];
- return buf;
-}
-
-/* return unused buffer portion and size */
-void * mpeg2_get_buf(size_t *size)
-{
- if ((size_t)mpeg2_mem_ptr + 32 >= mpeg2_bufsize)
- return NULL;
-
- *size = mpeg2_bufsize - mpeg2_mem_ptr;
- return &mpeg2_mallocbuf[mpeg2_mem_ptr];
-}
-
-/* de-allocate all non-dedicated buffer space */
-void mpeg2_mem_reset(void)
-{
- DEBUGF("mpeg2_mem_reset\n");
- mpeg2_mem_ptr = mpeg2_bufallocbuf - mpeg2_mallocbuf;
-}
-
-/* The following are expected by libmad */
-void * codec_malloc(size_t size)
-{
- void* ptr;
-
- ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr,
- bufsize, size, MPEG_ALLOC_CODEC_MALLOC);
-
- if (ptr)
- rb->memset(ptr,0,size);
-
- return ptr;
-}
-
-void * codec_calloc(size_t nmemb, size_t size)
-{
- void* ptr;
-
- ptr = mpeg_malloc_internal(mallocbuf, &mem_ptr,
- bufsize, nmemb*size,
- MPEG_ALLOC_CODEC_CALLOC);
-
- if (ptr)
- rb->memset(ptr,0,size);
-
- return ptr;
-}
-
-void codec_free(void* ptr)
-{
- DEBUGF("codec_free - %p\n", ptr);
-#if 0
- mem_ptr = (void *)ptr - (void *)mallocbuf;
-#endif
- (void)ptr;
-}
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
deleted file mode 100644
index 764ad111f2..0000000000
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * mpegplayer audio thread implementation
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-#include "codecs/libmad/bit.h"
-#include "codecs/libmad/mad.h"
-
-/** Audio stream and thread **/
-struct pts_queue_slot;
-struct audio_thread_data
-{
- struct queue_event ev; /* Our event queue to receive commands */
- int state; /* Thread state */
- int status; /* Media status (STREAM_PLAYING, etc.) */
- int mad_errors; /* A count of the errors in each frame */
- unsigned samplerate; /* Current stream sample rate */
- int nchannels; /* Number of audio channels */
- struct dsp_config *dsp; /* The DSP we're using */
- struct dsp_buffer src; /* Current audio data for DSP processing */
-};
-
-/* The audio thread is stolen from the core codec thread */
-static struct event_queue audio_str_queue SHAREDBSS_ATTR;
-static struct queue_sender_list audio_str_queue_send SHAREDBSS_ATTR;
-struct stream audio_str IBSS_ATTR;
-
-/* libmad related definitions */
-static struct mad_stream stream IBSS_ATTR;
-static struct mad_frame frame IBSS_ATTR;
-static struct mad_synth synth IBSS_ATTR;
-
-/*sbsample buffer for mad_frame*/
-mad_fixed_t sbsample[2][36][32];
-
-/* 2567 bytes */
-static unsigned char mad_main_data[MAD_BUFFER_MDLEN];
-
-/* There isn't enough room for this in IRAM on PortalPlayer, but there
- is for Coldfire. */
-
-/* 4608 bytes */
-#if defined(CPU_COLDFIRE) || defined(CPU_S5L870X)
-static mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR;
-#else
-static mad_fixed_t mad_frame_overlap[2][32][18];
-#endif
-
-/** A queue for saving needed information about MPEG audio packets **/
-#define AUDIODESC_QUEUE_LEN (1 << 5) /* 32 should be way more than sufficient -
- if not, the case is handled */
-#define AUDIODESC_QUEUE_MASK (AUDIODESC_QUEUE_LEN-1)
-struct audio_frame_desc
-{
- uint32_t time; /* Time stamp for packet in audio ticks */
- ssize_t size; /* Number of unprocessed bytes left in packet */
-};
-
- /* This starts out wr == rd but will never be emptied to zero during
- streaming again in order to support initializing the first packet's
- timestamp without a special case */
-struct
-{
- /* Compressed audio data */
- uint8_t *start; /* Start of encoded audio buffer */
- uint8_t *ptr; /* Pointer to next encoded audio data */
- ssize_t used; /* Number of bytes in MPEG audio buffer */
- /* Compressed audio data descriptors */
- unsigned read, write;
- struct audio_frame_desc *curr; /* Current slot */
- struct audio_frame_desc descs[AUDIODESC_QUEUE_LEN];
-} audio_queue;
-
-static inline int audiodesc_queue_count(void)
-{
- return audio_queue.write - audio_queue.read;
-}
-
-static inline bool audiodesc_queue_full(void)
-{
- return audio_queue.used >= MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD ||
- audiodesc_queue_count() >= AUDIODESC_QUEUE_LEN;
-}
-
-/* Increments the queue tail postion - should be used to preincrement */
-static inline void audiodesc_queue_add_tail(void)
-{
- if (audiodesc_queue_full())
- {
- DEBUGF("audiodesc_queue_add_tail: audiodesc queue full!\n");
- return;
- }
-
- audio_queue.write++;
-}
-
-/* Increments the queue head position - leaves one slot as current */
-static inline bool audiodesc_queue_remove_head(void)
-{
- if (audio_queue.write == audio_queue.read)
- return false;
-
- audio_queue.read++;
- return true;
-}
-
-/* Returns the "tail" at the index just behind the write index */
-static inline struct audio_frame_desc * audiodesc_queue_tail(void)
-{
- return &audio_queue.descs[(audio_queue.write - 1) & AUDIODESC_QUEUE_MASK];
-}
-
-/* Returns a pointer to the current head */
-static inline struct audio_frame_desc * audiodesc_queue_head(void)
-{
- return &audio_queue.descs[audio_queue.read & AUDIODESC_QUEUE_MASK];
-}
-
-/* Resets the pts queue - call when starting and seeking */
-static void audio_queue_reset(void)
-{
- audio_queue.ptr = audio_queue.start;
- audio_queue.used = 0;
- audio_queue.read = 0;
- audio_queue.write = 0;
- rb->memset(audio_queue.descs, 0, sizeof (audio_queue.descs));
- audio_queue.curr = audiodesc_queue_head();
-}
-
-static void audio_queue_advance_pos(ssize_t len)
-{
- audio_queue.ptr += len;
- audio_queue.used -= len;
- audio_queue.curr->size -= len;
-}
-
-static int audio_buffer(struct stream *str, enum stream_parse_mode type)
-{
- int ret = STREAM_OK;
-
- /* Carry any overshoot to the next size since we're technically
- -size bytes into it already. If size is negative an audio
- frame was split across packets. Old has to be saved before
- moving the head. */
- if (audio_queue.curr->size <= 0 && audiodesc_queue_remove_head())
- {
- struct audio_frame_desc *old = audio_queue.curr;
- audio_queue.curr = audiodesc_queue_head();
- audio_queue.curr->size += old->size;
- old->size = 0;
- }
-
- /* Add packets to compressed audio buffer until it's full or the
- * timestamp queue is full - whichever happens first */
- while (!audiodesc_queue_full())
- {
- ret = parser_get_next_data(str, type);
- struct audio_frame_desc *curr;
- ssize_t len;
-
- if (ret != STREAM_OK)
- break;
-
- /* Get data from next audio packet */
- len = str->curr_packet_end - str->curr_packet;
-
- if (str->pkt_flags & PKT_HAS_TS)
- {
- audiodesc_queue_add_tail();
- curr = audiodesc_queue_tail();
- curr->time = TS_TO_TICKS(str->pts);
- /* pts->size should have been zeroed when slot was
- freed */
- }
- else
- {
- /* Add to the one just behind the tail - this may be
- * the head or the previouly added tail - whether or
- * not we'll ever reach this is quite in question
- * since audio always seems to have every packet
- * timestamped */
- curr = audiodesc_queue_tail();
- }
-
- curr->size += len;
-
- /* Slide any remainder over to beginning */
- if (audio_queue.ptr > audio_queue.start && audio_queue.used > 0)
- {
- rb->memmove(audio_queue.start, audio_queue.ptr,
- audio_queue.used);
- }
-
- /* Splice this packet onto any remainder */
- rb->memcpy(audio_queue.start + audio_queue.used,
- str->curr_packet, len);
-
- audio_queue.used += len;
- audio_queue.ptr = audio_queue.start;
-
- rb->yield();
- }
-
- return ret;
-}
-
-/* Initialise libmad */
-static void init_mad(void)
-{
- /* init the sbsample buffer */
- frame.sbsample_prev = &sbsample;
- frame.sbsample = &sbsample;
-
- /* We do this so libmad doesn't try to call codec_calloc(). This needs to
- * be called before mad_stream_init(), mad_frame_inti() and
- * mad_synth_init(). */
- frame.overlap = &mad_frame_overlap;
- stream.main_data = &mad_main_data;
-
- /* Call mad initialization. Those will zero the arrays frame.overlap,
- * frame.sbsample and frame.sbsample_prev. Therefore there is no need to
- * zero them here. */
- mad_stream_init(&stream);
- mad_frame_init(&frame);
- mad_synth_init(&synth);
-}
-
-/* Sync audio stream to a particular frame - see main decoder loop for
- * detailed remarks */
-static int audio_sync(struct audio_thread_data *td,
- struct str_sync_data *sd)
-{
- int retval = STREAM_MATCH;
- uint32_t sdtime = TS_TO_TICKS(clip_time(&audio_str, sd->time));
- uint32_t time;
- uint32_t duration = 0;
- struct stream *str;
- struct stream tmp_str;
- struct mad_header header;
- struct mad_stream stream;
-
- if (td->ev.id == STREAM_SYNC)
- {
- /* Actually syncing for playback - use real stream */
- time = 0;
- str = &audio_str;
- }
- else
- {
- /* Probing - use temp stream */
- time = INVALID_TIMESTAMP;
- str = &tmp_str;
- str->id = audio_str.id;
- }
-
- str->hdr.pos = sd->sk.pos;
- str->hdr.limit = sd->sk.pos + sd->sk.len;
-
- mad_stream_init(&stream);
- mad_header_init(&header);
-
- while (1)
- {
- if (audio_buffer(str, STREAM_PM_RANDOM_ACCESS) == STREAM_DATA_END)
- {
- DEBUGF("audio_sync:STR_DATA_END\n aqu:%ld swl:%ld swr:%ld\n",
- (long)audio_queue.used, str->hdr.win_left, str->hdr.win_right);
- if (audio_queue.used <= MAD_BUFFER_GUARD)
- goto sync_data_end;
- }
-
- stream.error = 0;
- mad_stream_buffer(&stream, audio_queue.ptr, audio_queue.used);
-
- if (stream.sync && mad_stream_sync(&stream) < 0)
- {
- DEBUGF(" audio: mad_stream_sync failed\n");
- audio_queue_advance_pos(MAX(audio_queue.curr->size - 1, 1));
- continue;
- }
-
- stream.sync = 0;
-
- if (mad_header_decode(&header, &stream) < 0)
- {
- DEBUGF(" audio: mad_header_decode failed:%s\n",
- mad_stream_errorstr(&stream));
- audio_queue_advance_pos(1);
- continue;
- }
-
- duration = 32*MAD_NSBSAMPLES(&header);
- time = audio_queue.curr->time;
-
- DEBUGF(" audio: ft:%u t:%u fe:%u nsamp:%u sampr:%u\n",
- (unsigned)TICKS_TO_TS(time), (unsigned)sd->time,
- (unsigned)TICKS_TO_TS(time + duration),
- (unsigned)duration, header.samplerate);
-
- audio_queue_advance_pos(stream.this_frame - audio_queue.ptr);
-
- if (time <= sdtime && sdtime < time + duration)
- {
- DEBUGF(" audio: ft<=t sdtime)
- {
- DEBUGF(" audio: ft>t\n");
- break;
- }
-
- audio_queue_advance_pos(stream.next_frame - audio_queue.ptr);
- audio_queue.curr->time += duration;
-
- rb->yield();
- }
-
-sync_data_end:
- if (td->ev.id == STREAM_FIND_END_TIME)
- {
- if (time != INVALID_TIMESTAMP)
- {
- time = TICKS_TO_TS(time);
- duration = TICKS_TO_TS(duration);
- sd->time = time + duration;
- retval = STREAM_PERFECT_MATCH;
- }
- else
- {
- retval = STREAM_NOT_FOUND;
- }
- }
-
- DEBUGF(" audio header: 0x%02X%02X%02X%02X\n",
- (unsigned)audio_queue.ptr[0], (unsigned)audio_queue.ptr[1],
- (unsigned)audio_queue.ptr[2], (unsigned)audio_queue.ptr[3]);
-
- return retval;
- (void)td;
-}
-
-static void audio_thread_msg(struct audio_thread_data *td)
-{
- while (1)
- {
- intptr_t reply = 0;
-
- switch (td->ev.id)
- {
- case STREAM_PLAY:
- td->status = STREAM_PLAYING;
-
- switch (td->state)
- {
- case TSTATE_INIT:
- td->state = TSTATE_DECODE;
- case TSTATE_DECODE:
- case TSTATE_RENDER_WAIT:
- break;
-
- case TSTATE_EOS:
- /* At end of stream - no playback possible so fire the
- * completion event */
- stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
- break;
- }
-
- break;
-
- case STREAM_PAUSE:
- td->status = STREAM_PAUSED;
- reply = td->state != TSTATE_EOS;
- break;
-
- case STREAM_STOP:
- if (td->state == TSTATE_DATA)
- stream_clear_notify(&audio_str, DISK_BUF_DATA_NOTIFY);
-
- td->status = STREAM_STOPPED;
- td->state = TSTATE_EOS;
-
- reply = true;
- break;
-
- case STREAM_RESET:
- if (td->state == TSTATE_DATA)
- stream_clear_notify(&audio_str, DISK_BUF_DATA_NOTIFY);
-
- td->status = STREAM_STOPPED;
- td->state = TSTATE_INIT;
- td->samplerate = 0;
- td->nchannels = 0;
-
- init_mad();
- td->mad_errors = 0;
-
- audio_queue_reset();
-
- reply = true;
- break;
-
- case STREAM_NEEDS_SYNC:
- reply = true; /* Audio always needs to */
- break;
-
- case STREAM_SYNC:
- case STREAM_FIND_END_TIME:
- if (td->state != TSTATE_INIT)
- break;
-
- reply = audio_sync(td, (struct str_sync_data *)td->ev.data);
- break;
-
- case DISK_BUF_DATA_NOTIFY:
- /* Our bun is done */
- if (td->state != TSTATE_DATA)
- break;
-
- td->state = TSTATE_DECODE;
- str_data_notify_received(&audio_str);
- break;
-
- case STREAM_QUIT:
- /* Time to go - make thread exit */
- td->state = TSTATE_EOS;
- return;
- }
-
- str_reply_msg(&audio_str, reply);
-
- if (td->status == STREAM_PLAYING)
- {
- switch (td->state)
- {
- case TSTATE_DECODE:
- case TSTATE_RENDER_WAIT:
- /* These return when in playing state */
- return;
- }
- }
-
- str_get_msg(&audio_str, &td->ev);
- }
-}
-
-static void audio_thread(void)
-{
- struct audio_thread_data td;
-#ifdef HAVE_PRIORITY_SCHEDULING
- /* Up the priority since the core DSP over-yields internally */
- int old_priority = rb->thread_set_priority(rb->thread_self(),
- PRIORITY_PLAYBACK-4);
-#endif
-
- rb->memset(&td, 0, sizeof (td));
- td.status = STREAM_STOPPED;
- td.state = TSTATE_EOS;
-
- /* We need this here to init the EMAC for Coldfire targets */
- init_mad();
-
- td.dsp = rb->dsp_get_config(CODEC_IDX_AUDIO);
- rb->dsp_configure(td.dsp, DSP_SET_OUT_FREQUENCY, CLOCK_RATE);
-#ifdef HAVE_PITCHCONTROL
- rb->sound_set_pitch(PITCH_SPEED_100);
- rb->dsp_set_timestretch(PITCH_SPEED_100);
-#endif
- rb->dsp_configure(td.dsp, DSP_RESET, 0);
- rb->dsp_configure(td.dsp, DSP_FLUSH, 0);
- rb->dsp_configure(td.dsp, DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
-
- goto message_wait;
-
- /* This is the decoding loop. */
- while (1)
- {
- td.state = TSTATE_DECODE;
-
- /* Check for any pending messages and process them */
- if (str_have_msg(&audio_str))
- {
- message_wait:
- /* Wait for a message to be queued */
- str_get_msg(&audio_str, &td.ev);
-
- message_process:
- /* Process a message already dequeued */
- audio_thread_msg(&td);
-
- switch (td.state)
- {
- /* These states are the only ones that should return */
- case TSTATE_DECODE: goto audio_decode;
- case TSTATE_RENDER_WAIT: goto render_wait;
- /* Anything else is interpreted as an exit */
- default:
- {
-#ifdef HAVE_PRIORITY_SCHEDULING
- rb->thread_set_priority(rb->thread_self(), old_priority);
-#endif
- return;
- }
- }
- }
-
- audio_decode:
-
- /** Buffering **/
- switch (audio_buffer(&audio_str, STREAM_PM_STREAMING))
- {
- case STREAM_DATA_NOT_READY:
- {
- td.state = TSTATE_DATA;
- goto message_wait;
- } /* STREAM_DATA_NOT_READY: */
-
- case STREAM_DATA_END:
- {
- if (audio_queue.used > MAD_BUFFER_GUARD)
- break; /* Still have frames to decode */
-
- /* Used up remainder of compressed audio buffer. Wait for
- * samples on PCM buffer to finish playing. */
- audio_queue_reset();
-
- while (1)
- {
- if (pcm_output_empty())
- {
- td.state = TSTATE_EOS;
- stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
- break;
- }
-
- pcm_output_drain();
- str_get_msg_w_tmo(&audio_str, &td.ev, 1);
-
- if (td.ev.id != SYS_TIMEOUT)
- break;
- }
-
- goto message_wait;
- } /* STREAM_DATA_END: */
- }
-
- /** Decoding **/
- mad_stream_buffer(&stream, audio_queue.ptr, audio_queue.used);
-
- int mad_stat = mad_frame_decode(&frame, &stream);
-
- ssize_t len = stream.next_frame - audio_queue.ptr;
-
- if (mad_stat != 0)
- {
- DEBUGF("audio: Stream error: %s\n",
- mad_stream_errorstr(&stream));
-
- /* If something's goofed - try to perform resync by moving
- * at least one byte at a time */
- audio_queue_advance_pos(MAX(len, 1));
-
- if (stream.error == MAD_ERROR_BUFLEN)
- {
- /* This makes the codec support partially corrupted files */
- if (++td.mad_errors <= MPA_MAX_FRAME_SIZE)
- {
- stream.error = 0;
- rb->yield();
- continue;
- }
- DEBUGF("audio: Too many errors\n");
- }
- else if (MAD_RECOVERABLE(stream.error))
- {
- /* libmad says it can recover - just keep on decoding */
- rb->yield();
- continue;
- }
- else
- {
- /* Some other unrecoverable error */
- DEBUGF("audio: Unrecoverable error\n");
- }
-
- /* This is too hard - bail out */
- td.state = TSTATE_EOS;
- td.status = STREAM_ERROR;
- stream_generate_event(&audio_str, STREAM_EV_COMPLETE, 0);
-
- goto message_wait;
- }
-
- /* Adjust sizes by the frame size */
- audio_queue_advance_pos(len);
- td.mad_errors = 0; /* Clear errors */
-
- /* Generate the pcm samples */
- mad_synth_frame(&synth, &frame);
-
- /** Output **/
- if (frame.header.samplerate != td.samplerate)
- {
- td.samplerate = frame.header.samplerate;
- rb->dsp_configure(td.dsp, DSP_SET_FREQUENCY,
- td.samplerate);
- }
-
- if (MAD_NCHANNELS(&frame.header) != td.nchannels)
- {
- td.nchannels = MAD_NCHANNELS(&frame.header);
- rb->dsp_configure(td.dsp, DSP_SET_STEREO_MODE,
- td.nchannels == 1 ?
- STEREO_MONO : STEREO_NONINTERLEAVED);
- }
-
- td.src.remcount = synth.pcm.length;
- td.src.pin[0] = synth.pcm.samples[0];
- td.src.pin[1] = synth.pcm.samples[1];
- td.src.proc_mask = 0;
-
- td.state = TSTATE_RENDER_WAIT;
-
- /* Add a frame of audio to the pcm buffer. Maximum is 1152 samples. */
- render_wait:
- rb->yield();
-
- while (1)
- {
- struct dsp_buffer dst;
- dst.remcount = 0;
- dst.bufcount = MAX(td.src.remcount, 1024);
-
- ssize_t size = dst.bufcount * 2 * sizeof(int16_t);
-
- /* Wait for required amount of free buffer space */
- while ((dst.p16out = pcm_output_get_buffer(&size)) == NULL)
- {
- /* Wait one frame */
- int timeout = dst.bufcount*HZ / td.samplerate;
- str_get_msg_w_tmo(&audio_str, &td.ev, MAX(timeout, 1));
- if (td.ev.id != SYS_TIMEOUT)
- goto message_process;
- }
-
- dst.bufcount = size / (2 * sizeof (int16_t));
- rb->dsp_process(td.dsp, &td.src, &dst);
-
- if (dst.remcount > 0)
- {
- /* Make this data available to DMA */
- pcm_output_commit_data(dst.remcount * 2 * sizeof(int16_t),
- audio_queue.curr->time);
-
- /* As long as we're on this timestamp, the time is just
- incremented by the number of samples */
- audio_queue.curr->time += dst.remcount;
- }
- else if (td.src.remcount <= 0)
- {
- break;
- }
- }
- } /* end decoding loop */
-}
-
-/* Initializes the audio thread resources and starts the thread */
-bool audio_thread_init(void)
-{
- /* Initialise the encoded audio buffer and its descriptors */
- audio_queue.start = mpeg_malloc(AUDIOBUF_ALLOC_SIZE,
- MPEG_ALLOC_AUDIOBUF);
- if (audio_queue.start == NULL)
- return false;
-
- /* Start the audio thread */
- audio_str.hdr.q = &audio_str_queue;
- rb->queue_init(audio_str.hdr.q, false);
-
- /* We steal the codec thread for audio */
- rb->codec_thread_do_callback(audio_thread, &audio_str.thread);
-
- rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send,
- audio_str.thread);
-
- /* Wait for thread to initialize */
- str_send_msg(&audio_str, STREAM_NULL, 0);
-
- return true;
-}
-
-/* Stops the audio thread */
-void audio_thread_exit(void)
-{
- if (audio_str.thread != 0)
- {
- str_post_msg(&audio_str, STREAM_QUIT, 0);
- rb->codec_thread_do_callback(NULL, NULL);
- audio_str.thread = 0;
- }
-}
diff --git a/apps/plugins/mpegplayer/disk_buf.c b/apps/plugins/mpegplayer/disk_buf.c
deleted file mode 100644
index 50c4222192..0000000000
--- a/apps/plugins/mpegplayer/disk_buf.c
+++ /dev/null
@@ -1,989 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * mpegplayer buffering routines
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-#include
-
-static struct mutex disk_buf_mtx SHAREDBSS_ATTR;
-static struct event_queue disk_buf_queue SHAREDBSS_ATTR;
-static struct queue_sender_list disk_buf_queue_send SHAREDBSS_ATTR;
-static uint32_t disk_buf_stack[DEFAULT_STACK_SIZE*2/sizeof(uint32_t)];
-
-struct disk_buf disk_buf SHAREDBSS_ATTR;
-static void *nf_list[MPEGPLAYER_MAX_STREAMS+1];
-
-static inline void disk_buf_lock(void)
-{
- rb->mutex_lock(&disk_buf_mtx);
-}
-
-static inline void disk_buf_unlock(void)
-{
- rb->mutex_unlock(&disk_buf_mtx);
-}
-
-static inline void disk_buf_on_clear_data_notify(struct stream_hdr *sh)
-{
- DEBUGF("DISK_BUF_CLEAR_DATA_NOTIFY: 0x%02X (cleared)\n",
- STR_FROM_HDR(sh)->id);
- list_remove_item(nf_list, sh);
-}
-
-inline bool disk_buf_is_data_ready(struct stream_hdr *sh,
- ssize_t margin)
-{
- /* Data window available? */
- off_t right = sh->win_right;
-
- /* Margins past end-of-file can still return true */
- if (right > disk_buf.filesize - margin)
- right = disk_buf.filesize - margin;
-
- return sh->win_left >= disk_buf.win_left &&
- right + margin <= disk_buf.win_right;
-}
-
-void dbuf_l2_init(struct dbuf_l2_cache *l2_p)
-{
- l2_p->addr = OFF_T_MAX; /* Mark as invalid */
-}
-
-static int disk_buf_on_data_notify(struct stream_hdr *sh)
-{
- DEBUGF("DISK_BUF_DATA_NOTIFY: 0x%02X ", STR_FROM_HDR(sh)->id);
-
- if (sh->win_left <= sh->win_right)
- {
- /* Check if the data is already ready already */
- if (disk_buf_is_data_ready(sh, 0))
- {
- /* It was - don't register */
- DEBUGF("(was ready)\n"
- " swl:%lu swr:%lu\n"
- " dwl:%lu dwr:%lu\n",
- sh->win_left, sh->win_right,
- disk_buf.win_left, disk_buf.win_right);
- /* Be sure it's not listed though if multiple requests were made */
- list_remove_item(nf_list, sh);
- return DISK_BUF_NOTIFY_OK;
- }
-
- switch (disk_buf.state)
- {
- case TSTATE_DATA:
- case TSTATE_BUFFERING:
- case TSTATE_INIT:
- disk_buf.state = TSTATE_BUFFERING;
- list_add_item(nf_list, sh);
- DEBUGF("(registered)\n"
- " swl:%lu swr:%lu\n"
- " dwl:%lu dwr:%lu\n",
- sh->win_left, sh->win_right,
- disk_buf.win_left, disk_buf.win_right);
- return DISK_BUF_NOTIFY_REGISTERED;
- }
- }
-
- DEBUGF("(error)\n");
- return DISK_BUF_NOTIFY_ERROR;
-}
-
-static bool check_data_notifies_callback(struct stream_hdr *sh, void *data)
-{
- if (disk_buf_is_data_ready(sh, 0))
- {
- /* Remove from list then post notification - post because send
- * could result in a wait for each thread to finish resulting
- * in deadlock */
- list_remove_item(nf_list, sh);
- str_post_msg(STR_FROM_HDR(sh), DISK_BUF_DATA_NOTIFY, 0);
- DEBUGF("DISK_BUF_DATA_NOTIFY: 0x%02X (notified)\n",
- STR_FROM_HDR(sh)->id);
- }
-
- return true;
- (void)data;
-}
-
-/* Check registered streams and notify them if their data is available */
-static inline void check_data_notifies(void)
-{
- list_enum_items(nf_list,
- (list_enum_callback_t)check_data_notifies_callback,
- NULL);
-}
-
-/* Clear all registered notifications - do not post them */
-static inline void clear_data_notifies(void)
-{
- list_clear_all(nf_list);
-}
-
-/* Background buffering when streaming */
-static inline void disk_buf_buffer(void)
-{
- struct stream_window sw;
-
- switch (disk_buf.state)
- {
- default:
- {
- size_t wm;
- uint32_t time;
-
- /* Get remaining minimum data based upon the stream closest to the
- * right edge of the window */
- if (!stream_get_window(&sw))
- break;
-
- time = stream_get_ticks(NULL);
- wm = muldiv_uint32(5*CLOCK_RATE, sw.right - disk_buf.pos_last,
- time - disk_buf.time_last);
- wm = MIN(wm, (size_t)disk_buf.size);
- wm = MAX(wm, DISK_BUF_LOW_WATERMARK);
-
- disk_buf.time_last = time;
- disk_buf.pos_last = sw.right;
-
- /* Fast attack, slow decay */
- disk_buf.low_wm = (wm > (size_t)disk_buf.low_wm) ?
- wm : AVERAGE(disk_buf.low_wm, wm, 16);
-
-#if 0
- rb->splashf(0, "*%10ld %10ld", disk_buf.low_wm,
- disk_buf.win_right - sw.right);
-#endif
-
- if (disk_buf.win_right - sw.right > disk_buf.low_wm)
- break;
-
- disk_buf.state = TSTATE_BUFFERING;
- } /* default: */
-
- /* Fall-through */
- case TSTATE_BUFFERING:
- {
- ssize_t len, n;
- uint32_t tag, *tag_p;
-
- /* Limit buffering up to the stream with the least progress */
- if (!stream_get_window(&sw))
- {
- disk_buf.state = TSTATE_DATA;
- rb->storage_sleep();
- break;
- }
-
- /* Wrap pointer */
- if (disk_buf.tail >= disk_buf.end)
- disk_buf.tail = disk_buf.start;
-
- len = disk_buf.size - disk_buf.win_right + sw.left;
-
- if (len < DISK_BUF_PAGE_SIZE)
- {
- /* Free space is less than one page */
- disk_buf.state = TSTATE_DATA;
- disk_buf.low_wm = DISK_BUF_LOW_WATERMARK;
- rb->storage_sleep();
- break;
- }
-
- len = disk_buf.tail - disk_buf.start;
- tag = MAP_OFFSET_TO_TAG(disk_buf.win_right);
- tag_p = &disk_buf.cache[len >> DISK_BUF_PAGE_SHIFT];
-
- if (*tag_p != tag)
- {
- if (disk_buf.need_seek)
- {
- rb->lseek(disk_buf.in_file, disk_buf.win_right, SEEK_SET);
- disk_buf.need_seek = false;
- }
-
- n = rb->read(disk_buf.in_file, disk_buf.tail, DISK_BUF_PAGE_SIZE);
-
- if (n <= 0)
- {
- /* Error or end of stream */
- disk_buf.state = TSTATE_EOS;
- rb->storage_sleep();
- break;
- }
-
- if (len < DISK_GUARDBUF_SIZE)
- {
- /* Autoguard guard-o-rama - maintain guardbuffer coherency */
- rb->memcpy(disk_buf.end + len, disk_buf.tail,
- MIN(DISK_GUARDBUF_SIZE - len, n));
- }
-
- /* Update the cache entry for this page */
- *tag_p = tag;
- }
- else
- {
- /* Skipping a read */
- n = MIN(DISK_BUF_PAGE_SIZE,
- disk_buf.filesize - disk_buf.win_right);
- disk_buf.need_seek = true;
- }
-
- disk_buf.tail += DISK_BUF_PAGE_SIZE;
-
- /* Keep left edge moving forward */
-
- /* Advance right edge in temp variable first, then move
- * left edge if overflow would occur. This avoids a stream
- * thinking its data might be available when it actually
- * may not end up that way after a slide of the window. */
- len = disk_buf.win_right + n;
-
- if (len - disk_buf.win_left > disk_buf.size)
- disk_buf.win_left += n;
-
- disk_buf.win_right = len;
-
- /* Continue buffering until filled or file end */
- rb->yield();
- } /* TSTATE_BUFFERING: */
-
- case TSTATE_EOS:
- break;
- } /* end switch */
-}
-
-static void disk_buf_on_reset(ssize_t pos)
-{
- int page;
- uint32_t tag;
- off_t anchor;
-
- disk_buf.state = TSTATE_INIT;
- disk_buf.status = STREAM_STOPPED;
- clear_data_notifies();
-
- if (pos >= disk_buf.filesize)
- {
- /* Anchor on page immediately following the one containing final
- * data */
- anchor = disk_buf.file_pages * DISK_BUF_PAGE_SIZE;
- disk_buf.win_left = disk_buf.filesize;
- }
- else
- {
- anchor = pos & ~DISK_BUF_PAGE_MASK;
- disk_buf.win_left = anchor;
- }
-
- /* Collect all valid data already buffered that is contiguous with the
- * current position - probe to left, then to right */
- if (anchor > 0)
- {
- page = MAP_OFFSET_TO_PAGE(anchor);
- tag = MAP_OFFSET_TO_TAG(anchor);
-
- do
- {
- if (--tag, --page < 0)
- page = disk_buf.pgcount - 1;
-
- if (disk_buf.cache[page] != tag)
- break;
-
- disk_buf.win_left = tag << DISK_BUF_PAGE_SHIFT;
- }
- while (tag > 0);
- }
-
- if (anchor < disk_buf.filesize)
- {
- page = MAP_OFFSET_TO_PAGE(anchor);
- tag = MAP_OFFSET_TO_TAG(anchor);
-
- do
- {
- if (disk_buf.cache[page] != tag)
- break;
-
- if (++tag, ++page >= disk_buf.pgcount)
- page = 0;
-
- anchor += DISK_BUF_PAGE_SIZE;
- }
- while (anchor < disk_buf.filesize);
- }
-
- if (anchor >= disk_buf.filesize)
- {
- disk_buf.win_right = disk_buf.filesize;
- disk_buf.state = TSTATE_EOS;
- }
- else
- {
- disk_buf.win_right = anchor;
- }
-
- disk_buf.tail = disk_buf.start + MAP_OFFSET_TO_BUFFER(anchor);
-
- DEBUGF("disk buf reset\n"
- " dwl:%ld dwr:%ld\n",
- disk_buf.win_left, disk_buf.win_right);
-
- /* Next read position is at right edge */
- rb->lseek(disk_buf.in_file, disk_buf.win_right, SEEK_SET);
- disk_buf.need_seek = false;
-
- disk_buf_reply_msg(disk_buf.win_right - disk_buf.win_left);
-}
-
-static void disk_buf_on_stop(void)
-{
- bool was_buffering = disk_buf.state == TSTATE_BUFFERING;
-
- disk_buf.state = TSTATE_EOS;
- disk_buf.status = STREAM_STOPPED;
- clear_data_notifies();
-
- disk_buf_reply_msg(was_buffering);
-}
-
-static void disk_buf_on_play_pause(bool play, bool forcefill)
-{
- struct stream_window sw;
-
- if (disk_buf.state != TSTATE_EOS)
- {
- if (forcefill)
- {
- /* Force buffer filling to top */
- disk_buf.state = TSTATE_BUFFERING;
- }
- else if (disk_buf.state != TSTATE_BUFFERING)
- {
- /* If not filling already, simply monitor */
- disk_buf.state = TSTATE_DATA;
- }
- }
- /* else end of stream - no buffering to do */
-
- disk_buf.pos_last = stream_get_window(&sw) ? sw.right : 0;
- disk_buf.time_last = stream_get_ticks(NULL);
-
- disk_buf.status = play ? STREAM_PLAYING : STREAM_PAUSED;
-}
-
-static int disk_buf_on_load_range(struct dbuf_range *rng)
-{
- uint32_t tag = rng->tag_start;
- uint32_t tag_end = rng->tag_end;
- int page = rng->pg_start;
-
- /* Check if a seek is required */
- bool need_seek = rb->lseek(disk_buf.in_file, 0, SEEK_CUR)
- != (off_t)(tag << DISK_BUF_PAGE_SHIFT);
-
- do
- {
- uint32_t *tag_p = &disk_buf.cache[page];
-
- if (*tag_p != tag)
- {
- /* Page not cached - load it */
- ssize_t o, n;
-
- if (need_seek)
- {
- rb->lseek(disk_buf.in_file, tag << DISK_BUF_PAGE_SHIFT,
- SEEK_SET);
- need_seek = false;
- }
-
- o = page << DISK_BUF_PAGE_SHIFT;
- n = rb->read(disk_buf.in_file, disk_buf.start + o,
- DISK_BUF_PAGE_SIZE);
-
- if (n < 0)
- {
- /* Read error */
- return DISK_BUF_NOTIFY_ERROR;
- }
-
- if (n == 0)
- {
- /* End of file */
- break;
- }
-
- if (o < DISK_GUARDBUF_SIZE)
- {
- /* Autoguard guard-o-rama - maintain guardbuffer coherency */
- rb->memcpy(disk_buf.end + o, disk_buf.start + o,
- MIN(DISK_GUARDBUF_SIZE - o, n));
- }
-
- /* Update the cache entry */
- *tag_p = tag;
- }
- else
- {
- /* Skipping a disk read - must seek on next one */
- need_seek = true;
- }
-
- if (++page >= disk_buf.pgcount)
- page = 0;
- }
- while (++tag <= tag_end);
-
- return DISK_BUF_NOTIFY_OK;
-}
-
-static void disk_buf_thread(void)
-{
- struct queue_event ev;
-
- disk_buf.state = TSTATE_EOS;
- disk_buf.status = STREAM_STOPPED;
-
- while (1)
- {
- if (disk_buf.state != TSTATE_EOS)
- {
- /* Poll buffer status and messages */
- rb->queue_wait_w_tmo(disk_buf.q, &ev,
- disk_buf.state == TSTATE_BUFFERING ?
- 0 : HZ/5);
- }
- else
- {
- /* Sit idle and wait for commands */
- rb->queue_wait(disk_buf.q, &ev);
- }
-
- switch (ev.id)
- {
- case SYS_TIMEOUT:
- if (disk_buf.state == TSTATE_EOS)
- break;
-
- disk_buf_buffer();
-
- /* Check for any due notifications if any are pending */
- if (*nf_list != NULL)
- check_data_notifies();
-
- /* Still more data left? */
- if (disk_buf.state != TSTATE_EOS)
- continue;
-
- /* Nope - end of stream */
- break;
-
- case DISK_BUF_CACHE_RANGE:
- disk_buf_reply_msg(disk_buf_on_load_range(
- (struct dbuf_range *)ev.data));
- break;
-
- case STREAM_RESET:
- disk_buf_on_reset(ev.data);
- break;
-
- case STREAM_STOP:
- disk_buf_on_stop();
- break;
-
- case STREAM_PAUSE:
- case STREAM_PLAY:
- disk_buf_on_play_pause(ev.id == STREAM_PLAY, ev.data != 0);
- disk_buf_reply_msg(1);
- break;
-
- case STREAM_QUIT:
- disk_buf.state = TSTATE_EOS;
- return;
-
- case DISK_BUF_DATA_NOTIFY:
- disk_buf_reply_msg(disk_buf_on_data_notify(
- (struct stream_hdr *)ev.data));
- break;
-
- case DISK_BUF_CLEAR_DATA_NOTIFY:
- disk_buf_on_clear_data_notify((struct stream_hdr *)ev.data);
- disk_buf_reply_msg(1);
- break;
- }
- }
-}
-
-/* Caches some data from the current file */
-static ssize_t disk_buf_probe(off_t start, size_t length, void **p)
-{
- off_t end;
- uint32_t tag, tag_end;
- int page;
-
- /* Can't read past end of file */
- if (length > (size_t)(disk_buf.filesize - start))
- {
- length = disk_buf.filesize - start;
- }
-
- /* Can't cache more than the whole buffer size */
- if (length > (size_t)disk_buf.size)
- {
- length = disk_buf.size;
- }
- /* Zero-length probes permitted */
-
- end = start + length;
-
- /* Prepare the range probe */
- tag = MAP_OFFSET_TO_TAG(start);
- tag_end = MAP_OFFSET_TO_TAG(end);
- page = MAP_OFFSET_TO_PAGE(start);
-
- /* If the end is on a page boundary, check one less or an extra
- * one will be probed */
- if (tag_end > tag && (end & DISK_BUF_PAGE_MASK) == 0)
- {
- tag_end--;
- }
-
- if (p != NULL)
- {
- *p = disk_buf.start + (page << DISK_BUF_PAGE_SHIFT)
- + (start & DISK_BUF_PAGE_MASK);
- }
-
- /* Obtain initial load point. If all data was cached, no message is sent
- * otherwise begin on the first page that is not cached. Since we have to
- * send the message anyway, the buffering thread will determine what else
- * requires loading on its end in order to cache the specified range. */
- do
- {
- if (disk_buf.cache[page] != tag)
- {
- static struct dbuf_range rng IBSS_ATTR;
- intptr_t result;
-
- DEBUGF("disk_buf: cache miss\n");
- rng.tag_start = tag;
- rng.tag_end = tag_end;
- rng.pg_start = page;
-
- result = rb->queue_send(disk_buf.q, DISK_BUF_CACHE_RANGE,
- (intptr_t)&rng);
-
- return result == DISK_BUF_NOTIFY_OK ? (ssize_t)length : -1;
- }
-
- if (++page >= disk_buf.pgcount)
- page = 0;
- }
- while (++tag <= tag_end);
-
- return length;
-}
-
-/* Attempt to get a pointer to size bytes on the buffer. Returns real amount of
- * data available as well as the size of non-wrapped data after *p. */
-ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
- size_t *sizewrap)
-{
- disk_buf_lock();
-
- size = disk_buf_probe(disk_buf.offset, size, pp);
-
- if (size != (size_t)-1 && pwrap && sizewrap)
- {
- uint8_t *p = (uint8_t *)*pp;
-
- if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE)
- {
- /* Return pointer to wraparound and the size of same */
- size_t nowrap = (disk_buf.end + DISK_GUARDBUF_SIZE) - p;
- *pwrap = disk_buf.start + DISK_GUARDBUF_SIZE;
- *sizewrap = size - nowrap;
- }
- else
- {
- *pwrap = NULL;
- *sizewrap = 0;
- }
- }
-
- disk_buf_unlock();
-
- return size;
-}
-
-ssize_t _disk_buf_getbuffer_l2(struct dbuf_l2_cache *l2,
- size_t size, void **pp)
-{
- off_t offs;
- off_t l2_addr;
- size_t l2_size;
- void *l2_p;
-
- if (l2 == NULL)
- {
- /* Shouldn't have to check this normally */
- DEBUGF("disk_buf_getbuffer_l2: l2 = NULL!\n");
- }
-
- if (size > DISK_BUF_L2_CACHE_SIZE)
- {
- /* Asking for too much; just go through L1 */
- return disk_buf_getbuffer(size, pp, NULL, NULL);
- }
-
- offs = disk_buf.offset; /* Other calls keep this within bounds */
- l2_addr = l2->addr;
-
- if (offs >= l2_addr && offs < l2_addr + DISK_BUF_L2_CACHE_SIZE)
- {
- /* Data is in the local buffer */
- offs &= DISK_BUF_L2_CACHE_MASK;
-
- *pp = l2->data + offs;
- if (offs + size > l2->size)
- size = l2->size - offs; /* Keep size within file limits */
-
- return size;
- }
-
- /* Have to probe main buffer */
- l2_addr = offs & ~DISK_BUF_L2_CACHE_MASK;
- l2_size = DISK_BUF_L2_CACHE_SIZE*2; /* 2nd half is a guard buffer */
-
- disk_buf_lock();
-
- l2_size = disk_buf_probe(l2_addr, l2_size, &l2_p);
-
- if (l2_size != (size_t)-1)
- {
- rb->memcpy(l2->data, l2_p, l2_size);
-
- l2->addr = l2_addr;
- l2->size = l2_size;
- offs -= l2_addr;
-
- *pp = l2->data + offs;
- if (offs + size > l2->size)
- size = l2->size - offs; /* Keep size within file limits */
- }
- else
- {
- size = -1;
- }
-
- disk_buf_unlock();
-
- return size;
-}
-
-
-/* Read size bytes of data into a buffer - advances the buffer pointer
- * and returns the real size read. */
-ssize_t disk_buf_read(void *buffer, size_t size)
-{
- uint8_t *p;
-
- disk_buf_lock();
-
- size = disk_buf_probe(disk_buf.offset, size, PUN_PTR(void **, &p));
-
- if (size != (size_t)-1)
- {
- if (p + size > disk_buf.end + DISK_GUARDBUF_SIZE)
- {
- /* Read wraps */
- size_t nowrap = (disk_buf.end + DISK_GUARDBUF_SIZE) - p;
- rb->memcpy(buffer, p, nowrap);
- rb->memcpy(buffer + nowrap, disk_buf.start + DISK_GUARDBUF_SIZE,
- size - nowrap);
- }
- else
- {
- /* Read wasn't wrapped or guardbuffer holds it */
- rb->memcpy(buffer, p, size);
- }
-
- disk_buf.offset += size;
- }
-
- disk_buf_unlock();
-
- return size;
-}
-
-ssize_t disk_buf_lseek(off_t offset, int whence)
-{
- disk_buf_lock();
-
- /* The offset returned is the result of the current thread's action and
- * may be invalidated so a local result is returned and not the value
- * of disk_buf.offset directly */
- switch (whence)
- {
- case SEEK_SET:
- /* offset is just the offset */
- break;
- case SEEK_CUR:
- offset += disk_buf.offset;
- break;
- case SEEK_END:
- offset = disk_buf.filesize + offset;
- break;
- default:
- disk_buf_unlock();
- return -2; /* Invalid request */
- }
-
- if (offset < 0 || offset > disk_buf.filesize)
- {
- offset = -3;
- }
- else
- {
- disk_buf.offset = offset;
- }
-
- disk_buf_unlock();
-
- return offset;
-}
-
-/* Prepare the buffer to enter the streaming state. Evaluates the available
- * streaming window. */
-ssize_t disk_buf_prepare_streaming(off_t pos, size_t len)
-{
- disk_buf_lock();
-
- if (pos < 0)
- pos = 0;
- else if (pos > disk_buf.filesize)
- pos = disk_buf.filesize;
-
- DEBUGF("prepare streaming:\n pos:%ld len:%lu\n", pos, (unsigned long)len);
-
- pos = disk_buf_lseek(pos, SEEK_SET);
- len = disk_buf_probe(pos, len, NULL);
-
- DEBUGF(" probe done: pos:%ld len:%lu\n", pos, (unsigned long)len);
-
- len = disk_buf_send_msg(STREAM_RESET, pos);
-
- disk_buf_unlock();
-
- return len;
-}
-
-/* Set the streaming window to an arbitrary position within the file. Makes no
- * probes to validate data. Use after calling another function to cause data
- * to be cached and correct values are known. */
-ssize_t disk_buf_set_streaming_window(off_t left, off_t right)
-{
- ssize_t len;
-
- disk_buf_lock();
-
- if (left < 0)
- left = 0;
- else if (left > disk_buf.filesize)
- left = disk_buf.filesize;
-
- if (left > right)
- right = left;
-
- if (right > disk_buf.filesize)
- right = disk_buf.filesize;
-
- disk_buf.win_left = left;
- disk_buf.win_right = right;
- disk_buf.tail = disk_buf.start + ((right + DISK_BUF_PAGE_SIZE-1) &
- ~DISK_BUF_PAGE_MASK) % disk_buf.size;
-
- len = disk_buf.win_right - disk_buf.win_left;
-
- disk_buf_unlock();
-
- return len;
-}
-
-void * disk_buf_offset2ptr(off_t offset)
-{
- if (offset < 0)
- offset = 0;
- else if (offset > disk_buf.filesize)
- offset = disk_buf.filesize;
-
- return disk_buf.start + (offset % disk_buf.size);
-}
-
-void disk_buf_close(void)
-{
- disk_buf_lock();
-
- if (disk_buf.in_file >= 0)
- {
- rb->close(disk_buf.in_file);
- disk_buf.in_file = -1;
-
- /* Invalidate entire cache */
- rb->memset(disk_buf.cache, 0xff,
- disk_buf.pgcount*sizeof (*disk_buf.cache));
- disk_buf.file_pages = 0;
- disk_buf.filesize = 0;
- disk_buf.offset = 0;
- }
-
- disk_buf_unlock();
-}
-
-int disk_buf_open(const char *filename)
-{
- int fd;
-
- disk_buf_lock();
-
- disk_buf_close();
-
- fd = rb->open(filename, O_RDONLY);
-
- if (fd >= 0)
- {
- ssize_t filesize = rb->filesize(fd);
-
- if (filesize <= 0)
- {
- rb->close(disk_buf.in_file);
- }
- else
- {
- disk_buf.filesize = filesize;
- /* Number of file pages rounded up toward +inf */
- disk_buf.file_pages = ((size_t)filesize + DISK_BUF_PAGE_SIZE-1)
- / DISK_BUF_PAGE_SIZE;
- disk_buf.in_file = fd;
- }
- }
-
- disk_buf_unlock();
-
- return fd;
-}
-
-intptr_t disk_buf_send_msg(long id, intptr_t data)
-{
- return rb->queue_send(disk_buf.q, id, data);
-}
-
-void disk_buf_post_msg(long id, intptr_t data)
-{
- rb->queue_post(disk_buf.q, id, data);
-}
-
-void disk_buf_reply_msg(intptr_t retval)
-{
- rb->queue_reply(disk_buf.q, retval);
-}
-
-bool disk_buf_init(void)
-{
- disk_buf.thread = 0;
-
- rb->mutex_init(&disk_buf_mtx);
-
- disk_buf.q = &disk_buf_queue;
- rb->queue_init(disk_buf.q, false);
-
- disk_buf.state = TSTATE_EOS;
- disk_buf.status = STREAM_STOPPED;
-
- disk_buf.in_file = -1;
- disk_buf.filesize = 0;
- disk_buf.win_left = 0;
- disk_buf.win_right = 0;
- disk_buf.time_last = 0;
- disk_buf.pos_last = 0;
- disk_buf.low_wm = DISK_BUF_LOW_WATERMARK;
-
- disk_buf.start = mpeg_malloc_all((size_t*)&disk_buf.size, MPEG_ALLOC_DISKBUF);
- if (disk_buf.start == NULL)
- return false;
-
-#if NUM_CORES > 1
- CACHEALIGN_BUFFER(disk_buf.start, disk_buf.size);
- disk_buf.start = UNCACHED_ADDR(disk_buf.start);
-#endif
- disk_buf.size -= DISK_GUARDBUF_SIZE;
- disk_buf.pgcount = disk_buf.size / DISK_BUF_PAGE_SIZE;
-
- /* Fit it as tightly as possible */
- while (disk_buf.pgcount*(sizeof (*disk_buf.cache) + DISK_BUF_PAGE_SIZE)
- > (size_t)disk_buf.size)
- {
- disk_buf.pgcount--;
- }
-
- disk_buf.cache = (typeof (disk_buf.cache))disk_buf.start;
- disk_buf.start += sizeof (*disk_buf.cache)*disk_buf.pgcount;
- disk_buf.size = disk_buf.pgcount*DISK_BUF_PAGE_SIZE;
- disk_buf.end = disk_buf.start + disk_buf.size;
- disk_buf.tail = disk_buf.start;
-
- DEBUGF("disk_buf info:\n"
- " page count: %d\n"
- " size: %ld\n",
- disk_buf.pgcount, (long)disk_buf.size);
-
- rb->memset(disk_buf.cache, 0xff,
- disk_buf.pgcount*sizeof (*disk_buf.cache));
-
- disk_buf.thread = rb->create_thread(
- disk_buf_thread, disk_buf_stack, sizeof(disk_buf_stack), 0,
- "mpgbuffer" IF_PRIO(, PRIORITY_BUFFERING) IF_COP(, CPU));
-
- rb->queue_enable_queue_send(disk_buf.q, &disk_buf_queue_send,
- disk_buf.thread);
-
- if (disk_buf.thread == 0)
- return false;
-
- /* Wait for thread to initialize */
- disk_buf_send_msg(STREAM_NULL, 0);
-
- return true;
-}
-
-void disk_buf_exit(void)
-{
- if (disk_buf.thread != 0)
- {
- rb->queue_post(disk_buf.q, STREAM_QUIT, 0);
- rb->thread_wait(disk_buf.thread);
- disk_buf.thread = 0;
- }
-}
diff --git a/apps/plugins/mpegplayer/disk_buf.h b/apps/plugins/mpegplayer/disk_buf.h
deleted file mode 100644
index bc76ab6dc3..0000000000
--- a/apps/plugins/mpegplayer/disk_buf.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * AV disk buffer declarations
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef DISK_BUF_H
-#define DISK_BUF_H
-
-#ifndef OFF_T_MAX
-#define OFF_T_MAX (~((off_t)1 << (sizeof (off_t)*8 - 1)))
-#endif
-
-#ifndef OFF_T_MIN
-#define OFF_T_MIN ((off_t)1 << (sizeof (off_t)*8 - 1))
-#endif
-
-#define DISK_BUF_PAGE_SHIFT 15 /* 32KB cache lines */
-#define DISK_BUF_PAGE_SIZE (1 << DISK_BUF_PAGE_SHIFT)
-#define DISK_BUF_PAGE_MASK (DISK_BUF_PAGE_SIZE-1)
-
-enum
-{
- DISK_BUF_NOTIFY_ERROR = -1,
- DISK_BUF_NOTIFY_NULL = 0,
- DISK_BUF_NOTIFY_OK,
- DISK_BUF_NOTIFY_TIMEDOUT,
- DISK_BUF_NOTIFY_PROCESS_EVENT,
- DISK_BUF_NOTIFY_REGISTERED,
-};
-
-/** Macros to map file offsets to cached data **/
-
-/* Returns a cache tag given a file offset */
-#define MAP_OFFSET_TO_TAG(o) \
- ((o) >> DISK_BUF_PAGE_SHIFT)
-
-/* Returns the cache page number given a file offset */
-#define MAP_OFFSET_TO_PAGE(o) \
- (MAP_OFFSET_TO_TAG(o) % disk_buf.pgcount)
-
-/* Returns the buffer offset given a file offset */
-#define MAP_OFFSET_TO_BUFFER(o) \
- (MAP_OFFSET_TO_PAGE(o) * DISK_BUF_PAGE_SIZE)
-
-struct dbuf_range
-{
- uint32_t tag_start;
- uint32_t tag_end;
- int pg_start;
-};
-
-#define DISK_BUF_L2_CACHE_SHIFT 6
-#define DISK_BUF_L2_CACHE_SIZE (1 << DISK_BUF_L2_CACHE_SHIFT)
-#define DISK_BUF_L2_CACHE_MASK (DISK_BUF_L2_CACHE_SIZE-1)
-
-struct dbuf_l2_cache
-{
- off_t addr; /* L2 file offset */
- size_t size; /* Real size */
- uint8_t data[DISK_BUF_L2_CACHE_SIZE*2]; /* Local data and guard */
-};
-
-void dbuf_l2_init(struct dbuf_l2_cache *l2_p);
-
-/* This object is an extension of the stream manager and handles some
- * playback events as well as buffering */
-struct disk_buf
-{
- unsigned int thread;
- struct event_queue *q;
- uint8_t *start; /* Start pointer */
- uint8_t *end; /* End of buffer pointer less MPEG_GUARDBUF_SIZE. The
- guard space is used to wrap data at the buffer start to
- pass continuous data packets */
- uint8_t *tail; /* Location of last data + 1 filled into the buffer */
- ssize_t size; /* The buffer length _not_ including the guard space (end-start) */
- int pgcount; /* Total number of available cached pages */
- uint32_t *cache; /* Pointer to cache structure - allocated on buffer */
- int in_file; /* File being read */
- ssize_t filesize; /* Size of file in_file in bytes */
- int file_pages; /* Number of pages in file (rounded up) */
- off_t offset; /* Current position (random access) */
- off_t win_left; /* Left edge of buffer window (streaming) */
- off_t win_right; /* Right edge of buffer window (streaming) */
- uint32_t time_last; /* Last time watermark was checked */
- off_t pos_last; /* Last position at watermark check time */
- ssize_t low_wm; /* The low watermark for automatic rebuffering */
- int status; /* Status as stream */
- int state; /* Current thread state */
- bool need_seek; /* Need to seek because a read was not contiguous */
-};
-
-extern struct disk_buf disk_buf SHAREDBSS_ATTR;
-
-struct stream_hdr;
-bool disk_buf_is_data_ready(struct stream_hdr *sh, ssize_t margin);
-
-bool disk_buf_init(void);
-void disk_buf_exit(void);
-
-static inline int disk_buf_status(void)
- { return disk_buf.status; }
-
-int disk_buf_open(const char *filename);
-void disk_buf_close(void);
-ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
- size_t *sizewrap);
-#define disk_buf_getbuffer(size, pp, pwrap, sizewrap) \
- _disk_buf_getbuffer((size), PUN_PTR(void **, (pp)), \
- PUN_PTR(void **, (pwrap)), (sizewrap))
-
-ssize_t _disk_buf_getbuffer_l2(struct dbuf_l2_cache *l2,
- size_t size, void **pp);
-#define disk_buf_getbuffer_l2(l2, size, pp) \
- _disk_buf_getbuffer_l2((l2), (size), PUN_PTR(void **, (pp)))
-
-ssize_t disk_buf_read(void *buffer, size_t size);
-ssize_t disk_buf_lseek(off_t offset, int whence);
-
-static inline off_t disk_buf_ftell(void)
- { return disk_buf.offset; }
-
-static inline ssize_t disk_buf_filesize(void)
- { return disk_buf.filesize; }
-
-ssize_t disk_buf_prepare_streaming(off_t pos, size_t len);
-ssize_t disk_buf_set_streaming_window(off_t left, off_t right);
-void * disk_buf_offset2ptr(off_t offset);
-int disk_buf_check_streaming_window(off_t left, off_t right);
-
-intptr_t disk_buf_send_msg(long id, intptr_t data);
-void disk_buf_post_msg(long id, intptr_t data);
-void disk_buf_reply_msg(intptr_t retval);
-
-#endif /* DISK_BUF_H */
diff --git a/apps/plugins/mpegplayer/libmpeg2/AUTHORS b/apps/plugins/mpegplayer/libmpeg2/AUTHORS
deleted file mode 100644
index 4722897c97..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/AUTHORS
+++ /dev/null
@@ -1,33 +0,0 @@
-Aaron Holtzman started the project and
-made the initial working implementation.
-
-Michel Lespinasse did major changes for speed and
-mpeg conformance and is the current maintainer. Most of the current
-code was (re)written by him.
-
-Other contributors include:
- Bruno Barreyra - build fixes
- Gildas Bazin - mingw32 port
- Alexander W. Chin - progressive_seq fix
- Stephen Crowley - build fixes
- Didier Gautheron - bug fixes
- Ryan C. Gordon - SDL support
- Peter Gubanov - MMX IDCT scheduling
- HÃ¥kan Hjort - Solaris fixes, mlib code
- Nicolas Joly - assorted bug fixes
- Gerd Knorr - Xv support
- David I. Lehn - motion_comp mmx code
- Olie Lho - MMX yuv2rgb routine
- David S. Miller - sparc VIS optimizations
- Rick Niles - build fixes
- Real Ouellet - g200 fixes
- Bajusz Peter - motion comp fixes
- Franck Sicard - x11 fixes
- Brion Vibber - x11 fixes
- Martin Vogt - reentrancy fixes
- Fredrik Vraalsen - general hackage and stuff
-
-(let me know if I forgot anyone)
-
-Thanks to David Schleef for creating me an account on his ppc g4
-machine and making it possible for me to work on the altivec code.
diff --git a/apps/plugins/mpegplayer/libmpeg2/README b/apps/plugins/mpegplayer/libmpeg2/README
deleted file mode 100644
index 2a58846772..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/README
+++ /dev/null
@@ -1,204 +0,0 @@
-
-
-ABOUT LIBMPEG2
-
-libmpeg2 is a free library for decoding mpeg-2 and mpeg-1 video
-streams. It is released under the terms of the GPL license.
-
-The main goals in libmpeg2 development are:
-
- * Conformance - libmpeg2 is able to decode all mpeg streams that
- conform to certain restrictions: "constrained parameters" for
- mpeg-1, and "main profile" for mpeg-2. In practice, this is
- what most people are using. For streams that follow these
- restrictions, we believe libmpeg2 is 100% conformant to the
- mpeg standards - and we have a pretty extensive test suite to
- check this.
-
- * Speed - there has been huge efforts there, and we believe
- libmpeg2 is the fastest library around for what it
- does. Please tell us if you find a faster one ! With typical
- video streams as found on DVD's, and doing only decoding with
- no display, you should be able to get about 110 fps on a
- PIII/666, or 150 fps on an Athlon/950. This is less than 20
- cycles per output pixel. In a real player program, the display
- routines will probably take as much time as the actual
- decoding !
-
- * Portability - most of the code is written in C, and when we
- use platform-specific optimizations (typically assembly
- routines, currently used for the motion compensation and the
- inverse cosine transform stages) we always have a generic C
- routine to fall back on. This should be portable to all
- architectures - at least we have heard reports from people
- running this code on x86, ppc, sparc, arm and
- sh4. Assembly-optimized implementations are available on x86
- (MMX) and ppc (altivec) architectures. Ultrasparc (VIS) is
- probably the next on the list - we'll see.
-
- * Reuseability - we do not want libmpeg2 to include any
- project-specific code, but it should still include enough
- features to be used by very diverse projects. We are only
- starting to get there - the best way to help here is to give
- us some feedback !
-
-The project homepage is at http://libmpeg2.sourceforge.net/
-
-
-MPEG2DEC
-
-mpeg2dec is a test program for libmpeg2. It decodes mpeg-1 and mpeg-2
-video streams, and also includes a demultiplexer for mpeg-1 and mpeg-2
-program streams. It is purposely kept simple : it does not include
-features like reading files from a DVD, CSS, fullscreen output,
-navigation, etc... The main purpose of mpeg2dec is to have a simple
-test bed for libmpeg2.
-
-The libmpeg2 source code is always distributed in the mpeg2dec
-package, to make it easier for people to test it.
-
-The basic usage is to just type "mpeg2dec file" where file is a
-demultiplexed mpeg video file.
-
-The "-s" option must be used for multiplexed (audio and video) mpeg
-files using the "program stream" format. These files are usualy found
-on the internet or on unencrypted DVDs.
-
-The "-t" option must be used for multiplexed (audio and video) mpeg
-files using the "transport stream" format. These files are usualy
-found in digital TV applications.
-
-The "-o" option is used to select a given output module - for example
-to redirect the output to a file. This is also used for performance
-testing and conformance testing.
-
-The "-c" option is used to disable all optimizations.
-
-
-OTHER PROJECTS USING LIBMPEG2
-
-libmpeg2 is being used by various other projects, including:
-
- * xine (http://xine.sourceforge.net/) - started as a simple
- mpeg-2 audio and video decoder, but it since became a
- full-featured DVD and video media player.
-
- * VideoLAN (http://www.videolan.org/) - video streaming over an
- ethernet network, can also be used as a standalone player.
-
- * MPlayer (http://www.MPlayerHQ.hu) - another good player, it is
- also very robust against damaged streams.
-
- * movietime (http://movietime.sourceforge.net/) - still quite
- young, but it looks very promising !
-
- * mpeg2decX (http://homepage1.nifty.com/~toku/software_en.html) -
- a graphical interface for mpeg2dec for macintosh osX.
-
- * TCVP (http://tcvp.sf.net) - video and music player for unix.
-
- * drip (http://drip.sourceforge.net/) - a DVD to DIVX transcoder.
-
- * PoMP
- (http://www.dmclab.hanyang.ac.kr/research/project/PoDS/PoDS_sw.htm) -
- a research player optimized to minimize disk power consumption.
-
- * OMS (http://www.linuxvideo.org/oms/)
-
- * XMPS (http://xmps.sourceforge.net/)
-
- * GStreamer (http://www.gstreamer.net/) - a framework for
- streaming media; it has an mpeg2 decoding plugin based on
- libmpeg2.
-
- * mpeglib (http://mpeglib.sourceforge.net/) - a video decoding
- library that usess libmpeg2 when decoding mpeg streams.
-
- * daphne (http://daphne.rulecity.com/) - a laserdisc arcade game
- simulator.
-
- * GOPchop (http://outflux.net/unix/software/GOPchop/) - a
- GOP-accurate editor for MPEG2 streams.
-
-If you use libmpeg2 in another project, let us know !
-
-
-TASKS
-
-There are several places where we could easily use some help:
-
- * Documentation: libmpeg2 still has no documentation. Every
- project using it has had to figure things out by looking at
- the header files, at the mpeg2dec sample application, and by
- asking questions. Writing down a nice documentation would make
- the code more easily reuseable.
-
- * Testing: If you find any stream that does not decode right
- with libmpeg2, let us know ! The best thing would be to mail
- to the libmpeg2-devel mailing list. Also, it would be nice to
- build a stress test so we can make sure libmpeg2 never crashes
- on bad streams.
-
- * Coding: There is a small TODO list in the mpeg2dec package,
- you can have a look there ! Most items are pretty terse
- though.
-
- * Porting: If you're porting to a new architecture, you might
- want to experiment with the compile flags defined in
- configure.in . When you figure out whats fastest on your
- platform, send us a patch !
-
- * Assembly optimizations: We only have x86 and altivec
- optimizations yet, it would be worthwhile writing routines for
- other architectures, especially those that have SIMD
- instruction set extensions ! Also the yuv2rgb x86 routines
- could probably be optimized a lot.
-
-
-CVS SNAPSHOTS
-
-A daily snapshot is created using "make distcheck" every night and
-uploaded to http://libmpeg2.sourceforge.net/files/mpeg2dec-snapshot.tar.gz .
-It is easier to use than the CVS repository, because you do not need
-to have the right versions of automake, autoconf and libtool
-installed. It might be convenient when working on a libmpeg2 port for
-example.
-
-
-CVS REPOSITORY
-
-The latest libmpeg2 and mpeg2dec source code can always be found by
-anonymous CVS:
-
-# export CVSROOT=:pserver:anonymous@cvs.libmpeg2.sourceforge.net:/cvsroot/libmpeg2
-# cvs login (Just press Return when prompted for a password)
-# cvs checkout mpeg2dec
-
-You can also browse the latest changes online at
-http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/libmpeg2/mpeg2dec/
-
-The other CVS modules are mpeg2dec-streams for the test suite, and
-mpeg2dec-livid for the CVS history of the project while it was still
-hosted on the linuxvideo.org servers.
-
-
-MAILING LISTS
-
-See the subscription information at http://libmpeg2.sourceforge.net/lists.html
-
-libmpeg2-devel
-
-This is the main mailing list for technical discussion about
-libmpeg2. Anyone wanting to work on libmpeg2, or maybe just stay
-informed about the development process, should probably subscribe to
-this list.
-
-libmpeg2-checkins
-
-All libmpeg2 checkins are announced there. This is a good way to keep
-track of what goes into CVS.
-
-libmpeg2-announce
-
-This is a very low traffic mailing list, only for announcements of new
-versions of libmpeg2. Only project administrators can post there.
diff --git a/apps/plugins/mpegplayer/libmpeg2/README.rockbox b/apps/plugins/mpegplayer/libmpeg2/README.rockbox
deleted file mode 100644
index 95f5a3d4b5..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/README.rockbox
+++ /dev/null
@@ -1,44 +0,0 @@
-Library: libmpeg2 from mpeg2dec-0.4.0b (Released 2004-01-21)
-Imported: 2006-08-06 by Dave Chapman
-
-
-This directory contains a local version of libmpeg2 imported into
-Rockbox for MPEG video decoding.
-
-
-LICENSING INFORMATION
-
-mpeg2dec and libmpeg2 are licensed under Version 2 of the GNU General
-Public License.
-
-
-IMPORT DETAILS
-
-The following files were imported from the mpeg2dec-0.4.0b
-distribution. Minor changes were made to enable compilation in
-Rockbox and TABs were replaced by spaces to comply with the Rockbox
-coding guidelines.
-
-AUTHORS
-README
-SOURCES
-attributes.h
-cpu_accel.c
-cpu_state.c
-decode.c
-header.c
-idct.c
-motion_comp.c
-mpeg2.h
-mpeg2_internal.h
-slice.c
-video_out.h
-vlc.h
-
-The following files are new, but based on code in mpeg2dec.
-
-Makefile
-mpegplayer.c
-video_out_rockbox.c
-mpeg2dec_config.h
-alloc.c
diff --git a/apps/plugins/mpegplayer/libmpeg2/attributes.h b/apps/plugins/mpegplayer/libmpeg2/attributes.h
deleted file mode 100644
index 24b069223b..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/attributes.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * attributes.h
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.5
- */
-
-/* use gcc attribs to align critical data structures */
-#ifdef ATTRIBUTE_ALIGNED_MAX
-#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
-#else
-#define ATTR_ALIGN(align)
-#endif
-
-#if defined(LIKELY) && defined (UNLIKELY)
-#define likely(x) LIKELY(x)
-#define unlikely(x) UNLIKELY(x)
-#else
-#define likely(x) (x)
-#define unlikely(x) (x)
-#endif
-
diff --git a/apps/plugins/mpegplayer/libmpeg2/decode.c b/apps/plugins/mpegplayer/libmpeg2/decode.c
deleted file mode 100644
index 9c8081efbe..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/decode.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * decode.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.114
- */
-
-#include "plugin.h"
-
-#include "mpeg2dec_config.h"
-
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-
-#define BUFFER_SIZE (1194 * 1024)
-
-#if defined(CPU_COLDFIRE) || (defined(CPU_ARM) && ARM_ARCH >= 6)
-/* twice as large as on other targets because coldfire uses
- * a secondary, transposed buffer for optimisation */
-static int16_t static_dct_block[128] IBSS_ATTR ATTR_ALIGN(16);
-#define DCT_BLOCKSIZE (128 * sizeof (int16_t))
-#else
-static int16_t static_dct_block[64] IBSS_ATTR ATTR_ALIGN(16);
-#define DCT_BLOCKSIZE (64 * sizeof (int16_t))
-#endif
-
-const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec)
-{
- return &mpeg2dec->info;
-}
-
-static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes)
-{
- uint8_t * current;
- uint32_t shift;
- uint8_t * limit;
- uint8_t byte;
-
- if (!bytes)
- return 0;
-
- current = mpeg2dec->buf_start;
- shift = mpeg2dec->shift;
- limit = current + bytes;
-
- do
- {
- byte = *current++;
-
- if (shift == 0x00000100)
- {
- int skipped;
-
- mpeg2dec->shift = 0xffffff00;
- skipped = current - mpeg2dec->buf_start;
- mpeg2dec->buf_start = current;
-
- return skipped;
- }
-
- shift = (shift | byte) << 8;
- }
- while (current < limit);
-
- mpeg2dec->shift = shift;
- mpeg2dec->buf_start = current;
-
- return 0;
-}
-
-static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes)
-{
- uint8_t * current;
- uint32_t shift;
- uint8_t * chunk_ptr;
- uint8_t * limit;
- uint8_t byte;
-
- if (!bytes)
- return 0;
-
- current = mpeg2dec->buf_start;
- shift = mpeg2dec->shift;
- chunk_ptr = mpeg2dec->chunk_ptr;
- limit = current + bytes;
-
- do
- {
- byte = *current++;
-
- if (shift == 0x00000100)
- {
- int copied;
-
- mpeg2dec->shift = 0xffffff00;
- mpeg2dec->chunk_ptr = chunk_ptr + 1;
- copied = current - mpeg2dec->buf_start;
- mpeg2dec->buf_start = current;
- return copied;
- }
-
- shift = (shift | byte) << 8;
- *chunk_ptr++ = byte;
- }
- while (current < limit);
-
- mpeg2dec->shift = shift;
- mpeg2dec->buf_start = current;
- return 0;
-}
-
-void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end)
-{
- mpeg2dec->buf_start = start;
- mpeg2dec->buf_end = end;
-}
-
-int mpeg2_getpos (mpeg2dec_t * mpeg2dec)
-{
- return mpeg2dec->buf_end - mpeg2dec->buf_start;
-}
-
-static inline mpeg2_state_t seek_chunk (mpeg2dec_t * mpeg2dec)
-{
- int size, skipped;
-
- size = mpeg2dec->buf_end - mpeg2dec->buf_start;
- skipped = skip_chunk (mpeg2dec, size);
-
- if (!skipped)
- {
- mpeg2dec->bytes_since_tag += size;
- return STATE_BUFFER;
- }
-
- mpeg2dec->bytes_since_tag += skipped;
- mpeg2dec->code = mpeg2dec->buf_start[-1];
-
- return STATE_INTERNAL_NORETURN;
-}
-
-mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec)
-{
- while (!(mpeg2dec->code == 0xb3 ||
- ((mpeg2dec->code == 0xb7 || mpeg2dec->code == 0xb8 ||
- !mpeg2dec->code) && mpeg2dec->sequence.width != (unsigned)-1)))
- {
- if (seek_chunk (mpeg2dec) == STATE_BUFFER)
- return STATE_BUFFER;
- }
-
- mpeg2dec->chunk_start =
- mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
-
- mpeg2dec->user_data_len = 0;
-
- return ((mpeg2dec->code == 0xb7) ?
- mpeg2_header_end(mpeg2dec) : mpeg2_parse_header(mpeg2dec));
-}
-
-#define RECEIVED(code,state) (((state) << 8) + (code))
-
-mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec)
-{
- int size_buffer, size_chunk, copied;
-
- if (mpeg2dec->action)
- {
- mpeg2_state_t state;
-
- state = mpeg2dec->action (mpeg2dec);
-
- if (state > STATE_INTERNAL_NORETURN)
- return state;
- }
-
- while (1)
- {
- while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) <
- mpeg2dec->nb_decode_slices)
- {
- size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
- size_chunk = mpeg2dec->chunk_buffer + BUFFER_SIZE -
- mpeg2dec->chunk_ptr;
-
- if (size_buffer <= size_chunk)
- {
- copied = copy_chunk (mpeg2dec, size_buffer);
-
- if (!copied)
- {
- mpeg2dec->bytes_since_tag += size_buffer;
- mpeg2dec->chunk_ptr += size_buffer;
- return STATE_BUFFER;
- }
- }
- else
- {
- copied = copy_chunk (mpeg2dec, size_chunk);
-
- if (!copied)
- {
- /* filled the chunk buffer without finding a start code */
- mpeg2dec->bytes_since_tag += size_chunk;
- mpeg2dec->action = seek_chunk;
- return STATE_INVALID;
- }
- }
-
- mpeg2dec->bytes_since_tag += copied;
-
- mpeg2_slice (&mpeg2dec->decoder, mpeg2dec->code,
- mpeg2dec->chunk_start);
- mpeg2dec->code = mpeg2dec->buf_start[-1];
- mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
- }
-
- if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1)
- break;
-
- if (seek_chunk (mpeg2dec) == STATE_BUFFER)
- return STATE_BUFFER;
- }
-
- mpeg2dec->action = mpeg2_seek_header;
-
- switch (mpeg2dec->code)
- {
- case 0x00:
- return mpeg2dec->state;
- case 0xb3:
- case 0xb7:
- case 0xb8:
- return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID;
- default:
- mpeg2dec->action = seek_chunk;
- return STATE_INVALID;
- }
-}
-
-mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec)
-{
- static int (* const process_header[9]) (mpeg2dec_t *) =
- {
- mpeg2_header_picture,
- mpeg2_header_extension,
- mpeg2_header_user_data,
- mpeg2_header_sequence,
- NULL,
- NULL,
- NULL,
- NULL,
- mpeg2_header_gop
- };
-
- int size_buffer, size_chunk, copied;
-
- mpeg2dec->action = mpeg2_parse_header;
- mpeg2dec->info.user_data = NULL;
- mpeg2dec->info.user_data_len = 0;
-
- while (1)
- {
- size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
- size_chunk = mpeg2dec->chunk_buffer + BUFFER_SIZE -
- mpeg2dec->chunk_ptr;
-
- if (size_buffer <= size_chunk)
- {
- copied = copy_chunk (mpeg2dec, size_buffer);
-
- if (!copied)
- {
- mpeg2dec->bytes_since_tag += size_buffer;
- mpeg2dec->chunk_ptr += size_buffer;
- return STATE_BUFFER;
- }
- }
- else
- {
- copied = copy_chunk (mpeg2dec, size_chunk);
-
- if (!copied)
- {
- /* filled the chunk buffer without finding a start code */
- mpeg2dec->bytes_since_tag += size_chunk;
- mpeg2dec->code = 0xb4;
- mpeg2dec->action = mpeg2_seek_header;
- return STATE_INVALID;
- }
- }
-
- mpeg2dec->bytes_since_tag += copied;
-
- if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec))
- {
- mpeg2dec->code = mpeg2dec->buf_start[-1];
- mpeg2dec->action = mpeg2_seek_header;
- return STATE_INVALID;
- }
-
- mpeg2dec->code = mpeg2dec->buf_start[-1];
-
- switch (RECEIVED (mpeg2dec->code, mpeg2dec->state))
- {
- /* state transition after a sequence header */
- case RECEIVED (0x00, STATE_SEQUENCE):
- case RECEIVED (0xb8, STATE_SEQUENCE):
- mpeg2_header_sequence_finalize (mpeg2dec);
- break;
-
- /* other legal state transitions */
- case RECEIVED (0x00, STATE_GOP):
- mpeg2_header_gop_finalize (mpeg2dec);
- break;
- case RECEIVED (0x01, STATE_PICTURE):
- case RECEIVED (0x01, STATE_PICTURE_2ND):
- mpeg2_header_picture_finalize (mpeg2dec);
- mpeg2dec->action = mpeg2_header_slice_start;
- break;
-
- /* legal headers within a given state */
- case RECEIVED (0xb2, STATE_SEQUENCE):
- case RECEIVED (0xb2, STATE_GOP):
- case RECEIVED (0xb2, STATE_PICTURE):
- case RECEIVED (0xb2, STATE_PICTURE_2ND):
- case RECEIVED (0xb5, STATE_SEQUENCE):
- case RECEIVED (0xb5, STATE_PICTURE):
- case RECEIVED (0xb5, STATE_PICTURE_2ND):
- mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
- continue;
-
- default:
- mpeg2dec->action = mpeg2_seek_header;
- return STATE_INVALID;
- }
-
- mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
- mpeg2dec->user_data_len = 0;
-
- return mpeg2dec->state;
- }
-}
-
-int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg)
-{
- mpeg2_convert_init_t convert_init;
- int error;
-
- error = convert (MPEG2_CONVERT_SET, NULL, &mpeg2dec->sequence, 0,
- arg, &convert_init);
-
- if (!error)
- {
- mpeg2dec->convert = convert;
- mpeg2dec->convert_arg = arg;
- mpeg2dec->convert_id_size = convert_init.id_size;
- mpeg2dec->convert_stride = 0;
- }
-
- return error;
-}
-
-int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride)
-{
- if (!mpeg2dec->convert)
- {
- if (stride < (int) mpeg2dec->sequence.width)
- stride = mpeg2dec->sequence.width;
-
- mpeg2dec->decoder.stride_frame = stride;
- }
- else
- {
- mpeg2_convert_init_t convert_init;
-
- stride = mpeg2dec->convert(MPEG2_CONVERT_STRIDE, NULL,
- &mpeg2dec->sequence, stride,
- mpeg2dec->convert_arg,
- &convert_init);
-
- mpeg2dec->convert_id_size = convert_init.id_size;
- mpeg2dec->convert_stride = stride;
- }
-
- return stride;
-}
-
-void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS], void * id)
-{
- mpeg2_fbuf_t * fbuf;
-
- if (mpeg2dec->custom_fbuf)
- {
- if (mpeg2dec->state == STATE_SEQUENCE)
- {
- mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1];
- mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0];
- }
-
- mpeg2_set_fbuf (mpeg2dec, (mpeg2dec->decoder.coding_type ==
- PIC_FLAG_CODING_TYPE_B));
-
- fbuf = mpeg2dec->fbuf[0];
- }
- else
- {
- fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index].fbuf;
- mpeg2dec->alloc_index_user = ++mpeg2dec->alloc_index;
- }
-
- fbuf->buf[0] = buf[0];
-#if MPEG2_COLOR
- fbuf->buf[1] = buf[1];
- fbuf->buf[2] = buf[2];
-#endif
-
- fbuf->id = id;
-}
-
-void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf)
-{
- mpeg2dec->custom_fbuf = custom_fbuf;
-}
-
-void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip)
-{
- mpeg2dec->first_decode_slice = 1;
- mpeg2dec->nb_decode_slices = skip ? 0 : (0xb0 - 1);
-}
-
-void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end)
-{
- start = (start < 1) ? 1 : (start > 0xb0) ? 0xb0 : start;
- end = (end < start) ? start : (end > 0xb0) ? 0xb0 : end;
- mpeg2dec->first_decode_slice = start;
- mpeg2dec->nb_decode_slices = end - start;
-}
-
-void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2)
-{
- mpeg2dec->tag_previous = mpeg2dec->tag_current;
- mpeg2dec->tag2_previous = mpeg2dec->tag2_current;
- mpeg2dec->tag_current = tag;
- mpeg2dec->tag2_current = tag2;
- mpeg2dec->num_tags++;
- mpeg2dec->bytes_since_tag = 0;
-}
-
-void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset)
-{
- mpeg2dec->buf_start = mpeg2dec->buf_end = NULL;
- mpeg2dec->num_tags = 0;
- mpeg2dec->shift = 0xffffff00;
- mpeg2dec->code = 0xb4;
- mpeg2dec->action = mpeg2_seek_header;
- mpeg2dec->state = STATE_INVALID;
- mpeg2dec->first = 1;
-
- mpeg2_reset_info(&mpeg2dec->info);
- mpeg2dec->info.gop = NULL;
- mpeg2dec->info.user_data = NULL;
- mpeg2dec->info.user_data_len = 0;
-
- if (full_reset)
- {
- mpeg2dec->info.sequence = NULL;
- mpeg2_header_state_init (mpeg2dec);
- }
-}
-
-mpeg2dec_t * mpeg2_init (void)
-{
- mpeg2dec_t * mpeg2dec;
-
- mpeg2_idct_init ();
-
- mpeg2dec = (mpeg2dec_t *)mpeg2_bufalloc(sizeof (mpeg2dec_t),
- MPEG2_ALLOC_MPEG2DEC);
- if (mpeg2dec == NULL)
- return NULL;
-
- mpeg2dec->decoder.DCTblock = static_dct_block;
-
- rb->memset (mpeg2dec->decoder.DCTblock, 0, DCT_BLOCKSIZE);
-
- DEBUGF("DCTblock: %p\n", mpeg2dec->decoder.DCTblock);
-
- mpeg2dec->chunk_buffer = (uint8_t *)mpeg2_bufalloc(BUFFER_SIZE + 4,
- MPEG2_ALLOC_CHUNK);
-
- mpeg2dec->sequence.width = (unsigned)-1;
- mpeg2_reset (mpeg2dec, 1);
-
- return mpeg2dec;
-}
-
-void mpeg2_close (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_header_state_init (mpeg2dec);
-#if 0
- /* These are dedicated buffers in rockbox */
- mpeg2_free (mpeg2dec->chunk_buffer);
- mpeg2_free (mpeg2dec);
-#endif
-}
diff --git a/apps/plugins/mpegplayer/libmpeg2/header.c b/apps/plugins/mpegplayer/libmpeg2/header.c
deleted file mode 100644
index b40193a338..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/header.c
+++ /dev/null
@@ -1,1287 +0,0 @@
-/*
- * header.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 2003 Regis Duchesne
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.101
- */
-
-#include "plugin.h"
-
-#include "mpeg2dec_config.h"
-
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-
-#define SEQ_EXT 2
-#define SEQ_DISPLAY_EXT 4
-#define QUANT_MATRIX_EXT 8
-#define COPYRIGHT_EXT 0x10
-#define PIC_DISPLAY_EXT 0x80
-#define PIC_CODING_EXT 0x100
-
-/* default intra quant matrix, in zig-zag order */
-static const uint8_t default_intra_quantizer_matrix[64] =
-{
- 8,
- 16, 16,
- 19, 16, 19,
- 22, 22, 22, 22,
- 22, 22, 26, 24, 26,
- 27, 27, 27, 26, 26, 26,
- 26, 27, 27, 27, 29, 29, 29,
- 34, 34, 34, 29, 29, 29, 27, 27,
- 29, 29, 32, 32, 34, 34, 37,
- 38, 37, 35, 35, 34, 35,
- 38, 38, 40, 40, 40,
- 48, 48, 46, 46,
- 56, 56, 58,
- 69, 69,
- 83
-};
-
-const uint8_t default_mpeg2_scan_norm[64] =
-{
- /* Zig-Zag scan pattern */
- 0, 1, 8, 16, 9, 2, 3, 10,
- 17, 24, 32, 25, 18, 11, 4, 5,
- 12, 19, 26, 33, 40, 48, 41, 34,
- 27, 20, 13, 6, 7, 14, 21, 28,
- 35, 42, 49, 56, 57, 50, 43, 36,
- 29, 22, 15, 23, 30, 37, 44, 51,
- 58, 59, 52, 45, 38, 31, 39, 46,
- 53, 60, 61, 54, 47, 55, 62, 63
-};
-
-const uint8_t default_mpeg2_scan_alt[64] =
-{
- /* Alternate scan pattern */
- 0, 8, 16, 24, 1, 9, 2, 10,
- 17, 25, 32, 40, 48, 56, 57, 49,
- 41, 33, 26, 18, 3, 11, 4, 12,
- 19, 27, 34, 42, 50, 58, 35, 43,
- 51, 59, 20, 28, 5, 13, 6, 14,
- 21, 29, 36, 44, 52, 60, 37, 45,
- 53, 61, 22, 30, 7, 15, 23, 31,
- 38, 46, 54, 62, 39, 47, 55, 63
-};
-
-uint8_t mpeg2_scan_norm[64] IDATA_ATTR;
-uint8_t mpeg2_scan_alt[64] IDATA_ATTR;
-
-void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec)
-{
- if (mpeg2dec->sequence.width != (unsigned)-1)
- {
- mpeg2dec->sequence.width = (unsigned)-1;
- mpeg2_mem_reset(); /* Clean the memory slate */
-#if 0
- if (!mpeg2dec->custom_fbuf)
- {
- int i;
- for (i = mpeg2dec->alloc_index_user;
- i < mpeg2dec->alloc_index; i++)
- {
- mpeg2_free(mpeg2dec->fbuf_alloc[i].fbuf.buf[0]);
-#if MPEG2_COLOR
- mpeg2_free(mpeg2dec->fbuf_alloc[i].fbuf.buf[1]);
- mpeg2_free(mpeg2dec->fbuf_alloc[i].fbuf.buf[2]);
-#endif
- }
- }
-
- if (mpeg2dec->convert_start)
- {
- int i;
- for (i = 0; i < 3; i++)
- {
- mpeg2_free(mpeg2dec->yuv_buf[i][0]);
-#if MPEG2_COLOR
- mpeg2_free(mpeg2dec->yuv_buf[i][1]);
- mpeg2_free(mpeg2dec->yuv_buf[i][2]);
-#endif
- }
- }
-
- if (mpeg2dec->decoder.convert_id)
- {
- mpeg2_free(mpeg2dec->decoder.convert_id);
- }
-#endif
- }
-
- mpeg2dec->decoder.coding_type = I_TYPE;
- mpeg2dec->decoder.convert = NULL;
- mpeg2dec->decoder.convert_id = NULL;
-
- mpeg2dec->picture = mpeg2dec->pictures;
-
- mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[0].fbuf;
- mpeg2dec->fbuf[1] = &mpeg2dec->fbuf_alloc[1].fbuf;
- mpeg2dec->fbuf[2] = &mpeg2dec->fbuf_alloc[2].fbuf;
-
- mpeg2dec->first = 1;
- mpeg2dec->alloc_index = 0;
- mpeg2dec->alloc_index_user = 0;
- mpeg2dec->first_decode_slice = 1;
- mpeg2dec->nb_decode_slices = 0xb0 - 1;
- mpeg2dec->convert = NULL;
- mpeg2dec->convert_start = NULL;
- mpeg2dec->custom_fbuf = 0;
- mpeg2dec->yuv_index = 0;
-}
-
-void mpeg2_reset_info (mpeg2_info_t * info)
-{
- info->current_picture =
- info->current_picture_2nd = NULL;
-
- info->display_picture =
- info->display_picture_2nd = NULL;
-
- info->current_fbuf =
- info->display_fbuf =
- info->discard_fbuf = NULL;
-}
-
-static void info_user_data (mpeg2dec_t * mpeg2dec)
-{
- if (mpeg2dec->user_data_len)
- {
- mpeg2dec->info.user_data = mpeg2dec->chunk_buffer;
- mpeg2dec->info.user_data_len = mpeg2dec->user_data_len - 3;
- }
-}
-
-int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec)
-{
- static const unsigned int frame_period[16] =
- {
- 0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000,
- /* unofficial: xing 15 fps */
- 1800000,
- /* unofficial: libmpeg3 "Unofficial economy rates" 5/10/12/15 fps */
- 5400000, 2700000, 2250000, 1800000, 0, 0
- };
-
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_sequence_t * sequence = &mpeg2dec->new_sequence;
- int i;
-
- if ((buffer[6] & 0x20) != 0x20) /* missing marker_bit */
- return 1;
-
- i = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
-
- if (!(sequence->display_width = sequence->picture_width = i >> 12))
- return 1;
-
- if (!(sequence->display_height = sequence->picture_height = i & 0xfff))
- return 1;
-
- sequence->width = (sequence->picture_width + 15) & ~15;
- sequence->height = (sequence->picture_height + 15) & ~15;
- sequence->chroma_width = sequence->width >> 1;
- sequence->chroma_height = sequence->height >> 1;
-
- sequence->flags = SEQ_FLAG_PROGRESSIVE_SEQUENCE |
- SEQ_VIDEO_FORMAT_UNSPECIFIED;
-
- sequence->pixel_width = buffer[3] >> 4; /* aspect ratio */
- sequence->frame_period = frame_period[buffer[3] & 15];
-
- sequence->byte_rate = (buffer[4]<<10) | (buffer[5]<<2) | (buffer[6]>>6);
-
- sequence->vbv_buffer_size = ((buffer[6]<<16) | (buffer[7]<<8)) & 0x1ff800;
-
- if (buffer[7] & 4)
- sequence->flags |= SEQ_FLAG_CONSTRAINED_PARAMETERS;
-
- mpeg2dec->copy_matrix = 3;
-
- if (buffer[7] & 2)
- {
- for (i = 0; i < 64; i++)
- {
- mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] =
- (buffer[i+7] << 7) | (buffer[i+8] >> 1);
- }
-
- buffer += 64;
- }
- else
- {
- for (i = 0; i < 64; i++)
- {
- mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] =
- default_intra_quantizer_matrix[i];
- }
- }
-
- if (buffer[7] & 1)
- {
- for (i = 0; i < 64; i++)
- {
- mpeg2dec->new_quantizer_matrix[1][mpeg2_scan_norm[i]] =
- buffer[i+8];
- }
- }
- else
- {
- rb->memset (mpeg2dec->new_quantizer_matrix[1], 16, 64);
- }
-
- sequence->profile_level_id = 0x80;
- sequence->colour_primaries = 0;
- sequence->transfer_characteristics = 0;
- sequence->matrix_coefficients = 0;
-
- mpeg2dec->ext_state = SEQ_EXT;
- mpeg2dec->state = STATE_SEQUENCE;
-
- mpeg2dec->display_offset_x =
- mpeg2dec->display_offset_y = 0;
-
- return 0;
-}
-
-static int sequence_ext (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_sequence_t * sequence = &mpeg2dec->new_sequence;
- uint32_t flags;
-
- if (!(buffer[3] & 1))
- return 1;
-
- sequence->profile_level_id = (buffer[0] << 4) | (buffer[1] >> 4);
-
- sequence->picture_width += ((buffer[1] << 13) | (buffer[2] << 5)) & 0x3000;
- sequence->display_width = sequence->picture_width;
-
- sequence->picture_height += (buffer[2] << 7) & 0x3000;
- sequence->display_height = sequence->picture_height;
-
- sequence->width = (sequence->picture_width + 15) & ~15;
- sequence->height = (sequence->picture_height + 15) & ~15;
-
- flags = sequence->flags | SEQ_FLAG_MPEG2;
-
- if (!(buffer[1] & 8))
- {
- flags &= ~SEQ_FLAG_PROGRESSIVE_SEQUENCE;
- sequence->height = (sequence->height + 31) & ~31;
- }
-
- if (buffer[5] & 0x80)
- flags |= SEQ_FLAG_LOW_DELAY;
-
- sequence->flags = flags;
- sequence->chroma_width = sequence->width;
- sequence->chroma_height = sequence->height;
-
- switch (buffer[1] & 6)
- {
- case 0: /* invalid */
- return 1;
- case 2: /* 4:2:0 */
- sequence->chroma_height >>= 1;
- /* fallthrough */
- case 4: /* 4:2:2 */
- sequence->chroma_width >>= 1;
- }
-
- sequence->byte_rate += ((buffer[2]<<25) | (buffer[3]<<17)) & 0x3ffc0000;
-
- sequence->vbv_buffer_size |= buffer[4] << 21;
-
- sequence->frame_period =
- sequence->frame_period * ((buffer[5]&31)+1) / (((buffer[5]>>2)&3)+1);
-
- mpeg2dec->ext_state = SEQ_DISPLAY_EXT;
-
- return 0;
-}
-
-static int sequence_display_ext (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_sequence_t * sequence = &mpeg2dec->new_sequence;
- int x;
-
- sequence->flags = (sequence->flags & ~SEQ_MASK_VIDEO_FORMAT) |
- ((buffer[0] << 4) & SEQ_MASK_VIDEO_FORMAT);
-
- if (buffer[0] & 1)
- {
- sequence->flags |= SEQ_FLAG_COLOUR_DESCRIPTION;
- sequence->colour_primaries = buffer[1];
- sequence->transfer_characteristics = buffer[2];
- sequence->matrix_coefficients = buffer[3];
- buffer += 3;
- }
-
- if (!(buffer[2] & 2)) /* missing marker_bit */
- return 1;
-
- x = (buffer[1] << 6) | (buffer[2] >> 2);
- if (x)
- sequence->display_width = x;
-
- x = ((buffer[2] & 1) << 13) | (buffer[3] << 5) | (buffer[4] >> 3);
- if (x)
- sequence->display_height = x;
-
- return 0;
-}
-
-static inline void simplify (unsigned int * u, unsigned int * v)
-{
- unsigned int a, b, tmp;
-
- a = *u;
- b = *v;
-
- /* find greatest common divisor */
- while (a)
- {
- tmp = a;
- a = b % tmp;
- b = tmp;
- }
-
- *u /= b;
- *v /= b;
-}
-
-static inline void finalize_sequence (mpeg2_sequence_t * sequence)
-{
- int width;
- int height;
-
- sequence->byte_rate *= 50;
-
- if (sequence->flags & SEQ_FLAG_MPEG2)
- {
- switch (sequence->pixel_width)
- {
- case 1: /* square pixels */
- sequence->pixel_width =
- sequence->pixel_height = 1;
- return;
- case 2: /* 4:3 aspect ratio */
- width = 4;
- height = 3;
- break;
- case 3: /* 16:9 aspect ratio */
- width = 16;
- height = 9;
- break;
- case 4: /* 2.21:1 aspect ratio */
- width = 221;
- height = 100;
- break;
- default: /* illegal */
- sequence->pixel_width =
- sequence->pixel_height = 0;
- return;
- }
-
- width *= sequence->display_height;
- height *= sequence->display_width;
- }
- else
- {
- if (sequence->byte_rate == 50 * 0x3ffff)
- sequence->byte_rate = 0; /* mpeg-1 VBR */
-
- switch (sequence->pixel_width)
- {
- case 0:
- case 15: /* illegal */
- sequence->pixel_width =
- sequence->pixel_height = 0;
- return;
- case 1: /* square pixels */
- sequence->pixel_width =
- sequence->pixel_height = 1;
- return;
- case 3: /* 720x576 16:9 */
- sequence->pixel_width = 64;
- sequence->pixel_height = 45;
- return;
- case 6: /* 720x480 16:9 */
- sequence->pixel_width = 32;
- sequence->pixel_height = 27;
- return;
- case 8: /* BT.601 625 lines 4:3 */
- sequence->pixel_width = 59;
- sequence->pixel_height = 54;
- return;
- case 12: /* BT.601 525 lines 4:3 */
- sequence->pixel_width = 10;
- sequence->pixel_height = 11;
- return;
- default:
- height = 88 * sequence->pixel_width + 1171;
- width = 2000;
- }
- }
-
- sequence->pixel_width = width;
- sequence->pixel_height = height;
-
- simplify(&sequence->pixel_width, &sequence->pixel_height);
-}
-
-int mpeg2_guess_aspect (const mpeg2_sequence_t * sequence,
- unsigned int * pixel_width,
- unsigned int * pixel_height)
-{
- static const struct
- {
- unsigned int width, height;
- } video_modes[] =
- {
- {720, 576}, /* 625 lines, 13.5 MHz (D1, DV, DVB, DVD) */
- {704, 576}, /* 625 lines, 13.5 MHz (1/1 D1, DVB, DVD, 4CIF) */
- {544, 576}, /* 625 lines, 10.125 MHz (DVB, laserdisc) */
- {528, 576}, /* 625 lines, 10.125 MHz (3/4 D1, DVB, laserdisc) */
- {480, 576}, /* 625 lines, 9 MHz (2/3 D1, DVB, SVCD) */
- {352, 576}, /* 625 lines, 6.75 MHz (D2, 1/2 D1, CVD, DVB, DVD) */
- {352, 288}, /* 625 lines, 6.75 MHz, 1 field (D4, VCD, DVB, DVD, CIF) */
- {176, 144}, /* 625 lines, 3.375 MHz, half field (QCIF) */
- {720, 486}, /* 525 lines, 13.5 MHz (D1) */
- {704, 486}, /* 525 lines, 13.5 MHz */
- {720, 480}, /* 525 lines, 13.5 MHz (DV, DSS, DVD) */
- {704, 480}, /* 525 lines, 13.5 MHz (1/1 D1, ATSC, DVD) */
- {544, 480}, /* 525 lines. 10.125 MHz (DSS, laserdisc) */
- {528, 480}, /* 525 lines. 10.125 MHz (3/4 D1, laserdisc) */
- {480, 480}, /* 525 lines, 9 MHz (2/3 D1, SVCD) */
- {352, 480}, /* 525 lines, 6.75 MHz (D2, 1/2 D1, CVD, DVD) */
- {352, 240} /* 525 lines. 6.75 MHz, 1 field (D4, VCD, DSS, DVD) */
- };
- unsigned int width, height, pix_width, pix_height, i, DAR_16_9;
-
- *pixel_width = sequence->pixel_width;
- *pixel_height = sequence->pixel_height;
- width = sequence->picture_width;
- height = sequence->picture_height;
-
- for (i = 0; i < sizeof (video_modes) / sizeof (video_modes[0]); i++)
- {
- if (width == video_modes[i].width && height == video_modes[i].height)
- break;
- }
-
- if (i == ARRAYLEN(video_modes) ||
- (sequence->pixel_width == 1 && sequence->pixel_height == 1) ||
- width != sequence->display_width || height != sequence->display_height)
- {
- return 0;
- }
-
- for (pix_height = 1; height * pix_height < 480; pix_height <<= 1);
- height *= pix_height;
-
- for (pix_width = 1; width * pix_width <= 352; pix_width <<= 1);
- width *= pix_width;
-
- if (!(sequence->flags & SEQ_FLAG_MPEG2))
- {
- static unsigned int mpeg1_check[2][2] = {{11, 54}, {27, 45}};
- DAR_16_9 = (sequence->pixel_height == 27 ||
- sequence->pixel_height == 45);
- if (width < 704 ||
- sequence->pixel_height != mpeg1_check[DAR_16_9][height == 576])
- return 0;
- }
- else
- {
- DAR_16_9 = (3 * sequence->picture_width * sequence->pixel_width >
- 4 * sequence->picture_height * sequence->pixel_height);
- switch (width)
- {
- case 528:
- case 544:
- pix_width *= 4;
- pix_height *= 3;
- break;
- case 480:
- pix_width *= 3;
- pix_height *= 2;
- break;
- }
- }
-
- if (DAR_16_9)
- {
- pix_width *= 4;
- pix_height *= 3;
- }
-
- if (height == 576)
- {
- pix_width *= 59;
- pix_height *= 54;
- }
- else
- {
- pix_width *= 10;
- pix_height *= 11;
- }
-
- *pixel_width = pix_width;
- *pixel_height = pix_height;
-
- simplify (pixel_width, pixel_height);
-
- return (height == 576) ? 1 : 2;
-}
-
-static void copy_matrix (mpeg2dec_t * mpeg2dec, int index)
-{
- if (rb->memcmp (mpeg2dec->quantizer_matrix[index],
- mpeg2dec->new_quantizer_matrix[index], 64))
- {
- rb->memcpy (mpeg2dec->quantizer_matrix[index],
- mpeg2dec->new_quantizer_matrix[index], 64);
-
- mpeg2dec->scaled[index] = -1;
- }
-}
-
-static void finalize_matrix (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_decoder_t *decoder = &mpeg2dec->decoder;
- int i;
-
- for (i = 0; i < 2; i++)
- {
- if (mpeg2dec->copy_matrix & (1 << i))
- copy_matrix (mpeg2dec, i);
-
- if ((mpeg2dec->copy_matrix & (4 << i)) &&
- rb->memcmp(mpeg2dec->quantizer_matrix[i],
- mpeg2dec->new_quantizer_matrix[i+2], 64))
- {
- copy_matrix (mpeg2dec, i + 2);
- decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i+2];
- }
- else if (mpeg2dec->copy_matrix & (5 << i))
- {
- decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i];
- }
- }
-}
-
-static mpeg2_state_t invalid_end_action (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_reset_info (&mpeg2dec->info);
-
- mpeg2dec->info.gop = NULL;
-
- info_user_data (mpeg2dec);
-
- mpeg2_header_state_init (mpeg2dec);
-
- mpeg2dec->sequence = mpeg2dec->new_sequence;
- mpeg2dec->action = mpeg2_seek_header;
- mpeg2dec->state = STATE_SEQUENCE;
-
- return STATE_SEQUENCE;
-}
-
-void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_sequence_t * sequence = &mpeg2dec->new_sequence;
- mpeg2_decoder_t * decoder = &mpeg2dec->decoder;
-
- finalize_sequence(sequence);
- finalize_matrix(mpeg2dec);
-
- decoder->mpeg1 = !(sequence->flags & SEQ_FLAG_MPEG2);
- decoder->width = sequence->width;
- decoder->height = sequence->height;
- decoder->vertical_position_extension = sequence->picture_height > 2800;
- decoder->chroma_format = (sequence->chroma_width == sequence->width) +
- (sequence->chroma_height == sequence->height);
-
- if (mpeg2dec->sequence.width != (unsigned)-1)
- {
- /*
- * According to 6.1.1.6, repeat sequence headers should be
- * identical to the original. However some encoders don't
- * respect that and change various fields (including bitrate
- * and aspect ratio) in the repeat sequence headers. So we
- * choose to be as conservative as possible and only restart
- * the decoder if the width, height, chroma_width,
- * chroma_height or low_delay flag are modified.
- */
- if (sequence->width != mpeg2dec->sequence.width ||
- sequence->height != mpeg2dec->sequence.height ||
- sequence->chroma_width != mpeg2dec->sequence.chroma_width ||
- sequence->chroma_height != mpeg2dec->sequence.chroma_height ||
- ((sequence->flags ^ mpeg2dec->sequence.flags) &
- SEQ_FLAG_LOW_DELAY))
- {
- decoder->stride_frame = sequence->width;
- mpeg2_header_end (mpeg2dec);
- mpeg2dec->action = invalid_end_action;
- mpeg2dec->state = STATE_INVALID_END;
- return;
- }
-
- mpeg2dec->state = rb->memcmp(&mpeg2dec->sequence, sequence,
- sizeof (mpeg2_sequence_t)) ?
- STATE_SEQUENCE_MODIFIED :
- STATE_SEQUENCE_REPEATED;
- }
- else
- {
- decoder->stride_frame = sequence->width;
- }
-
- mpeg2dec->sequence = *sequence;
- mpeg2_reset_info(&mpeg2dec->info);
- mpeg2dec->info.sequence = &mpeg2dec->sequence;
- mpeg2dec->info.gop = NULL;
-
- info_user_data (mpeg2dec);
-}
-
-int mpeg2_header_gop (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_gop_t * gop = &mpeg2dec->new_gop;
-
- if (!(buffer[1] & 8))
- return 1;
-
- gop->hours = (buffer[0] >> 2) & 31;
- gop->minutes = ((buffer[0] << 4) | (buffer[1] >> 4)) & 63;
- gop->seconds = ((buffer[1] << 3) | (buffer[2] >> 5)) & 63;
- gop->pictures = ((buffer[2] << 1) | (buffer[3] >> 7)) & 63;
- gop->flags = (buffer[0] >> 7) | ((buffer[3] >> 4) & 6);
-
- mpeg2dec->state = STATE_GOP;
- return 0;
-}
-
-void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec)
-{
- mpeg2dec->gop = mpeg2dec->new_gop;
- mpeg2_reset_info (&mpeg2dec->info);
- mpeg2dec->info.gop = &mpeg2dec->gop;
- info_user_data (mpeg2dec);
-}
-
-void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type)
-{
- int i;
-
- for (i = 0; i < 3; i++)
- {
- if (mpeg2dec->fbuf[1] != &mpeg2dec->fbuf_alloc[i].fbuf &&
- mpeg2dec->fbuf[2] != &mpeg2dec->fbuf_alloc[i].fbuf)
- {
- mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[i].fbuf;
- mpeg2dec->info.current_fbuf = mpeg2dec->fbuf[0];
-
- if (b_type || (mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY))
- {
- if (b_type || mpeg2dec->convert)
- mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[0];
-
- mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[0];
- }
-
- break;
- }
- }
-}
-
-int mpeg2_header_picture (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_picture_t * picture = &mpeg2dec->new_picture;
- mpeg2_decoder_t * decoder = &mpeg2dec->decoder;
- int type;
-
- mpeg2dec->state = (mpeg2dec->state != STATE_SLICE_1ST) ?
- STATE_PICTURE : STATE_PICTURE_2ND;
- mpeg2dec->ext_state = PIC_CODING_EXT;
-
- picture->temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6);
-
- type = (buffer [1] >> 3) & 7;
-
- if (type == PIC_FLAG_CODING_TYPE_P || type == PIC_FLAG_CODING_TYPE_B)
- {
- /* forward_f_code and backward_f_code - used in mpeg1 only */
- decoder->f_motion.f_code[1] = (buffer[3] >> 2) & 1;
- decoder->f_motion.f_code[0] =
- (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1;
- decoder->b_motion.f_code[1] = (buffer[4] >> 6) & 1;
- decoder->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1;
- }
-
- picture->flags = PIC_FLAG_PROGRESSIVE_FRAME | type;
- picture->tag = picture->tag2 = 0;
-
- if (mpeg2dec->num_tags)
- {
- if (mpeg2dec->bytes_since_tag >= mpeg2dec->chunk_ptr - buffer + 4)
- {
- mpeg2dec->num_tags = 0;
- picture->tag = mpeg2dec->tag_current;
- picture->tag2 = mpeg2dec->tag2_current;
- picture->flags |= PIC_FLAG_TAGS;
- }
- else if (mpeg2dec->num_tags > 1)
- {
- mpeg2dec->num_tags = 1;
- picture->tag = mpeg2dec->tag_previous;
- picture->tag2 = mpeg2dec->tag2_previous;
- picture->flags |= PIC_FLAG_TAGS;
- }
- }
-
- picture->nb_fields = 2;
- picture->display_offset[0].x = picture->display_offset[1].x =
- picture->display_offset[2].x = mpeg2dec->display_offset_x;
-
- picture->display_offset[0].y = picture->display_offset[1].y =
- picture->display_offset[2].y = mpeg2dec->display_offset_y;
-
- /* XXXXXX decode extra_information_picture as well */
-
- mpeg2dec->q_scale_type = 0;
- decoder->intra_dc_precision = 7;
- decoder->frame_pred_frame_dct = 1;
- decoder->concealment_motion_vectors = 0;
- decoder->scan = mpeg2_scan_norm;
- decoder->picture_structure = FRAME_PICTURE;
- mpeg2dec->copy_matrix = 0;
-
- return 0;
-}
-
-static int picture_coding_ext (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_picture_t * picture = &mpeg2dec->new_picture;
- mpeg2_decoder_t * decoder = &mpeg2dec->decoder;
- uint32_t flags;
-
- /* pre subtract 1 for use later in compute_motion_vector */
- decoder->f_motion.f_code[0] = (buffer[0] & 15) - 1;
- decoder->f_motion.f_code[1] = (buffer[1] >> 4) - 1;
- decoder->b_motion.f_code[0] = (buffer[1] & 15) - 1;
- decoder->b_motion.f_code[1] = (buffer[2] >> 4) - 1;
-
- flags = picture->flags;
-
- decoder->intra_dc_precision = 7 - ((buffer[2] >> 2) & 3);
- decoder->picture_structure = buffer[2] & 3;
-
- switch (decoder->picture_structure)
- {
- case TOP_FIELD:
- flags |= PIC_FLAG_TOP_FIELD_FIRST;
- case BOTTOM_FIELD:
- picture->nb_fields = 1;
- break;
- case FRAME_PICTURE:
- if (!(mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE))
- {
- picture->nb_fields = (buffer[3] & 2) ? 3 : 2;
- flags |= (buffer[3] & 128) ? PIC_FLAG_TOP_FIELD_FIRST : 0;
- }
- else
- {
- picture->nb_fields = (buffer[3]&2) ? ((buffer[3]&128) ? 6 : 4) : 2;
- }
- break;
- default:
- return 1;
- }
-
- decoder->top_field_first = buffer[3] >> 7;
- decoder->frame_pred_frame_dct = (buffer[3] >> 6) & 1;
- decoder->concealment_motion_vectors = (buffer[3] >> 5) & 1;
- mpeg2dec->q_scale_type = buffer[3] & 16;
- decoder->intra_vlc_format = (buffer[3] >> 3) & 1;
- decoder->scan = (buffer[3] & 4) ? mpeg2_scan_alt : mpeg2_scan_norm;
-
- if (!(buffer[4] & 0x80))
- flags &= ~PIC_FLAG_PROGRESSIVE_FRAME;
-
- if (buffer[4] & 0x40)
- {
- flags |= (((buffer[4]<<26) | (buffer[5]<<18) | (buffer[6]<<10)) &
- PIC_MASK_COMPOSITE_DISPLAY) | PIC_FLAG_COMPOSITE_DISPLAY;
- }
-
- picture->flags = flags;
-
- mpeg2dec->ext_state = PIC_DISPLAY_EXT | COPYRIGHT_EXT | QUANT_MATRIX_EXT;
-
- return 0;
-}
-
-static int picture_display_ext (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- mpeg2_picture_t * picture = &mpeg2dec->new_picture;
- int i, nb_pos;
-
- nb_pos = picture->nb_fields;
-
- if (mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)
- nb_pos >>= 1;
-
- for (i = 0; i < nb_pos; i++)
- {
- int x, y;
-
- x = ((buffer[4*i] << 24) | (buffer[4*i+1] << 16) |
- (buffer[4*i+2] << 8) | buffer[4*i+3]) >> (11-2*i);
-
- y = ((buffer[4*i+2] << 24) | (buffer[4*i+3] << 16) |
- (buffer[4*i+4] << 8) | buffer[4*i+5]) >> (10-2*i);
-
- if (! (x & y & 1))
- return 1;
-
- picture->display_offset[i].x = mpeg2dec->display_offset_x = x >> 1;
- picture->display_offset[i].y = mpeg2dec->display_offset_y = y >> 1;
- }
-
- for (; i < 3; i++)
- {
- picture->display_offset[i].x = mpeg2dec->display_offset_x;
- picture->display_offset[i].y = mpeg2dec->display_offset_y;
- }
-
- return 0;
-}
-
-void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_decoder_t * decoder = &mpeg2dec->decoder;
- int old_type_b = decoder->coding_type == B_TYPE;
- int low_delay = mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY;
-
- finalize_matrix (mpeg2dec);
- decoder->coding_type = mpeg2dec->new_picture.flags & PIC_MASK_CODING_TYPE;
-
- if (mpeg2dec->state == STATE_PICTURE)
- {
- mpeg2_picture_t * picture;
- mpeg2_picture_t * other;
-
- decoder->second_field = 0;
-
- picture = other = mpeg2dec->pictures;
-
- if (old_type_b ^ (mpeg2dec->picture < mpeg2dec->pictures + 2))
- picture += 2;
- else
- other += 2;
-
- mpeg2dec->picture = picture;
- *picture = mpeg2dec->new_picture;
-
- if (!old_type_b)
- {
- mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1];
- mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0];
- }
-
- mpeg2dec->fbuf[0] = NULL;
- mpeg2_reset_info (&mpeg2dec->info);
- mpeg2dec->info.current_picture = picture;
- mpeg2dec->info.display_picture = picture;
-
- if (decoder->coding_type != B_TYPE)
- {
- if (!low_delay)
- {
- if (mpeg2dec->first)
- {
- mpeg2dec->info.display_picture = NULL;
- mpeg2dec->first = 0;
- }
- else
- {
- mpeg2dec->info.display_picture = other;
-
- if (other->nb_fields == 1)
- mpeg2dec->info.display_picture_2nd = other + 1;
-
- mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[1];
- }
- }
-
- if (!low_delay + !mpeg2dec->convert)
- {
- mpeg2dec->info.discard_fbuf =
- mpeg2dec->fbuf[!low_delay + !mpeg2dec->convert];
- }
- }
-
- if (mpeg2dec->convert)
- {
- mpeg2_convert_init_t convert_init;
-
- if (!mpeg2dec->convert_start)
- {
- mpeg2dec->decoder.convert_id =
- mpeg2_malloc (mpeg2dec->convert_id_size,
- MPEG2_ALLOC_CONVERT_ID);
-
- mpeg2dec->convert (MPEG2_CONVERT_START,
- mpeg2dec->decoder.convert_id,
- &mpeg2dec->sequence,
- mpeg2dec->convert_stride,
- mpeg2dec->convert_arg, &convert_init);
-
- mpeg2dec->convert_start = convert_init.start;
- mpeg2dec->decoder.convert = convert_init.copy;
-
- int y_size = decoder->stride_frame * mpeg2dec->sequence.height;
-
- mpeg2dec->yuv_buf[0][0] =
- (uint8_t *) mpeg2_malloc(y_size, MPEG2_ALLOC_YUV);
-#if MPEG2_COLOR
- int uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format);
-
- mpeg2dec->yuv_buf[0][1] =
- (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV);
- mpeg2dec->yuv_buf[0][2] =
- (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV);
-#endif
-
- mpeg2dec->yuv_buf[1][0] =
- (uint8_t *) mpeg2_malloc(y_size, MPEG2_ALLOC_YUV);
-#if MPEG2_COLOR
- mpeg2dec->yuv_buf[1][1] =
- (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV);
- mpeg2dec->yuv_buf[1][2] =
- (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV);
-#endif
- y_size = decoder->stride_frame * 32;
-
- mpeg2dec->yuv_buf[2][0] =
- (uint8_t *) mpeg2_malloc(y_size, MPEG2_ALLOC_YUV);
-#if MPEG2_COLOR
- uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format);
-
- mpeg2dec->yuv_buf[2][1] =
- (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV);
- mpeg2dec->yuv_buf[2][2] =
- (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV);
-#endif
- }
-
- if (!mpeg2dec->custom_fbuf)
- {
- while (mpeg2dec->alloc_index < 3)
- {
- mpeg2_fbuf_t * fbuf;
-
- fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf;
- fbuf->id = NULL;
-
- fbuf->buf[0] =
- (uint8_t *) mpeg2_malloc (convert_init.buf_size[0],
- MPEG2_ALLOC_CONVERTED);
-#if MPEG2_COLOR
- fbuf->buf[1] =
- (uint8_t *) mpeg2_malloc (convert_init.buf_size[1],
- MPEG2_ALLOC_CONVERTED);
- fbuf->buf[2] =
- (uint8_t *) mpeg2_malloc (convert_init.buf_size[2],
- MPEG2_ALLOC_CONVERTED);
-#endif
- }
-
- mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE));
- }
- }
- else if (!mpeg2dec->custom_fbuf)
- {
- while (mpeg2dec->alloc_index < 3)
- {
- mpeg2_fbuf_t * fbuf;
-
- fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf;
-
- fbuf->id = NULL;
-
- int y_size = decoder->stride_frame * mpeg2dec->sequence.height;
-
- fbuf->buf[0] = (uint8_t *) mpeg2_malloc (y_size,
- MPEG2_ALLOC_YUV);
-#if MPEG2_COLOR
- int uv_size = y_size >> (2 - decoder->chroma_format);
-
- fbuf->buf[1] = (uint8_t *) mpeg2_malloc (uv_size,
- MPEG2_ALLOC_YUV);
- fbuf->buf[2] = (uint8_t *) mpeg2_malloc (uv_size,
- MPEG2_ALLOC_YUV);
-#endif
- }
-
- mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE));
- }
- }
- else
- {
- decoder->second_field = 1;
- mpeg2dec->picture++; /* second field picture */
-
- *(mpeg2dec->picture) = mpeg2dec->new_picture;
-
- mpeg2dec->info.current_picture_2nd = mpeg2dec->picture;
-
- if (low_delay || decoder->coding_type == B_TYPE)
- mpeg2dec->info.display_picture_2nd = mpeg2dec->picture;
- }
-
- info_user_data (mpeg2dec);
-}
-
-static int copyright_ext (mpeg2dec_t * mpeg2dec)
-{
- (void)mpeg2dec;
- return 0;
-}
-
-static int quant_matrix_ext (mpeg2dec_t * mpeg2dec)
-{
- uint8_t * buffer = mpeg2dec->chunk_start;
- int i, j;
-
- for (i = 0; i < 4; i++)
- {
- if (buffer[0] & (8 >> i))
- {
- for (j = 0; j < 64; j++)
- {
- mpeg2dec->new_quantizer_matrix[i][mpeg2_scan_norm[j]] =
- (buffer[j] << (i+5)) | (buffer[j+1] >> (3-i));
- }
-
- mpeg2dec->copy_matrix |= 1 << i;
- buffer += 64;
- }
- }
-
- return 0;
-}
-
-int mpeg2_header_extension (mpeg2dec_t * mpeg2dec)
-{
- static int (* const parser[9]) (mpeg2dec_t *) =
- {
- NULL,
- sequence_ext,
- sequence_display_ext,
- quant_matrix_ext,
- copyright_ext,
- NULL,
- NULL,
- picture_display_ext,
- picture_coding_ext
- };
-
- int ext, ext_bit;
-
- ext = mpeg2dec->chunk_start[0] >> 4;
- ext_bit = 1 << ext;
-
- if (!(mpeg2dec->ext_state & ext_bit))
- return 0; /* ignore illegal extensions */
-
- mpeg2dec->ext_state &= ~ext_bit;
-
- return parser[ext] (mpeg2dec);
-}
-
-int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec)
-{
- mpeg2dec->user_data_len += mpeg2dec->chunk_ptr - 1 - mpeg2dec->chunk_start;
- mpeg2dec->chunk_start = mpeg2dec->chunk_ptr - 1;
-
- return 0;
-}
-
-static void prescale (mpeg2dec_t * mpeg2dec, int index)
-{
- static const int non_linear_scale[32] =
- {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 10, 12, 14, 16, 18, 20, 22,
- 24, 28, 32, 36, 40, 44, 48, 52,
- 56, 64, 72, 80, 88, 96, 104, 112
- };
-
- int i, j, k;
- mpeg2_decoder_t * decoder = &mpeg2dec->decoder;
-
- if (mpeg2dec->scaled[index] != mpeg2dec->q_scale_type)
- {
- mpeg2dec->scaled[index] = mpeg2dec->q_scale_type;
-
- for (i = 0; i < 32; i++)
- {
- k = mpeg2dec->q_scale_type ? non_linear_scale[i] : (i << 1);
-
- for (j = 0; j < 64; j++)
- {
- decoder->quantizer_prescale[index][i][j] =
- k * mpeg2dec->quantizer_matrix[index][j];
- }
- }
- }
-}
-
-mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_decoder_t * decoder = &mpeg2dec->decoder;
-
- mpeg2dec->info.user_data = NULL;
- mpeg2dec->info.user_data_len = 0;
- mpeg2dec->state = (mpeg2dec->picture->nb_fields > 1 ||
- mpeg2dec->state == STATE_PICTURE_2ND) ?
- STATE_SLICE : STATE_SLICE_1ST;
-
- if (mpeg2dec->decoder.coding_type != D_TYPE)
- {
- prescale (mpeg2dec, 0);
-
- if (decoder->chroma_quantizer[0] == decoder->quantizer_prescale[2])
- prescale (mpeg2dec, 2);
-
- if (mpeg2dec->decoder.coding_type != I_TYPE)
- {
- prescale (mpeg2dec, 1);
-
- if (decoder->chroma_quantizer[1] == decoder->quantizer_prescale[3])
- prescale (mpeg2dec, 3);
- }
- }
-
- if (!(mpeg2dec->nb_decode_slices))
- {
- mpeg2dec->picture->flags |= PIC_FLAG_SKIP;
- }
- else if (mpeg2dec->convert_start)
- {
- mpeg2dec->convert_start (decoder->convert_id, mpeg2dec->fbuf[0],
- mpeg2dec->picture, mpeg2dec->info.gop);
-
- if (mpeg2dec->decoder.coding_type == B_TYPE)
- {
- mpeg2_init_fbuf (&mpeg2dec->decoder, mpeg2dec->yuv_buf[2],
- mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1],
- mpeg2dec->yuv_buf[mpeg2dec->yuv_index]);
- }
- else
- {
- mpeg2_init_fbuf (&mpeg2dec->decoder,
- mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1],
- mpeg2dec->yuv_buf[mpeg2dec->yuv_index],
- mpeg2dec->yuv_buf[mpeg2dec->yuv_index]);
-
- if (mpeg2dec->state == STATE_SLICE)
- mpeg2dec->yuv_index ^= 1;
- }
- }
- else
- {
- int b_type;
-
- b_type = (mpeg2dec->decoder.coding_type == B_TYPE);
-
- mpeg2_init_fbuf (&mpeg2dec->decoder, mpeg2dec->fbuf[0]->buf,
- mpeg2dec->fbuf[b_type + 1]->buf,
- mpeg2dec->fbuf[b_type]->buf);
- }
-
- mpeg2dec->action = NULL;
-
- return STATE_INTERNAL_NORETURN;
-}
-
-static mpeg2_state_t seek_sequence (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_reset_info (&mpeg2dec->info);
-
- mpeg2dec->info.sequence = NULL;
- mpeg2dec->info.gop = NULL;
-
- mpeg2_header_state_init (mpeg2dec);
-
- mpeg2dec->action = mpeg2_seek_header;
-
- return mpeg2_seek_header (mpeg2dec);
-}
-
-mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec)
-{
- mpeg2_picture_t * picture;
- int b_type;
-
- b_type = (mpeg2dec->decoder.coding_type == B_TYPE);
- picture = mpeg2dec->pictures;
-
- if ((mpeg2dec->picture >= picture + 2) ^ b_type)
- picture = mpeg2dec->pictures + 2;
-
- mpeg2_reset_info (&mpeg2dec->info);
-
- if (!(mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY))
- {
- mpeg2dec->info.display_picture = picture;
-
- if (picture->nb_fields == 1)
- mpeg2dec->info.display_picture_2nd = picture + 1;
-
- mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[b_type];
-
- if (!mpeg2dec->convert)
- mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type + 1];
- }
- else if (!mpeg2dec->convert)
- {
- mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type];
- }
-
- mpeg2dec->action = seek_sequence;
-
- return STATE_END;
-}
diff --git a/apps/plugins/mpegplayer/libmpeg2/idct.c b/apps/plugins/mpegplayer/libmpeg2/idct.c
deleted file mode 100644
index 7f0b9a3c12..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/idct.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * idct.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.36
- */
-
-#include "plugin.h"
-
-#include "mpeg2dec_config.h"
-
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-
-#if defined(CPU_COLDFIRE) || defined (CPU_ARM)
-#define IDCT_ASM
-#endif
-
-#ifndef IDCT_ASM
-
-#define W1 2841 /* 2048 * sqrt (2) * cos (1 * pi / 16) */
-#define W2 2676 /* 2048 * sqrt (2) * cos (2 * pi / 16) */
-#define W3 2408 /* 2048 * sqrt (2) * cos (3 * pi / 16) */
-#define W5 1609 /* 2048 * sqrt (2) * cos (5 * pi / 16) */
-#define W6 1108 /* 2048 * sqrt (2) * cos (6 * pi / 16) */
-#define W7 565 /* 2048 * sqrt (2) * cos (7 * pi / 16) */
-
-/*
- * In legal streams, the IDCT output should be between -384 and +384.
- * In corrupted streams, it is possible to force the IDCT output to go
- * to +-3826 - this is the worst case for a column IDCT where the
- * column inputs are 16-bit values.
- */
-#define CLIP(i) \
- ({ typeof (i) _i = (i); \
- if ((_i & 0xff) != _i) \
- _i = ~(_i >> (8*sizeof(_i) - 1)); \
- _i; })
-
-#if 0
-#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
- do { \
- t0 = W0 * d0 + W1 * d1; \
- t1 = W0 * d1 - W1 * d0; \
- } while (0)
-#else
-#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
- do { \
- int tmp = W0 * (d0 + d1); \
- t0 = tmp + (W1 - W0) * d1; \
- t1 = tmp - (W1 + W0) * d0; \
- } while (0)
-#endif
-
-static inline void idct_row (int16_t * const block)
-{
- int d0, d1, d2, d3;
- int a0, a1, a2, a3, b0, b1, b2, b3;
- int t0, t1, t2, t3;
-
- /* shortcut */
- if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] |
- ((int32_t *)block)[3])))
- {
- uint32_t tmp = (uint16_t) (block[0] >> 1);
- tmp |= tmp << 16;
- ((int32_t *)block)[0] = tmp;
- ((int32_t *)block)[1] = tmp;
- ((int32_t *)block)[2] = tmp;
- ((int32_t *)block)[3] = tmp;
- return;
- }
-
- d0 = (block[0] << 11) + 2048;
- d1 = block[1];
- d2 = block[2] << 11;
- d3 = block[3];
- t0 = d0 + d2;
- t1 = d0 - d2;
- BUTTERFLY (t2, t3, W6, W2, d3, d1);
- a0 = t0 + t2;
- a1 = t1 + t3;
- a2 = t1 - t3;
- a3 = t0 - t2;
-
- d0 = block[4];
- d1 = block[5];
- d2 = block[6];
- d3 = block[7];
- BUTTERFLY (t0, t1, W7, W1, d3, d0);
- BUTTERFLY (t2, t3, W3, W5, d1, d2);
- b0 = t0 + t2;
- b3 = t1 + t3;
- t0 -= t2;
- t1 -= t3;
- b1 = ((t0 + t1) >> 8) * 181;
- b2 = ((t0 - t1) >> 8) * 181;
-
- block[0] = (a0 + b0) >> 12;
- block[1] = (a1 + b1) >> 12;
- block[2] = (a2 + b2) >> 12;
- block[3] = (a3 + b3) >> 12;
- block[4] = (a3 - b3) >> 12;
- block[5] = (a2 - b2) >> 12;
- block[6] = (a1 - b1) >> 12;
- block[7] = (a0 - b0) >> 12;
-}
-
-static inline void idct_col (int16_t * const block)
-{
- int d0, d1, d2, d3;
- int a0, a1, a2, a3, b0, b1, b2, b3;
- int t0, t1, t2, t3;
-
- d0 = (block[8*0] << 11) + 65536;
- d1 = block[8*1];
- d2 = block[8*2] << 11;
- d3 = block[8*3];
- t0 = d0 + d2;
- t1 = d0 - d2;
- BUTTERFLY (t2, t3, W6, W2, d3, d1);
- a0 = t0 + t2;
- a1 = t1 + t3;
- a2 = t1 - t3;
- a3 = t0 - t2;
-
- d0 = block[8*4];
- d1 = block[8*5];
- d2 = block[8*6];
- d3 = block[8*7];
- BUTTERFLY (t0, t1, W7, W1, d3, d0);
- BUTTERFLY (t2, t3, W3, W5, d1, d2);
- b0 = t0 + t2;
- b3 = t1 + t3;
- t0 -= t2;
- t1 -= t3;
- b1 = ((t0 + t1) >> 8) * 181;
- b2 = ((t0 - t1) >> 8) * 181;
-
- block[8*0] = (a0 + b0) >> 17;
- block[8*1] = (a1 + b1) >> 17;
- block[8*2] = (a2 + b2) >> 17;
- block[8*3] = (a3 + b3) >> 17;
- block[8*4] = (a3 - b3) >> 17;
- block[8*5] = (a2 - b2) >> 17;
- block[8*6] = (a1 - b1) >> 17;
- block[8*7] = (a0 - b0) >> 17;
-}
-
-void mpeg2_idct_copy (int16_t * block, uint8_t * dest,
- const int stride)
-{
- int i;
-
- for (i = 0; i < 8; i++)
- idct_row (block + 8 * i);
-
- for (i = 0; i < 8; i++)
- idct_col (block + i);
-
- do
- {
- dest[0] = CLIP (block[0]);
- dest[1] = CLIP (block[1]);
- dest[2] = CLIP (block[2]);
- dest[3] = CLIP (block[3]);
- dest[4] = CLIP (block[4]);
- dest[5] = CLIP (block[5]);
- dest[6] = CLIP (block[6]);
- dest[7] = CLIP (block[7]);
-
- ((int32_t *)block)[0] = 0;
- ((int32_t *)block)[1] = 0;
- ((int32_t *)block)[2] = 0;
- ((int32_t *)block)[3] = 0;
-
- dest += stride;
- block += 8;
- }
- while (--i);
-}
-
-void mpeg2_idct_add (const int last, int16_t * block,
- uint8_t * dest, const int stride)
-{
- int i;
-
- if (last != 129 || (block[0] & (7 << 4)) == (4 << 4))
- {
- for (i = 0; i < 8; i++)
- idct_row (block + 8 * i);
-
- for (i = 0; i < 8; i++)
- idct_col (block + i);
-
- do
- {
- dest[0] = CLIP (block[0] + dest[0]);
- dest[1] = CLIP (block[1] + dest[1]);
- dest[2] = CLIP (block[2] + dest[2]);
- dest[3] = CLIP (block[3] + dest[3]);
- dest[4] = CLIP (block[4] + dest[4]);
- dest[5] = CLIP (block[5] + dest[5]);
- dest[6] = CLIP (block[6] + dest[6]);
- dest[7] = CLIP (block[7] + dest[7]);
-
- ((int32_t *)block)[0] = 0;
- ((int32_t *)block)[1] = 0;
- ((int32_t *)block)[2] = 0;
- ((int32_t *)block)[3] = 0;
-
- dest += stride;
- block += 8;
- }
- while (--i);
- }
- else
- {
- int DC = (block[0] + 64) >> 7;
- block[0] = block[63] = 0;
- i = 8;
-
- do
- {
- dest[0] = CLIP (DC + dest[0]);
- dest[1] = CLIP (DC + dest[1]);
- dest[2] = CLIP (DC + dest[2]);
- dest[3] = CLIP (DC + dest[3]);
- dest[4] = CLIP (DC + dest[4]);
- dest[5] = CLIP (DC + dest[5]);
- dest[6] = CLIP (DC + dest[6]);
- dest[7] = CLIP (DC + dest[7]);
- dest += stride;
- }
- while (--i);
- }
-}
-
-#endif /* IDCT_ASM */
-
-void mpeg2_idct_init (void)
-{
- int i, j;
-
- for (i = 0; i < 64; i++)
- {
- j = default_mpeg2_scan_norm[i];
- mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
-
- j = default_mpeg2_scan_alt[i];
- mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
- }
-}
diff --git a/apps/plugins/mpegplayer/libmpeg2/idct_arm.S b/apps/plugins/mpegplayer/libmpeg2/idct_arm.S
deleted file mode 100644
index 97a87a8b59..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/idct_arm.S
+++ /dev/null
@@ -1,443 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2007 by Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include "config.h"
-
- .global mpeg2_idct_copy
- .type mpeg2_idct_copy, %function
- .global mpeg2_idct_add
- .type mpeg2_idct_add, %function
-
-
-/* Custom calling convention:
- * r0 contains block pointer and is non-volatile
- * all non-volatile c context saved and restored on its behalf
- */
-.idct:
- add r12, r0, #128
-1:
- ldrsh r1, [r0, #0] /* d0 */
- ldrsh r2, [r0, #2] /* d1 */
- ldrsh r3, [r0, #4] /* d2 */
- ldrsh r4, [r0, #6] /* d3 */
- ldrsh r5, [r0, #8] /* d0 */
- ldrsh r6, [r0, #10] /* d1 */
- ldrsh r7, [r0, #12] /* d2 */
- ldrsh r8, [r0, #14] /* d3 */
- orrs r9, r2, r3
- orreqs r9, r4, r5
- orreqs r9, r6, r7
- cmpeq r8, #0
- bne 2f
- mov r1, r1, asl #15
- bic r1, r1, #0x8000
- orr r1, r1, r1, lsr #16
- str r1, [r0], #4
- str r1, [r0], #4
- str r1, [r0], #4
- str r1, [r0], #4
- cmp r0, r12
- blo 1b
- b 3f
-2:
- mov r1, r1, asl #11 /* r1 = d0 = (block[0] << 11) + 2048 */
- add r1, r1, #2048
- add r1, r1, r3, asl #11 /* r1 = t0 = d0 + (block[2] << 11) */
- sub r3, r1, r3, asl #12 /* r3 = t1 = d0 - (block[2] << 11) */
-
- add r9, r2, r4 /* r9 = tmp = (d1+d3)*(1108/4) */
- add r10, r9, r9, asl #2
- add r10, r10, r9, asl #4
- add r9, r10, r9, asl #8
-
- add r10, r2, r2, asl #4 /* r2 = t2 = tmp + (d1*(1568/32)*8) */
- add r2, r10, r2, asl #5
- add r2, r9, r2, asl #3
-
- add r10, r4, r4, asl #2 /* r4 = t3 = tmp - (d3*(3784/8)*2) */
- rsb r10, r10, r4, asl #6
- add r4, r4, r10, asl #3
- sub r4, r9, r4, asl #1
- /* t2 & t3 are 1/4 final value here */
- add r1, r1, r2, asl #2 /* r1 = a0 = t0 + t2 */
- sub r2, r1, r2, asl #3 /* r2 = a3 = t0 - t2 */
- add r3, r3, r4, asl #2 /* r3 = a1 = t1 + t3 */
- sub r4, r3, r4, asl #3 /* r4 = a2 = t1 - t3 */
-
- add r9, r8, r5 /* r9 = tmp = 565*(d3 + d0) */
- add r10, r9, r9, asl #4
- add r10, r10, r10, asl #5
- add r9, r10, r9, asl #2
-
- add r10, r5, r5, asl #4 /* r5 = t0 = tmp + (((2276/4)*d0)*4) */
- add r10, r10, r10, asl #5
- add r5, r10, r5, asl #3
- add r5, r9, r5, asl #2
-
- add r10, r8, r8, asl #2 /* r8 = t1 = tmp - (((3406/2)*d3)*2) */
- add r10, r10, r10, asl #4
- add r10, r10, r8, asl #7
- rsb r8, r8, r10, asl #3
- sub r8, r9, r8, asl #1
-
- add r9, r6, r7 /* r9 = tmp = (2408/8)*(d1 + d2) */
- add r10, r9, r9, asl #3
- add r10, r10, r10, asl #5
- add r9, r10, r9, asl #2
-
- add r10, r7, r7, asl #3 /* r7 = t2 = (tmp*8) - 799*d2 */
- add r10, r10, r7, asl #4
- rsb r7, r7, r10, asl #5
- rsb r7, r7, r9, asl #3
-
- sub r10, r6, r6, asl #4 /* r6 = t3 = (tmp*8) - 4017*d1 */
- sub r10, r10, r6, asl #6
- add r10, r10, r6, asl #12
- add r6, r10, r6
- rsb r6, r6, r9, asl #3
- /* t0 = r5, t1 = r8, t2 = r7, t3 = r6*/
- add r9, r5, r7 /* r9 = b0 = t0 + t2 */
- add r10, r8, r6 /* r10 = b3 = t1 + t3 */
- sub r5, r5, r7 /* t0 -= t2 */
- sub r8, r8, r6 /* t1 -= t3 */
- add r6, r5, r8 /* r6 = t0 + t1 */
- sub r7, r5, r8 /* r7 = t0 - t1 */
-
- add r11, r6, r6, asr #2 /* r6 = b1 = r6*(181/128) */
- add r11, r11, r11, asr #5
- add r6, r11, r6, asr #3
- add r11, r7, r7, asr #2 /* r7 = b2 = r7*(181/128) */
- add r11, r11, r11, asr #5
- add r7, r11, r7, asr #3
- /* r1 = a0, r3 = a1, r4 = a2, r2 = a3 */
- /* r9 = b0, r6 = b1*2, r7 = b2*2, r10 = b3 */
- add r5, r1, r9 /* block[0] = (a0 + b0) >> 12 */
- mov r5, r5, asr #12
- strh r5, [r0], #2
- add r8, r3, r6, asr #1 /* block[1] = (a1 + b1) >> 12 */
- mov r8, r8, asr #12
- strh r8, [r0], #2
- add r5, r4, r7, asr #1 /* block[2] = (a2 + b2) >> 12 */
- mov r5, r5, asr #12
- strh r5, [r0], #2
- add r8, r2, r10 /* block[3] = (a3 + b3) >> 12 */
- mov r8, r8, asr #12
- strh r8, [r0], #2
- sub r5, r2, r10 /* block[4] = (a3 - b3) >> 12 */
- mov r5, r5, asr #12
- strh r5, [r0], #2
- sub r8, r4, r7, asr #1 /* block[5] = (a2 - b2) >> 12 */
- mov r8, r8, asr #12
- strh r8, [r0], #2
- sub r5, r3, r6, asr #1 /* block[6] = (a1 - b1) >> 12 */
- mov r5, r5, asr #12
- strh r5, [r0], #2
- sub r8, r1, r9 /* block[7] = (a0 - b0) >> 12 */
- mov r8, r8, asr #12
- strh r8, [r0], #2
- cmp r0, r12
- blo 1b
-3:
- sub r0, r0, #128
- add r12, r0, #16
-4:
- ldrsh r1, [r0, #0*8] /* d0 */
- ldrsh r2, [r0, #2*8] /* d1 */
- ldrsh r3, [r0, #4*8] /* d2 */
- ldrsh r4, [r0, #6*8] /* d3 */
- ldrsh r5, [r0, #8*8] /* d0 */
- ldrsh r6, [r0, #10*8] /* d1 */
- ldrsh r7, [r0, #12*8] /* d2 */
- ldrsh r8, [r0, #14*8] /* d3 */
-
- mov r1, r1, asl #11 /* r1 = d0 = (block[0] << 11) + 2048 */
- add r1, r1, #65536
- add r1, r1, r3, asl #11 /* r1 = t0 = d0 + d2:(block[2] << 11) */
- sub r3, r1, r3, asl #12 /* r3 = t1 = d0 - d2:(block[2] << 11) */
-
- add r9, r2, r4 /* r9 = tmp = (d1+d3)*(1108/4) */
- add r10, r9, r9, asl #2
- add r10, r10, r9, asl #4
- add r9, r10, r9, asl #8
-
- add r11, r2, r2, asl #4 /* r2 = t2 = tmp + (d1*(1568/32)*8) */
- add r2, r11, r2, asl #5
- add r2, r9, r2, asl #3
-
- add r10, r4, r4, asl #2 /* r4 = t3 = tmp - (d3*(3784/8)*2) */
- rsb r10, r10, r4, asl #6
- add r4, r4, r10, asl #3
- sub r4, r9, r4, asl #1
- /* t2 & t3 are 1/4 final value here */
- add r1, r1, r2, asl #2 /* r1 = a0 = t0 + t2 */
- sub r2, r1, r2, asl #3 /* r2 = a3 = t0 - t2 */
- add r3, r3, r4, asl #2 /* r3 = a1 = t1 + t3 */
- sub r4, r3, r4, asl #3 /* r4 = a2 = t1 - t3 */
-
- add r9, r8, r5 /* r9 = tmp = 565*(d3 + d0) */
- add r10, r9, r9, asl #4
- add r10, r10, r10, asl #5
- add r9, r10, r9, asl #2
-
- add r10, r5, r5, asl #4 /* r5 = t0 = tmp + (((2276/4)*d0)*4) */
- add r10, r10, r10, asl #5
- add r5, r10, r5, asl #3
- add r5, r9, r5, asl #2
-
- add r10, r8, r8, asl #2 /* r8 = t1 = tmp - (((3406/2)*d3)*2) */
- add r10, r10, r10, asl #4
- add r10, r10, r8, asl #7
- rsb r8, r8, r10, asl #3
- sub r8, r9, r8, asl #1
-
- add r9, r6, r7 /* r9 = tmp = (2408/8)*(d1 + d2) */
- add r10, r9, r9, asl #3
- add r10, r10, r10, asl #5
- add r9, r10, r9, asl #2
-
- add r10, r7, r7, asl #3 /* r7 = t2 = (tmp*8) - 799*d2 */
- add r10, r10, r7, asl #4
- rsb r7, r7, r10, asl #5
- rsb r7, r7, r9, asl #3
-
- sub r10, r6, r6, asl #4 /* r6 = t3 = (tmp*8) - 4017*d1 */
- sub r10, r10, r6, asl #6
- add r10, r10, r6, asl #12
- add r6, r10, r6
- rsb r6, r6, r9, asl #3
- /* t0=r5, t1=r8, t2=r7, t3=r6*/
- add r9, r5, r7 /* r9 = b0 = t0 + t2 */
- add r10, r8, r6 /* r10 = b3 = t1 + t3 */
- sub r5, r5, r7 /* t0 -= t2 */
- sub r8, r8, r6 /* t1 -= t3 */
- add r6, r5, r8 /* r6 = t0 + t1 */
- sub r7, r5, r8 /* r7 = t0 - t1 */
-
- add r11, r6, r6, asr #2 /* r6 = b1 = r5*(181/128) */
- add r11, r11, r11, asr #5
- add r6, r11, r6, asr #3
- add r11, r7, r7, asr #2 /* r7 = b2 = r6*(181/128) */
- add r11, r11, r11, asr #5
- add r7, r11, r7, asr #3
- /* r1 = a0, r3 = a1, r4 = a2, r2 = a3 */
- /* r9 = b0, r6 = b1*2, r7 = b2*2, r10 = b3 */
- add r5, r1, r9 /* block[0] = (a0 + b0) >> 17 */
- mov r5, r5, asr #17
- strh r5, [r0, #0*8]
- add r8, r3, r6, asr #1 /* block[1] = (a1 + b1) >> 17 */
- mov r8, r8, asr #17
- strh r8, [r0, #2*8]
- add r5, r4, r7, asr #1 /* block[2] = (a2 + b2) >> 17 */
- mov r5, r5, asr #17
- strh r5, [r0, #4*8]
- add r8, r2, r10 /* block[3] = (a3 + b3) >> 17 */
- mov r8, r8, asr #17
- strh r8, [r0, #6*8]
- sub r5, r2, r10 /* block[4] = (a3 - b3) >> 17 */
- mov r5, r5, asr #17
- strh r5, [r0, #8*8]
- sub r8, r4, r7, asr #1 /* block[5] = (a2 - b2) >> 17 */
- mov r8, r8, asr #17
- strh r8, [r0, #10*8]
- sub r5, r3, r6, asr #1 /* block[6] = (a1 - b1) >> 17 */
- mov r5, r5, asr #17
- strh r5, [r0, #12*8]
- sub r8, r1, r9 /* block[7] = (a0 - b0) >> 17 */
- mov r8, r8, asr #17
- strh r8, [r0, #14*8]
- add r0, r0, #2
- cmp r0, r12
- blo 4b
- sub r0, r0, #16
- bx lr
-
-mpeg2_idct_copy:
- stmfd sp!, { r1-r2, r4-r11, lr }
- bl .idct
- ldmfd sp!, { r1-r2 }
- mov r11, #0
- add r12, r0, #128
-1:
- ldrsh r3, [r0, #0]
- ldrsh r4, [r0, #2]
- ldrsh r5, [r0, #4]
- ldrsh r6, [r0, #6]
- ldrsh r7, [r0, #8]
- ldrsh r8, [r0, #10]
- ldrsh r9, [r0, #12]
- ldrsh r10, [r0, #14]
- cmp r3, #255
- mvnhi r3, r3, asr #31
- strb r3, [r1, #0]
- str r11, [r0], #4
- cmp r4, #255
- mvnhi r4, r4, asr #31
- strb r4, [r1, #1]
- cmp r5, #255
- mvnhi r5, r5, asr #31
- strb r5, [r1, #2]
- str r11, [r0], #4
- cmp r6, #255
- mvnhi r6, r6, asr #31
- strb r6, [r1, #3]
- cmp r7, #255
- mvnhi r7, r7, asr #31
- strb r7, [r1, #4]
- str r11, [r0], #4
- cmp r8, #255
- mvnhi r8, r8, asr #31
- strb r8, [r1, #5]
- cmp r9, #255
- mvnhi r9, r9, asr #31
- strb r9, [r1, #6]
- str r11, [r0], #4
- cmp r10, #255
- mvnhi r10, r10, asr #31
- strb r10, [r1, #7]
- add r1, r1, r2
- cmp r0, r12
- blo 1b
- ldmpc regs=r4-r11
-
-mpeg2_idct_add:
- cmp r0, #129
- mov r0, r1
- ldreqsh r1, [r0, #0]
- bne 1f
- and r1, r1, #0x70
- cmp r1, #0x40
- bne 3f
-1:
- stmfd sp!, { r2-r11, lr }
- bl .idct
- ldmfd sp!, { r1-r2 }
- mov r11, #0
- add r12, r0, #128
-2:
- ldrb r3, [r1, #0]
- ldrb r4, [r1, #1]
- ldrb r5, [r1, #2]
- ldrb r6, [r1, #3]
- ldrsh r7, [r0, #0]
- ldrsh r8, [r0, #2]
- ldrsh r9, [r0, #4]
- ldrsh r10, [r0, #6]
- add r7, r7, r3
- ldrb r3, [r1, #4]
- cmp r7, #255
- mvnhi r7, r7, asr #31
- strb r7, [r1, #0]
- ldrsh r7, [r0, #8]
- add r8, r8, r4
- ldrb r4, [r1, #5]
- cmp r8, #255
- mvnhi r8, r8, asr #31
- strb r8, [r1, #1]
- ldrsh r8, [r0, #10]
- add r9, r9, r5
- ldrb r5, [r1, #6]
- cmp r9, #255
- mvnhi r9, r9, asr #31
- strb r9, [r1, #2]
- ldrsh r9, [r0, #12]
- add r10, r10, r6
- ldrb r6, [r1, #7]
- cmp r10, #255
- mvnhi r10, r10, asr #31
- strb r10, [r1, #3]
- ldrsh r10, [r0, #14]
- str r11, [r0], #4
- add r7, r7, r3
- cmp r7, #255
- mvnhi r7, r7, asr #31
- strb r7, [r1, #4]
- str r11, [r0], #4
- add r8, r8, r4
- cmp r8, #255
- mvnhi r8, r8, asr #31
- strb r8, [r1, #5]
- str r11, [r0], #4
- add r9, r9, r5
- cmp r9, #255
- mvnhi r9, r9, asr #31
- strb r9, [r1, #6]
- add r10, r10, r6
- cmp r10, #255
- mvnhi r10, r10, asr #31
- strb r10, [r1, #7]
- str r11, [r0], #4
- add r1, r1, r2
- cmp r0, r12
- blo 2b
- ldmpc regs=r4-r11
-3:
- stmfd sp!, { r4-r5, lr }
- ldrsh r1, [r0, #0] /* r1 = block[0] */
- mov r4, #0
- strh r4, [r0, #0] /* block[0] = 0 */
- strh r4, [r0, #126] /* block[63] = 0 */
- add r1, r1, #64 /* r1 = DC << 7 */
- add r0, r2, r3, asl #3
-4:
- ldrb r4, [r2, #0]
- ldrb r5, [r2, #1]
- ldrb r12, [r2, #2]
- ldrb lr, [r2, #3]
- add r4, r4, r1, asr #7
- cmp r4, #255
- mvnhi r4, r4, asr #31
- strb r4, [r2, #0]
- add r5, r5, r1, asr #7
- cmp r5, #255
- mvnhi r5, r5, asr #31
- strb r5, [r2, #1]
- add r12, r12, r1, asr #7
- cmp r12, #255
- mvnhi r12, r12, asr #31
- strb r12, [r2, #2]
- add lr, lr, r1, asr #7
- cmp lr, #255
- mvnhi lr, lr, asr #31
- strb lr, [r2, #3]
- ldrb r4, [r2, #4]
- ldrb r5, [r2, #5]
- ldrb r12, [r2, #6]
- ldrb lr, [r2, #7]
- add r4, r4, r1, asr #7
- cmp r4, #255
- mvnhi r4, r4, asr #31
- strb r4, [r2, #4]
- add r5, r5, r1, asr #7
- cmp r5, #255
- mvnhi r5, r5, asr #31
- strb r5, [r2, #5]
- add r12, r12, r1, asr #7
- cmp r12, #255
- mvnhi r12, r12, asr #31
- strb r12, [r2, #6]
- add lr, lr, r1, asr #7
- cmp lr, #255
- mvnhi lr, lr, asr #31
- strb lr, [r2, #7]
- add r2, r2, r3
- cmp r2, r0
- blo 4b
- ldmpc regs=r4-r5
diff --git a/apps/plugins/mpegplayer/libmpeg2/idct_armv6.S b/apps/plugins/mpegplayer/libmpeg2/idct_armv6.S
deleted file mode 100644
index dc53cbd7bd..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/idct_armv6.S
+++ /dev/null
@@ -1,297 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2009 by Jens Arnold
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-
- .global mpeg2_idct_copy
- .type mpeg2_idct_copy, %function
- .global mpeg2_idct_add
- .type mpeg2_idct_add, %function
-
-/* Custom calling convention:
- * r0 contains block pointer and is non-volatile
- * all non-volatile c context saved and restored on its behalf
- */
-.idct:
- str lr, [sp, #-4]! @ lr is used
- add r1, r0, #128 @ secondary, transposed temp buffer
- mov r14, #8 @ loop counter
-
-.row_loop:
- ldmia r0!, {r2, r3, r10, r11} @ fetch f0, f2, f4, f6, f1, f3, f5, f7
- ldrd r4, L_W1357 @ load W1, W3, W5, W7
-
- smuad r6, r4, r10 @ b0 = W1 * f1 + W3 * f3
- smultt r7, r5, r10 @ -b1 = W7 * f3
- smulbt r8, r4, r10 @ -b2 = W1 * f3
-
- smusdx r9, r10, r5 @ b3 = f1 * W7 - f3 * W5
- smlabb r7, r4, r11, r7 @ -b1 += W1 * f5
- rsb r8, r8, #0 @ b2 = -b2
- smlabb r8, r5, r10, r8 @ b2 += W5 * f1
-
- smlad r6, r5, r11, r6 @ b0 += W5 * f5 + W7 * f7
- smlabt r7, r5, r11, r7 @ -b1 += W5 * f7
- smlatb r8, r5, r11, r8 @ b2 += W7 * f5
-
- smlsdx r9, r11, r4, r9 @ b3 += f5 * W3 - f7 * W1
- rsb r7, r7, #0 @ b1 = -b1
- smlatb r7, r4, r10, r7 @ b1 += W3 * f1
- smlatt r8, r4, r11, r8 @ b2 += W3 * f7
-
- ldrd r4, L_W0246 @ load W0, W2, W4, W6
- add r2, r2, #1 @ f0 += 1
-
- smulbb r10, r5, r3 @ a0' = W4 * f4
- smultt r12, r5, r3 @ a3' = W6 * f6
- smultt r3, r4, r3 @ -a2' = W2 * f6
-
- rsb r11, r10, #0 @ a1' = -W4 * f4
- smlabb r10, r4, r2, r10 @ a0' += W0 * f0
- smlabb r11, r4, r2, r11 @ a1' += W0 * f0
- smlatt r12, r4, r2, r12 @ a3' += W2 * f2
- rsb r3, r3, #0 @ a2' = -a2'
- smlatt r3, r5, r2, r3 @ a2' += W6 * f2
-
- add r10, r10, r12 @ a0 = a0' + a3'
- sub r12, r10, r12, lsl #1 @ a3 = a0 - 2 * a3'
- add r11, r11, r3 @ a1 = a1' + a2'
- sub r3, r11, r3, lsl #1 @ a2 = a1 - 2 * a2'
-
- subs r14, r14, #1 @ decrease loop count
-
- @ Special store order for making the column pass calculate columns in
- @ the order 0-2-1-3-4-6-5-7, allowing for uxtab16 use in later stages.
- sub r2, r10, r6 @ block[7] = (a0 - b0)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #7*16]
- sub r2, r11, r7 @ block[6] = (a1 - b1)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #5*16]
- sub r2, r3, r8 @ block[5] = (a2 - b2)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #6*16]
- sub r2, r12, r9 @ block[4] = (a3 - b3)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #4*16]
- add r2, r12, r9 @ block[3] = (a3 + b3)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #3*16]
- add r2, r3, r8 @ block[2] = (a2 + b2)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #1*16]
- add r2, r11, r7 @ block[1] = (a1 + b1)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1, #2*16]
- add r2, r10, r6 @ block[0] = (a0 + b0)
- mov r2, r2, asr #12 @ >> 12
- strh r2, [r1], #2 @ advance to next temp column
-
- bne .row_loop
- b .col_start
-
- @placed here because of ldrd's offset limit
-L_W1357:
- .short 2841
- .short 2408
- .short 1609
- .short 565
-
-L_W0246:
- .short 2048
- .short 2676
- .short 2048
- .short 1108
-
-.col_start:
- @ r0 now points to the temp buffer, where we need it.
- sub r1, r1, #128+16 @ point r1 back to the input block
- mov r14, #8 @ loop counter
-
-.col_loop:
- ldmia r0!, {r2, r3, r10, r11} @ fetch f0, f2, f4, f6, f1, f3, f5, f7
- ldrd r4, L_W1357 @ load W1, W3, W5, W7
-
- smuad r6, r4, r10 @ b0 = W1 * f1 + W3 * f3
- smultt r7, r5, r10 @ -b1 = W7 * f3
- smulbt r8, r4, r10 @ -b2 = W1 * f3
-
- smusdx r9, r10, r5 @ b3 = f1 * W7 - f3 * W5
- smlabb r7, r4, r11, r7 @ -b1 += W1 * f5
- rsb r8, r8, #0 @ b2 = -b2
- smlabb r8, r5, r10, r8 @ b2 += W5 * f1
-
- smlad r6, r5, r11, r6 @ b0 += W5 * f5 + W7 * f7
- smlabt r7, r5, r11, r7 @ -b1 += W5 * f7
- smlatb r8, r5, r11, r8 @ b2 += W7 * f5
-
- smlsdx r9, r11, r4, r9 @ b3 += f5 * W3 - f7 * W1
- rsb r7, r7, #0 @ b1 = -b1
- smlatb r7, r4, r10, r7 @ b1 += W3 * f1
- smlatt r8, r4, r11, r8 @ b2 += W3 * f7
-
- ldrd r4, L_W0246 @ load W0, W2, W4, W6
- add r2, r2, #32 @ DC offset: 0.5
-
- smulbb r10, r5, r3 @ a0' = W4 * f4
- smultt r12, r5, r3 @ a3' = W6 * f6
- smultt r3, r4, r3 @ -a2' = W2 * f6
-
- rsb r11, r10, #0 @ a1' = -W4 * f4
- smlabb r10, r4, r2, r10 @ a0' += W0 * f0
- smlabb r11, r4, r2, r11 @ a1' += W0 * f0
- smlatt r12, r4, r2, r12 @ a3' += W2 * f2
- rsb r3, r3, #0 @ a2' = -a2'
- smlatt r3, r5, r2, r3 @ a2' += W6 * f2
-
- add r10, r10, r12 @ a0 = a0' + a3'
- sub r12, r10, r12, lsl #1 @ a3 = a0 - 2 * a3'
- add r11, r11, r3 @ a1 = a1' + a2'
- sub r3, r11, r3, lsl #1 @ a2 = a1 - 2 * a2'
-
- subs r14, r14, #1 @ decrease loop count
-
- sub r2, r10, r6 @ block[7] = (a0 - b0)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #7*16]
- sub r2, r11, r7 @ block[6] = (a1 - b1)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #6*16]
- sub r2, r3, r8 @ block[5] = (a2 - b2)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #5*16]
- sub r2, r12, r9 @ block[4] = (a3 - b3)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #4*16]
- add r2, r12, r9 @ block[3] = (a3 + b3)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #3*16]
- add r2, r3, r8 @ block[2] = (a2 + b2)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #2*16]
- add r2, r11, r7 @ block[1] = (a1 + b1)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1, #1*16]
- add r2, r10, r6 @ block[0] = (a0 + b0)
- mov r2, r2, asr #17 @ >> 17
- strh r2, [r1], #2 @ advance to next column
-
- bne .col_loop
-
- sub r0, r0, #256 @ point r0 back to the input block
- ldr pc, [sp], #4
-
-
-mpeg2_idct_copy:
- stmfd sp!, {r1-r2, r4-r11, lr}
- bl .idct
- ldmfd sp!, {r1-r2}
-
- add r3, r0, #128
- mov r8, #0
- mov r9, #0
- mov r10, #0
- mov r11, #0
-1: @ idct data is in order 0-2-1-3-4-6-5-7,
- ldmia r0, {r4-r7} @ see above
- stmia r0!, {r8-r11}
- usat16 r4, #8, r4
- usat16 r5, #8, r5
- orr r4, r4, r5, lsl #8
- usat16 r6, #8, r6
- usat16 r7, #8, r7
- orr r5, r6, r7, lsl #8
- strd r4, [r1] @ r4, r5
- add r1, r1, r2
- cmp r0, r3
- blo 1b
-
- ldmfd sp!, {r4-r11, pc}
-
-mpeg2_idct_add:
- cmp r0, #129
- mov r0, r1
- ldreqsh r1, [r0, #0]
- bne 1f
- and r1, r1, #0x70
- cmp r1, #0x40
- bne 3f
-1:
- stmfd sp!, {r2-r11, lr}
- bl .idct
- ldmfd sp!, {r1-r2}
-
- add r3, r0, #128
- mov r10, #0
- mov r11, #0
- mov r12, #0
- mov lr, #0
- ldrd r8, [r1] @ r8, r9
-2: @ idct data is in order 0-2-1-3-4-6-5-7,
- ldmia r0, {r4-r7} @ see above
- stmia r0!, {r10-r12, lr}
- uxtab16 r4, r4, r8
- uxtab16 r5, r5, r8, ror #8
- usat16 r4, #8, r4
- usat16 r5, #8, r5
- orr r4, r4, r5, lsl #8
- uxtab16 r6, r6, r9
- uxtab16 r7, r7, r9, ror #8
- usat16 r6, #8, r6
- usat16 r7, #8, r7
- orr r5, r6, r7, lsl #8
- strd r4, [r1] @ r4, r5
- add r1, r1, r2
- cmp r0, r3
- ldrlod r8, [r1] @ r8, r9
- blo 2b
-
- ldmfd sp!, {r4-r11, pc}
-
-3:
- stmfd sp!, {r4, lr}
- ldrsh r4, [r0, #0] @ r4 = block[0]
- mov r12, #0
- strh r12, [r0, #0] @ block[0] = 0
- strh r12, [r0, #126] @ block[63] = 0
- add r4, r4, #64
- mov r4, r4, asr #7 @ r4 = DC
- mov r4, r4, lsl #16 @ spread to 2 halfwords
- orr r4, r4, r4, lsr #16
- ldrd r0, [r2] @ r0, r1
- add r12, r2, r3, asl #3
-4:
- uxtab16 lr, r4, r0, ror #8
- uxtab16 r0, r4, r0
- usat16 lr, #8, lr
- usat16 r0, #8, r0
- orr r0, r0, lr, lsl #8
- uxtab16 lr, r4, r1, ror #8
- uxtab16 r1, r4, r1
- usat16 lr, #8, lr
- usat16 r1, #8, r1
- orr r1, r1, lr, lsl #8
- strd r0, [r2] @ r0, r1
- add r2, r2, r3
- cmp r2, r12
- ldrlod r0, [r2] @ r0, r1
- blo 4b
-
- ldmfd sp!, {r4, pc}
diff --git a/apps/plugins/mpegplayer/libmpeg2/idct_coldfire.S b/apps/plugins/mpegplayer/libmpeg2/idct_coldfire.S
deleted file mode 100644
index abc54b16cb..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/idct_coldfire.S
+++ /dev/null
@@ -1,575 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2007 Jens Arnold
- * Based on the work of Karim Boucher and Rani Hod
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
- .global mpeg2_idct_copy
- .type mpeg2_idct_copy, @function
- .global mpeg2_idct_add
- .type mpeg2_idct_add, @function
-
- /* The IDCT itself.
- * Input: %a0: block pointer
- * Caller must save all registers. */
- .align 2
-.idct:
- move.l %a0, %a6
-
- move.l #0, %macsr | signed integer mode
-
- move.l #((2048<<16)+2841), %a0 | W0, W1
- move.l #((2676<<16)+2408), %a1 | W2, W3
- move.l #((2048<<16)+1609), %a2 | W4, W5
- move.l #((1108<<16)+ 565), %a3 | W6, W7
-
- lea.l (128,%a6), %a4 | secondary, transposed temp buffer
- moveq.l #8, %d3 | loop counter
-
-.row_loop:
- movem.l (%a6), %d0-%d2/%a5 | fetch (f0, f2, f4, f6, f1, f3, f5, f7)
-
- mac.w %a0l, %d2u, %acc0 | %acc0 = W1 * f1
- mac.w %a1l, %d2l, %acc0 | + W3 * f3
- mac.w %a2l, %a5u, %acc0 | + W5 * f5
- mac.w %a3l, %a5l, %acc0 | + W7 * f7
-
- mac.w %a1l, %d2u, %acc1 | %acc1 = W3 * f1
- msac.w %a3l, %d2l, %acc1 | - W7 * f3
- msac.w %a0l, %a5u, %acc1 | - W1 * f5
- msac.w %a2l, %a5l, %acc1 | - W5 * f7
-
- mac.w %a2l, %d2u, %acc2 | %acc2 = W5 * f1
- msac.w %a0l, %d2l, %acc2 | - W1 * f3
- mac.w %a3l, %a5u, %acc2 | + W7 * f5
- mac.w %a1l, %a5l, %acc2 | + W3 * f7
-
- mac.w %a3l, %d2u, %acc3 | %acc3 = W7 * f1
- msac.w %a2l, %d2l, %acc3 | - W5 * f3
- mac.w %a1l, %a5u, %acc3 | + W3 * f5
- msac.w %a0l, %a5l, %acc3 | - W1 * f7
-
- lea.l (16,%a6), %a6 | Advance to next row; put here to fill EMAC latency
- add.l #(1<<16), %d0 | f0 += 1;
-
- movclr.l %acc0, %d4 | b0
- movclr.l %acc1, %d5 | b1
- movclr.l %acc2, %d6 | b2
- movclr.l %acc3, %d7 | b3
-
- mac.w %a0u, %d0u, %acc0 | %acc0 = W0 * f0
- mac.w %a2u, %d1u, %acc0 | + W4 * f4
- move.l %acc0, %acc3
- mac.w %a1u, %d0l, %acc0 | + W2 * f2
- mac.w %a3u, %d1l, %acc0 | + W6 * f6
-
- mac.w %a0u, %d0u, %acc1 | %acc1 = W0 * f0
- msac.w %a2u, %d1u, %acc1 | - W4 * f4
- move.l %acc1, %acc2
- mac.w %a3u, %d0l, %acc1 | + W6 * f2
- msac.w %a1u, %d1l, %acc1 | - W2 * f6
-
- | ^ move.l %acc1, %acc2 %acc2 = W0 * f0 - W4 * f4
- msac.w %a3u, %d0l, %acc2 | - W6 * f2
- mac.w %a1u, %d1l, %acc2 | + W2 * f6
-
- | ^ move.l %acc0, %acc3 %acc3 = W0 * f0 + W4 * f4
- msac.w %a1u, %d0l, %acc3 | - W2 * f2
- msac.w %a3u, %d1l, %acc3 | - W6 * f6
-
- moveq.l #12, %d1 | shift amount
-
- move.l %acc0, %d0 | block[7] = (a0
- sub.l %d4,%d0 | - b0)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (7*16,%a4)
-
- move.l %acc1, %d0 | block[6] = (a1
- sub.l %d5,%d0 | - b1)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (6*16,%a4)
-
- move.l %acc2, %d0 | block[5] = (a2
- sub.l %d6,%d0 | - b2)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (5*16,%a4)
-
- move.l %acc3, %d0 | block[4] = (a3
- sub.l %d7,%d0 | - b3)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (4*16,%a4)
-
- movclr.l %acc3, %d0 | block[3] = (a3
- add.l %d7, %d0 | + b3)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (3*16,%a4)
-
- movclr.l %acc2, %d0 | block[2] = (a2
- add.l %d6, %d0 | + b2)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (2*16,%a4)
-
- movclr.l %acc1, %d0 | block[1] = (a1
- add.l %d5, %d0 | + b1)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (1*16,%a4)
-
- movclr.l %acc0, %d0 | block[0] = (a0
- add.l %d4, %d0 | + b0)
- asr.l %d1, %d0 | >> 12
- move.w %d0, (%a4)+ | advance to next temp column
-
- subq.l #1, %d3 | loop 8 times
- bne.w .row_loop
-
- | %a6 now points to the temp buffer, where we need it.
- lea.l (-16-128,%a4), %a4 | point %a4 back to the input block
- moveq.l #8, %d3 | loop counter
-
-.col_loop:
- movem.l (%a6), %d0-%d2/%a5 | fetch (f0, f2, f4, f6, f1, f3, f5, f7)
-
- mac.w %a0l, %d2u, %acc0 | %acc0 = W1 * f1
- mac.w %a1l, %d2l, %acc0 | + W3 * f3
- mac.w %a2l, %a5u, %acc0 | + W5 * f5
- mac.w %a3l, %a5l, %acc0 | + W7 * f7
-
- mac.w %a1l, %d2u, %acc1 | %acc1 = W3 * f1
- msac.w %a3l, %d2l, %acc1 | - W7 * f3
- msac.w %a0l, %a5u, %acc1 | - W1 * f5
- msac.w %a2l, %a5l, %acc1 | - W5 * f7
-
- mac.w %a2l, %d2u, %acc2 | %acc2 = W5 * f1
- msac.w %a0l, %d2l, %acc2 | - W1 * f3
- mac.w %a3l, %a5u, %acc2 | + W7 * f5
- mac.w %a1l, %a5l, %acc2 | + W3 * f7
-
- mac.w %a3l, %d2u, %acc3 | %acc3 = W7 * f1
- msac.w %a2l, %d2l, %acc3 | - W5 * f3
- mac.w %a1l, %a5u, %acc3 | + W3 * f5
- msac.w %a0l, %a5l, %acc3 | - W1 * f7
-
- lea.l (16,%a6), %a6 | Advance to next row; put here to fill EMAC latency
- add.l #(32<<16), %d0 | DC offset: 0.5
-
- movclr.l %acc0, %d4 | b0
- movclr.l %acc1, %d5 | b1
- movclr.l %acc2, %d6 | b2
- movclr.l %acc3, %d7 | b3
-
- mac.w %a0u, %d0u, %acc0 | %acc0 = W0 * f0
- mac.w %a2u, %d1u, %acc0 | + W4 * f4
- move.l %acc0, %acc3
- mac.w %a1u, %d0l, %acc0 | + W2 * f2
- mac.w %a3u, %d1l, %acc0 | + W6 * f6
-
- mac.w %a0u, %d0u, %acc1 | %acc1 = W0 * f0
- msac.w %a2u, %d1u, %acc1 | - W4 * f4
- move.l %acc1, %acc2
- mac.w %a3u, %d0l, %acc1 | + W6 * f2
- msac.w %a1u, %d1l, %acc1 | - W2 * f6
-
- | ^ move.l %acc1, %acc2 %acc2 = W0 * f0 - W4 * f4
- msac.w %a3u, %d0l, %acc2 | - W6 * f2
- mac.w %a1u, %d1l, %acc2 | + W2 * f6
-
- | ^ move.l %acc0, %acc3 %acc3 = W0 * f0 + W4 * f4
- msac.w %a1u, %d0l, %acc3 | - W2 * f2
- msac.w %a3u, %d1l, %acc3 | - W6 * f6
-
- moveq.l #17, %d1 | shift amount
-
- move.l %acc0, %d0 | block[7] = (a0
- sub.l %d4,%d0 | - b0)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (7*16,%a4)
-
- move.l %acc1, %d0 | block[6] = (a1
- sub.l %d5,%d0 | - b1)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (6*16,%a4)
-
- move.l %acc2, %d0 | block[5] = (a2
- sub.l %d6,%d0 | - b2)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (5*16,%a4)
-
- move.l %acc3, %d0 | block[4] = (a3
- sub.l %d7,%d0 | - b3)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (4*16,%a4)
-
- movclr.l %acc3, %d0 | block[3] = (a3
- add.l %d7, %d0 | + b3)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (3*16,%a4)
-
- movclr.l %acc2, %d0 | block[2] = (a2
- add.l %d6, %d0 | + b2)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (2*16,%a4)
-
- movclr.l %acc1, %d0 | block[1] = (a1
- add.l %d5, %d0 | + b1)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (1*16,%a4)
-
- movclr.l %acc0, %d0 | block[0] = (a0
- add.l %d4, %d0 | + b0)
- asr.l %d1, %d0 | >> 17
- move.w %d0, (%a4)+ | advance to next column
-
- subq.l #1, %d3 | loop 8 times
- bne.w .col_loop
-
- rts
-
- .align 2
-
-mpeg2_idct_copy:
- lea.l (-11*4,%sp), %sp
- movem.l %d2-%d7/%a2-%a6, (%sp) | save some registers
- move.l (11*4+4,%sp), %a0 | %a0 - block pointer for idct
-
- bsr.w .idct | apply idct to block
- movem.l (11*4+4,%sp), %a0-%a2 | %a0 - block pointer
- | %a1 - destination pointer
- | %a2 - stride
-
- move.l #255, %d1 | preload constant for clipping
- moveq.l #8, %d4 | loop counter
-
-.copy_clip_loop:
- move.w (%a0), %d0 | load block[0]
- ext.l %d0 | sign extend
- cmp.l %d1, %d0 | overflow?
- bls.b 1f
- spl.b %d0 | yes: set appropriate limit value in low byte
-1:
- move.b %d0, %d2 | collect output bytes 0..3 in %d2
- lsl.l #8, %d2
-
- move.w (2,%a0), %d0 | load block[1]
- ext.l %d0 | sign extend
- cmp.l %d1, %d0 | overflow?
- bls.b 1f
- spl.b %d0 | yes: set appropriate limit value in low byte
-1:
- move.b %d0, %d2 | collect output bytes 0..3 in %d2
- lsl.l #8, %d2
- clr.l (%a0)+ | clear block[0] and block[1],
- | %a0 now pointing to block[2]
- move.w (%a0), %d0 | do b2 and b3
- ext.l %d0
- cmp.l %d1, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.b %d0, %d2
- lsl.l #8, %d2
-
- move.w (2,%a0), %d0
- ext.l %d0
- cmp.l %d1, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.b %d0, %d2
- clr.l (%a0)+
-
- move.w (%a0), %d0 | do b4 and b5
- ext.l %d0
- cmp.l %d1, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.b %d0, %d3
- lsl.l #8, %d3
-
- move.w (2,%a0), %d0
- ext.l %d0
- cmp.l %d1, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.b %d0, %d3
- lsl.l #8, %d3
- clr.l (%a0)+
-
- move.w (%a0), %d0 | do b6 and b7
- ext.l %d0
- cmp.l %d1, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.b %d0, %d3
- lsl.l #8, %d3
-
- move.w (2,%a0), %d0
- ext.l %d0
- cmp.l %d1, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.b %d0, %d3
- clr.l (%a0)+
-
- movem.l %d2-%d3, (%a1) | write all 8 output bytes at once
- add.l %a2, %a1 | advance output pointer
- subq.l #1, %d4 | loop 8 times
- bne.w .copy_clip_loop
-
- movem.l (%sp), %d2-%d7/%a2-%a6
- lea.l (11*4,%sp), %sp
- rts
-
- .align 2
-
-mpeg2_idct_add:
- lea.l (-11*4,%sp), %sp
- movem.l %d2-%d7/%a2-%a6, (%sp)
- movem.l (11*4+4,%sp), %d0/%a0-%a2 | %d0 - last value
- | %a0 - block pointer
- | %a1 - destination pointer
- | %a2 - stride
-
- cmp.l #129, %d0 | last == 129 ?
- bne.b .idct_add | no: perform idct + addition
- move.w (%a0), %d0
- ext.l %d0 | ((block[0]
- asr.l #4, %d0 | >> 4)
- and.l #7, %d0 | & 7)
- subq.l #4, %d0 | - 4 == 0 ?
- bne.w .dc_add | no: just perform addition
-
-.idct_add:
- bsr.w .idct | apply idct
- movem.l (11*4+8,%sp), %a0-%a2 | reload arguments %a0..%a2
-
- move.l #255, %d2 | preload constant for clipping
- clr.l %d3 | used for splitting input words into bytes
- moveq.l #8, %d4 | loop counter
-
-.add_clip_loop:
- movem.l (%a1), %d6-%d7 | fetch (b0 b1 b2 b3) (b4 b5 b6 b7)
- swap %d6 | (b2 b3 b0 b1)
- swap %d7 | (b6 b7 b4 b5)
-
- move.w (2,%a0), %d0 | load block[1]
- ext.l %d0 | sign extend
- move.b %d6, %d3 | copy b1
- lsr.l #8, %d6 | prepare 1st buffer for next byte
- add.l %d3, %d0 | add b1
- cmp.l %d2, %d0 | overflow ?
- bls.b 1f
- spl.b %d0 | yes: set appropriate limit value in low byte
-1:
- move.w (%a0), %d1 | load block[0]
- ext.l %d1 | sign extend
- move.b %d6, %d3 | copy b0
- lsr.l #8, %d6 | prepare 1st buffer for next byte
- add.l %d3, %d1 | add b0
- cmp.l %d2, %d1 | overflow ?
- bls.b 1f
- spl.b %d1 | yes: set appropriate limit value in low byte
-1:
- move.b %d1, %d5 | collect output bytes 0..3 in %d5
- lsl.l #8, %d5
- move.b %d0, %d5
- lsl.l #8, %d5
- clr.l (%a0)+ | clear block[0] and block[1]
- | %a0 now pointing to block[2]
- move.w (2,%a0), %d0 | do b3 and b2
- ext.l %d0
- move.b %d6, %d3
- lsr.l #8, %d6
- add.l %d3, %d0
- cmp.l %d2, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.w (%a0), %d1
- ext.l %d1
- add.l %d6, %d1
- cmp.l %d2, %d1
- bls.b 1f
- spl.b %d1
-1:
- move.b %d1, %d5
- lsl.l #8, %d5
- move.b %d0, %d5
- clr.l (%a0)+
-
- move.w (2,%a0), %d0 | do b5 and b4
- ext.l %d0
- move.b %d7, %d3
- lsr.l #8, %d7
- add.l %d3, %d0
- cmp.l %d2, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.w (%a0), %d1
- ext.l %d1
- move.b %d7, %d3
- lsr.l #8, %d7
- add.l %d3, %d1
- cmp.l %d2, %d1
- bls.b 1f
- spl.b %d1
-1:
- move.b %d1, %d6
- lsl.l #8, %d6
- move.b %d0, %d6
- lsl.l #8, %d6
- clr.l (%a0)+
-
- move.w (2,%a0), %d0 | do b7 and b6
- ext.l %d0
- move.b %d7, %d3
- lsr.l #8, %d7
- add.l %d3, %d0
- cmp.l %d2, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.w (%a0), %d1
- ext.l %d1
- add.l %d7, %d1
- cmp.l %d2, %d1
- bls.b 1f
- spl.b %d1
-1:
- move.b %d1, %d6
- lsl.l #8, %d6
- move.b %d0, %d6
- clr.l (%a0)+
-
- movem.l %d5-%d6, (%a1) | write all 8 output bytes at once
- add.l %a2, %a1 | advance output pointer
- subq.l #1, %d4 | loop 8 times
- bne.w .add_clip_loop
-
- bra.w .idct_add_end
-
-.dc_add:
- move.w (%a0), %d0
- ext.l %d0 | %d0 = (block[0]
- add.l #64, %d0 | + 64)
- asr.l #7, %d0 | >> 7
- clr.w (%a0) | clear block[0]
- clr.w (63*2,%a0) | and block[63]
- move.l %d0, %a0 | DC value in %a0
-
- move.l #255, %d2 | preload constant for clipping
- clr.l %d3 | for splitting input words into bytes
- moveq.l #8, %d4 | loop counter
-
-.dc_clip_loop:
- movem.l (%a1), %d6-%d7 | (b0 b1 b2 b3) (b4 b5 b6 b7)
- swap %d6 | (b2 b3 b0 b1)
- swap %d7 | (b6 b7 b4 b5)
-
- move.l %a0, %d0 | copy DC
- move.b %d6, %d3 | copy b1
- lsr.l #8, %d6 | prepare 1st buffer for next byte
- add.l %d3, %d0 | add b1
- cmp.l %d2, %d0 | overflow ?
- bls.b 1f
- spl.b %d0 | yes: set appropriate limit value in low byte
-1:
- move.l %a0, %d1 | copy DC
- move.b %d6, %d3 | copy b0
- lsr.l #8, %d6 | prepare 1st buffer for next byte
- add.l %d3, %d1 | add b0
- cmp.l %d2, %d1 | overflow ?
- bls.b 1f
- spl.b %d1 | yes: set appropriate limit value in low byte
-1:
- move.b %d1, %d5 | collect output bytes 0..3 in %d5
- lsl.l #8, %d5
- move.b %d0, %d5
- lsl.l #8, %d5
-
- move.l %a0, %d0 | do b3 and b2
- move.b %d6, %d3
- lsr.l #8, %d6
- add.l %d3, %d0
- cmp.l %d2, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.l %a0, %d1
- add.l %d6, %d1
- cmp.l %d2, %d1
- bls.b 1f
- spl.b %d1
-1:
- move.b %d1, %d5
- lsl.l #8, %d5
- move.b %d0, %d5
-
- move.l %a0, %d0 | do b5 and b4
- move.b %d7, %d3
- lsr.l #8, %d7
- add.l %d3, %d0
- cmp.l %d2, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.l %a0, %d1
- move.b %d7, %d3
- lsr.l #8, %d7
- add.l %d3, %d1
- cmp.l %d2, %d1
- bls.b 1f
- spl.b %d1
-1:
- move.b %d1, %d6 | do b7 and b6
- lsl.l #8, %d6
- move.b %d0, %d6
- lsl.l #8, %d6
-
- move.l %a0, %d0
- move.b %d7, %d3
- lsr.l #8, %d7
- add.l %d3, %d0
- cmp.l %d2, %d0
- bls.b 1f
- spl.b %d0
-1:
- move.l %a0, %d1
- add.l %d7, %d1
- cmp.l %d2, %d1
- bls.b 1f
- spl.b %d1
-1:
- move.b %d1, %d6
- lsl.l #8, %d6
- move.b %d0, %d6
-
- movem.l %d5-%d6, (%a1) | write all 8 output bytes at once
- add.l %a2, %a1 | advance output pointer
- subq.l #1, %d4 | loop 8 times
- bne.w .dc_clip_loop
-
-.idct_add_end:
- movem.l (%sp), %d2-%d7/%a2-%a6
- lea.l (11*4,%sp), %sp
- rts
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp.c b/apps/plugins/mpegplayer/libmpeg2/motion_comp.c
deleted file mode 100644
index d6968f68ce..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * motion_comp.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.17 - lost compatibility previously to
- * provide simplified and CPU-optimized motion compensation.
- */
-
-#include "plugin.h"
-
-#include "mpeg2dec_config.h"
-
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-
-/* These are defined in their respective target files - motion_comp_X.c */
-extern mpeg2_mc_fct MC_put_o_16;
-extern mpeg2_mc_fct MC_put_o_8;
-extern mpeg2_mc_fct MC_put_x_16;
-extern mpeg2_mc_fct MC_put_x_8;
-extern mpeg2_mc_fct MC_put_y_16;
-extern mpeg2_mc_fct MC_put_y_8;
-extern mpeg2_mc_fct MC_put_xy_16;
-extern mpeg2_mc_fct MC_put_xy_8;
-
-extern mpeg2_mc_fct MC_avg_o_16;
-extern mpeg2_mc_fct MC_avg_o_8;
-extern mpeg2_mc_fct MC_avg_x_16;
-extern mpeg2_mc_fct MC_avg_x_8;
-extern mpeg2_mc_fct MC_avg_y_16;
-extern mpeg2_mc_fct MC_avg_y_8;
-extern mpeg2_mc_fct MC_avg_xy_16;
-extern mpeg2_mc_fct MC_avg_xy_8;
-
-const mpeg2_mc_t mpeg2_mc =
-{
- {
- MC_put_o_16, MC_put_x_16, MC_put_y_16, MC_put_xy_16,
- MC_put_o_8, MC_put_x_8, MC_put_y_8, MC_put_xy_8
- },
- {
- MC_avg_o_16, MC_avg_x_16, MC_avg_y_16, MC_avg_xy_16,
- MC_avg_o_8, MC_avg_x_8, MC_avg_y_8, MC_avg_xy_8
- }
-};
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp.h b/apps/plugins/mpegplayer/libmpeg2/motion_comp.h
deleted file mode 100644
index 4737e72cab..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * motion_comp.h
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- */
-
-
-#define avg2(a,b) ((a+b+1)>>1)
-#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
-
-#define predict_o(i) (ref[i])
-#define predict_x(i) (avg2 (ref[i], ref[i+1]))
-#define predict_y(i) (avg2 (ref[i], (ref+stride)[i]))
-#define predict_xy(i) (avg4 (ref[i], ref[i+1], \
- (ref+stride)[i], (ref+stride)[i+1]))
-
-#define put(predictor,i) dest[i] = predictor (i)
-#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i])
-
-/* mc function template */
-#define MC_FUNC(op, xy) \
- MC_FUNC_16(op, xy) \
- MC_FUNC_8(op, xy)
-
-#define MC_FUNC_16(op, xy) \
- void MC_##op##_##xy##_16 (uint8_t * dest, const uint8_t * ref, \
- const int stride, int height) \
- { \
- do { \
- op (predict_##xy, 0); \
- op (predict_##xy, 1); \
- op (predict_##xy, 2); \
- op (predict_##xy, 3); \
- op (predict_##xy, 4); \
- op (predict_##xy, 5); \
- op (predict_##xy, 6); \
- op (predict_##xy, 7); \
- op (predict_##xy, 8); \
- op (predict_##xy, 9); \
- op (predict_##xy, 10); \
- op (predict_##xy, 11); \
- op (predict_##xy, 12); \
- op (predict_##xy, 13); \
- op (predict_##xy, 14); \
- op (predict_##xy, 15); \
- ref += stride; \
- dest += stride; \
- } while (--height); \
- }
-
-#define MC_FUNC_8(op, xy) \
- void MC_##op##_##xy##_8 (uint8_t * dest, const uint8_t * ref, \
- const int stride, int height) \
- { \
- do { \
- op (predict_##xy, 0); \
- op (predict_##xy, 1); \
- op (predict_##xy, 2); \
- op (predict_##xy, 3); \
- op (predict_##xy, 4); \
- op (predict_##xy, 5); \
- op (predict_##xy, 6); \
- op (predict_##xy, 7); \
- ref += stride; \
- dest += stride; \
- } while (--height); \
- }
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp_arm_c.c b/apps/plugins/mpegplayer/libmpeg2/motion_comp_arm_c.c
deleted file mode 100644
index dcf1df53e9..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp_arm_c.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * motion_comp_arm.c
- * Copyright (C) 2004 AGAWA Koji
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- */
-#include
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-#include "motion_comp.h"
-
-/* definitions of the actual mc functions */
-
-/* MC_FUNC (put, o) <= ASM */
-MC_FUNC (avg, o)
-/* MC_FUNC (put, x) <= ASM */
-MC_FUNC (avg, x)
-MC_FUNC (put, y)
-MC_FUNC (avg, y)
-MC_FUNC (put, xy)
-MC_FUNC (avg, xy)
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp_arm_s.S b/apps/plugins/mpegplayer/libmpeg2/motion_comp_arm_s.S
deleted file mode 100644
index 1ec1b0686e..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp_arm_s.S
+++ /dev/null
@@ -1,342 +0,0 @@
-@ motion_comp_arm_s.S
-@ Copyright (C) 2004 AGAWA Koji
-@
-@ This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
-@ See http://libmpeg2.sourceforge.net/ for updates.
-@
-@ mpeg2dec is free software; you can redistribute it and/or modify
-@ it under the terms of the GNU General Public License as published by
-@ the Free Software Foundation; either version 2 of the License, or
-@ (at your option) any later version.
-@
-@ mpeg2dec is distributed in the hope that it will be useful,
-@ but WITHOUT ANY WARRANTY; without even the implied warranty of
-@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-@ GNU General Public License for more details.
-@
-@ You should have received a copy of the GNU General Public License
-@ along with this program; if not, write to the Free Software
-@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-@
-@ $Id$
-
-#include "config.h" /* Rockbox: ARM architecture version */
-
- .text
-
-@ ----------------------------------------------------------------
- .align
- .global MC_put_o_16
-MC_put_o_16:
- @@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
- @@ pld [r1]
- stmfd sp!, {r4-r7, lr} @ R14 is also called LR
- and r4, r1, #3
- ldr pc, [pc, r4, lsl #2]
- .word 0
- .word MC_put_o_16_align0
- .word MC_put_o_16_align1
- .word MC_put_o_16_align2
- .word MC_put_o_16_align3
-
-MC_put_o_16_align0:
- ldmia r1, {r4-r7}
- add r1, r1, r2
- @@ pld [r1]
- stmia r0, {r4-r7}
- subs r3, r3, #1
- add r0, r0, r2
- bne MC_put_o_16_align0
- ldmpc regs=r4-r7 @@ update PC with LR content.
-
-.macro ADJ_ALIGN_QW shift, R0, R1, R2, R3, R4
- mov \R0, \R0, lsr #(\shift)
- orr \R0, \R0, \R1, lsl #(32 - \shift)
- mov \R1, \R1, lsr #(\shift)
- orr \R1, \R1, \R2, lsl #(32 - \shift)
- mov \R2, \R2, lsr #(\shift)
- orr \R2, \R2, \R3, lsl #(32 - \shift)
- mov \R3, \R3, lsr #(\shift)
- orr \R3, \R3, \R4, lsl #(32 - \shift)
- mov \R4, \R4, lsr #(\shift)
-.endm
-
-MC_put_o_16_align1:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4-r7, r12}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_QW 8, r4, r5, r6, r7, r12
- stmia r0, {r4-r7}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-r7 @@ update PC with LR content.
-
-MC_put_o_16_align2:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4-r7, r12}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_QW 16, r4, r5, r6, r7, r12
- stmia r0, {r4-r7}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-r7 @@ update PC with LR content.
-
-MC_put_o_16_align3:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4-r7, r12}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_QW 24, r4, r5, r6, r7, r12
- stmia r0, {r4-r7}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-r7 @@ update PC with LR content.
-
-@ ----------------------------------------------------------------
- .align
- .global MC_put_o_8
-MC_put_o_8:
- @@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
- @@ pld [r1]
- stmfd sp!, {r4, r5, lr} @ R14 is also called LR
- and r4, r1, #3
- ldr pc, [pc, r4, lsl #2]
- .word 0
- .word MC_put_o_8_align0
- .word MC_put_o_8_align1
- .word MC_put_o_8_align2
- .word MC_put_o_8_align3
-
-MC_put_o_8_align0:
- ldmia r1, {r4, r5}
- add r1, r1, r2
- @@ pld [r1]
- stmia r0, {r4, r5}
- add r0, r0, r2
- subs r3, r3, #1
- bne MC_put_o_8_align0
- ldmpc regs=r4-r5 @@ update PC with LR content.
-
-.macro ADJ_ALIGN_DW shift, R0, R1, R2
- mov \R0, \R0, lsr #(\shift)
- orr \R0, \R0, \R1, lsl #(32 - \shift)
- mov \R1, \R1, lsr #(\shift)
- orr \R1, \R1, \R2, lsl #(32 - \shift)
- mov \R2, \R2, lsr #(\shift)
-.endm
-
-MC_put_o_8_align1:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4, r5, r12}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_DW 8, r4, r5, r12
- stmia r0, {r4, r5}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-r5 @@ update PC with LR content.
-
-MC_put_o_8_align2:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4, r5, r12}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_DW 16, r4, r5, r12
- stmia r0, {r4, r5}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-r5 @@ update PC with LR content.
-
-MC_put_o_8_align3:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4, r5, r12}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_DW 24, r4, r5, r12
- stmia r0, {r4, r5}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-r5 @@ update PC with LR content.
-
-@ ----------------------------------------------------------------
-.macro AVG_PW rW1, rW2
- mov \rW2, \rW2, lsl #24
- orr \rW2, \rW2, \rW1, lsr #8
- eor r9, \rW1, \rW2
-#if ARM_ARCH >= 6
- uhadd8 \rW2, \rW1, \rW2
-#else
- and \rW2, \rW1, \rW2
- and r10, r9, r11
- add \rW2, \rW2, r10, lsr #1
-#endif
- and r9, r9, r12
- add \rW2, \rW2, r9
-.endm
-
-#if ARM_ARCH >= 6
-#define HIGHEST_REG r9
-#else
-#define HIGHEST_REG r11
-#endif
-
- .align
- .global MC_put_x_16
-MC_put_x_16:
- @@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
- @@ pld [r1]
- stmfd sp!, {r4-HIGHEST_REG, lr} @ R14 is also called LR
- and r4, r1, #3
- ldr r12, 2f
-#if ARM_ARCH < 6
- mvn r11, r12
-#endif
- ldr pc, [pc, r4, lsl #2]
-2: .word 0x01010101
- .word MC_put_x_16_align0
- .word MC_put_x_16_align1
- .word MC_put_x_16_align2
- .word MC_put_x_16_align3
-
-MC_put_x_16_align0:
- ldmia r1, {r4-r8}
- add r1, r1, r2
- @@ pld [r1]
- AVG_PW r7, r8
- AVG_PW r6, r7
- AVG_PW r5, r6
- AVG_PW r4, r5
- stmia r0, {r5-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne MC_put_x_16_align0
- ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
-
-MC_put_x_16_align1:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4-r8}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_QW 8, r4, r5, r6, r7, r8
- AVG_PW r7, r8
- AVG_PW r6, r7
- AVG_PW r5, r6
- AVG_PW r4, r5
- stmia r0, {r5-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
-
-MC_put_x_16_align2:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4-r8}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_QW 16, r4, r5, r6, r7, r8
- AVG_PW r7, r8
- AVG_PW r6, r7
- AVG_PW r5, r6
- AVG_PW r4, r5
- stmia r0, {r5-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
-
-MC_put_x_16_align3:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r4-r8}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_QW 24, r4, r5, r6, r7, r8
- AVG_PW r7, r8
- AVG_PW r6, r7
- AVG_PW r5, r6
- AVG_PW r4, r5
- stmia r0, {r5-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
-
-@ ----------------------------------------------------------------
- .align
- .global MC_put_x_8
-MC_put_x_8:
- @@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
- @@ pld [r1]
- stmfd sp!, {r6-HIGHEST_REG, lr} @ R14 is also called LR
- and r6, r1, #3
- ldr r12, 2f
-#if ARM_ARCH < 6
- mvn r11, r12
-#endif
- ldr pc, [pc, r6, lsl #2]
-2: .word 0x01010101
- .word MC_put_x_8_align0
- .word MC_put_x_8_align1
- .word MC_put_x_8_align2
- .word MC_put_x_8_align3
-
-MC_put_x_8_align0:
- ldmia r1, {r6-r8}
- add r1, r1, r2
- @@ pld [r1]
- AVG_PW r7, r8
- AVG_PW r6, r7
- stmia r0, {r7-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne MC_put_x_8_align0
- ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
-
-MC_put_x_8_align1:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r6-r8}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_DW 8, r6, r7, r8
- AVG_PW r7, r8
- AVG_PW r6, r7
- stmia r0, {r7-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
-
-MC_put_x_8_align2:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r6-r8}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_DW 16, r6, r7, r8
- AVG_PW r7, r8
- AVG_PW r6, r7
- stmia r0, {r7-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
-
-MC_put_x_8_align3:
- and r1, r1, #0xFFFFFFFC
-1: ldmia r1, {r6-r8}
- add r1, r1, r2
- @@ pld [r1]
- ADJ_ALIGN_DW 24, r6, r7, r8
- AVG_PW r7, r8
- AVG_PW r6, r7
- stmia r0, {r7-r8}
- subs r3, r3, #1
- add r0, r0, r2
- bne 1b
- ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp_c.c b/apps/plugins/mpegplayer/libmpeg2/motion_comp_c.c
deleted file mode 100644
index 9a8640e7e6..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp_c.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * motion_comp.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- */
-#include
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-#include "motion_comp.h"
-
-/* definitions of the actual mc functions */
-
-MC_FUNC (put, o)
-MC_FUNC (avg, o)
-MC_FUNC (put, x)
-MC_FUNC (avg, x)
-MC_FUNC (put, y)
-MC_FUNC (avg, y)
-MC_FUNC (put, xy)
-MC_FUNC (avg, xy)
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp_coldfire_c.c b/apps/plugins/mpegplayer/libmpeg2/motion_comp_coldfire_c.c
deleted file mode 100644
index b97e3510e7..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp_coldfire_c.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Based on:
- * motion_comp_arm.c
- * Copyright (C) 2004 AGAWA Koji
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-#include "motion_comp.h"
-
-/* definitions of the actual mc functions */
-
-/* MC_FUNC (put, o) <= ASM */
-MC_FUNC (avg, o)
-/* MC_FUNC (put, x) <= ASM */
-MC_FUNC (avg, x)
-MC_FUNC (put, y)
-MC_FUNC (avg, y)
-MC_FUNC (put, xy)
-MC_FUNC (avg, xy)
diff --git a/apps/plugins/mpegplayer/libmpeg2/motion_comp_coldfire_s.S b/apps/plugins/mpegplayer/libmpeg2/motion_comp_coldfire_s.S
deleted file mode 100644
index 55d87cb708..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/motion_comp_coldfire_s.S
+++ /dev/null
@@ -1,436 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2007 Jens Arnold
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-.macro LEFT8_PW dW1, dW2 | needs %d0 == 24, clobbers %d2
- lsl.l #8, \dW1 | changes dW1, keeps dW2
- move.l \dW2, %d2
- lsr.l %d0, %d2
- or.l %d2, \dW1
-.endm
-
-.macro LEFT24_PW dW1, dW2 | needs %d0 == 24, clobbers %d2
- lsl.l %d0, \dW1 | changes dW1, keeps dW2
- move.l \dW2, %d2
- lsr.l #8, %d2
- or.l %d2, \dW1
-.endm
-
-/*****************************************************************************/
-
- .align 2
- .global MC_put_o_8
- .type MC_put_o_8, @function
-
-MC_put_o_8:
- movem.l (4,%sp), %a0-%a1 | dest, source
- move.l %a1, %d0
- and.l #3, %d0
- sub.l %d0, %a1 | align source
- jmp.l (2, %pc, %d0.l*4)
- bra.w .po8_0
- bra.w .po8_1
- bra.w .po8_2
- | last table entry coincides with target
-
-.po8_3:
- lea.l (-5*4,%sp), %sp
- movem.l %d2-%d5/%a2, (%sp) | save some registers
- move.l (5*4+12,%sp), %a2 | stride
- move.l (5*4+16,%sp), %d1 | height
- moveq.l #24, %d0 | shift amount
-1:
- movem.l (%a1), %d3-%d5
- add.l %a2, %a1
- LEFT24_PW %d3, %d4
- lsl.l %d0, %d4
- lsr.l #8, %d5
- or.l %d5, %d4
- movem.l %d3-%d4, (%a0)
- add.l %a2, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d5/%a2
- lea.l (5*4,%sp), %sp
- rts
-
-.po8_2:
- lea.l (-3*4,%sp), %sp
- movem.l %d2-%d4, (%sp) | save some registers
- movem.l (3*4+12,%sp), %d0-%d1 | stride, height
-1:
- movem.l (%a1), %d2-%d4
- add.l %d0, %a1
- swap %d2
- swap %d3
- move.w %d3, %d2
- swap %d4
- move.w %d4, %d3
- movem.l %d2-%d3, (%a0)
- add.l %d0, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d4
- lea.l (3*4,%sp), %sp
- rts
-
-.po8_1:
- lea.l (-5*4,%sp), %sp
- movem.l %d2-%d5/%a2, (%sp) | save some registers
- move.l (5*4+12,%sp), %a2 | stride
- move.l (5*4+16,%sp), %d1 | height
- moveq.l #24, %d0 | shift amount
-1:
- movem.l (%a1), %d3-%d5
- add.l %a2, %a1
- LEFT8_PW %d3, %d4
- lsl.l #8, %d4
- lsr.l %d0, %d5
- or.l %d5, %d4
- movem.l %d3-%d4, (%a0)
- add.l %a2, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d5/%a2
- lea.l (5*4,%sp), %sp
- rts
-
-.po8_0:
- movem.l (12,%sp), %d0-%d1 | stride, height
- subq.l #4, %d0 | adjust for increment within the loop
-1:
- move.l (%a1)+, (%a0)+
- move.l (%a1), (%a0)
- add.l %d0, %a0
- add.l %d0, %a1
- subq.l #1, %d1
- bne.s 1b
- rts
-
-/*****************************************************************************/
-
- .align 2
- .global MC_put_o_16
- .type MC_put_o_16, @function
-
-MC_put_o_16:
- lea.l (-7*4,%sp), %sp
- movem.l %d2-%d7/%a2, (%sp) | save some registers
- movem.l (7*4+4,%sp), %a0-%a2| dest, source, stride
- move.l (7*4+16,%sp), %d1 | height
- move.l %a1, %d0
- and.l #3, %d0
- sub.l %d0, %a1
- jmp.l (2, %pc, %d0.l*4)
- bra.w .po16_0
- bra.w .po16_1
- bra.w .po16_2
- | last table entry coincides with target
-
-.po16_3:
- moveq.l #24, %d0 | shift amount
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- LEFT24_PW %d3, %d4
- LEFT24_PW %d4, %d5
- LEFT24_PW %d5, %d6
- lsl.l %d0, %d6
- lsr.l #8, %d7
- or.l %d7, %d6
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d7/%a2
- lea.l (7*4,%sp), %sp
- rts
-
-.po16_2:
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- swap %d3
- swap %d4
- move.w %d4, %d3
- swap %d5
- move.w %d5, %d4
- swap %d6
- move.w %d6, %d5
- swap %d7
- move.w %d7, %d6
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d7/%a2
- lea.l (7*4,%sp), %sp
- rts
-
-.po16_1:
- moveq.l #24, %d0 | shift amount
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- LEFT8_PW %d3, %d4
- LEFT8_PW %d4, %d5
- LEFT8_PW %d5, %d6
- lsl.l #8, %d6
- lsr.l %d0, %d7
- or.l %d7, %d6
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d7/%a2
- lea.l (7*4,%sp), %sp
- rts
-
-.po16_0:
-1:
- movem.l (%a1), %d3-%d6
- add.l %a2, %a1
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %d1
- bne.s 1b
- movem.l (%sp), %d2-%d7/%a2
- lea.l (7*4,%sp), %sp
- rts
-
-/*****************************************************************************/
-
-.macro AVG_PW dW1, dW2 | needs %d0 == 24, clobbers %d1, %d2,
- move.l \dW1, %d1 | changes dW1, keeps dW2
- lsl.l #8, \dW1
- move.l \dW2, %d2
- lsr.l %d0, %d2
- or.l %d2, \dW1
- move.l %d1, %d2
- eor.l \dW1, %d1
- and.l %d2, \dW1
- move.l #0xfefefefe, %d2
- and.l %d1, %d2
- eor.l %d2, %d1
- lsr.l #1, %d2
- add.l %d2, \dW1
- add.l %d1, \dW1
-.endm
-
-/*****************************************************************************/
-
- .align 2
- .global MC_put_x_8
- .type MC_put_x_8, @function
-
-MC_put_x_8:
- lea.l (-6*4,%sp), %sp
- movem.l %d2-%d6/%a2, (%sp) | save some registers
- movem.l (6*4+4,%sp), %a0-%a2| dest, source, stride
- move.l (6*4+16,%sp), %d6 | height
- move.l %a1, %d0
- and.l #3, %d0
- sub.l %d0, %a1
- jmp.l (2, %pc, %d0.l*4)
- bra.w .px8_0
- bra.w .px8_1
- bra.w .px8_2
- | last table entry coincides with target
-
-.px8_3:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d5
- add.l %a2, %a1
- LEFT24_PW %d3, %d4
- LEFT24_PW %d4, %d5
- lsl.l %d0, %d5
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- movem.l %d3-%d4, (%a0)
- add.l %a2, %a0
- subq.l #1, %d6
- bne.s 1b
- movem.l (%sp), %d2-%d6/%a2
- lea.l (6*4,%sp), %sp
- rts
-
-.px8_2:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d5
- add.l %a2, %a1
- swap %d3
- swap %d4
- move.w %d4, %d3
- swap %d5
- move.w %d5, %d4
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- movem.l %d3-%d4, (%a0)
- add.l %a2, %a0
- subq.l #1, %d6
- bne.s 1b
- movem.l (%sp), %d2-%d6/%a2
- lea.l (6*4,%sp), %sp
- rts
-
-.px8_1:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d5
- add.l %a2, %a1
- LEFT8_PW %d3, %d4
- LEFT8_PW %d4, %d5
- lsl.l #8, %d5
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- movem.l %d3-%d4, (%a0)
- add.l %a2, %a0
- subq.l #1, %d6
- bne.s 1b
- movem.l (%sp), %d2-%d6/%a2
- lea.l (6*4,%sp), %sp
- rts
-
-.px8_0:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d5
- add.l %a2, %a1
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- movem.l %d3-%d4, (%a0)
- add.l %a2, %a0
- subq.l #1, %d6
- bne.s 1b
- movem.l (%sp), %d2-%d6/%a2
- lea.l (6*4,%sp), %sp
- rts
-
-/*****************************************************************************/
-
- .align 2
- .global MC_put_x_16
- .type MC_put_x_16, @function
-
-MC_put_x_16:
- lea.l (-8*4,%sp), %sp
- movem.l %d2-%d7/%a2-%a3, (%sp) | save some registers
- movem.l (8*4+4,%sp), %a0-%a3 | dest, source, stride, height
- move.l %a1, %d0
- and.l #3, %d0
- sub.l %d0, %a1
- jmp.l (2, %pc, %d0.l*4)
- bra.w .px16_0
- bra.w .px16_1
- bra.w .px16_2
- | last table entry coincides with target
-
-.px16_3:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- LEFT24_PW %d3, %d4
- LEFT24_PW %d4, %d5
- LEFT24_PW %d5, %d6
- LEFT24_PW %d6, %d7
- lsl.l %d0, %d7
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- AVG_PW %d5, %d6
- AVG_PW %d6, %d7
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %a3
- tst.l %a3
- bne.w 1b
- movem.l (%sp), %d2-%d7/%a2-%a3
- lea.l (8*4,%sp), %sp
- rts
-
-.px16_2:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- swap %d3
- swap %d4
- move.w %d4, %d3
- swap %d5
- move.w %d5, %d4
- swap %d6
- move.w %d6, %d5
- swap %d7
- move.w %d7, %d6
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- AVG_PW %d5, %d6
- AVG_PW %d6, %d7
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %a3
- tst.l %a3
- bne.w 1b
- movem.l (%sp), %d2-%d7/%a2-%a3
- lea.l (8*4,%sp), %sp
- rts
-
-.px16_1:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- LEFT8_PW %d3, %d4
- LEFT8_PW %d4, %d5
- LEFT8_PW %d5, %d6
- LEFT8_PW %d6, %d7
- lsl.l #8, %d7
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- AVG_PW %d5, %d6
- AVG_PW %d6, %d7
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %a3
- tst.l %a3
- bne.w 1b
- movem.l (%sp), %d2-%d7/%a2-%a3
- lea.l (8*4,%sp), %sp
- rts
-
-.px16_0:
- moveq.l #24, %d0
-1:
- movem.l (%a1), %d3-%d7
- add.l %a2, %a1
- AVG_PW %d3, %d4
- AVG_PW %d4, %d5
- AVG_PW %d5, %d6
- AVG_PW %d6, %d7
- movem.l %d3-%d6, (%a0)
- add.l %a2, %a0
- subq.l #1, %a3
- tst.l %a3
- bne.w 1b
- movem.l (%sp), %d2-%d7/%a2-%a3
- lea.l (8*4,%sp), %sp
- rts
diff --git a/apps/plugins/mpegplayer/libmpeg2/mpeg2.h b/apps/plugins/mpegplayer/libmpeg2/mpeg2.h
deleted file mode 100644
index bd14ead96e..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/mpeg2.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * mpeg2.h
- * Copyright (C) 2000-2004 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.67
- */
-
-#ifndef MPEG2_H
-#define MPEG2_H
-
-#include "mpeg2dec_config.h"
-
-#define MPEG2_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c))
-#define MPEG2_RELEASE MPEG2_VERSION (0, 5, 0) /* 0.5.0 */
-
-#define SEQ_FLAG_MPEG2 1
-#define SEQ_FLAG_CONSTRAINED_PARAMETERS 2
-#define SEQ_FLAG_PROGRESSIVE_SEQUENCE 4
-#define SEQ_FLAG_LOW_DELAY 8
-#define SEQ_FLAG_COLOUR_DESCRIPTION 16
-
-#define SEQ_MASK_VIDEO_FORMAT 0xe0
-#define SEQ_VIDEO_FORMAT_COMPONENT 0x00
-#define SEQ_VIDEO_FORMAT_PAL 0x20
-#define SEQ_VIDEO_FORMAT_NTSC 0x40
-#define SEQ_VIDEO_FORMAT_SECAM 0x60
-#define SEQ_VIDEO_FORMAT_MAC 0x80
-#define SEQ_VIDEO_FORMAT_UNSPECIFIED 0xa0
-
-typedef struct mpeg2_sequence_s
-{
- unsigned int width, height;
- unsigned int chroma_width, chroma_height;
- unsigned int byte_rate;
- unsigned int vbv_buffer_size;
- uint32_t flags;
-
- unsigned int picture_width, picture_height;
- unsigned int display_width, display_height;
- unsigned int pixel_width, pixel_height;
- unsigned int frame_period;
-
- uint8_t profile_level_id;
- uint8_t colour_primaries;
- uint8_t transfer_characteristics;
- uint8_t matrix_coefficients;
-} mpeg2_sequence_t;
-
-#define GOP_FLAG_DROP_FRAME 1
-#define GOP_FLAG_BROKEN_LINK 2
-#define GOP_FLAG_CLOSED_GOP 4
-
-typedef struct mpeg2_gop_s
-{
- uint8_t hours;
- uint8_t minutes;
- uint8_t seconds;
- uint8_t pictures;
- uint32_t flags;
-} mpeg2_gop_t;
-
-#define PIC_MASK_CODING_TYPE 7
-#define PIC_FLAG_CODING_TYPE_I 1
-#define PIC_FLAG_CODING_TYPE_P 2
-#define PIC_FLAG_CODING_TYPE_B 3
-#define PIC_FLAG_CODING_TYPE_D 4
-
-#define PIC_FLAG_TOP_FIELD_FIRST 8
-#define PIC_FLAG_PROGRESSIVE_FRAME 16
-#define PIC_FLAG_COMPOSITE_DISPLAY 32
-#define PIC_FLAG_SKIP 64
-#define PIC_FLAG_TAGS 128
-#define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000
-
-typedef struct mpeg2_picture_s
-{
- unsigned int temporal_reference;
- unsigned int nb_fields;
- uint32_t tag, tag2;
- uint32_t flags;
- struct
- {
- int x, y;
- } display_offset[3];
-} mpeg2_picture_t;
-
-typedef struct mpeg2_fbuf_s
-{
- uint8_t * buf[MPEG2_COMPONENTS];
- void * id;
-} mpeg2_fbuf_t;
-
-typedef struct mpeg2_info_s
-{
- const mpeg2_sequence_t * sequence;
- const mpeg2_gop_t * gop;
- const mpeg2_picture_t * current_picture;
- const mpeg2_picture_t * current_picture_2nd;
- const mpeg2_fbuf_t * current_fbuf;
- const mpeg2_picture_t * display_picture;
- const mpeg2_picture_t * display_picture_2nd;
- const mpeg2_fbuf_t * display_fbuf;
- const mpeg2_fbuf_t * discard_fbuf;
- const uint8_t * user_data;
- unsigned int user_data_len;
-} mpeg2_info_t;
-
-typedef struct mpeg2dec_s mpeg2dec_t;
-typedef struct mpeg2_decoder_s mpeg2_decoder_t;
-
-typedef enum
-{
- STATE_INTERNAL_NORETURN = -1,
- STATE_BUFFER = 0,
- STATE_SEQUENCE = 1,
- STATE_SEQUENCE_REPEATED = 2,
- STATE_SEQUENCE_MODIFIED = 3,
- STATE_GOP = 4,
- STATE_PICTURE = 5,
- STATE_SLICE_1ST = 6,
- STATE_PICTURE_2ND = 7,
- STATE_SLICE = 8,
- STATE_END = 9,
- STATE_INVALID = 10,
- STATE_INVALID_END = 11,
-} mpeg2_state_t;
-
-typedef struct mpeg2_convert_init_s
-{
- unsigned int id_size;
- unsigned int buf_size[MPEG2_COMPONENTS];
- void (* start)(void * id, const mpeg2_fbuf_t * fbuf,
- const mpeg2_picture_t * picture, const mpeg2_gop_t * gop);
- void (* copy)(void * id, uint8_t * const * src, unsigned int v_offset);
-} mpeg2_convert_init_t;
-
-typedef enum
-{
- MPEG2_CONVERT_SET = 0,
- MPEG2_CONVERT_STRIDE = 1,
- MPEG2_CONVERT_START = 2
-} mpeg2_convert_stage_t;
-
-typedef int mpeg2_convert_t (int stage, void * id,
- const mpeg2_sequence_t * sequence, int stride,
- void * arg, mpeg2_convert_init_t * result);
-int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg);
-int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride);
-void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS],
- void * id);
-void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf);
-
-mpeg2dec_t * mpeg2_init (void);
-const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec);
-void mpeg2_close (mpeg2dec_t * mpeg2dec);
-
-void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end);
-int mpeg2_getpos (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec);
-
-void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset);
-void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip);
-void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end);
-
-void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2);
-
-void mpeg2_init_fbuf (mpeg2_decoder_t * decoder,
- uint8_t * current_fbuf[MPEG2_COMPONENTS],
- uint8_t * forward_fbuf[MPEG2_COMPONENTS],
- uint8_t * backward_fbuf[MPEG2_COMPONENTS]);
-void mpeg2_slice (mpeg2_decoder_t * decoder, int code, const uint8_t * buffer);
-
-int mpeg2_guess_aspect (const mpeg2_sequence_t * sequence,
- unsigned int * pixel_width,
- unsigned int * pixel_height);
-
-typedef enum
-{
- MPEG2_ALLOC_MPEG2DEC = 0,
- MPEG2_ALLOC_CHUNK = 1,
- MPEG2_ALLOC_YUV = 2,
- MPEG2_ALLOC_CONVERT_ID = 3,
- MPEG2_ALLOC_CONVERTED = 4,
- MPEG_ALLOC_CODEC_MALLOC,
- MPEG_ALLOC_CODEC_CALLOC,
- MPEG_ALLOC_MPEG2_BUFFER,
- MPEG_ALLOC_AUDIOBUF,
- MPEG_ALLOC_PCMOUT,
- MPEG_ALLOC_DISKBUF,
- __MPEG_ALLOC_FIRST = -256,
-} mpeg2_alloc_t;
-
-void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason);
-#if 0
-void mpeg2_free (void * buf);
-#endif
-/* allocates a dedicated buffer and locks all previous allocation in place */
-void * mpeg2_bufalloc(unsigned size, mpeg2_alloc_t reason);
-/* clears all non-dedicated buffer space */
-void mpeg2_mem_reset(void);
-void mpeg2_alloc_init(unsigned char* buf, int mallocsize);
-
-#endif /* MPEG2_H */
diff --git a/apps/plugins/mpegplayer/libmpeg2/mpeg2_internal.h b/apps/plugins/mpegplayer/libmpeg2/mpeg2_internal.h
deleted file mode 100644
index e04562e18d..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/mpeg2_internal.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * mpeg2_internal.h
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.89
- */
-#ifndef MPEG2_INTERNAL_H
-#define MPEG2_INTERNAL_H
-
-#include "config.h" /* for Rockbox CPU_ #defines */
-
-/* macroblock modes */
-#define MACROBLOCK_INTRA 1
-#define MACROBLOCK_PATTERN 2
-#define MACROBLOCK_MOTION_BACKWARD 4
-#define MACROBLOCK_MOTION_FORWARD 8
-#define MACROBLOCK_QUANT 16
-#define DCT_TYPE_INTERLACED 32
-/* motion_type */
-#define MOTION_TYPE_SHIFT 6
-#define MC_FIELD 1
-#define MC_FRAME 2
-#define MC_16X8 2
-#define MC_DMV 3
-
-/* picture structure */
-#define TOP_FIELD 1
-#define BOTTOM_FIELD 2
-#define FRAME_PICTURE 3
-
-/* picture coding type */
-#define I_TYPE 1
-#define P_TYPE 2
-#define B_TYPE 3
-#define D_TYPE 4
-
-typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int);
-
-typedef struct
-{
- uint8_t * ref[2][MPEG2_COMPONENTS];
- uint8_t ** ref2[2];
- int pmv[2][2];
- int f_code[2];
-} motion_t;
-
-typedef void motion_parser_t(mpeg2_decoder_t * decoder,
- motion_t * motion,
- mpeg2_mc_fct * const * table);
-
-struct mpeg2_decoder_s
-{
- /* first, state that carries information from one macroblock to the */
- /* next inside a slice, and is never used outside of mpeg2_slice() */
-
- /* bit parsing stuff */
- uint32_t bitstream_buf; /* current 32 bit working set */
- int bitstream_bits; /* used bits in working set */
- const uint8_t * bitstream_ptr; /* buffer with stream data */
-
- uint8_t * dest[MPEG2_COMPONENTS];
-
- int offset;
- int stride;
- int uv_stride;
- int slice_stride;
- int slice_uv_stride;
- int stride_frame;
- unsigned int limit_x;
- unsigned int limit_y_16;
- unsigned int limit_y_8;
- unsigned int limit_y;
-
- /* Motion vectors */
- /* The f_ and b_ correspond to the forward and backward motion */
- /* predictors */
- motion_t b_motion;
- motion_t f_motion;
- motion_parser_t * motion_parser[5];
-
- /* predictor for DC coefficients in intra blocks */
- int16_t dc_dct_pred[MPEG2_COMPONENTS];
-
- /* DCT coefficients */
- int16_t * DCTblock; /* put buffer separately to have it in IRAM */
-
- uint8_t * picture_dest[MPEG2_COMPONENTS];
- void (* convert) (void * convert_id, uint8_t * const * src,
- unsigned int v_offset);
- void * convert_id;
-
- int dmv_offset;
- unsigned int v_offset;
-
- /* now non-slice-specific information */
-
- /* sequence header stuff */
- uint16_t * quantizer_matrix[4];
- uint16_t (* chroma_quantizer[2])[64];
- uint16_t quantizer_prescale[4][32][64];
-
- /* The width and height of the picture snapped to macroblock units */
- int width;
- int height;
- int vertical_position_extension;
- int chroma_format;
-
- /* picture header stuff */
-
- /* what type of picture this is (I, P, B, D) */
- int coding_type;
-
- /* picture coding extension stuff */
-
- /* quantization factor for intra dc coefficients */
- int intra_dc_precision;
- /* top/bottom/both fields */
- int picture_structure;
- /* bool to indicate all predictions are frame based */
- int frame_pred_frame_dct;
- /* bool to indicate whether intra blocks have motion vectors */
- /* (for concealment) */
- int concealment_motion_vectors;
- /* bool to use different vlc tables */
- int intra_vlc_format;
- /* used for DMV MC */
- int top_field_first;
-
- /* stuff derived from bitstream */
-
- /* pointer to the zigzag scan we're supposed to be using */
- const uint8_t * scan;
-
- int second_field;
-
- int mpeg1;
-};
-
-typedef struct
-{
- mpeg2_fbuf_t fbuf;
-} fbuf_alloc_t;
-
-struct mpeg2dec_s
-{
- mpeg2_decoder_t decoder;
-
- mpeg2_info_t info;
-
- uint32_t shift;
- int is_display_initialized;
- mpeg2_state_t (* action) (struct mpeg2dec_s * mpeg2dec);
- mpeg2_state_t state;
- uint32_t ext_state;
-
- /* allocated in init - gcc has problems allocating such big structures */
- uint8_t * ATTR_ALIGN(4) chunk_buffer;
- /* pointer to start of the current chunk */
- uint8_t * chunk_start;
- /* pointer to current position in chunk_buffer */
- uint8_t * chunk_ptr;
- /* last start code ? */
- uint8_t code;
-
- /* picture tags */
- uint32_t tag_current, tag2_current, tag_previous, tag2_previous;
- int num_tags;
- int bytes_since_tag;
-
- int first;
- int alloc_index_user;
- int alloc_index;
- uint8_t first_decode_slice;
- uint8_t nb_decode_slices;
-
- unsigned int user_data_len;
-
- mpeg2_sequence_t new_sequence;
- mpeg2_sequence_t sequence;
- mpeg2_gop_t new_gop;
- mpeg2_gop_t gop;
- mpeg2_picture_t new_picture;
- mpeg2_picture_t pictures[4];
- mpeg2_picture_t * picture;
- /*const*/ mpeg2_fbuf_t * fbuf[3]; /* 0: current fbuf, 1-2: prediction fbufs */
-
- fbuf_alloc_t fbuf_alloc[3];
- int custom_fbuf;
-
- uint8_t * yuv_buf[3][MPEG2_COMPONENTS];
- int yuv_index;
- mpeg2_convert_t * convert;
- void * convert_arg;
- unsigned int convert_id_size;
- int convert_stride;
- void (* convert_start) (void * id, const mpeg2_fbuf_t * fbuf,
- const mpeg2_picture_t * picture,
- const mpeg2_gop_t * gop);
-
- uint8_t * buf_start;
- uint8_t * buf_end;
-
- int16_t display_offset_x, display_offset_y;
-
- int copy_matrix;
- int8_t q_scale_type, scaled[4];
- uint8_t quantizer_matrix[4][64];
- uint8_t new_quantizer_matrix[4][64];
-};
-
-/* decode.c */
-mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec);
-
-/* header.c */
-void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec);
-void mpeg2_reset_info (mpeg2_info_t * info);
-int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_gop (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_picture (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_extension (mpeg2dec_t * mpeg2dec);
-int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec);
-void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec);
-void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec);
-void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec);
-mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec);
-void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type);
-
-/* idct.c */
-void mpeg2_idct_init (void);
-void mpeg2_idct_copy(int16_t * block, uint8_t * dest,
- const int stride);
-void mpeg2_idct_add(const int last, int16_t * block,
- uint8_t * dest, const int stride);
-
-extern const uint8_t default_mpeg2_scan_norm[64];
-extern const uint8_t default_mpeg2_scan_alt[64];
-extern uint8_t mpeg2_scan_norm[64];
-extern uint8_t mpeg2_scan_alt[64];
-
-/* motion_comp.c */
-void mpeg2_mc_init (void);
-
-typedef struct
-{
- mpeg2_mc_fct * put [8];
- mpeg2_mc_fct * avg [8];
-} mpeg2_mc_t;
-
-extern const mpeg2_mc_t mpeg2_mc;
-
-#endif /* MPEG2_INTERNAL_H */
-
diff --git a/apps/plugins/mpegplayer/libmpeg2/mpeg2dec_config.h b/apps/plugins/mpegplayer/libmpeg2/mpeg2dec_config.h
deleted file mode 100644
index c34ee374df..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/mpeg2dec_config.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id$ */
-#ifndef MPEG2DEC_CONFIG_H
-#define MPEG2DEC_CONFIG_H
-
-#define ATTRIBUTE_ALIGNED_MAX 16
-
-#ifdef HAVE_LCD_COLOR
-#define MPEG2_COLOR 1
-#define MPEG2_COMPONENTS 3
-#else
-#define MPEG2_COLOR 0
-#define MPEG2_COMPONENTS 1
-#endif
-
-#endif /* MPEG2DEC_CONFIG_H */
diff --git a/apps/plugins/mpegplayer/libmpeg2/slice.c b/apps/plugins/mpegplayer/libmpeg2/slice.c
deleted file mode 100644
index 926333d5d0..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/slice.c
+++ /dev/null
@@ -1,2898 +0,0 @@
-/*
- * slice.c
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 2003 Peter Gubanov
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.55
- */
-
-#include "plugin.h"
-
-#include "mpeg2dec_config.h"
-
-#include "mpeg2.h"
-#include "attributes.h"
-#include "mpeg2_internal.h"
-
-#include "vlc.h"
-
-static inline int get_macroblock_modes (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- int macroblock_modes;
- const MBtab * tab;
-
- switch (decoder->coding_type)
- {
- case I_TYPE:
- tab = MB_I + UBITS (bit_buf, 1);
- DUMPBITS (bit_buf, bits, tab->len);
- macroblock_modes = tab->modes;
-
- if (!(decoder->frame_pred_frame_dct) &&
- decoder->picture_structure == FRAME_PICTURE)
- {
- macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
- DUMPBITS (bit_buf, bits, 1);
- }
-
- return macroblock_modes;
-
- case P_TYPE:
- tab = MB_P + UBITS (bit_buf, 5);
- DUMPBITS (bit_buf, bits, tab->len);
- macroblock_modes = tab->modes;
-
- if (decoder->picture_structure != FRAME_PICTURE)
- {
- if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
- {
- macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
- DUMPBITS (bit_buf, bits, 2);
- }
-
- return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
- }
- else if (decoder->frame_pred_frame_dct)
- {
- if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
- macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT;
-
- return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
- }
- else
- {
- if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
- {
- macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
- DUMPBITS (bit_buf, bits, 2);
- }
-
- if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
- {
- macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
- DUMPBITS (bit_buf, bits, 1);
- }
-
- return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
- }
-
- case B_TYPE:
- tab = MB_B + UBITS (bit_buf, 6);
- DUMPBITS (bit_buf, bits, tab->len);
- macroblock_modes = tab->modes;
-
- if (decoder->picture_structure != FRAME_PICTURE)
- {
- if (! (macroblock_modes & MACROBLOCK_INTRA))
- {
- macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
- DUMPBITS (bit_buf, bits, 2);
- }
-
- return macroblock_modes;
- }
- else if (decoder->frame_pred_frame_dct)
- {
- /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
- macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT;
- return macroblock_modes;
- }
- else
- {
- if (macroblock_modes & MACROBLOCK_INTRA)
- goto intra;
-
- macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
- DUMPBITS (bit_buf, bits, 2);
-
- if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
- {
- intra:
- macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
- DUMPBITS (bit_buf, bits, 1);
- }
- return macroblock_modes;
- }
-
- case D_TYPE:
- DUMPBITS (bit_buf, bits, 1);
- return MACROBLOCK_INTRA;
-
- default:
- return 0;
- }
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static inline void get_quantizer_scale (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- int quantizer_scale_code;
-
- quantizer_scale_code = UBITS (bit_buf, 5);
- DUMPBITS (bit_buf, bits, 5);
-
- decoder->quantizer_matrix[0] =
- decoder->quantizer_prescale[0][quantizer_scale_code];
-
- decoder->quantizer_matrix[1] =
- decoder->quantizer_prescale[1][quantizer_scale_code];
-
- decoder->quantizer_matrix[2] =
- decoder->chroma_quantizer[0][quantizer_scale_code];
-
- decoder->quantizer_matrix[3] =
- decoder->chroma_quantizer[1][quantizer_scale_code];
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static inline int get_motion_delta (mpeg2_decoder_t * const decoder,
- const int f_code)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- int delta;
- int sign;
- const MVtab * tab;
-
- if (bit_buf & 0x80000000)
- {
- DUMPBITS (bit_buf, bits, 1);
- return 0;
- }
- else if (bit_buf >= 0x0c000000)
- {
- tab = MV_4 + UBITS (bit_buf, 4);
- delta = (tab->delta << f_code) + 1;
- bits += tab->len + f_code + 1;
- bit_buf <<= tab->len;
-
- sign = SBITS (bit_buf, 1);
- bit_buf <<= 1;
-
- if (f_code)
- delta += UBITS (bit_buf, f_code);
- bit_buf <<= f_code;
-
- return (delta ^ sign) - sign;
- }
- else
- {
- tab = MV_10 + UBITS (bit_buf, 10);
- delta = (tab->delta << f_code) + 1;
- bits += tab->len + 1;
- bit_buf <<= tab->len;
-
- sign = SBITS (bit_buf, 1);
- bit_buf <<= 1;
-
- if (f_code)
- {
- NEEDBITS (bit_buf, bits, bit_ptr);
- delta += UBITS (bit_buf, f_code);
- DUMPBITS (bit_buf, bits, f_code);
- }
-
- return (delta ^ sign) - sign;
-
- }
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static inline int bound_motion_vector (const int vector, const int f_code)
-{
- return ((int32_t)vector << (27 - f_code)) >> (27 - f_code);
-}
-
-static inline int get_dmv (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- const DMVtab * tab;
-
- tab = DMV_2 + UBITS (bit_buf, 2);
- DUMPBITS (bit_buf, bits, tab->len);
- return tab->dmv;
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static inline int get_coded_block_pattern (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- const CBPtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- if (bit_buf >= 0x20000000)
- {
- tab = CBP_7 + (UBITS (bit_buf, 7) - 16);
- DUMPBITS (bit_buf, bits, tab->len);
- return tab->cbp;
- }
- else
- {
- tab = CBP_9 + UBITS (bit_buf, 9);
- DUMPBITS (bit_buf, bits, tab->len);
- return tab->cbp;
- }
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static inline int get_luma_dc_dct_diff (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- const DCtab * tab;
- int size;
- int dc_diff;
-
- if (bit_buf < 0xf8000000)
- {
- tab = DC_lum_5 + UBITS (bit_buf, 5);
- size = tab->size;
-
- if (size)
- {
- bits += tab->len + size;
- bit_buf <<= tab->len;
- dc_diff =
- UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
- bit_buf <<= size;
- return dc_diff << decoder->intra_dc_precision;
- }
- else
- {
- DUMPBITS (bit_buf, bits, 3);
- return 0;
- }
- }
- else
- {
- tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0);
- size = tab->size;
- DUMPBITS (bit_buf, bits, tab->len);
- NEEDBITS (bit_buf, bits, bit_ptr);
- dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
- DUMPBITS (bit_buf, bits, size);
- return dc_diff << decoder->intra_dc_precision;
- }
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-#if MPEG2_COLOR
-static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- const DCtab * tab;
- int size;
- int dc_diff;
-
- if (bit_buf < 0xf8000000)
- {
- tab = DC_chrom_5 + UBITS (bit_buf, 5);
- size = tab->size;
-
- if (size)
- {
- bits += tab->len + size;
- bit_buf <<= tab->len;
- dc_diff =
- UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
- bit_buf <<= size;
- return dc_diff << decoder->intra_dc_precision;
- }
- else
- {
- DUMPBITS (bit_buf, bits, 2);
- return 0;
- }
- }
- else
- {
- tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0);
- size = tab->size;
- DUMPBITS (bit_buf, bits, tab->len + 1);
- NEEDBITS (bit_buf, bits, bit_ptr);
- dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
- DUMPBITS (bit_buf, bits, size);
- return dc_diff << decoder->intra_dc_precision;
- }
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-#endif /* MPEG2_COLOR */
-
-#define SATURATE(val) \
- do { \
- val <<= 4; \
- if (unlikely (val != (int16_t) val)) \
- val = (SBITS (val, 1) ^ 2047) << 4; \
- } while (0)
-
-static void get_intra_block_B14 (mpeg2_decoder_t * const decoder,
- const uint16_t * const quant_matrix)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- const uint8_t * const scan = decoder->scan;
- int16_t * const dest = decoder->DCTblock;
- int mismatch = ~dest[0];
- int i = 0;
- int j;
- int val;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- j = scan[i];
- bit_buf <<= tab->len;
- bits += tab->len + 1;
- val = (tab->level * quant_matrix[j]) >> 4;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
-
- SATURATE (val);
- dest[j] = val;
- mismatch ^= val;
-
- bit_buf <<= 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- j = scan[i];
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16;
-
- SATURATE (val);
- dest[j] = val;
- mismatch ^= val;
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- dest[63] ^= mismatch & 16;
- DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static void get_intra_block_B15 (mpeg2_decoder_t * const decoder,
- const uint16_t * const quant_matrix)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- const uint8_t * const scan = decoder->scan;
- int16_t * const dest = decoder->DCTblock;
- int mismatch = ~dest[0];
- int i = 0;
- int j;
- int val;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- while (1)
- {
- if (bit_buf >= 0x04000000)
- {
- tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
-
- if (i < 64)
- {
- normal_code:
- j = scan[i];
- bit_buf <<= tab->len;
- bits += tab->len + 1;
- val = (tab->level * quant_matrix[j]) >> 4;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
-
- SATURATE (val);
- dest[j] = val;
- mismatch ^= val;
-
- bit_buf <<= 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else
- {
- /* end of block. I commented out this code because if we */
- /* dont exit here we will still exit at the later test :) */
-
- /* if (i >= 128) break; */ /* end of block */
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check against buffer overflow */
-
- j = scan[i];
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16;
-
- SATURATE (val);
- dest[j] = val;
- mismatch ^= val;
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- dest[63] ^= mismatch & 16;
- DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static int get_non_intra_block (mpeg2_decoder_t * const decoder,
- const uint16_t * const quant_matrix)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- const uint8_t * const scan = decoder->scan;
- int16_t * const dest = decoder->DCTblock;
- int mismatch = -1;
- int i = -1;
- int j;
- int val;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
- goto entry_1;
- }
- else
- {
- goto entry_2;
- }
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- entry_1:
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- j = scan[i];
- bit_buf <<= tab->len;
- bits += tab->len + 1;
- val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
-
- SATURATE (val);
- dest[j] = val;
- mismatch ^= val;
-
- bit_buf <<= 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
-
- entry_2:
- if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- j = scan[i];
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1;
- val = (val * quant_matrix[j]) / 32;
-
- SATURATE (val);
- dest[j] = val;
- mismatch ^= val;
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- dest[63] ^= mismatch & 16;
- DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
- return i;
-}
-
-static void get_mpeg1_intra_block (mpeg2_decoder_t * const decoder)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- const uint8_t * const scan = decoder->scan;
- const uint16_t * const quant_matrix = decoder->quantizer_matrix[0];
- int16_t * const dest = decoder->DCTblock;
- int i = 0;
- int j;
- int val;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- j = scan[i];
- bit_buf <<= tab->len;
- bits += tab->len + 1;
- val = (tab->level * quant_matrix[j]) >> 4;
-
- /* oddification */
- val = (val - 1) | 1;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
-
- SATURATE (val);
- dest[j] = val;
-
- bit_buf <<= 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- j = scan[i];
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- val = SBITS (bit_buf, 8);
-
- if (! (val & 0x7f))
- {
- DUMPBITS (bit_buf, bits, 8);
- val = UBITS (bit_buf, 8) + 2 * val;
- }
-
- val = (val * quant_matrix[j]) / 16;
-
- /* oddification */
- val = (val + ~SBITS (val, 1)) | 1;
-
- SATURATE (val);
- dest[j] = val;
-
- DUMPBITS (bit_buf, bits, 8);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static int get_mpeg1_non_intra_block (mpeg2_decoder_t * const decoder)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- const uint8_t * const scan = decoder->scan;
- const uint16_t * const quant_matrix = decoder->quantizer_matrix[1];
- int16_t * const dest = decoder->DCTblock;
- int i = -1;
- int j;
- int val;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
- goto entry_1;
- }
- else
- {
- goto entry_2;
- }
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- entry_1:
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- j = scan[i];
- bit_buf <<= tab->len;
- bits += tab->len + 1;
- val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5;
-
- /* oddification */
- val = (val - 1) | 1;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
-
- SATURATE (val);
- dest[j] = val;
-
- bit_buf <<= 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
-
- entry_2:
- if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- j = scan[i];
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- val = SBITS (bit_buf, 8);
-
- if (! (val & 0x7f))
- {
- DUMPBITS (bit_buf, bits, 8);
- val = UBITS (bit_buf, 8) + 2 * val;
- }
-
- val = 2 * (val + SBITS (val, 1)) + 1;
- val = (val * quant_matrix[j]) / 32;
-
- /* oddification */
- val = (val + ~SBITS (val, 1)) | 1;
-
- SATURATE (val);
- dest[j] = val;
-
- DUMPBITS (bit_buf, bits, 8);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
-
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
- return i;
-}
-
-static inline void slice_intra_DCT (mpeg2_decoder_t * const decoder,
- const int cc,
- uint8_t * const dest, const int stride)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- /* Get the intra DC coefficient and inverse quantize it */
- if (cc == 0)
- {
- decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder);
- decoder->DCTblock[0] = decoder->dc_dct_pred[0];
-
- }
-#if MPEG2_COLOR
- else
- {
- decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder);
- decoder->DCTblock[0] = decoder->dc_dct_pred[cc];
- }
-#endif
-
- if (decoder->mpeg1)
- {
- if (decoder->coding_type != D_TYPE)
- get_mpeg1_intra_block (decoder);
- }
- else if (decoder->intra_vlc_format)
- {
- get_intra_block_B15 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]);
- }
- else
- {
- get_intra_block_B14 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]);
- }
-
- mpeg2_idct_copy (decoder->DCTblock, dest, stride);
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder,
- const int cc,
- uint8_t * const dest, const int stride)
-{
- int last;
-
- if (decoder->mpeg1)
- {
- last = get_mpeg1_non_intra_block (decoder);
- }
- else
- {
- last = get_non_intra_block (decoder,
- decoder->quantizer_matrix[cc ? 3 : 1]);
- }
-
- mpeg2_idct_add (last, decoder->DCTblock, dest, stride);
-}
-
-#if !MPEG2_COLOR
-static void skip_mpeg1_intra_block (mpeg2_decoder_t * const decoder)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- int i = 0;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- bit_buf <<= tab->len + 1;
- bits += tab->len + 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- }
- else if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- if (!(SBITS (bit_buf, 8) & 0x7f))
- DUMPBITS (bit_buf, bits, 8);
-
- DUMPBITS (bit_buf, bits, 8);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static void skip_intra_block_B14 (mpeg2_decoder_t * const decoder)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- int i = 0;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- bit_buf <<= tab->len + 1;
- bits += tab->len + 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- }
- else if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- DUMPBITS (bit_buf, bits, 12); /* Can't dump more than 16 atm */
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static void skip_intra_block_B15 (mpeg2_decoder_t * const decoder)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- int i = 0;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- while (1)
- {
- if (bit_buf >= 0x04000000)
- {
- tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
-
- if (i < 64)
- {
- normal_code:
- bit_buf <<= tab->len + 1;
- bits += tab->len + 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- }
- else
- {
- /* end of block. I commented out this code because if we */
- /* dont exit here we will still exit at the later test :) */
-
- /* if (i >= 128) break; */ /* end of block */
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check against buffer overflow */
-
- DUMPBITS (bit_buf, bits, 12); /* Can't dump more than 16 atm */
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- }
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- DUMPBITS (bit_buf, bits, 4); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static void skip_non_intra_block (mpeg2_decoder_t * const decoder)
-{
- uint32_t bit_buf = decoder->bitstream_buf;
- int bits = decoder->bitstream_bits;
- const uint8_t * bit_ptr = decoder->bitstream_ptr;
- int i = -1;
- const DCTtab * tab;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
- goto entry_1;
- }
- else
- {
- goto entry_2;
- }
-
- while (1)
- {
- if (bit_buf >= 0x28000000)
- {
- tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
-
- entry_1:
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- bit_buf <<= tab->len + 1;
- bits += tab->len + 1;
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- continue;
- }
-
- entry_2:
- if (bit_buf >= 0x04000000)
- {
- tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS (bit_buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- if (decoder->mpeg1)
- {
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- if (!(SBITS (bit_buf, 8) & 0x7f))
- DUMPBITS (bit_buf, bits, 8);
-
- DUMPBITS (bit_buf, bits, 8);
- }
- else
- {
- DUMPBITS (bit_buf, bits, 12);
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, 12);
- }
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- }
- else if (bit_buf >= 0x02000000)
- {
- tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00800000)
- {
- tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else if (bit_buf >= 0x00200000)
- {
- tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- else
- {
- tab = DCT_16 + UBITS (bit_buf, 16);
- bit_buf <<= 16;
- GETWORD (bit_buf, bits + 16, bit_ptr);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
-
- DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
- decoder->bitstream_buf = bit_buf;
- decoder->bitstream_bits = bits;
- decoder->bitstream_ptr = bit_ptr;
-}
-
-static void skip_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- const DCtab * tab;
- int size;
-
- if (bit_buf < 0xf8000000)
- {
- tab = DC_chrom_5 + UBITS (bit_buf, 5);
- size = tab->size;
-
- if (size)
- {
- bits += tab->len + size;
- bit_buf <<= tab->len;
- bit_buf <<= size;
- }
- else
- {
- DUMPBITS (bit_buf, bits, 2);
- }
- }
- else
- {
- tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0);
- size = tab->size;
- DUMPBITS (bit_buf, bits, tab->len + 1);
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, size);
- }
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static void skip_chroma_non_intra (mpeg2_decoder_t * const decoder,
- uint32_t coded_block_pattern)
-{
- static const uint32_t cbp_mask[3] =
- {
- 0x00000030,
- 0xc0000030,
- 0xfc000030,
- };
-
- uint32_t cbp = coded_block_pattern &
- cbp_mask[MIN((unsigned)decoder->chroma_format, 2u)];
-
- while (cbp)
- {
- skip_non_intra_block (decoder);
- cbp &= (cbp - 1);
- }
-}
-
-static void skip_chroma_intra (mpeg2_decoder_t * const decoder)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
- int i = 2 << decoder->chroma_format;
-
- if ((unsigned)i > 8)
- i = 8;
-
- while (i-- > 0)
- {
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- skip_chroma_dc_dct_diff (decoder);
-
- if (decoder->mpeg1)
- {
- if (decoder->coding_type != D_TYPE)
- skip_mpeg1_intra_block (decoder);
- }
- else if (decoder->intra_vlc_format)
- {
- skip_intra_block_B15 (decoder);
- }
- else
- {
- skip_intra_block_B14 (decoder);
- }
- }
-
- if (decoder->chroma_format == 0 && decoder->coding_type == D_TYPE)
- {
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, 1);
- }
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-#endif /* !MPEG2_COLOR */
-
-#define MOTION_420(table, ref, motion_x, motion_y, size, y) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y_ ## size)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
- motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
- ref[0] + (pos_x >> 1) + (pos_y >> 1) * decoder->stride, \
- decoder->stride, size); \
- \
- if (MPEG2_COLOR) \
- { \
- motion_x /= 2; \
- motion_y /= 2; \
- xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
- offset = ((decoder->offset + motion_x) >> 1) + \
- ((((decoder->v_offset + motion_y) >> 1) + y/2) * \
- decoder->uv_stride); \
- \
- table[4+xy_half] (decoder->dest[1] + y/2 * decoder->uv_stride + \
- (decoder->offset >> 1), ref[1] + offset, \
- decoder->uv_stride, size/2); \
- table[4+xy_half] (decoder->dest[2] + y/2 * decoder->uv_stride + \
- (decoder->offset >> 1), ref[2] + offset, \
- decoder->uv_stride, size/2); \
- }
-
-#define MOTION_FIELD_420(table, ref, motion_x, motion_y, \
- dest_field, op, src_field) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = decoder->v_offset + motion_y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
- motion_y = pos_y - decoder->v_offset; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
- decoder->offset, \
- (ref[0] + (pos_x >> 1) + \
- ((pos_y op) + src_field) * decoder->stride), \
- 2 * decoder->stride, 8); \
- \
- if (MPEG2_COLOR) \
- { \
- motion_x /= 2; \
- motion_y /= 2; \
- xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
- offset = ((decoder->offset + motion_x) >> 1) + \
- (((decoder->v_offset >> 1) + (motion_y op) + src_field) * \
- decoder->uv_stride); \
- \
- table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \
- (decoder->offset >> 1), ref[1] + offset, \
- 2 * decoder->uv_stride, 4); \
- table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \
- (decoder->offset >> 1), ref[2] + offset, \
- 2 * decoder->uv_stride, 4); \
- }
-
-#define MOTION_DMV_420(table, ref, motion_x, motion_y) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = decoder->v_offset + motion_y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
- motion_y = pos_y - decoder->v_offset; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
- table[xy_half] (decoder->dest[0] + decoder->offset, \
- ref[0] + offset, 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
- ref[0] + decoder->stride + offset, \
- 2 * decoder->stride, 8); \
- \
- if (MPEG2_COLOR) \
- { \
- motion_x /= 2; \
- motion_y /= 2; \
- xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
- offset = ((decoder->offset + motion_x) >> 1) + \
- (((decoder->v_offset >> 1) + (motion_y & ~1)) * \
- decoder->uv_stride); \
- \
- table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \
- ref[1] + offset, 2 * decoder->uv_stride, 4); \
- table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \
- (decoder->offset >> 1), \
- ref[1] + decoder->uv_stride + offset, \
- 2 * decoder->uv_stride, 4); \
- table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \
- ref[2] + offset, 2 * decoder->uv_stride, 4); \
- table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \
- (decoder->offset >> 1), \
- ref[2] + decoder->uv_stride + offset, \
- 2 * decoder->uv_stride, 4); \
- }
-
-#define MOTION_ZERO_420(table, ref) \
- table[0] (decoder->dest[0] + decoder->offset, \
- (ref[0] + decoder->offset + \
- decoder->v_offset * decoder->stride), decoder->stride, 16); \
- \
- if (MPEG2_COLOR) \
- { \
- offset = ((decoder->offset >> 1) + \
- (decoder->v_offset >> 1) * decoder->uv_stride); \
- \
- table[4] (decoder->dest[1] + (decoder->offset >> 1), \
- ref[1] + offset, decoder->uv_stride, 8); \
- table[4] (decoder->dest[2] + (decoder->offset >> 1), \
- ref[2] + offset, decoder->uv_stride, 8); \
- }
-
-#define MOTION_422(table, ref, motion_x, motion_y, size, y) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y_ ## size)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
- motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \
- \
- table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
- ref[0] + offset, decoder->stride, size); \
- \
- if (MPEG2_COLOR) \
- { \
- offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
- motion_x /= 2; \
- xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
- \
- table[4+xy_half] (decoder->dest[1] + y * decoder->uv_stride + \
- (decoder->offset >> 1), ref[1] + offset, \
- decoder->uv_stride, size); \
- table[4+xy_half] (decoder->dest[2] + y * decoder->uv_stride + \
- (decoder->offset >> 1), ref[2] + offset, \
- decoder->uv_stride, size); \
- }
-
-#define MOTION_FIELD_422(table, ref, motion_x, motion_y, \
- dest_field, op, src_field) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = decoder->v_offset + motion_y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
- motion_y = pos_y - decoder->v_offset; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \
- \
- table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
- decoder->offset, ref[0] + offset, \
- 2 * decoder->stride, 8); \
- \
- if (MPEG2_COLOR) \
- { \
- offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
- motion_x /= 2; \
- xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
- \
- table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \
- (decoder->offset >> 1), ref[1] + offset, \
- 2 * decoder->uv_stride, 8); \
- table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \
- (decoder->offset >> 1), ref[2] + offset, \
- 2 * decoder->uv_stride, 8); \
- }
-
-#define MOTION_DMV_422(table, ref, motion_x, motion_y) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = decoder->v_offset + motion_y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
- motion_y = pos_y - decoder->v_offset; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
- \
- table[xy_half] (decoder->dest[0] + decoder->offset, \
- ref[0] + offset, 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
- ref[0] + decoder->stride + offset, \
- 2 * decoder->stride, 8); \
- \
- if (MPEG2_COLOR) \
- { \
- offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
- motion_x /= 2; \
- xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
- \
- table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \
- ref[1] + offset, 2 * decoder->uv_stride, 8); \
- table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \
- (decoder->offset >> 1), \
- ref[1] + decoder->uv_stride + offset, \
- 2 * decoder->uv_stride, 8); \
- table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \
- ref[2] + offset, 2 * decoder->uv_stride, 8); \
- table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \
- (decoder->offset >> 1), \
- ref[2] + decoder->uv_stride + offset, \
- 2 * decoder->uv_stride, 8); \
- }
-
-#define MOTION_ZERO_422(table, ref) \
- offset = decoder->offset + decoder->v_offset * decoder->stride; \
- table[0] (decoder->dest[0] + decoder->offset, \
- ref[0] + offset, decoder->stride, 16); \
- \
- if (MPEG2_COLOR) \
- { \
- offset >>= 1; \
- table[4] (decoder->dest[1] + (decoder->offset >> 1), \
- ref[1] + offset, decoder->uv_stride, 16); \
- table[4] (decoder->dest[2] + (decoder->offset >> 1), \
- ref[2] + offset, decoder->uv_stride, 16); \
- }
-
-#define MOTION_444(table, ref, motion_x, motion_y, size, y) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y_ ## size)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
- motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \
- \
- table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
- ref[0] + offset, decoder->stride, size); \
- \
- if (MPEG2_COLOR) \
- { \
- table[xy_half] (decoder->dest[1] + y * decoder->stride + decoder->offset, \
- ref[1] + offset, decoder->stride, size); \
- table[xy_half] (decoder->dest[2] + y * decoder->stride + decoder->offset, \
- ref[2] + offset, decoder->stride, size); \
- }
-
-#define MOTION_FIELD_444(table, ref, motion_x, motion_y, \
- dest_field, op, src_field) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = decoder->v_offset + motion_y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
- motion_y = pos_y - decoder->v_offset; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \
- \
- table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
- decoder->offset, ref[0] + offset, \
- 2 * decoder->stride, 8); \
- \
- if (MPEG2_COLOR) \
- { \
- table[xy_half] (decoder->dest[1] + dest_field * decoder->stride + \
- decoder->offset, ref[1] + offset, \
- 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[2] + dest_field * decoder->stride + \
- decoder->offset, ref[2] + offset, \
- 2 * decoder->stride, 8); \
- }
-
-#define MOTION_DMV_444(table, ref, motion_x, motion_y) \
- pos_x = 2 * decoder->offset + motion_x; \
- pos_y = decoder->v_offset + motion_y; \
- \
- if (unlikely (pos_x > decoder->limit_x)) \
- { \
- pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
- motion_x = pos_x - 2 * decoder->offset; \
- } \
- \
- if (unlikely (pos_y > decoder->limit_y)) \
- { \
- pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
- motion_y = pos_y - decoder->v_offset; \
- } \
- \
- xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
- offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
- \
- table[xy_half] (decoder->dest[0] + decoder->offset, \
- ref[0] + offset, 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
- ref[0] + decoder->stride + offset, \
- 2 * decoder->stride, 8); \
- \
- if (MPEG2_COLOR) \
- { \
- table[xy_half] (decoder->dest[1] + decoder->offset, \
- ref[1] + offset, 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[1] + decoder->stride + decoder->offset, \
- ref[1] + decoder->stride + offset, \
- 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[2] + decoder->offset, \
- ref[2] + offset, 2 * decoder->stride, 8); \
- table[xy_half] (decoder->dest[2] + decoder->stride + decoder->offset, \
- ref[2] + decoder->stride + offset, \
- 2 * decoder->stride, 8); \
- }
-
-#define MOTION_ZERO_444(table, ref) \
- offset = decoder->offset + decoder->v_offset * decoder->stride; \
- \
- table[0] (decoder->dest[0] + decoder->offset, \
- ref[0] + offset, decoder->stride, 16); \
- \
- if (MPEG2_COLOR) \
- { \
- table[4] (decoder->dest[1] + decoder->offset, \
- ref[1] + offset, decoder->stride, 16); \
- table[4] (decoder->dest[2] + decoder->offset, \
- ref[2] + offset, decoder->stride, 16); \
- }
-
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
-static void motion_mp1 (mpeg2_decoder_t * const decoder,
- motion_t * const motion,
- mpeg2_mc_fct * const * const table)
-{
- int motion_x, motion_y;
- unsigned int pos_x, pos_y, xy_half, offset;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- motion_x = motion->pmv[0][0] +
- (get_motion_delta (decoder,
- motion->f_code[0]) << motion->f_code[1]);
- motion_x = bound_motion_vector (motion_x,
- motion->f_code[0] + motion->f_code[1]);
- motion->pmv[0][0] = motion_x;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- motion_y = motion->pmv[0][1] +
- (get_motion_delta (decoder,
- motion->f_code[0]) << motion->f_code[1]);
- motion_y = bound_motion_vector (motion_y,
- motion->f_code[0] + motion->f_code[1]);
- motion->pmv[0][1] = motion_y;
-
- MOTION_420 (table, motion->ref[0], motion_x, motion_y, 16, 0);
-}
-
-#define MOTION_FUNCTIONS(FORMAT, MOTION, MOTION_FIELD, \
- MOTION_DMV, MOTION_ZERO) \
- \
-static void motion_fr_frame_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
- motion->f_code[1]); \
- motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
- motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \
- \
- MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); \
-} \
- \
-static void motion_fr_field_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y, field; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- field = UBITS (bit_buf, 1); \
- DUMPBITS (bit_buf, bits, 1); \
- \
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[0][0] = motion_x; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_y = ((motion->pmv[0][1] >> 1) + \
- get_motion_delta (decoder, motion->f_code[1])); \
- /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \
- motion->pmv[0][1] = motion_y << 1; \
- \
- MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- field = UBITS (bit_buf, 1); \
- DUMPBITS (bit_buf, bits, 1); \
- \
- motion_x = motion->pmv[1][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[1][0] = motion_x; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_y = ((motion->pmv[1][1] >> 1) + \
- get_motion_delta (decoder, motion->f_code[1])); \
- /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \
- motion->pmv[1][1] = motion_y << 1; \
- \
- MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); \
-} \
- \
-static void motion_fr_dmv_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- (void)table; \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- dmv_x = get_dmv (decoder); \
- \
- motion_y = ((motion->pmv[0][1] >> 1) + \
- get_motion_delta (decoder, motion->f_code[1])); \
- /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \
- motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; \
- dmv_y = get_dmv (decoder); \
- \
- m = decoder->top_field_first ? 1 : 3; \
- other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; \
- other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; \
- MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); \
- \
- m = decoder->top_field_first ? 3 : 1; \
- other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; \
- other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; \
- MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0);\
- \
- MOTION_DMV (mpeg2_mc.avg, motion->ref[0], motion_x, motion_y); \
-} \
- \
-static void motion_reuse_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- motion_x = motion->pmv[0][0]; \
- motion_y = motion->pmv[0][1]; \
- \
- MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); \
-} \
- \
-static void motion_zero_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- unsigned int offset; \
- \
- motion->pmv[0][0] = motion->pmv[0][1] = 0; \
- motion->pmv[1][0] = motion->pmv[1][1] = 0; \
- \
- MOTION_ZERO (table, motion->ref[0]); \
-} \
- \
-static void motion_fi_field_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y; \
- uint8_t ** ref_field; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- ref_field = motion->ref2[UBITS (bit_buf, 1)]; \
- DUMPBITS (bit_buf, bits, 1); \
- \
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
- motion->f_code[1]); \
- motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
- motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \
- \
- MOTION (table, ref_field, motion_x, motion_y, 16, 0); \
-} \
- \
-static void motion_fi_16x8_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y; \
- uint8_t ** ref_field; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- ref_field = motion->ref2[UBITS (bit_buf, 1)]; \
- DUMPBITS (bit_buf, bits, 1); \
- \
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[0][0] = motion_x; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
- motion->f_code[1]); \
- motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
- motion->pmv[0][1] = motion_y; \
- \
- MOTION (table, ref_field, motion_x, motion_y, 8, 0); \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- ref_field = motion->ref2[UBITS (bit_buf, 1)]; \
- DUMPBITS (bit_buf, bits, 1); \
- \
- motion_x = motion->pmv[1][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[1][0] = motion_x; \
- \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_y = motion->pmv[1][1] + get_motion_delta (decoder, \
- motion->f_code[1]); \
- motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
- motion->pmv[1][1] = motion_y; \
- \
- MOTION (table, ref_field, motion_x, motion_y, 8, 8); \
-} \
- \
-static void motion_fi_dmv_##FORMAT (mpeg2_decoder_t * const decoder, \
- motion_t * const motion, \
- mpeg2_mc_fct * const * const table) \
-{ \
- int motion_x, motion_y, other_x, other_y; \
- unsigned int pos_x, pos_y, xy_half, offset; \
- \
- (void)table; \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
- motion->f_code[0]); \
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
- motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
- NEEDBITS (bit_buf, bits, bit_ptr); \
- other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (decoder); \
- \
- motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
- motion->f_code[1]); \
- motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
- motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \
- other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (decoder) + \
- decoder->dmv_offset); \
- \
- MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); \
- MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); \
-} \
-
-MOTION_FUNCTIONS (420, MOTION_420, MOTION_FIELD_420, MOTION_DMV_420,
- MOTION_ZERO_420)
-MOTION_FUNCTIONS (422, MOTION_422, MOTION_FIELD_422, MOTION_DMV_422,
- MOTION_ZERO_422)
-MOTION_FUNCTIONS (444, MOTION_444, MOTION_FIELD_444, MOTION_DMV_444,
- MOTION_ZERO_444)
-
-/* like motion_frame, but parsing without actual motion compensation */
-static void motion_fr_conceal (mpeg2_decoder_t * const decoder)
-{
- int tmp;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- tmp = (decoder->f_motion.pmv[0][0] +
- get_motion_delta (decoder, decoder->f_motion.f_code[0]));
- tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]);
- decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- tmp = (decoder->f_motion.pmv[0][1] +
- get_motion_delta (decoder, decoder->f_motion.f_code[1]));
- tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]);
- decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp;
-
- DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
-}
-
-static void motion_fi_conceal (mpeg2_decoder_t * const decoder)
-{
- int tmp;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, 1); /* remove field_select */
-
- tmp = decoder->f_motion.pmv[0][0] +
- get_motion_delta (decoder, decoder->f_motion.f_code[0]);
- tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]);
-
- decoder->f_motion.pmv[1][0] =
- decoder->f_motion.pmv[0][0] = tmp;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- tmp = (decoder->f_motion.pmv[0][1] +
- get_motion_delta (decoder, decoder->f_motion.f_code[1]));
- tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]);
-
- decoder->f_motion.pmv[1][1] =
- decoder->f_motion.pmv[0][1] = tmp;
-
- DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
-}
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-
-#define MOTION_CALL(routine, direction) \
-do { \
- if ((direction) & MACROBLOCK_MOTION_FORWARD) \
- routine (decoder, &decoder->f_motion, mpeg2_mc.put); \
- \
- if ((direction) & MACROBLOCK_MOTION_BACKWARD) \
- { \
- routine (decoder, &decoder->b_motion, \
- ((direction) & MACROBLOCK_MOTION_FORWARD ? \
- mpeg2_mc.avg : mpeg2_mc.put)); \
- } \
-} while (0)
-
-#define NEXT_MACROBLOCK \
-do { \
- decoder->offset += 16; \
- \
- if (decoder->offset == decoder->width) \
- { \
- do { /* just so we can use the break statement */ \
- if (decoder->convert) \
- { \
- decoder->convert (decoder->convert_id, decoder->dest, \
- decoder->v_offset); \
- if (decoder->coding_type == B_TYPE) \
- break; \
- } \
- \
- decoder->dest[0] += decoder->slice_stride; \
- if (MPEG2_COLOR) \
- { \
- decoder->dest[1] += decoder->slice_uv_stride; \
- decoder->dest[2] += decoder->slice_uv_stride; \
- } \
- } while (0); \
- \
- decoder->v_offset += 16; \
- \
- if (decoder->v_offset > decoder->limit_y) \
- return; \
- \
- decoder->offset = 0; \
- } \
-} while (0)
-
-void mpeg2_init_fbuf (mpeg2_decoder_t * decoder,
- uint8_t * current_fbuf[MPEG2_COMPONENTS],
- uint8_t * forward_fbuf[MPEG2_COMPONENTS],
- uint8_t * backward_fbuf[MPEG2_COMPONENTS])
-{
- int offset, stride, height, bottom_field;
-
- stride = decoder->stride_frame;
- bottom_field = (decoder->picture_structure == BOTTOM_FIELD);
- offset = bottom_field ? stride : 0;
- height = decoder->height;
-
- decoder->picture_dest[0] = current_fbuf[0] + offset;
-#if MPEG2_COLOR
- decoder->picture_dest[1] = current_fbuf[1] + (offset >> 1);
- decoder->picture_dest[2] = current_fbuf[2] + (offset >> 1);
-#endif
-
- decoder->f_motion.ref[0][0] = forward_fbuf[0] + offset;
-#if MPEG2_COLOR
- decoder->f_motion.ref[0][1] = forward_fbuf[1] + (offset >> 1);
- decoder->f_motion.ref[0][2] = forward_fbuf[2] + (offset >> 1);
-#endif
-
- decoder->b_motion.ref[0][0] = backward_fbuf[0] + offset;
-#if MPEG2_COLOR
- decoder->b_motion.ref[0][1] = backward_fbuf[1] + (offset >> 1);
- decoder->b_motion.ref[0][2] = backward_fbuf[2] + (offset >> 1);
-#endif
-
- if (decoder->picture_structure != FRAME_PICTURE)
- {
- decoder->dmv_offset = bottom_field ? 1 : -1;
- decoder->f_motion.ref2[0] = decoder->f_motion.ref[bottom_field];
- decoder->f_motion.ref2[1] = decoder->f_motion.ref[!bottom_field];
- decoder->b_motion.ref2[0] = decoder->b_motion.ref[bottom_field];
- decoder->b_motion.ref2[1] = decoder->b_motion.ref[!bottom_field];
- offset = stride - offset;
-
- if (decoder->second_field && (decoder->coding_type != B_TYPE))
- forward_fbuf = current_fbuf;
-
- decoder->f_motion.ref[1][0] = forward_fbuf[0] + offset;
-#if MPEG2_COLOR
- decoder->f_motion.ref[1][1] = forward_fbuf[1] + (offset >> 1);
- decoder->f_motion.ref[1][2] = forward_fbuf[2] + (offset >> 1);
-#endif
- decoder->b_motion.ref[1][0] = backward_fbuf[0] + offset;
-#if MPEG2_COLOR
- decoder->b_motion.ref[1][1] = backward_fbuf[1] + (offset >> 1);
- decoder->b_motion.ref[1][2] = backward_fbuf[2] + (offset >> 1);
-#endif
- stride <<= 1;
- height >>= 1;
- }
-
- decoder->stride = stride;
- decoder->slice_stride = 16 * stride;
-#if MPEG2_COLOR
- decoder->uv_stride = stride >> 1;
- decoder->slice_uv_stride =
- decoder->slice_stride >> (2 - decoder->chroma_format);
-#endif
- decoder->limit_x = 2 * decoder->width - 32;
- decoder->limit_y_16 = 2 * height - 32;
- decoder->limit_y_8 = 2 * height - 16;
- decoder->limit_y = height - 16;
-
- if (decoder->mpeg1)
- {
- decoder->motion_parser[0] = motion_zero_420;
- decoder->motion_parser[MC_FRAME] = motion_mp1;
- decoder->motion_parser[4] = motion_reuse_420;
- }
- else if (decoder->picture_structure == FRAME_PICTURE)
- {
- if (decoder->chroma_format == 0)
- {
- decoder->motion_parser[0] = motion_zero_420;
- decoder->motion_parser[MC_FIELD] = motion_fr_field_420;
- decoder->motion_parser[MC_FRAME] = motion_fr_frame_420;
- decoder->motion_parser[MC_DMV] = motion_fr_dmv_420;
- decoder->motion_parser[4] = motion_reuse_420;
- }
- else if (decoder->chroma_format == 1)
- {
- decoder->motion_parser[0] = motion_zero_422;
- decoder->motion_parser[MC_FIELD] = motion_fr_field_422;
- decoder->motion_parser[MC_FRAME] = motion_fr_frame_422;
- decoder->motion_parser[MC_DMV] = motion_fr_dmv_422;
- decoder->motion_parser[4] = motion_reuse_422;
- }
- else
- {
- decoder->motion_parser[0] = motion_zero_444;
- decoder->motion_parser[MC_FIELD] = motion_fr_field_444;
- decoder->motion_parser[MC_FRAME] = motion_fr_frame_444;
- decoder->motion_parser[MC_DMV] = motion_fr_dmv_444;
- decoder->motion_parser[4] = motion_reuse_444;
- }
- }
- else
- {
- if (decoder->chroma_format == 0)
- {
- decoder->motion_parser[0] = motion_zero_420;
- decoder->motion_parser[MC_FIELD] = motion_fi_field_420;
- decoder->motion_parser[MC_16X8] = motion_fi_16x8_420;
- decoder->motion_parser[MC_DMV] = motion_fi_dmv_420;
- decoder->motion_parser[4] = motion_reuse_420;
- }
- else if (decoder->chroma_format == 1)
- {
- decoder->motion_parser[0] = motion_zero_422;
- decoder->motion_parser[MC_FIELD] = motion_fi_field_422;
- decoder->motion_parser[MC_16X8] = motion_fi_16x8_422;
- decoder->motion_parser[MC_DMV] = motion_fi_dmv_422;
- decoder->motion_parser[4] = motion_reuse_422;
- }
- else
- {
- decoder->motion_parser[0] = motion_zero_444;
- decoder->motion_parser[MC_FIELD] = motion_fi_field_444;
- decoder->motion_parser[MC_16X8] = motion_fi_16x8_444;
- decoder->motion_parser[MC_DMV] = motion_fi_dmv_444;
- decoder->motion_parser[4] = motion_reuse_444;
- }
- }
-}
-
-static inline int slice_init (mpeg2_decoder_t * const decoder, int code)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- int offset;
- const MBAtab * mba;
-
-#if MPEG2_COLOR
- decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
- decoder->dc_dct_pred[2] = 16384;
-#else
- decoder->dc_dct_pred[0] = 16384;
-#endif
-
- decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0;
- decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0;
- decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0;
- decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0;
-
- if (decoder->vertical_position_extension)
- {
- code += UBITS (bit_buf, 3) << 7;
- DUMPBITS (bit_buf, bits, 3);
- }
-
- decoder->v_offset = (code - 1) * 16;
- offset = 0;
-
- if (!(decoder->convert) || decoder->coding_type != B_TYPE)
- {
- offset = (code - 1) * decoder->slice_stride;
- }
-
- decoder->dest[0] = decoder->picture_dest[0] + offset;
-#if MPEG2_COLOR
- offset >>= (2 - decoder->chroma_format);
- decoder->dest[1] = decoder->picture_dest[1] + offset;
- decoder->dest[2] = decoder->picture_dest[2] + offset;
-#endif
-
- get_quantizer_scale (decoder);
-
- /* ignore intra_slice and all the extra data */
- while (bit_buf & 0x80000000)
- {
- DUMPBITS (bit_buf, bits, 9);
- NEEDBITS (bit_buf, bits, bit_ptr);
- }
-
- /* decode initial macroblock address increment */
- offset = 0;
- while (1)
- {
- if (bit_buf >= 0x08000000)
- {
- mba = MBA_5 + (UBITS (bit_buf, 6) - 2);
- break;
- }
- else if (bit_buf >= 0x01800000)
- {
- mba = MBA_11 + (UBITS (bit_buf, 12) - 24);
- break;
- }
- else
- {
- switch (UBITS (bit_buf, 12))
- {
- case 8: /* macroblock_escape */
- offset += 33;
- DUMPBITS (bit_buf, bits, 11);
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- case 15: /* macroblock_stuffing (MPEG1 only) */
- bit_buf &= 0xfffff;
- DUMPBITS (bit_buf, bits, 11);
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- default: /* error */
- return 1;
- }
- }
- }
-
- DUMPBITS (bit_buf, bits, mba->len + 1);
- decoder->offset = (offset + mba->mba) << 4;
-
- while (decoder->offset - decoder->width >= 0)
- {
- decoder->offset -= decoder->width;
-
- if (!(decoder->convert) || decoder->coding_type != B_TYPE)
- {
- decoder->dest[0] += decoder->slice_stride;
-#if MPEG2_COLOR
- decoder->dest[1] += decoder->slice_uv_stride;
- decoder->dest[2] += decoder->slice_uv_stride;
-#endif
- }
-
- decoder->v_offset += 16;
- }
-
- if (decoder->v_offset > decoder->limit_y)
- return 1;
-
- return 0;
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code,
- const uint8_t * const buffer)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
-
- bitstream_init (decoder, buffer);
-
- if (slice_init (decoder, code))
- return;
-
- while (1)
- {
- int macroblock_modes;
- int mba_inc;
- const MBAtab * mba;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
-
- macroblock_modes = get_macroblock_modes (decoder);
-
- /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */
- if (macroblock_modes & MACROBLOCK_QUANT)
- get_quantizer_scale (decoder);
-
- if (macroblock_modes & MACROBLOCK_INTRA)
- {
- int DCT_offset, DCT_stride;
- int offset;
- uint8_t * dest_y;
-
- if (decoder->concealment_motion_vectors)
- {
- if (decoder->picture_structure == FRAME_PICTURE)
- motion_fr_conceal (decoder);
- else
- motion_fi_conceal (decoder);
- }
- else
- {
- decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0;
- decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0;
- decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0;
- decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0;
- }
-
- if (macroblock_modes & DCT_TYPE_INTERLACED)
- {
- DCT_offset = decoder->stride;
- DCT_stride = decoder->stride * 2;
- }
- else
- {
- DCT_offset = decoder->stride * 8;
- DCT_stride = decoder->stride;
- }
-
- offset = decoder->offset;
- dest_y = decoder->dest[0] + offset;
- slice_intra_DCT (decoder, 0, dest_y, DCT_stride);
- slice_intra_DCT (decoder, 0, dest_y + 8, DCT_stride);
- slice_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride);
- slice_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride);
-
-#if MPEG2_COLOR
- if (likely (decoder->chroma_format == 0))
- {
- slice_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1),
- decoder->uv_stride);
- slice_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1),
- decoder->uv_stride);
-
- if (decoder->coding_type == D_TYPE)
- {
- NEEDBITS (bit_buf, bits, bit_ptr);
- DUMPBITS (bit_buf, bits, 1);
- }
- }
- else if (likely (decoder->chroma_format == 1))
- {
- uint8_t * dest_u = decoder->dest[1] + (offset >> 1);
- uint8_t * dest_v = decoder->dest[2] + (offset >> 1);
-
- DCT_stride >>= 1;
- DCT_offset >>= 1;
-
- slice_intra_DCT (decoder, 1, dest_u, DCT_stride);
- slice_intra_DCT (decoder, 2, dest_v, DCT_stride);
- slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride);
- slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride);
- }
- else
- {
- uint8_t * dest_u = decoder->dest[1] + offset;
- uint8_t * dest_v = decoder->dest[2] + offset;
-
- slice_intra_DCT (decoder, 1, dest_u, DCT_stride);
- slice_intra_DCT (decoder, 2, dest_v, DCT_stride);
- slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride);
- slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride);
- slice_intra_DCT (decoder, 1, dest_u + 8, DCT_stride);
- slice_intra_DCT (decoder, 2, dest_v + 8, DCT_stride);
- slice_intra_DCT (decoder, 1, dest_u + DCT_offset + 8,
- DCT_stride);
- slice_intra_DCT (decoder, 2, dest_v + DCT_offset + 8,
- DCT_stride);
- }
-#else
- skip_chroma_intra(decoder);
-#endif /* MPEG2_COLOR */
- }
- else
- {
- motion_parser_t * parser;
-
- parser =
- decoder->motion_parser[macroblock_modes >> MOTION_TYPE_SHIFT];
- MOTION_CALL (parser, macroblock_modes);
-
- if (macroblock_modes & MACROBLOCK_PATTERN)
- {
- int coded_block_pattern;
- int DCT_offset, DCT_stride;
-
- if (macroblock_modes & DCT_TYPE_INTERLACED)
- {
- DCT_offset = decoder->stride;
- DCT_stride = decoder->stride * 2;
- }
- else
- {
- DCT_offset = decoder->stride * 8;
- DCT_stride = decoder->stride;
- }
-
- coded_block_pattern = get_coded_block_pattern (decoder);
-
- if (likely (decoder->chroma_format == 0))
- {
- int offset = decoder->offset;
- uint8_t * dest_y = decoder->dest[0] + offset;
-
- if (coded_block_pattern & 1)
- slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride);
-
- if (coded_block_pattern & 2)
- slice_non_intra_DCT (decoder, 0, dest_y + 8,
- DCT_stride);
-
- if (coded_block_pattern & 4)
- slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset,
- DCT_stride);
-
- if (coded_block_pattern & 8)
- slice_non_intra_DCT (decoder, 0,
- dest_y + DCT_offset + 8,
- DCT_stride);
-#if MPEG2_COLOR
- if (coded_block_pattern & 16)
- slice_non_intra_DCT (decoder, 1,
- decoder->dest[1] + (offset >> 1),
- decoder->uv_stride);
-
- if (coded_block_pattern & 32)
- slice_non_intra_DCT (decoder, 2,
- decoder->dest[2] + (offset >> 1),
- decoder->uv_stride);
-#endif /* MPEG2_COLOR */
- }
- else if (likely (decoder->chroma_format == 1))
- {
- int offset;
- uint8_t * dest_y;
-
- coded_block_pattern |= bit_buf & (3 << 30);
- DUMPBITS (bit_buf, bits, 2);
-
- offset = decoder->offset;
- dest_y = decoder->dest[0] + offset;
-
- if (coded_block_pattern & 1)
- slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride);
-
- if (coded_block_pattern & 2)
- slice_non_intra_DCT (decoder, 0, dest_y + 8,
- DCT_stride);
-
- if (coded_block_pattern & 4)
- slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset,
- DCT_stride);
-
- if (coded_block_pattern & 8)
- slice_non_intra_DCT (decoder, 0,
- dest_y + DCT_offset + 8,
- DCT_stride);
-#if MPEG2_COLOR
- DCT_stride >>= 1;
- DCT_offset = (DCT_offset + offset) >> 1;
-
- if (coded_block_pattern & 16)
- slice_non_intra_DCT (decoder, 1,
- decoder->dest[1] + (offset >> 1),
- DCT_stride);
-
- if (coded_block_pattern & 32)
- slice_non_intra_DCT (decoder, 2,
- decoder->dest[2] + (offset >> 1),
- DCT_stride);
-
- if (coded_block_pattern & (2 << 30))
- slice_non_intra_DCT (decoder, 1,
- decoder->dest[1] + DCT_offset,
- DCT_stride);
-
- if (coded_block_pattern & (1 << 30))
- slice_non_intra_DCT (decoder, 2,
- decoder->dest[2] + DCT_offset,
- DCT_stride);
-#endif /* MPEG2_COLOR */
- }
- else
- {
- int offset = decoder->offset;
- uint8_t * dest_y = decoder->dest[0] + offset;
-#if MPEG2_COLOR
- uint8_t * dest_u = decoder->dest[1] + offset;
- uint8_t * dest_v = decoder->dest[2] + offset;
-#endif
- coded_block_pattern |= bit_buf & (63 << 26);
- DUMPBITS (bit_buf, bits, 6);
-
- if (coded_block_pattern & 1)
- slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride);
-
- if (coded_block_pattern & 2)
- slice_non_intra_DCT (decoder, 0, dest_y + 8,
- DCT_stride);
-
- if (coded_block_pattern & 4)
- slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset,
- DCT_stride);
-
- if (coded_block_pattern & 8)
- slice_non_intra_DCT (decoder, 0,
- dest_y + DCT_offset + 8,
- DCT_stride);
-#if MPEG2_COLOR
- if (coded_block_pattern & 16)
- slice_non_intra_DCT (decoder, 1, dest_u, DCT_stride);
-
- if (coded_block_pattern & 32)
- slice_non_intra_DCT (decoder, 2, dest_v, DCT_stride);
-
- if (coded_block_pattern & (32 << 26))
- slice_non_intra_DCT (decoder, 1, dest_u + DCT_offset,
- DCT_stride);
-
- if (coded_block_pattern & (16 << 26))
- slice_non_intra_DCT (decoder, 2, dest_v + DCT_offset,
- DCT_stride);
-
- if (coded_block_pattern & (8 << 26))
- slice_non_intra_DCT (decoder, 1, dest_u + 8,
- DCT_stride);
-
- if (coded_block_pattern & (4 << 26))
- slice_non_intra_DCT (decoder, 2, dest_v + 8,
- DCT_stride);
-
- if (coded_block_pattern & (2 << 26))
- slice_non_intra_DCT (decoder, 1,
- dest_u + DCT_offset + 8,
- DCT_stride);
-
- if (coded_block_pattern & (1 << 26))
- slice_non_intra_DCT (decoder, 2,
- dest_v + DCT_offset + 8,
- DCT_stride);
-#endif /* MPEG2_COLOR */
- }
-#if !MPEG2_COLOR
- skip_chroma_non_intra(decoder, coded_block_pattern);
-#endif
- }
-
-#if MPEG2_COLOR
- decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
- decoder->dc_dct_pred[2] = 16384;
-#else
- decoder->dc_dct_pred[0] = 16384;
-#endif
- }
-
- NEXT_MACROBLOCK;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- mba_inc = 0;
-
- while (1)
- {
- if (bit_buf >= 0x10000000)
- {
- mba = MBA_5 + (UBITS (bit_buf, 5) - 2);
- break;
- }
- else if (bit_buf >= 0x03000000)
- {
- mba = MBA_11 + (UBITS (bit_buf, 11) - 24);
- break;
- }
- else
- {
- switch (UBITS (bit_buf, 11))
- {
- case 8: /* macroblock_escape */
- mba_inc += 33;
- /* pass through */
- case 15: /* macroblock_stuffing (MPEG1 only) */
- DUMPBITS (bit_buf, bits, 11);
- NEEDBITS (bit_buf, bits, bit_ptr);
- continue;
- default: /* end of slice, or error */
- return;
- }
- }
- }
-
- DUMPBITS (bit_buf, bits, mba->len);
- mba_inc += mba->mba;
-
- if (mba_inc)
- {
-#if MPEG2_COLOR
- decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
- decoder->dc_dct_pred[2] = 16384;
-#else
- decoder->dc_dct_pred[0] = 16384;
-#endif
- if (decoder->coding_type == P_TYPE)
- {
- do
- {
- MOTION_CALL (decoder->motion_parser[0],
- MACROBLOCK_MOTION_FORWARD);
- NEXT_MACROBLOCK;
- }
- while (--mba_inc);
- }
- else
- {
- do
- {
- MOTION_CALL (decoder->motion_parser[4], macroblock_modes);
- NEXT_MACROBLOCK;
- }
- while (--mba_inc);
- }
- }
- }
-
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
diff --git a/apps/plugins/mpegplayer/libmpeg2/vlc.h b/apps/plugins/mpegplayer/libmpeg2/vlc.h
deleted file mode 100644
index d1b6a98cde..0000000000
--- a/apps/plugins/mpegplayer/libmpeg2/vlc.h
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * vlc.h
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.12
- */
-
-#define GETWORD(bit_buf, shift, bit_ptr) \
-do { \
- bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \
- bit_ptr += 2; \
-} while (0)
-
-static inline void bitstream_init (mpeg2_decoder_t * decoder,
- const uint8_t * start)
-{
- decoder->bitstream_buf =
- (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3];
- decoder->bitstream_ptr = start + 4;
- decoder->bitstream_bits = -16;
-}
-
-/* make sure that there are at least 16 valid bits in bit_buf */
-#define NEEDBITS(bit_buf, bits, bit_ptr) \
-do { \
- if (unlikely (bits > 0)) { \
- GETWORD (bit_buf, bits, bit_ptr); \
- bits -= 16; \
- } \
-} while (0)
-
-/* remove num valid bits from bit_buf */
-#define DUMPBITS(bit_buf, bits, num) \
-do { \
- bit_buf <<= (num); \
- bits += (num); \
-} while (0)
-
-/* take num bits from the high part of bit_buf and zero extend them */
-#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num)))
-
-/* take num bits from the high part of bit_buf and sign extend them */
-#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num)))
-
-typedef struct {
- uint8_t modes;
- uint8_t len;
-} MBtab;
-
-typedef struct {
- uint8_t delta;
- uint8_t len;
-} MVtab;
-
-typedef struct {
- int8_t dmv;
- uint8_t len;
-} DMVtab;
-
-typedef struct {
- uint8_t cbp;
- uint8_t len;
-} CBPtab;
-
-typedef struct {
- uint8_t size;
- uint8_t len;
-} DCtab;
-
-typedef struct {
- uint8_t run;
- uint8_t level;
- uint8_t len;
-} DCTtab;
-
-typedef struct {
- uint8_t mba;
- uint8_t len;
-} MBAtab;
-
-
-#define INTRA MACROBLOCK_INTRA
-#define QUANT MACROBLOCK_QUANT
-
-static const MBtab MB_I [] ICONST_ATTR = {
- {INTRA|QUANT, 2}, {INTRA, 1}
-};
-
-#define MC MACROBLOCK_MOTION_FORWARD
-#define CODED MACROBLOCK_PATTERN
-
-static const MBtab MB_P [] ICONST_ATTR = {
- {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5},
- {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3},
- {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
- {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}
-};
-
-#define FWD MACROBLOCK_MOTION_FORWARD
-#define BWD MACROBLOCK_MOTION_BACKWARD
-#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD
-
-static const MBtab MB_B [] ICONST_ATTR = {
- {0, 6}, {INTRA|QUANT, 6},
- {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6},
- {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5},
- {INTRA, 5}, {INTRA, 5},
- {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4},
- {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4},
- {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
- {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
- {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
- {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}
-};
-
-#undef INTRA
-#undef QUANT
-#undef MC
-#undef CODED
-#undef FWD
-#undef BWD
-#undef INTER
-
-
-static const MVtab MV_4 [] ICONST_ATTR = {
- { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2}
-};
-
-static const MVtab MV_10 [] ICONST_ATTR = {
- { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10},
- { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10},
- {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9},
- { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7},
- { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7},
- { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}
-};
-
-
-static const DMVtab DMV_2 [] ICONST_ATTR = {
- { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
-};
-
-
-static const CBPtab CBP_7 [] ICONST_ATTR = {
- {0x11, 7}, {0x12, 7}, {0x14, 7}, {0x18, 7},
- {0x21, 7}, {0x22, 7}, {0x24, 7}, {0x28, 7},
- {0x3f, 6}, {0x3f, 6}, {0x30, 6}, {0x30, 6},
- {0x09, 6}, {0x09, 6}, {0x06, 6}, {0x06, 6},
- {0x1f, 5}, {0x1f, 5}, {0x1f, 5}, {0x1f, 5},
- {0x10, 5}, {0x10, 5}, {0x10, 5}, {0x10, 5},
- {0x2f, 5}, {0x2f, 5}, {0x2f, 5}, {0x2f, 5},
- {0x20, 5}, {0x20, 5}, {0x20, 5}, {0x20, 5},
- {0x07, 5}, {0x07, 5}, {0x07, 5}, {0x07, 5},
- {0x0b, 5}, {0x0b, 5}, {0x0b, 5}, {0x0b, 5},
- {0x0d, 5}, {0x0d, 5}, {0x0d, 5}, {0x0d, 5},
- {0x0e, 5}, {0x0e, 5}, {0x0e, 5}, {0x0e, 5},
- {0x05, 5}, {0x05, 5}, {0x05, 5}, {0x05, 5},
- {0x0a, 5}, {0x0a, 5}, {0x0a, 5}, {0x0a, 5},
- {0x03, 5}, {0x03, 5}, {0x03, 5}, {0x03, 5},
- {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5},
- {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4},
- {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4},
- {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4},
- {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4},
- {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
- {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
- {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
- {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
- {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
- {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
- {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
- {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}
-};
-
-static const CBPtab CBP_9 [] ICONST_ATTR = {
- {0, 9}, {0x00, 9}, {0x39, 9}, {0x36, 9},
- {0x37, 9}, {0x3b, 9}, {0x3d, 9}, {0x3e, 9},
- {0x17, 8}, {0x17, 8}, {0x1b, 8}, {0x1b, 8},
- {0x1d, 8}, {0x1d, 8}, {0x1e, 8}, {0x1e, 8},
- {0x27, 8}, {0x27, 8}, {0x2b, 8}, {0x2b, 8},
- {0x2d, 8}, {0x2d, 8}, {0x2e, 8}, {0x2e, 8},
- {0x19, 8}, {0x19, 8}, {0x16, 8}, {0x16, 8},
- {0x29, 8}, {0x29, 8}, {0x26, 8}, {0x26, 8},
- {0x35, 8}, {0x35, 8}, {0x3a, 8}, {0x3a, 8},
- {0x33, 8}, {0x33, 8}, {0x3c, 8}, {0x3c, 8},
- {0x15, 8}, {0x15, 8}, {0x1a, 8}, {0x1a, 8},
- {0x13, 8}, {0x13, 8}, {0x1c, 8}, {0x1c, 8},
- {0x25, 8}, {0x25, 8}, {0x2a, 8}, {0x2a, 8},
- {0x23, 8}, {0x23, 8}, {0x2c, 8}, {0x2c, 8},
- {0x31, 8}, {0x31, 8}, {0x32, 8}, {0x32, 8},
- {0x34, 8}, {0x34, 8}, {0x38, 8}, {0x38, 8}
-};
-
-
-static const DCtab DC_lum_5 [] ICONST_ATTR = {
- {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
- {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
- {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
- {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}
-};
-
-static const DCtab DC_chrom_5 [] ICONST_ATTR = {
- {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
- {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
- {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
- {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}
-};
-
-static const DCtab DC_long [] ICONST_ATTR = {
- {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
- {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
- {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6},
- {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9}
-};
-
-
-static const DCTtab DCT_16 [] ICONST_ATTR = {
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
- { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
- { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
- { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
-};
-
-static const DCTtab DCT_15 [] ICONST_ATTR = {
- { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
- { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
- { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
- { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
- { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
- { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
- { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
- { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
- { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
- { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
- { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
- { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
-};
-
-static const DCTtab DCT_13 [] ICONST_ATTR = {
- { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
- { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
- { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
- { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
- { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
- { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
- { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
- { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
- { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
- { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
- { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
- { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
-};
-
-static const DCTtab DCT_B14_10 [] ICONST_ATTR = {
- { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
- { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
-};
-
-static const DCTtab DCT_B14_8 [] ICONST_ATTR = {
- { 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12},
- { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
- { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
- { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
- { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
- { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
- { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
- { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
- { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
-};
-
-static const DCTtab DCT_B14AC_5 [] ICONST_ATTR = {
- { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
- { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
- {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
-};
-
-static const DCTtab DCT_B14DC_5 [] ICONST_ATTR = {
- { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
- { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
-};
-
-static const DCTtab DCT_B15_10 [] ICONST_ATTR = {
- { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
- { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
-};
-
-static const DCTtab DCT_B15_8 [] ICONST_ATTR = {
- { 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12},
- { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
- { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
- { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
- { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
- { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
- { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
- { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
- { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
- { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
- { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
- { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
- { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
- { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
- { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
- { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
- { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
- { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
- { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
- { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
- { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
- { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
-};
-
-
-static const MBAtab MBA_5 [] ICONST_ATTR = {
- {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4},
- {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
- {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
- {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}
-};
-
-static const MBAtab MBA_11 [] ICONST_ATTR = {
- {32, 11}, {31, 11}, {30, 11}, {29, 11},
- {28, 11}, {27, 11}, {26, 11}, {25, 11},
- {24, 11}, {23, 11}, {22, 11}, {21, 11},
- {20, 10}, {20, 10}, {19, 10}, {19, 10},
- {18, 10}, {18, 10}, {17, 10}, {17, 10},
- {16, 10}, {16, 10}, {15, 10}, {15, 10},
- {14, 8}, {14, 8}, {14, 8}, {14, 8},
- {14, 8}, {14, 8}, {14, 8}, {14, 8},
- {13, 8}, {13, 8}, {13, 8}, {13, 8},
- {13, 8}, {13, 8}, {13, 8}, {13, 8},
- {12, 8}, {12, 8}, {12, 8}, {12, 8},
- {12, 8}, {12, 8}, {12, 8}, {12, 8},
- {11, 8}, {11, 8}, {11, 8}, {11, 8},
- {11, 8}, {11, 8}, {11, 8}, {11, 8},
- {10, 8}, {10, 8}, {10, 8}, {10, 8},
- {10, 8}, {10, 8}, {10, 8}, {10, 8},
- { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
- { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
-};
diff --git a/apps/plugins/mpegplayer/mpeg_alloc.h b/apps/plugins/mpegplayer/mpeg_alloc.h
deleted file mode 100644
index 9acfbc5dec..0000000000
--- a/apps/plugins/mpegplayer/mpeg_alloc.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2007 by Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef MPEG_ALLOC_H
-#define MPEG_ALLOC_H
-
-/* returns the remaining mpeg2 buffer and it's size */
-void * mpeg2_get_buf(size_t *size);
-void *mpeg_malloc(size_t size, mpeg2_alloc_t reason);
-/* Grabs all the buffer available sans margin */
-void *mpeg_malloc_all(size_t *size_out, mpeg2_alloc_t reason);
-/* Initializes the malloc buffer with the given base buffer */
-bool mpeg_alloc_init(unsigned char *buf, size_t mallocsize);
-
-#endif /* MPEG_ALLOC_H */
diff --git a/apps/plugins/mpegplayer/mpeg_misc.c b/apps/plugins/mpegplayer/mpeg_misc.c
deleted file mode 100644
index 31f0644212..0000000000
--- a/apps/plugins/mpegplayer/mpeg_misc.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Miscellaneous helper API definitions
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-
-/** Streams **/
-
-/* Initializes the cursor */
-void stream_scan_init(struct stream_scan *sk)
-{
- dbuf_l2_init(&sk->l2);
-}
-
-/* Ensures direction is -1 or 1 and margin is properly initialized */
-void stream_scan_normalize(struct stream_scan *sk)
-{
- if (sk->dir >= 0)
- {
- sk->dir = SSCAN_FORWARD;
- sk->margin = sk->len;
- }
- else if (sk->dir < 0)
- {
- sk->dir = SSCAN_REVERSE;
- sk->margin = 0;
- }
-}
-
-/* Moves a scan cursor. If amount is positive, the increment is in the scan
- * direction, otherwise opposite the scan direction */
-void stream_scan_offset(struct stream_scan *sk, off_t by)
-{
- off_t bydir = by*sk->dir;
- sk->pos += bydir;
- sk->margin -= bydir;
- sk->len -= by;
-}
-
-/** Time helpers **/
-void ts_to_hms(uint32_t pts, struct hms *hms)
-{
- hms->frac = pts % TS_SECOND;
- hms->sec = pts / TS_SECOND;
- hms->min = hms->sec / 60;
- hms->hrs = hms->min / 60;
- hms->sec %= 60;
- hms->min %= 60;
-}
-
-void hms_format(char *buf, size_t bufsize, struct hms *hms)
-{
- /* Only display hours if nonzero */
- if (hms->hrs != 0)
- {
- rb->snprintf(buf, bufsize, "%u:%02u:%02u",
- hms->hrs, hms->min, hms->sec);
- }
- else
- {
- rb->snprintf(buf, bufsize, "%u:%02u",
- hms->min, hms->sec);
- }
-}
-
-/** Maths **/
-uint32_t muldiv_uint32(uint32_t multiplicand,
- uint32_t multiplier,
- uint32_t divisor)
-{
- if (divisor != 0)
- {
- uint64_t prod = (uint64_t)multiplier*multiplicand + divisor/2;
-
- if ((uint32_t)(prod >> 32) < divisor)
- return (uint32_t)(prod / divisor);
- }
- else if (multiplicand == 0 || multiplier == 0)
- {
- return 0; /* 0/0 = 0 : yaya */
- }
- /* else (> 0) / 0 = UINT32_MAX */
-
- return UINT32_MAX; /* Saturate */
-}
-
-
-/** Lists **/
-
-/* Does the list have any members? */
-bool list_is_empty(void **list)
-{
- return *list == NULL;
-}
-
-/* Is the item inserted into a particular list? */
-bool list_is_member(void **list, void *item)
-{
- return *rb->find_array_ptr(list, item) != NULL;
-}
-
-/* Removes an item from a list - returns true if item was found
- * and thus removed. */
-bool list_remove_item(void **list, void *item)
-{
- return rb->remove_array_ptr(list, item) != -1;
-}
-
-/* Adds a list item, insert last, if not already present. */
-void list_add_item(void **list, void *item)
-{
- void **item_p = rb->find_array_ptr(list, item);
- if (*item_p == NULL)
- *item_p = item;
-}
-
-/* Clears the entire list. */
-void list_clear_all(void **list)
-{
- while (*list != NULL)
- *list++ = NULL;
-}
-
-/* Enumerate all items in the array, passing each item in turn to the
- * callback as well as the data value. The current item may be safely
- * removed. Other changes during enumeration are undefined. The callback
- * may return 'false' to stop the enumeration early. */
-void list_enum_items(void **list,
- list_enum_callback_t callback,
- void* data)
-{
- for (;;)
- {
- void *item = *list;
-
- if (item == NULL)
- break;
-
- if (callback != NULL && !callback(item, data))
- break;
-
- if (*list == item)
- list++; /* Item still there */
- }
-}
-
-
-/** System events **/
-static long mpeg_sysevent_id;
-
-void mpeg_sysevent_clear(void)
-{
- mpeg_sysevent_id = 0;
-}
-
-void mpeg_sysevent_set(void)
-{
- /* Nonzero and won't invoke anything in default event handler */
- mpeg_sysevent_id = ACTION_STD_CANCEL;
-}
-
-long mpeg_sysevent(void)
-{
- return mpeg_sysevent_id;
-}
-
-int mpeg_sysevent_callback(int btn,
- const struct menu_item_ex *menu,
- struct gui_synclist *this_list)
-{
- (void) this_list;
- switch (btn)
- {
- case SYS_USB_CONNECTED:
- case SYS_POWEROFF:
- case SYS_REBOOT:
- mpeg_sysevent_id = btn;
- return ACTION_STD_CANCEL;
- }
-
- return btn;
- (void)menu;
-}
-
-void mpeg_sysevent_handle(void)
-{
- long id = mpeg_sysevent();
- if (id != 0)
- rb->default_event_handler(id);
-}
-
-
-/** Buttons **/
-
-int mpeg_button_get(int timeout)
-{
- int button;
-
- mpeg_sysevent_clear();
- button = timeout == TIMEOUT_BLOCK ? rb->button_get(true) :
- rb->button_get_w_tmo(timeout);
-
- /* Produce keyclick */
- rb->keyclick_click(true, button);
-
- return mpeg_sysevent_callback(button, NULL, NULL);
-}
-
diff --git a/apps/plugins/mpegplayer/mpeg_misc.h b/apps/plugins/mpegplayer/mpeg_misc.h
deleted file mode 100644
index e04db0e19d..0000000000
--- a/apps/plugins/mpegplayer/mpeg_misc.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Miscellaneous helper API declarations
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef MPEG_MISC_H
-#define MPEG_MISC_H
-
-/* Miscellaneous helpers */
-#ifndef ALIGNED_ATTR
-#define ALIGNED_ATTR(x) __attribute__((aligned(x)))
-#endif
-
-#include "disk_buf.h"
-
-/* Generic states for when things are too simple to care about naming them */
-enum state_enum
-{
- STATE0 = 0,
- STATE1,
- STATE2,
- STATE3,
- STATE4,
- STATE5,
- STATE6,
- STATE7,
- STATE8,
- STATE9,
-};
-
-/* Macros for comparing memory bytes to a series of constant bytes in an
- efficient manner - evaluate to true if corresponding bytes match */
-#if defined (CPU_ARM)
-/* ARM must load 32-bit values at addres % 4 == 0 offsets but this data
- isn't aligned nescessarily, so just byte compare */
-#define CMP_3_CONST(_a, _b) \
- ({ int _x; \
- asm volatile ( \
- "ldrb %[x], [%[a], #0] \n" \
- "eors %[x], %[x], %[b0] \n" \
- "ldreqb %[x], [%[a], #1] \n" \
- "eoreqs %[x], %[x], %[b1] \n" \
- "ldreqb %[x], [%[a], #2] \n" \
- "eoreqs %[x], %[x], %[b2] \n" \
- : [x]"=&r"(_x) \
- : [a]"r"(_a), \
- [b0]"i"(((_b) >> 24) & 0xff), \
- [b1]"i"(((_b) >> 16) & 0xff), \
- [b2]"i"(((_b) >> 8) & 0xff) \
- ); \
- _x == 0; })
-
-#define CMP_4_CONST(_a, _b) \
- ({ int _x; \
- asm volatile ( \
- "ldrb %[x], [%[a], #0] \n" \
- "eors %[x], %[x], %[b0] \n" \
- "ldreqb %[x], [%[a], #1] \n" \
- "eoreqs %[x], %[x], %[b1] \n" \
- "ldreqb %[x], [%[a], #2] \n" \
- "eoreqs %[x], %[x], %[b2] \n" \
- "ldreqb %[x], [%[a], #3] \n" \
- "eoreqs %[x], %[x], %[b3] \n" \
- : [x]"=&r"(_x) \
- : [a]"r"(_a), \
- [b0]"i"(((_b) >> 24) & 0xff), \
- [b1]"i"(((_b) >> 16) & 0xff), \
- [b2]"i"(((_b) >> 8) & 0xff), \
- [b3]"i"(((_b) ) & 0xff) \
- ); \
- _x == 0; })
-
-#elif defined (CPU_COLDFIRE)
-/* Coldfire can just load a 32 bit value at any offset but ASM is not the
- best way to integrate this with the C code */
-#define CMP_3_CONST(a, b) \
- (((*(uint32_t *)(a) >> 8) == ((uint32_t)(b) >> 8)))
-
-#define CMP_4_CONST(a, b) \
- ((*(uint32_t *)(a) == (b)))
-
-#else
-/* Don't know what this is - use bytewise comparisons */
-#define CMP_3_CONST(a, b) \
- (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
- ((a)[1] ^ (((b) >> 16) & 0xff)) | \
- ((a)[2] ^ (((b) >> 8) & 0xff)) ) == 0)
-
-#define CMP_4_CONST(a, b) \
- (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
- ((a)[1] ^ (((b) >> 16) & 0xff)) | \
- ((a)[2] ^ (((b) >> 8) & 0xff)) | \
- ((a)[3] ^ (((b) ) & 0xff)) ) == 0)
-#endif /* CPU_* */
-
-
-/** Streams **/
-
-/* Convert PTS/DTS ticks to our clock ticks */
-#define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / TS_SECOND)
-/* Convert our clock ticks to PTS/DTS ticks */
-#define TICKS_TO_TS(ts) ((uint64_t)TS_SECOND*(ts) / CLOCK_RATE)
-/* Convert timecode ticks to our clock ticks */
-#define TC_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / TC_SECOND)
-/* Convert our clock ticks to timecode ticks */
-#define TICKS_TO_TC(stamp) ((uint64_t)TC_SECOND*(stamp) / CLOCK_RATE)
-/* Convert timecode ticks to timestamp ticks */
-#define TC_TO_TS(stamp) ((stamp) / 600)
-
-/*
- * S = start position, E = end position
- *
- * pos:
- * initialize to search start position (S)
- *
- * len:
- * initialize to = ABS(S-E)
- * scanning = remaining bytes in scan direction
- *
- * dir:
- * scan direction; >= 0 == forward, < 0 == reverse
- *
- * margin:
- * amount of data to right of cursor - initialize by stream_scan_normalize
- *
- * data:
- * Extra data used/returned by the function implemented
- *
- * Forward scan:
- * S pos E
- * | *<-margin->| dir->
- * | |<--len--->|
- *
- * Reverse scan:
- * E pos S
- * |<-len->*<-margin->| <-dir
- * | | |
- */
-struct stream_scan
-{
- off_t pos; /* Initial scan position (file offset) */
- ssize_t len; /* Maximum length of scan */
- off_t dir; /* Direction - >= 0; forward, < 0 backward */
- ssize_t margin; /* Used by function to track margin between position and data end */
- intptr_t data; /* */
- struct dbuf_l2_cache l2;
-};
-
-#define SSCAN_REVERSE (-1)
-#define SSCAN_FORWARD 1
-
-/* Initializes the cursor */
-void stream_scan_init(struct stream_scan *sk);
-
-/* Ensures direction is -1 or 1 and margin is properly initialized */
-void stream_scan_normalize(struct stream_scan *sk);
-
-/* Moves a scan cursor. If amount is positive, the increment is in the scan
- * direction, otherwise opposite the scan direction */
-void stream_scan_offset(struct stream_scan *sk, off_t by);
-
-/** Time helpers **/
-struct hms
-{
- unsigned int hrs;
- unsigned int min;
- unsigned int sec;
- unsigned int frac;
-};
-
-void ts_to_hms(uint32_t ts, struct hms *hms);
-void hms_format(char *buf, size_t bufsize, struct hms *hms);
-
-/** Maths **/
-
-/* Moving average */
-#define AVERAGE(var, x, count) \
- ({ typeof (count) _c = (count); \
- ((var) * (_c-1) + (x)) / (_c); })
-
-/* Multiply two unsigned 32-bit integers yielding a 64-bit result and
- * divide by another unsigned 32-bit integer to yield a 32-bit result.
- * Rounds to nearest with saturation. */
-uint32_t muldiv_uint32(uint32_t multiplicand,
- uint32_t multiplier,
- uint32_t divisor);
-
-
-/** Lists **/
-
-/* Does the list have any members? */
-bool list_is_empty(void **list);
-
-/* Is the item inserted into a particular list? */
-bool list_is_member(void **list, void *item);
-
-/* Removes an item from a list - returns true if item was found
- * and thus removed. */
-bool list_remove_item(void **list, void *item);
-
-/* Adds a list item, insert last, if not already present. */
-void list_add_item(void **list, void *item);
-
-/* Clears the entire list. */
-void list_clear_all(void **list);
-
-/* Enumerate all items in the array. */
-typedef bool (*list_enum_callback_t)(void *item, void* data);
-
-void list_enum_items(void **list,
- list_enum_callback_t callback,
- void *data);
-
-
-/** System events **/
-
-/* Clear event */
-void mpeg_sysevent_clear(void);
-
-/* Set to ACTION_STD_CANCEL */
-void mpeg_sysevent_set(void);
-
-/* Get event code */
-long mpeg_sysevent(void);
-
-/* Call with a system event code and used as menu callback */
-int mpeg_sysevent_callback(int btn, const struct menu_item_ex *menu,
- struct gui_synclist *this_list);
-
-/* Handle recorded event */
-void mpeg_sysevent_handle(void);
-
-
-/** Buttons **/
-
-/* Get button codes while remembering important events for later
- * processing; return of ACTION_STD_CANCEL means plugin should
- * abort and handle the event */
-int mpeg_button_get(int timeout);
-
-#endif /* MPEG_MISC_H */
diff --git a/apps/plugins/mpegplayer/mpeg_parser.c b/apps/plugins/mpegplayer/mpeg_parser.c
deleted file mode 100644
index cc57b0c43c..0000000000
--- a/apps/plugins/mpegplayer/mpeg_parser.c
+++ /dev/null
@@ -1,1203 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Parser for MPEG streams
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-
-struct stream_parser str_parser SHAREDBSS_ATTR;
-
-static void parser_init_state(void)
-{
- str_parser.last_seek_time = 0;
- str_parser.format = STREAM_FMT_UNKNOWN;
- str_parser.start_pts = INVALID_TIMESTAMP;
- str_parser.end_pts = INVALID_TIMESTAMP;
- str_parser.flags = 0;
- str_parser.dims.w = 0;
- str_parser.dims.h = 0;
-}
-
-/* Place the stream in a state to begin parsing - sync will be performed
- * first */
-void str_initialize(struct stream *str, off_t pos)
-{
- /* Initial positions start here */
- str->hdr.win_left = str->hdr.win_right = pos;
- /* No packet */
- str->curr_packet = NULL;
- /* Pick up parsing from this point in the buffer */
- str->curr_packet_end = disk_buf_offset2ptr(pos);
- /* No flags */
- str->pkt_flags = 0;
- /* Sync first */
- str->state = SSTATE_SYNC;
-}
-
-/* Place the stream in an end of data state */
-void str_end_of_stream(struct stream *str)
-{
- /* Offsets that prevent this stream from being included in the
- * min left/max right window so that no buffering is triggered on
- * its behalf. Set right to the min first so a thread reading the
- * overall window gets doesn't see this as valid no matter what the
- * file length. */
- str->hdr.win_right = OFF_T_MIN;
- str->hdr.win_left = OFF_T_MAX;
- /* No packets */
- str->curr_packet = str->curr_packet_end = NULL;
- /* No flags */
- str->pkt_flags = 0;
- /* Fin */
- str->state = SSTATE_END;
-}
-
-/* Return a timestamp at address p+offset if the marker bits are in tact */
-static inline uint32_t read_pts(uint8_t *p, off_t offset)
-{
- return TS_CHECK_MARKERS(p, offset) ?
- TS_FROM_HEADER(p, offset) : INVALID_TIMESTAMP;
-}
-
-static inline bool validate_timestamp(uint32_t ts)
-{
- return ts >= str_parser.start_pts && ts <= str_parser.end_pts;
-}
-
-/* Find a start code before or after a given position */
-uint8_t * mpeg_parser_scan_start_code(struct stream_scan *sk, uint32_t code)
-{
- stream_scan_normalize(sk);
-
- if (sk->dir < 0)
- {
- /* Reverse scan - start with at least the min needed */
- stream_scan_offset(sk, 4);
- }
-
- code &= 0xff; /* Only the low byte matters */
-
- while (sk->len >= 0 && sk->margin >= 4)
- {
- uint8_t *p;
- off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
- ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 4, &p);
-
- if (pos < 0 || len < 4)
- break;
-
- if (CMP_3_CONST(p, PACKET_START_CODE_PREFIX) && p[3] == code)
- {
- return p;
- }
-
- stream_scan_offset(sk, 1);
- }
-
- return NULL;
-}
-
-/* Find a PES packet header for any stream - return stream to which it
- * belongs */
-unsigned mpeg_parser_scan_pes(struct stream_scan *sk)
-{
- stream_scan_normalize(sk);
-
- if (sk->dir < 0)
- {
- /* Reverse scan - start with at least the min needed */
- stream_scan_offset(sk, 4);
- }
-
- while (sk->len >= 0 && sk->margin >= 4)
- {
- uint8_t *p;
- off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
- ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 4, &p);
-
- if (pos < 0 || len < 4)
- break;
-
- if (CMP_3_CONST(p, PACKET_START_CODE_PREFIX))
- {
- unsigned id = p[3];
- if (id >= 0xb9)
- return id; /* PES header */
- /* else some video stream element */
- }
-
- stream_scan_offset(sk, 1);
- }
-
- return -1;
-}
-
-/* Return the first SCR found from the scan direction */
-uint32_t mpeg_parser_scan_scr(struct stream_scan *sk)
-{
- uint8_t *p = mpeg_parser_scan_start_code(sk, MPEG_STREAM_PACK_HEADER);
-
- if (p != NULL && sk->margin >= 9) /* 9 bytes total required */
- {
- sk->data = 9;
-
- if ((p[4] & 0xc0) == 0x40) /* mpeg-2 */
- {
- /* Lookhead p+8 */
- if (MPEG2_CHECK_PACK_SCR_MARKERS(p, 4))
- return MPEG2_PACK_HEADER_SCR(p, 4);
- }
- else if ((p[4] & 0xf0) == 0x20) /* mpeg-1 */
- {
- /* Lookahead p+8 */
- if (TS_CHECK_MARKERS(p, 4))
- return TS_FROM_HEADER(p, 4);
- }
- /* Weird pack header */
- sk->data = 5;
- }
-
- return INVALID_TIMESTAMP;
-}
-
-uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id)
-{
- stream_scan_normalize(sk);
-
- if (sk->dir < 0)
- {
- /* Reverse scan - start with at least the min needed */
- stream_scan_offset(sk, 4);
- }
-
- while (sk->len >= 0 && sk->margin >= 4)
- {
- uint8_t *p;
- off_t pos = disk_buf_lseek(sk->pos, SEEK_SET);
- ssize_t len = disk_buf_getbuffer_l2(&sk->l2, 30, &p);
-
- if (pos < 0 || len < 4)
- break;
-
- if (CMP_3_CONST(p, PACKET_START_CODE_PREFIX) && p[3] == id)
- {
- uint8_t *h = p;
-
- if (sk->margin < 7)
- {
- /* Insufficient data */
- }
- else if ((h[6] & 0xc0) == 0x80) /* mpeg2 */
- {
- if (sk->margin >= 14 && (h[7] & 0x80) != 0x00)
- {
- sk->data = 14;
- return read_pts(h, 9);
- }
- }
- else /* mpeg1 */
- {
- ssize_t l = 6;
- ssize_t margin = sk->margin;
-
- /* Skip stuffing_byte */
- while (margin > 7 && h[l] == 0xff && ++l <= 22)
- --margin;
-
- if (margin >= 7)
- {
- if ((h[l] & 0xc0) == 0x40)
- {
- /* Skip STD_buffer_scale and STD_buffer_size */
- margin -= 2;
- l += 2;
- }
-
- if (margin >= 5)
- {
- /* Header points to the mpeg1 pes header */
- h += l;
-
- if ((h[0] & 0xe0) == 0x20)
- {
- /* PTS or PTS_DTS indicated */
- sk->data = (h + 5) - p;
- return read_pts(h, 0);
- }
- }
- }
- }
- /* No PTS present - keep searching for a matching PES header with
- * one */
- }
-
- stream_scan_offset(sk, 1);
- }
-
- return INVALID_TIMESTAMP;
-}
-
-static bool init_video_info(void)
-{
- DEBUGF("Getting movie size\n");
-
- /* The decoder handles this in order to initialize its knowledge of the
- * movie parameters making seeking easier */
- str_send_msg(&video_str, STREAM_RESET, 0);
- if (str_send_msg(&video_str, VIDEO_GET_SIZE,
- (intptr_t)&str_parser.dims) != 0)
- {
- return true;
- }
-
- DEBUGF(" failed\n");
- return false;
-}
-
-static bool init_times(struct stream *str)
-{
- struct stream tmp_str;
- const ssize_t filesize = disk_buf_filesize();
- const ssize_t max_probe = MIN(512*1024, filesize);
- bool found_stream;
-
- /* Simply find the first earliest timestamp - this will be the one
- * used when streaming anyway */
- DEBUGF("Finding start_pts: 0x%02x\n", str->id);
-
- found_stream = false;
- str->start_pts = INVALID_TIMESTAMP;
- str->end_pts = INVALID_TIMESTAMP;
-
- tmp_str.id = str->id;
- tmp_str.hdr.pos = 0;
- tmp_str.hdr.limit = max_probe;
-
- /* Probe for many for the start because some stamps could be anomalous.
- * Video also can also have things out of order. Just see what it's got.
- */
- while (1)
- {
- switch (parser_get_next_data(&tmp_str, STREAM_PM_RANDOM_ACCESS))
- {
- case STREAM_DATA_END:
- break;
- case STREAM_OK:
- found_stream = true;
- if (tmp_str.pkt_flags & PKT_HAS_TS)
- {
- if (tmp_str.pts < str->start_pts)
- str->start_pts = tmp_str.pts;
- }
- continue;
- }
-
- break;
- }
-
- if (!found_stream)
- {
- DEBUGF(" stream not found:0x%02x\n", str->id);
- return false;
- }
-
- DEBUGF(" start:%u\n", (unsigned)str->start_pts);
-
- /* Use the decoder thread to perform a synchronized search - no
- * decoding should take place but just a simple run through timestamps
- * and durations as the decoder would see them. This should give the
- * precise time at the end of the last frame for the stream. */
- DEBUGF("Finding end_pts: 0x%02x\n", str->id);
-
- str_parser.parms.sd.time = MAX_TIMESTAMP;
- str_parser.parms.sd.sk.pos = filesize - max_probe;
- str_parser.parms.sd.sk.len = max_probe;
- str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
-
- str_send_msg(str, STREAM_RESET, 0);
-
- if (str_send_msg(str, STREAM_FIND_END_TIME,
- (intptr_t)&str_parser.parms.sd) == STREAM_PERFECT_MATCH)
- {
- str->end_pts = str_parser.parms.sd.time;
- DEBUGF(" end:%u\n", (unsigned)str->end_pts);
- }
-
- return true;
-}
-
-static bool check_times(const struct stream *str)
-{
- return str->start_pts < str->end_pts &&
- str->end_pts != INVALID_TIMESTAMP;
-}
-
-/* Return the best-fit file offset of a timestamp in the PES where
- * timstamp <= time < next timestamp. Will try to return something reasonably
- * valid if best-fit could not be made. */
-static off_t mpeg_parser_seek_PTS(uint32_t time, unsigned id)
-{
- ssize_t pos_left = 0;
- ssize_t pos_right = disk_buf.filesize;
- ssize_t pos, pos_new;
- uint32_t time_left = str_parser.start_pts;
- uint32_t time_right = str_parser.end_pts;
- uint32_t pts = 0;
- uint32_t prevpts = 0;
- enum state_enum state = STATE0;
- struct stream_scan sk;
-
- stream_scan_init(&sk);
-
- /* Initial estimate taken from average bitrate - later interpolations are
- * taken similarly based on the remaining file interval */
- pos_new = muldiv_uint32(time - time_left, pos_right - pos_left,
- time_right - time_left) + pos_left;
-
- /* return this estimated position if nothing better comes up */
- pos = pos_new;
-
- DEBUGF("Seeking stream 0x%02x\n", id);
- DEBUGF("$$ tl:%u t:%u ct:?? tr:%u\n pl:%ld pn:%ld pr:%ld\n",
- (unsigned)time_left, (unsigned)time, (unsigned)time_right,
- (long)pos_left, (long)pos_new, (long)pos_right);
-
- sk.dir = SSCAN_REVERSE;
-
- while (state < STATE9)
- {
- uint32_t currpts;
- sk.pos = pos_new;
- sk.len = (sk.dir < 0) ? pos_new - pos_left : pos_right - pos_new;
-
- currpts = mpeg_parser_scan_pts(&sk, id);
-
- if (currpts != INVALID_TIMESTAMP)
- {
- ssize_t pos_adj; /* Adjustment to over or under-estimate */
-
- /* Found a valid timestamp - see were it lies in relation to
- * target */
- if (currpts < time)
- {
- /* Time at current position is before seek time - move
- * forward */
- if (currpts > pts)
- {
- /* This is less than the desired time but greater than
- * the currently seeked one; move the position up */
- pts = currpts;
- pos = sk.pos;
- }
-
- /* No next timestamp can be sooner */
- pos_left = sk.pos + sk.data;
- time_left = currpts;
-
- if (pos_right <= pos_left)
- break; /* If the window disappeared - we're done */
-
- pos_new = muldiv_uint32(time - time_left,
- pos_right - pos_left,
- time_right - time_left);
- /* Point is ahead of us - fudge estimate a bit high */
- pos_adj = pos_new / 10;
-
- if (pos_adj > 512*1024)
- pos_adj = 512*1024;
-
- pos_new += pos_left + pos_adj;
-
- if (pos_new >= pos_right)
- {
- /* Estimate could push too far */
- pos_new = pos_right;
- }
-
- state = STATE2; /* Last scan was early */
- sk.dir = SSCAN_REVERSE;
-
- DEBUGF(">> tl:%u t:%u ct:%u tr:%u\n pl:%ld pn:%ld pr:%ld\n",
- (unsigned)time_left, (unsigned)time, (unsigned)currpts,
- (unsigned)time_right, (long)pos_left, (long)pos_new,
- (long)pos_right);
- }
- else if (currpts > time)
- {
- /* Time at current position is past seek time - move
- backward */
- pos_right = sk.pos;
- time_right = currpts;
-
- if (pos_right <= pos_left)
- break; /* If the window disappeared - we're done */
-
- pos_new = muldiv_uint32(time - time_left,
- pos_right - pos_left,
- time_right - time_left);
- /* Overshot the seek point - fudge estimate a bit low */
- pos_adj = pos_new / 10;
-
- if (pos_adj > 512*1024)
- pos_adj = 512*1024;
-
- pos_new += pos_left - pos_adj;
-
- state = STATE3; /* Last scan was late */
- sk.dir = SSCAN_REVERSE;
-
- DEBUGF("<< tl:%u t:%u ct:%u tr:%u\n pl:%ld pn:%ld pr:%ld\n",
- (unsigned)time_left, (unsigned)time, (unsigned)currpts,
- (unsigned)time_right, (long)pos_left, (long)pos_new,
- (long)pos_right);
- }
- else
- {
- /* Exact match - it happens */
- DEBUGF("|| tl:%u t:%u ct:%u tr:%u\n pl:%ld pn:%ld pr:%ld\n",
- (unsigned)time_left, (unsigned)time, (unsigned)currpts,
- (unsigned)time_right, (long)pos_left, (long)pos_new,
- (long)pos_right);
- pts = currpts;
- pos = sk.pos;
- state = STATE9;
- }
- }
- else
- {
- /* Nothing found */
-
- switch (state)
- {
- case STATE1:
- /* We already tried the bruteforce scan and failed again - no
- * more stamps could possibly exist in the interval */
- DEBUGF("!! no timestamp 2x\n");
- break;
- case STATE0:
- /* Hardly likely except at very beginning - just do L->R scan
- * to find something */
- DEBUGF("!! no timestamp on first probe: %ld\n", sk.pos);
- case STATE2:
- case STATE3:
- /* Could just be missing timestamps because the interval is
- * narrowing down. A large block of data from another stream
- * may also be in the midst of our chosen points which could
- * cluster at either extreme end. If anything is there, this
- * will find it. */
- pos_new = pos_left;
- sk.dir = SSCAN_FORWARD;
- DEBUGF("?? tl:%u t:%u ct:%u tr:%u\n pl:%ld pn:%ld pr:%ld\n",
- (unsigned)time_left, (unsigned)time, (unsigned)currpts,
- (unsigned)time_right, (long)pos_left, (long)pos_new,
- (long)pos_right);
- state = STATE1;
- break;
- default:
- DEBUGF("?? Invalid state: %d\n", state);
- }
- }
-
- /* Same timestamp twice = quit */
- if (currpts == prevpts)
- {
- DEBUGF("!! currpts == prevpts (stop)\n");
- state = STATE9;
- }
-
- prevpts = currpts;
- }
-
-#if defined(DEBUG) || defined(SIMULATOR)
- /* The next pts after the seeked-to position should be greater -
- * most of the time - frames out of presentation order may muck it
- * up a slight bit */
- sk.pos = pos + 1;
- sk.len = disk_buf.filesize;
- sk.dir = SSCAN_FORWARD;
-
- uint32_t nextpts = mpeg_parser_scan_pts(&sk, id);
- DEBUGF("Seek pos:%ld pts:%u t:%u next pts:%u \n",
- (long)pos, (unsigned)pts, (unsigned)time, (unsigned)nextpts);
-
- if (pts <= time && time < nextpts)
- {
- /* Smile - it worked */
- DEBUGF(" :) pts<=time time)
- {
- /* Hmm */
- DEBUGF(" :\\ pts>time\n");
- }
- if (pts >= nextpts)
- {
- /* Weird - probably because of encoded order & tends to be right
- * anyway if other criteria are met */
- DEBUGF(" :p pts>=next pts\n");
- }
- if (time >= nextpts)
- {
- /* Ugh */
- DEBUGF(" :( time>=nextpts\n");
- }
- }
-#endif
-
- return pos;
-}
-
-static void prepare_audio(uint32_t time)
-{
- off_t pos;
-
- if (!str_send_msg(&audio_str, STREAM_NEEDS_SYNC, time))
- {
- DEBUGF("Audio was ready\n");
- return;
- }
-
- pos = mpeg_parser_seek_PTS(time, audio_str.id);
- str_send_msg(&audio_str, STREAM_RESET, 0);
-
- str_parser.parms.sd.time = time;
- str_parser.parms.sd.sk.pos = pos;
- str_parser.parms.sd.sk.len = 1024*1024;
- str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
-
- str_send_msg(&audio_str, STREAM_SYNC, (intptr_t)&str_parser.parms.sd);
-}
-
-/* This function demuxes the streams and gives the next stream data
- * pointer.
- *
- * STREAM_PM_STREAMING is for operation during playback. If the nescessary
- * data and worst-case lookahead margin is not available, the stream is
- * registered for notification when the data becomes available. If parsing
- * extends beyond the end of the file or the end of stream marker is reached,
- * STREAM_DATA_END is returned and the stream state changed to SSTATE_EOS.
- *
- * STREAM_PM_RANDOM_ACCESS is for operation when not playing such as seeking.
- * If the file cache misses for the current position + lookahead, it will be
- * loaded from disk. When the specified limit is reached, STREAM_DATA_END is
- * returned.
- *
- * The results from one mode may be used as input to the other. Random access
- * requires cooperation amongst threads to avoid evicting another stream's
- * data.
- */
-static int parse_demux(struct stream *str, enum stream_parse_mode type)
-{
- #define INC_BUF(offset) \
- ({ off_t _o = (offset); \
- str->hdr.win_right += _o; \
- if ((p += _o) >= disk_buf.end) \
- p -= disk_buf.size; })
-
- static const int mpeg1_skip_table[16] =
- { 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- uint8_t *p = str->curr_packet_end;
-
- str->pkt_flags = 0;
-
- while (1)
- {
- uint8_t *header;
- unsigned id;
- ssize_t length, bytes;
-
- switch (type)
- {
- case STREAM_PM_STREAMING:
- /* Has the end been reached already? */
- switch (str->state)
- {
- case SSTATE_PARSE: /* Expected case first if no jumptable */
- /* Are we at the end of file? */
- if (str->hdr.win_left < disk_buf.filesize)
- break;
- str_end_of_stream(str);
- return STREAM_DATA_END;
-
- case SSTATE_SYNC:
- /* Is sync at the end of file? */
- if (str->hdr.win_right < disk_buf.filesize)
- break;
- str_end_of_stream(str);
- /* Fall-through */
- case SSTATE_END:
- return STREAM_DATA_END;
- }
-
- if (!disk_buf_is_data_ready(&str->hdr, MIN_BUFAHEAD))
- {
- /* This data range is not buffered yet - register stream to
- * be notified when it becomes available. Stream is obliged
- * to enter a TSTATE_DATA state if it must wait. */
- int res = str_next_data_not_ready(str);
-
- if (res != STREAM_OK)
- return res;
- }
- break;
- /* STREAM_PM_STREAMING: */
-
- case STREAM_PM_RANDOM_ACCESS:
- str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET);
-
- if (str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit ||
- disk_buf_getbuffer(MIN_BUFAHEAD, &p, NULL, NULL) <= 0)
- {
- str_end_of_stream(str);
- return STREAM_DATA_END;
- }
-
- str->state = SSTATE_SYNC;
- str->hdr.win_left = str->hdr.pos;
- str->curr_packet = NULL;
- str->curr_packet_end = p;
- break;
- /* STREAM_PM_RANDOM_ACCESS: */
- }
-
- if (str->state == SSTATE_SYNC)
- {
- /* Scanning for start code */
- if (!CMP_3_CONST(p, PACKET_START_CODE_PREFIX))
- {
- INC_BUF(1);
- continue;
- }
- }
-
- /* Found a start code - enter parse state */
- str->state = SSTATE_PARSE;
-
- /* Pack header, skip it */
- if (CMP_4_CONST(p, PACK_START_CODE))
- {
- /* Max lookahead: 14 */
- if ((p[4] & 0xc0) == 0x40) /* mpeg-2 */
- {
- /* Max delta: 14 + 7 = 21 */
- /* Skip pack header and any stuffing bytes*/
- bytes = 14 + (p[13] & 7);
- }
- else if ((p[4] & 0xf0) == 0x20) /* mpeg-1 */
- {
- bytes = 12;
- }
- else /* unknown - skip it */
- {
- DEBUGF("weird pack header!\n");
- bytes = 5;
- }
-
- INC_BUF(bytes);
- }
-
- /* System header, parse and skip it - 6 bytes + size */
- if (CMP_4_CONST(p, SYSTEM_HEADER_START_CODE))
- {
- /* Skip start code */
- /* Max Delta = 65535 + 6 = 65541 */
- bytes = 6 + ((p[4] << 8) | p[5]);
- INC_BUF(bytes);
- }
-
- /* Packet header, parse it */
- if (!CMP_3_CONST(p, PACKET_START_CODE_PREFIX))
- {
- /* Problem? Meh...probably not but just a corrupted section.
- * Try to resync the parser which will probably succeed. */
- DEBUGF("packet start code prefix not found: 0x%02x\n"
- " wl:%lu wr:%lu\n"
- " p:%p cp:%p cpe:%p\n"
- " dbs:%p dbe:%p dbt:%p\n",
- str->id, str->hdr.win_left, str->hdr.win_right,
- p, str->curr_packet, str->curr_packet_end,
- disk_buf.start, disk_buf.end, disk_buf.tail);
- str->state = SSTATE_SYNC;
- INC_BUF(1); /* Next byte - this one's no good */
- continue;
- }
-
- /* We retrieve basic infos */
- /* Maximum packet length: 6 + 65535 = 65541 */
- id = p[3];
- length = ((p[4] << 8) | p[5]) + 6;
-
- if (id != str->id)
- {
- switch (id)
- {
- case MPEG_STREAM_PROGRAM_END:
- /* end of stream */
- str_end_of_stream(str);
- DEBUGF("MPEG program end: 0x%02x\n", str->id);
- return STREAM_DATA_END;
- case MPEG_STREAM_PACK_HEADER:
- case MPEG_STREAM_SYSTEM_HEADER:
- /* These shouldn't be here - no increment or resync
- * since we'll pick it up above. */
- continue;
- default:
- /* It's not the packet we're looking for, skip it */
- INC_BUF(length);
- continue;
- }
- }
-
- /* Ok, it's our packet */
- header = p;
-
- if ((header[6] & 0xc0) == 0x80) /* mpeg2 */
- {
- /* Max Lookahead: 18 */
- /* Min length: 9 */
- /* Max length: 9 + 255 = 264 */
- length = 9 + header[8];
-
- /* header points to the mpeg2 pes header */
- if ((header[7] & 0x80) != 0)
- {
- /* header has a pts */
- uint32_t pts = read_pts(header, 9);
-
- if (pts != INVALID_TIMESTAMP)
- {
- str->pts = pts;
-#if 0
- /* DTS isn't used for anything since things just get
- decoded ASAP but keep the code around */
- if (STREAM_IS_VIDEO(id))
- {
- /* Video stream - header may have a dts as well */
- str->dts = pts;
-
- if (header[7] & 0x40) != 0x00)
- {
- pts = read_pts(header, 14);
- if (pts != INVALID_TIMESTAMP)
- str->dts = pts;
- }
- }
-#endif
- str->pkt_flags |= PKT_HAS_TS;
- }
- }
- }
- else /* mpeg1 */
- {
- /* Max lookahead: 24 + 2 + 9 = 35 */
- /* Max len_skip: 24 + 2 = 26 */
- /* Min length: 7 */
- /* Max length: 24 + 2 + 9 = 35 */
- off_t len_skip;
- uint8_t * ptsbuf;
-
- length = 7;
-
- while (header[length - 1] == 0xff)
- {
- if (++length > 23)
- {
- DEBUGF("Too much stuffing" );
- break;
- }
- }
-
- if ((header[length - 1] & 0xc0) == 0x40)
- length += 2;
-
- len_skip = length;
- length += mpeg1_skip_table[header[length - 1] >> 4];
-
- /* Header points to the mpeg1 pes header */
- ptsbuf = header + len_skip;
-
- if ((ptsbuf[-1] & 0xe0) == 0x20 && TS_CHECK_MARKERS(ptsbuf, -1))
- {
- /* header has a pts */
- uint32_t pts = read_pts(ptsbuf, -1);
-
- if (pts != INVALID_TIMESTAMP)
- {
- str->pts = pts;
-#if 0
- /* DTS isn't used for anything since things just get
- decoded ASAP but keep the code around */
- if (STREAM_IS_VIDEO(id))
- {
- /* Video stream - header may have a dts as well */
- str->dts = pts;
-
- if (ptsbuf[-1] & 0xf0) == 0x30)
- {
- pts = read_pts(ptsbuf, 4);
-
- if (pts != INVALID_TIMESTAMP)
- str->dts = pts;
- }
- }
-#endif
- str->pkt_flags |= PKT_HAS_TS;
- }
- }
- }
-
- p += length;
- /* Max bytes: 6 + 65535 - 7 = 65534 */
- bytes = 6 + (header[4] << 8) + header[5] - length;
-
- str->curr_packet = p;
- str->curr_packet_end = p + bytes;
- str->hdr.win_left = str->hdr.win_right + length;
- str->hdr.win_right = str->hdr.win_left + bytes;
-
- if (str->hdr.win_right > disk_buf.filesize)
- {
- /* No packet that exceeds end of file can be valid */
- str_end_of_stream(str);
- return STREAM_DATA_END;
- }
-
- return STREAM_OK;
- } /* end while */
-
- #undef INC_BUF
-}
-
-/* This simply reads data from the file one page at a time and returns a
- * pointer to it in the buffer. */
-static int parse_elementary(struct stream *str, enum stream_parse_mode type)
-{
- uint8_t *p;
- ssize_t len = 0;
-
- str->pkt_flags = 0;
-
- switch (type)
- {
- case STREAM_PM_STREAMING:
- /* Has the end been reached already? */
- if (str->state == SSTATE_END)
- return STREAM_DATA_END;
-
- /* Are we at the end of file? */
- if (str->hdr.win_left >= disk_buf.filesize)
- {
- str_end_of_stream(str);
- return STREAM_DATA_END;
- }
-
- if (!disk_buf_is_data_ready(&str->hdr, MIN_BUFAHEAD))
- {
- /* This data range is not buffered yet - register stream to
- * be notified when it becomes available. Stream is obliged
- * to enter a TSTATE_DATA state if it must wait. */
- int res = str_next_data_not_ready(str);
-
- if (res != STREAM_OK)
- return res;
- }
-
- len = DISK_BUF_PAGE_SIZE;
-
- if ((size_t)(str->hdr.win_right + len) > (size_t)disk_buf.filesize)
- len = disk_buf.filesize - str->hdr.win_right;
-
- if (len <= 0)
- {
- str_end_of_stream(str);
- return STREAM_DATA_END;
- }
-
- p = str->curr_packet_end;
- if (p >= disk_buf.end)
- p -= disk_buf.size;
- break;
- /* STREAM_PM_STREAMING: */
-
- case STREAM_PM_RANDOM_ACCESS:
- str->hdr.pos = disk_buf_lseek(str->hdr.pos, SEEK_SET);
- len = disk_buf_getbuffer(DISK_BUF_PAGE_SIZE, &p, NULL, NULL);
-
- if (len <= 0 || str->hdr.pos < 0 || str->hdr.pos >= str->hdr.limit)
- {
- str_end_of_stream(str);
- return STREAM_DATA_END;
- }
- break;
- /* STREAM_PM_RANDOM_ACCESS: */
- }
-
- str->state = SSTATE_PARSE;
- str->curr_packet = p;
- str->curr_packet_end = p + len;
- str->hdr.win_left = str->hdr.win_right;
- str->hdr.win_right = str->hdr.win_left + len;
-
- return STREAM_OK;
-}
-
-bool parser_prepare_image(uint32_t time)
-{
- struct stream_scan sk;
- int tries;
- int result;
-
- stream_scan_init(&sk);
-
- if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
- {
- DEBUGF("Image was ready\n");
- return true; /* Should already have the image */
- }
-
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(true); /* No interference with trigger_cpu_boost */
-#endif
-
- str_send_msg(&video_str, STREAM_RESET, 0);
-
- sk.pos = parser_can_seek() ?
- mpeg_parser_seek_PTS(time, video_str.id) : 0;
- sk.len = sk.pos;
- sk.dir = SSCAN_REVERSE;
-
- tries = 1;
-try_again:
-
- if (mpeg_parser_scan_start_code(&sk, MPEG_START_GOP))
- {
- DEBUGF("GOP found at: %ld\n", sk.pos);
-
- unsigned id = mpeg_parser_scan_pes(&sk);
-
- if (id != video_str.id && sk.pos > 0)
- {
- /* Not part of our stream */
- DEBUGF(" wrong stream: 0x%02x\n", id);
- goto try_again;
- }
-
- /* This will hit the PES header since it's known to be there */
- uint32_t pts = mpeg_parser_scan_pts(&sk, id);
-
- if (pts == INVALID_TIMESTAMP || pts > time)
- {
- DEBUGF(" wrong timestamp: %u\n", (unsigned)pts);
- goto try_again;
- }
- }
-
- str_parser.parms.sd.time = time;
- str_parser.parms.sd.sk.pos = MAX(sk.pos, 0);
- str_parser.parms.sd.sk.len = 1024*1024;
- str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
-
- DEBUGF("thumb pos:%ld len:%ld\n", str_parser.parms.sd.sk.pos,
- (long)str_parser.parms.sd.sk.len);
-
- result = str_send_msg(&video_str, STREAM_SYNC,
- (intptr_t)&str_parser.parms.sd);
-
- if (result != STREAM_PERFECT_MATCH)
- {
- /* Two tries should be all that is nescessary to find the exact frame
- * if the first GOP actually started later than the timestamp - the
- * GOP just prior must then start on or earlier. */
- if (++tries <= 2)
- goto try_again;
- }
-
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(false);
-#endif
-
- return result > STREAM_OK;
-}
-
-/* Seek parser to the specified time and return absolute time.
- * No actual hard stuff is performed here. That's done when streaming is
- * about to begin or something from the current position is requested */
-uint32_t parser_seek_time(uint32_t time)
-{
- if (!parser_can_seek())
- time = 0;
- else if (time > str_parser.duration)
- time = str_parser.duration;
-
- str_parser.last_seek_time = time + str_parser.start_pts;
- return str_parser.last_seek_time;
-}
-
-void parser_prepare_streaming(void)
-{
- struct stream_window sw;
-
- DEBUGF("parser_prepare_streaming\n");
-
- /* Prepare initial video frame */
- parser_prepare_image(str_parser.last_seek_time);
-
- /* Sync audio stream */
- if (audio_str.start_pts != INVALID_TIMESTAMP)
- prepare_audio(str_parser.last_seek_time);
-
- /* Prequeue some data and set buffer window */
- if (!stream_get_window(&sw))
- sw.left = sw.right = disk_buf.filesize;
-
- DEBUGF(" swl:%ld swr:%ld\n", sw.left, sw.right);
-
- if (sw.right > disk_buf.filesize - 4*MIN_BUFAHEAD)
- sw.right = disk_buf.filesize - 4*MIN_BUFAHEAD;
-
- disk_buf_prepare_streaming(sw.left,
- sw.right - sw.left + 4*MIN_BUFAHEAD);
-}
-
-int parser_init_stream(void)
-{
- if (disk_buf.in_file < 0)
- return STREAM_ERROR;
-
- /* TODO: Actually find which streams are available */
- audio_str.id = MPEG_STREAM_AUDIO_FIRST;
- video_str.id = MPEG_STREAM_VIDEO_FIRST;
-
- /* Try to pull a video PES - if not found, try video init anyway which
- * should succeed if it really is a video-only stream */
- video_str.hdr.pos = 0;
- video_str.hdr.limit = 256*1024;
-
- if (parse_demux(&video_str, STREAM_PM_RANDOM_ACCESS) == STREAM_OK)
- {
- /* Found a video packet - assume program stream */
- str_parser.format = STREAM_FMT_MPEG_PS;
- str_parser.next_data = parse_demux;
- }
- else
- {
- /* No PES element found - assume video elementary stream */
- str_parser.format = STREAM_FMT_MPV;
- str_parser.next_data = parse_elementary;
- }
-
- if (!init_video_info())
- {
- /* Cannot determine video size, etc. */
- parser_init_state();
- return STREAM_UNSUPPORTED;
- }
-
- if (str_parser.format == STREAM_FMT_MPEG_PS)
- {
- /* Initalize start_pts and end_pts with the length (in 45kHz units) of
- * the movie. INVALID_TIMESTAMP if the time could not be determined */
- if (!init_times(&video_str) || !check_times(&video_str))
- {
- /* Must have video at least */
- parser_init_state();
- return STREAM_UNSUPPORTED;
- }
-
- str_parser.flags |= STREAMF_CAN_SEEK;
-
- if (init_times(&audio_str))
- {
- /* Audio will be part of playback pool */
- stream_add_stream(&audio_str);
-
- if (check_times(&audio_str))
- {
- /* Overall duration is maximum span */
- str_parser.start_pts = MIN(audio_str.start_pts, video_str.start_pts);
- str_parser.end_pts = MAX(audio_str.end_pts, video_str.end_pts);
- }
- else
- {
- /* Bad times on audio - use video times */
- str_parser.start_pts = video_str.start_pts;
- str_parser.end_pts = video_str.end_pts;
-
- /* Questionable: could use bitrate seek and match video to that */
- audio_str.start_pts = video_str.start_pts;
- audio_str.end_pts = video_str.end_pts;
- }
- }
- else
- {
- /* No audio stream - use video only */
- str_parser.start_pts = video_str.start_pts;
- str_parser.end_pts = video_str.end_pts;
- }
-
- str_parser.last_seek_time = str_parser.start_pts;
- }
- else
- {
- /* There's no way to handle times on this without a full file
- * scan */
- audio_str.start_pts = INVALID_TIMESTAMP;
- audio_str.end_pts = INVALID_TIMESTAMP;
- video_str.start_pts = 0;
- video_str.end_pts = INVALID_TIMESTAMP;
- str_parser.start_pts = 0;
- str_parser.end_pts = INVALID_TIMESTAMP;
- }
-
- /* Add video to playback pool */
- stream_add_stream(&video_str);
-
- /* Cache duration - it's used very often */
- str_parser.duration = str_parser.end_pts - str_parser.start_pts;
-
- DEBUGF("Movie info:\n"
- " size:%dx%d\n"
- " start:%u\n"
- " end:%u\n"
- " duration:%u\n",
- str_parser.dims.w, str_parser.dims.h,
- (unsigned)str_parser.start_pts,
- (unsigned)str_parser.end_pts,
- (unsigned)str_parser.duration);
-
- return STREAM_OK;
-}
-
-void parser_close_stream(void)
-{
- stream_remove_streams();
- parser_init_state();
-}
-
-bool parser_init(void)
-{
- parser_init_state();
- return true;
-}
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
deleted file mode 100644
index c904de466d..0000000000
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-#include "plugin.h"
-#include "lib/helper.h"
-#include "lib/configfile.h"
-
-#include "mpegplayer.h"
-#include "mpeg_settings.h"
-
-struct mpeg_settings settings;
-
-#define THUMB_DELAY (75*HZ/100)
-
-/* button definitions */
-#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
- (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_ON
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_OFF
-
-#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
- (CONFIG_KEYPAD == IPOD_3G_PAD) || \
- (CONFIG_KEYPAD == IPOD_1G2G_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_SCROLL_FWD
-#define MPEG_START_TIME_DOWN BUTTON_SCROLL_BACK
-#define MPEG_START_TIME_EXIT BUTTON_MENU
-
-#elif CONFIG_KEYPAD == GIGABEAT_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#define MPEG_START_TIME_RC_SELECT (BUTTON_RC_PLAY | BUTTON_REL)
-#define MPEG_START_TIME_RC_LEFT BUTTON_RC_REW
-#define MPEG_START_TIME_RC_RIGHT BUTTON_RC_FF
-#define MPEG_START_TIME_RC_UP BUTTON_RC_VOL_UP
-#define MPEG_START_TIME_RC_DOWN BUTTON_RC_VOL_DOWN
-#define MPEG_START_TIME_RC_EXIT (BUTTON_RC_PLAY | BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#define MPEG_START_TIME_RC_SELECT (BUTTON_RC_PLAY | BUTTON_REL)
-#define MPEG_START_TIME_RC_LEFT BUTTON_RC_REW
-#define MPEG_START_TIME_RC_RIGHT BUTTON_RC_FF
-#define MPEG_START_TIME_RC_UP BUTTON_RC_VOL_UP
-#define MPEG_START_TIME_RC_DOWN BUTTON_RC_VOL_DOWN
-#define MPEG_START_TIME_RC_EXIT (BUTTON_RC_PLAY | BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_SCROLL_UP
-#define MPEG_START_TIME_DOWN BUTTON_SCROLL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_SCROLL_BACK
-#define MPEG_START_TIME_RIGHT2 BUTTON_SCROLL_FWD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_SCROLL_BACK
-#define MPEG_START_TIME_RIGHT2 BUTTON_SCROLL_FWD
-#define MPEG_START_TIME_EXIT (BUTTON_HOME|BUTTON_REPEAT)
-
-#elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
-(CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
-(CONFIG_KEYPAD == SANSA_M200_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == MROBE500_PAD
-#define MPEG_START_TIME_SELECT BUTTON_RC_HEART
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_RC_PLAY
-#define MPEG_START_TIME_DOWN BUTTON_RC_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_RC_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_RC_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == MROBE100_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_PLAY
-#define MPEG_START_TIME_RIGHT2 BUTTON_MENU
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
-#define MPEG_START_TIME_SELECT BUTTON_RC_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_RC_REW
-#define MPEG_START_TIME_RIGHT BUTTON_RC_FF
-#define MPEG_START_TIME_UP BUTTON_RC_VOL_UP
-#define MPEG_START_TIME_DOWN BUTTON_RC_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_RC_REC
-
-#elif CONFIG_KEYPAD == COWON_D2_PAD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_PLAY
-#define MPEG_START_TIME_RIGHT2 BUTTON_MENU
-#define MPEG_START_TIME_EXIT BUTTON_BACK
-
-#elif (CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD)
-#define MPEG_START_TIME_SELECT (BUTTON_PLAY|BUTTON_REL)
-#define MPEG_START_TIME_LEFT BUTTON_BACK
-#define MPEG_START_TIME_RIGHT BUTTON_MENU
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT (BUTTON_PLAY|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_PREV
-#define MPEG_START_TIME_RIGHT BUTTON_NEXT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == ONDAVX747_PAD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == ONDAVX777_PAD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \
- (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_REW
-
-#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_PREV
-#define MPEG_START_TIME_RIGHT BUTTON_NEXT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_LEFT2 BUTTON_OK
-#define MPEG_START_TIME_RIGHT2 BUTTON_CANCEL
-#define MPEG_START_TIME_EXIT BUTTON_REC
-
-#elif CONFIG_KEYPAD == MPIO_HD200_PAD
-#define MPEG_START_TIME_SELECT BUTTON_FUNC
-#define MPEG_START_TIME_LEFT BUTTON_REW
-#define MPEG_START_TIME_RIGHT BUTTON_FF
-#define MPEG_START_TIME_UP BUTTON_VOL_UP
-#define MPEG_START_TIME_DOWN BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_REC
-
-#elif CONFIG_KEYPAD == MPIO_HD300_PAD
-#define MPEG_START_TIME_SELECT BUTTON_ENTER
-#define MPEG_START_TIME_LEFT BUTTON_REW
-#define MPEG_START_TIME_RIGHT BUTTON_FF
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_REC
-
-#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_BACK
-
-#elif (CONFIG_KEYPAD == HM60X_PAD) || (CONFIG_KEYPAD == HM801_PAD)
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == SONY_NWZ_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_BACK
-
-#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_BACK
-
-#elif CONFIG_KEYPAD == DX50_PAD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_VOL_UP
-#define MPEG_START_TIME_DOWN BUTTON_VOL_DOWN
-
-#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == XDUOO_X3_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_PREV
-#define MPEG_START_TIME_RIGHT BUTTON_NEXT
-#define MPEG_START_TIME_UP BUTTON_HOME
-#define MPEG_START_TIME_DOWN BUTTON_OPTION
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_PREV
-#define MPEG_START_TIME_RIGHT BUTTON_NEXT
-#define MPEG_START_TIME_UP BUTTON_HOME
-#define MPEG_START_TIME_DOWN BUTTON_OPTION
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_PREV
-#define MPEG_START_TIME_RIGHT BUTTON_NEXT
-#define MPEG_START_TIME_UP BUTTON_HOME
-#define MPEG_START_TIME_DOWN BUTTON_OPTION
-#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP
-#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_HOME
-#define MPEG_START_TIME_RIGHT BUTTON_VOL_DOWN
-#define MPEG_START_TIME_UP BUTTON_PREV
-#define MPEG_START_TIME_DOWN BUTTON_NEXT
-#define MPEG_START_TIME_LEFT2 (BUTTON_POWER + BUTTON_HOME)
-#define MPEG_START_TIME_RIGHT2 (BUTTON_POWER + BUTTON_VOL_DOWN)
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == EROSQ_PAD
-#define MPEG_START_TIME_SELECT BUTTON_PLAY
-#define MPEG_START_TIME_LEFT BUTTON_SCROLL_BACK
-#define MPEG_START_TIME_RIGHT BUTTON_SCROLL_FWD
-#define MPEG_START_TIME_UP BUTTON_PREV
-#define MPEG_START_TIME_DOWN BUTTON_NEXT
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == FIIO_M3K_PAD
-#define MPEG_START_TIME_SELECT BUTTON_SELECT
-#define MPEG_START_TIME_LEFT BUTTON_LEFT
-#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
-#define MPEG_START_TIME_UP BUTTON_UP
-#define MPEG_START_TIME_DOWN BUTTON_DOWN
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
-#define MPEG_START_TIME_EXIT BUTTON_POWER
-
-#else
-#error No keymap defined!
-#endif
-
-#ifdef HAVE_TOUCHSCREEN
-#ifndef MPEG_START_TIME_SELECT
-#define MPEG_START_TIME_SELECT BUTTON_CENTER
-#endif
-#ifndef MPEG_START_TIME_LEFT
-#define MPEG_START_TIME_LEFT BUTTON_MIDLEFT
-#endif
-#ifndef MPEG_START_TIME_RIGHT
-#define MPEG_START_TIME_RIGHT BUTTON_MIDRIGHT
-#endif
-#ifndef MPEG_START_TIME_UP
-#define MPEG_START_TIME_UP BUTTON_TOPMIDDLE
-#endif
-#ifndef MPEG_START_TIME_DOWN
-#define MPEG_START_TIME_DOWN BUTTON_BOTTOMMIDDLE
-#endif
-#ifndef MPEG_START_TIME_LEFT2
-#define MPEG_START_TIME_LEFT2 BUTTON_TOPRIGHT
-#endif
-#ifndef MPEG_START_TIME_RIGHT2
-#define MPEG_START_TIME_RIGHT2 BUTTON_TOPLEFT
-#endif
-#ifndef MPEG_START_TIME_EXIT
-#define MPEG_START_TIME_EXIT BUTTON_TOPLEFT
-#endif
-#endif
-
-static struct configdata config[] =
-{
- {TYPE_INT, 0, 2, { .int_p = &settings.showfps }, "Show FPS", NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.limitfps }, "Limit FPS", NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.skipframes }, "Skip frames", NULL},
- {TYPE_INT, 0, INT_MAX, { .int_p = &settings.resume_count }, "Resume count",
- NULL},
- {TYPE_INT, 0, MPEG_RESUME_NUM_OPTIONS,
- { .int_p = &settings.resume_options }, "Resume options", NULL},
-#if MPEG_OPTION_DITHERING_ENABLED
- {TYPE_INT, 0, INT_MAX, { .int_p = &settings.displayoptions },
- "Display options", NULL},
-#endif
- {TYPE_INT, 0, 2, { .int_p = &settings.tone_controls }, "Tone controls",
- NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.channel_modes }, "Channel modes",
- NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.crossfeed }, "Crossfeed", NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.equalizer }, "Equalizer", NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.dithering }, "Dithering", NULL},
- {TYPE_INT, 0, 2, { .int_p = &settings.play_mode }, "Play mode", NULL},
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- {TYPE_INT, -1, INT_MAX, { .int_p = &settings.backlight_brightness },
- "Backlight brightness", NULL},
-#endif
-};
-
-static const struct opt_items noyes[2] = {
- { STR(LANG_SET_BOOL_NO) },
- { STR(LANG_SET_BOOL_YES) },
-};
-
-static const struct opt_items singleall[2] = {
- { STR(LANG_SINGLE) },
- { STR(LANG_ALL) },
-};
-
-static const struct opt_items globaloff[2] = {
- { STR(LANG_OFF) },
- { STR(LANG_USE_SOUND_SETTING) },
-};
-
-static void mpeg_settings(void);
-static bool mpeg_set_option(const char* string,
- void* variable,
- enum optiontype type,
- const struct opt_items* options,
- int numoptions,
- void (*function)(int))
-{
- mpeg_sysevent_clear();
-
- /* This eats SYS_POWEROFF - :\ */
- bool usb = rb->set_option(string, variable, type, options, numoptions,
- function);
-
- if (usb)
- mpeg_sysevent_set();
-
- return usb;
-}
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS /* Only used for this atm */
-static bool mpeg_set_int(const char *string, const char *unit,
- int voice_unit, const int *variable,
- void (*function)(int), int step,
- int min,
- int max,
- const char* (*formatter)(char*, size_t, int, const char*),
- int32_t (*get_talk_id)(int, int))
-{
- mpeg_sysevent_clear();
-
- bool usb = rb->set_int_ex(string, unit, voice_unit, variable, function,
- step, min, max, formatter, get_talk_id);
-
- if (usb)
- mpeg_sysevent_set();
-
- return usb;
-}
-
-static int32_t backlight_brightness_getlang(int value, int unit)
-{
- if (value < 0)
- return LANG_USE_COMMON_SETTING;
-
- return TALK_ID(value + MIN_BRIGHTNESS_SETTING, unit);
-}
-
-void mpeg_backlight_update_brightness(int value)
-{
- if (value >= 0)
- {
- value += MIN_BRIGHTNESS_SETTING;
- backlight_brightness_set(value);
- }
- else
- {
- backlight_brightness_use_setting();
- }
-}
-
-static void backlight_brightness_function(int value)
-{
- mpeg_backlight_update_brightness(value);
-}
-
-static const char* backlight_brightness_formatter(char *buf, size_t length,
- int value, const char *input)
-{
- (void)input;
-
- if (value < 0)
- return rb->str(LANG_USE_COMMON_SETTING);
- else
- rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING);
- return buf;
-}
-#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
-
-/* Sync a particular audio setting to global or mpegplayer forced off */
-static void sync_audio_setting(int setting, bool global)
-{
- switch (setting)
- {
- case MPEG_AUDIO_TONE_CONTROLS:
- #ifdef AUDIOHW_HAVE_BASS
- rb->sound_set(SOUND_BASS, (global || settings.tone_controls)
- ? rb->global_settings->bass
- : rb->sound_default(SOUND_BASS));
- #endif
- #ifdef AUDIOHW_HAVE_TREBLE
- rb->sound_set(SOUND_TREBLE, (global || settings.tone_controls)
- ? rb->global_settings->treble
- : rb->sound_default(SOUND_TREBLE));
- #endif
-
- #ifdef AUDIOHW_HAVE_EQ
- for (int band = 0;; band++)
- {
- int setting = rb->sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN);
-
- if (setting == -1)
- break;
-
- rb->sound_set(setting, (global || settings.tone_controls)
- ? rb->global_settings->hw_eq_bands[band].gain
- : rb->sound_default(setting));
- }
- #endif /* AUDIOHW_HAVE_EQ */
- break;
-
- case MPEG_AUDIO_CHANNEL_MODES:
- rb->sound_set(SOUND_CHANNELS, (global || settings.channel_modes)
- ? rb->global_settings->channel_config
- : SOUND_CHAN_STEREO);
- break;
-
- case MPEG_AUDIO_CROSSFEED:
- rb->dsp_set_crossfeed_type((global || settings.crossfeed) ?
- rb->global_settings->crossfeed :
- CROSSFEED_TYPE_NONE);
- break;
-
- case MPEG_AUDIO_EQUALIZER:
- rb->dsp_eq_enable((global || settings.equalizer) ?
- rb->global_settings->eq_enabled : false);
- break;
-
- case MPEG_AUDIO_DITHERING:
- rb->dsp_dither_enable((global || settings.dithering) ?
- rb->global_settings->dithering_enabled : false);
- break;
- }
-}
-
-/* Sync all audio settings to global or mpegplayer forced off */
-static void sync_audio_settings(bool global)
-{
- static const int setting_index[] =
- {
- MPEG_AUDIO_TONE_CONTROLS,
- MPEG_AUDIO_CHANNEL_MODES,
- MPEG_AUDIO_CROSSFEED,
- MPEG_AUDIO_EQUALIZER,
- MPEG_AUDIO_DITHERING,
- };
- unsigned i;
-
- for (i = 0; i < ARRAYLEN(setting_index); i++)
- {
- sync_audio_setting(setting_index[i], global);
- }
-}
-
-#ifndef HAVE_LCD_COLOR
-/* Cheapo splash implementation for the grey surface */
-static void grey_splash(int ticks, const unsigned char *fmt, ...)
-{
- unsigned char buffer[256];
- int x, y, w, h;
- int oldfg, oldmode;
-
- va_list ap;
- va_start(ap, fmt);
-
- rb->vsnprintf(buffer, sizeof (buffer), fmt, ap);
-
- va_end(ap);
-
- grey_getstringsize(buffer, &w, &h);
-
- oldfg = grey_get_foreground();
- oldmode = grey_get_drawmode();
-
- grey_set_drawmode(DRMODE_FG);
- grey_set_foreground(GREY_LIGHTGRAY);
-
- x = (LCD_WIDTH - w) / 2;
- y = (LCD_HEIGHT - h) / 2;
-
- grey_fillrect(x - 1, y - 1, w + 2, h + 2);
-
- grey_set_foreground(GREY_BLACK);
-
- grey_putsxy(x, y, buffer);
- grey_drawrect(x - 2, y - 2, w + 4, h + 4);
-
- grey_set_foreground(oldfg);
- grey_set_drawmode(oldmode);
-
- grey_update();
-
- if (ticks > 0)
- rb->sleep(ticks);
-}
-#endif /* !HAVE_LCD_COLOR */
-
-static void show_loading(struct vo_rect *rc)
-{
- int oldmode = mylcd_get_drawmode();
- mylcd_set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
- mylcd_fillrect(rc->l-1, rc->t-1, rc->r - rc->l + 2, rc->b - rc->t + 2);
- mylcd_set_drawmode(oldmode);
- mylcd_splash(0, "Loading...");
-}
-
-static void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc)
-{
- #define SLIDER_WIDTH (LCD_WIDTH-SLIDER_LMARGIN-SLIDER_RMARGIN)
- #define SLIDER_X SLIDER_LMARGIN
- #define SLIDER_Y (LCD_HEIGHT-SLIDER_HEIGHT-SLIDER_BMARGIN)
- #define SLIDER_HEIGHT 8
- #define SLIDER_TEXTMARGIN 1
- #define SLIDER_LMARGIN 1
- #define SLIDER_RMARGIN 1
- #define SLIDER_TMARGIN 1
- #define SLIDER_BMARGIN 1
- #define SCREEN_MARGIN 1
-
- struct hms hms;
- char str[32];
- int text_w, text_h, text_y;
-
- /* Put positition on left */
- ts_to_hms(pos, &hms);
- hms_format(str, sizeof(str), &hms);
- mylcd_getstringsize(str, NULL, &text_h);
- text_y = SLIDER_Y - SLIDER_TEXTMARGIN - text_h;
-
- if (rc == NULL)
- {
- int oldmode = mylcd_get_drawmode();
- mylcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
- mylcd_fillrect(SLIDER_X, text_y, SLIDER_WIDTH,
- LCD_HEIGHT - SLIDER_BMARGIN - text_y
- - SLIDER_TMARGIN);
- mylcd_set_drawmode(oldmode);
-
- mylcd_putsxy(SLIDER_X, text_y, str);
-
- /* Put duration on right */
- ts_to_hms(range, &hms);
- hms_format(str, sizeof(str), &hms);
- mylcd_getstringsize(str, &text_w, NULL);
-
- mylcd_putsxy(SLIDER_X + SLIDER_WIDTH - text_w, text_y, str);
-
- /* Draw slider */
- mylcd_drawrect(SLIDER_X, SLIDER_Y, SLIDER_WIDTH, SLIDER_HEIGHT);
- mylcd_fillrect(SLIDER_X, SLIDER_Y,
- muldiv_uint32(pos, SLIDER_WIDTH, range),
- SLIDER_HEIGHT);
-
- /* Update screen */
- mylcd_update_rect(SLIDER_X, text_y - SLIDER_TMARGIN, SLIDER_WIDTH,
- LCD_HEIGHT - SLIDER_BMARGIN - text_y + SLIDER_TEXTMARGIN);
- }
- else
- {
- /* Just return slider rectangle */
- rc->l = SLIDER_X;
- rc->t = text_y - SLIDER_TMARGIN;
- rc->r = rc->l + SLIDER_WIDTH;
- rc->b = rc->t + LCD_HEIGHT - SLIDER_BMARGIN - text_y;
- }
-}
-
-static bool display_thumb_image(const struct vo_rect *rc)
-{
- bool retval = true;
- unsigned ltgray = MYLCD_LIGHTGRAY;
- unsigned dkgray = MYLCD_DARKGRAY;
-
- int oldcolor = mylcd_get_foreground();
-
- if (!stream_display_thumb(rc))
- {
- /* Display "No Frame" and erase any border */
- const char * const str = "No Frame";
- int x, y, w, h;
-
- mylcd_getstringsize(str, &w, &h);
- x = (rc->r + rc->l - w) / 2;
- y = (rc->b + rc->t - h) / 2;
- mylcd_putsxy(x, y, str);
-
- mylcd_update_rect(x, y, w, h);
-
- ltgray = dkgray = mylcd_get_background();
- retval = false;
- }
-
- /* Draw a raised border around the frame (or erase if no frame) */
-
- mylcd_set_foreground(ltgray);
-
- mylcd_hline(rc->l-1, rc->r-1, rc->t-1);
- mylcd_vline(rc->l-1, rc->t, rc->b-1);
-
- mylcd_set_foreground(dkgray);
-
- mylcd_hline(rc->l-1, rc->r, rc->b);
- mylcd_vline(rc->r, rc->t-1, rc->b);
-
- mylcd_set_foreground(oldcolor);
-
- mylcd_update_rect(rc->l-1, rc->t-1, rc->r - rc->l + 2, 1);
- mylcd_update_rect(rc->l-1, rc->t, 1, rc->b - rc->t);
- mylcd_update_rect(rc->l-1, rc->b, rc->r - rc->l + 2, 1);
- mylcd_update_rect(rc->r, rc->t, 1, rc->b - rc->t);
-
- return retval;
-}
-
-/* Add an amount to the specified time - with saturation */
-static uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range)
-{
- if (amount < 0)
- {
- uint32_t off = -amount;
- if (range > off && val >= off)
- val -= off;
- else
- val = 0;
- }
- else if (amount > 0)
- {
- uint32_t off = amount;
- if (range > off && val <= range - off)
- val += off;
- else
- val = range;
- }
-
- return val;
-}
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void get_start_time_lcd_enable_hook(unsigned short id, void *param)
-{
- (void)id;
- (void)param;
- rb->queue_post(rb->button_queue, LCD_ENABLE_EVENT_0, 0);
-}
-#endif /* HAVE_LCD_ENABLE */
-
-static int get_start_time(uint32_t duration)
-{
- int button = 0;
- int tmo = TIMEOUT_NOBLOCK;
- uint32_t resume_time = settings.resume_time;
- struct vo_rect rc_vid, rc_bound;
- uint32_t aspect_vid, aspect_bound;
- bool sliding = false;
-
- enum state_enum slider_state = STATE0;
-
- mylcd_clear_display();
- mylcd_update();
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- rb->add_event(LCD_EVENT_ACTIVATION, get_start_time_lcd_enable_hook);
-#endif
-
- draw_slider(0, 100, &rc_bound);
- rc_bound.b = rc_bound.t - SLIDER_TMARGIN;
- rc_bound.t = SCREEN_MARGIN;
-
- DEBUGF("rc_bound: %d, %d, %d, %d\n", rc_bound.l, rc_bound.t,
- rc_bound.r, rc_bound.b);
-
- rc_vid.l = rc_vid.t = 0;
- if (!stream_vo_get_size((struct vo_ext *)&rc_vid.r))
- {
- /* Can't get size - fill whole thing */
- rc_vid.r = rc_bound.r - rc_bound.l;
- rc_vid.b = rc_bound.b - rc_bound.t;
- }
-
- /* Get aspect ratio of bounding rectangle and video in u16.16 */
- aspect_bound = ((rc_bound.r - rc_bound.l) << 16) /
- (rc_bound.b - rc_bound.t);
-
- DEBUGF("aspect_bound: %u.%02u\n", (unsigned)(aspect_bound >> 16),
- (unsigned)(100*(aspect_bound & 0xffff) >> 16));
-
- aspect_vid = (rc_vid.r << 16) / rc_vid.b;
-
- DEBUGF("aspect_vid: %u.%02u\n", (unsigned)(aspect_vid >> 16),
- (unsigned)(100*(aspect_vid & 0xffff) >> 16));
-
- if (aspect_vid >= aspect_bound)
- {
- /* Video proportionally wider than or same as bounding rectangle */
- if (rc_vid.r > rc_bound.r - rc_bound.l)
- {
- rc_vid.r = rc_bound.r - rc_bound.l;
- rc_vid.b = (rc_vid.r << 16) / aspect_vid;
- }
- /* else already fits */
- }
- else
- {
- /* Video proportionally narrower than bounding rectangle */
- if (rc_vid.b > rc_bound.b - rc_bound.t)
- {
- rc_vid.b = rc_bound.b - rc_bound.t;
- rc_vid.r = (aspect_vid * rc_vid.b) >> 16;
- }
- /* else already fits */
- }
-
- /* Even width and height >= 2 */
- rc_vid.r = (rc_vid.r < 2) ? 2 : (rc_vid.r & ~1);
- rc_vid.b = (rc_vid.b < 2) ? 2 : (rc_vid.b & ~1);
-
- /* Center display in bounding rectangle */
- rc_vid.l = ((rc_bound.l + rc_bound.r) - rc_vid.r) / 2;
- rc_vid.r += rc_vid.l;
-
- rc_vid.t = ((rc_bound.t + rc_bound.b) - rc_vid.b) / 2;
- rc_vid.b += rc_vid.t;
-
- DEBUGF("rc_vid: %d, %d, %d, %d\n", rc_vid.l, rc_vid.t,
- rc_vid.r, rc_vid.b);
-
-#ifndef HAVE_LCD_COLOR
- stream_gray_show(true);
-#endif
-
- while (slider_state < STATE9)
- {
- button = mpeg_button_get(tmo);
-
- switch (button)
- {
- case BUTTON_NONE:
- break;
-
- /* Coarse (1 minute) control */
- case MPEG_START_TIME_DOWN:
- case MPEG_START_TIME_DOWN | BUTTON_REPEAT:
-#ifdef MPEG_START_TIME_RC_DOWN
- case MPEG_START_TIME_RC_DOWN:
- case MPEG_START_TIME_RC_DOWN | BUTTON_REPEAT:
-#endif
- resume_time = increment_time(resume_time, -60*TS_SECOND, duration);
- slider_state = STATE0;
- break;
-
- case MPEG_START_TIME_UP:
- case MPEG_START_TIME_UP | BUTTON_REPEAT:
-#ifdef MPEG_START_TIME_RC_UP
- case MPEG_START_TIME_RC_UP:
- case MPEG_START_TIME_RC_UP | BUTTON_REPEAT:
-#endif
- resume_time = increment_time(resume_time, 60*TS_SECOND, duration);
- slider_state = STATE0;
- break;
-
- /* Fine (1 second) control */
- case MPEG_START_TIME_LEFT:
- case MPEG_START_TIME_LEFT | BUTTON_REPEAT:
-#ifdef MPEG_START_TIME_RC_LEFT
- case MPEG_START_TIME_RC_LEFT:
- case MPEG_START_TIME_RC_LEFT | BUTTON_REPEAT:
-#endif
-#ifdef MPEG_START_TIME_LEFT2
- case MPEG_START_TIME_LEFT2:
- case MPEG_START_TIME_LEFT2 | BUTTON_REPEAT:
-#endif
- resume_time = increment_time(resume_time, -TS_SECOND, duration);
- slider_state = STATE0;
- break;
-
- case MPEG_START_TIME_RIGHT:
- case MPEG_START_TIME_RIGHT | BUTTON_REPEAT:
-#ifdef MPEG_START_TIME_RC_RIGHT
- case MPEG_START_TIME_RC_RIGHT:
- case MPEG_START_TIME_RC_RIGHT | BUTTON_REPEAT:
-#endif
-#ifdef MPEG_START_TIME_RIGHT2
- case MPEG_START_TIME_RIGHT2:
- case MPEG_START_TIME_RIGHT2 | BUTTON_REPEAT:
-#endif
- resume_time = increment_time(resume_time, TS_SECOND, duration);
- slider_state = STATE0;
- break;
-
- case MPEG_START_TIME_SELECT:
-#ifdef MPEG_START_TIME_RC_SELECT
- case MPEG_START_TIME_RC_SELECT:
-#endif
- settings.resume_time = resume_time;
- button = MPEG_START_SEEK;
- slider_state = STATE9;
- break;
-
- case MPEG_START_TIME_EXIT:
-#ifdef MPEG_START_TIME_RC_EXIT
- case MPEG_START_TIME_RC_EXIT:
-#endif
- button = MPEG_START_EXIT;
- slider_state = STATE9;
- break;
-
- case ACTION_STD_CANCEL:
- button = MPEG_START_QUIT;
- slider_state = STATE9;
- break;
-
-#ifdef HAVE_LCD_ENABLE
- case LCD_ENABLE_EVENT_0:
- if (slider_state == STATE2)
- display_thumb_image(&rc_vid);
- continue;
-#endif
-
- default:
- rb->default_event_handler(button);
- rb->yield();
- continue;
- }
-
- switch (slider_state)
- {
- case STATE0:
- if (!sliding)
- {
- if (rb->global_settings->talk_menu)
- {
- rb->talk_disable(true);
-#ifdef PLUGIN_USE_IRAM
- mpegplayer_iram_restore();
-#endif
- }
- trigger_cpu_boost();
- sliding = true;
- }
- stream_seek(resume_time, SEEK_SET);
- show_loading(&rc_bound);
- draw_slider(duration, resume_time, NULL);
- slider_state = STATE1;
- tmo = THUMB_DELAY;
- break;
- case STATE1:
- display_thumb_image(&rc_vid);
- slider_state = STATE2;
- tmo = TIMEOUT_BLOCK;
- if (sliding)
- {
- cancel_cpu_boost();
- if (rb->global_settings->talk_menu)
- {
-#ifdef PLUGIN_USE_IRAM
- mpegplayer_iram_preserve();
-#endif
- rb->talk_disable(false);
- talk_val(resume_time / TS_SECOND, UNIT_TIME, false);
- talk_val(resume_time * 100 / duration, UNIT_PERCENT, true);
- }
- sliding = false;
- }
- default:
- break;
- }
-
- rb->yield();
- }
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- rb->remove_event(LCD_EVENT_ACTIVATION, get_start_time_lcd_enable_hook);
-#endif
-#ifndef HAVE_LCD_COLOR
- stream_gray_show(false);
- grey_clear_display();
- grey_update();
-#endif
-
- cancel_cpu_boost();
-
- return button;
-}
-
-static int show_start_menu(uint32_t duration)
-{
- int selected = 0;
- int result = 0;
- bool menu_quit = false;
-
- MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback,
- ID2P(LANG_RESTART_PLAYBACK),
- ID2P(LANG_RESUME_PLAYBACK),
- ID2P(LANG_SET_RESUME_TIME),
- ID2P(LANG_SETTINGS),
- ID2P(LANG_MENU_QUIT));
-
- if (rb->global_settings->talk_menu)
- {
-#ifdef PLUGIN_USE_IRAM
- mpegplayer_iram_preserve();
-#endif
- rb->talk_disable(false);
- }
-
- rb->button_clear_queue();
-
- while (!menu_quit)
- {
- mpeg_sysevent_clear();
- result = rb->do_menu(&menu, &selected, NULL, false);
-
- switch (result)
- {
- case MPEG_START_RESTART:
- settings.resume_time = 0;
- menu_quit = true;
- break;
-
- case MPEG_START_RESUME:
- menu_quit = true;
- break;
-
- case MPEG_START_SEEK:
- if (!stream_can_seek())
- {
- rb->splash(HZ, ID2P(LANG_UNAVAILABLE));
- break;
- }
-
- result = get_start_time(duration);
-
- if (result != MPEG_START_EXIT)
- menu_quit = true;
- break;
-
- case MPEG_START_SETTINGS:
- mpeg_settings();
- break;
-
- default:
- result = MPEG_START_QUIT;
- menu_quit = true;
- break;
- }
-
- if (mpeg_sysevent() != 0)
- {
- result = MPEG_START_QUIT;
- menu_quit = true;
- }
- }
-
- if (rb->global_settings->talk_menu)
- {
- rb->talk_disable(true);
-#ifdef PLUGIN_USE_IRAM
- mpegplayer_iram_restore();
-#endif
- }
-
- return result;
-}
-
-/* Return the desired resume action */
-int mpeg_start_menu(uint32_t duration)
-{
- mpeg_sysevent_clear();
-
- switch (settings.resume_options)
- {
- case MPEG_RESUME_MENU_IF_INCOMPLETE:
- if (!stream_can_seek() || settings.resume_time == 0)
- {
- case MPEG_RESUME_RESTART:
- settings.resume_time = 0;
- return MPEG_START_RESTART;
- }
- default:
- case MPEG_RESUME_MENU_ALWAYS:
- return show_start_menu(duration);
- case MPEG_RESUME_ALWAYS:
- return MPEG_START_SEEK;
- }
-}
-
-int mpeg_menu(void)
-{
- int result;
-
- MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_sysevent_callback,
- ID2P(LANG_SETTINGS),
- ID2P(LANG_RESUME_PLAYBACK),
- ID2P(LANG_MENU_QUIT));
-
- if (rb->global_settings->talk_menu)
- {
-#ifdef PLUGIN_USE_IRAM
- mpegplayer_iram_preserve();
-#endif
- rb->talk_disable(false);
- }
-
- rb->button_clear_queue();
-
- mpeg_sysevent_clear();
-
- result = rb->do_menu(&menu, NULL, NULL, false);
-
- switch (result)
- {
- case MPEG_MENU_SETTINGS:
- mpeg_settings();
- break;
-
- case MPEG_MENU_RESUME:
- break;
-
- case MPEG_MENU_QUIT:
- break;
-
- default:
- break;
- }
-
- if (mpeg_sysevent() != 0)
- result = MPEG_MENU_QUIT;
-
- if (rb->global_settings->talk_menu)
- {
- rb->talk_disable(true);
-#ifdef PLUGIN_USE_IRAM
- mpegplayer_iram_restore();
-#endif
- }
-
- return result;
-}
-
-static void display_options(void)
-{
- int selected = 0;
- int result;
- bool menu_quit = false;
-
- MENUITEM_STRINGLIST(menu, "Display Options", mpeg_sysevent_callback,
-#if MPEG_OPTION_DITHERING_ENABLED
- ID2P(LANG_DITHERING),
-#endif
- ID2P(LANG_DISPLAY_FPS),
- ID2P(LANG_LIMIT_FPS),
- ID2P(LANG_SKIP_FRAMES),
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- ID2P(LANG_BACKLIGHT_BRIGHTNESS),
-#endif
- );
-
- rb->button_clear_queue();
-
- while (!menu_quit)
- {
- mpeg_sysevent_clear();
- result = rb->do_menu(&menu, &selected, NULL, false);
-
- switch (result)
- {
-#if MPEG_OPTION_DITHERING_ENABLED
- case MPEG_OPTION_DITHERING:
- result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
- mpeg_set_option(rb->str(LANG_DITHERING), &result, INT, noyes, 2, NULL);
- settings.displayoptions =
- (settings.displayoptions & ~LCD_YUV_DITHER)
- | ((result != 0) ? LCD_YUV_DITHER : 0);
- rb->lcd_yuv_set_options(settings.displayoptions);
- break;
-#endif /* MPEG_OPTION_DITHERING_ENABLED */
-
- case MPEG_OPTION_DISPLAY_FPS:
- mpeg_set_option(rb->str(LANG_DISPLAY_FPS), &settings.showfps, INT,
- noyes, 2, NULL);
- break;
-
- case MPEG_OPTION_LIMIT_FPS:
- mpeg_set_option(rb->str(LANG_LIMIT_FPS), &settings.limitfps, INT,
- noyes, 2, NULL);
- break;
-
- case MPEG_OPTION_SKIP_FRAMES:
- mpeg_set_option(rb->str(LANG_SKIP_FRAMES), &settings.skipframes, INT,
- noyes, 2, NULL);
- break;
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- case MPEG_OPTION_BACKLIGHT_BRIGHTNESS:
- result = settings.backlight_brightness;
- mpeg_backlight_update_brightness(result);
- mpeg_set_int(rb->str(LANG_BACKLIGHT_BRIGHTNESS), NULL, UNIT_INT, &result,
- backlight_brightness_function, 1, -1,
- MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING,
- backlight_brightness_formatter,
- backlight_brightness_getlang);
- settings.backlight_brightness = result;
- mpeg_backlight_update_brightness(-1);
- break;
-#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
-
- default:
- menu_quit = true;
- break;
- }
-
- if (mpeg_sysevent() != 0)
- menu_quit = true;
- }
-}
-
-static void audio_options(void)
-{
- int selected = 0;
- int result;
- bool menu_quit = false;
-
- MENUITEM_STRINGLIST(menu, "Audio Options", mpeg_sysevent_callback,
- ID2P(LANG_TONE_CONTROLS),
- ID2P(LANG_CHANNEL_CONFIGURATION),
- ID2P(LANG_CROSSFEED),
- ID2P(LANG_EQUALIZER),
- ID2P(LANG_DITHERING));
-
- rb->button_clear_queue();
-
- while (!menu_quit)
- {
- mpeg_sysevent_clear();
- result = rb->do_menu(&menu, &selected, NULL, false);
-
- switch (result)
- {
- case MPEG_AUDIO_TONE_CONTROLS:
- mpeg_set_option(rb->str(LANG_TONE_CONTROLS), &settings.tone_controls, INT,
- globaloff, 2, NULL);
- sync_audio_setting(result, false);
- break;
-
- case MPEG_AUDIO_CHANNEL_MODES:
- mpeg_set_option(rb->str(LANG_CHANNEL_CONFIGURATION), &settings.channel_modes,
- INT, globaloff, 2, NULL);
- sync_audio_setting(result, false);
- break;
-
- case MPEG_AUDIO_CROSSFEED:
- mpeg_set_option(rb->str(LANG_CROSSFEED), &settings.crossfeed, INT,
- globaloff, 2, NULL);
- sync_audio_setting(result, false);
- break;
-
- case MPEG_AUDIO_EQUALIZER:
- mpeg_set_option(rb->str(LANG_EQUALIZER), &settings.equalizer, INT,
- globaloff, 2, NULL);
- sync_audio_setting(result, false);
- break;
-
- case MPEG_AUDIO_DITHERING:
- mpeg_set_option(rb->str(LANG_DITHERING), &settings.dithering, INT,
- globaloff, 2, NULL);
- sync_audio_setting(result, false);
- break;
-
- default:
- menu_quit = true;
- break;
- }
-
- if (mpeg_sysevent() != 0)
- menu_quit = true;
- }
-}
-
-static void resume_options(void)
-{
- static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = {
- [MPEG_RESUME_MENU_ALWAYS] =
- { STR(LANG_FORCE_START_MENU) },
- [MPEG_RESUME_MENU_IF_INCOMPLETE] =
- { STR(LANG_CONDITIONAL_START_MENU) },
- [MPEG_RESUME_ALWAYS] =
- { STR(LANG_AUTO_RESUME) },
- [MPEG_RESUME_RESTART] =
- { STR(LANG_RESTART_PLAYBACK) },
- };
-
- mpeg_set_option(rb->str(LANG_MENU_RESUME_OPTIONS), &settings.resume_options,
- INT, items, MPEG_RESUME_NUM_OPTIONS, NULL);
-}
-
-static void clear_resume_count(void)
-{
- settings.resume_count = 0;
- configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config),
- SETTINGS_VERSION);
-}
-
-static void mpeg_settings(void)
-{
- int selected = 0;
- int result;
- bool menu_quit = false;
-
- MENUITEM_STRINGLIST(menu, "Settings", mpeg_sysevent_callback,
- ID2P(LANG_MENU_DISPLAY_OPTIONS),
- ID2P(LANG_MENU_AUDIO_OPTIONS),
- ID2P(LANG_MENU_RESUME_OPTIONS),
- ID2P(LANG_MENU_PLAY_MODE),
- ID2P(LANG_CLEAR_ALL_RESUMES));
-
- rb->button_clear_queue();
-
- while (!menu_quit)
- {
- mpeg_sysevent_clear();
-
- result = rb->do_menu(&menu, &selected, NULL, false);
-
- switch (result)
- {
- case MPEG_SETTING_DISPLAY_SETTINGS:
- display_options();
- break;
-
- case MPEG_SETTING_AUDIO_SETTINGS:
- audio_options();
- break;
-
- case MPEG_SETTING_ENABLE_START_MENU:
- resume_options();
- break;
-
- case MPEG_SETTING_PLAY_MODE:
- mpeg_set_option(rb->str(LANG_MENU_PLAY_MODE), &settings.play_mode,
- INT, singleall, 2, NULL);
- break;
-
- case MPEG_SETTING_CLEAR_RESUMES:
- clear_resume_count();
- break;
-
- default:
- menu_quit = true;
- break;
- }
-
- if (mpeg_sysevent() != 0)
- menu_quit = true;
- }
-}
-
-void init_settings(const char* filename)
-{
- /* Set the default settings */
- settings.showfps = 0; /* Do not show FPS */
- settings.limitfps = 1; /* Limit FPS */
- settings.skipframes = 1; /* Skip frames */
- settings.play_mode = 0; /* Play single video */
- settings.resume_options = MPEG_RESUME_MENU_ALWAYS; /* Enable start menu */
- settings.resume_count = 0;
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- settings.backlight_brightness = -1; /* Use default setting */
-#endif
-#if MPEG_OPTION_DITHERING_ENABLED
- settings.displayoptions = 0; /* No visual effects */
-#endif
- settings.tone_controls = false;
- settings.channel_modes = false;
- settings.crossfeed = false;
- settings.equalizer = false;
- settings.dithering = false;
-
- if (configfile_load(SETTINGS_FILENAME, config, ARRAYLEN(config),
- SETTINGS_MIN_VERSION) < 0)
- {
- /* Generate a new config file with default values */
- configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config),
- SETTINGS_VERSION);
- }
-
- rb->strlcpy(settings.resume_filename, filename, MAX_PATH);
-
- /* get the resume time for the current mpeg if it exists */
- if ((settings.resume_time = configfile_get_value
- (SETTINGS_FILENAME, filename)) < 0)
- {
- settings.resume_time = 0;
- }
-
-#if MPEG_OPTION_DITHERING_ENABLED
- rb->lcd_yuv_set_options(settings.displayoptions);
-#endif
-
- /* Set our audio options */
- sync_audio_settings(false);
-}
-
-void save_settings(void)
-{
- unsigned i;
- for (i = 0; i < ARRAYLEN(config); i++)
- {
- configfile_update_entry(SETTINGS_FILENAME, config[i].name,
- *(config[i].int_p));
- }
-
- /* If this was a new resume entry then update the total resume count */
- if (configfile_update_entry(SETTINGS_FILENAME, settings.resume_filename,
- settings.resume_time) == 0)
- {
- configfile_update_entry(SETTINGS_FILENAME, "Resume count",
- ++settings.resume_count);
- }
-
- /* Restore audio options */
- sync_audio_settings(true);
-}
diff --git a/apps/plugins/mpegplayer/mpeg_settings.h b/apps/plugins/mpegplayer/mpeg_settings.h
deleted file mode 100644
index b1704ef707..0000000000
--- a/apps/plugins/mpegplayer/mpeg_settings.h
+++ /dev/null
@@ -1,110 +0,0 @@
-
-#include "plugin.h"
-
-#define SETTINGS_VERSION 5
-#define SETTINGS_MIN_VERSION 1
-#define SETTINGS_FILENAME "mpegplayer.cfg"
-
-#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) \
- || defined(IRIVER_H10) || defined(COWON_D2) || defined(PHILIPS_HDD1630) \
- || defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_FUZEV2) \
- || defined(TOSHIBA_GIGABEAT_S) || defined(PHILIPS_SA9200)
-#define MPEG_OPTION_DITHERING_ENABLED 1
-#endif
-
-#ifndef MPEG_OPTION_DITHERING_ENABLED
-#define MPEG_OPTION_DITHERING_ENABLED 0
-#endif
-
-enum mpeg_option_id
-{
-#if MPEG_OPTION_DITHERING_ENABLED
- MPEG_OPTION_DITHERING,
-#endif
- MPEG_OPTION_DISPLAY_FPS,
- MPEG_OPTION_LIMIT_FPS,
- MPEG_OPTION_SKIP_FRAMES,
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- MPEG_OPTION_BACKLIGHT_BRIGHTNESS,
-#endif
-};
-
-enum mpeg_audio_option_id
-{
- MPEG_AUDIO_TONE_CONTROLS,
- MPEG_AUDIO_CHANNEL_MODES,
- MPEG_AUDIO_CROSSFEED,
- MPEG_AUDIO_EQUALIZER,
- MPEG_AUDIO_DITHERING,
-};
-
-enum mpeg_resume_id
-{
- MPEG_RESUME_MENU_ALWAYS = 0,
- MPEG_RESUME_MENU_IF_INCOMPLETE,
- MPEG_RESUME_RESTART,
- MPEG_RESUME_ALWAYS,
- MPEG_RESUME_NUM_OPTIONS,
-};
-
-enum mpeg_start_id
-{
- MPEG_START_RESTART,
- MPEG_START_RESUME,
- MPEG_START_SEEK,
- MPEG_START_SETTINGS,
- MPEG_START_QUIT,
- MPEG_START_EXIT,
-};
-
-enum mpeg_setting_id
-{
- MPEG_SETTING_DISPLAY_SETTINGS,
- MPEG_SETTING_AUDIO_SETTINGS,
- MPEG_SETTING_ENABLE_START_MENU,
- MPEG_SETTING_PLAY_MODE,
- MPEG_SETTING_CLEAR_RESUMES,
-};
-
-enum mpeg_menu_id
-{
- MPEG_MENU_SETTINGS,
- MPEG_MENU_RESUME,
- MPEG_MENU_QUIT,
-};
-
-struct mpeg_settings {
- int showfps; /* flag to display fps */
- int limitfps; /* flag to limit fps */
- int skipframes; /* flag to skip frames */
- int resume_options; /* type of resume action at start */
- int resume_count; /* total # of resumes in config file */
- int resume_time; /* resume time for current mpeg (in half minutes) */
- char resume_filename[MAX_PATH]; /* filename of current mpeg */
-#if MPEG_OPTION_DITHERING_ENABLED
- int displayoptions;
-#endif
- int play_mode; /* play single file or all files in directory */
- /* Audio options - simple on/off specification */
- int tone_controls;
- int channel_modes;
- int crossfeed;
- int equalizer;
- int dithering;
- /* Backlight options */
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
- int backlight_brightness;
-#endif
-};
-
-extern struct mpeg_settings settings;
-
-int mpeg_start_menu(uint32_t duration);
-int mpeg_menu(void);
-
-void init_settings(const char* filename);
-void save_settings(void);
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-void mpeg_backlight_update_brightness(int value);
-#endif
diff --git a/apps/plugins/mpegplayer/mpeg_stream.h b/apps/plugins/mpegplayer/mpeg_stream.h
deleted file mode 100644
index 26fdaf07b4..0000000000
--- a/apps/plugins/mpegplayer/mpeg_stream.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Stream definitions for MPEG
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef MPEG_STREAM_H
-#define MPEG_STREAM_H
-
-/* Codes for various header byte sequences - MSB represents lowest memory
- address */
-#define PACKET_START_CODE_PREFIX 0x00000100ul
-#define END_CODE 0x000001b9ul
-#define PACK_START_CODE 0x000001baul
-#define SYSTEM_HEADER_START_CODE 0x000001bbul
-
-/* p = base pointer, b0 - b4 = byte offsets from p */
-/* We only care about the MS 32 bits of the 33 and so the ticks are 45kHz */
-#define TS_FROM_HEADER(p, b0) \
- ((uint32_t)((((p)[(b0)+0] & 0x0e) << 28) | \
- (((p)[(b0)+1] ) << 21) | \
- (((p)[(b0)+2] & 0xfe) << 13) | \
- (((p)[(b0)+3] ) << 6) | \
- (((p)[(b0)+4] ) >> 2)))
-
-#define TS_CHECK_MARKERS(p, b0) \
- (((((p)[(b0)+0] & 0x01) << 2) | \
- (((p)[(b0)+2] & 0x01) << 1) | \
- (((p)[(b0)+4] & 0x01) )) == 0x07)
-
-/* Get the SCR in our 45kHz ticks. Ignore the 9-bit extension */
-#define MPEG2_PACK_HEADER_SCR(p, b0) \
- ((uint32_t)((((p)[(b0)+0] & 0x38) << 26) | \
- (((p)[(b0)+0] & 0x03) << 27) | \
- (((p)[(b0)+1] ) << 19) | \
- (((p)[(b0)+2] & 0xf8) << 11) | \
- (((p)[(b0)+2] & 0x03) << 12) | \
- (((p)[(b0)+3] ) << 4) | \
- (((p)[(b0)+4] ) >> 4)))
-
-#define MPEG2_CHECK_PACK_SCR_MARKERS(ph, b0) \
- (((((ph)[(b0)+0] & 0x04) ) | \
- (((ph)[(b0)+2] & 0x04) >> 1) | \
- (((ph)[(b0)+4] & 0x04) >> 2)) == 0x07)
-
-#define INVALID_TIMESTAMP (~(uint32_t)0)
-#define MAX_TIMESTAMP (INVALID_TIMESTAMP-1)
-#define TS_SECOND (45000) /* Timestamp ticks per second */
-#define TC_SECOND (27000000) /* MPEG timecode ticks per second */
-
-/* These values immediately follow the start code prefix '00 00 01' */
-
-/* Video start codes */
-#define MPEG_START_PICTURE 0x00
-#define MPEG_START_SLICE_FIRST 0x01
-#define MPEG_START_SLICE_LAST 0xaf
-#define MPEG_START_RESERVED_1 0xb0
-#define MPEG_START_RESERVED_2 0xb1
-#define MPEG_START_USER_DATA 0xb2
-#define MPEG_START_SEQUENCE_HEADER 0xb3
-#define MPEG_START_SEQUENCE_ERROR 0xb4
-#define MPEG_START_EXTENSION 0xb5
-#define MPEG_START_RESERVED_3 0xb6
-#define MPEG_START_SEQUENCE_END 0xb7
-#define MPEG_START_GOP 0xb8
-
-/* Stream IDs */
-#define MPEG_STREAM_PROGRAM_END 0xb9
-#define MPEG_STREAM_PACK_HEADER 0xba
-#define MPEG_STREAM_SYSTEM_HEADER 0xbb
-#define MPEG_STREAM_PROGRAM_STREAM_MAP 0xbc
-#define MPEG_STREAM_PRIVATE_1 0xbd
-#define MPEG_STREAM_PADDING 0xbe
-#define MPEG_STREAM_PRIVATE_2 0xbf
-#define MPEG_STREAM_AUDIO_FIRST 0xc0
-#define MPEG_STREAM_AUDIO_LAST 0xcf
-#define MPEG_STREAM_VIDEO_FIRST 0xe0
-#define MPEG_STREAM_VIDEO_LAST 0xef
-#define MPEG_STREAM_ECM 0xf0
-#define MPEG_STREAM_EMM 0xf1
-/* ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A or
- * ISO/IEC 13818-6_DSMCC_stream */
-#define MPEG_STREAM_MISC_1 0xf2
-/* ISO/IEC_13522_stream */
-#define MPEG_STREAM_MISC_2 0xf3
-/* ITU-T Rec. H.222.1 type A - E */
-#define MPEG_STREAM_MISC_3 0xf4
-#define MPEG_STREAM_MISC_4 0xf5
-#define MPEG_STREAM_MISC_5 0xf6
-#define MPEG_STREAM_MISC_6 0xf7
-#define MPEG_STREAM_MISC_7 0xf8
-#define MPEG_STREAM_ANCILLARY 0xf9
-#define MPEG_STREAM_RESERVED_FIRST 0xfa
-#define MPEG_STREAM_RESERVED_LAST 0xfe
-/* Program stream directory */
-#define MPEG_STREAM_PROGRAM_DIRECTORY 0xff
-
-#define STREAM_IS_AUDIO(s) (((s) & 0xf0) == 0xc0)
-#define STREAM_IS_VIDEO(s) (((s) & 0xf0) == 0xe0)
-
-#define MPEG_MAX_PACKET_SIZE (64*1024+16)
-
-/* Largest MPEG audio frame - MPEG1, Layer II, 384kbps, 32kHz, pad */
-#define MPA_MAX_FRAME_SIZE 1729
-
-#endif /* MPEG_STREAM_H */
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
deleted file mode 100644
index e66b4df146..0000000000
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ /dev/null
@@ -1,2638 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * mpegplayer main entrypoint and UI implementation
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * NOTES:
- *
- * mpegplayer is structured as follows:
- *
- * +-->Video Thread-->Video Output-->LCD
- * |
- * UI-->Stream Manager-->+-->Audio Thread-->PCM buffer--Audio Device
- * | | | | (ref. clock)
- * | | +-->Buffer Thread |
- * Stream Data | | (clock intf./
- * Requests | File Cache drift adj.)
- * | Disk I/O
- * Stream services
- * (timing, etc.)
- *
- * Thread list:
- * 1) The main thread - Handles user input, settings, basic playback control
- * and USB connect.
- *
- * 2) Stream Manager thread - Handles playback state, events from streams
- * such as when a stream is finished, stream commands, PCM state. The
- * layer in which this thread run also handles arbitration of data
- * requests between the streams and the disk buffer. The actual specific
- * transport layer code may get moved out to support multiple container
- * formats.
- *
- * 3) Buffer thread - Buffers data in the background, generates notifications
- * to streams when their data has been buffered, and watches streams'
- * progress to keep data available during playback. Handles synchronous
- * random access requests when the file cache is missed.
- *
- * 4) Video thread (running on the COP for PortalPlayer targets) - Decodes
- * the video stream and renders video frames to the LCD. Handles
- * miscellaneous video tasks like frame and thumbnail printing.
- *
- * 5) Audio thread (running on the main CPU to maintain consistency with the
- * audio FIQ hander on PP) - Decodes audio frames and places them into
- * the PCM buffer for rendering by the audio device.
- *
- * Streams are neither aware of one another nor care about one another. All
- * streams shall have their own thread (unless it is _really_ efficient to
- * have a single thread handle a couple minor streams). All coordination of
- * the streams is done through the stream manager. The clocking is controlled
- * by and exposed by the stream manager to other streams and implemented at
- * the PCM level.
- *
- * Notes about MPEG files:
- *
- * MPEG System Clock is 27MHz - i.e. 27000000 ticks/second.
- *
- * FPS is represented in terms of a frame period - this is always an
- * integer number of 27MHz ticks.
- *
- * e.g. 29.97fps (30000/1001) NTSC video has an exact frame period of
- * 900900 27MHz ticks.
- *
- * In libmpeg2, info->sequence->frame_period contains the frame_period.
- *
- * Working with Rockbox's 100Hz tick, the common frame rates would need
- * to be as follows (1):
- *
- * FPS | 27Mhz | 100Hz | 44.1KHz | 48KHz
- * --------|-----------------------------------------------------------
- * 10* | 2700000 | 10 | 4410 | 4800
- * 12* | 2250000 | 8.3333 | 3675 | 4000
- * 15* | 1800000 | 6.6667 | 2940 | 3200
- * 23.9760 | 1126125 | 4.170833333 | 1839.3375 | 2002
- * 24 | 1125000 | 4.166667 | 1837.5 | 2000
- * 25 | 1080000 | 4 | 1764 | 1920
- * 29.9700 | 900900 | 3.336667 | 1471,47 | 1601.6
- * 30 | 900000 | 3.333333 | 1470 | 1600
- *
- * *Unofficial framerates
- *
- * (1) But we don't really care since the audio clock is used anyway and has
- * very fine resolution ;-)
- *****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-#include "lib/helper.h"
-#include "mpeg_settings.h"
-#include "video_out.h"
-#include "stream_thread.h"
-#include "stream_mgr.h"
-
-
-/* button definitions */
-#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define MPEG_MENU BUTTON_MODE
-#define MPEG_STOP BUTTON_OFF
-#define MPEG_PAUSE BUTTON_ON
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
- (CONFIG_KEYPAD == IPOD_1G2G_PAD)
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_PAUSE (BUTTON_PLAY | BUTTON_REL)
-#define MPEG_STOP (BUTTON_PLAY | BUTTON_REPEAT)
-#define MPEG_VOLDOWN BUTTON_SCROLL_BACK
-#define MPEG_VOLUP BUTTON_SCROLL_FWD
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
-#define MPEG_MENU (BUTTON_REC | BUTTON_REL)
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == GIGABEAT_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_SELECT
-#define MPEG_PAUSE2 BUTTON_A
-#define MPEG_VOLDOWN BUTTON_LEFT
-#define MPEG_VOLUP BUTTON_RIGHT
-#define MPEG_VOLDOWN2 BUTTON_VOL_DOWN
-#define MPEG_VOLUP2 BUTTON_VOL_UP
-#define MPEG_RW BUTTON_UP
-#define MPEG_FF BUTTON_DOWN
-
-#define MPEG_RC_MENU BUTTON_RC_DSP
-#define MPEG_RC_STOP (BUTTON_RC_PLAY | BUTTON_REPEAT)
-#define MPEG_RC_PAUSE (BUTTON_RC_PLAY | BUTTON_REL)
-#define MPEG_RC_VOLDOWN BUTTON_RC_VOL_DOWN
-#define MPEG_RC_VOLUP BUTTON_RC_VOL_UP
-#define MPEG_RC_RW BUTTON_RC_REW
-#define MPEG_RC_FF BUTTON_RC_FF
-
-#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_SELECT
-#define MPEG_PAUSE2 BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_LEFT
-#define MPEG_VOLUP BUTTON_RIGHT
-#define MPEG_VOLDOWN2 BUTTON_VOL_DOWN
-#define MPEG_VOLUP2 BUTTON_VOL_UP
-#define MPEG_RW BUTTON_UP
-#define MPEG_RW2 BUTTON_PREV
-#define MPEG_FF BUTTON_DOWN
-#define MPEG_FF2 BUTTON_NEXT
-#define MPEG_SHOW_OSD BUTTON_BACK
-
-#define MPEG_RC_MENU BUTTON_RC_DSP
-#define MPEG_RC_STOP (BUTTON_RC_PLAY | BUTTON_REPEAT)
-#define MPEG_RC_PAUSE (BUTTON_RC_PLAY | BUTTON_REL)
-#define MPEG_RC_VOLDOWN BUTTON_RC_VOL_DOWN
-#define MPEG_RC_VOLUP BUTTON_RC_VOL_UP
-#define MPEG_RC_RW BUTTON_RC_REW
-#define MPEG_RC_FF BUTTON_RC_FF
-
-#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-#define MPEG_MENU BUTTON_LEFT
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_SCROLL_DOWN
-#define MPEG_VOLUP BUTTON_SCROLL_UP
-#define MPEG_RW BUTTON_REW
-#define MPEG_FF BUTTON_FF
-
-#elif CONFIG_KEYPAD == SANSA_E200_PAD
-#define MPEG_MENU BUTTON_SELECT
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_RIGHT
-#define MPEG_VOLDOWN BUTTON_SCROLL_BACK
-#define MPEG_VOLUP BUTTON_SCROLL_FWD
-#define MPEG_RW BUTTON_UP
-#define MPEG_FF BUTTON_DOWN
-
-#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
-#define MPEG_MENU BUTTON_SELECT
-#define MPEG_STOP (BUTTON_HOME|BUTTON_REPEAT)
-#define MPEG_PAUSE BUTTON_UP
-#define MPEG_VOLDOWN BUTTON_SCROLL_BACK
-#define MPEG_VOLUP BUTTON_SCROLL_FWD
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-
-#elif CONFIG_KEYPAD == SANSA_C200_PAD || \
-CONFIG_KEYPAD == SANSA_CLIP_PAD || \
-CONFIG_KEYPAD == SANSA_M200_PAD
-#define MPEG_MENU BUTTON_SELECT
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_UP
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == MROBE500_PAD
-#define MPEG_STOP BUTTON_POWER
-
-#define MPEG_RC_MENU BUTTON_RC_HEART
-#define MPEG_RC_STOP BUTTON_RC_DOWN
-#define MPEG_RC_PAUSE BUTTON_RC_PLAY
-#define MPEG_RC_VOLDOWN BUTTON_RC_VOL_DOWN
-#define MPEG_RC_VOLUP BUTTON_RC_VOL_UP
-#define MPEG_RC_RW BUTTON_RC_REW
-#define MPEG_RC_FF BUTTON_RC_FF
-
-#elif CONFIG_KEYPAD == MROBE100_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
-#define MPEG_MENU BUTTON_RC_MENU
-#define MPEG_STOP BUTTON_RC_REC
-#define MPEG_PAUSE BUTTON_RC_PLAY
-#define MPEG_VOLDOWN BUTTON_RC_VOL_DOWN
-#define MPEG_VOLUP BUTTON_RC_VOL_UP
-#define MPEG_RW BUTTON_RC_REW
-#define MPEG_FF BUTTON_RC_FF
-
-#elif CONFIG_KEYPAD == COWON_D2_PAD
-#define MPEG_MENU (BUTTON_MENU|BUTTON_REL)
-//#define MPEG_STOP BUTTON_POWER
-#define MPEG_VOLDOWN BUTTON_MINUS
-#define MPEG_VOLUP BUTTON_PLUS
-
-#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_BACK
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_UP
-#define MPEG_VOLUP BUTTON_DOWN
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP (BUTTON_PLAY|BUTTON_REPEAT)
-#define MPEG_PAUSE (BUTTON_PLAY|BUTTON_REL)
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_DOWN
-#define MPEG_FF BUTTON_UP
-
-#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_SELECT
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_UP
-#define MPEG_FF BUTTON_DOWN
-
-#elif CONFIG_KEYPAD == ONDAVX747_PAD
-#define MPEG_MENU (BUTTON_MENU|BUTTON_REL)
-//#define MPEG_STOP BUTTON_POWER
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-
-#elif CONFIG_KEYPAD == ONDAVX777_PAD
-#define MPEG_MENU BUTTON_POWER
-
-#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \
- (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
-#define MPEG_MENU BUTTON_REW
-#define MPEG_STOP (BUTTON_PLAY | BUTTON_REPEAT)
-#define MPEG_PAUSE (BUTTON_PLAY | BUTTON_REL)
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-#define MPEG_SHOW_OSD BUTTON_FFWD
-
-#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_REC
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == MPIO_HD200_PAD
-#define MPEG_MENU BUTTON_FUNC
-#define MPEG_PAUSE (BUTTON_PLAY | BUTTON_REL)
-#define MPEG_STOP (BUTTON_PLAY | BUTTON_REPEAT)
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_REW
-#define MPEG_FF BUTTON_FF
-
-#elif CONFIG_KEYPAD == MPIO_HD300_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_PAUSE (BUTTON_PLAY | BUTTON_REL)
-#define MPEG_STOP (BUTTON_PLAY | BUTTON_REPEAT)
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_REW
-#define MPEG_FF BUTTON_FF
-
-#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_PAUSE (BUTTON_PLAYPAUSE | BUTTON_REL)
-#define MPEG_STOP (BUTTON_PLAYPAUSE | BUTTON_REPEAT)
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_PAUSE (BUTTON_SELECT | BUTTON_REL)
-#define MPEG_STOP (BUTTON_SELECT | BUTTON_REPEAT)
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_PAUSE BUTTON_SELECT
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == HM60X_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_PAUSE BUTTON_SELECT
-#define MPEG_STOP (BUTTON_SELECT | BUTTON_POWER)
-#define MPEG_VOLDOWN (BUTTON_POWER | BUTTON_DOWN)
-#define MPEG_VOLUP (BUTTON_POWER | BUTTON_UP)
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == HM801_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_STOP (BUTTON_POWER | BUTTON_PLAY)
-#define MPEG_VOLDOWN (BUTTON_POWER | BUTTON_DOWN)
-#define MPEG_VOLUP (BUTTON_POWER | BUTTON_UP)
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == SONY_NWZ_PAD
-#define MPEG_MENU BUTTON_BACK
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_VOLDOWN BUTTON_UP
-#define MPEG_VOLUP BUTTON_DOWN
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_PAUSE BUTTON_PLAYPAUSE
-#define MPEG_STOP BUTTON_BACK
-#define MPEG_VOLDOWN BUTTON_DOWN
-#define MPEG_VOLUP BUTTON_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == DX50_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_STOP (BUTTON_PLAY|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_PAUSE BUTTON_MENU
-#define MPEG_STOP (BUTTON_MENU|BUTTON_REPEAT)
-
-#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
-#define MPEG_MENU BUTTON_POWER
-#define MPEG_PAUSE BUTTON_SELECT
-#define MPEG_STOP BUTTON_DOWN
-#define MPEG_VOLDOWN BUTTON_VOLDOWN
-#define MPEG_VOLUP BUTTON_VOLUP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == XDUOO_X3_PAD
-#define MPEG_MENU BUTTON_PLAY
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_HOME
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD
-#define MPEG_MENU BUTTON_PLAY
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_HOME
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD
-#define MPEG_MENU BUTTON_PLAY
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_HOME
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD
-#define MPEG_MENU BUTTON_PLAY
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_HOME
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == EROSQ_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_PREV
-#define MPEG_FF BUTTON_NEXT
-
-#elif CONFIG_KEYPAD == FIIO_M3K_PAD
-#define MPEG_MENU BUTTON_MENU
-#define MPEG_STOP BUTTON_POWER
-#define MPEG_PAUSE BUTTON_PLAY
-#define MPEG_VOLDOWN BUTTON_VOL_DOWN
-#define MPEG_VOLUP BUTTON_VOL_UP
-#define MPEG_RW BUTTON_LEFT
-#define MPEG_FF BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
-/* use touchscreen */
-
-#else
-#error No keymap defined!
-#endif
-
-#ifdef HAVE_TOUCHSCREEN
-#ifndef MPEG_MENU
-#define MPEG_MENU (BUTTON_TOPRIGHT|BUTTON_REL)
-#endif
-#ifndef MPEG_STOP
-#define MPEG_STOP BUTTON_TOPLEFT
-#endif
-#ifndef MPEG_PAUSE
-#define MPEG_PAUSE BUTTON_CENTER
-#endif
-#ifndef MPEG_VOLDOWN
-#define MPEG_VOLDOWN BUTTON_BOTTOMMIDDLE
-#endif
-#ifndef MPEG_VOLUP
-#define MPEG_VOLUP BUTTON_TOPMIDDLE
-#endif
-#ifndef MPEG_RW
-#define MPEG_RW BUTTON_MIDLEFT
-#endif
-#ifndef MPEG_FF
-#define MPEG_FF BUTTON_MIDRIGHT
-#endif
-#endif
-
-/* One thing we can do here for targets with remotes is having a display
- * always on the remote instead of always forcing a popup on the main display */
-
-#define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */
- /* 3% of 30min file == 54s step size */
-#define MIN_FF_REWIND_STEP (TS_SECOND/2)
-#define OSD_MIN_UPDATE_INTERVAL (HZ/2)
-#define FPS_UPDATE_INTERVAL (HZ) /* Get new FPS reading each second */
-
-enum video_action
-{
- VIDEO_STOP = 0,
- VIDEO_PREV,
- VIDEO_NEXT,
- VIDEO_ACTION_MANUAL = 0x8000, /* Flag that says user did it */
-};
-
-/* OSD status - same order as icon array */
-enum osd_status_enum
-{
- OSD_STATUS_STOPPED = 0,
- OSD_STATUS_PAUSED,
- OSD_STATUS_PLAYING,
- OSD_STATUS_FF,
- OSD_STATUS_RW,
- OSD_STATUS_COUNT,
- OSD_STATUS_MASK = 0x7
-};
-
-enum osd_bits
-{
- OSD_REFRESH_DEFAULT = 0x0000, /* Only refresh elements when due */
- /* Refresh the... */
- OSD_REFRESH_VOLUME = 0x0001, /* ...volume display */
- OSD_REFRESH_TIME = 0x0002, /* ...time display+progress */
- OSD_REFRESH_STATUS = 0x0004, /* ...playback status icon */
- OSD_REFRESH_BACKGROUND = 0x0008, /* ...background (implies ALL) */
- OSD_REFRESH_VIDEO = 0x0010, /* ...video image upon timeout */
- OSD_REFRESH_RESUME = 0x0020, /* Resume playback upon timeout */
- OSD_NODRAW = 0x8000, /* OR bitflag - don't draw anything */
- OSD_SHOW = 0x4000, /* OR bitflag - show the OSD */
-#ifdef HAVE_HEADPHONE_DETECTION
- OSD_HP_PAUSE = 0x2000, /* OR bitflag - headphones caused pause */
-#endif
- OSD_HIDE = 0x0000, /* hide the OSD (aid readability) */
- OSD_REFRESH_ALL = 0x000f, /* Only immediate graphical elements */
-};
-
-/* Status icons selected according to font height */
-extern const unsigned char mpegplayer_status_icons_8x8x1[];
-extern const unsigned char mpegplayer_status_icons_12x12x1[];
-extern const unsigned char mpegplayer_status_icons_16x16x1[];
-
-/* Main border areas that contain OSD elements */
-#define OSD_BDR_L 2
-#define OSD_BDR_T 2
-#define OSD_BDR_R 2
-#define OSD_BDR_B 2
-
-struct osd
-{
- long hide_tick;
- long show_for;
- long print_tick;
- long print_delay;
- long resume_tick;
- long resume_delay;
- long next_auto_refresh;
- int x;
- int y;
- int width;
- int height;
- unsigned fgcolor;
- unsigned bgcolor;
- unsigned prog_fillcolor;
- struct vo_rect update_rect;
- struct vo_rect prog_rect;
- struct vo_rect time_rect;
- struct vo_rect dur_rect;
- struct vo_rect vol_rect;
- const unsigned char *icons;
- struct vo_rect stat_rect;
- int status;
- uint32_t curr_time;
- unsigned auto_refresh;
- unsigned flags;
- int font;
-};
-
-struct fps
-{
- /* FPS Display */
- struct vo_rect rect; /* OSD coordinates */
- int pf_x; /* Screen coordinates */
- int pf_y;
- int pf_width;
- int pf_height;
- long update_tick; /* When to next update FPS reading */
- #define FPS_FORMAT "%d.%02d"
- #define FPS_DIMSTR "999.99" /* For establishing rect size */
- #define FPS_BUFSIZE sizeof("999.99")
-};
-
-static struct osd osd;
-static struct fps fps NOCACHEBSS_ATTR; /* Accessed on other processor */
-
-#ifdef LCD_PORTRAIT
-static fb_data* get_framebuffer(void)
-{
- struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
- return vp_main->buffer->fb_ptr;
-}
-#endif
-
-static void osd_show(unsigned show);
-
-#ifdef LCD_LANDSCAPE
- #define __X (x + osd.x)
- #define __Y (y + osd.y)
- #define __W width
- #define __H height
-#else
- #define __X (LCD_WIDTH - (y + osd.y) - height)
- #define __Y (x + osd.x)
- #define __W height
- #define __H width
-#endif
-
-#ifdef HAVE_LCD_COLOR
-/* Blend two colors in 0-100% (0-255) mix of c2 into c1 */
-static unsigned draw_blendcolor(unsigned c1, unsigned c2, unsigned char amount)
-{
- int r1 = RGB_UNPACK_RED(c1);
- int g1 = RGB_UNPACK_GREEN(c1);
- int b1 = RGB_UNPACK_BLUE(c1);
-
- int r2 = RGB_UNPACK_RED(c2);
- int g2 = RGB_UNPACK_GREEN(c2);
- int b2 = RGB_UNPACK_BLUE(c2);
-
- return LCD_RGBPACK(amount*(r2 - r1) / 255 + r1,
- amount*(g2 - g1) / 255 + g1,
- amount*(b2 - b1) / 255 + b1);
-}
-#endif
-
-#ifdef PLUGIN_USE_IRAM
-/* IRAM preserving mechanism to enable talking menus */
-static char *iram_saved_copy;
-extern char iramstart[], iramend[];
-
-static void iram_saving_init(void)
-{
-#ifndef SIMULATOR
- size_t size;
- iram_saved_copy = (char *)rb->plugin_get_buffer(&size);
-
- if (size >= (size_t)(iramend-iramstart))
- iram_saved_copy += size - (size_t)(iramend - iramstart);
- else
-#endif
- iram_saved_copy = NULL;
-
- return;
-}
-
-void mpegplayer_iram_preserve(void)
-{
- if (iram_saved_copy)
- {
- rb->memcpy(iram_saved_copy, iramstart, iramend-iramstart);
-#ifdef HAVE_CPUCACHE_INVALIDATE
- /* make the icache (if it exists) up to date with the new code */
- rb->cpucache_invalidate();
-#endif /* HAVE_CPUCACHE_INVALIDATE */
- }
- return;
-}
-
-void mpegplayer_iram_restore(void)
-{
- if (iram_saved_copy)
- {
- rb->audio_hard_stop();
- rb->memcpy(iramstart, iram_saved_copy, iramend-iramstart);
-#ifdef HAVE_CPUCACHE_INVALIDATE
- /* make the icache (if it exists) up to date with the new code */
- rb->cpucache_invalidate();
-#endif /* HAVE_CPUCACHE_INVALIDATE */
- }
- return;
-}
-#endif
-
-/* Drawing functions that operate rotated on LCD_PORTRAIT displays -
- * most are just wrappers of lcd_* functions with transforms applied.
- * The origin is the upper-left corner of the OSD area */
-static void draw_update_rect(int x, int y, int width, int height)
-{
- mylcd_update_rect(__X, __Y, __W, __H);
-}
-
-static void draw_clear_area(int x, int y, int width, int height)
-{
-#ifdef HAVE_LCD_COLOR
- rb->screen_clear_area(rb->screens[SCREEN_MAIN], __X, __Y, __W, __H);
-#else
- int oldmode = grey_get_drawmode();
- grey_set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
- grey_fillrect(__X, __Y, __W, __H);
- grey_set_drawmode(oldmode);
-#endif
-}
-
-static void draw_clear_area_rect(const struct vo_rect *rc)
-{
- draw_clear_area(rc->l, rc->t, rc->r - rc->l, rc->b - rc->t);
-}
-
-static void draw_fillrect(int x, int y, int width, int height)
-{
- mylcd_fillrect(__X, __Y, __W, __H);
-}
-
-static void draw_hline(int x1, int x2, int y)
-{
-#ifdef LCD_LANDSCAPE
- mylcd_hline(x1 + osd.x, x2 + osd.x, y + osd.y);
-#else
- y = LCD_WIDTH - (y + osd.y) - 1;
- mylcd_vline(y, x1 + osd.x, x2 + osd.x);
-#endif
-}
-
-static void draw_vline(int x, int y1, int y2)
-{
-#ifdef LCD_LANDSCAPE
- mylcd_vline(x + osd.x, y1 + osd.y, y2 + osd.y);
-#else
- y1 = LCD_WIDTH - (y1 + osd.y) - 1;
- y2 = LCD_WIDTH - (y2 + osd.y) - 1;
- mylcd_hline(y1, y2, x + osd.x);
-#endif
-}
-
-static void draw_scrollbar_draw(int x, int y, int width, int height,
- uint32_t min, uint32_t max, uint32_t val)
-{
- unsigned oldfg = mylcd_get_foreground();
-
- draw_hline(x + 1, x + width - 2, y);
- draw_hline(x + 1, x + width - 2, y + height - 1);
- draw_vline(x, y + 1, y + height - 2);
- draw_vline(x + width - 1, y + 1, y + height - 2);
-
- val = muldiv_uint32(width - 2, val, max - min);
- val = MIN(val, (uint32_t)(width - 2));
-
- draw_fillrect(x + 1, y + 1, val, height - 2);
-
- mylcd_set_foreground(osd.prog_fillcolor);
-
- draw_fillrect(x + 1 + val, y + 1, width - 2 - val, height - 2);
-
- mylcd_set_foreground(oldfg);
-}
-
-static void draw_scrollbar_draw_rect(const struct vo_rect *rc, int min,
- int max, int val)
-{
- draw_scrollbar_draw(rc->l, rc->t, rc->r - rc->l, rc->b - rc->t,
- min, max, val);
-}
-
-static void draw_setfont(int font)
-{
- osd.font = font;
- mylcd_setfont(font);
-}
-
-#ifdef LCD_PORTRAIT
-/* Portrait displays need rotated text rendering */
-
-/* Limited function that only renders in DRMODE_FG and uses absolute screen
- * coordinates */
-static void draw_oriented_mono_bitmap_part(const unsigned char *src,
- int src_x, int src_y,
- int stride, int x, int y,
- int width, int height)
-{
- const unsigned char *src_end;
- fb_data *dst, *dst_end;
- unsigned fg_pattern;
-
- if (x + width > SCREEN_WIDTH)
- width = SCREEN_WIDTH - x; /* Clip right */
- if (x < 0)
- width += x, x = 0; /* Clip left */
- if (width <= 0)
- return; /* nothing left to do */
-
- if (y + height > SCREEN_HEIGHT)
- height = SCREEN_HEIGHT - y; /* Clip bottom */
- if (y < 0)
- height += y, y = 0; /* Clip top */
- if (height <= 0)
- return; /* nothing left to do */
-
- fg_pattern = rb->lcd_get_foreground();
- /*bg_pattern =*/ rb->lcd_get_background();
-
- src += stride * (src_y >> 3) + src_x; /* move starting point */
- src_y &= 7;
- src_end = src + width;
-
- dst = get_framebuffer() + (LCD_WIDTH - y) + x*LCD_WIDTH;
- do
- {
- const unsigned char *src_col = src++;
- unsigned data = *src_col >> src_y;
- int numbits = 8 - src_y;
-
- fb_data *dst_col = dst;
- dst_end = dst_col - height;
- dst += LCD_WIDTH;
-
- do
- {
- dst_col--;
-
- if (data & 1)
- *dst_col = FB_SCALARPACK(fg_pattern);
-#if 0
- else
- *dst_col = bg_pattern;
-#endif
- data >>= 1;
- if (--numbits == 0) {
- src_col += stride;
- data = *src_col;
- numbits = 8;
- }
- }
- while (dst_col > dst_end);
- }
- while (src < src_end);
-}
-
-
-#define ALPHA_COLOR_FONT_DEPTH 2
-#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH)
-#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1)
-#define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH)
-#define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH)
-#ifdef CPU_ARM
-#define BLEND_INIT do {} while (0)
-#define BLEND_FINISH do {} while(0)
-#define BLEND_START(acc, color, alpha) \
- asm volatile("mul %0, %1, %2" : "=&r" (acc) : "r" (color), "r" (alpha))
-#define BLEND_CONT(acc, color, alpha) \
- asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha))
-#define BLEND_OUT(acc) do {} while (0)
-#elif defined(CPU_COLDFIRE)
-#define ALPHA_BITMAP_READ_WORDS
-#define BLEND_INIT \
- unsigned long _macsr = coldfire_get_macsr(); \
- coldfire_set_macsr(EMAC_UNSIGNED)
-#define BLEND_FINISH \
- coldfire_set_macsr(_macsr)
-#define BLEND_START(acc, color, alpha) \
- asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha))
-#define BLEND_CONT BLEND_START
-#define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc))
-#else
-#define BLEND_INIT do {} while (0)
-#define BLEND_FINISH do {} while(0)
-#define BLEND_START(acc, color, alpha) ((acc) = (color) * (alpha))
-#define BLEND_CONT(acc, color, alpha) ((acc) += (color) * (alpha))
-#define BLEND_OUT(acc) do {} while (0)
-#endif
-
-/* Blend the given two colors */
-static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a)
-{
-#if LCD_DEPTH == 16
- a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1);
-#if (LCD_PIXELFORMAT == RGB565SWAPPED)
- c1 = swap16(c1);
- c2 = swap16(c2);
-#endif
- unsigned c1l = (c1 | (c1 << 16)) & 0x07e0f81f;
- unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f;
- unsigned p;
- BLEND_START(p, c1l, a);
- BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a);
- BLEND_OUT(p);
- p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f;
- p |= (p >> 16);
-#if (LCD_PIXELFORMAT == RGB565SWAPPED)
- return swap16(p);
-#else
- return p;
-#endif
-
-#else /* LCD_DEPTH == 24 */
- unsigned s = c1;
- unsigned d = c2;
- unsigned s1 = s & 0xff00ff;
- unsigned d1 = d & 0xff00ff;
- a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1);
- d1 = (d1 + ((s1 - d1) * a >> ALPHA_COLOR_LOOKUP_SHIFT)) & 0xff00ff;
- s &= 0xff00;
- d &= 0xff00;
- d = (d + ((s - d) * a >> ALPHA_COLOR_LOOKUP_SHIFT)) & 0xff00;
-
- return d1 | d;
-#endif
-}
-
-static void draw_oriented_alpha_bitmap_part(const unsigned char *src,
- int src_x, int src_y,
- int stride, int x, int y,
- int width, int height)
-{
- fb_data *dst, *dst_start;
- unsigned fg_pattern;
-
- if (x + width > SCREEN_WIDTH)
- width = SCREEN_WIDTH - x; /* Clip right */
- if (x < 0)
- width += x, x = 0; /* Clip left */
- if (width <= 0)
- return; /* nothing left to do */
-
- if (y + height > SCREEN_HEIGHT)
- height = SCREEN_HEIGHT - y; /* Clip bottom */
- if (y < 0)
- height += y, y = 0; /* Clip top */
- if (height <= 0)
- return; /* nothing left to do */
-
- /* initialize blending */
- BLEND_INIT;
-
- fg_pattern = rb->lcd_get_foreground();
- /*bg_pattern=*/ rb->lcd_get_background();
-
- dst_start = get_framebuffer() + (LCD_WIDTH - y - 1) + x*LCD_WIDTH;
- int col, row = height;
- unsigned data, pixels;
- unsigned skip_end = (stride - width);
- unsigned skip_start = src_y * stride + src_x;
-
-#ifdef ALPHA_BITMAP_READ_WORDS
- uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3);
- skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3);
- src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD;
- data = letoh32(*src_w++);
-#else
- src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE;
- data = *src;
-#endif
- pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD;
- data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
-#ifdef ALPHA_BITMAP_READ_WORDS
- pixels = 8 - pixels;
-#endif
-
- do
- {
- col = width;
- dst = dst_start--;
-#ifdef ALPHA_BITMAP_READ_WORDS
-#define UPDATE_SRC_ALPHA do { \
- if (--pixels) \
- data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
- else \
- { \
- data = letoh32(*src_w++); \
- pixels = ALPHA_COLOR_PIXEL_PER_WORD; \
- } \
- } while (0)
-#elif ALPHA_COLOR_PIXEL_PER_BYTE == 2
-#define UPDATE_SRC_ALPHA do { \
- if (pixels ^= 1) \
- data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
- else \
- data = *(++src); \
- } while (0)
-#else
-#define UPDATE_SRC_ALPHA do { \
- if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \
- data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
- else \
- data = *(++src); \
- } while (0)
-#endif
- do
- {
- unsigned color = blend_two_colors(FB_UNPACK_SCALAR_LCD(*dst), fg_pattern,
- data & ALPHA_COLOR_LOOKUP_SIZE );
- *dst= FB_SCALARPACK(color);
- dst += LCD_WIDTH;
- UPDATE_SRC_ALPHA;
- }
- while (--col);
-#ifdef ALPHA_BITMAP_READ_WORDS
- if (skip_end < pixels)
- {
- pixels -= skip_end;
- data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
- } else {
- pixels = skip_end - pixels;
- src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD;
- pixels %= ALPHA_COLOR_PIXEL_PER_WORD;
- data = letoh32(*src_w++);
- data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
- pixels = 8 - pixels;
- }
-#else
- if (skip_end)
- {
- pixels += skip_end;
- if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE)
- {
- src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE;
- pixels %= ALPHA_COLOR_PIXEL_PER_BYTE;
- data = *src;
- data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT;
- } else
- data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
- }
-#endif
- } while (--row);
-}
-
-static void draw_putsxy_oriented(int x, int y, const char *str)
-{
- unsigned short ch;
- unsigned short *ucs;
- int ofs = MIN(x, 0);
- struct font* pf = rb->font_get(osd.font);
-
- ucs = rb->bidi_l2v(str, 1);
-
- x += osd.x;
- y += osd.y;
-
- while ((ch = *ucs++) != 0 && x < SCREEN_WIDTH)
- {
- int width;
- const unsigned char *bits;
-
- /* get proportional width and glyph bits */
- width = rb->font_get_width(pf, ch);
-
- if (ofs > width) {
- ofs -= width;
- continue;
- }
-
- bits = rb->font_get_bits(pf, ch);
-
- if (pf->depth)
- draw_oriented_alpha_bitmap_part(bits, ofs, 0, width, x, y,
- width - ofs, pf->height);
- else
- draw_oriented_mono_bitmap_part(bits, ofs, 0, width, x, y,
- width - ofs, pf->height);
-
- x += width - ofs;
- ofs = 0;
- }
-}
-#else
-static void draw_oriented_mono_bitmap_part(const unsigned char *src,
- int src_x, int src_y,
- int stride, int x, int y,
- int width, int height)
-{
- int mode = mylcd_get_drawmode();
- mylcd_set_drawmode(DRMODE_FG);
- mylcd_mono_bitmap_part(src, src_x, src_y, stride, x, y, width, height);
- mylcd_set_drawmode(mode);
-}
-
-static void draw_putsxy_oriented(int x, int y, const char *str)
-{
- int mode = mylcd_get_drawmode();
- mylcd_set_drawmode(DRMODE_FG);
- mylcd_putsxy(x + osd.x, y + osd.y, str);
- mylcd_set_drawmode(mode);
-}
-#endif /* LCD_PORTRAIT */
-
-/** FPS Display **/
-
-/* Post-frame callback (on video thread) - update the FPS rectangle from the
- * framebuffer */
-static void fps_post_frame_callback(void)
-{
- vo_lock();
- mylcd_update_rect(fps.pf_x, fps.pf_y,
- fps.pf_width, fps.pf_height);
- vo_unlock();
-}
-
-/* Set up to have the callback only update the intersection of the video
- * rectangle and the FPS text rectangle - if they don't intersect, then
- * the callback is set to NULL */
-static void fps_update_post_frame_callback(void)
-{
- void (*cb)(void) = NULL;
-
- if (settings.showfps) {
- struct vo_rect cliprect;
-
- if (stream_vo_get_clip(&cliprect)) {
- /* Oriented screen coordinates -> OSD coordinates */
- vo_rect_offset(&cliprect, -osd.x, -osd.y);
-
- if (vo_rect_intersect(&cliprect, &cliprect, &fps.rect)) {
- int x = cliprect.l;
- int y = cliprect.t;
- int width = cliprect.r - cliprect.l;
- int height = cliprect.b - cliprect.t;
-
- /* OSD coordinates -> framebuffer coordinates */
- fps.pf_x = __X;
- fps.pf_y = __Y;
- fps.pf_width = __W;
- fps.pf_height = __H;
-
- cb = fps_post_frame_callback;
- }
- }
- }
-
- stream_set_callback(VIDEO_SET_POST_FRAME_CALLBACK, cb);
-}
-
-/* Refresh the FPS display */
-static void fps_refresh(void)
-{
- char str[FPS_BUFSIZE];
- struct video_output_stats stats;
- int w, h, sw;
- long tick;
-
- tick = *rb->current_tick;
-
- if (TIME_BEFORE(tick, fps.update_tick))
- return;
-
- fps.update_tick = tick + FPS_UPDATE_INTERVAL;
-
- stream_video_stats(&stats);
-
- rb->snprintf(str, FPS_BUFSIZE, FPS_FORMAT,
- stats.fps / 100, stats.fps % 100);
-
- w = fps.rect.r - fps.rect.l;
- h = fps.rect.b - fps.rect.t;
-
- draw_clear_area(fps.rect.l, fps.rect.t, w, h);
- mylcd_getstringsize(str, &sw, NULL);
- draw_putsxy_oriented(fps.rect.r - sw, fps.rect.t, str);
-
- vo_lock();
- draw_update_rect(fps.rect.l, fps.rect.t, w, h);
- vo_unlock();
-}
-
-/* Initialize the FPS display */
-static void fps_init(void)
-{
- fps.update_tick = *rb->current_tick;
- fps.rect.l = fps.rect.t = 0;
- mylcd_getstringsize(FPS_DIMSTR, &fps.rect.r, &fps.rect.b);
- vo_rect_offset(&fps.rect, -osd.x, -osd.y);
- fps_update_post_frame_callback();
-}
-
-/** OSD **/
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-/* So we can refresh the overlay */
-static void osd_lcd_enable_hook(unsigned short id, void* param)
-{
- (void)id;
- (void)param;
- rb->queue_post(rb->button_queue, LCD_ENABLE_EVENT_1, 0);
-}
-#endif
-
-static void osdbacklight_hw_on_video_mode(bool video_on)
-{
- if (video_on) {
-#ifdef HAVE_BACKLIGHT
- /* Turn off backlight timeout */
- backlight_ignore_timeout();
-#endif
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- rb->remove_event(LCD_EVENT_ACTIVATION, osd_lcd_enable_hook);
-#endif
- } else {
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- rb->add_event(LCD_EVENT_ACTIVATION, osd_lcd_enable_hook);
-#endif
-#ifdef HAVE_BACKLIGHT
- /* Revert to user's backlight settings */
- backlight_use_settings();
-#endif
- }
-}
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-static void osd_backlight_brightness_video_mode(bool video_on)
-{
- if (settings.backlight_brightness < 0)
- return;
-
- mpeg_backlight_update_brightness(
- video_on ? settings.backlight_brightness : -1);
-}
-#else
-#define osd_backlight_brightness_video_mode(video_on)
-#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
-
-static void osd_text_init(void)
-{
- struct hms hms;
- char buf[32];
- int phys;
- int spc_width;
-
- draw_setfont(FONT_UI);
-
- osd.x = 0;
- osd.width = SCREEN_WIDTH;
-
- vo_rect_clear(&osd.time_rect);
- vo_rect_clear(&osd.stat_rect);
- vo_rect_clear(&osd.prog_rect);
- vo_rect_clear(&osd.vol_rect);
-
- ts_to_hms(stream_get_duration(), &hms);
- hms_format(buf, sizeof (buf), &hms);
- mylcd_getstringsize(buf, &osd.time_rect.r, &osd.time_rect.b);
-
- /* Choose well-sized bitmap images relative to font height */
- if (osd.time_rect.b < 12) {
- osd.icons = mpegplayer_status_icons_8x8x1;
- osd.stat_rect.r = osd.stat_rect.b = 8;
- } else if (osd.time_rect.b < 16) {
- osd.icons = mpegplayer_status_icons_12x12x1;
- osd.stat_rect.r = osd.stat_rect.b = 12;
- } else {
- osd.icons = mpegplayer_status_icons_16x16x1;
- osd.stat_rect.r = osd.stat_rect.b = 16;
- }
-
- if (osd.stat_rect.b < osd.time_rect.b) {
- vo_rect_offset(&osd.stat_rect, 0,
- (osd.time_rect.b - osd.stat_rect.b) / 2 + OSD_BDR_T);
- vo_rect_offset(&osd.time_rect, OSD_BDR_L, OSD_BDR_T);
- } else {
- vo_rect_offset(&osd.time_rect, OSD_BDR_L,
- osd.stat_rect.b - osd.time_rect.b + OSD_BDR_T);
- vo_rect_offset(&osd.stat_rect, 0, OSD_BDR_T);
- }
-
- osd.dur_rect = osd.time_rect;
-
- phys = rb->sound_val2phys(SOUND_VOLUME, rb->sound_min(SOUND_VOLUME));
- rb->snprintf(buf, sizeof(buf), "%d%s", phys,
- rb->sound_unit(SOUND_VOLUME));
-
- mylcd_getstringsize(" ", &spc_width, NULL);
- mylcd_getstringsize(buf, &osd.vol_rect.r, &osd.vol_rect.b);
-
- osd.prog_rect.r = SCREEN_WIDTH - OSD_BDR_L - spc_width -
- osd.vol_rect.r - OSD_BDR_R;
- osd.prog_rect.b = 3*osd.stat_rect.b / 4;
- vo_rect_offset(&osd.prog_rect, osd.time_rect.l,
- osd.time_rect.b);
-
- vo_rect_offset(&osd.stat_rect,
- (osd.prog_rect.r + osd.prog_rect.l - osd.stat_rect.r) / 2,
- 0);
-
- vo_rect_offset(&osd.dur_rect,
- osd.prog_rect.r - osd.dur_rect.r, 0);
-
- vo_rect_offset(&osd.vol_rect, osd.prog_rect.r + spc_width,
- (osd.prog_rect.b + osd.prog_rect.t - osd.vol_rect.b) / 2);
-
- osd.height = OSD_BDR_T + MAX(osd.prog_rect.b, osd.vol_rect.b) -
- MIN(osd.time_rect.t, osd.stat_rect.t) + OSD_BDR_B;
-
-#ifdef HAVE_LCD_COLOR
- osd.height = ALIGN_UP(osd.height, 2);
-#endif
- osd.y = SCREEN_HEIGHT - osd.height;
-
- draw_setfont(FONT_SYSFIXED);
-}
-
-static void osd_init(void)
-{
- osd.flags = 0;
- osd.show_for = HZ*4;
- osd.print_delay = 75*HZ/100;
- osd.resume_delay = HZ/2;
-#ifdef HAVE_LCD_COLOR
- osd.bgcolor = LCD_RGBPACK(0x73, 0x75, 0xbd);
- osd.fgcolor = LCD_WHITE;
- osd.prog_fillcolor = LCD_BLACK;
-#else
- osd.bgcolor = GREY_LIGHTGRAY;
- osd.fgcolor = GREY_BLACK;
- osd.prog_fillcolor = GREY_WHITE;
-#endif
- osd.curr_time = 0;
- osd.status = OSD_STATUS_STOPPED;
- osd.auto_refresh = OSD_REFRESH_TIME;
- osd.next_auto_refresh = *rb->current_tick;
- osd_text_init();
- fps_init();
-}
-
-#ifdef HAVE_HEADPHONE_DETECTION
-static void osd_set_hp_pause_flag(bool set)
-{
- if (set)
- osd.flags |= OSD_HP_PAUSE;
- else
- osd.flags &= ~OSD_HP_PAUSE;
-}
-#else
-#define osd_set_hp_pause_flag(set)
-#endif /* HAVE_HEADPHONE_DETECTION */
-
-static void osd_schedule_refresh(unsigned refresh)
-{
- long tick = *rb->current_tick;
-
- if (refresh & OSD_REFRESH_VIDEO)
- osd.print_tick = tick + osd.print_delay;
-
- if (refresh & OSD_REFRESH_RESUME)
- osd.resume_tick = tick + osd.resume_delay;
-
- osd.auto_refresh |= refresh;
-}
-
-static void osd_cancel_refresh(unsigned refresh)
-{
- osd.auto_refresh &= ~refresh;
-}
-
-/* Refresh the background area */
-static void osd_refresh_background(void)
-{
- char buf[32];
- struct hms hms;
-
- unsigned bg = mylcd_get_background();
- mylcd_set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
-
-#ifdef HAVE_LCD_COLOR
- /* Draw a "raised" area for our graphics */
- mylcd_set_background(draw_blendcolor(bg, MYLCD_WHITE, 192));
- draw_hline(0, osd.width, 0);
-
- mylcd_set_background(draw_blendcolor(bg, MYLCD_WHITE, 80));
- draw_hline(0, osd.width, 1);
-
- mylcd_set_background(draw_blendcolor(bg, MYLCD_BLACK, 48));
- draw_hline(0, osd.width, osd.height-2);
-
- mylcd_set_background(draw_blendcolor(bg, MYLCD_BLACK, 128));
- draw_hline(0, osd.width, osd.height-1);
-
- mylcd_set_background(bg);
- draw_clear_area(0, 2, osd.width, osd.height - 4);
-#else
- /* Give contrast with the main background */
- mylcd_set_background(MYLCD_WHITE);
- draw_hline(0, osd.width, 0);
-
- mylcd_set_background(MYLCD_DARKGRAY);
- draw_hline(0, osd.width, osd.height-1);
-
- mylcd_set_background(bg);
- draw_clear_area(0, 1, osd.width, osd.height - 2);
-#endif
-
- vo_rect_set_ext(&osd.update_rect, 0, 0, osd.width, osd.height);
- mylcd_set_drawmode(DRMODE_SOLID);
-
- if (stream_get_duration() != INVALID_TIMESTAMP) {
- /* Draw the movie duration */
- ts_to_hms(stream_get_duration(), &hms);
- hms_format(buf, sizeof (buf), &hms);
- draw_putsxy_oriented(osd.dur_rect.l, osd.dur_rect.t, buf);
- }
- /* else don't know the duration */
-}
-
-/* Refresh the current time display + the progress bar */
-static void osd_refresh_time(void)
-{
- char buf[32];
- struct hms hms;
-
- uint32_t duration = stream_get_duration();
-
- draw_scrollbar_draw_rect(&osd.prog_rect, 0, duration,
- osd.curr_time);
-
- ts_to_hms(osd.curr_time, &hms);
- hms_format(buf, sizeof (buf), &hms);
-
- draw_clear_area_rect(&osd.time_rect);
- draw_putsxy_oriented(osd.time_rect.l, osd.time_rect.t, buf);
-
- vo_rect_union(&osd.update_rect, &osd.update_rect,
- &osd.prog_rect);
- vo_rect_union(&osd.update_rect, &osd.update_rect,
- &osd.time_rect);
-}
-
-/* Refresh the volume display area */
-static void osd_refresh_volume(void)
-{
- char buf[32];
- int width;
-
- int volume = rb->global_settings->volume;
- rb->snprintf(buf, sizeof (buf), "%d%s",
- rb->sound_val2phys(SOUND_VOLUME, volume),
- rb->sound_unit(SOUND_VOLUME));
- mylcd_getstringsize(buf, &width, NULL);
-
- /* Right-justified */
- draw_clear_area_rect(&osd.vol_rect);
- draw_putsxy_oriented(osd.vol_rect.r - width, osd.vol_rect.t, buf);
-
- vo_rect_union(&osd.update_rect, &osd.update_rect, &osd.vol_rect);
-}
-
-/* Refresh the status icon */
-static void osd_refresh_status(void)
-{
- int icon_size = osd.stat_rect.r - osd.stat_rect.l;
-
- draw_clear_area_rect(&osd.stat_rect);
-
-#ifdef HAVE_LCD_COLOR
- /* Draw status icon with a drop shadow */
- unsigned oldfg = mylcd_get_foreground();
- int i = 1;
-
- mylcd_set_foreground(draw_blendcolor(mylcd_get_background(),
- MYLCD_BLACK, 96));
-
- while (1)
- {
- draw_oriented_mono_bitmap_part(osd.icons,
- icon_size*osd.status,
- 0,
- icon_size*OSD_STATUS_COUNT,
- osd.stat_rect.l + osd.x + i,
- osd.stat_rect.t + osd.y + i,
- icon_size, icon_size);
-
- if (--i < 0)
- break;
-
- mylcd_set_foreground(oldfg);
- }
-
- vo_rect_union(&osd.update_rect, &osd.update_rect, &osd.stat_rect);
-#else
- draw_oriented_mono_bitmap_part(osd.icons,
- icon_size*osd.status,
- 0,
- icon_size*OSD_STATUS_COUNT,
- osd.stat_rect.l + osd.x,
- osd.stat_rect.t + osd.y,
- icon_size, icon_size);
- vo_rect_union(&osd.update_rect, &osd.update_rect, &osd.stat_rect);
-#endif
-}
-
-/* Update the current status which determines which icon is displayed */
-static bool osd_update_status(void)
-{
- int status;
-
- switch (stream_status())
- {
- default:
- status = OSD_STATUS_STOPPED;
- break;
- case STREAM_PAUSED:
- /* If paused with a pending resume, coerce it to OSD_STATUS_PLAYING */
- status = (osd.auto_refresh & OSD_REFRESH_RESUME) ?
- OSD_STATUS_PLAYING : OSD_STATUS_PAUSED;
- break;
- case STREAM_PLAYING:
- status = OSD_STATUS_PLAYING;
- break;
- }
-
- if (status != osd.status) {
- /* A refresh is needed */
- osd.status = status;
- return true;
- }
-
- return false;
-}
-
-/* Update the current time that will be displayed */
-static void osd_update_time(void)
-{
- uint32_t start;
- osd.curr_time = stream_get_seek_time(&start);
- osd.curr_time -= start;
-}
-
-/* Refresh various parts of the OSD - showing it if it is hidden */
-static void osd_refresh(int hint)
-{
- long tick;
- unsigned oldbg, oldfg;
-
- tick = *rb->current_tick;
-
- if (settings.showfps)
- fps_refresh();
-
- if (hint == OSD_REFRESH_DEFAULT) {
- /* The default which forces no updates */
-
- /* Make sure Rockbox doesn't turn off the player because of
- too little activity */
- if (osd.status == OSD_STATUS_PLAYING)
- rb->reset_poweroff_timer();
-
- /* Redraw the current or possibly extract a new video frame */
- if ((osd.auto_refresh & OSD_REFRESH_VIDEO) &&
- TIME_AFTER(tick, osd.print_tick)) {
- osd.auto_refresh &= ~OSD_REFRESH_VIDEO;
- stream_draw_frame(false);
- }
-
- /* Restart playback if the timout was reached */
- if ((osd.auto_refresh & OSD_REFRESH_RESUME) &&
- TIME_AFTER(tick, osd.resume_tick)) {
- osd.auto_refresh &= ~(OSD_REFRESH_RESUME | OSD_REFRESH_VIDEO);
- stream_resume();
- }
-
- /* If not visible, return */
- if (!(osd.flags & OSD_SHOW))
- return;
-
- /* Hide if the visibility duration was reached */
- if (TIME_AFTER(tick, osd.hide_tick)) {
- osd_show(OSD_HIDE);
- return;
- }
- } else {
- /* A forced update of some region */
-
- /* Show if currently invisible */
- if (!(osd.flags & OSD_SHOW)) {
- /* Avoid call back into this function - it will be drawn */
- osd_show(OSD_SHOW | OSD_NODRAW);
- hint = OSD_REFRESH_ALL;
- }
-
- /* Move back timeouts for frame print and hide */
- osd.print_tick = tick + osd.print_delay;
- osd.hide_tick = tick + osd.show_for;
- }
-
- if (TIME_AFTER(tick, osd.next_auto_refresh)) {
- /* Refresh whatever graphical elements are due automatically */
- osd.next_auto_refresh = tick + OSD_MIN_UPDATE_INTERVAL;
-
- if (osd.auto_refresh & OSD_REFRESH_STATUS) {
- if (osd_update_status())
- hint |= OSD_REFRESH_STATUS;
- }
-
- if (osd.auto_refresh & OSD_REFRESH_TIME) {
- osd_update_time();
- hint |= OSD_REFRESH_TIME;
- }
- }
-
- if (hint == 0)
- return; /* No drawing needed */
-
- /* Set basic drawing params that are used. Elements that perform variations
- * will restore them. */
- oldfg = mylcd_get_foreground();
- oldbg = mylcd_get_background();
-
- draw_setfont(FONT_UI);
- mylcd_set_foreground(osd.fgcolor);
- mylcd_set_background(osd.bgcolor);
-
- vo_rect_clear(&osd.update_rect);
-
- if (hint & OSD_REFRESH_BACKGROUND) {
- osd_refresh_background();
- hint |= OSD_REFRESH_ALL; /* Requires a redraw of everything */
- }
-
- if (hint & OSD_REFRESH_TIME) {
- osd_refresh_time();
- }
-
- if (hint & OSD_REFRESH_VOLUME) {
- osd_refresh_volume();
- }
-
- if (hint & OSD_REFRESH_STATUS) {
- osd_refresh_status();
- }
-
- /* Go back to defaults */
- draw_setfont(FONT_SYSFIXED);
- mylcd_set_foreground(oldfg);
- mylcd_set_background(oldbg);
-
- /* Update the dirty rectangle */
- vo_lock();
-
- draw_update_rect(osd.update_rect.l,
- osd.update_rect.t,
- osd.update_rect.r - osd.update_rect.l,
- osd.update_rect.b - osd.update_rect.t);
-
- vo_unlock();
-}
-
-/* Show/Hide the OSD */
-static void osd_show(unsigned show)
-{
- if (((show ^ osd.flags) & OSD_SHOW) == 0)
- {
- if (show & OSD_SHOW) {
- osd.hide_tick = *rb->current_tick + osd.show_for;
- }
- return;
- }
-
- if (show & OSD_SHOW) {
- /* Clip away the part of video that is covered */
- struct vo_rect rc = { 0, 0, SCREEN_WIDTH, osd.y };
-
- osd.flags |= OSD_SHOW;
-
- if (osd.status != OSD_STATUS_PLAYING) {
- /* Not playing - set brightness to mpegplayer setting */
- osd_backlight_brightness_video_mode(true);
- }
-
- stream_vo_set_clip(&rc);
-
- if (!(show & OSD_NODRAW))
- osd_refresh(OSD_REFRESH_ALL);
- } else {
- /* Uncover clipped video area and redraw it */
- osd.flags &= ~OSD_SHOW;
-
- draw_clear_area(0, 0, osd.width, osd.height);
-
- if (!(show & OSD_NODRAW)) {
- vo_lock();
- draw_update_rect(0, 0, osd.width, osd.height);
- vo_unlock();
-
- stream_vo_set_clip(NULL);
- stream_draw_frame(false);
- } else {
- stream_vo_set_clip(NULL);
- }
-
- if (osd.status != OSD_STATUS_PLAYING) {
- /* Not playing - restore backlight brightness */
- osd_backlight_brightness_video_mode(false);
- }
- }
-}
-
-/* Set the current status - update screen if specified */
-static void osd_set_status(int status)
-{
- bool draw = (status & OSD_NODRAW) == 0;
-
- status &= OSD_STATUS_MASK;
-
- if (osd.status != status) {
-
- osd.status = status;
-
- if (draw)
- osd_refresh(OSD_REFRESH_STATUS);
- }
-}
-
-/* Get the current status value */
-static int osd_get_status(void)
-{
- return osd.status & OSD_STATUS_MASK;
-}
-
-/* Handle Fast-forward/Rewind keys using WPS settings (and some nicked code ;)
- * Returns last button code
- */
-static int osd_ff_rw(int btn, unsigned refresh, uint32_t *new_time)
-{
- unsigned int step = TS_SECOND*rb->global_settings->ff_rewind_min_step;
- const long ff_rw_accel = (rb->global_settings->ff_rewind_accel + 3);
- uint32_t start;
- uint32_t time = stream_get_seek_time(&start);
- const uint32_t duration = stream_get_duration();
- unsigned int max_step = 0;
- uint32_t ff_rw_count = 0;
- unsigned status = osd.status;
- int new_btn;
-
- osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME |
- OSD_REFRESH_TIME);
-
- time -= start; /* Absolute clock => stream-relative */
-
- switch (btn)
- {
- case MPEG_FF:
-#ifdef MPEG_FF2
- case MPEG_FF2:
-#endif
-#ifdef MPEG_RC_FF
- case MPEG_RC_FF:
-#endif
- osd_set_status(OSD_STATUS_FF);
- new_btn = btn | BUTTON_REPEAT; /* simplify code below */
- break;
- case MPEG_RW:
-#ifdef MPEG_RW2
- case MPEG_RW2:
-#endif
-#ifdef MPEG_RC_RW
- case MPEG_RC_RW:
-#endif
- osd_set_status(OSD_STATUS_RW);
- new_btn = btn | BUTTON_REPEAT; /* simplify code below */
- break;
- default:
- new_btn = BUTTON_NONE; /* Fail tests below but still do proper exit */
- }
-
- while (1)
- {
- stream_keep_disk_active();
-
- if (new_btn == (btn | BUTTON_REPEAT)) {
- if (osd.status == OSD_STATUS_FF) {
- /* fast forwarding, calc max step relative to end */
- max_step = muldiv_uint32(duration - (time + ff_rw_count),
- FF_REWIND_MAX_PERCENT, 100);
- } else {
- /* rewinding, calc max step relative to start */
- max_step = muldiv_uint32(time - ff_rw_count,
- FF_REWIND_MAX_PERCENT, 100);
- }
-
- max_step = MAX(max_step, MIN_FF_REWIND_STEP);
-
- if (step > max_step)
- step = max_step;
-
- ff_rw_count += step;
-
- /* smooth seeking by multiplying step by: 1 + (2 ^ -accel) */
- step += step >> ff_rw_accel;
-
- if (osd.status == OSD_STATUS_FF) {
- if (duration - time <= ff_rw_count)
- ff_rw_count = duration - time;
-
- osd.curr_time = time + ff_rw_count;
- } else {
- if (time <= ff_rw_count)
- ff_rw_count = time;
-
- osd.curr_time = time - ff_rw_count;
- }
-
- osd_refresh(OSD_REFRESH_TIME);
-
- new_btn = mpeg_button_get(TIMEOUT_BLOCK);
- }
- else {
- if (new_btn == (btn | BUTTON_REL)) {
- if (osd.status == OSD_STATUS_FF)
- time += ff_rw_count;
- else if (osd.status == OSD_STATUS_RW)
- time -= ff_rw_count;
- }
-
- *new_time = time;
-
- osd_schedule_refresh(refresh);
- osd_set_status(status);
- osd_schedule_refresh(OSD_REFRESH_TIME);
-
- return new_btn;
- }
- }
-}
-
-/* Return adjusted STREAM_* status */
-static int osd_stream_status(void)
-{
- int status = stream_status();
-
- /* Coerce to STREAM_PLAYING if paused with a pending resume */
- if (status == STREAM_PAUSED) {
- if (osd.auto_refresh & OSD_REFRESH_RESUME)
- status = STREAM_PLAYING;
- }
-
- return status;
-}
-
-/* Change the current audio volume by a specified amount */
-static void osd_set_volume(int delta)
-{
- int vol = rb->global_settings->volume;
- int limit;
-
- vol += delta;
-
- if (delta < 0) {
- /* Volume down - clip to lower limit */
- limit = rb->sound_min(SOUND_VOLUME);
- if (vol < limit)
- vol = limit;
- } else {
- /* Volume up - clip to upper limit */
- limit = rb->sound_max(SOUND_VOLUME);
- if (vol > limit)
- vol = limit;
- }
-
- /* Sync the global settings */
- if (vol != rb->global_settings->volume) {
- rb->sound_set(SOUND_VOLUME, vol);
- rb->global_settings->volume = vol;
- }
-
- /* Update the volume display */
- osd_refresh(OSD_REFRESH_VOLUME);
-}
-
-/* Begin playback at the specified time */
-static int osd_play(uint32_t time)
-{
- int retval;
-
- osd_set_hp_pause_flag(false);
- osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME);
-
- retval = stream_seek(time, SEEK_SET);
-
- if (retval >= STREAM_OK) {
- osdbacklight_hw_on_video_mode(true);
- osd_backlight_brightness_video_mode(true);
- stream_show_vo(true);
-
- retval = stream_play();
-
- if (retval >= STREAM_OK)
- osd_set_status(OSD_STATUS_PLAYING | OSD_NODRAW);
- }
-
- return retval;
-}
-
-/* Halt playback - pause engine and return logical state */
-static int osd_halt(void)
-{
- int status = stream_pause();
-
- /* Coerce to STREAM_PLAYING if paused with a pending resume */
- if (status == STREAM_PAUSED) {
- if (osd_get_status() == OSD_STATUS_PLAYING)
- status = STREAM_PLAYING;
- }
-
- /* Cancel some auto refreshes - caller will restart them if desired */
- osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME);
-
- /* No backlight fiddling here - callers does the right thing */
-
- return status;
-}
-
-/* Pause playback if playing */
-static int osd_pause(void)
-{
- unsigned refresh = osd.auto_refresh;
- int status = osd_halt();
-
- osd_set_hp_pause_flag(false);
-
- if (status == STREAM_PLAYING && (refresh & OSD_REFRESH_RESUME)) {
- /* Resume pending - change to a still video frame update */
- osd_schedule_refresh(OSD_REFRESH_VIDEO);
- }
-
- osd_set_status(OSD_STATUS_PAUSED);
-
- osdbacklight_hw_on_video_mode(false);
- /* Leave brightness alone and restore it when OSD is hidden */
-
- if (stream_can_seek() && rb->global_settings->pause_rewind) {
- stream_seek(-rb->global_settings->pause_rewind*TS_SECOND,
- SEEK_CUR);
- osd_schedule_refresh(OSD_REFRESH_VIDEO);
- /* Update time display now */
- osd_update_time();
- osd_refresh(OSD_REFRESH_TIME);
- }
-
- return status;
-}
-
-/* Resume playback if halted or paused */
-static void osd_resume(void)
-{
- /* Cancel video and resume auto refresh - the resyc when starting
- * playback will perform those tasks */
- osd_set_hp_pause_flag(false);
- osdbacklight_hw_on_video_mode(true);
- osd_backlight_brightness_video_mode(true);
- osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME);
- osd_set_status(OSD_STATUS_PLAYING);
- stream_resume();
-}
-
-/* Stop playback - remember the resume point if not closed */
-static void osd_stop(void)
-{
- uint32_t resume_time;
-
- osd_set_hp_pause_flag(false);
- osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME);
- osd_set_status(OSD_STATUS_STOPPED | OSD_NODRAW);
- osd_show(OSD_HIDE);
-
- stream_stop();
-
- resume_time = stream_get_resume_time();
-
- if (resume_time != INVALID_TIMESTAMP)
- settings.resume_time = resume_time;
-
- osdbacklight_hw_on_video_mode(false);
- osd_backlight_brightness_video_mode(false);
-}
-
-/* Perform a seek by button if seeking is possible for this stream.
- *
- * A delay will be inserted before restarting in case the user decides to
- * seek again soon after.
- *
- * Returns last button code
- */
-static int osd_seek_btn(int btn)
-{
- int status;
- unsigned refresh = 0;
- uint32_t time;
-
- if (!stream_can_seek())
- return true;
-
- /* Halt playback - not strictly necessary but nice when doing
- * buttons */
- status = osd_halt();
-
- if (status == STREAM_STOPPED)
- return true;
-
- osd_show(OSD_SHOW);
-
- /* Obtain a new playback point according to the buttons */
- if (status == STREAM_PLAYING)
- refresh = OSD_REFRESH_RESUME; /* delay resume if playing */
- else
- refresh = OSD_REFRESH_VIDEO; /* refresh if paused */
-
- btn = osd_ff_rw(btn, refresh, &time);
-
- /* Tell engine to resume at that time */
- stream_seek(time, SEEK_SET);
-
- return btn;
-}
-
-/* Perform a seek by time if seeking is possible for this stream
- *
- * If playing, the seeking is immediate, otherise a delay is added to showing
- * a still if paused in case the user does another seek soon after.
- *
- * If seeking isn't possible, a time of zero performs a skip to the
- * beginning.
- */
-static void osd_seek_time(uint32_t time)
-{
- int status;
- unsigned refresh = 0;
-
- if (!stream_can_seek() && time != 0)
- return;
-
- stream_wait_status();
- status = osd_stream_status();
-
- if (status == STREAM_STOPPED)
- return;
-
- if (status == STREAM_PLAYING) /* merely preserve resume */
- refresh = osd.auto_refresh & OSD_REFRESH_RESUME;
- else
- refresh = OSD_REFRESH_VIDEO; /* refresh if paused */
-
- /* Cancel print or resume if pending */
- osd_cancel_refresh(OSD_REFRESH_VIDEO | OSD_REFRESH_RESUME);
-
- /* Tell engine to seek to the given time - no state change */
- stream_seek(time, SEEK_SET);
-
- osd_update_time();
- osd_refresh(OSD_REFRESH_TIME);
- osd_schedule_refresh(refresh);
-}
-
-/* Has this file one of the supported extensions? */
-static bool is_videofile(const char* file)
-{
- static const char * const extensions[] =
- {
- /* Should match apps/plugins/viewers.config */
- "mpg", "mpeg", "mpv", "m2v"
- };
-
- const char* ext = rb->strrchr(file, '.');
- int i;
-
- if (!ext)
- return false;
-
- for (i = ARRAYLEN(extensions) - 1; i >= 0; i--)
- {
- if (!rb->strcasecmp(ext + 1, extensions[i]))
- break;
- }
-
- return i >= 0;
-}
-
-/* deliver the next/previous video file in the current directory.
- returns false if there is none. */
-static bool get_videofile(int direction, char* videofile, size_t bufsize)
-{
- struct tree_context *tree = rb->tree_get_context();
- struct entry *dircache = rb->tree_get_entries(tree);
- int i, step, end, found = 0;
- char *videoname = rb->strrchr(videofile, '/') + 1;
- size_t rest = bufsize - (videoname - videofile) - 1;
-
- if (direction == VIDEO_NEXT) {
- i = 0;
- step = 1;
- end = tree->filesindir;
- } else {
- i = tree->filesindir-1;
- step = -1;
- end = -1;
- }
- for (; i != end; i += step)
- {
- const char* name = dircache[i].name;
- if (!rb->strcmp(name, videoname)) {
- found = 1;
- continue;
- }
- if (found && rb->strlen(name) <= rest &&
- !(dircache[i].attr & ATTR_DIRECTORY) && is_videofile(name))
- {
- rb->strcpy(videoname, name);
- return true;
- }
- }
-
- return false;
-}
-
-#ifdef HAVE_HEADPHONE_DETECTION
-/* Handle SYS_PHONE_PLUGGED/UNPLUGGED */
-static void osd_handle_phone_plug(bool inserted)
-{
- if (rb->global_settings->unplug_mode == 0)
- return;
-
- /* Wait for any incomplete state transition to complete first */
- stream_wait_status();
-
- int status = osd_stream_status();
-
- if (inserted) {
- if (rb->global_settings->unplug_mode > 1) {
- if (status == STREAM_PAUSED &&
- (osd.flags & OSD_HP_PAUSE)) {
- osd_resume();
- }
- }
- } else {
- if (status == STREAM_PLAYING) {
- osd_pause();
-
- osd_set_hp_pause_flag(true);
- }
- }
-}
-#endif
-
-static int button_loop(void)
-{
- int next_action = (settings.play_mode == 0) ? VIDEO_STOP : VIDEO_NEXT;
-
- rb->lcd_setfont(FONT_SYSFIXED);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_BLACK);
-#endif
- rb->lcd_clear_display();
- rb->lcd_update();
-
-#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_YUV)
- rb->lcd_set_mode(LCD_MODE_YUV);
-#endif
-
- osd_init();
-
- /* Start playback at the specified starting time */
- if (osd_play(settings.resume_time) < STREAM_OK) {
- rb->splash(HZ*2, "Playback failed");
- return VIDEO_STOP;
- }
-
- /* Gently poll the video player for EOS and handle UI */
- while (stream_status() != STREAM_STOPPED)
- {
- int button = mpeg_button_get(OSD_MIN_UPDATE_INTERVAL/2);
-
- switch (button)
- {
- case BUTTON_NONE:
- {
- osd_refresh(OSD_REFRESH_DEFAULT);
- continue;
- } /* BUTTON_NONE: */
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- case LCD_ENABLE_EVENT_1:
- {
- /* Draw the current frame if prepared already */
- stream_draw_frame(true);
- break;
- } /* LCD_ENABLE_EVENT_1: */
-#endif
-
- case MPEG_VOLUP:
- case MPEG_VOLUP|BUTTON_REPEAT:
-#ifdef MPEG_VOLUP2
- case MPEG_VOLUP2:
- case MPEG_VOLUP2|BUTTON_REPEAT:
-#endif
-#ifdef MPEG_RC_VOLUP
- case MPEG_RC_VOLUP:
- case MPEG_RC_VOLUP|BUTTON_REPEAT:
-#endif
- {
- osd_set_volume(+1);
- break;
- } /* MPEG_VOLUP*: */
-
- case MPEG_VOLDOWN:
- case MPEG_VOLDOWN|BUTTON_REPEAT:
-#ifdef MPEG_VOLDOWN2
- case MPEG_VOLDOWN2:
- case MPEG_VOLDOWN2|BUTTON_REPEAT:
-#endif
-#ifdef MPEG_RC_VOLDOWN
- case MPEG_RC_VOLDOWN:
- case MPEG_RC_VOLDOWN|BUTTON_REPEAT:
-#endif
- {
- osd_set_volume(-1);
- break;
- } /* MPEG_VOLDOWN*: */
-
- case MPEG_MENU:
-#ifdef MPEG_RC_MENU
- case MPEG_RC_MENU:
-#endif
- {
- int state = osd_halt(); /* save previous state */
- int result;
-
- /* Hide video output */
- osd_show(OSD_HIDE | OSD_NODRAW);
- stream_show_vo(false);
- osd_backlight_brightness_video_mode(false);
-
-#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_YUV)
- rb->lcd_set_mode(LCD_MODE_RGB565);
-#endif
-
- result = mpeg_menu();
-
- next_action = (settings.play_mode == 0) ? VIDEO_STOP : VIDEO_NEXT;
-
- fps_update_post_frame_callback();
-
- /* The menu can change the font, so restore */
- rb->lcd_setfont(FONT_SYSFIXED);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_BLACK);
-#endif
- rb->lcd_clear_display();
- rb->lcd_update();
-
- switch (result)
- {
- case MPEG_MENU_QUIT:
- next_action = VIDEO_STOP;
- osd_stop();
- break;
-
- default:
-#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_YUV)
- rb->lcd_set_mode(LCD_MODE_YUV);
-#endif
- /* If not stopped, show video again */
- if (state != STREAM_STOPPED) {
- osd_show(OSD_SHOW);
- stream_show_vo(true);
- }
-
- /* If stream was playing, restart it */
- if (state == STREAM_PLAYING) {
- osd_resume();
- }
- break;
- }
- break;
- } /* MPEG_MENU: */
-
-#ifdef MPEG_SHOW_OSD
- case MPEG_SHOW_OSD:
- case MPEG_SHOW_OSD | BUTTON_REPEAT:
- /* Show if not visible */
- osd_show(OSD_SHOW);
- /* Make sure it refreshes */
- osd_refresh(OSD_REFRESH_DEFAULT);
- break;
-#endif
-
- case MPEG_STOP:
-#ifdef MPEG_RC_STOP
- case MPEG_RC_STOP:
-#endif
- case ACTION_STD_CANCEL:
- {
- cancel_playback:
- next_action = VIDEO_STOP;
- osd_stop();
- break;
- } /* MPEG_STOP: */
-
- case MPEG_PAUSE:
-#ifdef MPEG_PAUSE2
- case MPEG_PAUSE2:
-#endif
-#ifdef MPEG_RC_PAUSE
- case MPEG_RC_PAUSE:
-#endif
- {
- int status = osd_stream_status();
-
- if (status == STREAM_PLAYING) {
- /* Playing => Paused */
- osd_pause();
- }
- else if (status == STREAM_PAUSED) {
- /* Paused => Playing */
- osd_resume();
- }
-
- break;
- } /* MPEG_PAUSE*: */
-
- case MPEG_RW:
-#ifdef MPEG_RW2
- case MPEG_RW2:
-#endif
-#ifdef MPEG_RC_RW
- case MPEG_RC_RW:
-#endif
- {
- int old_button = button;
-
- /* If button has been released: skip to next/previous file */
- button = mpeg_button_get(OSD_MIN_UPDATE_INTERVAL);
-
- if ((old_button | BUTTON_REL) == button) {
- /* Check current playback position */
- osd_update_time();
-
- if (settings.play_mode == 0 || osd.curr_time >= 3*TS_SECOND) {
- /* Start the current video from the beginning */
- osd_seek_time(0*TS_SECOND);
- }
- else {
- /* Release within 3 seconds of start: skip to previous
- * file */
- osd_stop();
- next_action = VIDEO_PREV | VIDEO_ACTION_MANUAL;
- }
- }
- else if ((button & ~BUTTON_REPEAT) == old_button) {
- button = osd_seek_btn(old_button);
- }
-
- if (button == ACTION_STD_CANCEL)
- goto cancel_playback; /* jump to stop handling above */
-
- rb->default_event_handler(button);
- break;
- } /* MPEG_RW: */
-
- case MPEG_FF:
-#ifdef MPEG_FF2
- case MPEG_FF2:
-#endif
-#ifdef MPEG_RC_FF
- case MPEG_RC_FF:
-#endif
- {
- int old_button = button;
-
- if (settings.play_mode != 0)
- button = mpeg_button_get(OSD_MIN_UPDATE_INTERVAL);
-
- if ((old_button | BUTTON_REL) == button) {
- /* If button has been released: skip to next file */
- osd_stop();
- next_action = VIDEO_NEXT | VIDEO_ACTION_MANUAL;
- }
- else if ((button & ~BUTTON_REPEAT) == old_button) {
- button = osd_seek_btn(old_button);
- }
-
- if (button == ACTION_STD_CANCEL)
- goto cancel_playback; /* jump to stop handling above */
-
- rb->default_event_handler(button);
- break;
- } /* MPEG_FF: */
-
-#ifdef HAVE_HEADPHONE_DETECTION
- case SYS_PHONE_PLUGGED:
- case SYS_PHONE_UNPLUGGED:
- {
- osd_handle_phone_plug(button == SYS_PHONE_PLUGGED);
- break;
- } /* SYS_PHONE_*: */
-#endif
-
- default:
- {
- osd_refresh(OSD_REFRESH_DEFAULT);
- rb->default_event_handler(button);
- break;
- } /* default: */
- }
-
- rb->yield();
- } /* end while */
-
- osd_stop();
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- /* Be sure hook is removed before exiting since the stop will put it
- * back because of the backlight restore. */
- rb->remove_event(LCD_EVENT_ACTIVATION, osd_lcd_enable_hook);
-#endif
-
- rb->lcd_setfont(FONT_UI);
-
- return next_action;
-}
-
-enum plugin_status plugin_start(const void* parameter)
-{
- static char videofile[MAX_PATH];
- int status = PLUGIN_OK; /* assume success */
- bool quit = false;
-
-#if defined(PLUGIN_USE_IRAM) && !defined(SIMULATOR)
- bool preserved_talk_state;
-#endif
-
- if (parameter == NULL) {
- /* No file = GTFO */
- rb->splash(HZ*2, "No File");
- return PLUGIN_ERROR;
- }
-
- /* Disable all talking before initializing IRAM */
- rb->talk_disable(true);
-
-#ifdef PLUGIN_USE_IRAM
- iram_saving_init();
-
-#ifndef SIMULATOR
- preserved_talk_state = rb->global_settings->talk_menu;
- if (!iram_saved_copy)
- rb->global_settings->talk_menu = false;
-#endif
-#endif
-
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_backdrop(NULL);
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_BLACK);
-#endif
-
- rb->lcd_clear_display();
- rb->lcd_update();
-
- rb->strcpy(videofile, (const char*) parameter);
-
- if (stream_init() < STREAM_OK) {
- /* Fatal because this should not fail */
- DEBUGF("Could not initialize streams\n");
- status = PLUGIN_ERROR;
- } else {
- int next_action = VIDEO_STOP;
- bool get_videofile_says = true;
-
- while (!quit)
- {
- init_settings(videofile);
-
- int result = stream_open(videofile);
- bool manual_skip = false;
-
- if (result >= STREAM_OK) {
- /* start menu */
- rb->lcd_clear_display();
- rb->lcd_update();
- result = mpeg_start_menu(stream_get_duration());
-
- next_action = VIDEO_STOP;
- if (result != MPEG_START_QUIT) {
- /* Enter button loop and process UI */
- next_action = button_loop();
- manual_skip = next_action & VIDEO_ACTION_MANUAL;
- next_action &= ~VIDEO_ACTION_MANUAL;
- }
-
- stream_close();
-
- rb->lcd_clear_display();
- rb->lcd_update();
-
- save_settings();
- } else {
- /* Problem with file; display message about it - not
- * considered a plugin error */
- long tick;
- const char *errstring;
-
- DEBUGF("Could not open %s\n", videofile);
- switch (result)
- {
- case STREAM_UNSUPPORTED:
- errstring = "Unsupported format";
- break;
- default:
- errstring = "Error opening file: %d";
- }
-
- tick = *rb->current_tick + HZ*2;
-
- rb->splashf(0, errstring, result);
-
- /* Be sure it doesn't get stuck in an unbreakable loop of bad
- * files, just in case! Otherwise, keep searching in the
- * chosen direction until a good one is found. */
- while (!quit && TIME_BEFORE(*rb->current_tick, tick))
- {
- int button = mpeg_button_get(HZ*2);
-
- switch (button)
- {
- case MPEG_STOP:
- case ACTION_STD_CANCEL:
- /* Abort the search and exit */
- next_action = VIDEO_STOP;
- quit = true;
- break;
-
- case BUTTON_NONE:
- if (settings.play_mode != 0) {
- if (next_action == VIDEO_STOP) {
- /* Default to next file */
- next_action = VIDEO_NEXT;
- }
- else if (next_action == VIDEO_PREV &&
- !get_videofile_says) {
- /* Was first file already; avoid endlessly
- * retrying it */
- next_action = VIDEO_STOP;
- }
- }
- break;
-
- default:
- rb->default_event_handler(button);
- } /* switch */
- } /* while */
- }
-
- /* return value of button_loop says, what's next */
- switch (next_action)
- {
- case VIDEO_NEXT:
- {
- get_videofile_says = get_videofile(VIDEO_NEXT, videofile,
- sizeof(videofile));
- /* quit after finished the last videofile */
- quit = !get_videofile_says;
-
- if (manual_skip)
- {
- rb->system_sound_play(get_videofile_says ?
- SOUND_TRACK_SKIP : SOUND_TRACK_NO_MORE);
- }
-
- break;
- }
- case VIDEO_PREV:
- {
- get_videofile_says = get_videofile(VIDEO_PREV, videofile,
- sizeof(videofile));
- /* if there is no previous file, play the same videofile */
-
- if (manual_skip)
- {
- rb->system_sound_play(get_videofile_says ?
- SOUND_TRACK_SKIP : SOUND_TRACK_NO_MORE);
- }
-
- break;
- }
- case VIDEO_STOP:
- {
- quit = true;
- break;
- }
- }
- } /* while */
- }
-
-#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_YUV)
- rb->lcd_set_mode(LCD_MODE_RGB565);
-#endif
-
- stream_exit();
-
-#if defined(PLUGIN_USE_IRAM) && !defined(SIMULATOR)
- if (!iram_saved_copy)
- rb->global_settings->talk_menu = preserved_talk_state;
-#endif
-
- rb->talk_disable(false);
-
- /* Actually handle delayed processing of system events of interest
- * that were captured in other button loops */
- mpeg_sysevent_handle();
-
- return status;
-}
diff --git a/apps/plugins/mpegplayer/mpegplayer.h b/apps/plugins/mpegplayer/mpegplayer.h
deleted file mode 100644
index 51fb9a8f8a..0000000000
--- a/apps/plugins/mpegplayer/mpegplayer.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Main mpegplayer config header.
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef MPEGPLAYER_H
-#define MPEGPLAYER_H
-
-#ifdef HAVE_SCHEDULER_BOOSTCTRL
-#define trigger_cpu_boost rb->trigger_cpu_boost
-#define cancel_cpu_boost rb->cancel_cpu_boost
-#endif
-/* #else function-like empty macros are defined in the headers */
-
-/* Should be enough for now */
-#define MPEGPLAYER_MAX_STREAMS 4
-
-/* Memory allotments for various subsystems */
-#define MIN_MEMMARGIN (4*1024)
-
-/** Video thread **/
-#define LIBMPEG2_ALLOC_SIZE (2*1024*1024)
-
-/** MPEG audio buffer **/
-#define AUDIOBUF_GUARD_SIZE (MPA_MAX_FRAME_SIZE + 2*MAD_BUFFER_GUARD)
-#define AUDIOBUF_SIZE (64*1024)
-#define AUDIOBUF_ALLOC_SIZE (AUDIOBUF_SIZE+AUDIOBUF_GUARD_SIZE)
-
-/** PCM buffer **/
-#define CLOCK_RATE 44100 /* Our clock rate in ticks/second (samplerate) */
-
-/* Define this as "1" to have a test tone instead of silence clip */
-#define SILENCE_TEST_TONE 0
-
-/* NOTE: Sizes make no frame header allowance when considering duration */
-#define PCMOUT_BUFSIZE (CLOCK_RATE/2*4) /* 1/2s */
-#define PCMOUT_GUARD_SIZE (PCMOUT_BUFSIZE) /* guarantee contiguous sizes */
-#define PCMOUT_ALLOC_SIZE (PCMOUT_BUFSIZE + PCMOUT_GUARD_SIZE)
- /* Start pcm playback @ 25% full */
-#define PCMOUT_PLAY_WM (PCMOUT_BUFSIZE/4)
-#define PCMOUT_LOW_WM (0)
-
-/** disk buffer **/
-#define DISK_BUF_LOW_WATERMARK (1024*1024)
-/* 65535+6 is required since each PES has a 6 byte header with a 16 bit
- * packet length field */
-#define DISK_GUARDBUF_SIZE ALIGN_UP(65535+6, 4)
-
-#ifdef HAVE_LCD_COLOR
-#define mylcd_splash rb->splash
-#else
-#include "lib/grey.h"
-#define mylcd_splash grey_splash
-#endif
-
-#include "lib/mylcd.h"
-
-#include "libmpeg2/mpeg2.h"
-#include "video_out.h"
-#include "mpeg_stream.h"
-#include "mpeg_misc.h"
-#include "mpeg_alloc.h"
-#include "stream_thread.h"
-#include "parser.h"
-#include "pcm_output.h"
-#include "disk_buf.h"
-#include "stream_mgr.h"
-
-#define LCD_ENABLE_EVENT_0 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0)
-#define LCD_ENABLE_EVENT_1 MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 1)
-
-#ifdef PLUGIN_USE_IRAM
-/* IRAM preserving mechanism to enable talking menus */
-extern void mpegplayer_iram_preserve(void);
-extern void mpegplayer_iram_restore(void);
-#endif
-
-#endif /* MPEGPLAYER_H */
diff --git a/apps/plugins/mpegplayer/mpegplayer.make b/apps/plugins/mpegplayer/mpegplayer.make
deleted file mode 100644
index af2156787e..0000000000
--- a/apps/plugins/mpegplayer/mpegplayer.make
+++ /dev/null
@@ -1,32 +0,0 @@
-# __________ __ ___.
-# Open \______ \ ____ ____ | | _\_ |__ _______ ___
-# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
-# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
-# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
-# \/ \/ \/ \/ \/
-# $Id$
-#
-
-MPEGSRCDIR := $(APPSDIR)/plugins/mpegplayer
-MPEGBUILDDIR := $(BUILDDIR)/apps/plugins/mpegplayer
-
-ROCKS += $(MPEGBUILDDIR)/mpegplayer.rock
-
-MPEG_SRC := $(call preprocess, $(MPEGSRCDIR)/SOURCES)
-MPEG_OBJ := $(call c2obj, $(MPEG_SRC))
-
-# add source files to OTHER_SRC to get automatic dependencies
-OTHER_SRC += $(MPEG_SRC)
-
-# Set '-fgnu89-inline' if supported (GCCVER >= 4.1.3, GCCNUM > 401)
-ifeq ($(shell expr $(GCCNUM) \> 401),1)
- MPEGCFLAGS = $(PLUGINFLAGS) -fgnu89-inline
-else
- MPEGCFLAGS = $(PLUGINFLAGS)
-endif
-
-$(MPEGBUILDDIR)/mpegplayer.rock: $(MPEG_OBJ) $(CODECDIR)/libmad-mpeg.a
-
-$(MPEGBUILDDIR)/%.o: $(MPEGSRCDIR)/%.c $(MPEGSRCDIR)/mpegplayer.make
- $(SILENT)mkdir -p $(dir $@)
- $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(MPEGCFLAGS) -c $< -o $@
diff --git a/apps/plugins/mpegplayer/parser.h b/apps/plugins/mpegplayer/parser.h
deleted file mode 100644
index ba2181e98b..0000000000
--- a/apps/plugins/mpegplayer/parser.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * AV parser inteface declarations
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef PARSER_H
-#define PARSER_H
-
-enum stream_formats
-{
- STREAM_FMT_UNKNOWN = -1,
- STREAM_FMT_MPEG_TS, /* MPEG transport stream */
- STREAM_FMT_MPEG_PS, /* MPEG program stream */
- STREAM_FMT_MPV, /* MPEG Video only (1 or 2) */
- STREAM_FMT_MPA, /* MPEG Audio only */
-};
-
-/* Structure used by a thread that handles a single demuxed data stream and
- * receives commands from the stream manager */
-enum stream_parse_states
-{
- /* Stream is... */
- SSTATE_SYNC, /* synchronizing by trying to find a start code */
- SSTATE_PARSE, /* parsing the stream looking for packets */
- SSTATE_END, /* at the end of data */
-};
-
-enum stream_parse_mode
-{
- STREAM_PM_STREAMING = 0, /* Next packet when streaming */
- STREAM_PM_RANDOM_ACCESS, /* Random-access parsing */
-};
-
-enum stream_parser_flags
-{
- STREAMF_CAN_SEEK = 0x1, /* Seeking possible for this stream */
-};
-
-struct stream_parser
-{
- /* Common generic parser data */
- enum stream_formats format; /* Stream format */
- uint32_t start_pts; /* The movie start time as represented by
- the first audio PTS tag in the
- stream converted to half minutes */
- uint32_t end_pts; /* The movie end time as represented by
- the maximum audio PTS tag in the
- stream converted to half minutes */
- uint32_t duration; /* Duration in PTS units */
- unsigned flags; /* Various attributes set at init */
- struct vo_ext dims; /* Movie dimensions in pixels */
- uint32_t last_seek_time;
- int (*next_data)(struct stream *str, enum stream_parse_mode type);
- union /* A place for reusable no-cache parameters */
- {
- struct str_sync_data sd;
- } parms;
-};
-
-extern struct stream_parser str_parser;
-
-/* MPEG parsing */
-uint8_t * mpeg_parser_scan_start_code(struct stream_scan *sk, uint32_t code);
-unsigned mpeg_parser_scan_pes(struct stream_scan *sk);
-uint32_t mpeg_parser_scan_scr(struct stream_scan *sk);
-uint32_t mpeg_parser_scan_pts(struct stream_scan *sk, unsigned id);
-off_t mpeg_stream_stream_seek_PTS(uint32_t time, int id);
-
-/* General parsing */
-bool parser_init(void);
-void str_initialize(struct stream *str, off_t pos);
-bool parser_prepare_image(uint32_t time);
-bool parser_get_video_size(struct vo_ext *sz);
-int parser_init_stream(void);
-void parser_close_stream(void);
-static inline bool parser_can_seek(void)
- { return str_parser.flags & STREAMF_CAN_SEEK; }
-uint32_t parser_seek_time(uint32_t time);
-void parser_prepare_streaming(void);
-void str_end_of_stream(struct stream *str);
-
-static inline int parser_get_next_data(struct stream *str,
- enum stream_parse_mode type)
- { return str_parser.next_data(str, type); }
-
-#endif /* PARSER_H */
diff --git a/apps/plugins/mpegplayer/pcm_output.c b/apps/plugins/mpegplayer/pcm_output.c
deleted file mode 100644
index 5e95d16316..0000000000
--- a/apps/plugins/mpegplayer/pcm_output.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * PCM output buffer definitions
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-
-/* PCM channel we're using */
-#define MPEG_PCM_CHANNEL PCM_MIXER_CHAN_PLAYBACK
-
-/* Pointers */
-
-/* Start of buffer */
-static struct pcm_frame_header * ALIGNED_ATTR(4) pcm_buffer;
-/* End of buffer (not guard) */
-static struct pcm_frame_header * ALIGNED_ATTR(4) pcmbuf_end;
-/* Read pointer */
-static struct pcm_frame_header * ALIGNED_ATTR(4) pcmbuf_head IBSS_ATTR;
-/* Write pointer */
-static struct pcm_frame_header * ALIGNED_ATTR(4) pcmbuf_tail IBSS_ATTR;
-
-/* Bytes */
-static ssize_t pcmbuf_curr_size IBSS_ATTR; /* Size of currently playing frame */
-static ssize_t pcmbuf_read IBSS_ATTR; /* Number of bytes read by DMA */
-static ssize_t pcmbuf_written IBSS_ATTR; /* Number of bytes written by source */
-static ssize_t pcmbuf_threshold IBSS_ATTR; /* Non-silence threshold */
-
-/* Clock */
-static uint32_t clock_start IBSS_ATTR; /* Clock at playback start */
-static uint32_t volatile clock_tick IBSS_ATTR; /* Our base clock */
-static uint32_t volatile clock_time IBSS_ATTR; /* Timestamp adjusted */
-
-static int pcm_skipped = 0;
-static int pcm_underruns = 0;
-
-static unsigned int old_sampr = 0;
-
-/* Small silence clip. ~5.80ms @ 44.1kHz */
-static int16_t silence[256*2] ALIGNED_ATTR(4) = { 0 };
-
-/* Delete all buffer contents */
-static void pcm_reset_buffer(void)
-{
- pcmbuf_threshold = PCMOUT_PLAY_WM;
- pcmbuf_curr_size = pcmbuf_read = pcmbuf_written = 0;
- pcmbuf_head = pcmbuf_tail = pcm_buffer;
- pcm_skipped = pcm_underruns = 0;
-}
-
-/* Advance a PCM buffer pointer by size bytes circularly */
-static inline void pcm_advance_buffer(struct pcm_frame_header **p,
- size_t size)
-{
- *p = SKIPBYTES(*p, size);
- if (*p >= pcmbuf_end)
- *p = SKIPBYTES(*p, -PCMOUT_BUFSIZE);
-}
-
-/* Return physical space used */
-static inline ssize_t pcm_output_bytes_used(void)
-{
- return pcmbuf_written - pcmbuf_read; /* wrap-safe */
-}
-
-/* Return physical space free */
-static inline ssize_t pcm_output_bytes_free(void)
-{
- return PCMOUT_BUFSIZE - pcm_output_bytes_used();
-}
-
-/* Audio DMA handler */
-static void get_more(const void **start, size_t *size)
-{
- ssize_t sz;
-
- /* Free-up the last frame played frame if any */
- pcmbuf_read += pcmbuf_curr_size;
- pcmbuf_curr_size = 0;
-
- sz = pcm_output_bytes_used();
-
- if (sz > pcmbuf_threshold)
- {
- pcmbuf_threshold = PCMOUT_LOW_WM;
-
- while (1)
- {
- uint32_t time = pcmbuf_head->time;
- int32_t offset = time - clock_time;
-
- sz = pcmbuf_head->size;
-
- if (sz < (ssize_t)(PCM_HDR_SIZE + 4) ||
- (sz & 3) != 0)
- {
- /* Just show a warning about this - will never happen
- * without a corrupted buffer */
- DEBUGF("get_more: invalid size (%ld)\n", (long)sz);
- }
-
- if (offset < -100*CLOCK_RATE/1000)
- {
- /* Frame more than 100ms late - drop it */
- pcm_advance_buffer(&pcmbuf_head, sz);
- pcmbuf_read += sz;
- pcm_skipped++;
- if (pcm_output_bytes_used() > 0)
- continue;
-
- /* Ran out so revert to default watermark */
- pcmbuf_threshold = PCMOUT_PLAY_WM;
- pcm_underruns++;
- }
- else if (offset < 100*CLOCK_RATE/1000)
- {
- /* Frame less than 100ms early - play it */
- struct pcm_frame_header *head = pcmbuf_head;
-
- pcm_advance_buffer(&pcmbuf_head, sz);
- pcmbuf_curr_size = sz;
-
- sz -= PCM_HDR_SIZE;
-
- /* Audio is time master - keep clock synchronized */
- clock_time = time + (sz >> 2);
-
- /* Update base clock */
- clock_tick += sz >> 2;
-
- *start = head->data;
- *size = sz;
- return;
- }
- /* Frame will be dropped - play silence clip */
- break;
- }
- }
- else
- {
- /* Ran out so revert to default watermark */
- if (pcmbuf_threshold == PCMOUT_LOW_WM)
- pcm_underruns++;
-
- pcmbuf_threshold = PCMOUT_PLAY_WM;
- }
-
- /* Keep clock going at all times */
- clock_time += sizeof (silence) / 4;
- clock_tick += sizeof (silence) / 4;
-
- *start = silence;
- *size = sizeof (silence);
-
- if (sz < 0)
- pcmbuf_read = pcmbuf_written;
-}
-
-/** Public interface **/
-
-/* Return a buffer pointer if at least size bytes are available and if so,
- * give the actual free space */
-void * pcm_output_get_buffer(ssize_t *size)
-{
- ssize_t sz = *size;
- ssize_t free = pcm_output_bytes_free() - PCM_HDR_SIZE;
-
- if (sz >= 0 && free >= sz)
- {
- *size = free; /* return actual free space (- header) */
- return pcmbuf_tail->data;
- }
-
- /* Leave *size alone so caller doesn't have to reinit */
- return NULL;
-}
-
-/* Commit the buffer returned by pcm_ouput_get_buffer; timestamp is PCM
- * clock time units, not video format time units */
-bool pcm_output_commit_data(ssize_t size, uint32_t timestamp)
-{
- if (size <= 0 || (size & 3))
- return false; /* invalid */
-
- size += PCM_HDR_SIZE;
-
- if (size > pcm_output_bytes_free())
- return false; /* too big */
-
- pcmbuf_tail->size = size;
- pcmbuf_tail->time = timestamp;
-
- pcm_advance_buffer(&pcmbuf_tail, size);
- pcmbuf_written += size;
-
- return true;
-}
-
-/* Returns 'true' if the buffer is completely empty */
-bool pcm_output_empty(void)
-{
- return pcm_output_bytes_used() <= 0;
-}
-
-/* Flushes the buffer - clock keeps counting */
-void pcm_output_flush(void)
-{
- rb->pcm_play_lock();
-
- enum channel_status status = rb->mixer_channel_status(MPEG_PCM_CHANNEL);
-
- /* Stop PCM to clear current buffer */
- if (status != CHANNEL_STOPPED)
- rb->mixer_channel_stop(MPEG_PCM_CHANNEL);
-
- rb->pcm_play_unlock();
-
- pcm_reset_buffer();
-
- /* Restart if playing state was current */
- if (status == CHANNEL_PLAYING)
- rb->mixer_channel_play_data(MPEG_PCM_CHANNEL,
- get_more, NULL, 0);
-}
-
-/* Seek the reference clock to the specified time - next audio data ready to
- go to DMA should be on the buffer with the same time index or else the PCM
- buffer should be empty */
-void pcm_output_set_clock(uint32_t time)
-{
- rb->pcm_play_lock();
-
- clock_start = time;
- clock_tick = time;
- clock_time = time;
-
- rb->pcm_play_unlock();
-}
-
-/* Return the clock as synchronized by audio frame timestamps */
-uint32_t pcm_output_get_clock(void)
-{
- uint32_t time, rem;
-
- /* Reread if data race detected - rem will be 0 if driver hasn't yet
- * updated to the new buffer size. Also be sure pcm state doesn't
- * cause indefinite loop.
- *
- * FYI: NOT scrutinized for rd/wr reordering on different cores. */
- do
- {
- time = clock_time;
- rem = rb->mixer_channel_get_bytes_waiting(MPEG_PCM_CHANNEL) >> 2;
- }
- while (UNLIKELY(time != clock_time ||
- (rem == 0 &&
- rb->mixer_channel_status(MPEG_PCM_CHANNEL) == CHANNEL_PLAYING))
- );
-
- return time - rem;
-
-}
-
-/* Return the raw clock as counted from the last pcm_output_set_clock
- * call */
-uint32_t pcm_output_get_ticks(uint32_t *start)
-{
- uint32_t tick, rem;
-
- /* Same procedure as pcm_output_get_clock */
- do
- {
- tick = clock_tick;
- rem = rb->mixer_channel_get_bytes_waiting(MPEG_PCM_CHANNEL) >> 2;
- }
- while (UNLIKELY(tick != clock_tick ||
- (rem == 0 &&
- rb->mixer_channel_status(MPEG_PCM_CHANNEL) == CHANNEL_PLAYING))
- );
-
- if (start)
- *start = clock_start;
-
- return tick - rem;
-}
-
-/* Pauses/Starts pcm playback - and the clock */
-void pcm_output_play_pause(bool play)
-{
- rb->pcm_play_lock();
-
- if (rb->mixer_channel_status(MPEG_PCM_CHANNEL) != CHANNEL_STOPPED)
- {
- rb->mixer_channel_play_pause(MPEG_PCM_CHANNEL, play);
- rb->pcm_play_unlock();
- }
- else
- {
- rb->pcm_play_unlock();
-
- if (play)
- {
- rb->mixer_channel_set_amplitude(MPEG_PCM_CHANNEL, MIX_AMP_UNITY);
- rb->mixer_channel_play_data(MPEG_PCM_CHANNEL,
- get_more, NULL, 0);
- }
- }
-}
-
-/* Stops all playback and resets the clock */
-void pcm_output_stop(void)
-{
- rb->pcm_play_lock();
-
- if (rb->mixer_channel_status(MPEG_PCM_CHANNEL) != CHANNEL_STOPPED)
- rb->mixer_channel_stop(MPEG_PCM_CHANNEL);
-
- rb->pcm_play_unlock();
-
- pcm_output_flush();
- pcm_output_set_clock(0);
-}
-
-/* Drains any data if the start threshold hasn't been reached */
-void pcm_output_drain(void)
-{
- rb->pcm_play_lock();
- pcmbuf_threshold = PCMOUT_LOW_WM;
- rb->pcm_play_unlock();
-}
-
-bool pcm_output_init(void)
-{
- pcm_buffer = mpeg_malloc(PCMOUT_ALLOC_SIZE, MPEG_ALLOC_PCMOUT);
- if (pcm_buffer == NULL)
- return false;
-
- pcmbuf_end = SKIPBYTES(pcm_buffer, PCMOUT_BUFSIZE);
-
- pcm_reset_buffer();
-
-#if INPUT_SRC_CAPS != 0
- /* Select playback */
- rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
- rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
-#endif
-
-#if SILENCE_TEST_TONE
- /* Make the silence clip a square wave */
- const int16_t silence_amp = INT16_MAX / 16;
- unsigned i;
-
- for (i = 0; i < ARRAYLEN(silence); i += 2)
- {
- if (i < ARRAYLEN(silence)/2)
- {
- silence[i] = silence_amp;
- silence[i+1] = silence_amp;
- }
- else
- {
- silence[i] = -silence_amp;
- silence[i+1] = -silence_amp;
- }
- }
-#endif
-
- old_sampr = rb->mixer_get_frequency();
- rb->mixer_set_frequency(CLOCK_RATE);
- rb->pcmbuf_fade(false, true);
- return true;
-}
-
-void pcm_output_exit(void)
-{
- rb->pcmbuf_fade(false, false);
- if (old_sampr != 0)
- rb->mixer_set_frequency(old_sampr);
-}
diff --git a/apps/plugins/mpegplayer/pcm_output.h b/apps/plugins/mpegplayer/pcm_output.h
deleted file mode 100644
index bae00cd045..0000000000
--- a/apps/plugins/mpegplayer/pcm_output.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * PCM output buffer declarations
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef PCM_OUTPUT_H
-#define PCM_OUTPUT_H
-
-#define PCM_HDR_SIZE (sizeof (struct pcm_frame_header))
-struct pcm_frame_header /* Header added to pcm data every time a decoded
- audio frame is sent out */
-{
- uint32_t size; /* size of this frame - including header */
- uint32_t time; /* timestamp for this frame in audio ticks */
- unsigned char data[]; /* open array of audio data */
-} ALIGNED_ATTR(4);
-
-bool pcm_output_init(void);
-void pcm_output_exit(void);
-void pcm_output_flush(void);
-void pcm_output_set_clock(uint32_t time);
-uint32_t pcm_output_get_clock(void);
-uint32_t pcm_output_get_ticks(uint32_t *start);
-void pcm_output_play_pause(bool play);
-void pcm_output_stop(void);
-void pcm_output_drain(void);
-void * pcm_output_get_buffer(ssize_t *size);
-bool pcm_output_commit_data(ssize_t size, uint32_t timestamp);
-bool pcm_output_empty(void);
-
-#endif /* PCM_OUTPUT_H */
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
deleted file mode 100644
index 3cac8c0f57..0000000000
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ /dev/null
@@ -1,1163 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * AV stream manager implementation
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-#include "lib/grey.h"
-#include "mpeg_settings.h"
-
-#ifndef HAVE_LCD_COLOR
-GREY_INFO_STRUCT_IRAM
-#endif
-
-static struct event_queue stream_mgr_queue SHAREDBSS_ATTR;
-static struct queue_sender_list stream_mgr_queue_send SHAREDBSS_ATTR;
-static uint32_t stream_mgr_thread_stack[DEFAULT_STACK_SIZE*2/sizeof(uint32_t)];
-
-struct stream_mgr stream_mgr SHAREDBSS_ATTR;
-
-/* Forward decs */
-static int stream_on_close(void);
-
-struct str_broadcast_data
-{
- long cmd; /* Command to send to stream */
- intptr_t data; /* Data to send with command */
-};
-
-static inline void stream_mgr_lock(void)
-{
- rb->mutex_lock(&stream_mgr.str_mtx);
-}
-
-static inline void stream_mgr_unlock(void)
-{
- rb->mutex_unlock(&stream_mgr.str_mtx);
-}
-
-static inline void actl_lock(void)
-{
- rb->mutex_lock(&stream_mgr.actl_mtx);
-}
-
-static inline void actl_unlock(void)
-{
- rb->mutex_unlock(&stream_mgr.actl_mtx);
-}
-
-static inline void stream_mgr_post_msg(long id, intptr_t data)
-{
- rb->queue_post(stream_mgr.q, id, data);
-}
-
-static inline intptr_t stream_mgr_send_msg(long id, intptr_t data)
-{
- return rb->queue_send(stream_mgr.q, id, data);
-}
-
-static inline void stream_mgr_reply_msg(intptr_t retval)
-{
- rb->queue_reply(stream_mgr.q, retval);
-}
-
-int str_next_data_not_ready(struct stream *str)
-{
- /* Save the current window since it actually might be ready by the time
- * the registration is received by buffering. */
- off_t win_right = str->hdr.win_right;
-
- if (str->hdr.win_right < disk_buf.filesize - MIN_BUFAHEAD &&
- disk_buf.filesize > MIN_BUFAHEAD)
- {
- /* Set right edge to where probing left off + the minimum margin */
- str->hdr.win_right += MIN_BUFAHEAD;
- }
- else
- {
- /* Request would be passed the end of the file */
- str->hdr.win_right = disk_buf.filesize;
- }
-
- switch (disk_buf_send_msg(DISK_BUF_DATA_NOTIFY, (intptr_t)str))
- {
- case DISK_BUF_NOTIFY_OK:
- /* Was ready - restore window and process */
- str->hdr.win_right = win_right;
- return STREAM_OK;
-
- case DISK_BUF_NOTIFY_ERROR:
- /* Error - quit parsing */
- str_end_of_stream(str);
- return STREAM_DATA_END;
-
- default:
- /* Not ready - go wait for notification from buffering. */
- str->pkt_flags = 0;
- return STREAM_DATA_NOT_READY;
- }
-}
-
-void str_data_notify_received(struct stream *str)
-{
- /* Normalize win_right back to the packet length */
- if (str->state == SSTATE_END)
- return;
-
- if (str->curr_packet == NULL)
- {
- /* Nothing was yet parsed since init */
- str->hdr.win_right = str->hdr.win_left;
- }
- else
- {
- /* Restore window based upon current packet */
- str->hdr.win_right = str->hdr.win_left +
- (str->curr_packet_end - str->curr_packet);
- }
-}
-
-/* Set stream manager to a "no-file" state */
-static void stream_mgr_init_state(void)
-{
- stream_mgr.filename = NULL;
- stream_mgr.resume_time = INVALID_TIMESTAMP;
- stream_mgr.seeked = false;
-}
-
-/* Add a stream to the playback pool */
-void stream_add_stream(struct stream *str)
-{
- actl_lock();
-
- list_remove_item(stream_mgr.strl, str);
- list_add_item(stream_mgr.strl, str);
-
- actl_unlock();
-}
-
-/* Callback for various list-moving operations */
-static bool strl_enum_callback(struct stream *str, void *data)
-{
- actl_lock();
-
- list_remove_item(stream_mgr.strl, str);
-
- if (*(int*)data == 1)
- list_add_item(stream_mgr.actl, str);
-
- actl_unlock();
-
- return true;
-}
-
-/* Clear all streams from active and playback pools */
-void stream_remove_streams(void)
-{
- int add_item = 0;
- list_enum_items(stream_mgr.strl,
- (list_enum_callback_t)strl_enum_callback, (void *)&add_item);
-}
-
-/* Move the playback pool to the active list */
-void move_strl_to_actl(void)
-{
- int add_item = 1;
- list_enum_items(stream_mgr.strl,
- (list_enum_callback_t)strl_enum_callback, (void *)&add_item);
-}
-
-/* Remove a stream from the active list and return it to the pool */
-static bool actl_stream_remove(struct stream *str)
-{
- bool retval;
-
- actl_lock();
-
- retval = list_remove_item(stream_mgr.actl, str);
-
- if (retval)
- list_add_item(stream_mgr.strl, str);
-
- actl_unlock();
-
- return retval;
-}
-
-/* Broadcast a message to all active streams */
-static bool actl_stream_broadcast_callback(struct stream *str,
- struct str_broadcast_data *sbd)
-{
- switch (sbd->cmd)
- {
- case STREAM_PLAY:
- case STREAM_PAUSE:
- break;
-
- case STREAM_STOP:
- if (sbd->data != 0)
- {
- actl_lock();
-
- list_remove_item(stream_mgr.actl, str);
- list_add_item(stream_mgr.strl, str);
-
- actl_unlock();
- sbd->data = 0;
- }
- break;
-
- default:
- return false;
- }
-
- str_send_msg(str, sbd->cmd, sbd->data);
- return true;
-}
-
-static void actl_stream_broadcast(int cmd, intptr_t data)
-{
- struct str_broadcast_data sbd;
- sbd.cmd = cmd;
- sbd.data = data;
- list_enum_items(stream_mgr.actl,
- (list_enum_callback_t)actl_stream_broadcast_callback,
- (void*)&sbd);
-}
-
-/* Set the current base clock */
-static void set_stream_clock(uint32_t time)
-{
- /* Fudge: Start clock 100ms early to allow for some filling time */
- if (time > 100*TS_SECOND/1000)
- time -= 100*TS_SECOND/1000;
- else
- time = 0;
-
- pcm_output_set_clock(TS_TO_TICKS(time));
-}
-
-static void stream_start_playback(uint32_t time, bool fill_buffer)
-{
- if (stream_mgr.seeked)
- {
- /* Clear any seeked status */
- stream_mgr.seeked = false;
-
- /* Flush old PCM data */
- pcm_output_flush();
-
- /* Set the master clock */
- set_stream_clock(time);
-
- /* Make sure streams are back in active pool */
- move_strl_to_actl();
-
- /* Prepare the parser and associated streams */
- parser_prepare_streaming();
- }
-
- /* Start buffer which optional force fill */
- disk_buf_send_msg(STREAM_PLAY, fill_buffer);
-
- /* Tell each stream to start - may generate end of stream signals
- * now - we'll handle this when finished */
- actl_stream_broadcast(STREAM_PLAY, 0);
-
- /* Actually start the clock */
- pcm_output_play_pause(true);
-}
-
-/* Return the play time relative to the specified play time */
-static uint32_t time_from_whence(uint32_t time, int whence)
-{
- int64_t currtime;
- uint32_t start;
-
- switch (whence)
- {
- case SEEK_SET:
- /* Set the current time (time = unsigned offset from 0) */
- if (time > str_parser.duration)
- time = str_parser.duration;
- break;
- case SEEK_CUR:
- /* Seek forward or backward from the current time
- * (time = signed offset from current) */
- currtime = stream_get_seek_time(&start);
- currtime -= start;
- currtime += (int32_t)time;
-
- if (currtime < 0)
- currtime = 0;
- else if ((uint64_t)currtime > str_parser.duration)
- currtime = str_parser.duration;
-
- time = (uint32_t)currtime;
- break;
- case SEEK_END:
- /* Seek from the end (time = unsigned offset from end) */
- if (time > str_parser.duration)
- time = str_parser.duration;
- time = str_parser.duration - time;
- break;
- }
-
- return time;
-}
-
-/* Handle seeking details if playing or paused */
-static uint32_t stream_seek_intl(uint32_t time, int whence,
- int status, bool *was_buffering)
-{
- if (status != STREAM_STOPPED)
- {
- bool wb;
-
- /* Place streams in a non-running state - keep them on actl if
- * still there */
- actl_stream_broadcast(STREAM_PAUSE, 0);
-
- /* Stop all buffering or else risk clobbering random-access data */
- wb = disk_buf_send_msg(STREAM_STOP, 0);
-
- if (was_buffering != NULL)
- *was_buffering = wb;
- }
-
- time = time_from_whence(time, whence);
-
- stream_mgr.seeked = true;
-
- return parser_seek_time(time);
-}
-
-/* Store the resume time at the last seek/current clock point */
-static void stream_remember_resume_time(void)
-{
- /* Assume invalidity */
- stream_mgr.resume_time = 0;
-
- if (stream_can_seek())
- {
- /* Read the current stream time or the last seeked position */
- uint32_t start;
- uint32_t time = stream_get_seek_time(&start);
-
- if (time >= str_parser.start_pts && time <= str_parser.end_pts)
- {
- /* Save the current stream time */
- stream_mgr.resume_time = time - start;
- }
- }
-}
-
-/* Handle STREAM_OPEN */
-void stream_on_open(const char *filename)
-{
- int err = STREAM_ERROR;
-
- stream_mgr_lock();
-
- trigger_cpu_boost();
-
- /* Open the video file */
- if (disk_buf_open(filename) >= 0)
- {
- /* Initialize the parser */
- err = parser_init_stream();
-
- if (err >= STREAM_OK)
- {
- /* File ok - save the opened filename */
- stream_mgr.filename = filename;
- }
- }
-
- /* If error - cleanup */
- if (err < STREAM_OK)
- stream_on_close();
-
- cancel_cpu_boost();
-
- stream_mgr_unlock();
-
- stream_mgr_reply_msg(err);
-}
-
-/* Handler STREAM_PLAY */
-static void stream_on_play(void)
-{
- int status = stream_mgr.status;
-
- stream_mgr_lock();
-
- if (status == STREAM_STOPPED)
- {
- uint32_t start;
-
- /* We just say we're playing now */
- stream_mgr.status = STREAM_PLAYING;
-
- /* Reply with previous state */
- stream_mgr_reply_msg(status);
-
- trigger_cpu_boost();
-
- /* Seek to initial position and set clock to that time */
-
- /* Save the resume time */
- stream_remember_resume_time();
-
- /* Prepare seek to start point */
- start = stream_seek_intl(stream_mgr.resume_time, SEEK_SET,
- STREAM_STOPPED, NULL);
-
- /* Sync and start - force buffer fill */
- stream_start_playback(start, true);
- }
- else
- {
- /* Reply with previous state */
- stream_mgr_reply_msg(status);
- }
-
- stream_mgr_unlock();
-}
-
-/* Handle STREAM_PAUSE */
-static void stream_on_pause(void)
-{
- int status = stream_mgr.status;
-
- stream_mgr_lock();
-
- /* Reply with previous state */
- stream_mgr_reply_msg(status);
-
- if (status == STREAM_PLAYING)
- {
- /* Pause the clock */
- pcm_output_play_pause(false);
-
- /* Pause each active stream */
- actl_stream_broadcast(STREAM_PAUSE, 0);
-
- /* Pause the disk buffer - buffer may continue filling */
- disk_buf_send_msg(STREAM_PAUSE, false);
-
- /* Unboost the CPU */
- cancel_cpu_boost();
-
- /* Offically paused */
- stream_mgr.status = STREAM_PAUSED;
- }
-
- stream_mgr_unlock();
-}
-
-/* Handle STREAM_RESUME */
-static void stream_on_resume(void)
-{
- int status = stream_mgr.status;
-
- stream_mgr_lock();
-
- /* Reply with previous state */
- stream_mgr_reply_msg(status);
-
- if (status == STREAM_PAUSED)
- {
- /* Boost the CPU */
- trigger_cpu_boost();
-
- /* Sync and start - no force buffering */
- stream_start_playback(str_parser.last_seek_time, false);
-
- /* Officially playing */
- stream_mgr.status = STREAM_PLAYING;
- }
-
- stream_mgr_unlock();
-}
-
-/* Handle STREAM_STOP */
-static void stream_on_stop(bool reply)
-{
- int status = stream_mgr.status;
-
- stream_mgr_lock();
-
- if (reply)
- stream_mgr_reply_msg(status);
-
- if (status != STREAM_STOPPED)
- {
- /* Pause the clock */
- pcm_output_play_pause(false);
-
- /* Update the resume time info */
- stream_remember_resume_time();
-
- /* Not stopped = paused or playing */
- stream_mgr.seeked = false;
-
- /* Stop buffering */
- disk_buf_send_msg(STREAM_STOP, 0);
-
- /* Clear any still-active streams and remove from actl */
- actl_stream_broadcast(STREAM_STOP, 1);
-
- /* Stop PCM output (and clock) */
- pcm_output_stop();
-
- /* Cancel our processor boost */
- cancel_cpu_boost();
-
- stream_mgr.status = STREAM_STOPPED;
- }
-
- stream_mgr_unlock();
-}
-
-/* Handle STREAM_SEEK */
-static void stream_on_seek(struct stream_seek_data *skd)
-{
- uint32_t time = skd->time;
- int whence = skd->whence;
-
- switch (whence)
- {
- case SEEK_SET:
- case SEEK_CUR:
- case SEEK_END:
- if (stream_mgr.filename == NULL)
- break;
-
- /* Keep things spinning if already doing so */
- stream_keep_disk_active();
-
- /* Have data - reply in order to acquire lock */
- stream_mgr_reply_msg(STREAM_OK);
-
- stream_mgr_lock();
-
- /* Either seeking must be possible or a full rewind must be done */
- if (stream_can_seek() || time_from_whence(time, whence) == 0)
- {
- bool buffer = false;
-
- if (stream_mgr.status == STREAM_PLAYING)
- {
- /* Keep clock from advancing while seeking */
- pcm_output_play_pause(false);
- }
-
- time = stream_seek_intl(time, whence, stream_mgr.status, &buffer);
- stream_remember_resume_time();
-
- if (stream_mgr.status == STREAM_PLAYING)
- {
- /* Sync and restart - no force buffering */
- stream_start_playback(time, buffer);
- }
- }
-
- stream_mgr_unlock();
- return;
- }
-
- /* Invalid parameter or no file */
- stream_mgr_reply_msg(STREAM_ERROR);
-}
-
-/* Handle STREAM_CLOSE */
-static int stream_on_close(void)
-{
- int status = STREAM_STOPPED;
-
- stream_mgr_lock();
-
- /* Any open file that was accepted for playback? */
- if (stream_mgr.filename != NULL)
- {
- /* Yes - hide video */
- stream_show_vo(false);
- /* Stop any playback */
- status = stream_mgr.status;
- stream_on_stop(false);
- /* Tell parser file is finished */
- parser_close_stream();
- /* Reinitialize manager */
- stream_mgr_init_state();
- }
-
- /* Let disk buffer reset itself - file might be open even if no good */
- disk_buf_close();
-
- stream_mgr_unlock();
-
- return status;
-}
-
-/* Handle STREAM_EV_COMPLETE */
-static void stream_on_ev_complete(struct stream *str)
-{
- stream_mgr_lock();
-
- /* Stream is active? */
- if (actl_stream_remove(str))
- {
- /* No - remove this stream from the active list */
- DEBUGF(" finished: 0x%02x\n", str->id);
- if (list_is_empty(stream_mgr.actl))
- {
- /* All streams have acked - stop playback */
- stream_on_stop(false);
- stream_mgr.resume_time = 0; /* Played to end - no resume */
- }
- else
- {
- /* Stream is done - stop it and place back in pool */
- str_send_msg(str, STREAM_STOP, 1);
- }
- }
-
- stream_mgr_unlock();
-}
-
-/* Callback for stream to notify about events internal to them */
-void stream_generate_event(struct stream *str, long id, intptr_t data)
-{
- if (str == NULL)
- return;
-
- switch (id)
- {
- case STREAM_EV_COMPLETE:
- /* The last stream has ended */
- stream_mgr_post_msg(STREAM_EV_COMPLETE, (intptr_t)str);
- break;
- }
-
- (void)data;
-}
-
-/* Clear any particular notification for which a stream registered */
-void stream_clear_notify(struct stream *str, int for_msg)
-{
- switch (for_msg)
- {
- case DISK_BUF_DATA_NOTIFY:
- disk_buf_send_msg(DISK_BUF_CLEAR_DATA_NOTIFY, (intptr_t)str);
- break;
- }
-}
-
-/* Special handling for certain messages since they involve multiple
- * operations behind the scenes */
-static intptr_t send_video_msg(long id, intptr_t data)
-{
- intptr_t retval = 0;
-
- if (video_str.thread != 0 && disk_buf.in_file >= 0)
- {
-
- switch (id)
- {
- case VIDEO_DISPLAY_SHOW:
- if (data != 0 && disk_buf_status() == STREAM_STOPPED)
- { /* Only prepare image if showing and not playing */
- parser_prepare_image(str_parser.last_seek_time);
- }
- break;
-
- case VIDEO_PRINT_FRAME:
- if (data)
- break;
- case VIDEO_PRINT_THUMBNAIL:
- if (disk_buf_status() != STREAM_STOPPED)
- break; /* Prepare image if not playing */
-
- /* Ignore return and try video thread anyway */
- parser_prepare_image(str_parser.last_seek_time);
-
- /* Image ready - pass message to video thread */
- break;
- }
-
- retval = str_send_msg(&video_str, id, data);
- }
-
- return retval;
-}
-
-/* Show/hide the video output */
-bool stream_show_vo(bool show)
-{
- bool vis;
- stream_mgr_lock();
-
- vis = send_video_msg(VIDEO_DISPLAY_SHOW, show);
-#ifndef HAVE_LCD_COLOR
- grey_show(show);
-#endif
- stream_mgr_unlock();
-
- return vis;
-}
-
-/* Query the visibility of video output */
-bool stream_vo_is_visible(void)
-{
- bool vis;
- stream_mgr_lock();
- vis = send_video_msg(VIDEO_DISPLAY_IS_VISIBLE, 0);
- stream_mgr_unlock();
- return vis;
-}
-
-/* Return the video dimensions */
-bool stream_vo_get_size(struct vo_ext *sz)
-{
- bool retval = false;
-
- stream_mgr_lock();
-
- if (str_parser.dims.w > 0 && str_parser.dims.h > 0)
- {
- *sz = str_parser.dims;
- retval = true;
- }
-
- stream_mgr_unlock();
-
- return retval;
-}
-
-void stream_vo_set_clip(const struct vo_rect *rc)
-{
- stream_mgr_lock();
-
- if (rc)
- {
- stream_mgr.parms.rc = *rc;
- rc = &stream_mgr.parms.rc;
- }
-
- send_video_msg(VIDEO_SET_CLIP_RECT, (intptr_t)rc);
-
- stream_mgr_unlock();
-}
-
-bool stream_vo_get_clip(struct vo_rect *rc)
-{
- bool retval;
-
- if (!rc)
- return false;
-
- stream_mgr_lock();
-
- retval = send_video_msg(VIDEO_GET_CLIP_RECT,
- (intptr_t)&stream_mgr.parms.rc);
-
- *rc = stream_mgr.parms.rc;
-
- stream_mgr_unlock();
-
- return retval;
-}
-
-#ifndef HAVE_LCD_COLOR
-/* Show/hide the gray video overlay (independently of vo visibility). */
-void stream_gray_show(bool show)
-{
- stream_mgr_lock();
-
- grey_show(show);
-
- stream_mgr_unlock();
-}
-
-#endif /* !HAVE_LCD_COLOR */
-
-/* Display a thumbnail at the last seek point */
-bool stream_display_thumb(const struct vo_rect *rc)
-{
- bool retval;
-
- if (rc == NULL)
- return false;
-
- stream_mgr_lock();
-
- stream_mgr.parms.rc = *rc;
- retval = send_video_msg(VIDEO_PRINT_THUMBNAIL,
- (intptr_t)&stream_mgr.parms.rc);
-
- stream_mgr_unlock();
-
- return retval;
-}
-
-bool stream_draw_frame(bool no_prepare)
-{
- bool retval;
- stream_mgr_lock();
-
- retval = send_video_msg(VIDEO_PRINT_FRAME, no_prepare);
-
- stream_mgr_unlock();
-
- return retval;
-}
-
-bool stream_set_callback(long id, void *fn)
-{
- bool retval = false;
-
- stream_mgr_lock();
-
- switch (id)
- {
- case VIDEO_SET_POST_FRAME_CALLBACK:
- retval = send_video_msg(id, (intptr_t)fn);
- }
-
- stream_mgr_unlock();
-
- return retval;
-}
-
-/* Return the time playback should resume if interrupted */
-uint32_t stream_get_resume_time(void)
-{
- uint32_t resume_time;
-
- /* A stop request is async and replies before setting this - must lock */
- stream_mgr_lock();
-
- resume_time = stream_mgr.resume_time;
-
- stream_mgr_unlock();
-
- return resume_time;
-}
-
-uint32_t stream_get_seek_time(uint32_t *start)
-{
- uint32_t time;
-
- stream_mgr_lock();
-
- if (stream_mgr.seeked)
- {
- time = str_parser.last_seek_time;
- }
- else
- {
- time = TICKS_TO_TS(pcm_output_get_clock());
-
- /* Clock can be start early so keep in range */
- if (time < str_parser.start_pts)
- time = str_parser.start_pts;
- }
-
- if (start != NULL)
- *start = str_parser.start_pts;
-
- stream_mgr_unlock();
-
- return time;
-}
-
-/* Wait for a state transistion to complete */
-void stream_wait_status(void)
-{
- stream_mgr_lock();
- stream_mgr_unlock();
-}
-
-/* Returns the smallest file window that includes all active streams'
- * windows */
-static bool stream_get_window_callback(struct stream *str,
- struct stream_window *sw)
-{
- off_t swl = str->hdr.win_left;
- off_t swr = str->hdr.win_right;
-
- if (swl < sw->left)
- sw->left = swl;
-
- if (swr > sw->right)
- sw->right = swr;
-
- return true;
-}
-
-bool stream_get_window(struct stream_window *sw)
-{
- if (sw == NULL)
- return false;
-
- sw->left = LONG_MAX;
- sw->right = LONG_MIN;
-
- actl_lock();
- list_enum_items(stream_mgr.actl,
- (list_enum_callback_t)stream_get_window_callback,
- (void*)sw);
- actl_unlock();
-
- return sw->left <= sw->right;
-}
-
-/* Playback control thread */
-static void stream_mgr_thread(void)
-{
- struct queue_event ev;
-
- while (1)
- {
- rb->queue_wait(stream_mgr.q, &ev);
-
- switch (ev.id)
- {
- case STREAM_OPEN:
- stream_on_open((const char *)ev.data);
- break;
-
- case STREAM_CLOSE:
- stream_on_close();
- break;
-
- case STREAM_PLAY:
- stream_on_play();
- break;
-
- case STREAM_PAUSE:
- if (ev.data)
- stream_on_resume();
- else
- stream_on_pause();
- break;
-
- case STREAM_STOP:
- stream_on_stop(true);
- break;
-
- case STREAM_SEEK:
- stream_on_seek((struct stream_seek_data *)ev.data);
- break;
-
- case STREAM_EV_COMPLETE:
- stream_on_ev_complete((struct stream *)ev.data);
- break;
-
- case STREAM_QUIT:
- if (stream_mgr.status != STREAM_STOPPED)
- stream_on_stop(false);
- return;
- }
- }
-}
-
-/* Stream command interface APIs */
-
-/* Opens a new file */
-int stream_open(const char *filename)
-{
- if (stream_mgr.thread != 0)
- return stream_mgr_send_msg(STREAM_OPEN, (intptr_t)filename);
- return STREAM_ERROR;
-}
-
-/* Plays the current file starting at time 'start' */
-int stream_play(void)
-{
- if (stream_mgr.thread != 0)
- return stream_mgr_send_msg(STREAM_PLAY, 0);
- return STREAM_ERROR;
-}
-
-/* Pauses playback if playing */
-int stream_pause(void)
-{
- if (stream_mgr.thread != 0)
- return stream_mgr_send_msg(STREAM_PAUSE, false);
- return STREAM_ERROR;
-}
-
-/* Resumes playback if paused */
-int stream_resume(void)
-{
- if (stream_mgr.thread != 0)
- return stream_mgr_send_msg(STREAM_PAUSE, true);
- return STREAM_ERROR;
-}
-
-/* Stops playback if not stopped */
-int stream_stop(void)
-{
- if (stream_mgr.thread != 0)
- return stream_mgr_send_msg(STREAM_STOP, 0);
- return STREAM_ERROR;
-}
-
-/* Seeks playback time to/by the specified time */
-int stream_seek(uint32_t time, int whence)
-{
- int ret;
-
- if (stream_mgr.thread == 0)
- return STREAM_ERROR;
-
- stream_mgr_lock();
-
- stream_mgr.parms.skd.time = time;
- stream_mgr.parms.skd.whence = whence;
-
- ret = stream_mgr_send_msg(STREAM_SEEK, (intptr_t)&stream_mgr.parms.skd);
-
- stream_mgr_unlock();
-
- return ret;
-}
-
-/* Closes the current file */
-int stream_close(void)
-{
- if (stream_mgr.thread != 0)
- return stream_mgr_send_msg(STREAM_CLOSE, 0);
- return STREAM_ERROR;
-}
-
-/* Initializes the playback engine */
-int stream_init(void)
-{
- void *mem;
- size_t memsize;
-
- stream_mgr.status = STREAM_STOPPED;
- stream_mgr_init_state();
-
- /* Initialize our window to the outside world first */
- rb->mutex_init(&stream_mgr.str_mtx);
- rb->mutex_init(&stream_mgr.actl_mtx);
-
- stream_mgr.q = &stream_mgr_queue;
- rb->queue_init(stream_mgr.q, false);
-
- /* sets audiosize and returns buffer pointer */
- mem = rb->plugin_get_audio_buffer(&memsize);
-
- /* Initialize non-allocator blocks first */
-#ifndef HAVE_LCD_COLOR
- long greysize;
-
- /* Greylib init handles all necessary cache alignment */
- if (!grey_init(mem, memsize, GREY_BUFFERED|GREY_ON_COP,
- LCD_WIDTH, LCD_HEIGHT, &greysize))
- {
- rb->splash(HZ, "greylib init failed!");
- return STREAM_ERROR;
- }
-
- mem += greysize;
- memsize -= greysize;
-
- grey_clear_display();
-#endif /* !HAVE_LCD_COLOR */
-
- stream_mgr.thread = rb->create_thread(stream_mgr_thread,
- stream_mgr_thread_stack, sizeof(stream_mgr_thread_stack),
- 0, "mpgstream_mgr" IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU));
-
- rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send,
- stream_mgr.thread);
-
- if (stream_mgr.thread == 0)
- {
- rb->splash(HZ, "Could not create stream manager thread!");
- return STREAM_ERROR;
- }
-
- /* Wait for thread to initialize */
- stream_mgr_send_msg(STREAM_NULL, 0);
-
- /* Initialise our malloc buffer */
- if (!mpeg_alloc_init(mem, memsize))
- {
- rb->splash(HZ, "Out of memory in stream_init");
- }
- /* These inits use the allocator */
- else if (!pcm_output_init())
- {
- rb->splash(HZ, "Could not initialize PCM!");
- }
- else if (!audio_thread_init())
- {
- rb->splash(HZ, "Cannot create audio thread!");
- }
- else if (!video_thread_init())
- {
- rb->splash(HZ, "Cannot create video thread!");
- }
- /* Disk buffer takes max allotment of what's left so it must be last */
- else if (!disk_buf_init())
- {
- rb->splash(HZ, "Cannot create buffering thread!");
- }
- else if (!parser_init())
- {
- rb->splash(HZ, "Parser init failed!");
- }
- else
- {
- return STREAM_OK;
- }
-
- return STREAM_ERROR;
-}
-
-/* Cleans everything up */
-void stream_exit(void)
-{
- stream_close();
-
- /* Stop the threads and wait for them to terminate */
- video_thread_exit();
- audio_thread_exit();
- disk_buf_exit();
- pcm_output_exit();
-
- if (stream_mgr.thread != 0)
- {
- stream_mgr_post_msg(STREAM_QUIT, 0);
- rb->thread_wait(stream_mgr.thread);
- stream_mgr.thread = 0;
- }
-
-#ifndef HAVE_LCD_COLOR
- grey_release();
-#endif
-}
diff --git a/apps/plugins/mpegplayer/stream_mgr.h b/apps/plugins/mpegplayer/stream_mgr.h
deleted file mode 100644
index 7dba9acc09..0000000000
--- a/apps/plugins/mpegplayer/stream_mgr.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * AV stream manager decalarations
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef STREAM_MGR_H
-#define STREAM_MGR_H
-
-/* Basic media control interface - this handles state changes and stream
- * coordination with assistance from the parser */
-struct stream_mgr
-{
- unsigned int thread; /* Playback control thread */
- struct event_queue *q; /* event queue for control thread */
- const char *filename; /* Current filename */
- uint32_t resume_time; /* The stream tick where playback was
- stopped (or started) */
- bool seeked; /* A seek happened and things must be
- resynced */
- int status; /* Current playback status */
- void *strl[MPEGPLAYER_MAX_STREAMS+1]; /* List of available streams */
- void *actl[MPEGPLAYER_MAX_STREAMS+1]; /* List of active streams */
- struct mutex str_mtx; /* Main stream manager mutex */
- struct mutex actl_mtx; /* Lock for current-streams list */
- union /* A place for reusable non-cacheable parameters */
- {
- struct vo_rect rc;
- struct stream_seek_data skd;
- } parms;
-};
-
-extern struct stream_mgr stream_mgr SHAREDBSS_ATTR;
-
-struct stream_window
-{
- off_t left, right;
-};
-
-/** Interface for use by streams and other internal objects **/
-bool stream_get_window(struct stream_window *sw);
-void stream_clear_notify(struct stream *str, int for_msg);
-int str_next_data_not_ready(struct stream *str);
-/* Called by a stream to say it got its buffering notification */
-void str_data_notify_received(struct stream *str);
-void stream_add_stream(struct stream *str);
-void stream_remove_streams(void);
-
-enum stream_events
-{
- __STREAM_EV_FIRST = STREAM_MESSAGE_LAST-1,
- STREAM_EV_COMPLETE,
-};
-
-void stream_generate_event(struct stream *str, long id, intptr_t data);
-
-/** Main control functions **/
-
-/* Initialize the playback engine */
-int stream_init(void);
-
-/* Close the playback engine */
-void stream_exit(void);
-
-/* Open a new file */
-int stream_open(const char *filename);
-
-/* Close the current file */
-int stream_close(void);
-
-/* Plays from the current seekpoint if stopped */
-int stream_play(void);
-
-/* Pauses playback if playing */
-int stream_pause(void);
-
-/* Resumes playback if paused */
-int stream_resume(void);
-
-/* Stops all streaming activity if playing or paused */
-int stream_stop(void);
-
-/* Point stream at a particular time.
- * whence = one of SEEK_SET, SEEK_CUR, SEEK_END */
-int stream_seek(uint32_t time, int whence);
-
-/* Show/Hide the video image at the current seekpoint */
-bool stream_show_vo(bool show);
-
-/* Set the visible section of video */
-void stream_vo_set_clip(const struct vo_rect *rc);
-
-/* Return current visible section of video */
-bool stream_vo_get_clip(struct vo_rect *rc);
-
-#ifndef HAVE_LCD_COLOR
-void stream_gray_show(bool show);
-#endif
-
-/* Display thumbnail of the current seekpoint */
-bool stream_display_thumb(const struct vo_rect *rc);
-
-/* Draw the frame at the current position */
-bool stream_draw_frame(bool no_prepare);
-
-/* Return video dimensions */
-bool stream_vo_get_size(struct vo_ext *sz);
-
-/* Returns the resume time in timestamp ticks */
-uint32_t stream_get_resume_time(void);
-
-/* Returns stream_get_time if no seek is pending or else the
- last time give to seek */
-uint32_t stream_get_seek_time(uint32_t *start);
-
-/* Return the absolute stream time in clock ticks - adjusted by
- * master clock stream via audio timestamps */
-static inline uint32_t stream_get_time(void)
- { return pcm_output_get_clock(); }
-
-/* Return the absolute clock time in clock ticks - unadjusted */
-static inline uint32_t stream_get_ticks(uint32_t *start)
- { return pcm_output_get_ticks(start); }
-
-/* Returns the current playback status */
-static inline int stream_status(void)
- { return stream_mgr.status; }
-
-/* Wait for a state transistion to complete */
-void stream_wait_status(void);
-
-/* Returns the playback length of the stream */
-static inline uint32_t stream_get_duration(void)
- { return str_parser.duration; }
-
-static inline bool stream_can_seek(void)
- { return parser_can_seek(); }
-
-static inline void stream_video_stats(struct video_output_stats *s)
- { video_thread_get_stats(s); }
-
-bool stream_set_callback(long id, void * fn);
-
-/* Keep the disk spinning (for seeking and browsing) */
-static inline void stream_keep_disk_active(void)
-{
-#ifdef HAVE_DISK_STORAGE
- rb->storage_spin();
-#endif
- }
-
-#endif /* STREAM_MGR_H */
diff --git a/apps/plugins/mpegplayer/stream_thread.h b/apps/plugins/mpegplayer/stream_thread.h
deleted file mode 100644
index dfa6e8c9a1..0000000000
--- a/apps/plugins/mpegplayer/stream_thread.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Declarations for stream-specific threading
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef STREAM_THREAD_H
-#define STREAM_THREAD_H
-
-#define PKT_HAS_TS 0x1
-
-/* Stream header which is the minimum to receive asynchronous buffering
- * notifications.
- * Layed-out to allow streaming access after random-access parsing */
-struct stream_hdr
-{
- struct event_queue *q; /* Communication queue - separate to allow it
- to be placed in another section */
- off_t win_left; /* Left position within data stream */
- union
- {
- off_t win_right; /* Right position within data stream */
- off_t pos; /* Start/current position for random-access read */
- };
- off_t limit; /* Limit for random-access read */
-};
-
-struct stream
-{
- struct stream_hdr hdr; /* Base stream data */
- unsigned int thread; /* Stream's thread */
- uint8_t* curr_packet; /* Current stream packet beginning */
- uint8_t* curr_packet_end; /* Current stream packet end */
- int state; /* State machine parsing mode */
- uint32_t start_pts; /* First timestamp for stream */
- uint32_t end_pts; /* Last timestamp for stream */
- uint32_t pts; /* Last presentation timestamp */
- uint32_t pkt_flags; /* PKT_* flags */
- unsigned id; /* Stream identifier */
-};
-
-#define STR_FROM_HDR(sh) ((struct stream *)(sh))
-
-/* Make sure there there is always enough data buffered ahead for
- * the worst possible case - regardless of whether a valid stream
- * would actually produce that */
-#define MIN_BUFAHEAD (21+65535+6+65535+6) /* 131103 */
-
-/* States that a stream's thread assumes internally */
-enum thread_states
-{
- /* Stream thread... */
- TSTATE_INIT = 0, /* is initialized and primed */
- TSTATE_DATA, /* is awaiting data to be available */
- TSTATE_BUFFERING, /* is buffering data */
- TSTATE_EOS, /* has hit the end of data */
- TSTATE_DECODE, /* is in a decoding state */
- TSTATE_RENDER, /* is in a rendering state */
- TSTATE_RENDER_WAIT, /* is waiting to render */
-};
-
-/* Commands that streams respond to */
-enum stream_message
-{
- STREAM_NULL = 0, /* A NULL message for whatever reason -
- usually ignored */
- STREAM_PLAY, /* Start playback at current position */
- STREAM_PAUSE, /* Stop playing and await further commands */
- STREAM_RESET, /* Reset the stream for a discontinuity */
- STREAM_STOP, /* Stop stream - requires a reset later */
- STREAM_SEEK, /* Seek the current stream to a new location */
- STREAM_OPEN, /* Open a new file */
- STREAM_CLOSE, /* Close the current file */
- STREAM_QUIT, /* Exit the stream and thread */
- STREAM_NEEDS_SYNC, /* Need to sync before stream decoding? */
- STREAM_SYNC, /* Sync to the specified time from some key point */
- STREAM_FIND_END_TIME, /* Get the exact end time of an elementary
- * stream - ie. time just after last frame is finished */
- /* Disk buffer */
- STREAM_DISK_BUF_FIRST,
- DISK_BUF_DATA_NOTIFY = STREAM_DISK_BUF_FIRST,
- DISK_BUF_CLEAR_DATA_NOTIFY, /* Cancel pending data notification */
- DISK_BUF_CACHE_RANGE, /* Cache a range of the file in the buffer */
- /* Audio stream */
- STREAM_AUDIO_FIRST,
- /* Video stream */
- STREAM_VIDEO_FIRST,
- VIDEO_DISPLAY_SHOW = STREAM_VIDEO_FIRST, /* Show/hide video output */
- VIDEO_DISPLAY_IS_VISIBLE, /* Is the video output visible? */
- VIDEO_GET_SIZE, /* Get the video dimensions */
- VIDEO_PRINT_FRAME, /* Print the frame at the current position */
- VIDEO_PRINT_THUMBNAIL, /* Print a thumbnail of the current position */
- VIDEO_SET_CLIP_RECT, /* Set the visible video area */
- VIDEO_GET_CLIP_RECT, /* Return the visible video area */
- VIDEO_SET_POST_FRAME_CALLBACK, /* Set a callback after frame is drawn */
- STREAM_MESSAGE_LAST,
-};
-
-/* Data parameter for STREAM_SEEK */
-struct stream_seek_data
-{
- uint32_t time; /* Time to seek to/by */
- int whence; /* Specification of relationship to current position/file */
-};
-
-/* Data parameter for STREAM_SYNC */
-struct str_sync_data
-{
- uint32_t time; /* Time to sync to */
- struct stream_scan sk; /* Specification of start/limits/direction */
-};
-
-/* Stream status codes - not eqivalent to thread states */
-enum stream_status
-{
- /* Stream status is... */
- STREAM_DATA_END = -4, /* Stream has ended */
- STREAM_DATA_NOT_READY = -3, /* Data was not available yet */
- STREAM_UNSUPPORTED = -2, /* Format is unsupported */
- STREAM_ERROR = -1, /* some kind of error - quit it or reset it */
- STREAM_OK = 0, /* General inequality for success >= is OK, < error */
- STREAM_STOPPED = 0, /* stopped and awaiting commands - send STREAM_INIT */
- STREAM_PLAYING, /* playing and rendering its data */
- STREAM_PAUSED, /* paused and awaiting commands */
- /* Other status codes (> STREAM_OK) */
- STREAM_MATCH, /* A good match was found */
- STREAM_PERFECT_MATCH, /* Exactly what was wanted was found or
- no better match is possible */
- STREAM_NOT_FOUND, /* Match not found */
-};
-
-/* Clip time to range for a particular stream */
-static inline uint32_t clip_time(struct stream *str, uint32_t time)
-{
- if (time < str->start_pts)
- time = str->start_pts;
- else if (time >= str->end_pts)
- time = str->end_pts;
-
- return time;
-}
-
-extern struct stream video_str IBSS_ATTR;
-extern struct stream audio_str IBSS_ATTR;
-
-bool video_thread_init(void);
-void video_thread_exit(void);
-
-struct video_output_stats
-{
- int num_drawn; /* Number of frames drawn since reset */
- int num_skipped; /* Number of frames skipped since reset */
- int fps; /* fps rate in 100ths of a frame per second */
-};
-
-void video_thread_get_stats(struct video_output_stats *s);
-
-bool audio_thread_init(void);
-void audio_thread_exit(void);
-
-
-/* Some queue function wrappers to keep things clean-ish */
-
-/* For stream use only */
-static inline bool str_have_msg(struct stream *str)
- { return !rb->queue_empty(str->hdr.q); }
-
-static inline void str_get_msg(struct stream *str, struct queue_event *ev)
- { rb->queue_wait(str->hdr.q, ev); }
-
-static inline void str_get_msg_w_tmo(struct stream *str, struct queue_event *ev,
- int timeout)
- { rb->queue_wait_w_tmo(str->hdr.q, ev, timeout); }
-
-static inline void str_reply_msg(struct stream *str, intptr_t reply)
- { rb->queue_reply(str->hdr.q, reply); }
-
-/* Public use */
-static inline intptr_t str_send_msg(struct stream *str, long id, intptr_t data)
- { return rb->queue_send(str->hdr.q, id, data); }
-
-static inline void str_post_msg(struct stream *str, long id, intptr_t data)
- { rb->queue_post(str->hdr.q, id, data); }
-
-#endif /* STREAM_THREAD_H */
diff --git a/apps/plugins/mpegplayer/video_out.h b/apps/plugins/mpegplayer/video_out.h
deleted file mode 100644
index 2a3364c382..0000000000
--- a/apps/plugins/mpegplayer/video_out.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * video_out.h
- * Copyright (C) 2000-2003 Michel Lespinasse
- * Copyright (C) 1999-2000 Aaron Holtzman
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- * libmpeg2 sync history:
- * 2008-07-01 - CVS revision 1.22
- */
-
-#ifndef VIDEO_OUT_H
-#define VIDEO_OUT_H
-
-#if LCD_WIDTH >= LCD_HEIGHT
-#define SCREEN_WIDTH LCD_WIDTH
-#define SCREEN_HEIGHT LCD_HEIGHT
-#define LCD_LANDSCAPE
-#else /* Assume the screen is rotated on portrait LCDs */
-#define SCREEN_WIDTH LCD_HEIGHT
-#define SCREEN_HEIGHT LCD_WIDTH
-#define LCD_PORTRAIT
-#endif
-
-/* Structure to hold width and height values */
-struct vo_ext
-{
- int w, h;
-};
-
-/* Structure that defines a rectangle by its edges */
-struct vo_rect
-{
- int l, t, r, b;
-};
-
-void vo_draw_frame (uint8_t * const * buf);
-bool vo_draw_frame_thumb (uint8_t * const * buf,
- const struct vo_rect *rc);
-bool vo_init (void);
-bool vo_show (bool show);
-bool vo_is_visible(void);
-void vo_setup (const mpeg2_sequence_t * sequence);
-void vo_set_clip_rect(const struct vo_rect *rc);
-bool vo_get_clip_rect(struct vo_rect *rc);
-void vo_dimensions(struct vo_ext *sz);
-void vo_cleanup (void);
-void vo_set_post_draw_callback(void (*cb)(void));
-
-#if NUM_CORES > 1
-void vo_lock(void);
-void vo_unlock(void);
-#else
-static inline void vo_lock(void) {}
-static inline void vo_unlock(void) {}
-#endif
-
-/* Sets all coordinates of a vo_rect to 0 */
-void vo_rect_clear(struct vo_rect *rc);
-/* Returns true if left >= right or top >= bottom */
-bool vo_rect_empty(const struct vo_rect *rc);
-/* Initializes a vo_rect using upper-left corner and extents */
-void vo_rect_set_ext(struct vo_rect *rc, int x, int y,
- int width, int height);
-/* Query if two rectangles intersect
- * If either are empty returns false */
-bool vo_rects_intersect(const struct vo_rect *rc1,
- const struct vo_rect *rc2);
-
-/* Intersect two rectangles
- * Resulting rectangle is placed in rc_dst.
- * rc_dst is set to empty if they don't intersect.
- * Empty source rectangles do not intersect any rectangle.
- * rc_dst may be the same structure as rc1 or rc2.
- * Returns true if the resulting rectangle is not empty. */
-bool vo_rect_intersect(struct vo_rect *rc_dst,
- const struct vo_rect *rc1,
- const struct vo_rect *rc2);
-
-bool vo_rect_union(struct vo_rect *rc_dst,
- const struct vo_rect *rc1,
- const struct vo_rect *rc2);
-
-void vo_rect_offset(struct vo_rect *rc, int dx, int dy);
-
-#endif /* VIDEO_OUT_H */
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
deleted file mode 100644
index 331383843b..0000000000
--- a/apps/plugins/mpegplayer/video_out_rockbox.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * mpegplayer video output routines
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "libmpeg2/mpeg2dec_config.h"
-
-#include "plugin.h"
-#include "mpegplayer.h"
-
-#define VO_NON_NULL_RECT 0x1
-#define VO_VISIBLE 0x2
-
-struct vo_data
-{
- int image_width;
- int image_height;
- int image_chroma_x;
- int image_chroma_y;
- int display_width;
- int display_height;
- int output_x;
- int output_y;
- int output_width;
- int output_height;
- unsigned flags;
- struct vo_rect rc_vid;
- struct vo_rect rc_clip;
- void (*post_draw_callback)(void);
-};
-
-#if NUM_CORES > 1
-/* Cache aligned and padded to avoid clobbering other processors' cacheable
- * data */
-static union {
- uint8_t __vo_data[CACHEALIGN_UP(sizeof(struct vo_data))];
- struct vo_data vo;
-} vo_raw CACHEALIGN_ATTR;
-#define vo vo_raw.vo
-#else
-static struct vo_data vo;
-#endif
-
-#if NUM_CORES > 1
-static struct mutex vo_mtx SHAREDBSS_ATTR;
-#endif
-
-static inline void video_lock_init(void)
-{
-#if NUM_CORES > 1
- rb->mutex_init(&vo_mtx);
-#endif
-}
-
-static inline void video_lock(void)
-{
-#if NUM_CORES > 1
- rb->mutex_lock(&vo_mtx);
-#endif
-}
-
-static inline void video_unlock(void)
-{
-#if NUM_CORES > 1
- rb->mutex_unlock(&vo_mtx);
-#endif
-}
-
-
-/* Draw a black rectangle if no video frame is available */
-static void vo_draw_black(struct vo_rect *rc)
-{
- int foreground;
- int x, y, w, h;
-
- video_lock();
-
- foreground = mylcd_get_foreground();
-
- mylcd_set_foreground(MYLCD_BLACK);
-
- if (rc)
- {
- x = rc->l;
- y = rc->t;
- w = rc->r - rc->l;
- h = rc->b - rc->t;
- }
- else
- {
-#if LCD_WIDTH >= LCD_HEIGHT
- x = vo.output_x;
- y = vo.output_y;
- w = vo.output_width;
- h = vo.output_height;
-#else
- x = LCD_WIDTH - vo.output_height - vo.output_y;
- y = vo.output_x;
- w = vo.output_height;
- h = vo.output_width;
-#endif
- }
-
- mylcd_fillrect(x, y, w, h);
- mylcd_update_rect(x, y, w, h);
-
- mylcd_set_foreground(foreground);
-
- video_unlock();
-}
-
-static inline void yuv_blit(uint8_t * const * buf, int src_x, int src_y,
- int stride, int x, int y, int width, int height)
-{
- video_lock();
-
-#ifdef HAVE_LCD_COLOR
- rb->lcd_blit_yuv(buf, src_x, src_y, stride, x, y , width, height);
-#else
- grey_ub_gray_bitmap_part(buf[0], src_x, src_y, stride, x, y, width, height);
-#endif
-
- video_unlock();
-}
-
-void vo_draw_frame(uint8_t * const * buf)
-{
- if ((vo.flags & (VO_NON_NULL_RECT | VO_VISIBLE)) !=
- (VO_NON_NULL_RECT | VO_VISIBLE))
- {
- /* Frame is hidden - either by being set invisible or is clipped
- * away - copout */
- DEBUGF("vo hidden\n");
- }
- else if (buf == NULL)
- {
- /* No frame exists - draw black */
- vo_draw_black(NULL);
- DEBUGF("vo no frame\n");
- }
- else
- {
- yuv_blit(buf, 0, 0, vo.image_width,
- vo.output_x, vo.output_y, vo.output_width,
- vo.output_height);
- }
-
- if (vo.post_draw_callback)
- vo.post_draw_callback();
-}
-
-static inline void vo_rect_clear_inl(struct vo_rect *rc)
-{
- rc->l = rc->t = rc->r = rc->b = 0;
-}
-
-static inline bool vo_rect_empty_inl(const struct vo_rect *rc)
-{
- return rc == NULL || rc->l >= rc->r || rc->t >= rc->b;
-}
-
-static inline bool vo_rects_intersect_inl(const struct vo_rect *rc1,
- const struct vo_rect *rc2)
-{
- return !vo_rect_empty_inl(rc1) &&
- !vo_rect_empty_inl(rc2) &&
- rc1->l < rc2->r && rc1->r > rc2->l &&
- rc1->t < rc2->b && rc1->b > rc2->t;
-}
-
-/* Sets all coordinates of a vo_rect to 0 */
-void vo_rect_clear(struct vo_rect *rc)
-{
- vo_rect_clear_inl(rc);
-}
-
-/* Returns true if left >= right or top >= bottom */
-bool vo_rect_empty(const struct vo_rect *rc)
-{
- return vo_rect_empty_inl(rc);
-}
-
-/* Initializes a vo_rect using upper-left corner and extents */
-void vo_rect_set_ext(struct vo_rect *rc, int x, int y,
- int width, int height)
-{
- rc->l = x;
- rc->t = y;
- rc->r = x + width;
- rc->b = y + height;
-}
-
-/* Query if two rectangles intersect */
-bool vo_rects_intersect(const struct vo_rect *rc1,
- const struct vo_rect *rc2)
-{
- return vo_rects_intersect_inl(rc1, rc2);
-}
-
-/* Intersect two rectangles, placing the result in rc_dst */
-bool vo_rect_intersect(struct vo_rect *rc_dst,
- const struct vo_rect *rc1,
- const struct vo_rect *rc2)
-{
- if (rc_dst != NULL)
- {
- if (vo_rects_intersect_inl(rc1, rc2))
- {
- rc_dst->l = MAX(rc1->l, rc2->l);
- rc_dst->r = MIN(rc1->r, rc2->r);
- rc_dst->t = MAX(rc1->t, rc2->t);
- rc_dst->b = MIN(rc1->b, rc2->b);
- return true;
- }
-
- vo_rect_clear_inl(rc_dst);
- }
-
- return false;
-}
-
-bool vo_rect_union(struct vo_rect *rc_dst,
- const struct vo_rect *rc1,
- const struct vo_rect *rc2)
-{
- if (rc_dst != NULL)
- {
- if (!vo_rect_empty_inl(rc1))
- {
- if (!vo_rect_empty_inl(rc2))
- {
- rc_dst->l = MIN(rc1->l, rc2->l);
- rc_dst->t = MIN(rc1->t, rc2->t);
- rc_dst->r = MAX(rc1->r, rc2->r);
- rc_dst->b = MAX(rc1->b, rc2->b);
- }
- else
- {
- *rc_dst = *rc1;
- }
-
- return true;
- }
- else if (!vo_rect_empty_inl(rc2))
- {
- *rc_dst = *rc2;
- return true;
- }
-
- vo_rect_clear_inl(rc_dst);
- }
-
- return false;
-}
-
-void vo_rect_offset(struct vo_rect *rc, int dx, int dy)
-{
- rc->l += dx;
- rc->t += dy;
- rc->r += dx;
- rc->b += dy;
-}
-
-/* Shink or stretch each axis - rotate counter-clockwise to retain upright
- * orientation on rotated displays (they rotate clockwise) */
-void stretch_image_plane(const uint8_t * src, uint8_t *dst, int stride,
- int src_w, int src_h, int dst_w, int dst_h)
-{
- uint8_t *dst_end = dst + dst_w*dst_h;
-
-#if LCD_WIDTH >= LCD_HEIGHT
- int src_w2 = src_w*2; /* 2x dimensions (for rounding before division) */
- int dst_w2 = dst_w*2;
- int src_h2 = src_h*2;
- int dst_h2 = dst_h*2;
- int qw = src_w2 / dst_w2; /* src-dst width ratio quotient */
- int rw = src_w2 - qw*dst_w2; /* src-dst width ratio remainder */
- int qh = src_h2 / dst_h2; /* src-dst height ratio quotient */
- int rh = src_h2 - qh*dst_h2; /* src-dst height ratio remainder */
- int dw = dst_w; /* Width error accumulator */
- int dh = dst_h; /* Height error accumulator */
-#else
- int src_w2 = src_w*2;
- int dst_w2 = dst_h*2;
- int src_h2 = src_h*2;
- int dst_h2 = dst_w*2;
- int qw = src_h2 / dst_w2;
- int rw = src_h2 - qw*dst_w2;
- int qh = src_w2 / dst_h2;
- int rh = src_w2 - qh*dst_h2;
- int dw = dst_h;
- int dh = dst_w;
-
- src += src_w - 1;
-#endif
-
- while (1)
- {
- const uint8_t *s = src;
-#if LCD_WIDTH >= LCD_HEIGHT
- uint8_t * const dst_line_end = dst + dst_w;
-#else
- uint8_t * const dst_line_end = dst + dst_h;
-#endif
- while (1)
- {
- *dst++ = *s;
-
- if (dst >= dst_line_end)
- {
- dw = dst_w;
- break;
- }
-
-#if LCD_WIDTH >= LCD_HEIGHT
- s += qw;
-#else
- s += qw*stride;
-#endif
- dw += rw;
-
- if (dw >= dst_w2)
- {
- dw -= dst_w2;
-#if LCD_WIDTH >= LCD_HEIGHT
- s++;
-#else
- s += stride;
-#endif
- }
- }
-
- if (dst >= dst_end)
- break;
-#if LCD_WIDTH >= LCD_HEIGHT
- src += qh*stride;
-#else
- src -= qh;
-#endif
- dh += rh;
-
- if (dh >= dst_h2)
- {
- dh -= dst_h2;
-#if LCD_WIDTH >= LCD_HEIGHT
- src += stride;
-#else
- src--;
-#endif
- }
- }
-}
-
-bool vo_draw_frame_thumb(uint8_t * const * buf, const struct vo_rect *rc)
-{
- void *mem;
- size_t bufsize = 0;
- uint8_t *yuv[3];
- struct vo_rect thumb_rc;
- int thumb_width, thumb_height;
-#ifdef HAVE_LCD_COLOR
- int thumb_uv_width, thumb_uv_height;
-#endif
-
- /* Obtain rectangle as clipped to the screen */
- vo_rect_set_ext(&thumb_rc, 0, 0, LCD_WIDTH, LCD_HEIGHT);
- if (!vo_rect_intersect(&thumb_rc, rc, &thumb_rc))
- return true;
-
- if (buf == NULL)
- goto no_thumb_exit;
-
- DEBUGF("thumb_rc: %d, %d, %d, %d\n", thumb_rc.l, thumb_rc.t,
- thumb_rc.r, thumb_rc.b);
-
- thumb_width = rc->r - rc->l;
- thumb_height = rc->b - rc->t;
-#ifdef HAVE_LCD_COLOR
- thumb_uv_width = thumb_width / 2;
- thumb_uv_height = thumb_height / 2;
-
- DEBUGF("thumb: w: %d h: %d uvw: %d uvh: %d\n", thumb_width,
- thumb_height, thumb_uv_width, thumb_uv_height);
-#else
- DEBUGF("thumb: w: %d h: %d\n", thumb_width, thumb_height);
-#endif
-
- /* Use remaining mpeg2 buffer as temp space */
- mem = mpeg2_get_buf(&bufsize);
-
- if (bufsize < (size_t)(thumb_width*thumb_height)
-#ifdef HAVE_LCD_COLOR
- + 2u*(thumb_uv_width * thumb_uv_height)
-#endif
- )
- {
- DEBUGF("thumb: insufficient buffer\n");
- goto no_thumb_exit;
- }
-
- yuv[0] = mem;
- stretch_image_plane(buf[0], yuv[0], vo.image_width,
- vo.display_width, vo.display_height,
- thumb_width, thumb_height);
-
-#ifdef HAVE_LCD_COLOR
- yuv[1] = yuv[0] + thumb_width*thumb_height;
- yuv[2] = yuv[1] + thumb_uv_width*thumb_uv_height;
-
- stretch_image_plane(buf[1], yuv[1], vo.image_width / 2,
- vo.display_width / 2, vo.display_height / 2,
- thumb_uv_width, thumb_uv_height);
-
- stretch_image_plane(buf[2], yuv[2], vo.image_width / 2,
- vo.display_width / 2, vo.display_height / 2,
- thumb_uv_width, thumb_uv_height);
-#endif
-
-#if LCD_WIDTH >= LCD_HEIGHT
- yuv_blit(yuv, 0, 0, thumb_width,
- thumb_rc.l, thumb_rc.t,
- thumb_rc.r - thumb_rc.l,
- thumb_rc.b - thumb_rc.t);
-#else
- yuv_blit(yuv, 0, 0, thumb_height,
- thumb_rc.t, thumb_rc.l,
- thumb_rc.b - thumb_rc.t,
- thumb_rc.r - thumb_rc.l);
-#endif /* LCD_WIDTH >= LCD_HEIGHT */
-
- return true;
-
-no_thumb_exit:
- vo_draw_black(&thumb_rc);
- return false;
-}
-
-void vo_setup(const mpeg2_sequence_t * sequence)
-{
- vo.image_width = sequence->width;
- vo.image_height = sequence->height;
- vo.display_width = sequence->display_width;
- vo.display_height = sequence->display_height;
-
- DEBUGF("vo_setup - w:%d h:%d\n", vo.display_width, vo.display_height);
-
- vo.image_chroma_x = vo.image_width / sequence->chroma_width;
- vo.image_chroma_y = vo.image_height / sequence->chroma_height;
-
- if (sequence->display_width >= SCREEN_WIDTH)
- {
- vo.rc_vid.l = 0;
- vo.rc_vid.r = SCREEN_WIDTH;
- }
- else
- {
- vo.rc_vid.l = (SCREEN_WIDTH - sequence->display_width) / 2;
-#ifdef HAVE_LCD_COLOR
- vo.rc_vid.l &= ~1;
-#endif
- vo.rc_vid.r = vo.rc_vid.l + sequence->display_width;
- }
-
- if (sequence->display_height >= SCREEN_HEIGHT)
- {
- vo.rc_vid.t = 0;
- vo.rc_vid.b = SCREEN_HEIGHT;
- }
- else
- {
- vo.rc_vid.t = (SCREEN_HEIGHT - sequence->display_height) / 2;
-#ifdef HAVE_LCD_COLOR
- vo.rc_vid.t &= ~1;
-#endif
- vo.rc_vid.b = vo.rc_vid.t + sequence->display_height;
- }
-
- vo_set_clip_rect(&vo.rc_clip);
-}
-
-void vo_dimensions(struct vo_ext *sz)
-{
- sz->w = vo.display_width;
- sz->h = vo.display_height;
-}
-
-bool vo_init(void)
-{
- vo.flags = 0;
- vo_rect_set_ext(&vo.rc_clip, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- video_lock_init();
- return true;
-}
-
-bool vo_show(bool show)
-{
- bool vis = vo.flags & VO_VISIBLE;
-
- if (show)
- vo.flags |= VO_VISIBLE;
- else
- vo.flags &= ~VO_VISIBLE;
-
- return vis;
-}
-
-bool vo_is_visible(void)
-{
- return vo.flags & VO_VISIBLE;
-}
-
-void vo_cleanup(void)
-{
- vo.flags = 0;
-}
-
-void vo_set_clip_rect(const struct vo_rect *rc)
-{
- struct vo_rect rc_out;
-
- if (rc == NULL)
- vo_rect_set_ext(&vo.rc_clip, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- else
- vo.rc_clip = *rc;
-
- if (!vo_rect_intersect(&rc_out, &vo.rc_vid, &vo.rc_clip))
- vo.flags &= ~VO_NON_NULL_RECT;
- else
- vo.flags |= VO_NON_NULL_RECT;
-
- vo.output_x = rc_out.l;
- vo.output_y = rc_out.t;
- vo.output_width = rc_out.r - rc_out.l;
- vo.output_height = rc_out.b - rc_out.t;
-}
-
-bool vo_get_clip_rect(struct vo_rect *rc)
-{
- rc->l = vo.output_x;
- rc->t = vo.output_y;
- rc->r = rc->l + vo.output_width;
- rc->b = rc->t + vo.output_height;
- return (vo.flags & VO_NON_NULL_RECT) != 0;
-}
-
-void vo_set_post_draw_callback(void (*cb)(void))
-{
- vo.post_draw_callback = cb;
-}
-
-#if NUM_CORES > 1
-void vo_lock(void)
-{
- video_lock();
-}
-
-void vo_unlock(void)
-{
- video_unlock();
-}
-#endif
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c
deleted file mode 100644
index 392cc6179f..0000000000
--- a/apps/plugins/mpegplayer/video_thread.c
+++ /dev/null
@@ -1,1059 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * mpegplayer video thread implementation
- *
- * Copyright (c) 2007 Michael Sevakis
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "mpegplayer.h"
-#include "libmpeg2/mpeg2dec_config.h"
-#include "lib/grey.h"
-#include "video_out.h"
-#include "mpeg_settings.h"
-
-/** Video stream and thread **/
-
-/* Video thread data passed around to its various functions */
-struct video_thread_data
-{
- /* Stream data */
- mpeg2dec_t *mpeg2dec; /* Our video decoder */
- const mpeg2_info_t *info; /* Info about video stream */
- int state; /* Thread state */
- int status; /* Media status */
- struct queue_event ev;/* Our event queue to receive commands */
- /* Operational info */
- uint32_t stream_time; /* Current time from beginning of stream */
- uint32_t goal_time; /* Scheduled time of current frame */
- int32_t remain_time; /* T-minus value to frame_time (-:early, +:late) */
- int skip_ref_pics; /* Severe skipping - wait for I-frame */
- int skip_level; /* Number of frames still to skip */
- int num_picture; /* Number of picture headers read */
- int num_intra; /* Number of I-picture headers read */
- int group_est; /* Estmated number remaining as of last I */
- long last_render; /* Last time a frame was drawn */
- /* Sync info */
- uint32_t frame_time; /* Current due time of frame (unadjusted) */
- uint32_t frame_period; /* Frame period in clock ticks */
- int num_ref_pics; /* Number of I and P frames since sync/skip */
- int syncf_perfect; /* Last sync fit result */
-};
-
-/* Number drawn since reset */
-static int video_num_drawn SHAREDBSS_ATTR;
-/* Number skipped since reset */
-static int video_num_skipped SHAREDBSS_ATTR;
-
-/* TODO: Check if 4KB is appropriate - it works for my test streams,
- so maybe we can reduce it. */
-#define VIDEO_STACKSIZE (4*1024)
-static uint32_t video_stack[VIDEO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR;
-static struct event_queue video_str_queue SHAREDBSS_ATTR;
-static struct queue_sender_list video_str_queue_send SHAREDBSS_ATTR;
-struct stream video_str IBSS_ATTR;
-
-#define DEFAULT_GOP_SIZE INT_MAX /* no I/P skips until it learns */
-#define DROP_THRESHOLD (100*TS_SECOND/1000)
-#define MAX_EARLINESS (120*TS_SECOND/1000)
-
-#if defined(DEBUG) || defined(SIMULATOR)
-static unsigned char pic_coding_type_char(unsigned type)
-{
- switch (type)
- {
- case PIC_FLAG_CODING_TYPE_I:
- return 'I'; /* Intra-coded */
- case PIC_FLAG_CODING_TYPE_P:
- return 'P'; /* Forward-predicted */
- case PIC_FLAG_CODING_TYPE_B:
- return 'B'; /* Bidirectionally-predicted */
- case PIC_FLAG_CODING_TYPE_D:
- return 'D'; /* DC-coded */
- default:
- return '?'; /* Say what? */
- }
-}
-#endif /* defined(DEBUG) || defined(SIMULATOR) */
-
-/* Multi-use:
- * 1) Find the sequence header and initialize video out
- * 2) Find the end of the final frame
- */
-static int video_str_scan(struct video_thread_data *td,
- struct str_sync_data *sd)
-{
- int retval = STREAM_ERROR;
- uint32_t time = INVALID_TIMESTAMP;
- uint32_t period = 0;
- struct stream tmp_str;
-
- tmp_str.id = video_str.id;
- tmp_str.hdr.pos = sd->sk.pos;
- tmp_str.hdr.limit = sd->sk.pos + sd->sk.len;
-
- /* Fully reset if obtaining size for a new stream */
- mpeg2_reset(td->mpeg2dec, td->ev.id == VIDEO_GET_SIZE);
- mpeg2_skip(td->mpeg2dec, 1);
-
- while (1)
- {
- mpeg2_state_t mp2state = mpeg2_parse(td->mpeg2dec);
- rb->yield();
-
- switch (mp2state)
- {
- case STATE_BUFFER:
- switch (parser_get_next_data(&tmp_str, STREAM_PM_RANDOM_ACCESS))
- {
- case STREAM_DATA_END:
- DEBUGF("video_stream_scan:STREAM_DATA_END\n");
- goto scan_finished;
-
- case STREAM_OK:
- if (tmp_str.pkt_flags & PKT_HAS_TS)
- mpeg2_tag_picture(td->mpeg2dec, tmp_str.pts, 0);
-
- mpeg2_buffer(td->mpeg2dec, tmp_str.curr_packet,
- tmp_str.curr_packet_end);
- td->info = mpeg2_info(td->mpeg2dec);
- break;
- }
- break;
-
- case STATE_SEQUENCE:
- DEBUGF("video_stream_scan:STATE_SEQUENCE\n");
- vo_setup(td->info->sequence);
-
- if (td->ev.id == VIDEO_GET_SIZE)
- {
- retval = STREAM_OK;
- goto scan_finished;
- }
- break;
-
- case STATE_SLICE:
- case STATE_END:
- case STATE_INVALID_END:
- {
- if (td->info->display_picture == NULL)
- break;
-
- switch (td->ev.id)
- {
- case STREAM_SYNC:
- retval = STREAM_OK;
- goto scan_finished;
-
- case STREAM_FIND_END_TIME:
- if (td->info->display_picture->flags & PIC_FLAG_TAGS)
- time = td->info->display_picture->tag;
- else if (time != INVALID_TIMESTAMP)
- time += period;
-
- period = TC_TO_TS(td->info->sequence->frame_period);
- break;
- }
-
- break;
- }
-
- default:
- break;
- }
- }
-
-scan_finished:
-
- if (td->ev.id == STREAM_FIND_END_TIME)
- {
- if (time != INVALID_TIMESTAMP)
- {
- sd->time = time + period;
- retval = STREAM_PERFECT_MATCH;
- }
- else
- {
- retval = STREAM_NOT_FOUND;
- }
- }
-
- mpeg2_skip(td->mpeg2dec, 0);
- return retval;
-}
-
-static bool init_sequence(struct video_thread_data *td)
-{
- struct str_sync_data sd;
-
- sd.time = 0; /* Ignored */
- sd.sk.pos = 0;
- sd.sk.len = 1024*1024;
- sd.sk.dir = SSCAN_FORWARD;
-
- return video_str_scan(td, &sd) == STREAM_OK;
-}
-
-static bool check_needs_sync(struct video_thread_data *td, uint32_t time)
-{
- uint32_t end_time;
-
- DEBUGF("check_needs_sync:\n");
- if (td->info == NULL || td->info->display_fbuf == NULL)
- {
- DEBUGF(" no fbuf\n");
- return true;
- }
-
- if (td->syncf_perfect == 0)
- {
- DEBUGF(" no frame\n");
- return true;
- }
-
- time = clip_time(&video_str, time);
- end_time = td->frame_time + td->frame_period;
-
- DEBUGF(" sft:%u t:%u sfte:%u\n", (unsigned)td->frame_time,
- (unsigned)time, (unsigned)end_time);
-
- if (time < td->frame_time)
- return true;
-
- if (time >= end_time)
- return time < video_str.end_pts || end_time < video_str.end_pts;
-
- return false;
-}
-
-/* Do any needed decoding/slide up to the specified time */
-static int sync_decoder(struct video_thread_data *td,
- struct str_sync_data *sd)
-{
- int retval = STREAM_ERROR;
- uint32_t time = clip_time(&video_str, sd->time);
-
- td->syncf_perfect = 0;
- td->frame_time = 0;
- td->frame_period = 0;
- td->num_ref_pics = 0;
-
- /* Sometimes theres no sequence headers nearby and libmpeg2 may have reset
- * fully at some point */
- if ((td->info == NULL || td->info->sequence == NULL) && !init_sequence(td))
- {
- DEBUGF("sync_decoder=>init_sequence failed\n");
- goto sync_finished;
- }
-
- video_str.hdr.pos = sd->sk.pos;
- video_str.hdr.limit = sd->sk.pos + sd->sk.len;
- mpeg2_reset(td->mpeg2dec, false);
- mpeg2_skip(td->mpeg2dec, 1);
-
- while (1)
- {
- mpeg2_state_t mp2state = mpeg2_parse(td->mpeg2dec);
-
- switch (mp2state)
- {
- case STATE_BUFFER:
- switch (parser_get_next_data(&video_str, STREAM_PM_RANDOM_ACCESS))
- {
- case STREAM_DATA_END:
- DEBUGF("sync_decoder:STR_DATA_END\n");
- if (td->info && td->info->display_picture &&
- !(td->info->display_picture->flags & PIC_FLAG_SKIP))
- {
- /* No frame matching the time was found up to the end of
- * the stream - consider a perfect match since no better
- * can be made */
- retval = STREAM_PERFECT_MATCH;
- td->syncf_perfect = 1;
- }
- goto sync_finished;
-
- case STREAM_OK:
- if (video_str.pkt_flags & PKT_HAS_TS)
- mpeg2_tag_picture(td->mpeg2dec, video_str.pts, 0);
- mpeg2_buffer(td->mpeg2dec, video_str.curr_packet,
- video_str.curr_packet_end);
- td->info = mpeg2_info(td->mpeg2dec);
- break;
- }
- break;
-
- case STATE_SEQUENCE:
- DEBUGF(" STATE_SEQUENCE\n");
- vo_setup(td->info->sequence);
- break;
-
- case STATE_GOP:
- DEBUGF(" STATE_GOP: (%s)\n",
- (td->info->gop->flags & GOP_FLAG_CLOSED_GOP) ?
- "closed" : "open");
- break;
-
- case STATE_PICTURE:
- {
- int type = td->info->current_picture->flags
- & PIC_MASK_CODING_TYPE;
-
- switch (type)
- {
- case PIC_FLAG_CODING_TYPE_I:
- /* I-frame; start decoding */
- mpeg2_skip(td->mpeg2dec, 0);
- td->num_ref_pics++;
- break;
-
- case PIC_FLAG_CODING_TYPE_P:
- /* P-frames don't count without I-frames */
- if (td->num_ref_pics > 0)
- td->num_ref_pics++;
- break;
- }
-
- if (td->info->current_picture->flags & PIC_FLAG_TAGS)
- {
- DEBUGF(" STATE_PICTURE (%c): %u\n", pic_coding_type_char(type),
- (unsigned)td->info->current_picture->tag);
- }
- else
- {
- DEBUGF(" STATE_PICTURE (%c): -\n", pic_coding_type_char(type));
- }
-
- break;
- }
-
- case STATE_SLICE:
- case STATE_END:
- case STATE_INVALID_END:
- {
- uint32_t end_time;
-
- if (td->info->display_picture == NULL)
- {
- DEBUGF(" td->info->display_picture == NULL\n");
- break; /* No picture */
- }
-
- int type = td->info->display_picture->flags
- & PIC_MASK_CODING_TYPE;
-
- if (td->info->display_picture->flags & PIC_FLAG_TAGS)
- {
- td->frame_time = td->info->display_picture->tag;
- DEBUGF(" frame tagged:%u (%c%s)\n", (unsigned)td->frame_time,
- pic_coding_type_char(type),
- (td->info->display_picture->flags & PIC_FLAG_SKIP) ?
- " skipped" : "");
- }
- else
- {
- td->frame_time += td->frame_period;
- DEBUGF(" add frame_period:%u (%c%s)\n", (unsigned)td->frame_time,
- pic_coding_type_char(type),
- (td->info->display_picture->flags & PIC_FLAG_SKIP) ?
- " skipped" : "");
- }
-
- td->frame_period = TC_TO_TS(td->info->sequence->frame_period);
- end_time = td->frame_time + td->frame_period;
-
- DEBUGF(" ft:%u t:%u fe:%u (%c%s)",
- (unsigned)td->frame_time,
- (unsigned)time,
- (unsigned)end_time,
- pic_coding_type_char(type),
- (td->info->display_picture->flags & PIC_FLAG_SKIP) ?
- " skipped" : "");
-
- if (end_time <= time && end_time < video_str.end_pts)
- {
- /* Still too early and have not hit at EOS */
- DEBUGF(" too early\n");
- break;
- }
- else if (!(td->info->display_picture->flags & PIC_FLAG_SKIP))
- {
- /* One perfect point if dependent frames were decoded */
- switch (type)
- {
- case PIC_FLAG_CODING_TYPE_B:
- if (td->num_ref_pics > 1)
- {
- case PIC_FLAG_CODING_TYPE_P:
- if (td->num_ref_pics > 0)
- {
- case PIC_FLAG_CODING_TYPE_I:
- td->syncf_perfect = 1;
- break;
- }
- }
- }
-
- if ((td->frame_time <= time && time < end_time) ||
- end_time >= video_str.end_pts)
- {
- /* One perfect point for matching time goal */
- DEBUGF(" ft<=tsyncf_perfect++;
- }
- else
- {
- DEBUGF(" ft>t\n");
- }
-
- /* Two or more perfect points = perfect match - yay! */
- retval = (td->syncf_perfect >= 2) ?
- STREAM_PERFECT_MATCH : STREAM_MATCH;
- }
- else
- {
- /* Too late, no I-Frame yet */
- DEBUGF("\n");
- }
-
- goto sync_finished;
- }
-
- default:
- break;
- }
-
- rb->yield();
- } /* end while */
-
-sync_finished:
- mpeg2_skip(td->mpeg2dec, 0);
- return retval;
-}
-
-static bool frame_print_handler(struct video_thread_data *td)
-{
- bool retval;
- uint8_t * const * buf = NULL;
-
- if (td->info != NULL && td->info->display_fbuf != NULL &&
- td->syncf_perfect > 0)
- buf = td->info->display_fbuf->buf;
-
- if (td->ev.id == VIDEO_PRINT_THUMBNAIL)
- {
- /* Print a thumbnail of whatever was last decoded - scale and
- * position to fill the specified rectangle */
- retval = vo_draw_frame_thumb(buf, (struct vo_rect *)td->ev.data);
- }
- else
- {
- /* Print the last frame decoded */
- vo_draw_frame(buf);
- retval = buf != NULL;
- }
-
- return retval;
-}
-
-/* This only returns to play or quit */
-static void video_thread_msg(struct video_thread_data *td)
-{
- while (1)
- {
- intptr_t reply = 0;
-
- switch (td->ev.id)
- {
- case STREAM_PLAY:
- td->status = STREAM_PLAYING;
-
- switch (td->state)
- {
- case TSTATE_INIT:
- /* Begin decoding state */
- td->state = TSTATE_DECODE;
- /* */
- case TSTATE_DECODE:
- if (td->syncf_perfect <= 0)
- break;
- /* There should be a frame already, just draw it */
- td->goal_time = td->frame_time;
- td->state = TSTATE_RENDER_WAIT;
- /* */
- case TSTATE_RENDER_WAIT:
- /* Settings may have changed to nonlimited - just draw
- * what was previously being waited for */
- td->stream_time = TICKS_TO_TS(stream_get_time());
- if (!settings.limitfps)
- td->state = TSTATE_RENDER;
- /* */
- case TSTATE_RENDER:
- break;
-
- case TSTATE_EOS:
- /* At end of stream - no playback possible so fire the
- * completion event */
- stream_generate_event(&video_str, STREAM_EV_COMPLETE, 0);
- break;
- }
-
- reply = td->state != TSTATE_EOS;
- break;
-
- case STREAM_PAUSE:
- td->status = STREAM_PAUSED;
- reply = td->state != TSTATE_EOS;
- break;
-
- case STREAM_STOP:
- if (td->state == TSTATE_DATA)
- stream_clear_notify(&video_str, DISK_BUF_DATA_NOTIFY);
-
- td->status = STREAM_STOPPED;
- td->state = TSTATE_EOS;
- reply = true;
- break;
-
- case VIDEO_DISPLAY_IS_VISIBLE:
- reply = vo_is_visible();
- break;
-
- case VIDEO_DISPLAY_SHOW:
- /* Show video and draw the last frame we had if any or reveal the
- * underlying framebuffer if hiding */
- reply = vo_show(!!td->ev.data);
-
-#ifdef HAVE_LCD_COLOR
- /* Match graylib behavior as much as possible */
- if (!td->ev.data == !reply)
- break;
-
- if (td->ev.data)
- {
- frame_print_handler(td);
- }
- else
- {
- IF_COP(rb->commit_discard_dcache());
- vo_lock();
- rb->lcd_update();
- vo_unlock();
- }
-#endif
- break;
-
- case STREAM_RESET:
- if (td->state == TSTATE_DATA)
- stream_clear_notify(&video_str, DISK_BUF_DATA_NOTIFY);
-
- td->state = TSTATE_INIT;
- td->status = STREAM_STOPPED;
-
- /* Reset operational info but not sync info */
- td->stream_time = UINT32_MAX;
- td->goal_time = 0;
- td->remain_time = 0;
- td->skip_ref_pics = 0;
- td->skip_level = 0;
- td->num_picture = 0;
- td->num_intra = 0;
- td->group_est = DEFAULT_GOP_SIZE;
- td->last_render = *rb->current_tick - HZ;
- video_num_drawn = 0;
- video_num_skipped = 0;
-
- reply = true;
- break;
-
- case STREAM_NEEDS_SYNC:
- reply = check_needs_sync(td, td->ev.data);
- break;
-
- case STREAM_SYNC:
- if (td->state == TSTATE_INIT)
- reply = sync_decoder(td, (struct str_sync_data *)td->ev.data);
- break;
-
- case DISK_BUF_DATA_NOTIFY:
- /* Our bun is done */
- if (td->state != TSTATE_DATA)
- break;
-
- td->state = TSTATE_DECODE;
- str_data_notify_received(&video_str);
- break;
-
- case VIDEO_PRINT_FRAME:
- case VIDEO_PRINT_THUMBNAIL:
- reply = frame_print_handler(td);
- break;
-
- case VIDEO_SET_CLIP_RECT:
- vo_set_clip_rect((const struct vo_rect *)td->ev.data);
- break;
-
- case VIDEO_GET_CLIP_RECT:
- reply = vo_get_clip_rect((struct vo_rect *)td->ev.data);
- break;
-
- case VIDEO_GET_SIZE:
- {
- if (td->state != TSTATE_INIT)
- break; /* Can only use after a reset was issued */
-
- /* This will reset the decoder in full for this particular event */
- if (init_sequence(td))
- {
- reply = true;
- vo_dimensions((struct vo_ext *)td->ev.data);
- }
- break;
- }
-
- case STREAM_FIND_END_TIME:
- if (td->state != TSTATE_INIT)
- {
- reply = STREAM_ERROR;
- break;
- }
-
- reply = video_str_scan(td, (struct str_sync_data *)td->ev.data);
- break;
-
- case VIDEO_SET_POST_FRAME_CALLBACK:
- vo_set_post_draw_callback((void (*)(void))td->ev.data);
- reply = true;
- break;
-
- case STREAM_QUIT:
- /* Time to go - make thread exit */
- td->state = TSTATE_EOS;
- return;
- }
-
- str_reply_msg(&video_str, reply);
-
- if (td->status == STREAM_PLAYING)
- {
- switch (td->state)
- {
- case TSTATE_DECODE:
- case TSTATE_RENDER:
- case TSTATE_RENDER_WAIT:
- /* These return when in playing state */
- return;
- }
- }
-
- str_get_msg(&video_str, &td->ev);
- }
-}
-
-static void video_thread(void)
-{
- struct video_thread_data td;
-
- memset(&td, 0, sizeof (td));
- td.mpeg2dec = mpeg2_init();
- td.status = STREAM_STOPPED;
- td.state = TSTATE_EOS;
-
- if (td.mpeg2dec == NULL)
- {
- td.status = STREAM_ERROR;
- /* Loop and wait for quit message */
- while (1)
- {
- str_get_msg(&video_str, &td.ev);
- if (td.ev.id == STREAM_QUIT)
- return;
- str_reply_msg(&video_str, STREAM_ERROR);
- }
- }
-
- vo_init();
-
- goto message_wait;
-
- while (1)
- {
- mpeg2_state_t mp2state;
- td.state = TSTATE_DECODE;
-
- /* Check for any pending messages and process them */
- if (str_have_msg(&video_str))
- {
- message_wait:
- /* Wait for a message to be queued */
- str_get_msg(&video_str, &td.ev);
-
- message_process:
- /* Process a message already dequeued */
- video_thread_msg(&td);
-
- switch (td.state)
- {
- /* These states are the only ones that should return */
- case TSTATE_DECODE: goto picture_decode;
- case TSTATE_RENDER: goto picture_draw;
- case TSTATE_RENDER_WAIT: goto picture_wait;
- /* Anything else is interpreted as an exit */
- default: goto video_exit;
- }
- }
-
- picture_decode:
- mp2state = mpeg2_parse (td.mpeg2dec);
-
- switch (mp2state)
- {
- case STATE_BUFFER:
- /* Request next packet data */
- switch (parser_get_next_data(&video_str, STREAM_PM_STREAMING))
- {
- case STREAM_DATA_NOT_READY:
- /* Wait for data to be buffered */
- td.state = TSTATE_DATA;
- goto message_wait;
-
- case STREAM_DATA_END:
- /* No more data. */
- td.state = TSTATE_EOS;
- if (td.status == STREAM_PLAYING)
- stream_generate_event(&video_str, STREAM_EV_COMPLETE, 0);
- goto message_wait;
-
- case STREAM_OK:
- if (video_str.pkt_flags & PKT_HAS_TS)
- mpeg2_tag_picture(td.mpeg2dec, video_str.pts, 0);
-
- mpeg2_buffer(td.mpeg2dec, video_str.curr_packet,
- video_str.curr_packet_end);
- td.info = mpeg2_info(td.mpeg2dec);
- break;
- }
- break;
-
- case STATE_SEQUENCE:
- /* New video sequence, inform output of any changes */
- vo_setup(td.info->sequence);
- break;
-
- case STATE_PICTURE:
- {
- /* This is not in presentation order - do our best anyway */
- int skip = td.skip_ref_pics;
-
- /* Frame type: I/P/B/D */
- switch (td.info->current_picture->flags & PIC_MASK_CODING_TYPE)
- {
- case PIC_FLAG_CODING_TYPE_I:
- if (++td.num_intra >= 2)
- td.group_est = td.num_picture / (td.num_intra - 1);
-
- /* Things are extremely late and all frames will be
- dropped until the next key frame */
- if (td.skip_level > 0 && td.skip_level >= td.group_est)
- {
- td.skip_level--; /* skip frame */
- skip = td.skip_ref_pics = 1; /* wait for I-frame */
- td.num_ref_pics = 0;
- }
- else if (skip != 0)
- {
- skip = td.skip_ref_pics = 0; /* now, decode */
- td.num_ref_pics = 1;
- }
- break;
-
- case PIC_FLAG_CODING_TYPE_P:
- if (skip == 0)
- {
- td.num_ref_pics++;
-
- /* If skip_level at least the estimated number of frames
- left in I-I span, skip until next I-frame */
- if (td.group_est > 0 && td.skip_level >= td.group_est)
- {
- skip = td.skip_ref_pics = 1; /* wait for I-frame */
- td.num_ref_pics = 0;
- }
- }
-
- if (skip != 0)
- td.skip_level--;
- break;
-
- case PIC_FLAG_CODING_TYPE_B:
- /* We want to drop something, so this B-frame won't even be
- decoded. Drawing can happen on the next frame if so desired
- so long as the B-frames were not dependent upon those from
- a previous open GOP where the needed reference frames were
- skipped */
- if (td.skip_level > 0 || td.num_ref_pics < 2)
- {
- skip = 1;
- td.skip_level--;
- }
- break;
-
- default:
- skip = 1;
- break;
- }
-
- if (td.num_intra > 0)
- td.num_picture++;
-
- td.group_est--;
-
- mpeg2_skip(td.mpeg2dec, skip);
- break;
- }
-
- case STATE_SLICE:
- case STATE_END:
- case STATE_INVALID_END:
- {
- int32_t offset; /* Tick adjustment to keep sync */
-
- if (td.info->display_fbuf == NULL)
- break; /* No picture */
-
- /* Get presentation times in audio samples - quite accurate
- enough - add previous frame duration if not stamped */
- if (td.info->display_picture->flags & PIC_FLAG_TAGS)
- td.frame_time = td.info->display_picture->tag;
- else
- td.frame_time += td.frame_period;
-
- td.frame_period = TC_TO_TS(td.info->sequence->frame_period);
-
- if (!settings.limitfps)
- {
- /* No limiting => no dropping or waiting - draw this frame */
- td.remain_time = 0;
- td.skip_level = 0;
- td.syncf_perfect = 1; /* have frame */
- goto picture_draw;
- }
-
- td.goal_time = td.frame_time;
- td.stream_time = TICKS_TO_TS(stream_get_time());
-
- /* How early/late are we? > 0 = late, < 0 early */
- offset = td.stream_time - td.goal_time;
-
- if (offset >= 0)
- {
- /* Late or on-time */
- if (td.remain_time < 0)
- td.remain_time = 0; /* now, late */
-
- offset = AVERAGE(td.remain_time, offset, 4);
- td.remain_time = offset;
- }
- else
- {
- /* Early */
- if (td.remain_time >= 0)
- td.remain_time = 0; /* now, early */
- else if (offset > td.remain_time)
- td.remain_time = MAX(offset, -MAX_EARLINESS); /* less early */
- else if (td.remain_time != 0)
- td.remain_time = AVERAGE(td.remain_time, 0, 8); /* earlier/same */
- /* else there's been no frame drop */
-
- offset = -td.remain_time;
- }
-
- /* Skip anything not decoded */
- if (td.info->display_picture->flags & PIC_FLAG_SKIP)
- goto picture_skip;
-
- td.syncf_perfect = 1; /* have frame (assume so from now on) */
-
- /* Keep goal_time >= 0 */
- if ((uint32_t)offset > td.goal_time)
- offset = td.goal_time;
-
- td.goal_time -= offset;
-
- if (!settings.skipframes)
- {
- /* No skipping - just wait if we're early and correct for
- lateness as much as possible. */
- td.skip_level = 0;
- goto picture_wait;
- }
-
- /** Possibly skip this frame **/
-
- /* Frameskipping has the following order of preference:
- *
- * Frame Type Who Notes/Rationale
- * B decoder arbitrarily drop - no decode or draw
- * Any renderer arbitrarily drop - I/P unless B decoded
- * P decoder must wait for I-frame
- * I decoder must wait for I-frame
- *
- * If a frame can be drawn and it has been at least 1/2 second,
- * the image will be updated no matter how late it is just to
- * avoid looking stuck.
- */
- if (td.skip_level > 0 &&
- TIME_BEFORE(*rb->current_tick, td.last_render + HZ/2))
- {
- /* Frame skip was set previously but either there wasn't anything
- dropped yet or not dropped enough. So we quit at least rendering
- the actual frame to avoid further increase of a/v-drift. */
- td.skip_level--;
- goto picture_skip;
- }
-
- /* At this point a frame _will_ be drawn - a skip may happen on
- the next however */
-
- /* Calculate number of frames to drop/skip - allow brief periods
- of lateness before producing skips */
- td.skip_level = 0;
- if (td.remain_time > 0 && (uint32_t)offset > DROP_THRESHOLD)
- {
- td.skip_level = (offset - DROP_THRESHOLD + td.frame_period)
- / td.frame_period;
- }
-
- picture_wait:
- td.state = TSTATE_RENDER_WAIT;
-
- /* Wait until time catches up */
- while (1)
- {
- int32_t twait = td.goal_time - td.stream_time;
- /* Watch for messages while waiting for the frame time */
-
- if (twait <= 0)
- break;
-
- if (twait > TS_SECOND/HZ)
- {
- /* Several ticks to wait - do some sleeping */
- int timeout = (twait - HZ) / (TS_SECOND/HZ);
- str_get_msg_w_tmo(&video_str, &td.ev, MAX(timeout, 1));
- if (td.ev.id != SYS_TIMEOUT)
- goto message_process;
- }
- else
- {
- /* Just a little left - spin and be accurate */
- rb->yield();
- if (str_have_msg(&video_str))
- goto message_wait;
- }
-
- td.stream_time = TICKS_TO_TS(stream_get_time());
- }
-
- picture_draw:
- /* Record last frame time */
- td.last_render = *rb->current_tick;
-
- vo_draw_frame(td.info->display_fbuf->buf);
- video_num_drawn++;
- break;
-
- picture_skip:
- if (td.remain_time <= DROP_THRESHOLD)
- {
- td.skip_level = 0;
- if (td.remain_time <= 0)
- td.remain_time = INT32_MIN;
- }
-
- video_num_skipped++;
- break;
- }
-
- default:
- break;
- }
-
- rb->yield();
- } /* end while */
-
-video_exit:
- vo_cleanup();
- mpeg2_close(td.mpeg2dec);
-}
-
-/* Initializes the video thread */
-bool video_thread_init(void)
-{
- intptr_t rep;
-
- IF_COP(rb->commit_dcache());
-
- video_str.hdr.q = &video_str_queue;
- rb->queue_init(video_str.hdr.q, false);
-
- /* We put the video thread on another processor for multi-core targets. */
- video_str.thread = rb->create_thread(
- video_thread, video_stack, VIDEO_STACKSIZE, 0,
- "mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, COP));
-
- rb->queue_enable_queue_send(video_str.hdr.q, &video_str_queue_send,
- video_str.thread);
-
- if (video_str.thread == 0)
- return false;
-
- /* Wait for thread to initialize */
- rep = str_send_msg(&video_str, STREAM_NULL, 0);
- IF_COP(rb->commit_discard_dcache());
-
- return rep == 0; /* Normally STREAM_NULL should be ignored */
-}
-
-/* Terminates the video thread */
-void video_thread_exit(void)
-{
- if (video_str.thread != 0)
- {
- str_post_msg(&video_str, STREAM_QUIT, 0);
- rb->thread_wait(video_str.thread);
- IF_COP(rb->commit_discard_dcache());
- video_str.thread = 0;
- }
-}
-
-
-/** Misc **/
-void video_thread_get_stats(struct video_output_stats *s)
-{
- uint32_t start;
- uint32_t now = stream_get_ticks(&start);
- s->num_drawn = video_num_drawn;
- s->num_skipped = video_num_skipped;
-
- s->fps = 0;
-
- if (now > start)
- s->fps = muldiv_uint32(CLOCK_RATE*100, s->num_drawn, now - start);
-}
-
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 8d266966d0..26c1543fdd 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -71,10 +71,6 @@ wav,viewers/wavview,10
wav,viewers/wav2wv,-
wav,viewers/mp3_encoder,-
wav,viewers/test_codec,-
-mpg,viewers/mpegplayer,4
-mpeg,viewers/mpegplayer,4
-mpv,viewers/mpegplayer,4
-m2v,viewers/mpegplayer,4
iriver,viewers/iriver_flash,3
tap,viewers/zxbox,12
opx,viewers/open_plugins,-
diff --git a/docs/MAINTAINERS b/docs/MAINTAINERS
index 143e6fa2b4..2771adb7ad 100644
--- a/docs/MAINTAINERS
+++ b/docs/MAINTAINERS
@@ -189,7 +189,6 @@ Plugins
:minesweeper: Antoine Cellerier
:mosaique:
:mp3_encoder:
-:mpegplayer: Michael Sevakis
:nim:
:oscilloscope: Jens Arnold
:pacbox: Dave Chapman
diff --git a/lib/rbcodec/codecs/libmad/libmad.make b/lib/rbcodec/codecs/libmad/libmad.make
index 6c50e1d201..479dd54773 100644
--- a/lib/rbcodec/codecs/libmad/libmad.make
+++ b/lib/rbcodec/codecs/libmad/libmad.make
@@ -7,16 +7,9 @@
# $Id$
#
-# we need to build two different mad libraries
-# (one for codec, one for mpegplayer)
-# so a little trickery is necessary
-
MADFLAGS = $(CODECFLAGS) -I$(RBCODECLIB_DIR)/codecs/libmad
MADFLAGS += -UDEBUG -DNDEBUG -DHAVE_LIMITS_H -DHAVE_ASSERT_H
-# MPEGplayer
-MPEGMADFLAGS = $(MADFLAGS) -DMPEGPLAYER
-
# libmad
MADLIB := $(CODECDIR)/libmad.a
MADLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libmad/SOURCES)
@@ -27,26 +20,8 @@ $(MADLIB): $(MADLIB_OBJ)
$(SILENT)$(shell rm -f $@)
$(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
-# libmad-mpeg
-MPEGMADLIB := $(CODECDIR)/libmad-mpeg.a
-MPEGMADLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libmad/SOURCES)
-MPEGMADLIB_OBJ := $(addsuffix .o,$(basename $(subst $(RBCODECLIB_DIR)/codecs/libmad,$(RBCODEC_BLD)/codecs/libmad-mpeg,$(MPEGMADLIB_SRC))))
-
-$(MPEGMADLIB): $(MPEGMADLIB_OBJ)
- $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
-
# pattern rules
-$(CODECDIR)/libmad-mpeg/%.o : $(RBCODECLIB_DIR)/codecs/libmad/%.c
- $(SILENT)mkdir -p $(dir $@)
- $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<)) \
- $(CC) $(MPEGMADFLAGS) -c $< -o $@
-
-$(CODECDIR)/libmad-mpeg/%.o : $(RBCODECLIB_DIR)/codecs/libmad/%.S
- $(SILENT)mkdir -p $(dir $@)
- $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<)) \
- $(CC) $(MPEGMADFLAGS) -c $< -o $@
-
$(CODECDIR)/libmad/%.o: $(RBCODECLIB_DIR)/codecs/libmad/%.c
$(SILENT)mkdir -p $(dir $@)
$(call PRINTS,CC $(subst $(ROOTDIR)/,,$<)) \
diff --git a/lib/rbcodec/codecs/libmad/mad_iram.h b/lib/rbcodec/codecs/libmad/mad_iram.h
index ac0b64cca9..5a315c0381 100644
--- a/lib/rbcodec/codecs/libmad/mad_iram.h
+++ b/lib/rbcodec/codecs/libmad/mad_iram.h
@@ -35,10 +35,9 @@
#define ICODE_ATTR_MPA_SYNTH
#define ICONST_ATTR_MPA_HUFFMAN
#else
-/* Code performs slower in IRAM on PP502x and there is no space in
- mpegplayer on the PP5002. S3C2440 doesn't have any IRAM available for
- codecs */
-#if defined(CPU_PP502x) || (CONFIG_CPU == PP5002 && defined(MPEGPLAYER))
+/* Code performs slower in IRAM on PP502x
+ S3C2440 doesn't have any IRAM available for codecs */
+#if defined(CPU_PP502x)
#define ICODE_SECTION_MPA_ARM .text
#define ICODE_ATTR_MPA_SYNTH
#else
diff --git a/lib/rbcodec/codecs/mpa.c b/lib/rbcodec/codecs/mpa.c
index d6bcc04910..db33f17c3b 100644
--- a/lib/rbcodec/codecs/mpa.c
+++ b/lib/rbcodec/codecs/mpa.c
@@ -26,7 +26,7 @@
CODEC_HEADER
-#if NUM_CORES > 1 && !defined(MPEGPLAYER)
+#if NUM_CORES > 1
#define MPA_SYNTH_ON_COP
#endif
diff --git a/manual/plugins/main.tex b/manual/plugins/main.tex
index 3348b1fce5..73cc1a2ada 100644
--- a/manual/plugins/main.tex
+++ b/manual/plugins/main.tex
@@ -201,8 +201,6 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).}
\nopt{lowmem}{\input{plugins/midiplay.tex}}
\nopt{lowmem}{\input{plugins/mikmod.tex}}
-\nopt{lowmem}{\input{plugins/mpegplayer.tex}}
-
\input{plugins/mp3_encoder.tex}
\opt{iriverh300,iriverh100,SANSA_FUZE_PAD,SANSA_E200_PAD,IPOD_4G_PAD,IPOD_3G_PAD%
diff --git a/manual/plugins/mpegplayer.tex b/manual/plugins/mpegplayer.tex
deleted file mode 100644
index 9fa438dabe..0000000000
--- a/manual/plugins/mpegplayer.tex
+++ /dev/null
@@ -1,119 +0,0 @@
-% $Id$ %
-\subsection{MPEG Player}
-The Mpeg Player is a video player plugin capable of playing back MPEG-1 and
-MPEG-2 video streams with MPEG audio multiplexed into \fname{.mpg} files.
-
-To play a video file, you just select it in the Rockbox \setting{File Browser}.
-If your file does not have the \fname{.mpg} extension but is encoded in the
-supported format, you will need to use the \setting{Open With...} context menu
-option and choose \setting{mpegplayer}.
-
-\begin{btnmap}
- \opt{GIGABEAT_S_PAD}{\ButtonSelect{} or \ButtonPlay}
- \opt{GIGABEAT_PAD}{\ButtonSelect{} or \ButtonA}
- \nopt{GIGABEAT_S_PAD,GIGABEAT_PAD}{\ActionWpsPlay}
- \opt{HAVEREMOTEKEYMAP}{& }
- & Pause / Resume\\
- \ActionWpsStop
- \opt{HAVEREMOTEKEYMAP}{& }
- & Stop\\
- \nopt{GIGABEAT_S_PAD,GIGABEAT_PAD}{\ActionWpsVolUp{} / \ActionWpsVolDown}
- \opt{GIGABEAT_S_PAD,GIGABEAT_PAD}{\ButtonLeft{} or \ButtonVolDown{} /
- \ButtonRight{} or \ButtonVolUp}
- \opt{HAVEREMOTEKEYMAP}{& }
- & Adjust volume up / down\\
- \nopt{GIGABEAT_S_PAD,GIGABEAT_PAD,SAMSUNG_YH92X_PAD,SAMSUNG_YH820_PAD}{%
- \ActionWpsSkipPrev{} / \ActionWpsSkipNext}
- \opt{GIGABEAT_S_PAD,GIGABEAT_PAD}{\ButtonUp{} / \ButtonDown}
- \opt{SAMSUNG_YH92X_PAD,SAMSUNG_YH820_PAD}{\ButtonLeft{} / \ButtonRight}
- \opt{HAVEREMOTEKEYMAP}{& }
- & Rewind / Fast Forward\\
- \opt{IRIVER_H100_PAD,IRIVER_H300_PAD}{\ButtonMode}
- \opt{IPOD_4G_PAD,IPOD_3G_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,PBELL_VIBE500_PAD}
- {\ButtonMenu}
- \opt{IAUDIO_X5_PAD}{\ButtonRec}
- \opt{IRIVER_H10_PAD}{\ButtonRew}
- \opt{SAMSUNG_YH92X_PAD,SAMSUNG_YH820_PAD}{\ButtonRew}
- \opt{SANSA_E200_PAD,SANSA_FUZE_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}{\ButtonSelect}
- \opt{HAVEREMOTEKEYMAP}{& }
- & Open the MPEG Player menu\\
-\end{btnmap}
-
-When a video file is selected, the Start Menu will be displayed, unless it is
-disabled via the \setting{Resume Options} (see below). In the latter case the video
-will start playing immediately.
-
-Start Menu
-
-\begin{description}
-\item[Play from beginning] Resume information is discarded and the video plays
- from the start.
-\item[Resume at: mm:ss] Resume video playback at stored resume time mm:ss
- (start of the video if no resume time is found).
-\item[Set start time] A preview screen is presented consisting of a
- thumbnail preview and a progress bar where the user can select a start time
- by `seeking' through the video. The video playback is started by pressing
- the select button.
-\item[Settings] Open \setting{Settings} submenu -- see below.
-\item[Quit mpegplayer] Exit the plugin.
-\end{description}
-
-Main Menu
-
-\begin{description}
-\item[Settings] Open \setting{Settings} submenu -- see below.
-\item[Resume playback] Return to playback screen.
-\item[Quit mpegplayer] Exit the plugin.
-\end{description}
-
-Settings Menu
-
-\begin{description}
-\item[Display Options] Open \setting{Display Options} submenu -- see below.
-\item[Audio Options] Open \setting{Audio Options} submenu -- see below.
-\item[Resume Options] (default: Start menu) Enable/disable the start menu.
-\item[Play Mode] (default: Single) Set to \setting{All} to play multiple
- \fname{.mpg} files in the directory continuously.
-\item[Clear all resumes: x] Discard all x resume points.
-\end{description}
-
-Display Options Menu
-
-\begin{description}
-\item[Dithering] (default: off) Prevent banding effects in gradients by blending
- of colours. (only available on Sansa e200, Sansa c200 and Gigabeat F/X)
-\item[Display FPS] (default: off) This option displays (once a second -- if your
- video is full-screen this means it will get overwritten by the video and
- appear to flash once per second) the average number of frames decoded per
- second, the total number of frames skipped (see the Skip Frames option),
- the current time (in 100~Hz ticks) and the time the current frame is due to
- be displayed.
-\item[Limit FPS] (default: on) With this option disabled, mpegplayer will
- display the video as fast as it can. Useful for benchmarking.
-\item[Skip frames] (default: on) This option causes mpegplayer to attempt to
- maintain realtime playback by skipping the display of frames -- but these
- frames are still decoded. Disabling this option can cause loss of A/V sync.
-\opt{backlight_brightness}{
- \item[Backlight Brightness] (default: Use setting) Choose brightness to use
- during video playback. Set to \setting{Use setting} to use the Brightness
- setting.
-}
-\end{description}
-
-Audio Options Menu
-
-\begin{description}
-\item[Tone Controls] (default: force off) Use the bass and treble control
- settings or force them off.
-\item[Channel Modes] (default: force off) Use the channel configuration setting
- or force Stereo mode.
-\item[Crossfeed] (default: force off) Use the Crossfeed setting or force
- crossfeed off.
-\item[Equalizer] (default: force off) Use the Equalizer setting or force the
- equalizer off.
-\item[Dithering] (default: force off) Use the Dithering setting or force
- audio dithering off.
-\end{description}
-
-See this page in the Rockbox wiki for information on how to encode your videos
-to the supported format. \wikilink{PluginMpegplayer}