summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-08-07 22:11:07 +0000
committerDave Chapman <dave@dchapman.com>2006-08-07 22:11:07 +0000
commitc9d66562afc15de210854b32f30976859bce2023 (patch)
tree4fc7c506797bf96e389bd2fb68dd0e36d2735750
parent754e173c252ab80a9e1e290bddfa126e6227ac1c (diff)
downloadrockbox-c9d66562afc15de210854b32f30976859bce2023.tar.gz
rockbox-c9d66562afc15de210854b32f30976859bce2023.zip
Initial commit of work-in-progress MPEG video player plugin based on libmpeg2. Works on all targets with colour LCDs, but most optimised for the ipod Color/Photo and Nano. It currently only plays raw MPEG-1 or MPEG-2 video streams (no audio). Also adds a new lcd_yuv_blit() function to the plugin API - currently only implemented for the ipod Color/Photo and Nano.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10479 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c5
-rw-r--r--apps/plugin.h9
-rw-r--r--apps/plugins/SUBDIRS5
-rw-r--r--apps/plugins/mpegplayer/AUTHORS33
-rw-r--r--apps/plugins/mpegplayer/Makefile116
-rw-r--r--apps/plugins/mpegplayer/README204
-rw-r--r--apps/plugins/mpegplayer/README.rockbox44
-rw-r--r--apps/plugins/mpegplayer/SOURCES10
-rw-r--r--apps/plugins/mpegplayer/alloc.c76
-rw-r--r--apps/plugins/mpegplayer/attributes.h37
-rw-r--r--apps/plugins/mpegplayer/cpu_accel.c220
-rw-r--r--apps/plugins/mpegplayer/cpu_state.c129
-rw-r--r--apps/plugins/mpegplayer/decode.c447
-rw-r--r--apps/plugins/mpegplayer/header.c892
-rw-r--r--apps/plugins/mpegplayer/idct.c287
-rw-r--r--apps/plugins/mpegplayer/motion_comp.c131
-rw-r--r--apps/plugins/mpegplayer/mpeg2.h195
-rw-r--r--apps/plugins/mpegplayer/mpeg2_internal.h300
-rw-r--r--apps/plugins/mpegplayer/mpeg2dec_config.h2
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c246
-rw-r--r--apps/plugins/mpegplayer/slice.c2060
-rw-r--r--apps/plugins/mpegplayer/video_out.h58
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c285
-rw-r--r--apps/plugins/mpegplayer/vlc.h429
-rw-r--r--apps/plugins/viewers.config2
-rw-r--r--firmware/drivers/lcd-ipod.c231
-rw-r--r--firmware/export/lcd.h6
27 files changed, 6457 insertions, 2 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index f9f7e42b80..96d55abfd1 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -462,6 +462,11 @@ static const struct plugin_api rockbox_api = {
462 lcd_remote_bitmap_part, 462 lcd_remote_bitmap_part,
463 lcd_remote_bitmap, 463 lcd_remote_bitmap,
464#endif 464#endif
465
466#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO) && \
467 !defined(SIMULATOR)
468 lcd_yuv_blit,
469#endif
465}; 470};
466 471
467int plugin_load(const char* plugin, void* parameter) 472int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 0187de8678..69fbea9a22 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -104,7 +104,7 @@
104#define PLUGIN_MAGIC 0x526F634B /* RocK */ 104#define PLUGIN_MAGIC 0x526F634B /* RocK */
105 105
106/* increase this every time the api struct changes */ 106/* increase this every time the api struct changes */
107#define PLUGIN_API_VERSION 25 107#define PLUGIN_API_VERSION 26
108 108
109/* update this to latest version if a change to the api struct breaks 109/* update this to latest version if a change to the api struct breaks
110 backwards compatibility (and please take the opportunity to sort in any 110 backwards compatibility (and please take the opportunity to sort in any
@@ -539,6 +539,13 @@ struct plugin_api {
539 void (*lcd_remote_bitmap)(const fb_remote_data *src, int x, int y, int width, 539 void (*lcd_remote_bitmap)(const fb_remote_data *src, int x, int y, int width,
540 int height); 540 int height);
541#endif 541#endif
542#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO) && \
543 !defined(SIMULATOR)
544 void (*lcd_yuv_blit)(unsigned char * const src[3],
545 int src_x, int src_y, int stride,
546 int x, int y, int width, int height);
547#endif
548
542}; 549};
543 550
544/* plugin header */ 551/* plugin header */
diff --git a/apps/plugins/SUBDIRS b/apps/plugins/SUBDIRS
index 2d0d6d3c19..d45283c1d5 100644
--- a/apps/plugins/SUBDIRS
+++ b/apps/plugins/SUBDIRS
@@ -32,5 +32,10 @@ pacbox
32doom 32doom
33#endif 33#endif
34 34
35/* For all the colour targets */
36#if defined(HAVE_LCD_COLOR)
37mpegplayer
38#endif
39
35 40
36#endif /* IRIVER_IFP7XX_SERIES */ 41#endif /* IRIVER_IFP7XX_SERIES */
diff --git a/apps/plugins/mpegplayer/AUTHORS b/apps/plugins/mpegplayer/AUTHORS
new file mode 100644
index 0000000000..901810bc3d
--- /dev/null
+++ b/apps/plugins/mpegplayer/AUTHORS
@@ -0,0 +1,33 @@
1Aaron Holtzman <aholtzma@ess.engr.uvic.ca> started the project and
2made the initial working implementation.
3
4Michel Lespinasse <walken@zoy.org> did major changes for speed and
5mpeg conformance and is the current maintainer. Most of the current
6code was (re)written by him.
7
8Other contributors include:
9 Bruno Barreyra <barreyra@ufl.edu> - build fixes
10 Gildas Bazin <gbazin@netcourrier.com> - mingw32 port
11 Alexander W. Chin <alexc@newt.phys.unsw.edu.au> - progressive_seq fix
12 Stephen Crowley <stephenc@dns2.digitalpassage.com> - build fixes
13 Didier Gautheron <dgautheron@magic.fr> - bug fixes
14 Ryan C. Gordon <icculus@lokigames.com> - SDL support
15 Peter Gubanov <peter@elecard.net.ru> - MMX IDCT scheduling
16 Håkan Hjort <d95hjort@dtek.chalmers.se> - Solaris fixes, mlib code
17 Nicolas Joly <njoly@pasteur.fr> - assorted bug fixes
18 Gerd Knorr <kraxel@goldbach.in-berlin.de> - Xv support
19 David I. Lehn <dlehn@vt.edu> - motion_comp mmx code
20 Olie Lho <ollie@sis.com.tw> - MMX yuv2rgb routine
21 David S. Miller <davem@redhat.com> - sparc VIS optimizations
22 Rick Niles <niles@scyld.com> - build fixes
23 Real Ouellet <realo@sympatico.ca> - g200 fixes
24 Bajusz Peter <hyp-x@inf.bme.hu> - motion comp fixes
25 Franck Sicard <Franck.Sicard@miniruth.solsoft.fr> - x11 fixes
26 Brion Vibber <brion@gizmo.usc.edu> - x11 fixes
27 Martin Vogt <mvogt@rhrk.uni-kl.de> - reentrancy fixes
28 Fredrik Vraalsen <vraalsen@cs.uiuc.edu> - general hackage and stuff
29
30(let me know if I forgot anyone)
31
32Thanks to David Schleef for creating me an account on his ppc g4
33machine and making it possible for me to work on the altivec code.
diff --git a/apps/plugins/mpegplayer/Makefile b/apps/plugins/mpegplayer/Makefile
new file mode 100644
index 0000000000..46ea76633b
--- /dev/null
+++ b/apps/plugins/mpegplayer/Makefile
@@ -0,0 +1,116 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10INCLUDES = -I$(APPSDIR) -I.. -I. $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
11 -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR)
12CFLAGS = $(INCLUDES) $(GCCOPTS) -O2 $(TARGET) $(EXTRA_DEFINES) \
13 -DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN
14
15
16ifdef APPEXTRA
17 INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
18endif
19
20LINKFILE := $(OBJDIR)/link.lds
21DEPFILE = $(OBJDIR)/dep-mpegplayer
22
23# This sets up 'SRC' based on the files mentioned in SOURCES
24include $(TOOLSDIR)/makesrc.inc
25
26SOURCES = $(SRC)
27OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o)
28OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2))
29DIRS = .
30
31LDS := ../plugin.lds
32OUTPUT = $(OUTDIR)/mpegplayer.rock
33
34all: $(OUTPUT)
35
36ifndef SIMVER
37$(OBJDIR)/mpegplayer.elf: $(OBJS) $(LINKFILE)
38 @echo "LD "`basename $@`
39 @$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lgcc \
40 -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/mpegplayer.map
41
42$(OUTPUT): $(OBJDIR)/mpegplayer.elf
43 @echo "OBJCOPY "`basename $@`
44 @$(OC) -O binary $< $@
45else
46
47ifeq ($(SIMVER), x11)
48###################################################
49# This is the X11 simulator version
50
51$(OUTPUT): $(OBJS)
52 @echo "LD $<"
53 @$(CC) $(CFLAGS) -shared $(OBJS) -L$(BUILDDIR) -lplugin -o $@
54ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
55# 'x' must be kept or you'll have "Win32 error 5"
56# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
57# #define ERROR_ACCESS_DENIED 5L
58else
59 @chmod -x $@
60endif
61
62else # end of x11-simulator
63ifeq ($(SIMVER), sdl)
64###################################################
65# This is the SDL simulator version
66
67$(OUTPUT): $(OBJS)
68 @echo "LD $<"
69 @$(CC) $(CFLAGS) -shared $(OBJS) -L$(BUILDDIR) -lplugin -o $@
70ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
71# 'x' must be kept or you'll have "Win32 error 5"
72# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
73# #define ERROR_ACCESS_DENIED 5L
74else
75 @chmod -x $@
76endif
77
78else # end of sdl-simulator
79###################################################
80# This is the win32 simulator version
81DLLTOOLFLAGS = --export-all
82DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
83
84$(OUTPUT): $(OBJS)
85 @echo "DLL "`basename $@`
86 @$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS)
87 @$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \
88 $(BUILDDIR)/libplugin.a -o $@
89ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
90# 'x' must be kept or you'll have "Win32 error 5"
91# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
92# #define ERROR_ACCESS_DENIED 5L
93else
94 @chmod -x $@
95endif
96endif # end of win32-simulator
97endif
98endif # end of simulator section
99
100
101include $(TOOLSDIR)/make.inc
102
103# MEMORYSIZE should be passed on to this makefile with the chosen memory size
104# given in number of MB
105$(LINKFILE): $(LDS)
106 @echo "build "`basename $@`
107 @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) \
108 $(DEFINES) -E -P - >$@
109
110clean:
111 @echo "cleaning mpegplayer"
112 @rm -rf $(OBJDIR)/mpegplayer
113 @rm -f $(OBJDIR)/mpegplayer.* $(DEPFILE)
114
115-include $(DEPFILE)
116
diff --git a/apps/plugins/mpegplayer/README b/apps/plugins/mpegplayer/README
new file mode 100644
index 0000000000..2a58846772
--- /dev/null
+++ b/apps/plugins/mpegplayer/README
@@ -0,0 +1,204 @@
1
2
3ABOUT LIBMPEG2
4
5libmpeg2 is a free library for decoding mpeg-2 and mpeg-1 video
6streams. It is released under the terms of the GPL license.
7
8The main goals in libmpeg2 development are:
9
10 * Conformance - libmpeg2 is able to decode all mpeg streams that
11 conform to certain restrictions: "constrained parameters" for
12 mpeg-1, and "main profile" for mpeg-2. In practice, this is
13 what most people are using. For streams that follow these
14 restrictions, we believe libmpeg2 is 100% conformant to the
15 mpeg standards - and we have a pretty extensive test suite to
16 check this.
17
18 * Speed - there has been huge efforts there, and we believe
19 libmpeg2 is the fastest library around for what it
20 does. Please tell us if you find a faster one ! With typical
21 video streams as found on DVD's, and doing only decoding with
22 no display, you should be able to get about 110 fps on a
23 PIII/666, or 150 fps on an Athlon/950. This is less than 20
24 cycles per output pixel. In a real player program, the display
25 routines will probably take as much time as the actual
26 decoding !
27
28 * Portability - most of the code is written in C, and when we
29 use platform-specific optimizations (typically assembly
30 routines, currently used for the motion compensation and the
31 inverse cosine transform stages) we always have a generic C
32 routine to fall back on. This should be portable to all
33 architectures - at least we have heard reports from people
34 running this code on x86, ppc, sparc, arm and
35 sh4. Assembly-optimized implementations are available on x86
36 (MMX) and ppc (altivec) architectures. Ultrasparc (VIS) is
37 probably the next on the list - we'll see.
38
39 * Reuseability - we do not want libmpeg2 to include any
40 project-specific code, but it should still include enough
41 features to be used by very diverse projects. We are only
42 starting to get there - the best way to help here is to give
43 us some feedback !
44
45The project homepage is at http://libmpeg2.sourceforge.net/
46
47
48MPEG2DEC
49
50mpeg2dec is a test program for libmpeg2. It decodes mpeg-1 and mpeg-2
51video streams, and also includes a demultiplexer for mpeg-1 and mpeg-2
52program streams. It is purposely kept simple : it does not include
53features like reading files from a DVD, CSS, fullscreen output,
54navigation, etc... The main purpose of mpeg2dec is to have a simple
55test bed for libmpeg2.
56
57The libmpeg2 source code is always distributed in the mpeg2dec
58package, to make it easier for people to test it.
59
60The basic usage is to just type "mpeg2dec file" where file is a
61demultiplexed mpeg video file.
62
63The "-s" option must be used for multiplexed (audio and video) mpeg
64files using the "program stream" format. These files are usualy found
65on the internet or on unencrypted DVDs.
66
67The "-t" option must be used for multiplexed (audio and video) mpeg
68files using the "transport stream" format. These files are usualy
69found in digital TV applications.
70
71The "-o" option is used to select a given output module - for example
72to redirect the output to a file. This is also used for performance
73testing and conformance testing.
74
75The "-c" option is used to disable all optimizations.
76
77
78OTHER PROJECTS USING LIBMPEG2
79
80libmpeg2 is being used by various other projects, including:
81
82 * xine (http://xine.sourceforge.net/) - started as a simple
83 mpeg-2 audio and video decoder, but it since became a
84 full-featured DVD and video media player.
85
86 * VideoLAN (http://www.videolan.org/) - video streaming over an
87 ethernet network, can also be used as a standalone player.
88
89 * MPlayer (http://www.MPlayerHQ.hu) - another good player, it is
90 also very robust against damaged streams.
91
92 * movietime (http://movietime.sourceforge.net/) - still quite
93 young, but it looks very promising !
94
95 * mpeg2decX (http://homepage1.nifty.com/~toku/software_en.html) -
96 a graphical interface for mpeg2dec for macintosh osX.
97
98 * TCVP (http://tcvp.sf.net) - video and music player for unix.
99
100 * drip (http://drip.sourceforge.net/) - a DVD to DIVX transcoder.
101
102 * PoMP
103 (http://www.dmclab.hanyang.ac.kr/research/project/PoDS/PoDS_sw.htm) -
104 a research player optimized to minimize disk power consumption.
105
106 * OMS (http://www.linuxvideo.org/oms/)
107
108 * XMPS (http://xmps.sourceforge.net/)
109
110 * GStreamer (http://www.gstreamer.net/) - a framework for
111 streaming media; it has an mpeg2 decoding plugin based on
112 libmpeg2.
113
114 * mpeglib (http://mpeglib.sourceforge.net/) - a video decoding
115 library that usess libmpeg2 when decoding mpeg streams.
116
117 * daphne (http://daphne.rulecity.com/) - a laserdisc arcade game
118 simulator.
119
120 * GOPchop (http://outflux.net/unix/software/GOPchop/) - a
121 GOP-accurate editor for MPEG2 streams.
122
123If you use libmpeg2 in another project, let us know !
124
125
126TASKS
127
128There are several places where we could easily use some help:
129
130 * Documentation: libmpeg2 still has no documentation. Every
131 project using it has had to figure things out by looking at
132 the header files, at the mpeg2dec sample application, and by
133 asking questions. Writing down a nice documentation would make
134 the code more easily reuseable.
135
136 * Testing: If you find any stream that does not decode right
137 with libmpeg2, let us know ! The best thing would be to mail
138 to the libmpeg2-devel mailing list. Also, it would be nice to
139 build a stress test so we can make sure libmpeg2 never crashes
140 on bad streams.
141
142 * Coding: There is a small TODO list in the mpeg2dec package,
143 you can have a look there ! Most items are pretty terse
144 though.
145
146 * Porting: If you're porting to a new architecture, you might
147 want to experiment with the compile flags defined in
148 configure.in . When you figure out whats fastest on your
149 platform, send us a patch !
150
151 * Assembly optimizations: We only have x86 and altivec
152 optimizations yet, it would be worthwhile writing routines for
153 other architectures, especially those that have SIMD
154 instruction set extensions ! Also the yuv2rgb x86 routines
155 could probably be optimized a lot.
156
157
158CVS SNAPSHOTS
159
160A daily snapshot is created using "make distcheck" every night and
161uploaded to http://libmpeg2.sourceforge.net/files/mpeg2dec-snapshot.tar.gz .
162It is easier to use than the CVS repository, because you do not need
163to have the right versions of automake, autoconf and libtool
164installed. It might be convenient when working on a libmpeg2 port for
165example.
166
167
168CVS REPOSITORY
169
170The latest libmpeg2 and mpeg2dec source code can always be found by
171anonymous CVS:
172
173# export CVSROOT=:pserver:anonymous@cvs.libmpeg2.sourceforge.net:/cvsroot/libmpeg2
174# cvs login (Just press Return when prompted for a password)
175# cvs checkout mpeg2dec
176
177You can also browse the latest changes online at
178http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/libmpeg2/mpeg2dec/
179
180The other CVS modules are mpeg2dec-streams for the test suite, and
181mpeg2dec-livid for the CVS history of the project while it was still
182hosted on the linuxvideo.org servers.
183
184
185MAILING LISTS
186
187See the subscription information at http://libmpeg2.sourceforge.net/lists.html
188
189libmpeg2-devel
190
191This is the main mailing list for technical discussion about
192libmpeg2. Anyone wanting to work on libmpeg2, or maybe just stay
193informed about the development process, should probably subscribe to
194this list.
195
196libmpeg2-checkins
197
198All libmpeg2 checkins are announced there. This is a good way to keep
199track of what goes into CVS.
200
201libmpeg2-announce
202
203This is a very low traffic mailing list, only for announcements of new
204versions of libmpeg2. Only project administrators can post there.
diff --git a/apps/plugins/mpegplayer/README.rockbox b/apps/plugins/mpegplayer/README.rockbox
new file mode 100644
index 0000000000..95f5a3d4b5
--- /dev/null
+++ b/apps/plugins/mpegplayer/README.rockbox
@@ -0,0 +1,44 @@
1Library: libmpeg2 from mpeg2dec-0.4.0b (Released 2004-01-21)
2Imported: 2006-08-06 by Dave Chapman
3
4
5This directory contains a local version of libmpeg2 imported into
6Rockbox for MPEG video decoding.
7
8
9LICENSING INFORMATION
10
11mpeg2dec and libmpeg2 are licensed under Version 2 of the GNU General
12Public License.
13
14
15IMPORT DETAILS
16
17The following files were imported from the mpeg2dec-0.4.0b
18distribution. Minor changes were made to enable compilation in
19Rockbox and TABs were replaced by spaces to comply with the Rockbox
20coding guidelines.
21
22AUTHORS
23README
24SOURCES
25attributes.h
26cpu_accel.c
27cpu_state.c
28decode.c
29header.c
30idct.c
31motion_comp.c
32mpeg2.h
33mpeg2_internal.h
34slice.c
35video_out.h
36vlc.h
37
38The following files are new, but based on code in mpeg2dec.
39
40Makefile
41mpegplayer.c
42video_out_rockbox.c
43mpeg2dec_config.h
44alloc.c
diff --git a/apps/plugins/mpegplayer/SOURCES b/apps/plugins/mpegplayer/SOURCES
new file mode 100644
index 0000000000..2ea6f303ec
--- /dev/null
+++ b/apps/plugins/mpegplayer/SOURCES
@@ -0,0 +1,10 @@
1alloc.c
2cpu_accel.c
3cpu_state.c
4decode.c
5header.c
6idct.c
7motion_comp.c
8slice.c
9video_out_rockbox.c
10mpegplayer.c
diff --git a/apps/plugins/mpegplayer/alloc.c b/apps/plugins/mpegplayer/alloc.c
new file mode 100644
index 0000000000..0a3568ae5b
--- /dev/null
+++ b/apps/plugins/mpegplayer/alloc.c
@@ -0,0 +1,76 @@
1/*
2 * alloc.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "plugin.h"
25
26#include "mpeg2.h"
27
28extern struct plugin_api* rb;
29
30long mem_ptr;
31long bufsize;
32unsigned char* mallocbuf;
33
34void mpeg2_alloc_init(unsigned char* buf, int mallocsize)
35{
36 mem_ptr = 0;
37 bufsize = mallocsize;
38 mallocbuf = buf;
39
40 return;
41}
42
43void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason)
44{
45 void* x;
46
47 (void)reason;
48
49 if (mem_ptr + (long)size > bufsize) {
50 DEBUGF("OUT OF MEMORY\n");
51 return NULL;
52 }
53
54 x=&mallocbuf[mem_ptr];
55 mem_ptr+=(size+3)&~3; /* Keep memory 32-bit aligned */
56
57 return(x);
58}
59
60void mpeg2_free(void* ptr) {
61 (void)ptr;
62}
63
64/* gcc may want to use memcpy before rb is initialised, so here's a trivial
65 implementation */
66
67void *memcpy(void *dest, const void *src, size_t n) {
68 size_t i;
69 char* d=(char*)dest;
70 char* s=(char*)src;
71
72 for (i=0;i<n;i++)
73 d[i]=s[i];
74
75 return dest;
76}
diff --git a/apps/plugins/mpegplayer/attributes.h b/apps/plugins/mpegplayer/attributes.h
new file mode 100644
index 0000000000..eefbc0dd1b
--- /dev/null
+++ b/apps/plugins/mpegplayer/attributes.h
@@ -0,0 +1,37 @@
1/*
2 * attributes.h
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/* use gcc attribs to align critical data structures */
25#ifdef ATTRIBUTE_ALIGNED_MAX
26#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
27#else
28#define ATTR_ALIGN(align)
29#endif
30
31#ifdef HAVE_BUILTIN_EXPECT
32#define likely(x) __builtin_expect ((x) != 0, 1)
33#define unlikely(x) __builtin_expect ((x) != 0, 0)
34#else
35#define likely(x) (x)
36#define unlikely(x) (x)
37#endif
diff --git a/apps/plugins/mpegplayer/cpu_accel.c b/apps/plugins/mpegplayer/cpu_accel.c
new file mode 100644
index 0000000000..2616e04cd0
--- /dev/null
+++ b/apps/plugins/mpegplayer/cpu_accel.c
@@ -0,0 +1,220 @@
1/*
2 * cpu_accel.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "plugin.h"
25
26#include "mpeg2dec_config.h"
27
28#include "mpeg2.h"
29#include "attributes.h"
30#include "mpeg2_internal.h"
31
32#ifdef ACCEL_DETECT
33#ifdef ARCH_X86
34static inline uint32_t arch_accel (void)
35{
36 uint32_t eax, ebx, ecx, edx;
37 int AMD;
38 uint32_t caps;
39
40#if !defined(PIC) && !defined(__PIC__)
41#define cpuid(op,eax,ebx,ecx,edx) \
42 __asm__ ("cpuid" \
43 : "=a" (eax), \
44 "=b" (ebx), \
45 "=c" (ecx), \
46 "=d" (edx) \
47 : "a" (op) \
48 : "cc")
49#else /* PIC version : save ebx */
50#define cpuid(op,eax,ebx,ecx,edx) \
51 __asm__ ("push %%ebx\n\t" \
52 "cpuid\n\t" \
53 "movl %%ebx,%1\n\t" \
54 "pop %%ebx" \
55 : "=a" (eax), \
56 "=r" (ebx), \
57 "=c" (ecx), \
58 "=d" (edx) \
59 : "a" (op) \
60 : "cc")
61#endif
62
63 __asm__ ("pushf\n\t"
64 "pushf\n\t"
65 "pop %0\n\t"
66 "movl %0,%1\n\t"
67 "xorl $0x200000,%0\n\t"
68 "push %0\n\t"
69 "popf\n\t"
70 "pushf\n\t"
71 "pop %0\n\t"
72 "popf"
73 : "=r" (eax),
74 "=r" (ebx)
75 :
76 : "cc");
77
78 if (eax == ebx) /* no cpuid */
79 return 0;
80
81 cpuid (0x00000000, eax, ebx, ecx, edx);
82 if (!eax) /* vendor string only */
83 return 0;
84
85 AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
86
87 cpuid (0x00000001, eax, ebx, ecx, edx);
88 if (! (edx & 0x00800000)) /* no MMX */
89 return 0;
90
91 caps = MPEG2_ACCEL_X86_MMX;
92 if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */
93 caps = MPEG2_ACCEL_X86_MMX | MPEG2_ACCEL_X86_MMXEXT;
94
95 cpuid (0x80000000, eax, ebx, ecx, edx);
96 if (eax < 0x80000001) /* no extended capabilities */
97 return caps;
98
99 cpuid (0x80000001, eax, ebx, ecx, edx);
100
101 if (edx & 0x80000000)
102 caps |= MPEG2_ACCEL_X86_3DNOW;
103
104 if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
105 caps |= MPEG2_ACCEL_X86_MMXEXT;
106
107 return caps;
108}
109#endif /* ARCH_X86 */
110
111#if defined(ARCH_PPC) || defined(ARCH_SPARC)
112#include <signal.h>
113#include <setjmp.h>
114
115static sigjmp_buf jmpbuf;
116static volatile sig_atomic_t canjump = 0;
117
118static RETSIGTYPE sigill_handler (int sig)
119{
120 if (!canjump) {
121 signal (sig, SIG_DFL);
122 raise (sig);
123 }
124
125 canjump = 0;
126 siglongjmp (jmpbuf, 1);
127}
128
129#ifdef ARCH_PPC
130static inline uint32_t arch_accel (void)
131{
132 static RETSIGTYPE (* oldsig) (int);
133
134 oldsig = signal (SIGILL, sigill_handler);
135 if (sigsetjmp (jmpbuf, 1)) {
136 signal (SIGILL, oldsig);
137 return 0;
138 }
139
140 canjump = 1;
141
142#ifdef HAVE_ALTIVEC_H /* gnu */
143#define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t"
144#else /* apple */
145#define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t"
146#endif
147 asm volatile ("mtspr 256, %0\n\t"
148 VAND (0, 0, 0)
149 :
150 : "r" (-1));
151
152 canjump = 0;
153
154 signal (SIGILL, oldsig);
155 return MPEG2_ACCEL_PPC_ALTIVEC;
156}
157#endif /* ARCH_PPC */
158
159#ifdef ARCH_SPARC
160static inline uint32_t arch_accel (void)
161{
162 static RETSIGTYPE (* oldsig) (int);
163
164 oldsig = signal (SIGILL, sigill_handler);
165 if (sigsetjmp (jmpbuf, 1)) {
166 signal (SIGILL, oldsig);
167 return 0;
168 }
169
170 canjump = 1;
171
172 /* pdist %f0, %f0, %f0 */
173 __asm__ __volatile__(".word\t0x81b007c0");
174
175 canjump = 0;
176
177 if (sigsetjmp (jmpbuf, 1)) {
178 signal (SIGILL, oldsig);
179 return MPEG2_ACCEL_SPARC_VIS;
180 }
181
182 canjump = 1;
183
184 /* edge8n %g0, %g0, %g0 */
185 __asm__ __volatile__(".word\t0x81b00020");
186
187 canjump = 0;
188
189 signal (SIGILL, oldsig);
190 return MPEG2_ACCEL_SPARC_VIS | MPEG2_ACCEL_SPARC_VIS2;
191}
192#endif /* ARCH_SPARC */
193#endif /* ARCH_PPC || ARCH_SPARC */
194
195#ifdef ARCH_ALPHA
196static inline uint32_t arch_accel (void)
197{
198 uint64_t no_mvi;
199
200 asm volatile ("amask %1, %0"
201 : "=r" (no_mvi)
202 : "rI" (256)); /* AMASK_MVI */
203 return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA |
204 MPEG2_ACCEL_ALPHA_MVI);
205}
206#endif /* ARCH_ALPHA */
207#endif /* ACCEL_DETECT */
208
209uint32_t mpeg2_detect_accel (void)
210{
211 uint32_t accel;
212
213 accel = 0;
214#ifdef ACCEL_DETECT
215#if defined (ARCH_X86) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC)
216 accel = arch_accel ();
217#endif
218#endif
219 return accel;
220}
diff --git a/apps/plugins/mpegplayer/cpu_state.c b/apps/plugins/mpegplayer/cpu_state.c
new file mode 100644
index 0000000000..4406853626
--- /dev/null
+++ b/apps/plugins/mpegplayer/cpu_state.c
@@ -0,0 +1,129 @@
1/*
2 * cpu_state.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "plugin.h"
25
26#include "mpeg2dec_config.h"
27
28#include "mpeg2.h"
29#include "attributes.h"
30#include "mpeg2_internal.h"
31#ifdef ARCH_X86
32#include "mmx.h"
33#endif
34
35void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL;
36void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL;
37
38#ifdef ARCH_X86
39static void state_restore_mmx (cpu_state_t * state)
40{
41 emms ();
42}
43#endif
44
45#ifdef ARCH_PPC
46#ifdef HAVE_ALTIVEC_H /* gnu */
47#define LI(a,b) "li " #a "," #b "\n\t"
48#define STVX0(a,b,c) "stvx " #a ",0," #c "\n\t"
49#define STVX(a,b,c) "stvx " #a "," #b "," #c "\n\t"
50#define LVX0(a,b,c) "lvx " #a ",0," #c "\n\t"
51#define LVX(a,b,c) "lvx " #a "," #b "," #c "\n\t"
52#else /* apple */
53#define LI(a,b) "li r" #a "," #b "\n\t"
54#define STVX0(a,b,c) "stvx v" #a ",0,r" #c "\n\t"
55#define STVX(a,b,c) "stvx v" #a ",r" #b ",r" #c "\n\t"
56#define LVX0(a,b,c) "lvx v" #a ",0,r" #c "\n\t"
57#define LVX(a,b,c) "lvx v" #a ",r" #b ",r" #c "\n\t"
58#endif
59
60static void state_save_altivec (cpu_state_t * state)
61{
62 asm (LI (9, 16)
63 STVX0 (20, 0, 3)
64 LI (11, 32)
65 STVX (21, 9, 3)
66 LI (9, 48)
67 STVX (22, 11, 3)
68 LI (11, 64)
69 STVX (23, 9, 3)
70 LI (9, 80)
71 STVX (24, 11, 3)
72 LI (11, 96)
73 STVX (25, 9, 3)
74 LI (9, 112)
75 STVX (26, 11, 3)
76 LI (11, 128)
77 STVX (27, 9, 3)
78 LI (9, 144)
79 STVX (28, 11, 3)
80 LI (11, 160)
81 STVX (29, 9, 3)
82 LI (9, 176)
83 STVX (30, 11, 3)
84 STVX (31, 9, 3));
85}
86
87static void state_restore_altivec (cpu_state_t * state)
88{
89 asm (LI (9, 16)
90 LVX0 (20, 0, 3)
91 LI (11, 32)
92 LVX (21, 9, 3)
93 LI (9, 48)
94 LVX (22, 11, 3)
95 LI (11, 64)
96 LVX (23, 9, 3)
97 LI (9, 80)
98 LVX (24, 11, 3)
99 LI (11, 96)
100 LVX (25, 9, 3)
101 LI (9, 112)
102 LVX (26, 11, 3)
103 LI (11, 128)
104 LVX (27, 9, 3)
105 LI (9, 144)
106 LVX (28, 11, 3)
107 LI (11, 160)
108 LVX (29, 9, 3)
109 LI (9, 176)
110 LVX (30, 11, 3)
111 LVX (31, 9, 3));
112}
113#endif
114
115void mpeg2_cpu_state_init (uint32_t accel)
116{
117 (void)accel;
118#ifdef ARCH_X86
119 if (accel & MPEG2_ACCEL_X86_MMX) {
120 mpeg2_cpu_state_restore = state_restore_mmx;
121 }
122#endif
123#ifdef ARCH_PPC
124 if (accel & MPEG2_ACCEL_PPC_ALTIVEC) {
125 mpeg2_cpu_state_save = state_save_altivec;
126 mpeg2_cpu_state_restore = state_restore_altivec;
127 }
128#endif
129}
diff --git a/apps/plugins/mpegplayer/decode.c b/apps/plugins/mpegplayer/decode.c
new file mode 100644
index 0000000000..613292699d
--- /dev/null
+++ b/apps/plugins/mpegplayer/decode.c
@@ -0,0 +1,447 @@
1/*
2 * decode.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "plugin.h"
25
26#include "mpeg2dec_config.h"
27
28extern struct plugin_api* rb;
29
30#include "mpeg2.h"
31#include "attributes.h"
32#include "mpeg2_internal.h"
33
34static int mpeg2_accels = 0;
35
36#define BUFFER_SIZE (1194 * 1024)
37
38const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec)
39{
40 return &(mpeg2dec->info);
41}
42
43static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes)
44{
45 uint8_t * current;
46 uint32_t shift;
47 uint8_t * limit;
48 uint8_t byte;
49
50 if (!bytes)
51 return 0;
52
53 current = mpeg2dec->buf_start;
54 shift = mpeg2dec->shift;
55 limit = current + bytes;
56
57 do {
58 byte = *current++;
59 if (shift == 0x00000100) {
60 int skipped;
61
62 mpeg2dec->shift = 0xffffff00;
63 skipped = current - mpeg2dec->buf_start;
64 mpeg2dec->buf_start = current;
65 return skipped;
66 }
67 shift = (shift | byte) << 8;
68 } while (current < limit);
69
70 mpeg2dec->shift = shift;
71 mpeg2dec->buf_start = current;
72 return 0;
73}
74
75static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes)
76{
77 uint8_t * current;
78 uint32_t shift;
79 uint8_t * chunk_ptr;
80 uint8_t * limit;
81 uint8_t byte;
82
83 if (!bytes)
84 return 0;
85
86 current = mpeg2dec->buf_start;
87 shift = mpeg2dec->shift;
88 chunk_ptr = mpeg2dec->chunk_ptr;
89 limit = current + bytes;
90
91 do {
92 byte = *current++;
93 if (shift == 0x00000100) {
94 int copied;
95
96 mpeg2dec->shift = 0xffffff00;
97 mpeg2dec->chunk_ptr = chunk_ptr + 1;
98 copied = current - mpeg2dec->buf_start;
99 mpeg2dec->buf_start = current;
100 return copied;
101 }
102 shift = (shift | byte) << 8;
103 *chunk_ptr++ = byte;
104 } while (current < limit);
105
106 mpeg2dec->shift = shift;
107 mpeg2dec->buf_start = current;
108 return 0;
109}
110
111void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end)
112{
113 mpeg2dec->buf_start = start;
114 mpeg2dec->buf_end = end;
115}
116
117int mpeg2_getpos (mpeg2dec_t * mpeg2dec)
118{
119 return mpeg2dec->buf_end - mpeg2dec->buf_start;
120}
121
122static inline mpeg2_state_t seek_chunk (mpeg2dec_t * mpeg2dec)
123{
124 int size, skipped;
125
126 size = mpeg2dec->buf_end - mpeg2dec->buf_start;
127 skipped = skip_chunk (mpeg2dec, size);
128 if (!skipped) {
129 mpeg2dec->bytes_since_tag += size;
130 return STATE_BUFFER;
131 }
132 mpeg2dec->bytes_since_tag += skipped;
133 mpeg2dec->code = mpeg2dec->buf_start[-1];
134 return (mpeg2_state_t)-1;
135}
136
137mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec)
138{
139 while (mpeg2dec->code != 0xb3 &&
140 ((mpeg2dec->code != 0xb7 && mpeg2dec->code != 0xb8 &&
141 mpeg2dec->code) || mpeg2dec->sequence.width == (unsigned)-1))
142 if (seek_chunk (mpeg2dec) == STATE_BUFFER)
143 return STATE_BUFFER;
144 mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
145 mpeg2dec->user_data_len = 0;
146 return (mpeg2dec->code ? mpeg2_parse_header (mpeg2dec) :
147 mpeg2_header_picture_start (mpeg2dec));
148}
149
150#define RECEIVED(code,state) (((state) << 8) + (code))
151
152mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec)
153{
154 int size_buffer, size_chunk, copied;
155
156 if (mpeg2dec->action) {
157 mpeg2_state_t state;
158
159 state = mpeg2dec->action (mpeg2dec);
160 if ((int)state >= 0)
161 return state;
162 }
163
164 while (1) {
165 while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) <
166 mpeg2dec->nb_decode_slices) {
167 size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
168 size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE -
169 mpeg2dec->chunk_ptr);
170 if (size_buffer <= size_chunk) {
171 copied = copy_chunk (mpeg2dec, size_buffer);
172 if (!copied) {
173 mpeg2dec->bytes_since_tag += size_buffer;
174 mpeg2dec->chunk_ptr += size_buffer;
175 return STATE_BUFFER;
176 }
177 } else {
178 copied = copy_chunk (mpeg2dec, size_chunk);
179 if (!copied) {
180 /* filled the chunk buffer without finding a start code */
181 mpeg2dec->bytes_since_tag += size_chunk;
182 mpeg2dec->action = seek_chunk;
183 return STATE_INVALID;
184 }
185 }
186 mpeg2dec->bytes_since_tag += copied;
187
188 mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code,
189 mpeg2dec->chunk_start);
190 mpeg2dec->code = mpeg2dec->buf_start[-1];
191 mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
192 }
193 if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1)
194 break;
195 if (seek_chunk (mpeg2dec) == STATE_BUFFER)
196 return STATE_BUFFER;
197 }
198
199 switch (mpeg2dec->code) {
200 case 0x00:
201 mpeg2dec->action = mpeg2_header_picture_start;
202 return mpeg2dec->state;
203 case 0xb7:
204 mpeg2dec->action = mpeg2_header_end;
205 break;
206 case 0xb3:
207 case 0xb8:
208 mpeg2dec->action = mpeg2_parse_header;
209 break;
210 default:
211 mpeg2dec->action = seek_chunk;
212 return STATE_INVALID;
213 }
214 return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID;
215}
216
217mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec)
218{
219 static int (* process_header[]) (mpeg2dec_t * mpeg2dec) = {
220 mpeg2_header_picture, mpeg2_header_extension, mpeg2_header_user_data,
221 mpeg2_header_sequence, NULL, NULL, NULL, NULL, mpeg2_header_gop
222 };
223 int size_buffer, size_chunk, copied;
224
225 mpeg2dec->action = mpeg2_parse_header;
226 mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0;
227 while (1) {
228 size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
229 size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE -
230 mpeg2dec->chunk_ptr);
231 if (size_buffer <= size_chunk) {
232 copied = copy_chunk (mpeg2dec, size_buffer);
233 if (!copied) {
234 mpeg2dec->bytes_since_tag += size_buffer;
235 mpeg2dec->chunk_ptr += size_buffer;
236 return STATE_BUFFER;
237 }
238 } else {
239 copied = copy_chunk (mpeg2dec, size_chunk);
240 if (!copied) {
241 /* filled the chunk buffer without finding a start code */
242 mpeg2dec->bytes_since_tag += size_chunk;
243 mpeg2dec->code = 0xb4;
244 mpeg2dec->action = mpeg2_seek_header;
245 return STATE_INVALID;
246 }
247 }
248 mpeg2dec->bytes_since_tag += copied;
249
250 if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec)) {
251 mpeg2dec->code = mpeg2dec->buf_start[-1];
252 mpeg2dec->action = mpeg2_seek_header;
253 return STATE_INVALID;
254 }
255
256 mpeg2dec->code = mpeg2dec->buf_start[-1];
257 switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) {
258
259 /* state transition after a sequence header */
260 case RECEIVED (0x00, STATE_SEQUENCE):
261 mpeg2dec->action = mpeg2_header_picture_start;
262 case RECEIVED (0xb8, STATE_SEQUENCE):
263 mpeg2_header_sequence_finalize (mpeg2dec);
264 break;
265
266 /* other legal state transitions */
267 case RECEIVED (0x00, STATE_GOP):
268 mpeg2_header_gop_finalize (mpeg2dec);
269 mpeg2dec->action = mpeg2_header_picture_start;
270 break;
271 case RECEIVED (0x01, STATE_PICTURE):
272 case RECEIVED (0x01, STATE_PICTURE_2ND):
273 mpeg2_header_picture_finalize (mpeg2dec, mpeg2_accels);
274 mpeg2dec->action = mpeg2_header_slice_start;
275 break;
276
277 /* legal headers within a given state */
278 case RECEIVED (0xb2, STATE_SEQUENCE):
279 case RECEIVED (0xb2, STATE_GOP):
280 case RECEIVED (0xb2, STATE_PICTURE):
281 case RECEIVED (0xb2, STATE_PICTURE_2ND):
282 case RECEIVED (0xb5, STATE_SEQUENCE):
283 case RECEIVED (0xb5, STATE_PICTURE):
284 case RECEIVED (0xb5, STATE_PICTURE_2ND):
285 mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
286 continue;
287
288 default:
289 mpeg2dec->action = mpeg2_seek_header;
290 return STATE_INVALID;
291 }
292
293 mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
294 mpeg2dec->user_data_len = 0;
295 return mpeg2dec->state;
296 }
297}
298
299int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg)
300{
301 mpeg2_convert_init_t convert_init;
302 int error;
303
304 error = convert (MPEG2_CONVERT_SET, NULL, &(mpeg2dec->sequence), 0,
305 mpeg2_accels, arg, &convert_init);
306 if (!error) {
307 mpeg2dec->convert = convert;
308 mpeg2dec->convert_arg = arg;
309 mpeg2dec->convert_id_size = convert_init.id_size;
310 mpeg2dec->convert_stride = 0;
311 }
312 return error;
313}
314
315int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride)
316{
317 if (!mpeg2dec->convert) {
318 if (stride < (int) mpeg2dec->sequence.width)
319 stride = mpeg2dec->sequence.width;
320 mpeg2dec->decoder.stride_frame = stride;
321 } else {
322 mpeg2_convert_init_t convert_init;
323
324 stride = mpeg2dec->convert (MPEG2_CONVERT_STRIDE, NULL,
325 &(mpeg2dec->sequence), stride,
326 mpeg2_accels, mpeg2dec->convert_arg,
327 &convert_init);
328 mpeg2dec->convert_id_size = convert_init.id_size;
329 mpeg2dec->convert_stride = stride;
330 }
331 return stride;
332}
333
334void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id)
335{
336 mpeg2_fbuf_t * fbuf;
337
338 if (mpeg2dec->custom_fbuf) {
339 if (mpeg2dec->state == STATE_SEQUENCE) {
340 mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1];
341 mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0];
342 }
343 mpeg2_set_fbuf (mpeg2dec, (mpeg2dec->decoder.coding_type ==
344 PIC_FLAG_CODING_TYPE_B));
345 fbuf = mpeg2dec->fbuf[0];
346 } else {
347 fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index].fbuf);
348 mpeg2dec->alloc_index_user = ++mpeg2dec->alloc_index;
349 }
350 fbuf->buf[0] = buf[0];
351 fbuf->buf[1] = buf[1];
352 fbuf->buf[2] = buf[2];
353 fbuf->id = id;
354}
355
356void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf)
357{
358 mpeg2dec->custom_fbuf = custom_fbuf;
359}
360
361void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip)
362{
363 mpeg2dec->first_decode_slice = 1;
364 mpeg2dec->nb_decode_slices = skip ? 0 : (0xb0 - 1);
365}
366
367void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end)
368{
369 start = (start < 1) ? 1 : (start > 0xb0) ? 0xb0 : start;
370 end = (end < start) ? start : (end > 0xb0) ? 0xb0 : end;
371 mpeg2dec->first_decode_slice = start;
372 mpeg2dec->nb_decode_slices = end - start;
373}
374
375void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2)
376{
377 mpeg2dec->tag_previous = mpeg2dec->tag_current;
378 mpeg2dec->tag2_previous = mpeg2dec->tag2_current;
379 mpeg2dec->tag_current = tag;
380 mpeg2dec->tag2_current = tag2;
381 mpeg2dec->num_tags++;
382 mpeg2dec->bytes_since_tag = 0;
383}
384
385uint32_t mpeg2_accel (uint32_t accel)
386{
387 if (!mpeg2_accels) {
388 if (accel & MPEG2_ACCEL_DETECT)
389 accel |= mpeg2_detect_accel ();
390 mpeg2_accels = accel |= MPEG2_ACCEL_DETECT;
391 mpeg2_cpu_state_init (accel);
392 mpeg2_idct_init (accel);
393 mpeg2_mc_init (accel);
394 }
395 return mpeg2_accels & ~MPEG2_ACCEL_DETECT;
396}
397
398void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset)
399{
400 mpeg2dec->buf_start = mpeg2dec->buf_end = NULL;
401 mpeg2dec->num_tags = 0;
402 mpeg2dec->shift = 0xffffff00;
403 mpeg2dec->code = 0xb4;
404 mpeg2dec->action = mpeg2_seek_header;
405 mpeg2dec->state = STATE_INVALID;
406 mpeg2dec->first = 1;
407
408 mpeg2_reset_info(&(mpeg2dec->info));
409 mpeg2dec->info.gop = NULL;
410 mpeg2dec->info.user_data = NULL;
411 mpeg2dec->info.user_data_len = 0;
412 if (full_reset) {
413 mpeg2dec->info.sequence = NULL;
414 mpeg2_header_state_init (mpeg2dec);
415 }
416
417}
418
419mpeg2dec_t * mpeg2_init (void)
420{
421 mpeg2dec_t * mpeg2dec;
422
423 mpeg2_accel (MPEG2_ACCEL_DETECT);
424
425 mpeg2dec = (mpeg2dec_t *) mpeg2_malloc (sizeof (mpeg2dec_t),
426 MPEG2_ALLOC_MPEG2DEC);
427 if (mpeg2dec == NULL)
428 return NULL;
429
430 rb->memset (mpeg2dec->decoder.DCTblock, 0, 64 * sizeof (int16_t));
431 rb->memset (mpeg2dec->quantizer_matrix, 0, 4 * 64 * sizeof (uint8_t));
432
433 mpeg2dec->chunk_buffer = (uint8_t *) mpeg2_malloc (BUFFER_SIZE + 4,
434 MPEG2_ALLOC_CHUNK);
435
436 mpeg2dec->sequence.width = (unsigned)-1;
437 mpeg2_reset (mpeg2dec, 1);
438
439 return mpeg2dec;
440}
441
442void mpeg2_close (mpeg2dec_t * mpeg2dec)
443{
444 mpeg2_header_state_init (mpeg2dec);
445 mpeg2_free (mpeg2dec->chunk_buffer);
446 mpeg2_free (mpeg2dec);
447}
diff --git a/apps/plugins/mpegplayer/header.c b/apps/plugins/mpegplayer/header.c
new file mode 100644
index 0000000000..a5dc27f2f4
--- /dev/null
+++ b/apps/plugins/mpegplayer/header.c
@@ -0,0 +1,892 @@
1/*
2 * header.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 2003 Regis Duchesne <hpreg@zoy.org>
5 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
6 *
7 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
8 * See http://libmpeg2.sourceforge.net/ for updates.
9 *
10 * mpeg2dec is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * mpeg2dec is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include "plugin.h"
26
27#include "mpeg2dec_config.h"
28
29extern struct plugin_api* rb;
30
31#include "mpeg2.h"
32#include "attributes.h"
33#include "mpeg2_internal.h"
34
35#define SEQ_EXT 2
36#define SEQ_DISPLAY_EXT 4
37#define QUANT_MATRIX_EXT 8
38#define COPYRIGHT_EXT 0x10
39#define PIC_DISPLAY_EXT 0x80
40#define PIC_CODING_EXT 0x100
41
42/* default intra quant matrix, in zig-zag order */
43static const uint8_t default_intra_quantizer_matrix[64] IBSS_ATTR = {
44 8,
45 16, 16,
46 19, 16, 19,
47 22, 22, 22, 22,
48 22, 22, 26, 24, 26,
49 27, 27, 27, 26, 26, 26,
50 26, 27, 27, 27, 29, 29, 29,
51 34, 34, 34, 29, 29, 29, 27, 27,
52 29, 29, 32, 32, 34, 34, 37,
53 38, 37, 35, 35, 34, 35,
54 38, 38, 40, 40, 40,
55 48, 48, 46, 46,
56 56, 56, 58,
57 69, 69,
58 83
59};
60
61uint8_t mpeg2_scan_norm[64] ICONST_ATTR = {
62 /* Zig-Zag scan pattern */
63 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
64 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
65 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
66 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
67};
68
69uint8_t mpeg2_scan_alt[64] ICONST_ATTR = {
70 /* Alternate scan pattern */
71 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49,
72 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43,
73 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45,
74 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63
75};
76
77void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec)
78{
79 if (mpeg2dec->sequence.width != (unsigned)-1) {
80 int i;
81
82 mpeg2dec->sequence.width = (unsigned)-1;
83 if (!mpeg2dec->custom_fbuf)
84 for (i = mpeg2dec->alloc_index_user;
85 i < mpeg2dec->alloc_index; i++) {
86 mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[0]);
87 mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[1]);
88 mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[2]);
89 }
90 if (mpeg2dec->convert_start)
91 for (i = 0; i < 3; i++) {
92 mpeg2_free (mpeg2dec->yuv_buf[i][0]);
93 mpeg2_free (mpeg2dec->yuv_buf[i][1]);
94 mpeg2_free (mpeg2dec->yuv_buf[i][2]);
95 }
96 if (mpeg2dec->decoder.convert_id)
97 mpeg2_free (mpeg2dec->decoder.convert_id);
98 }
99 mpeg2dec->decoder.coding_type = I_TYPE;
100 mpeg2dec->decoder.convert = NULL;
101 mpeg2dec->decoder.convert_id = NULL;
102 mpeg2dec->picture = mpeg2dec->pictures;
103 mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[0].fbuf;
104 mpeg2dec->fbuf[1] = &mpeg2dec->fbuf_alloc[1].fbuf;
105 mpeg2dec->fbuf[2] = &mpeg2dec->fbuf_alloc[2].fbuf;
106 mpeg2dec->first = 1;
107 mpeg2dec->alloc_index = 0;
108 mpeg2dec->alloc_index_user = 0;
109 mpeg2dec->first_decode_slice = 1;
110 mpeg2dec->nb_decode_slices = 0xb0 - 1;
111 mpeg2dec->convert = NULL;
112 mpeg2dec->convert_start = NULL;
113 mpeg2dec->custom_fbuf = 0;
114 mpeg2dec->yuv_index = 0;
115}
116
117void mpeg2_reset_info (mpeg2_info_t * info)
118{
119 info->current_picture = info->current_picture_2nd = NULL;
120 info->display_picture = info->display_picture_2nd = NULL;
121 info->current_fbuf = info->display_fbuf = info->discard_fbuf = NULL;
122}
123
124static void info_user_data (mpeg2dec_t * mpeg2dec)
125{
126 if (mpeg2dec->user_data_len) {
127 mpeg2dec->info.user_data = mpeg2dec->chunk_buffer;
128 mpeg2dec->info.user_data_len = mpeg2dec->user_data_len - 3;
129 }
130}
131
132int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec)
133{
134 uint8_t * buffer = mpeg2dec->chunk_start;
135 mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence);
136 static unsigned int frame_period[16] = {
137 0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000,
138 /* unofficial: xing 15 fps */
139 1800000,
140 /* unofficial: libmpeg3 "Unofficial economy rates" 5/10/12/15 fps */
141 5400000, 2700000, 2250000, 1800000, 0, 0
142 };
143 int i;
144
145 if ((buffer[6] & 0x20) != 0x20) /* missing marker_bit */
146 return 1;
147
148 i = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
149 if (! (sequence->display_width = sequence->picture_width = i >> 12))
150 return 1;
151 if (! (sequence->display_height = sequence->picture_height = i & 0xfff))
152 return 1;
153 sequence->width = (sequence->picture_width + 15) & ~15;
154 sequence->height = (sequence->picture_height + 15) & ~15;
155 sequence->chroma_width = sequence->width >> 1;
156 sequence->chroma_height = sequence->height >> 1;
157
158 sequence->flags = (SEQ_FLAG_PROGRESSIVE_SEQUENCE |
159 SEQ_VIDEO_FORMAT_UNSPECIFIED);
160
161 sequence->pixel_width = buffer[3] >> 4; /* aspect ratio */
162 sequence->frame_period = frame_period[buffer[3] & 15];
163
164 sequence->byte_rate = (buffer[4]<<10) | (buffer[5]<<2) | (buffer[6]>>6);
165
166 sequence->vbv_buffer_size = ((buffer[6]<<16)|(buffer[7]<<8))&0x1ff800;
167
168 if (buffer[7] & 4)
169 sequence->flags |= SEQ_FLAG_CONSTRAINED_PARAMETERS;
170
171 mpeg2dec->copy_matrix = 3;
172 if (buffer[7] & 2) {
173 for (i = 0; i < 64; i++)
174 mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] =
175 (buffer[i+7] << 7) | (buffer[i+8] >> 1);
176 buffer += 64;
177 } else
178 for (i = 0; i < 64; i++)
179 mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] =
180 default_intra_quantizer_matrix[i];
181
182 if (buffer[7] & 1)
183 for (i = 0; i < 64; i++)
184 mpeg2dec->new_quantizer_matrix[1][mpeg2_scan_norm[i]] =
185 buffer[i+8];
186 else
187 rb->memset (mpeg2dec->new_quantizer_matrix[1], 16, 64);
188
189 sequence->profile_level_id = 0x80;
190 sequence->colour_primaries = 0;
191 sequence->transfer_characteristics = 0;
192 sequence->matrix_coefficients = 0;
193
194 mpeg2dec->ext_state = SEQ_EXT;
195 mpeg2dec->state = STATE_SEQUENCE;
196 mpeg2dec->display_offset_x = mpeg2dec->display_offset_y = 0;
197
198 return 0;
199}
200
201static int sequence_ext (mpeg2dec_t * mpeg2dec)
202{
203 uint8_t * buffer = mpeg2dec->chunk_start;
204 mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence);
205 uint32_t flags;
206
207 if (!(buffer[3] & 1))
208 return 1;
209
210 sequence->profile_level_id = (buffer[0] << 4) | (buffer[1] >> 4);
211
212 sequence->display_width = sequence->picture_width +=
213 ((buffer[1] << 13) | (buffer[2] << 5)) & 0x3000;
214 sequence->display_height = sequence->picture_height +=
215 (buffer[2] << 7) & 0x3000;
216 sequence->width = (sequence->picture_width + 15) & ~15;
217 sequence->height = (sequence->picture_height + 15) & ~15;
218 flags = sequence->flags | SEQ_FLAG_MPEG2;
219 if (!(buffer[1] & 8)) {
220 flags &= ~SEQ_FLAG_PROGRESSIVE_SEQUENCE;
221 sequence->height = (sequence->height + 31) & ~31;
222 }
223 if (buffer[5] & 0x80)
224 flags |= SEQ_FLAG_LOW_DELAY;
225 sequence->flags = flags;
226 sequence->chroma_width = sequence->width;
227 sequence->chroma_height = sequence->height;
228 switch (buffer[1] & 6) {
229 case 0: /* invalid */
230 return 1;
231 case 2: /* 4:2:0 */
232 sequence->chroma_height >>= 1;
233 case 4: /* 4:2:2 */
234 sequence->chroma_width >>= 1;
235 }
236
237 sequence->byte_rate += ((buffer[2]<<25) | (buffer[3]<<17)) & 0x3ffc0000;
238
239 sequence->vbv_buffer_size |= buffer[4] << 21;
240
241 sequence->frame_period =
242 sequence->frame_period * ((buffer[5]&31)+1) / (((buffer[5]>>2)&3)+1);
243
244 mpeg2dec->ext_state = SEQ_DISPLAY_EXT;
245
246 return 0;
247}
248
249static int sequence_display_ext (mpeg2dec_t * mpeg2dec)
250{
251 uint8_t * buffer = mpeg2dec->chunk_start;
252 mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence);
253 uint32_t flags;
254
255 flags = ((sequence->flags & ~SEQ_MASK_VIDEO_FORMAT) |
256 ((buffer[0]<<4) & SEQ_MASK_VIDEO_FORMAT));
257 if (buffer[0] & 1) {
258 flags |= SEQ_FLAG_COLOUR_DESCRIPTION;
259 sequence->colour_primaries = buffer[1];
260 sequence->transfer_characteristics = buffer[2];
261 sequence->matrix_coefficients = buffer[3];
262 buffer += 3;
263 }
264
265 if (!(buffer[2] & 2)) /* missing marker_bit */
266 return 1;
267
268 sequence->display_width = (buffer[1] << 6) | (buffer[2] >> 2);
269 sequence->display_height =
270 ((buffer[2]& 1 ) << 13) | (buffer[3] << 5) | (buffer[4] >> 3);
271
272 return 0;
273}
274
275static inline void finalize_sequence (mpeg2_sequence_t * sequence)
276{
277 int width;
278 int height;
279
280 sequence->byte_rate *= 50;
281
282 if (sequence->flags & SEQ_FLAG_MPEG2) {
283 switch (sequence->pixel_width) {
284 case 1: /* square pixels */
285 sequence->pixel_width = sequence->pixel_height = 1; return;
286 case 2: /* 4:3 aspect ratio */
287 width = 4; height = 3; break;
288 case 3: /* 16:9 aspect ratio */
289 width = 16; height = 9; break;
290 case 4: /* 2.21:1 aspect ratio */
291 width = 221; height = 100; break;
292 default: /* illegal */
293 sequence->pixel_width = sequence->pixel_height = 0; return;
294 }
295 width *= sequence->display_height;
296 height *= sequence->display_width;
297
298 } else {
299 if (sequence->byte_rate == 50 * 0x3ffff)
300 sequence->byte_rate = 0; /* mpeg-1 VBR */
301
302 switch (sequence->pixel_width) {
303 case 0: case 15: /* illegal */
304 sequence->pixel_width = sequence->pixel_height = 0; return;
305 case 1: /* square pixels */
306 sequence->pixel_width = sequence->pixel_height = 1; return;
307 case 3: /* 720x576 16:9 */
308 sequence->pixel_width = 64; sequence->pixel_height = 45; return;
309 case 6: /* 720x480 16:9 */
310 sequence->pixel_width = 32; sequence->pixel_height = 27; return;
311 case 12: /* 720*480 4:3 */
312 sequence->pixel_width = 8; sequence->pixel_height = 9; return;
313 default:
314 height = 88 * sequence->pixel_width + 1171;
315 width = 2000;
316 }
317 }
318
319 sequence->pixel_width = width;
320 sequence->pixel_height = height;
321 while (width) { /* find greatest common divisor */
322 int tmp = width;
323 width = height % tmp;
324 height = tmp;
325 }
326 sequence->pixel_width /= height;
327 sequence->pixel_height /= height;
328}
329
330static void copy_matrix (mpeg2dec_t * mpeg2dec, int index)
331{
332 if (rb->memcmp (mpeg2dec->quantizer_matrix[index],
333 mpeg2dec->new_quantizer_matrix[index], 64)) {
334 rb->memcpy (mpeg2dec->quantizer_matrix[index],
335 mpeg2dec->new_quantizer_matrix[index], 64);
336 mpeg2dec->scaled[index] = -1;
337 }
338}
339
340static void finalize_matrix (mpeg2dec_t * mpeg2dec)
341{
342 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
343 int i;
344
345 for (i = 0; i < 2; i++) {
346 if (mpeg2dec->copy_matrix & (1 << i))
347 copy_matrix (mpeg2dec, i);
348 if ((mpeg2dec->copy_matrix & (4 << i)) &&
349 rb->memcmp (mpeg2dec->quantizer_matrix[i],
350 mpeg2dec->new_quantizer_matrix[i+2], 64)) {
351 copy_matrix (mpeg2dec, i + 2);
352 decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i+2];
353 } else if (mpeg2dec->copy_matrix & (5 << i))
354 decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i];
355 }
356}
357
358static mpeg2_state_t invalid_end_action (mpeg2dec_t * mpeg2dec)
359{
360 mpeg2_reset_info (&(mpeg2dec->info));
361 mpeg2dec->info.gop = NULL;
362 info_user_data (mpeg2dec);
363 mpeg2_header_state_init (mpeg2dec);
364 mpeg2dec->sequence = mpeg2dec->new_sequence;
365 mpeg2dec->action = mpeg2_seek_header;
366 mpeg2dec->state = STATE_SEQUENCE;
367 return STATE_SEQUENCE;
368}
369
370void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec)
371{
372 mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence);
373 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
374
375 finalize_sequence (sequence);
376 finalize_matrix (mpeg2dec);
377
378 decoder->mpeg1 = !(sequence->flags & SEQ_FLAG_MPEG2);
379 decoder->width = sequence->width;
380 decoder->height = sequence->height;
381 decoder->vertical_position_extension = (sequence->picture_height > 2800);
382 decoder->chroma_format = ((sequence->chroma_width == sequence->width) +
383 (sequence->chroma_height == sequence->height));
384
385 if (mpeg2dec->sequence.width != (unsigned)-1) {
386 unsigned int new_byte_rate;
387
388 /*
389 * According to 6.1.1.6, repeat sequence headers should be
390 * identical to the original. However some DVDs dont respect
391 * that and have different bitrates in the repeat sequence
392 * headers. So we'll ignore that in the comparison and still
393 * consider these as repeat sequence headers.
394 *
395 * However, be careful not to alter the current sequence when
396 * returning STATE_INVALID_END.
397 */
398 new_byte_rate = sequence->byte_rate;
399 sequence->byte_rate = mpeg2dec->sequence.byte_rate;
400 if (rb->memcmp (&(mpeg2dec->sequence), sequence,
401 sizeof (mpeg2_sequence_t))) {
402 decoder->stride_frame = sequence->width;
403 sequence->byte_rate = new_byte_rate;
404 mpeg2_header_end (mpeg2dec);
405 mpeg2dec->action = invalid_end_action;
406 mpeg2dec->state = STATE_INVALID_END;
407 return;
408 }
409 sequence->byte_rate = new_byte_rate;
410 mpeg2dec->state = STATE_SEQUENCE_REPEATED;
411 } else
412 decoder->stride_frame = sequence->width;
413 mpeg2dec->sequence = *sequence;
414 mpeg2_reset_info (&(mpeg2dec->info));
415 mpeg2dec->info.sequence = &(mpeg2dec->sequence);
416 mpeg2dec->info.gop = NULL;
417 info_user_data (mpeg2dec);
418}
419
420int mpeg2_header_gop (mpeg2dec_t * mpeg2dec)
421{
422 uint8_t * buffer = mpeg2dec->chunk_start;
423 mpeg2_gop_t * gop = &(mpeg2dec->new_gop);
424
425 if (! (buffer[1] & 8))
426 return 1;
427 gop->hours = (buffer[0] >> 2) & 31;
428 gop->minutes = ((buffer[0] << 4) | (buffer[1] >> 4)) & 63;
429 gop->seconds = ((buffer[1] << 3) | (buffer[2] >> 5)) & 63;
430 gop->pictures = ((buffer[2] << 1) | (buffer[3] >> 7)) & 63;
431 gop->flags = (buffer[0] >> 7) | ((buffer[3] >> 4) & 6);
432 mpeg2dec->state = STATE_GOP;
433 return 0;
434}
435
436void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec)
437{
438 mpeg2dec->gop = mpeg2dec->new_gop;
439 mpeg2_reset_info (&(mpeg2dec->info));
440 mpeg2dec->info.gop = &(mpeg2dec->gop);
441 info_user_data (mpeg2dec);
442}
443
444void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type)
445{
446 int i;
447
448 for (i = 0; i < 3; i++)
449 if (mpeg2dec->fbuf[1] != &mpeg2dec->fbuf_alloc[i].fbuf &&
450 mpeg2dec->fbuf[2] != &mpeg2dec->fbuf_alloc[i].fbuf) {
451 mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[i].fbuf;
452 mpeg2dec->info.current_fbuf = mpeg2dec->fbuf[0];
453 if (b_type || (mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) {
454 if (b_type || mpeg2dec->convert)
455 mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[0];
456 mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[0];
457 }
458 break;
459 }
460}
461
462mpeg2_state_t mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec)
463{
464 mpeg2_picture_t * picture = &(mpeg2dec->new_picture);
465
466 mpeg2dec->state = ((mpeg2dec->state != STATE_SLICE_1ST) ?
467 STATE_PICTURE : STATE_PICTURE_2ND);
468 picture->flags = 0;
469 picture->tag = picture->tag2 = 0;
470 if (mpeg2dec->num_tags) {
471 if (mpeg2dec->bytes_since_tag >= 4) {
472 mpeg2dec->num_tags = 0;
473 picture->tag = mpeg2dec->tag_current;
474 picture->tag2 = mpeg2dec->tag2_current;
475 picture->flags = PIC_FLAG_TAGS;
476 } else if (mpeg2dec->num_tags > 1) {
477 mpeg2dec->num_tags = 1;
478 picture->tag = mpeg2dec->tag_previous;
479 picture->tag2 = mpeg2dec->tag2_previous;
480 picture->flags = PIC_FLAG_TAGS;
481 }
482 }
483 picture->display_offset[0].x = picture->display_offset[1].x =
484 picture->display_offset[2].x = mpeg2dec->display_offset_x;
485 picture->display_offset[0].y = picture->display_offset[1].y =
486 picture->display_offset[2].y = mpeg2dec->display_offset_y;
487 return mpeg2_parse_header (mpeg2dec);
488}
489
490int mpeg2_header_picture (mpeg2dec_t * mpeg2dec)
491{
492 uint8_t * buffer = mpeg2dec->chunk_start;
493 mpeg2_picture_t * picture = &(mpeg2dec->new_picture);
494 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
495 int type;
496
497 type = (buffer [1] >> 3) & 7;
498 mpeg2dec->ext_state = PIC_CODING_EXT;
499
500 picture->temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6);
501
502 picture->flags |= type;
503
504 if (type == PIC_FLAG_CODING_TYPE_P || type == PIC_FLAG_CODING_TYPE_B) {
505 /* forward_f_code and backward_f_code - used in mpeg1 only */
506 decoder->f_motion.f_code[1] = (buffer[3] >> 2) & 1;
507 decoder->f_motion.f_code[0] =
508 (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1;
509 decoder->b_motion.f_code[1] = (buffer[4] >> 6) & 1;
510 decoder->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1;
511 }
512
513 /* XXXXXX decode extra_information_picture as well */
514
515 picture->nb_fields = 2;
516
517 mpeg2dec->q_scale_type = 0;
518 decoder->intra_dc_precision = 7;
519 decoder->frame_pred_frame_dct = 1;
520 decoder->concealment_motion_vectors = 0;
521 decoder->scan = mpeg2_scan_norm;
522 decoder->picture_structure = FRAME_PICTURE;
523 mpeg2dec->copy_matrix = 0;
524
525 return 0;
526}
527
528static int picture_coding_ext (mpeg2dec_t * mpeg2dec)
529{
530 uint8_t * buffer = mpeg2dec->chunk_start;
531 mpeg2_picture_t * picture = &(mpeg2dec->new_picture);
532 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
533 uint32_t flags;
534
535 /* pre subtract 1 for use later in compute_motion_vector */
536 decoder->f_motion.f_code[0] = (buffer[0] & 15) - 1;
537 decoder->f_motion.f_code[1] = (buffer[1] >> 4) - 1;
538 decoder->b_motion.f_code[0] = (buffer[1] & 15) - 1;
539 decoder->b_motion.f_code[1] = (buffer[2] >> 4) - 1;
540
541 flags = picture->flags;
542 decoder->intra_dc_precision = 7 - ((buffer[2] >> 2) & 3);
543 decoder->picture_structure = buffer[2] & 3;
544 switch (decoder->picture_structure) {
545 case TOP_FIELD:
546 flags |= PIC_FLAG_TOP_FIELD_FIRST;
547 case BOTTOM_FIELD:
548 picture->nb_fields = 1;
549 break;
550 case FRAME_PICTURE:
551 if (!(mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)) {
552 picture->nb_fields = (buffer[3] & 2) ? 3 : 2;
553 flags |= (buffer[3] & 128) ? PIC_FLAG_TOP_FIELD_FIRST : 0;
554 } else
555 picture->nb_fields = (buffer[3]&2) ? ((buffer[3]&128) ? 6 : 4) : 2;
556 break;
557 default:
558 return 1;
559 }
560 decoder->top_field_first = buffer[3] >> 7;
561 decoder->frame_pred_frame_dct = (buffer[3] >> 6) & 1;
562 decoder->concealment_motion_vectors = (buffer[3] >> 5) & 1;
563 mpeg2dec->q_scale_type = buffer[3] & 16;
564 decoder->intra_vlc_format = (buffer[3] >> 3) & 1;
565 decoder->scan = (buffer[3] & 4) ? mpeg2_scan_alt : mpeg2_scan_norm;
566 flags |= (buffer[4] & 0x80) ? PIC_FLAG_PROGRESSIVE_FRAME : 0;
567 if (buffer[4] & 0x40)
568 flags |= (((buffer[4]<<26) | (buffer[5]<<18) | (buffer[6]<<10)) &
569 PIC_MASK_COMPOSITE_DISPLAY) | PIC_FLAG_COMPOSITE_DISPLAY;
570 picture->flags = flags;
571
572 mpeg2dec->ext_state = PIC_DISPLAY_EXT | COPYRIGHT_EXT | QUANT_MATRIX_EXT;
573
574 return 0;
575}
576
577static int picture_display_ext (mpeg2dec_t * mpeg2dec)
578{
579 uint8_t * buffer = mpeg2dec->chunk_start;
580 mpeg2_picture_t * picture = &(mpeg2dec->new_picture);
581 int i, nb_pos;
582
583 nb_pos = picture->nb_fields;
584 if (mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)
585 nb_pos >>= 1;
586
587 for (i = 0; i < nb_pos; i++) {
588 int x, y;
589
590 x = ((buffer[4*i] << 24) | (buffer[4*i+1] << 16) |
591 (buffer[4*i+2] << 8) | buffer[4*i+3]) >> (11-2*i);
592 y = ((buffer[4*i+2] << 24) | (buffer[4*i+3] << 16) |
593 (buffer[4*i+4] << 8) | buffer[4*i+5]) >> (10-2*i);
594 if (! (x & y & 1))
595 return 1;
596 picture->display_offset[i].x = mpeg2dec->display_offset_x = x >> 1;
597 picture->display_offset[i].y = mpeg2dec->display_offset_y = y >> 1;
598 }
599 for (; i < 3; i++) {
600 picture->display_offset[i].x = mpeg2dec->display_offset_x;
601 picture->display_offset[i].y = mpeg2dec->display_offset_y;
602 }
603 return 0;
604}
605
606void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels)
607{
608 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
609 int old_type_b = (decoder->coding_type == B_TYPE);
610 int low_delay = mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY;
611
612 finalize_matrix (mpeg2dec);
613 decoder->coding_type = mpeg2dec->new_picture.flags & PIC_MASK_CODING_TYPE;
614
615 if (mpeg2dec->state == STATE_PICTURE) {
616 mpeg2_picture_t * picture;
617 mpeg2_picture_t * other;
618
619 decoder->second_field = 0;
620
621 picture = other = mpeg2dec->pictures;
622 if (old_type_b ^ (mpeg2dec->picture < mpeg2dec->pictures + 2))
623 picture += 2;
624 else
625 other += 2;
626 mpeg2dec->picture = picture;
627 *picture = mpeg2dec->new_picture;
628
629 if (!old_type_b) {
630 mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1];
631 mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0];
632 }
633 mpeg2dec->fbuf[0] = NULL;
634 mpeg2_reset_info (&(mpeg2dec->info));
635 mpeg2dec->info.current_picture = picture;
636 mpeg2dec->info.display_picture = picture;
637 if (decoder->coding_type != B_TYPE) {
638 if (!low_delay) {
639 if (mpeg2dec->first) {
640 mpeg2dec->info.display_picture = NULL;
641 mpeg2dec->first = 0;
642 } else {
643 mpeg2dec->info.display_picture = other;
644 if (other->nb_fields == 1)
645 mpeg2dec->info.display_picture_2nd = other + 1;
646 mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[1];
647 }
648 }
649 if (!low_delay + !mpeg2dec->convert)
650 mpeg2dec->info.discard_fbuf =
651 mpeg2dec->fbuf[!low_delay + !mpeg2dec->convert];
652 }
653 if (mpeg2dec->convert) {
654 mpeg2_convert_init_t convert_init;
655 if (!mpeg2dec->convert_start) {
656 int y_size, uv_size;
657
658 mpeg2dec->decoder.convert_id =
659 mpeg2_malloc (mpeg2dec->convert_id_size,
660 MPEG2_ALLOC_CONVERT_ID);
661 mpeg2dec->convert (MPEG2_CONVERT_START,
662 mpeg2dec->decoder.convert_id,
663 &(mpeg2dec->sequence),
664 mpeg2dec->convert_stride, accels,
665 mpeg2dec->convert_arg, &convert_init);
666 mpeg2dec->convert_start = convert_init.start;
667 mpeg2dec->decoder.convert = convert_init.copy;
668
669 y_size = decoder->stride_frame * mpeg2dec->sequence.height;
670 uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format);
671 mpeg2dec->yuv_buf[0][0] =
672 (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV);
673 mpeg2dec->yuv_buf[0][1] =
674 (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);
675 mpeg2dec->yuv_buf[0][2] =
676 (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);
677 mpeg2dec->yuv_buf[1][0] =
678 (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV);
679 mpeg2dec->yuv_buf[1][1] =
680 (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);
681 mpeg2dec->yuv_buf[1][2] =
682 (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);
683 y_size = decoder->stride_frame * 32;
684 uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format);
685 mpeg2dec->yuv_buf[2][0] =
686 (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV);
687 mpeg2dec->yuv_buf[2][1] =
688 (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);
689 mpeg2dec->yuv_buf[2][2] =
690 (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV);
691 }
692 if (!mpeg2dec->custom_fbuf) {
693 while (mpeg2dec->alloc_index < 3) {
694 mpeg2_fbuf_t * fbuf;
695
696 fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf;
697 fbuf->id = NULL;
698 fbuf->buf[0] =
699 (uint8_t *) mpeg2_malloc (convert_init.buf_size[0],
700 MPEG2_ALLOC_CONVERTED);
701 fbuf->buf[1] =
702 (uint8_t *) mpeg2_malloc (convert_init.buf_size[1],
703 MPEG2_ALLOC_CONVERTED);
704 fbuf->buf[2] =
705 (uint8_t *) mpeg2_malloc (convert_init.buf_size[2],
706 MPEG2_ALLOC_CONVERTED);
707 }
708 mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE));
709 }
710 } else if (!mpeg2dec->custom_fbuf) {
711 while (mpeg2dec->alloc_index < 3) {
712 mpeg2_fbuf_t * fbuf;
713 int y_size, uv_size;
714
715 fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf);
716 fbuf->id = NULL;
717 y_size = decoder->stride_frame * mpeg2dec->sequence.height;
718 uv_size = y_size >> (2 - decoder->chroma_format);
719 fbuf->buf[0] = (uint8_t *) mpeg2_malloc (y_size,
720 MPEG2_ALLOC_YUV);
721 fbuf->buf[1] = (uint8_t *) mpeg2_malloc (uv_size,
722 MPEG2_ALLOC_YUV);
723 fbuf->buf[2] = (uint8_t *) mpeg2_malloc (uv_size,
724 MPEG2_ALLOC_YUV);
725 }
726 mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE));
727 }
728 } else {
729 decoder->second_field = 1;
730 mpeg2dec->picture++; /* second field picture */
731 *(mpeg2dec->picture) = mpeg2dec->new_picture;
732 mpeg2dec->info.current_picture_2nd = mpeg2dec->picture;
733 if (low_delay || decoder->coding_type == B_TYPE)
734 mpeg2dec->info.display_picture_2nd = mpeg2dec->picture;
735 }
736
737 info_user_data (mpeg2dec);
738}
739
740static int copyright_ext (mpeg2dec_t * mpeg2dec)
741{
742 (void)mpeg2dec;
743 return 0;
744}
745
746static int quant_matrix_ext (mpeg2dec_t * mpeg2dec)
747{
748 uint8_t * buffer = mpeg2dec->chunk_start;
749 int i, j;
750
751 for (i = 0; i < 4; i++)
752 if (buffer[0] & (8 >> i)) {
753 for (j = 0; j < 64; j++)
754 mpeg2dec->new_quantizer_matrix[i][mpeg2_scan_norm[j]] =
755 (buffer[j] << (i+5)) | (buffer[j+1] >> (3-i));
756 mpeg2dec->copy_matrix |= 1 << i;
757 buffer += 64;
758 }
759
760 return 0;
761}
762
763int mpeg2_header_extension (mpeg2dec_t * mpeg2dec)
764{
765 static int (* parser[]) (mpeg2dec_t *) = {
766 0, sequence_ext, sequence_display_ext, quant_matrix_ext,
767 copyright_ext, 0, 0, picture_display_ext, picture_coding_ext
768 };
769 int ext, ext_bit;
770
771 ext = mpeg2dec->chunk_start[0] >> 4;
772 ext_bit = 1 << ext;
773
774 if (!(mpeg2dec->ext_state & ext_bit))
775 return 0; /* ignore illegal extensions */
776 mpeg2dec->ext_state &= ~ext_bit;
777 return parser[ext] (mpeg2dec);
778}
779
780int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec)
781{
782 mpeg2dec->user_data_len += mpeg2dec->chunk_ptr - 1 - mpeg2dec->chunk_start;
783 mpeg2dec->chunk_start = mpeg2dec->chunk_ptr - 1;
784
785 return 0;
786}
787
788static void prescale (mpeg2dec_t * mpeg2dec, int index)
789{
790 static int non_linear_scale [] = {
791 0, 1, 2, 3, 4, 5, 6, 7,
792 8, 10, 12, 14, 16, 18, 20, 22,
793 24, 28, 32, 36, 40, 44, 48, 52,
794 56, 64, 72, 80, 88, 96, 104, 112
795 };
796 int i, j, k;
797 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
798
799 if (mpeg2dec->scaled[index] != mpeg2dec->q_scale_type) {
800 mpeg2dec->scaled[index] = mpeg2dec->q_scale_type;
801 for (i = 0; i < 32; i++) {
802 k = mpeg2dec->q_scale_type ? non_linear_scale[i] : (i << 1);
803 for (j = 0; j < 64; j++)
804 decoder->quantizer_prescale[index][i][j] =
805 k * mpeg2dec->quantizer_matrix[index][j];
806 }
807 }
808}
809
810mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec)
811{
812 mpeg2_decoder_t * decoder = &(mpeg2dec->decoder);
813
814 mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0;
815 mpeg2dec->state = ((mpeg2dec->picture->nb_fields > 1 ||
816 mpeg2dec->state == STATE_PICTURE_2ND) ?
817 STATE_SLICE : STATE_SLICE_1ST);
818
819 if (mpeg2dec->decoder.coding_type != D_TYPE) {
820 prescale (mpeg2dec, 0);
821 if (decoder->chroma_quantizer[0] == decoder->quantizer_prescale[2])
822 prescale (mpeg2dec, 2);
823 if (mpeg2dec->decoder.coding_type != I_TYPE) {
824 prescale (mpeg2dec, 1);
825 if (decoder->chroma_quantizer[1] == decoder->quantizer_prescale[3])
826 prescale (mpeg2dec, 3);
827 }
828 }
829
830 if (!(mpeg2dec->nb_decode_slices))
831 mpeg2dec->picture->flags |= PIC_FLAG_SKIP;
832 else if (mpeg2dec->convert_start) {
833 mpeg2dec->convert_start (decoder->convert_id, mpeg2dec->fbuf[0],
834 mpeg2dec->picture, mpeg2dec->info.gop);
835
836 if (mpeg2dec->decoder.coding_type == B_TYPE)
837 mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->yuv_buf[2],
838 mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1],
839 mpeg2dec->yuv_buf[mpeg2dec->yuv_index]);
840 else {
841 mpeg2_init_fbuf (&(mpeg2dec->decoder),
842 mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1],
843 mpeg2dec->yuv_buf[mpeg2dec->yuv_index],
844 mpeg2dec->yuv_buf[mpeg2dec->yuv_index]);
845 if (mpeg2dec->state == STATE_SLICE)
846 mpeg2dec->yuv_index ^= 1;
847 }
848 } else {
849 int b_type;
850
851 b_type = (mpeg2dec->decoder.coding_type == B_TYPE);
852 mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->fbuf[0]->buf,
853 mpeg2dec->fbuf[b_type + 1]->buf,
854 mpeg2dec->fbuf[b_type]->buf);
855 }
856 mpeg2dec->action = NULL;
857 return (mpeg2_state_t)-1;
858}
859
860static mpeg2_state_t seek_sequence (mpeg2dec_t * mpeg2dec)
861{
862 mpeg2_reset_info (&(mpeg2dec->info));
863 mpeg2dec->info.sequence = NULL;
864 mpeg2dec->info.gop = NULL;
865 mpeg2_header_state_init (mpeg2dec);
866 mpeg2dec->action = mpeg2_seek_header;
867 return mpeg2_seek_header (mpeg2dec);
868}
869
870mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec)
871{
872 mpeg2_picture_t * picture;
873 int b_type;
874
875 b_type = (mpeg2dec->decoder.coding_type == B_TYPE);
876 picture = mpeg2dec->pictures;
877 if ((mpeg2dec->picture >= picture + 2) ^ b_type)
878 picture = mpeg2dec->pictures + 2;
879
880 mpeg2_reset_info (&(mpeg2dec->info));
881 if (!(mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) {
882 mpeg2dec->info.display_picture = picture;
883 if (picture->nb_fields == 1)
884 mpeg2dec->info.display_picture_2nd = picture + 1;
885 mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[b_type];
886 if (!mpeg2dec->convert)
887 mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type + 1];
888 } else if (!mpeg2dec->convert)
889 mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type];
890 mpeg2dec->action = seek_sequence;
891 return STATE_END;
892}
diff --git a/apps/plugins/mpegplayer/idct.c b/apps/plugins/mpegplayer/idct.c
new file mode 100644
index 0000000000..8a0b56ea22
--- /dev/null
+++ b/apps/plugins/mpegplayer/idct.c
@@ -0,0 +1,287 @@
1/*
2 * idct.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "plugin.h"
25
26#include "mpeg2dec_config.h"
27
28#include "mpeg2.h"
29#include "attributes.h"
30#include "mpeg2_internal.h"
31
32#define W1 2841 /* 2048 * sqrt (2) * cos (1 * pi / 16) */
33#define W2 2676 /* 2048 * sqrt (2) * cos (2 * pi / 16) */
34#define W3 2408 /* 2048 * sqrt (2) * cos (3 * pi / 16) */
35#define W5 1609 /* 2048 * sqrt (2) * cos (5 * pi / 16) */
36#define W6 1108 /* 2048 * sqrt (2) * cos (6 * pi / 16) */
37#define W7 565 /* 2048 * sqrt (2) * cos (7 * pi / 16) */
38
39/* idct main entry point */
40void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride);
41void (* mpeg2_idct_add) (int last, int16_t * block,
42 uint8_t * dest, int stride);
43
44/*
45 * In legal streams, the IDCT output should be between -384 and +384.
46 * In corrupted streams, it is possible to force the IDCT output to go
47 * to +-3826 - this is the worst case for a column IDCT where the
48 * column inputs are 16-bit values.
49 */
50uint8_t mpeg2_clip[3840 * 2 + 256] IBSS_ATTR;
51#define CLIP(i) ((mpeg2_clip + 3840)[i])
52
53#if 0
54#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
55do { \
56 t0 = W0 * d0 + W1 * d1; \
57 t1 = W0 * d1 - W1 * d0; \
58} while (0)
59#else
60#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
61do { \
62 int tmp = W0 * (d0 + d1); \
63 t0 = tmp + (W1 - W0) * d1; \
64 t1 = tmp - (W1 + W0) * d0; \
65} while (0)
66#endif
67
68static inline void idct_row (int16_t * const block)
69{
70 int d0, d1, d2, d3;
71 int a0, a1, a2, a3, b0, b1, b2, b3;
72 int t0, t1, t2, t3;
73
74 /* shortcut */
75 if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] |
76 ((int32_t *)block)[3]))) {
77 uint32_t tmp = (uint16_t) (block[0] >> 1);
78 tmp |= tmp << 16;
79 ((int32_t *)block)[0] = tmp;
80 ((int32_t *)block)[1] = tmp;
81 ((int32_t *)block)[2] = tmp;
82 ((int32_t *)block)[3] = tmp;
83 return;
84 }
85
86 d0 = (block[0] << 11) + 2048;
87 d1 = block[1];
88 d2 = block[2] << 11;
89 d3 = block[3];
90 t0 = d0 + d2;
91 t1 = d0 - d2;
92 BUTTERFLY (t2, t3, W6, W2, d3, d1);
93 a0 = t0 + t2;
94 a1 = t1 + t3;
95 a2 = t1 - t3;
96 a3 = t0 - t2;
97
98 d0 = block[4];
99 d1 = block[5];
100 d2 = block[6];
101 d3 = block[7];
102 BUTTERFLY (t0, t1, W7, W1, d3, d0);
103 BUTTERFLY (t2, t3, W3, W5, d1, d2);
104 b0 = t0 + t2;
105 b3 = t1 + t3;
106 t0 -= t2;
107 t1 -= t3;
108 b1 = ((t0 + t1) >> 8) * 181;
109 b2 = ((t0 - t1) >> 8) * 181;
110
111 block[0] = (a0 + b0) >> 12;
112 block[1] = (a1 + b1) >> 12;
113 block[2] = (a2 + b2) >> 12;
114 block[3] = (a3 + b3) >> 12;
115 block[4] = (a3 - b3) >> 12;
116 block[5] = (a2 - b2) >> 12;
117 block[6] = (a1 - b1) >> 12;
118 block[7] = (a0 - b0) >> 12;
119}
120
121static inline void idct_col (int16_t * const block)
122{
123 int d0, d1, d2, d3;
124 int a0, a1, a2, a3, b0, b1, b2, b3;
125 int t0, t1, t2, t3;
126
127 d0 = (block[8*0] << 11) + 65536;
128 d1 = block[8*1];
129 d2 = block[8*2] << 11;
130 d3 = block[8*3];
131 t0 = d0 + d2;
132 t1 = d0 - d2;
133 BUTTERFLY (t2, t3, W6, W2, d3, d1);
134 a0 = t0 + t2;
135 a1 = t1 + t3;
136 a2 = t1 - t3;
137 a3 = t0 - t2;
138
139 d0 = block[8*4];
140 d1 = block[8*5];
141 d2 = block[8*6];
142 d3 = block[8*7];
143 BUTTERFLY (t0, t1, W7, W1, d3, d0);
144 BUTTERFLY (t2, t3, W3, W5, d1, d2);
145 b0 = t0 + t2;
146 b3 = t1 + t3;
147 t0 -= t2;
148 t1 -= t3;
149 b1 = ((t0 + t1) >> 8) * 181;
150 b2 = ((t0 - t1) >> 8) * 181;
151
152 block[8*0] = (a0 + b0) >> 17;
153 block[8*1] = (a1 + b1) >> 17;
154 block[8*2] = (a2 + b2) >> 17;
155 block[8*3] = (a3 + b3) >> 17;
156 block[8*4] = (a3 - b3) >> 17;
157 block[8*5] = (a2 - b2) >> 17;
158 block[8*6] = (a1 - b1) >> 17;
159 block[8*7] = (a0 - b0) >> 17;
160}
161
162static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest,
163 const int stride)
164{
165 int i;
166
167 for (i = 0; i < 8; i++)
168 idct_row (block + 8 * i);
169 for (i = 0; i < 8; i++)
170 idct_col (block + i);
171 do {
172 dest[0] = CLIP (block[0]);
173 dest[1] = CLIP (block[1]);
174 dest[2] = CLIP (block[2]);
175 dest[3] = CLIP (block[3]);
176 dest[4] = CLIP (block[4]);
177 dest[5] = CLIP (block[5]);
178 dest[6] = CLIP (block[6]);
179 dest[7] = CLIP (block[7]);
180
181 ((int32_t *)block)[0] = 0; ((int32_t *)block)[1] = 0;
182 ((int32_t *)block)[2] = 0; ((int32_t *)block)[3] = 0;
183
184 dest += stride;
185 block += 8;
186 } while (--i);
187}
188
189static void mpeg2_idct_add_c (const int last, int16_t * block,
190 uint8_t * dest, const int stride)
191{
192 int i;
193
194 if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) {
195 for (i = 0; i < 8; i++)
196 idct_row (block + 8 * i);
197 for (i = 0; i < 8; i++)
198 idct_col (block + i);
199 do {
200 dest[0] = CLIP (block[0] + dest[0]);
201 dest[1] = CLIP (block[1] + dest[1]);
202 dest[2] = CLIP (block[2] + dest[2]);
203 dest[3] = CLIP (block[3] + dest[3]);
204 dest[4] = CLIP (block[4] + dest[4]);
205 dest[5] = CLIP (block[5] + dest[5]);
206 dest[6] = CLIP (block[6] + dest[6]);
207 dest[7] = CLIP (block[7] + dest[7]);
208
209 ((int32_t *)block)[0] = 0; ((int32_t *)block)[1] = 0;
210 ((int32_t *)block)[2] = 0; ((int32_t *)block)[3] = 0;
211
212 dest += stride;
213 block += 8;
214 } while (--i);
215 } else {
216 int DC;
217
218 DC = (block[0] + 64) >> 7;
219 block[0] = block[63] = 0;
220 i = 8;
221 do {
222 dest[0] = CLIP (DC + dest[0]);
223 dest[1] = CLIP (DC + dest[1]);
224 dest[2] = CLIP (DC + dest[2]);
225 dest[3] = CLIP (DC + dest[3]);
226 dest[4] = CLIP (DC + dest[4]);
227 dest[5] = CLIP (DC + dest[5]);
228 dest[6] = CLIP (DC + dest[6]);
229 dest[7] = CLIP (DC + dest[7]);
230 dest += stride;
231 } while (--i);
232 }
233}
234
235void mpeg2_idct_init (uint32_t accel)
236{
237 (void)accel;
238#ifdef ARCH_X86
239 if (accel & MPEG2_ACCEL_X86_MMXEXT) {
240 mpeg2_idct_copy = mpeg2_idct_copy_mmxext;
241 mpeg2_idct_add = mpeg2_idct_add_mmxext;
242 mpeg2_idct_mmx_init ();
243 } else if (accel & MPEG2_ACCEL_X86_MMX) {
244 mpeg2_idct_copy = mpeg2_idct_copy_mmx;
245 mpeg2_idct_add = mpeg2_idct_add_mmx;
246 mpeg2_idct_mmx_init ();
247 } else
248#endif
249#ifdef ARCH_PPC
250 if (accel & MPEG2_ACCEL_PPC_ALTIVEC) {
251 mpeg2_idct_copy = mpeg2_idct_copy_altivec;
252 mpeg2_idct_add = mpeg2_idct_add_altivec;
253 mpeg2_idct_altivec_init ();
254 } else
255#endif
256#ifdef ARCH_ALPHA
257 if (accel & MPEG2_ACCEL_ALPHA_MVI) {
258 mpeg2_idct_copy = mpeg2_idct_copy_mvi;
259 mpeg2_idct_add = mpeg2_idct_add_mvi;
260 mpeg2_idct_alpha_init ();
261 } else if (accel & MPEG2_ACCEL_ALPHA) {
262 int i;
263
264 mpeg2_idct_copy = mpeg2_idct_copy_alpha;
265 mpeg2_idct_add = mpeg2_idct_add_alpha;
266 mpeg2_idct_alpha_init ();
267 for (i = -3840; i < 3840 + 256; i++)
268 CLIP(i) = (i < 0) ? 0 : ((i > 255) ? 255 : i);
269 } else
270#endif
271 {
272 extern uint8_t mpeg2_scan_norm[64];
273 extern uint8_t mpeg2_scan_alt[64];
274 int i, j;
275
276 mpeg2_idct_copy = mpeg2_idct_copy_c;
277 mpeg2_idct_add = mpeg2_idct_add_c;
278 for (i = -3840; i < 3840 + 256; i++)
279 CLIP(i) = (i < 0) ? 0 : ((i > 255) ? 255 : i);
280 for (i = 0; i < 64; i++) {
281 j = mpeg2_scan_norm[i];
282 mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
283 j = mpeg2_scan_alt[i];
284 mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
285 }
286 }
287}
diff --git a/apps/plugins/mpegplayer/motion_comp.c b/apps/plugins/mpegplayer/motion_comp.c
new file mode 100644
index 0000000000..fbf2ee1eb4
--- /dev/null
+++ b/apps/plugins/mpegplayer/motion_comp.c
@@ -0,0 +1,131 @@
1/*
2 * motion_comp.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "plugin.h"
25
26#include "mpeg2dec_config.h"
27
28#include "mpeg2.h"
29#include "attributes.h"
30#include "mpeg2_internal.h"
31
32mpeg2_mc_t mpeg2_mc;
33
34void mpeg2_mc_init (uint32_t accel)
35{
36 (void)accel;
37#ifdef ARCH_X86
38 if (accel & MPEG2_ACCEL_X86_MMXEXT)
39 mpeg2_mc = mpeg2_mc_mmxext;
40 else if (accel & MPEG2_ACCEL_X86_3DNOW)
41 mpeg2_mc = mpeg2_mc_3dnow;
42 else if (accel & MPEG2_ACCEL_X86_MMX)
43 mpeg2_mc = mpeg2_mc_mmx;
44 else
45#endif
46#ifdef ARCH_PPC
47 if (accel & MPEG2_ACCEL_PPC_ALTIVEC)
48 mpeg2_mc = mpeg2_mc_altivec;
49 else
50#endif
51#ifdef ARCH_ALPHA
52 if (accel & MPEG2_ACCEL_ALPHA)
53 mpeg2_mc = mpeg2_mc_alpha;
54 else
55#endif
56#ifdef ARCH_SPARC
57 if (accel & MPEG2_ACCEL_SPARC_VIS)
58 mpeg2_mc = mpeg2_mc_vis;
59 else
60#endif
61 mpeg2_mc = mpeg2_mc_c;
62}
63
64#define avg2(a,b) ((a+b+1)>>1)
65#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
66
67#define predict_o(i) (ref[i])
68#define predict_x(i) (avg2 (ref[i], ref[i+1]))
69#define predict_y(i) (avg2 (ref[i], (ref+stride)[i]))
70#define predict_xy(i) (avg4 (ref[i], ref[i+1], \
71 (ref+stride)[i], (ref+stride)[i+1]))
72
73#define put(predictor,i) dest[i] = predictor (i)
74#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i])
75
76/* mc function template */
77
78#define MC_FUNC(op,xy) \
79static void MC_##op##_##xy##_16_c (uint8_t * dest, const uint8_t * ref, \
80 const int stride, int height) \
81{ \
82 do { \
83 op (predict_##xy, 0); \
84 op (predict_##xy, 1); \
85 op (predict_##xy, 2); \
86 op (predict_##xy, 3); \
87 op (predict_##xy, 4); \
88 op (predict_##xy, 5); \
89 op (predict_##xy, 6); \
90 op (predict_##xy, 7); \
91 op (predict_##xy, 8); \
92 op (predict_##xy, 9); \
93 op (predict_##xy, 10); \
94 op (predict_##xy, 11); \
95 op (predict_##xy, 12); \
96 op (predict_##xy, 13); \
97 op (predict_##xy, 14); \
98 op (predict_##xy, 15); \
99 ref += stride; \
100 dest += stride; \
101 } while (--height); \
102} \
103static void MC_##op##_##xy##_8_c (uint8_t * dest, const uint8_t * ref, \
104 const int stride, int height) \
105{ \
106 do { \
107 op (predict_##xy, 0); \
108 op (predict_##xy, 1); \
109 op (predict_##xy, 2); \
110 op (predict_##xy, 3); \
111 op (predict_##xy, 4); \
112 op (predict_##xy, 5); \
113 op (predict_##xy, 6); \
114 op (predict_##xy, 7); \
115 ref += stride; \
116 dest += stride; \
117 } while (--height); \
118}
119
120/* definitions of the actual mc functions */
121
122MC_FUNC (put,o)
123MC_FUNC (avg,o)
124MC_FUNC (put,x)
125MC_FUNC (avg,x)
126MC_FUNC (put,y)
127MC_FUNC (avg,y)
128MC_FUNC (put,xy)
129MC_FUNC (avg,xy)
130
131MPEG2_MC_EXTERN (c)
diff --git a/apps/plugins/mpegplayer/mpeg2.h b/apps/plugins/mpegplayer/mpeg2.h
new file mode 100644
index 0000000000..6062f93010
--- /dev/null
+++ b/apps/plugins/mpegplayer/mpeg2.h
@@ -0,0 +1,195 @@
1/*
2 * mpeg2.h
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#ifndef MPEG2_H
25#define MPEG2_H
26
27#define MPEG2_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c))
28#define MPEG2_RELEASE MPEG2_VERSION (0, 4, 0) /* 0.4.0 */
29
30#define SEQ_FLAG_MPEG2 1
31#define SEQ_FLAG_CONSTRAINED_PARAMETERS 2
32#define SEQ_FLAG_PROGRESSIVE_SEQUENCE 4
33#define SEQ_FLAG_LOW_DELAY 8
34#define SEQ_FLAG_COLOUR_DESCRIPTION 16
35
36#define SEQ_MASK_VIDEO_FORMAT 0xe0
37#define SEQ_VIDEO_FORMAT_COMPONENT 0
38#define SEQ_VIDEO_FORMAT_PAL 0x20
39#define SEQ_VIDEO_FORMAT_NTSC 0x40
40#define SEQ_VIDEO_FORMAT_SECAM 0x60
41#define SEQ_VIDEO_FORMAT_MAC 0x80
42#define SEQ_VIDEO_FORMAT_UNSPECIFIED 0xa0
43
44typedef struct mpeg2_sequence_s {
45 unsigned int width, height;
46 unsigned int chroma_width, chroma_height;
47 unsigned int byte_rate;
48 unsigned int vbv_buffer_size;
49 uint32_t flags;
50
51 unsigned int picture_width, picture_height;
52 unsigned int display_width, display_height;
53 unsigned int pixel_width, pixel_height;
54 unsigned int frame_period;
55
56 uint8_t profile_level_id;
57 uint8_t colour_primaries;
58 uint8_t transfer_characteristics;
59 uint8_t matrix_coefficients;
60} mpeg2_sequence_t;
61
62#define GOP_FLAG_DROP_FRAME 1
63#define GOP_FLAG_BROKEN_LINK 2
64#define GOP_FLAG_CLOSED_GOP 4
65
66typedef struct mpeg2_gop_s {
67 uint8_t hours;
68 uint8_t minutes;
69 uint8_t seconds;
70 uint8_t pictures;
71 uint32_t flags;
72} mpeg2_gop_t;
73
74#define PIC_MASK_CODING_TYPE 7
75#define PIC_FLAG_CODING_TYPE_I 1
76#define PIC_FLAG_CODING_TYPE_P 2
77#define PIC_FLAG_CODING_TYPE_B 3
78#define PIC_FLAG_CODING_TYPE_D 4
79
80#define PIC_FLAG_TOP_FIELD_FIRST 8
81#define PIC_FLAG_PROGRESSIVE_FRAME 16
82#define PIC_FLAG_COMPOSITE_DISPLAY 32
83#define PIC_FLAG_SKIP 64
84#define PIC_FLAG_TAGS 128
85#define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000
86
87typedef struct mpeg2_picture_s {
88 unsigned int temporal_reference;
89 unsigned int nb_fields;
90 uint32_t tag, tag2;
91 uint32_t flags;
92 struct {
93 int x, y;
94 } display_offset[3];
95} mpeg2_picture_t;
96
97typedef struct mpeg2_fbuf_s {
98 uint8_t * buf[3];
99 void * id;
100} mpeg2_fbuf_t;
101
102typedef struct mpeg2_info_s {
103 const mpeg2_sequence_t * sequence;
104 const mpeg2_gop_t * gop;
105 const mpeg2_picture_t * current_picture;
106 const mpeg2_picture_t * current_picture_2nd;
107 const mpeg2_fbuf_t * current_fbuf;
108 const mpeg2_picture_t * display_picture;
109 const mpeg2_picture_t * display_picture_2nd;
110 const mpeg2_fbuf_t * display_fbuf;
111 const mpeg2_fbuf_t * discard_fbuf;
112 const uint8_t * user_data;
113 unsigned int user_data_len;
114} mpeg2_info_t;
115
116typedef struct mpeg2dec_s mpeg2dec_t;
117typedef struct mpeg2_decoder_s mpeg2_decoder_t;
118
119typedef enum {
120 STATE_BUFFER = 0,
121 STATE_SEQUENCE = 1,
122 STATE_SEQUENCE_REPEATED = 2,
123 STATE_GOP = 3,
124 STATE_PICTURE = 4,
125 STATE_SLICE_1ST = 5,
126 STATE_PICTURE_2ND = 6,
127 STATE_SLICE = 7,
128 STATE_END = 8,
129 STATE_INVALID = 9,
130 STATE_INVALID_END = 10
131} mpeg2_state_t;
132
133typedef struct mpeg2_convert_init_s {
134 unsigned int id_size;
135 unsigned int buf_size[3];
136 void (* start) (void * id, const mpeg2_fbuf_t * fbuf,
137 const mpeg2_picture_t * picture, const mpeg2_gop_t * gop);
138 void (* copy) (void * id, uint8_t * const * src, unsigned int v_offset);
139} mpeg2_convert_init_t;
140typedef enum {
141 MPEG2_CONVERT_SET = 0,
142 MPEG2_CONVERT_STRIDE = 1,
143 MPEG2_CONVERT_START = 2
144} mpeg2_convert_stage_t;
145typedef int mpeg2_convert_t (int stage, void * id,
146 const mpeg2_sequence_t * sequence, int stride,
147 uint32_t accel, void * arg,
148 mpeg2_convert_init_t * result);
149int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg);
150int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride);
151void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id);
152void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf);
153
154#define MPEG2_ACCEL_X86_MMX 1
155#define MPEG2_ACCEL_X86_3DNOW 2
156#define MPEG2_ACCEL_X86_MMXEXT 4
157#define MPEG2_ACCEL_PPC_ALTIVEC 1
158#define MPEG2_ACCEL_ALPHA 1
159#define MPEG2_ACCEL_ALPHA_MVI 2
160#define MPEG2_ACCEL_SPARC_VIS 1
161#define MPEG2_ACCEL_SPARC_VIS2 2
162#define MPEG2_ACCEL_DETECT 0x80000000
163
164uint32_t mpeg2_accel (uint32_t accel);
165mpeg2dec_t * mpeg2_init (void);
166const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec);
167void mpeg2_close (mpeg2dec_t * mpeg2dec);
168
169void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end);
170int mpeg2_getpos (mpeg2dec_t * mpeg2dec);
171mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec);
172
173void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset);
174void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip);
175void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end);
176
177void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2);
178
179void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3],
180 uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]);
181void mpeg2_slice (mpeg2_decoder_t * decoder, int code, const uint8_t * buffer);
182
183typedef enum {
184 MPEG2_ALLOC_MPEG2DEC = 0,
185 MPEG2_ALLOC_CHUNK = 1,
186 MPEG2_ALLOC_YUV = 2,
187 MPEG2_ALLOC_CONVERT_ID = 3,
188 MPEG2_ALLOC_CONVERTED = 4
189} mpeg2_alloc_t;
190
191void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason);
192void mpeg2_free (void * buf);
193void mpeg2_alloc_init(unsigned char* buf, int mallocsize);
194
195#endif /* MPEG2_H */
diff --git a/apps/plugins/mpegplayer/mpeg2_internal.h b/apps/plugins/mpegplayer/mpeg2_internal.h
new file mode 100644
index 0000000000..850456b1f8
--- /dev/null
+++ b/apps/plugins/mpegplayer/mpeg2_internal.h
@@ -0,0 +1,300 @@
1/*
2 * mpeg2_internal.h
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/* macroblock modes */
25#define MACROBLOCK_INTRA 1
26#define MACROBLOCK_PATTERN 2
27#define MACROBLOCK_MOTION_BACKWARD 4
28#define MACROBLOCK_MOTION_FORWARD 8
29#define MACROBLOCK_QUANT 16
30#define DCT_TYPE_INTERLACED 32
31/* motion_type */
32#define MOTION_TYPE_SHIFT 6
33#define MC_FIELD 1
34#define MC_FRAME 2
35#define MC_16X8 2
36#define MC_DMV 3
37
38/* picture structure */
39#define TOP_FIELD 1
40#define BOTTOM_FIELD 2
41#define FRAME_PICTURE 3
42
43/* picture coding type */
44#define I_TYPE 1
45#define P_TYPE 2
46#define B_TYPE 3
47#define D_TYPE 4
48
49typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int);
50
51typedef struct {
52 uint8_t * ref[2][3];
53 uint8_t ** ref2[2];
54 int pmv[2][2];
55 int f_code[2];
56} motion_t;
57
58typedef void motion_parser_t (mpeg2_decoder_t * decoder,
59 motion_t * motion,
60 mpeg2_mc_fct * const * table);
61
62struct mpeg2_decoder_s {
63 /* first, state that carries information from one macroblock to the */
64 /* next inside a slice, and is never used outside of mpeg2_slice() */
65
66 /* bit parsing stuff */
67 uint32_t bitstream_buf; /* current 32 bit working set */
68 int bitstream_bits; /* used bits in working set */
69 const uint8_t * bitstream_ptr; /* buffer with stream data */
70
71 uint8_t * dest[3];
72
73 int offset;
74 int stride;
75 int uv_stride;
76 int slice_stride;
77 int slice_uv_stride;
78 int stride_frame;
79 unsigned int limit_x;
80 unsigned int limit_y_16;
81 unsigned int limit_y_8;
82 unsigned int limit_y;
83
84 /* Motion vectors */
85 /* The f_ and b_ correspond to the forward and backward motion */
86 /* predictors */
87 motion_t b_motion;
88 motion_t f_motion;
89 motion_parser_t * motion_parser[5];
90
91 /* predictor for DC coefficients in intra blocks */
92 int16_t dc_dct_pred[3];
93
94 /* DCT coefficients */
95 int16_t DCTblock[64] ATTR_ALIGN(64);
96
97 uint8_t * picture_dest[3];
98 void (* convert) (void * convert_id, uint8_t * const * src,
99 unsigned int v_offset);
100 void * convert_id;
101
102 int dmv_offset;
103 unsigned int v_offset;
104
105 /* now non-slice-specific information */
106
107 /* sequence header stuff */
108 uint16_t * quantizer_matrix[4];
109 uint16_t (* chroma_quantizer[2])[64];
110 uint16_t quantizer_prescale[4][32][64];
111
112 /* The width and height of the picture snapped to macroblock units */
113 int width;
114 int height;
115 int vertical_position_extension;
116 int chroma_format;
117
118 /* picture header stuff */
119
120 /* what type of picture this is (I, P, B, D) */
121 int coding_type;
122
123 /* picture coding extension stuff */
124
125 /* quantization factor for intra dc coefficients */
126 int intra_dc_precision;
127 /* top/bottom/both fields */
128 int picture_structure;
129 /* bool to indicate all predictions are frame based */
130 int frame_pred_frame_dct;
131 /* bool to indicate whether intra blocks have motion vectors */
132 /* (for concealment) */
133 int concealment_motion_vectors;
134 /* bool to use different vlc tables */
135 int intra_vlc_format;
136 /* used for DMV MC */
137 int top_field_first;
138
139 /* stuff derived from bitstream */
140
141 /* pointer to the zigzag scan we're supposed to be using */
142 const uint8_t * scan;
143
144 int second_field;
145
146 int mpeg1;
147};
148
149typedef struct {
150 mpeg2_fbuf_t fbuf;
151} fbuf_alloc_t;
152
153struct mpeg2dec_s {
154 mpeg2_decoder_t decoder;
155
156 mpeg2_info_t info;
157
158 uint32_t shift;
159 int is_display_initialized;
160 mpeg2_state_t (* action) (struct mpeg2dec_s * mpeg2dec);
161 mpeg2_state_t state;
162 uint32_t ext_state;
163
164 /* allocated in init - gcc has problems allocating such big structures */
165 uint8_t * chunk_buffer;
166 /* pointer to start of the current chunk */
167 uint8_t * chunk_start;
168 /* pointer to current position in chunk_buffer */
169 uint8_t * chunk_ptr;
170 /* last start code ? */
171 uint8_t code;
172
173 /* picture tags */
174 uint32_t tag_current, tag2_current, tag_previous, tag2_previous;
175 int num_tags;
176 int bytes_since_tag;
177
178 int first;
179 int alloc_index_user;
180 int alloc_index;
181 uint8_t first_decode_slice;
182 uint8_t nb_decode_slices;
183
184 unsigned int user_data_len;
185
186 mpeg2_sequence_t new_sequence;
187 mpeg2_sequence_t sequence;
188 mpeg2_gop_t new_gop;
189 mpeg2_gop_t gop;
190 mpeg2_picture_t new_picture;
191 mpeg2_picture_t pictures[4];
192 mpeg2_picture_t * picture;
193 /*const*/ mpeg2_fbuf_t * fbuf[3]; /* 0: current fbuf, 1-2: prediction fbufs */
194
195 fbuf_alloc_t fbuf_alloc[3];
196 int custom_fbuf;
197
198 uint8_t * yuv_buf[3][3];
199 int yuv_index;
200 mpeg2_convert_t * convert;
201 void * convert_arg;
202 unsigned int convert_id_size;
203 int convert_stride;
204 void (* convert_start) (void * id, const mpeg2_fbuf_t * fbuf,
205 const mpeg2_picture_t * picture,
206 const mpeg2_gop_t * gop);
207
208 uint8_t * buf_start;
209 uint8_t * buf_end;
210
211 int16_t display_offset_x, display_offset_y;
212
213 int copy_matrix;
214 int8_t q_scale_type, scaled[4];
215 uint8_t quantizer_matrix[4][64];
216 uint8_t new_quantizer_matrix[4][64];
217};
218
219typedef struct {
220#ifdef ARCH_PPC
221 uint8_t regv[12*16];
222#endif
223 int dummy;
224} cpu_state_t;
225
226/* cpu_accel.c */
227uint32_t mpeg2_detect_accel (void);
228
229/* cpu_state.c */
230void mpeg2_cpu_state_init (uint32_t accel);
231
232/* decode.c */
233mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec);
234mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec);
235
236/* header.c */
237void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec);
238void mpeg2_reset_info (mpeg2_info_t * info);
239int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec);
240int mpeg2_header_gop (mpeg2dec_t * mpeg2dec);
241mpeg2_state_t mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec);
242int mpeg2_header_picture (mpeg2dec_t * mpeg2dec);
243int mpeg2_header_extension (mpeg2dec_t * mpeg2dec);
244int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec);
245void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec);
246void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec);
247void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels);
248mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec);
249mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec);
250void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type);
251
252/* idct.c */
253void mpeg2_idct_init (uint32_t accel);
254
255/* idct_mmx.c */
256void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride);
257void mpeg2_idct_add_mmxext (int last, int16_t * block,
258 uint8_t * dest, int stride);
259void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride);
260void mpeg2_idct_add_mmx (int last, int16_t * block,
261 uint8_t * dest, int stride);
262void mpeg2_idct_mmx_init (void);
263
264/* idct_altivec.c */
265void mpeg2_idct_copy_altivec (int16_t * block, uint8_t * dest, int stride);
266void mpeg2_idct_add_altivec (int last, int16_t * block,
267 uint8_t * dest, int stride);
268void mpeg2_idct_altivec_init (void);
269
270/* idct_alpha.c */
271void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, int stride);
272void mpeg2_idct_add_mvi (int last, int16_t * block,
273 uint8_t * dest, int stride);
274void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, int stride);
275void mpeg2_idct_add_alpha (int last, int16_t * block,
276 uint8_t * dest, int stride);
277void mpeg2_idct_alpha_init (void);
278
279/* motion_comp.c */
280void mpeg2_mc_init (uint32_t accel);
281
282typedef struct {
283 mpeg2_mc_fct * put [8];
284 mpeg2_mc_fct * avg [8];
285} mpeg2_mc_t;
286
287#define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \
288 {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \
289 MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \
290 {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \
291 MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \
292};
293
294extern mpeg2_mc_t mpeg2_mc_c;
295extern mpeg2_mc_t mpeg2_mc_mmx;
296extern mpeg2_mc_t mpeg2_mc_mmxext;
297extern mpeg2_mc_t mpeg2_mc_3dnow;
298extern mpeg2_mc_t mpeg2_mc_altivec;
299extern mpeg2_mc_t mpeg2_mc_alpha;
300extern mpeg2_mc_t mpeg2_mc_vis;
diff --git a/apps/plugins/mpegplayer/mpeg2dec_config.h b/apps/plugins/mpegplayer/mpeg2dec_config.h
new file mode 100644
index 0000000000..b8ad11664a
--- /dev/null
+++ b/apps/plugins/mpegplayer/mpeg2dec_config.h
@@ -0,0 +1,2 @@
1#define ATTRIBUTE_ALIGNED_MAX 16
2
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
new file mode 100644
index 0000000000..ce4199a1d0
--- /dev/null
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -0,0 +1,246 @@
1/*
2 * mpegplayer.c - based on mpeg2dec.c
3 *
4 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
5 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
6 *
7 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
8 * See http://libmpeg2.sourceforge.net/ for updates.
9 *
10 * mpeg2dec is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * mpeg2dec is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include "mpeg2dec_config.h"
26
27#include "plugin.h"
28
29#include "mpeg2.h"
30#include "video_out.h"
31
32PLUGIN_HEADER
33
34#ifdef USE_IRAM
35extern char iramcopy[];
36extern char iramstart[];
37extern char iramend[];
38extern char iedata[];
39extern char iend[];
40#endif
41
42struct plugin_api* rb;
43
44#define BUFFER_SIZE 25*1024*1024
45
46static mpeg2dec_t * mpeg2dec;
47static vo_open_t * output_open = NULL;
48static vo_instance_t * output;
49static int total_offset = 0;
50
51extern vo_open_t vo_rockbox_open;
52
53static void decode_mpeg2 (uint8_t * current, uint8_t * end)
54{
55 const mpeg2_info_t * info;
56 mpeg2_state_t state;
57 vo_setup_result_t setup_result;
58
59 mpeg2_buffer (mpeg2dec, current, end);
60 total_offset += end - current;
61
62 info = mpeg2_info (mpeg2dec);
63 while (1) {
64 state = mpeg2_parse (mpeg2dec);
65
66 switch (state) {
67 case STATE_BUFFER:
68 return;
69 case STATE_SEQUENCE:
70 /* might set nb fbuf, convert format, stride */
71 /* might set fbufs */
72 if (output->setup (output, info->sequence->width,
73 info->sequence->height,
74 info->sequence->chroma_width,
75 info->sequence->chroma_height, &setup_result)) {
76 //fprintf (stderr, "display setup failed\n");
77 return;
78 }
79 if (setup_result.convert &&
80 mpeg2_convert (mpeg2dec, setup_result.convert, NULL)) {
81 //fprintf (stderr, "color conversion setup failed\n");
82 return;
83 }
84 if (output->set_fbuf) {
85 uint8_t * buf[3];
86 void * id;
87
88 mpeg2_custom_fbuf (mpeg2dec, 1);
89 output->set_fbuf (output, buf, &id);
90 mpeg2_set_buf (mpeg2dec, buf, id);
91 output->set_fbuf (output, buf, &id);
92 mpeg2_set_buf (mpeg2dec, buf, id);
93 } else if (output->setup_fbuf) {
94 uint8_t * buf[3];
95 void * id;
96
97 output->setup_fbuf (output, buf, &id);
98 mpeg2_set_buf (mpeg2dec, buf, id);
99 output->setup_fbuf (output, buf, &id);
100 mpeg2_set_buf (mpeg2dec, buf, id);
101 output->setup_fbuf (output, buf, &id);
102 mpeg2_set_buf (mpeg2dec, buf, id);
103 }
104 mpeg2_skip (mpeg2dec, (output->draw == NULL));
105 break;
106 case STATE_PICTURE:
107 /* might skip */
108 /* might set fbuf */
109 if (output->set_fbuf) {
110 uint8_t * buf[3];
111 void * id;
112
113 output->set_fbuf (output, buf, &id);
114 mpeg2_set_buf (mpeg2dec, buf, id);
115 }
116 if (output->start_fbuf)
117 output->start_fbuf (output, info->current_fbuf->buf,
118 info->current_fbuf->id);
119 break;
120 case STATE_SLICE:
121 case STATE_END:
122 case STATE_INVALID_END:
123 /* draw current picture */
124 /* might free frame buffer */
125 if (info->display_fbuf) {
126 if (output->draw)
127 output->draw (output, info->display_fbuf->buf,
128 info->display_fbuf->id);
129 //print_fps (0);
130 }
131 if (output->discard && info->discard_fbuf)
132 output->discard (output, info->discard_fbuf->buf,
133 info->discard_fbuf->id);
134 break;
135 default:
136 break;
137 }
138
139 rb->yield();
140 }
141}
142
143static void es_loop (int in_file)
144{
145 static uint8_t* buffer;
146 uint8_t * end;
147
148 buffer=mpeg2_malloc(BUFFER_SIZE,0);
149
150 if (buffer==NULL)
151 return;
152
153 do {
154 rb->splash(0,true,"Buffering...");
155 end = buffer + rb->read (in_file, buffer, BUFFER_SIZE);
156 decode_mpeg2 (buffer, end);
157 } while (end == buffer + BUFFER_SIZE);
158}
159
160enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
161{
162 (void)parameter;
163 void* audiobuf;
164 int audiosize;
165 int in_file;
166
167 rb = api;
168
169 /* This also stops audio playback - so we do it before using IRAM */
170 audiobuf = rb->plugin_get_audio_buffer(&audiosize);
171
172 /* Initialise our malloc buffer */
173 mpeg2_alloc_init(audiobuf,audiosize);
174
175#ifdef USE_IRAM
176 rb->memcpy(iramstart, iramcopy, iramend-iramstart);
177 rb->memset(iedata, 0, iend - iedata);
178#endif
179
180#ifdef HAVE_LCD_COLOR
181 rb->lcd_set_foreground(LCD_WHITE);
182 rb->lcd_set_background(LCD_BLACK);
183#endif
184 rb->lcd_clear_display();
185 rb->lcd_update();
186
187 if (parameter == NULL) {
188 return PLUGIN_ERROR;
189 }
190
191 in_file = rb->open((char*)parameter,O_RDONLY);
192
193 if (in_file < 0) {
194 //fprintf(stderr,"Could not open %s\n",argv[1]);
195 return PLUGIN_ERROR;
196 }
197
198 output_open = vo_rockbox_open;
199
200 if (output_open == NULL) {
201 //fprintf (stderr, "output_open is NULL\n");
202 return PLUGIN_ERROR;
203 }
204
205 output = output_open ();
206
207 if (output == NULL) {
208 //fprintf (stderr, "Can not open output\n");
209 return PLUGIN_ERROR;
210 }
211
212 mpeg2dec = mpeg2_init ();
213
214 if (mpeg2dec == NULL)
215 return PLUGIN_ERROR;
216
217 /* make sure the backlight is always on when viewing video
218 (actually it should also set the timeout when plugged in,
219 but the function backlight_set_timeout_plugged is not
220 available in plugins) */
221#ifdef CONFIG_BACKLIGHT
222 if (rb->global_settings->backlight_timeout > 0)
223 rb->backlight_set_timeout(1);
224#endif
225
226#ifdef HAVE_ADJUSTABLE_CPU_FREQ
227 rb->cpu_boost(true);
228#endif
229
230 es_loop (in_file);
231
232 mpeg2_close (mpeg2dec);
233
234 rb->close (in_file);
235
236#ifdef HAVE_ADJUSTABLE_CPU_FREQ
237 rb->cpu_boost(false);
238#endif
239
240#ifdef CONFIG_BACKLIGHT
241 /* reset backlight settings */
242 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
243#endif
244
245 return PLUGIN_OK;
246}
diff --git a/apps/plugins/mpegplayer/slice.c b/apps/plugins/mpegplayer/slice.c
new file mode 100644
index 0000000000..8ee341739d
--- /dev/null
+++ b/apps/plugins/mpegplayer/slice.c
@@ -0,0 +1,2060 @@
1/*
2 * slice.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 2003 Peter Gubanov <peter@elecard.net.ru>
5 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
6 *
7 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
8 * See http://libmpeg2.sourceforge.net/ for updates.
9 *
10 * mpeg2dec is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * mpeg2dec is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include "plugin.h"
26
27#include "mpeg2dec_config.h"
28
29#include "mpeg2.h"
30#include "attributes.h"
31#include "mpeg2_internal.h"
32
33extern mpeg2_mc_t mpeg2_mc;
34extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride);
35extern void (* mpeg2_idct_add) (int last, int16_t * block,
36 uint8_t * dest, int stride);
37extern void (* mpeg2_cpu_state_save) (cpu_state_t * state);
38extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state);
39
40#include "vlc.h"
41
42static inline int get_macroblock_modes (mpeg2_decoder_t * const decoder)
43{
44#define bit_buf (decoder->bitstream_buf)
45#define bits (decoder->bitstream_bits)
46#define bit_ptr (decoder->bitstream_ptr)
47 int macroblock_modes;
48 const MBtab * tab;
49
50 switch (decoder->coding_type) {
51 case I_TYPE:
52
53 tab = MB_I + UBITS (bit_buf, 1);
54 DUMPBITS (bit_buf, bits, tab->len);
55 macroblock_modes = tab->modes;
56
57 if ((! (decoder->frame_pred_frame_dct)) &&
58 (decoder->picture_structure == FRAME_PICTURE)) {
59 macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
60 DUMPBITS (bit_buf, bits, 1);
61 }
62
63 return macroblock_modes;
64
65 case P_TYPE:
66
67 tab = MB_P + UBITS (bit_buf, 5);
68 DUMPBITS (bit_buf, bits, tab->len);
69 macroblock_modes = tab->modes;
70
71 if (decoder->picture_structure != FRAME_PICTURE) {
72 if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
73 macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
74 DUMPBITS (bit_buf, bits, 2);
75 }
76 return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
77 } else if (decoder->frame_pred_frame_dct) {
78 if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
79 macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT;
80 return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
81 } else {
82 if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
83 macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
84 DUMPBITS (bit_buf, bits, 2);
85 }
86 if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
87 macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
88 DUMPBITS (bit_buf, bits, 1);
89 }
90 return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
91 }
92
93 case B_TYPE:
94
95 tab = MB_B + UBITS (bit_buf, 6);
96 DUMPBITS (bit_buf, bits, tab->len);
97 macroblock_modes = tab->modes;
98
99 if (decoder->picture_structure != FRAME_PICTURE) {
100 if (! (macroblock_modes & MACROBLOCK_INTRA)) {
101 macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
102 DUMPBITS (bit_buf, bits, 2);
103 }
104 return macroblock_modes;
105 } else if (decoder->frame_pred_frame_dct) {
106 /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
107 macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT;
108 return macroblock_modes;
109 } else {
110 if (macroblock_modes & MACROBLOCK_INTRA)
111 goto intra;
112 macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
113 DUMPBITS (bit_buf, bits, 2);
114 if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
115 intra:
116 macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
117 DUMPBITS (bit_buf, bits, 1);
118 }
119 return macroblock_modes;
120 }
121
122 case D_TYPE:
123
124 DUMPBITS (bit_buf, bits, 1);
125 return MACROBLOCK_INTRA;
126
127 default:
128 return 0;
129 }
130#undef bit_buf
131#undef bits
132#undef bit_ptr
133}
134
135static inline void get_quantizer_scale (mpeg2_decoder_t * const decoder)
136{
137#define bit_buf (decoder->bitstream_buf)
138#define bits (decoder->bitstream_bits)
139#define bit_ptr (decoder->bitstream_ptr)
140
141 int quantizer_scale_code;
142
143 quantizer_scale_code = UBITS (bit_buf, 5);
144 DUMPBITS (bit_buf, bits, 5);
145
146 decoder->quantizer_matrix[0] =
147 decoder->quantizer_prescale[0][quantizer_scale_code];
148 decoder->quantizer_matrix[1] =
149 decoder->quantizer_prescale[1][quantizer_scale_code];
150 decoder->quantizer_matrix[2] =
151 decoder->chroma_quantizer[0][quantizer_scale_code];
152 decoder->quantizer_matrix[3] =
153 decoder->chroma_quantizer[1][quantizer_scale_code];
154#undef bit_buf
155#undef bits
156#undef bit_ptr
157}
158
159static inline int get_motion_delta (mpeg2_decoder_t * const decoder,
160 const int f_code)
161{
162#define bit_buf (decoder->bitstream_buf)
163#define bits (decoder->bitstream_bits)
164#define bit_ptr (decoder->bitstream_ptr)
165
166 int delta;
167 int sign;
168 const MVtab * tab;
169
170 if (bit_buf & 0x80000000) {
171 DUMPBITS (bit_buf, bits, 1);
172 return 0;
173 } else if (bit_buf >= 0x0c000000) {
174
175 tab = MV_4 + UBITS (bit_buf, 4);
176 delta = (tab->delta << f_code) + 1;
177 bits += tab->len + f_code + 1;
178 bit_buf <<= tab->len;
179
180 sign = SBITS (bit_buf, 1);
181 bit_buf <<= 1;
182
183 if (f_code)
184 delta += UBITS (bit_buf, f_code);
185 bit_buf <<= f_code;
186
187 return (delta ^ sign) - sign;
188
189 } else {
190
191 tab = MV_10 + UBITS (bit_buf, 10);
192 delta = (tab->delta << f_code) + 1;
193 bits += tab->len + 1;
194 bit_buf <<= tab->len;
195
196 sign = SBITS (bit_buf, 1);
197 bit_buf <<= 1;
198
199 if (f_code) {
200 NEEDBITS (bit_buf, bits, bit_ptr);
201 delta += UBITS (bit_buf, f_code);
202 DUMPBITS (bit_buf, bits, f_code);
203 }
204
205 return (delta ^ sign) - sign;
206
207 }
208#undef bit_buf
209#undef bits
210#undef bit_ptr
211}
212
213static inline int bound_motion_vector (const int vector, const int f_code)
214{
215 return ((int32_t)vector << (27 - f_code)) >> (27 - f_code);
216}
217
218static inline int get_dmv (mpeg2_decoder_t * const decoder)
219{
220#define bit_buf (decoder->bitstream_buf)
221#define bits (decoder->bitstream_bits)
222#define bit_ptr (decoder->bitstream_ptr)
223
224 const DMVtab * tab;
225
226 tab = DMV_2 + UBITS (bit_buf, 2);
227 DUMPBITS (bit_buf, bits, tab->len);
228 return tab->dmv;
229#undef bit_buf
230#undef bits
231#undef bit_ptr
232}
233
234static inline int get_coded_block_pattern (mpeg2_decoder_t * const decoder)
235{
236#define bit_buf (decoder->bitstream_buf)
237#define bits (decoder->bitstream_bits)
238#define bit_ptr (decoder->bitstream_ptr)
239
240 const CBPtab * tab;
241
242 NEEDBITS (bit_buf, bits, bit_ptr);
243
244 if (bit_buf >= 0x20000000) {
245
246 tab = CBP_7 + (UBITS (bit_buf, 7) - 16);
247 DUMPBITS (bit_buf, bits, tab->len);
248 return tab->cbp;
249
250 } else {
251
252 tab = CBP_9 + UBITS (bit_buf, 9);
253 DUMPBITS (bit_buf, bits, tab->len);
254 return tab->cbp;
255 }
256
257#undef bit_buf
258#undef bits
259#undef bit_ptr
260}
261
262static inline int get_luma_dc_dct_diff (mpeg2_decoder_t * const decoder)
263{
264#define bit_buf (decoder->bitstream_buf)
265#define bits (decoder->bitstream_bits)
266#define bit_ptr (decoder->bitstream_ptr)
267 const DCtab * tab;
268 int size;
269 int dc_diff;
270
271 if (bit_buf < 0xf8000000) {
272 tab = DC_lum_5 + UBITS (bit_buf, 5);
273 size = tab->size;
274 if (size) {
275 bits += tab->len + size;
276 bit_buf <<= tab->len;
277 dc_diff =
278 UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
279 bit_buf <<= size;
280 return dc_diff << decoder->intra_dc_precision;
281 } else {
282 DUMPBITS (bit_buf, bits, 3);
283 return 0;
284 }
285 } else {
286 tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0);
287 size = tab->size;
288 DUMPBITS (bit_buf, bits, tab->len);
289 NEEDBITS (bit_buf, bits, bit_ptr);
290 dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
291 DUMPBITS (bit_buf, bits, size);
292 return dc_diff << decoder->intra_dc_precision;
293 }
294#undef bit_buf
295#undef bits
296#undef bit_ptr
297}
298
299static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder)
300{
301#define bit_buf (decoder->bitstream_buf)
302#define bits (decoder->bitstream_bits)
303#define bit_ptr (decoder->bitstream_ptr)
304 const DCtab * tab;
305 int size;
306 int dc_diff;
307
308 if (bit_buf < 0xf8000000) {
309 tab = DC_chrom_5 + UBITS (bit_buf, 5);
310 size = tab->size;
311 if (size) {
312 bits += tab->len + size;
313 bit_buf <<= tab->len;
314 dc_diff =
315 UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
316 bit_buf <<= size;
317 return dc_diff << decoder->intra_dc_precision;
318 } else {
319 DUMPBITS (bit_buf, bits, 2);
320 return 0;
321 }
322 } else {
323 tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0);
324 size = tab->size;
325 DUMPBITS (bit_buf, bits, tab->len + 1);
326 NEEDBITS (bit_buf, bits, bit_ptr);
327 dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
328 DUMPBITS (bit_buf, bits, size);
329 return dc_diff << decoder->intra_dc_precision;
330 }
331#undef bit_buf
332#undef bits
333#undef bit_ptr
334}
335
336#define SATURATE(val) \
337do { \
338 val <<= 4; \
339 if (unlikely (val != (int16_t) val)) \
340 val = (SBITS (val, 1) ^ 2047) << 4; \
341} while (0)
342
343static void get_intra_block_B14 (mpeg2_decoder_t * const decoder,
344 const uint16_t * const quant_matrix)
345{
346 int i;
347 int j;
348 int val;
349 const uint8_t * const scan = decoder->scan;
350 int mismatch;
351 const DCTtab * tab;
352 uint32_t bit_buf;
353 int bits;
354 const uint8_t * bit_ptr;
355 int16_t * const dest = decoder->DCTblock;
356
357 i = 0;
358 mismatch = ~dest[0];
359
360 bit_buf = decoder->bitstream_buf;
361 bits = decoder->bitstream_bits;
362 bit_ptr = decoder->bitstream_ptr;
363
364 NEEDBITS (bit_buf, bits, bit_ptr);
365
366 while (1) {
367 if (bit_buf >= 0x28000000) {
368
369 tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
370
371 i += tab->run;
372 if (i >= 64)
373 break; /* end of block */
374
375 normal_code:
376 j = scan[i];
377 bit_buf <<= tab->len;
378 bits += tab->len + 1;
379 val = (tab->level * quant_matrix[j]) >> 4;
380
381 /* if (bitstream_get (1)) val = -val; */
382 val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
383
384 SATURATE (val);
385 dest[j] = val;
386 mismatch ^= val;
387
388 bit_buf <<= 1;
389 NEEDBITS (bit_buf, bits, bit_ptr);
390
391 continue;
392
393 } else if (bit_buf >= 0x04000000) {
394
395 tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
396
397 i += tab->run;
398 if (i < 64)
399 goto normal_code;
400
401 /* escape code */
402
403 i += UBITS (bit_buf << 6, 6) - 64;
404 if (i >= 64)
405 break; /* illegal, check needed to avoid buffer overflow */
406
407 j = scan[i];
408
409 DUMPBITS (bit_buf, bits, 12);
410 NEEDBITS (bit_buf, bits, bit_ptr);
411 val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16;
412
413 SATURATE (val);
414 dest[j] = val;
415 mismatch ^= val;
416
417 DUMPBITS (bit_buf, bits, 12);
418 NEEDBITS (bit_buf, bits, bit_ptr);
419
420 continue;
421
422 } else if (bit_buf >= 0x02000000) {
423 tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
424 i += tab->run;
425 if (i < 64)
426 goto normal_code;
427 } else if (bit_buf >= 0x00800000) {
428 tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
429 i += tab->run;
430 if (i < 64)
431 goto normal_code;
432 } else if (bit_buf >= 0x00200000) {
433 tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
434 i += tab->run;
435 if (i < 64)
436 goto normal_code;
437 } else {
438 tab = DCT_16 + UBITS (bit_buf, 16);
439 bit_buf <<= 16;
440 GETWORD (bit_buf, bits + 16, bit_ptr);
441 i += tab->run;
442 if (i < 64)
443 goto normal_code;
444 }
445 break; /* illegal, check needed to avoid buffer overflow */
446 }
447 dest[63] ^= mismatch & 16;
448 DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
449 decoder->bitstream_buf = bit_buf;
450 decoder->bitstream_bits = bits;
451 decoder->bitstream_ptr = bit_ptr;
452}
453
454static void get_intra_block_B15 (mpeg2_decoder_t * const decoder,
455 const uint16_t * const quant_matrix)
456{
457 int i;
458 int j;
459 int val;
460 const uint8_t * const scan = decoder->scan;
461 int mismatch;
462 const DCTtab * tab;
463 uint32_t bit_buf;
464 int bits;
465 const uint8_t * bit_ptr;
466 int16_t * const dest = decoder->DCTblock;
467
468 i = 0;
469 mismatch = ~dest[0];
470
471 bit_buf = decoder->bitstream_buf;
472 bits = decoder->bitstream_bits;
473 bit_ptr = decoder->bitstream_ptr;
474
475 NEEDBITS (bit_buf, bits, bit_ptr);
476
477 while (1) {
478 if (bit_buf >= 0x04000000) {
479
480 tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4);
481
482 i += tab->run;
483 if (i < 64) {
484
485 normal_code:
486 j = scan[i];
487 bit_buf <<= tab->len;
488 bits += tab->len + 1;
489 val = (tab->level * quant_matrix[j]) >> 4;
490
491 /* if (bitstream_get (1)) val = -val; */
492 val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
493
494 SATURATE (val);
495 dest[j] = val;
496 mismatch ^= val;
497
498 bit_buf <<= 1;
499 NEEDBITS (bit_buf, bits, bit_ptr);
500
501 continue;
502
503 } else {
504
505 /* end of block. I commented out this code because if we */
506 /* dont exit here we will still exit at the later test :) */
507
508 /* if (i >= 128) break; */ /* end of block */
509
510 /* escape code */
511
512 i += UBITS (bit_buf << 6, 6) - 64;
513 if (i >= 64)
514 break; /* illegal, check against buffer overflow */
515
516 j = scan[i];
517
518 DUMPBITS (bit_buf, bits, 12);
519 NEEDBITS (bit_buf, bits, bit_ptr);
520 val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16;
521
522 SATURATE (val);
523 dest[j] = val;
524 mismatch ^= val;
525
526 DUMPBITS (bit_buf, bits, 12);
527 NEEDBITS (bit_buf, bits, bit_ptr);
528
529 continue;
530
531 }
532 } else if (bit_buf >= 0x02000000) {
533 tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8);
534 i += tab->run;
535 if (i < 64)
536 goto normal_code;
537 } else if (bit_buf >= 0x00800000) {
538 tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
539 i += tab->run;
540 if (i < 64)
541 goto normal_code;
542 } else if (bit_buf >= 0x00200000) {
543 tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
544 i += tab->run;
545 if (i < 64)
546 goto normal_code;
547 } else {
548 tab = DCT_16 + UBITS (bit_buf, 16);
549 bit_buf <<= 16;
550 GETWORD (bit_buf, bits + 16, bit_ptr);
551 i += tab->run;
552 if (i < 64)
553 goto normal_code;
554 }
555 break; /* illegal, check needed to avoid buffer overflow */
556 }
557 dest[63] ^= mismatch & 16;
558 DUMPBITS (bit_buf, bits, 4); /* dump end of block code */
559 decoder->bitstream_buf = bit_buf;
560 decoder->bitstream_bits = bits;
561 decoder->bitstream_ptr = bit_ptr;
562}
563
564static int get_non_intra_block (mpeg2_decoder_t * const decoder,
565 const uint16_t * const quant_matrix)
566{
567 int i;
568 int j;
569 int val;
570 const uint8_t * const scan = decoder->scan;
571 int mismatch;
572 const DCTtab * tab;
573 uint32_t bit_buf;
574 int bits;
575 const uint8_t * bit_ptr;
576 int16_t * const dest = decoder->DCTblock;
577
578 i = -1;
579 mismatch = -1;
580
581 bit_buf = decoder->bitstream_buf;
582 bits = decoder->bitstream_bits;
583 bit_ptr = decoder->bitstream_ptr;
584
585 NEEDBITS (bit_buf, bits, bit_ptr);
586 if (bit_buf >= 0x28000000) {
587 tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
588 goto entry_1;
589 } else
590 goto entry_2;
591
592 while (1) {
593 if (bit_buf >= 0x28000000) {
594
595 tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
596
597 entry_1:
598 i += tab->run;
599 if (i >= 64)
600 break; /* end of block */
601
602 normal_code:
603 j = scan[i];
604 bit_buf <<= tab->len;
605 bits += tab->len + 1;
606 val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5;
607
608 /* if (bitstream_get (1)) val = -val; */
609 val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
610
611 SATURATE (val);
612 dest[j] = val;
613 mismatch ^= val;
614
615 bit_buf <<= 1;
616 NEEDBITS (bit_buf, bits, bit_ptr);
617
618 continue;
619
620 }
621
622 entry_2:
623 if (bit_buf >= 0x04000000) {
624
625 tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
626
627 i += tab->run;
628 if (i < 64)
629 goto normal_code;
630
631 /* escape code */
632
633 i += UBITS (bit_buf << 6, 6) - 64;
634 if (i >= 64)
635 break; /* illegal, check needed to avoid buffer overflow */
636
637 j = scan[i];
638
639 DUMPBITS (bit_buf, bits, 12);
640 NEEDBITS (bit_buf, bits, bit_ptr);
641 val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1;
642 val = (val * quant_matrix[j]) / 32;
643
644 SATURATE (val);
645 dest[j] = val;
646 mismatch ^= val;
647
648 DUMPBITS (bit_buf, bits, 12);
649 NEEDBITS (bit_buf, bits, bit_ptr);
650
651 continue;
652
653 } else if (bit_buf >= 0x02000000) {
654 tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
655 i += tab->run;
656 if (i < 64)
657 goto normal_code;
658 } else if (bit_buf >= 0x00800000) {
659 tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
660 i += tab->run;
661 if (i < 64)
662 goto normal_code;
663 } else if (bit_buf >= 0x00200000) {
664 tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
665 i += tab->run;
666 if (i < 64)
667 goto normal_code;
668 } else {
669 tab = DCT_16 + UBITS (bit_buf, 16);
670 bit_buf <<= 16;
671 GETWORD (bit_buf, bits + 16, bit_ptr);
672 i += tab->run;
673 if (i < 64)
674 goto normal_code;
675 }
676 break; /* illegal, check needed to avoid buffer overflow */
677 }
678 dest[63] ^= mismatch & 16;
679 DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
680 decoder->bitstream_buf = bit_buf;
681 decoder->bitstream_bits = bits;
682 decoder->bitstream_ptr = bit_ptr;
683 return i;
684}
685
686static void get_mpeg1_intra_block (mpeg2_decoder_t * const decoder)
687{
688 int i;
689 int j;
690 int val;
691 const uint8_t * const scan = decoder->scan;
692 const uint16_t * const quant_matrix = decoder->quantizer_matrix[0];
693 const DCTtab * tab;
694 uint32_t bit_buf;
695 int bits;
696 const uint8_t * bit_ptr;
697 int16_t * const dest = decoder->DCTblock;
698
699 i = 0;
700
701 bit_buf = decoder->bitstream_buf;
702 bits = decoder->bitstream_bits;
703 bit_ptr = decoder->bitstream_ptr;
704
705 NEEDBITS (bit_buf, bits, bit_ptr);
706
707 while (1) {
708 if (bit_buf >= 0x28000000) {
709
710 tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
711
712 i += tab->run;
713 if (i >= 64)
714 break; /* end of block */
715
716 normal_code:
717 j = scan[i];
718 bit_buf <<= tab->len;
719 bits += tab->len + 1;
720 val = (tab->level * quant_matrix[j]) >> 4;
721
722 /* oddification */
723 val = (val - 1) | 1;
724
725 /* if (bitstream_get (1)) val = -val; */
726 val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
727
728 SATURATE (val);
729 dest[j] = val;
730
731 bit_buf <<= 1;
732 NEEDBITS (bit_buf, bits, bit_ptr);
733
734 continue;
735
736 } else if (bit_buf >= 0x04000000) {
737
738 tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
739
740 i += tab->run;
741 if (i < 64)
742 goto normal_code;
743
744 /* escape code */
745
746 i += UBITS (bit_buf << 6, 6) - 64;
747 if (i >= 64)
748 break; /* illegal, check needed to avoid buffer overflow */
749
750 j = scan[i];
751
752 DUMPBITS (bit_buf, bits, 12);
753 NEEDBITS (bit_buf, bits, bit_ptr);
754 val = SBITS (bit_buf, 8);
755 if (! (val & 0x7f)) {
756 DUMPBITS (bit_buf, bits, 8);
757 val = UBITS (bit_buf, 8) + 2 * val;
758 }
759 val = (val * quant_matrix[j]) / 16;
760
761 /* oddification */
762 val = (val + ~SBITS (val, 1)) | 1;
763
764 SATURATE (val);
765 dest[j] = val;
766
767 DUMPBITS (bit_buf, bits, 8);
768 NEEDBITS (bit_buf, bits, bit_ptr);
769
770 continue;
771
772 } else if (bit_buf >= 0x02000000) {
773 tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
774 i += tab->run;
775 if (i < 64)
776 goto normal_code;
777 } else if (bit_buf >= 0x00800000) {
778 tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
779 i += tab->run;
780 if (i < 64)
781 goto normal_code;
782 } else if (bit_buf >= 0x00200000) {
783 tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
784 i += tab->run;
785 if (i < 64)
786 goto normal_code;
787 } else {
788 tab = DCT_16 + UBITS (bit_buf, 16);
789 bit_buf <<= 16;
790 GETWORD (bit_buf, bits + 16, bit_ptr);
791 i += tab->run;
792 if (i < 64)
793 goto normal_code;
794 }
795 break; /* illegal, check needed to avoid buffer overflow */
796 }
797 DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
798 decoder->bitstream_buf = bit_buf;
799 decoder->bitstream_bits = bits;
800 decoder->bitstream_ptr = bit_ptr;
801}
802
803static int get_mpeg1_non_intra_block (mpeg2_decoder_t * const decoder)
804{
805 int i;
806 int j;
807 int val;
808 const uint8_t * const scan = decoder->scan;
809 const uint16_t * const quant_matrix = decoder->quantizer_matrix[1];
810 const DCTtab * tab;
811 uint32_t bit_buf;
812 int bits;
813 const uint8_t * bit_ptr;
814 int16_t * const dest = decoder->DCTblock;
815
816 i = -1;
817
818 bit_buf = decoder->bitstream_buf;
819 bits = decoder->bitstream_bits;
820 bit_ptr = decoder->bitstream_ptr;
821
822 NEEDBITS (bit_buf, bits, bit_ptr);
823 if (bit_buf >= 0x28000000) {
824 tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
825 goto entry_1;
826 } else
827 goto entry_2;
828
829 while (1) {
830 if (bit_buf >= 0x28000000) {
831
832 tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
833
834 entry_1:
835 i += tab->run;
836 if (i >= 64)
837 break; /* end of block */
838
839 normal_code:
840 j = scan[i];
841 bit_buf <<= tab->len;
842 bits += tab->len + 1;
843 val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5;
844
845 /* oddification */
846 val = (val - 1) | 1;
847
848 /* if (bitstream_get (1)) val = -val; */
849 val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
850
851 SATURATE (val);
852 dest[j] = val;
853
854 bit_buf <<= 1;
855 NEEDBITS (bit_buf, bits, bit_ptr);
856
857 continue;
858
859 }
860
861 entry_2:
862 if (bit_buf >= 0x04000000) {
863
864 tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
865
866 i += tab->run;
867 if (i < 64)
868 goto normal_code;
869
870 /* escape code */
871
872 i += UBITS (bit_buf << 6, 6) - 64;
873 if (i >= 64)
874 break; /* illegal, check needed to avoid buffer overflow */
875
876 j = scan[i];
877
878 DUMPBITS (bit_buf, bits, 12);
879 NEEDBITS (bit_buf, bits, bit_ptr);
880 val = SBITS (bit_buf, 8);
881 if (! (val & 0x7f)) {
882 DUMPBITS (bit_buf, bits, 8);
883 val = UBITS (bit_buf, 8) + 2 * val;
884 }
885 val = 2 * (val + SBITS (val, 1)) + 1;
886 val = (val * quant_matrix[j]) / 32;
887
888 /* oddification */
889 val = (val + ~SBITS (val, 1)) | 1;
890
891 SATURATE (val);
892 dest[j] = val;
893
894 DUMPBITS (bit_buf, bits, 8);
895 NEEDBITS (bit_buf, bits, bit_ptr);
896
897 continue;
898
899 } else if (bit_buf >= 0x02000000) {
900 tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
901 i += tab->run;
902 if (i < 64)
903 goto normal_code;
904 } else if (bit_buf >= 0x00800000) {
905 tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
906 i += tab->run;
907 if (i < 64)
908 goto normal_code;
909 } else if (bit_buf >= 0x00200000) {
910 tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
911 i += tab->run;
912 if (i < 64)
913 goto normal_code;
914 } else {
915 tab = DCT_16 + UBITS (bit_buf, 16);
916 bit_buf <<= 16;
917 GETWORD (bit_buf, bits + 16, bit_ptr);
918 i += tab->run;
919 if (i < 64)
920 goto normal_code;
921 }
922 break; /* illegal, check needed to avoid buffer overflow */
923 }
924 DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
925 decoder->bitstream_buf = bit_buf;
926 decoder->bitstream_bits = bits;
927 decoder->bitstream_ptr = bit_ptr;
928 return i;
929}
930
931static inline void slice_intra_DCT (mpeg2_decoder_t * const decoder,
932 const int cc,
933 uint8_t * const dest, const int stride)
934{
935#define bit_buf (decoder->bitstream_buf)
936#define bits (decoder->bitstream_bits)
937#define bit_ptr (decoder->bitstream_ptr)
938 NEEDBITS (bit_buf, bits, bit_ptr);
939 /* Get the intra DC coefficient and inverse quantize it */
940 if (cc == 0)
941 decoder->DCTblock[0] =
942 decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder);
943 else
944 decoder->DCTblock[0] =
945 decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder);
946
947 if (decoder->mpeg1) {
948 if (decoder->coding_type != D_TYPE)
949 get_mpeg1_intra_block (decoder);
950 } else if (decoder->intra_vlc_format)
951 get_intra_block_B15 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]);
952 else
953 get_intra_block_B14 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]);
954 mpeg2_idct_copy (decoder->DCTblock, dest, stride);
955#undef bit_buf
956#undef bits
957#undef bit_ptr
958}
959
960static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder,
961 const int cc,
962 uint8_t * const dest, const int stride)
963{
964 int last;
965
966 if (decoder->mpeg1)
967 last = get_mpeg1_non_intra_block (decoder);
968 else
969 last = get_non_intra_block (decoder,
970 decoder->quantizer_matrix[cc ? 3 : 1]);
971 mpeg2_idct_add (last, decoder->DCTblock, dest, stride);
972}
973
974#define MOTION_420(table,ref,motion_x,motion_y,size,y) \
975 pos_x = 2 * decoder->offset + motion_x; \
976 pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \
977 if (unlikely (pos_x > decoder->limit_x)) { \
978 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
979 motion_x = pos_x - 2 * decoder->offset; \
980 } \
981 if (unlikely (pos_y > decoder->limit_y_ ## size)) { \
982 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
983 motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
984 } \
985 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
986 table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
987 ref[0] + (pos_x >> 1) + (pos_y >> 1) * decoder->stride, \
988 decoder->stride, size); \
989 motion_x /= 2; motion_y /= 2; \
990 xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
991 offset = (((decoder->offset + motion_x) >> 1) + \
992 ((((decoder->v_offset + motion_y) >> 1) + y/2) * \
993 decoder->uv_stride)); \
994 table[4+xy_half] (decoder->dest[1] + y/2 * decoder->uv_stride + \
995 (decoder->offset >> 1), ref[1] + offset, \
996 decoder->uv_stride, size/2); \
997 table[4+xy_half] (decoder->dest[2] + y/2 * decoder->uv_stride + \
998 (decoder->offset >> 1), ref[2] + offset, \
999 decoder->uv_stride, size/2)
1000
1001#define MOTION_FIELD_420(table,ref,motion_x,motion_y,dest_field,op,src_field) \
1002 pos_x = 2 * decoder->offset + motion_x; \
1003 pos_y = decoder->v_offset + motion_y; \
1004 if (unlikely (pos_x > decoder->limit_x)) { \
1005 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1006 motion_x = pos_x - 2 * decoder->offset; \
1007 } \
1008 if (unlikely (pos_y > decoder->limit_y)) { \
1009 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
1010 motion_y = pos_y - decoder->v_offset; \
1011 } \
1012 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1013 table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
1014 decoder->offset, \
1015 (ref[0] + (pos_x >> 1) + \
1016 ((pos_y op) + src_field) * decoder->stride), \
1017 2 * decoder->stride, 8); \
1018 motion_x /= 2; motion_y /= 2; \
1019 xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
1020 offset = (((decoder->offset + motion_x) >> 1) + \
1021 (((decoder->v_offset >> 1) + (motion_y op) + src_field) * \
1022 decoder->uv_stride)); \
1023 table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \
1024 (decoder->offset >> 1), ref[1] + offset, \
1025 2 * decoder->uv_stride, 4); \
1026 table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \
1027 (decoder->offset >> 1), ref[2] + offset, \
1028 2 * decoder->uv_stride, 4)
1029
1030#define MOTION_DMV_420(table,ref,motion_x,motion_y) \
1031 pos_x = 2 * decoder->offset + motion_x; \
1032 pos_y = decoder->v_offset + motion_y; \
1033 if (unlikely (pos_x > decoder->limit_x)) { \
1034 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1035 motion_x = pos_x - 2 * decoder->offset; \
1036 } \
1037 if (unlikely (pos_y > decoder->limit_y)) { \
1038 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
1039 motion_y = pos_y - decoder->v_offset; \
1040 } \
1041 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1042 offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
1043 table[xy_half] (decoder->dest[0] + decoder->offset, \
1044 ref[0] + offset, 2 * decoder->stride, 8); \
1045 table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
1046 ref[0] + decoder->stride + offset, \
1047 2 * decoder->stride, 8); \
1048 motion_x /= 2; motion_y /= 2; \
1049 xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
1050 offset = (((decoder->offset + motion_x) >> 1) + \
1051 (((decoder->v_offset >> 1) + (motion_y & ~1)) * \
1052 decoder->uv_stride)); \
1053 table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \
1054 ref[1] + offset, 2 * decoder->uv_stride, 4); \
1055 table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \
1056 (decoder->offset >> 1), \
1057 ref[1] + decoder->uv_stride + offset, \
1058 2 * decoder->uv_stride, 4); \
1059 table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \
1060 ref[2] + offset, 2 * decoder->uv_stride, 4); \
1061 table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \
1062 (decoder->offset >> 1), \
1063 ref[2] + decoder->uv_stride + offset, \
1064 2 * decoder->uv_stride, 4)
1065
1066#define MOTION_ZERO_420(table,ref) \
1067 table[0] (decoder->dest[0] + decoder->offset, \
1068 (ref[0] + decoder->offset + \
1069 decoder->v_offset * decoder->stride), decoder->stride, 16); \
1070 offset = ((decoder->offset >> 1) + \
1071 (decoder->v_offset >> 1) * decoder->uv_stride); \
1072 table[4] (decoder->dest[1] + (decoder->offset >> 1), \
1073 ref[1] + offset, decoder->uv_stride, 8); \
1074 table[4] (decoder->dest[2] + (decoder->offset >> 1), \
1075 ref[2] + offset, decoder->uv_stride, 8)
1076
1077#define MOTION_422(table,ref,motion_x,motion_y,size,y) \
1078 pos_x = 2 * decoder->offset + motion_x; \
1079 pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \
1080 if (unlikely (pos_x > decoder->limit_x)) { \
1081 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1082 motion_x = pos_x - 2 * decoder->offset; \
1083 } \
1084 if (unlikely (pos_y > decoder->limit_y_ ## size)) { \
1085 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
1086 motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
1087 } \
1088 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1089 offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \
1090 table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
1091 ref[0] + offset, decoder->stride, size); \
1092 offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
1093 motion_x /= 2; \
1094 xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
1095 table[4+xy_half] (decoder->dest[1] + y * decoder->uv_stride + \
1096 (decoder->offset >> 1), ref[1] + offset, \
1097 decoder->uv_stride, size); \
1098 table[4+xy_half] (decoder->dest[2] + y * decoder->uv_stride + \
1099 (decoder->offset >> 1), ref[2] + offset, \
1100 decoder->uv_stride, size)
1101
1102#define MOTION_FIELD_422(table,ref,motion_x,motion_y,dest_field,op,src_field) \
1103 pos_x = 2 * decoder->offset + motion_x; \
1104 pos_y = decoder->v_offset + motion_y; \
1105 if (unlikely (pos_x > decoder->limit_x)) { \
1106 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1107 motion_x = pos_x - 2 * decoder->offset; \
1108 } \
1109 if (unlikely (pos_y > decoder->limit_y)) { \
1110 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
1111 motion_y = pos_y - decoder->v_offset; \
1112 } \
1113 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1114 offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \
1115 table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
1116 decoder->offset, ref[0] + offset, \
1117 2 * decoder->stride, 8); \
1118 offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
1119 motion_x /= 2; \
1120 xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
1121 table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \
1122 (decoder->offset >> 1), ref[1] + offset, \
1123 2 * decoder->uv_stride, 8); \
1124 table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \
1125 (decoder->offset >> 1), ref[2] + offset, \
1126 2 * decoder->uv_stride, 8)
1127
1128#define MOTION_DMV_422(table,ref,motion_x,motion_y) \
1129 pos_x = 2 * decoder->offset + motion_x; \
1130 pos_y = decoder->v_offset + motion_y; \
1131 if (unlikely (pos_x > decoder->limit_x)) { \
1132 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1133 motion_x = pos_x - 2 * decoder->offset; \
1134 } \
1135 if (unlikely (pos_y > decoder->limit_y)) { \
1136 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
1137 motion_y = pos_y - decoder->v_offset; \
1138 } \
1139 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1140 offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
1141 table[xy_half] (decoder->dest[0] + decoder->offset, \
1142 ref[0] + offset, 2 * decoder->stride, 8); \
1143 table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
1144 ref[0] + decoder->stride + offset, \
1145 2 * decoder->stride, 8); \
1146 offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
1147 motion_x /= 2; \
1148 xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
1149 table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \
1150 ref[1] + offset, 2 * decoder->uv_stride, 8); \
1151 table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \
1152 (decoder->offset >> 1), \
1153 ref[1] + decoder->uv_stride + offset, \
1154 2 * decoder->uv_stride, 8); \
1155 table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \
1156 ref[2] + offset, 2 * decoder->uv_stride, 8); \
1157 table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \
1158 (decoder->offset >> 1), \
1159 ref[2] + decoder->uv_stride + offset, \
1160 2 * decoder->uv_stride, 8)
1161
1162#define MOTION_ZERO_422(table,ref) \
1163 offset = decoder->offset + decoder->v_offset * decoder->stride; \
1164 table[0] (decoder->dest[0] + decoder->offset, \
1165 ref[0] + offset, decoder->stride, 16); \
1166 offset >>= 1; \
1167 table[4] (decoder->dest[1] + (decoder->offset >> 1), \
1168 ref[1] + offset, decoder->uv_stride, 16); \
1169 table[4] (decoder->dest[2] + (decoder->offset >> 1), \
1170 ref[2] + offset, decoder->uv_stride, 16)
1171
1172#define MOTION_444(table,ref,motion_x,motion_y,size,y) \
1173 pos_x = 2 * decoder->offset + motion_x; \
1174 pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \
1175 if (unlikely (pos_x > decoder->limit_x)) { \
1176 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1177 motion_x = pos_x - 2 * decoder->offset; \
1178 } \
1179 if (unlikely (pos_y > decoder->limit_y_ ## size)) { \
1180 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
1181 motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
1182 } \
1183 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1184 offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \
1185 table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
1186 ref[0] + offset, decoder->stride, size); \
1187 table[xy_half] (decoder->dest[1] + y * decoder->stride + decoder->offset, \
1188 ref[1] + offset, decoder->stride, size); \
1189 table[xy_half] (decoder->dest[2] + y * decoder->stride + decoder->offset, \
1190 ref[2] + offset, decoder->stride, size)
1191
1192#define MOTION_FIELD_444(table,ref,motion_x,motion_y,dest_field,op,src_field) \
1193 pos_x = 2 * decoder->offset + motion_x; \
1194 pos_y = decoder->v_offset + motion_y; \
1195 if (unlikely (pos_x > decoder->limit_x)) { \
1196 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1197 motion_x = pos_x - 2 * decoder->offset; \
1198 } \
1199 if (unlikely (pos_y > decoder->limit_y)) { \
1200 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
1201 motion_y = pos_y - decoder->v_offset; \
1202 } \
1203 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1204 offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \
1205 table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
1206 decoder->offset, ref[0] + offset, \
1207 2 * decoder->stride, 8); \
1208 table[xy_half] (decoder->dest[1] + dest_field * decoder->stride + \
1209 decoder->offset, ref[1] + offset, \
1210 2 * decoder->stride, 8); \
1211 table[xy_half] (decoder->dest[2] + dest_field * decoder->stride + \
1212 decoder->offset, ref[2] + offset, \
1213 2 * decoder->stride, 8)
1214
1215#define MOTION_DMV_444(table,ref,motion_x,motion_y) \
1216 pos_x = 2 * decoder->offset + motion_x; \
1217 pos_y = decoder->v_offset + motion_y; \
1218 if (unlikely (pos_x > decoder->limit_x)) { \
1219 pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
1220 motion_x = pos_x - 2 * decoder->offset; \
1221 } \
1222 if (unlikely (pos_y > decoder->limit_y)) { \
1223 pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
1224 motion_y = pos_y - decoder->v_offset; \
1225 } \
1226 xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
1227 offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
1228 table[xy_half] (decoder->dest[0] + decoder->offset, \
1229 ref[0] + offset, 2 * decoder->stride, 8); \
1230 table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
1231 ref[0] + decoder->stride + offset, \
1232 2 * decoder->stride, 8); \
1233 table[xy_half] (decoder->dest[1] + decoder->offset, \
1234 ref[1] + offset, 2 * decoder->stride, 8); \
1235 table[xy_half] (decoder->dest[1] + decoder->stride + decoder->offset, \
1236 ref[1] + decoder->stride + offset, \
1237 2 * decoder->stride, 8); \
1238 table[xy_half] (decoder->dest[2] + decoder->offset, \
1239 ref[2] + offset, 2 * decoder->stride, 8); \
1240 table[xy_half] (decoder->dest[2] + decoder->stride + decoder->offset, \
1241 ref[2] + decoder->stride + offset, \
1242 2 * decoder->stride, 8)
1243
1244#define MOTION_ZERO_444(table,ref) \
1245 offset = decoder->offset + decoder->v_offset * decoder->stride; \
1246 table[0] (decoder->dest[0] + decoder->offset, \
1247 ref[0] + offset, decoder->stride, 16); \
1248 table[4] (decoder->dest[1] + decoder->offset, \
1249 ref[1] + offset, decoder->stride, 16); \
1250 table[4] (decoder->dest[2] + (decoder->offset >> 1), \
1251 ref[2] + offset, decoder->stride, 16)
1252
1253#define bit_buf (decoder->bitstream_buf)
1254#define bits (decoder->bitstream_bits)
1255#define bit_ptr (decoder->bitstream_ptr)
1256
1257static void motion_mp1 (mpeg2_decoder_t * const decoder,
1258 motion_t * const motion,
1259 mpeg2_mc_fct * const * const table)
1260{
1261 int motion_x, motion_y;
1262 unsigned int pos_x, pos_y, xy_half, offset;
1263
1264 NEEDBITS (bit_buf, bits, bit_ptr);
1265 motion_x = (motion->pmv[0][0] +
1266 (get_motion_delta (decoder,
1267 motion->f_code[0]) << motion->f_code[1]));
1268 motion_x = bound_motion_vector (motion_x,
1269 motion->f_code[0] + motion->f_code[1]);
1270 motion->pmv[0][0] = motion_x;
1271
1272 NEEDBITS (bit_buf, bits, bit_ptr);
1273 motion_y = (motion->pmv[0][1] +
1274 (get_motion_delta (decoder,
1275 motion->f_code[0]) << motion->f_code[1]));
1276 motion_y = bound_motion_vector (motion_y,
1277 motion->f_code[0] + motion->f_code[1]);
1278 motion->pmv[0][1] = motion_y;
1279
1280 MOTION_420 (table, motion->ref[0], motion_x, motion_y, 16, 0);
1281}
1282
1283#define MOTION_FUNCTIONS(FORMAT,MOTION,MOTION_FIELD,MOTION_DMV,MOTION_ZERO) \
1284 \
1285static void motion_fr_frame_##FORMAT (mpeg2_decoder_t * const decoder, \
1286 motion_t * const motion, \
1287 mpeg2_mc_fct * const * const table) \
1288{ \
1289 int motion_x, motion_y; \
1290 unsigned int pos_x, pos_y, xy_half, offset; \
1291 \
1292 NEEDBITS (bit_buf, bits, bit_ptr); \
1293 motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
1294 motion->f_code[0]); \
1295 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1296 motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
1297 \
1298 NEEDBITS (bit_buf, bits, bit_ptr); \
1299 motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
1300 motion->f_code[1]); \
1301 motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
1302 motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \
1303 \
1304 MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); \
1305} \
1306 \
1307static void motion_fr_field_##FORMAT (mpeg2_decoder_t * const decoder, \
1308 motion_t * const motion, \
1309 mpeg2_mc_fct * const * const table) \
1310{ \
1311 int motion_x, motion_y, field; \
1312 unsigned int pos_x, pos_y, xy_half, offset; \
1313 \
1314 NEEDBITS (bit_buf, bits, bit_ptr); \
1315 field = UBITS (bit_buf, 1); \
1316 DUMPBITS (bit_buf, bits, 1); \
1317 \
1318 motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
1319 motion->f_code[0]); \
1320 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1321 motion->pmv[0][0] = motion_x; \
1322 \
1323 NEEDBITS (bit_buf, bits, bit_ptr); \
1324 motion_y = ((motion->pmv[0][1] >> 1) + \
1325 get_motion_delta (decoder, motion->f_code[1])); \
1326 /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \
1327 motion->pmv[0][1] = motion_y << 1; \
1328 \
1329 MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); \
1330 \
1331 NEEDBITS (bit_buf, bits, bit_ptr); \
1332 field = UBITS (bit_buf, 1); \
1333 DUMPBITS (bit_buf, bits, 1); \
1334 \
1335 motion_x = motion->pmv[1][0] + get_motion_delta (decoder, \
1336 motion->f_code[0]); \
1337 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1338 motion->pmv[1][0] = motion_x; \
1339 \
1340 NEEDBITS (bit_buf, bits, bit_ptr); \
1341 motion_y = ((motion->pmv[1][1] >> 1) + \
1342 get_motion_delta (decoder, motion->f_code[1])); \
1343 /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \
1344 motion->pmv[1][1] = motion_y << 1; \
1345 \
1346 MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); \
1347} \
1348 \
1349static void motion_fr_dmv_##FORMAT (mpeg2_decoder_t * const decoder, \
1350 motion_t * const motion, \
1351 mpeg2_mc_fct * const * const table) \
1352{ \
1353 int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; \
1354 unsigned int pos_x, pos_y, xy_half, offset; \
1355 \
1356 (void)table; \
1357 NEEDBITS (bit_buf, bits, bit_ptr); \
1358 motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
1359 motion->f_code[0]); \
1360 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1361 motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
1362 NEEDBITS (bit_buf, bits, bit_ptr); \
1363 dmv_x = get_dmv (decoder); \
1364 \
1365 motion_y = ((motion->pmv[0][1] >> 1) + \
1366 get_motion_delta (decoder, motion->f_code[1])); \
1367 /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \
1368 motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; \
1369 dmv_y = get_dmv (decoder); \
1370 \
1371 m = decoder->top_field_first ? 1 : 3; \
1372 other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; \
1373 other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; \
1374 MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); \
1375 \
1376 m = decoder->top_field_first ? 3 : 1; \
1377 other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; \
1378 other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; \
1379 MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0);\
1380 \
1381 MOTION_DMV (mpeg2_mc.avg, motion->ref[0], motion_x, motion_y); \
1382} \
1383 \
1384static void motion_reuse_##FORMAT (mpeg2_decoder_t * const decoder, \
1385 motion_t * const motion, \
1386 mpeg2_mc_fct * const * const table) \
1387{ \
1388 int motion_x, motion_y; \
1389 unsigned int pos_x, pos_y, xy_half, offset; \
1390 \
1391 motion_x = motion->pmv[0][0]; \
1392 motion_y = motion->pmv[0][1]; \
1393 \
1394 MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); \
1395} \
1396 \
1397static void motion_zero_##FORMAT (mpeg2_decoder_t * const decoder, \
1398 motion_t * const motion, \
1399 mpeg2_mc_fct * const * const table) \
1400{ \
1401 unsigned int offset; \
1402 \
1403 motion->pmv[0][0] = motion->pmv[0][1] = 0; \
1404 motion->pmv[1][0] = motion->pmv[1][1] = 0; \
1405 \
1406 MOTION_ZERO (table, motion->ref[0]); \
1407} \
1408 \
1409static void motion_fi_field_##FORMAT (mpeg2_decoder_t * const decoder, \
1410 motion_t * const motion, \
1411 mpeg2_mc_fct * const * const table) \
1412{ \
1413 int motion_x, motion_y; \
1414 uint8_t ** ref_field; \
1415 unsigned int pos_x, pos_y, xy_half, offset; \
1416 \
1417 NEEDBITS (bit_buf, bits, bit_ptr); \
1418 ref_field = motion->ref2[UBITS (bit_buf, 1)]; \
1419 DUMPBITS (bit_buf, bits, 1); \
1420 \
1421 motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
1422 motion->f_code[0]); \
1423 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1424 motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
1425 \
1426 NEEDBITS (bit_buf, bits, bit_ptr); \
1427 motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
1428 motion->f_code[1]); \
1429 motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
1430 motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \
1431 \
1432 MOTION (table, ref_field, motion_x, motion_y, 16, 0); \
1433} \
1434 \
1435static void motion_fi_16x8_##FORMAT (mpeg2_decoder_t * const decoder, \
1436 motion_t * const motion, \
1437 mpeg2_mc_fct * const * const table) \
1438{ \
1439 int motion_x, motion_y; \
1440 uint8_t ** ref_field; \
1441 unsigned int pos_x, pos_y, xy_half, offset; \
1442 \
1443 NEEDBITS (bit_buf, bits, bit_ptr); \
1444 ref_field = motion->ref2[UBITS (bit_buf, 1)]; \
1445 DUMPBITS (bit_buf, bits, 1); \
1446 \
1447 motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
1448 motion->f_code[0]); \
1449 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1450 motion->pmv[0][0] = motion_x; \
1451 \
1452 NEEDBITS (bit_buf, bits, bit_ptr); \
1453 motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
1454 motion->f_code[1]); \
1455 motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
1456 motion->pmv[0][1] = motion_y; \
1457 \
1458 MOTION (table, ref_field, motion_x, motion_y, 8, 0); \
1459 \
1460 NEEDBITS (bit_buf, bits, bit_ptr); \
1461 ref_field = motion->ref2[UBITS (bit_buf, 1)]; \
1462 DUMPBITS (bit_buf, bits, 1); \
1463 \
1464 motion_x = motion->pmv[1][0] + get_motion_delta (decoder, \
1465 motion->f_code[0]); \
1466 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1467 motion->pmv[1][0] = motion_x; \
1468 \
1469 NEEDBITS (bit_buf, bits, bit_ptr); \
1470 motion_y = motion->pmv[1][1] + get_motion_delta (decoder, \
1471 motion->f_code[1]); \
1472 motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
1473 motion->pmv[1][1] = motion_y; \
1474 \
1475 MOTION (table, ref_field, motion_x, motion_y, 8, 8); \
1476} \
1477 \
1478static void motion_fi_dmv_##FORMAT (mpeg2_decoder_t * const decoder, \
1479 motion_t * const motion, \
1480 mpeg2_mc_fct * const * const table) \
1481{ \
1482 int motion_x, motion_y, other_x, other_y; \
1483 unsigned int pos_x, pos_y, xy_half, offset; \
1484 \
1485 (void)table; \
1486 NEEDBITS (bit_buf, bits, bit_ptr); \
1487 motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \
1488 motion->f_code[0]); \
1489 motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \
1490 motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \
1491 NEEDBITS (bit_buf, bits, bit_ptr); \
1492 other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (decoder); \
1493 \
1494 motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \
1495 motion->f_code[1]); \
1496 motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \
1497 motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \
1498 other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (decoder) + \
1499 decoder->dmv_offset); \
1500 \
1501 MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); \
1502 MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); \
1503} \
1504
1505MOTION_FUNCTIONS (420, MOTION_420, MOTION_FIELD_420, MOTION_DMV_420,
1506 MOTION_ZERO_420)
1507MOTION_FUNCTIONS (422, MOTION_422, MOTION_FIELD_422, MOTION_DMV_422,
1508 MOTION_ZERO_422)
1509MOTION_FUNCTIONS (444, MOTION_444, MOTION_FIELD_444, MOTION_DMV_444,
1510 MOTION_ZERO_444)
1511
1512/* like motion_frame, but parsing without actual motion compensation */
1513static void motion_fr_conceal (mpeg2_decoder_t * const decoder)
1514{
1515 int tmp;
1516
1517 NEEDBITS (bit_buf, bits, bit_ptr);
1518 tmp = (decoder->f_motion.pmv[0][0] +
1519 get_motion_delta (decoder, decoder->f_motion.f_code[0]));
1520 tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]);
1521 decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp;
1522
1523 NEEDBITS (bit_buf, bits, bit_ptr);
1524 tmp = (decoder->f_motion.pmv[0][1] +
1525 get_motion_delta (decoder, decoder->f_motion.f_code[1]));
1526 tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]);
1527 decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp;
1528
1529 DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
1530}
1531
1532static void motion_fi_conceal (mpeg2_decoder_t * const decoder)
1533{
1534 int tmp;
1535
1536 NEEDBITS (bit_buf, bits, bit_ptr);
1537 DUMPBITS (bit_buf, bits, 1); /* remove field_select */
1538
1539 tmp = (decoder->f_motion.pmv[0][0] +
1540 get_motion_delta (decoder, decoder->f_motion.f_code[0]));
1541 tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]);
1542 decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp;
1543
1544 NEEDBITS (bit_buf, bits, bit_ptr);
1545 tmp = (decoder->f_motion.pmv[0][1] +
1546 get_motion_delta (decoder, decoder->f_motion.f_code[1]));
1547 tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]);
1548 decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp;
1549
1550 DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
1551}
1552
1553#undef bit_buf
1554#undef bits
1555#undef bit_ptr
1556
1557#define MOTION_CALL(routine,direction) \
1558do { \
1559 if ((direction) & MACROBLOCK_MOTION_FORWARD) \
1560 routine (decoder, &(decoder->f_motion), mpeg2_mc.put); \
1561 if ((direction) & MACROBLOCK_MOTION_BACKWARD) \
1562 routine (decoder, &(decoder->b_motion), \
1563 ((direction) & MACROBLOCK_MOTION_FORWARD ? \
1564 mpeg2_mc.avg : mpeg2_mc.put)); \
1565} while (0)
1566
1567#define NEXT_MACROBLOCK \
1568do { \
1569 decoder->offset += 16; \
1570 if (decoder->offset == decoder->width) { \
1571 do { /* just so we can use the break statement */ \
1572 if (decoder->convert) { \
1573 decoder->convert (decoder->convert_id, decoder->dest, \
1574 decoder->v_offset); \
1575 if (decoder->coding_type == B_TYPE) \
1576 break; \
1577 } \
1578 decoder->dest[0] += decoder->slice_stride; \
1579 decoder->dest[1] += decoder->slice_uv_stride; \
1580 decoder->dest[2] += decoder->slice_uv_stride; \
1581 } while (0); \
1582 decoder->v_offset += 16; \
1583 if (decoder->v_offset > decoder->limit_y) { \
1584 if (mpeg2_cpu_state_restore) \
1585 mpeg2_cpu_state_restore (&cpu_state); \
1586 return; \
1587 } \
1588 decoder->offset = 0; \
1589 } \
1590} while (0)
1591
1592void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3],
1593 uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3])
1594{
1595 int offset, stride, height, bottom_field;
1596
1597 stride = decoder->stride_frame;
1598 bottom_field = (decoder->picture_structure == BOTTOM_FIELD);
1599 offset = bottom_field ? stride : 0;
1600 height = decoder->height;
1601
1602 decoder->picture_dest[0] = current_fbuf[0] + offset;
1603 decoder->picture_dest[1] = current_fbuf[1] + (offset >> 1);
1604 decoder->picture_dest[2] = current_fbuf[2] + (offset >> 1);
1605
1606 decoder->f_motion.ref[0][0] = forward_fbuf[0] + offset;
1607 decoder->f_motion.ref[0][1] = forward_fbuf[1] + (offset >> 1);
1608 decoder->f_motion.ref[0][2] = forward_fbuf[2] + (offset >> 1);
1609
1610 decoder->b_motion.ref[0][0] = backward_fbuf[0] + offset;
1611 decoder->b_motion.ref[0][1] = backward_fbuf[1] + (offset >> 1);
1612 decoder->b_motion.ref[0][2] = backward_fbuf[2] + (offset >> 1);
1613
1614 if (decoder->picture_structure != FRAME_PICTURE) {
1615 decoder->dmv_offset = bottom_field ? 1 : -1;
1616 decoder->f_motion.ref2[0] = decoder->f_motion.ref[bottom_field];
1617 decoder->f_motion.ref2[1] = decoder->f_motion.ref[!bottom_field];
1618 decoder->b_motion.ref2[0] = decoder->b_motion.ref[bottom_field];
1619 decoder->b_motion.ref2[1] = decoder->b_motion.ref[!bottom_field];
1620 offset = stride - offset;
1621
1622 if (decoder->second_field && (decoder->coding_type != B_TYPE))
1623 forward_fbuf = current_fbuf;
1624
1625 decoder->f_motion.ref[1][0] = forward_fbuf[0] + offset;
1626 decoder->f_motion.ref[1][1] = forward_fbuf[1] + (offset >> 1);
1627 decoder->f_motion.ref[1][2] = forward_fbuf[2] + (offset >> 1);
1628
1629 decoder->b_motion.ref[1][0] = backward_fbuf[0] + offset;
1630 decoder->b_motion.ref[1][1] = backward_fbuf[1] + (offset >> 1);
1631 decoder->b_motion.ref[1][2] = backward_fbuf[2] + (offset >> 1);
1632
1633 stride <<= 1;
1634 height >>= 1;
1635 }
1636
1637 decoder->stride = stride;
1638 decoder->uv_stride = stride >> 1;
1639 decoder->slice_stride = 16 * stride;
1640 decoder->slice_uv_stride =
1641 decoder->slice_stride >> (2 - decoder->chroma_format);
1642 decoder->limit_x = 2 * decoder->width - 32;
1643 decoder->limit_y_16 = 2 * height - 32;
1644 decoder->limit_y_8 = 2 * height - 16;
1645 decoder->limit_y = height - 16;
1646
1647 if (decoder->mpeg1) {
1648 decoder->motion_parser[0] = motion_zero_420;
1649 decoder->motion_parser[MC_FRAME] = motion_mp1;
1650 decoder->motion_parser[4] = motion_reuse_420;
1651 } else if (decoder->picture_structure == FRAME_PICTURE) {
1652 if (decoder->chroma_format == 0) {
1653 decoder->motion_parser[0] = motion_zero_420;
1654 decoder->motion_parser[MC_FIELD] = motion_fr_field_420;
1655 decoder->motion_parser[MC_FRAME] = motion_fr_frame_420;
1656 decoder->motion_parser[MC_DMV] = motion_fr_dmv_420;
1657 decoder->motion_parser[4] = motion_reuse_420;
1658 } else if (decoder->chroma_format == 1) {
1659 decoder->motion_parser[0] = motion_zero_422;
1660 decoder->motion_parser[MC_FIELD] = motion_fr_field_422;
1661 decoder->motion_parser[MC_FRAME] = motion_fr_frame_422;
1662 decoder->motion_parser[MC_DMV] = motion_fr_dmv_422;
1663 decoder->motion_parser[4] = motion_reuse_422;
1664 } else {
1665 decoder->motion_parser[0] = motion_zero_444;
1666 decoder->motion_parser[MC_FIELD] = motion_fr_field_444;
1667 decoder->motion_parser[MC_FRAME] = motion_fr_frame_444;
1668 decoder->motion_parser[MC_DMV] = motion_fr_dmv_444;
1669 decoder->motion_parser[4] = motion_reuse_444;
1670 }
1671 } else {
1672 if (decoder->chroma_format == 0) {
1673 decoder->motion_parser[0] = motion_zero_420;
1674 decoder->motion_parser[MC_FIELD] = motion_fi_field_420;
1675 decoder->motion_parser[MC_16X8] = motion_fi_16x8_420;
1676 decoder->motion_parser[MC_DMV] = motion_fi_dmv_420;
1677 decoder->motion_parser[4] = motion_reuse_420;
1678 } else if (decoder->chroma_format == 1) {
1679 decoder->motion_parser[0] = motion_zero_422;
1680 decoder->motion_parser[MC_FIELD] = motion_fi_field_422;
1681 decoder->motion_parser[MC_16X8] = motion_fi_16x8_422;
1682 decoder->motion_parser[MC_DMV] = motion_fi_dmv_422;
1683 decoder->motion_parser[4] = motion_reuse_422;
1684 } else {
1685 decoder->motion_parser[0] = motion_zero_444;
1686 decoder->motion_parser[MC_FIELD] = motion_fi_field_444;
1687 decoder->motion_parser[MC_16X8] = motion_fi_16x8_444;
1688 decoder->motion_parser[MC_DMV] = motion_fi_dmv_444;
1689 decoder->motion_parser[4] = motion_reuse_444;
1690 }
1691 }
1692}
1693
1694static inline int slice_init (mpeg2_decoder_t * const decoder, int code)
1695{
1696#define bit_buf (decoder->bitstream_buf)
1697#define bits (decoder->bitstream_bits)
1698#define bit_ptr (decoder->bitstream_ptr)
1699 int offset;
1700 const MBAtab * mba;
1701
1702 decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
1703 decoder->dc_dct_pred[2] = 16384;
1704
1705 decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0;
1706 decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0;
1707 decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0;
1708 decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0;
1709
1710 if (decoder->vertical_position_extension) {
1711 code += UBITS (bit_buf, 3) << 7;
1712 DUMPBITS (bit_buf, bits, 3);
1713 }
1714 decoder->v_offset = (code - 1) * 16;
1715 offset = 0;
1716 if (!(decoder->convert) || decoder->coding_type != B_TYPE)
1717 offset = (code - 1) * decoder->slice_stride;
1718
1719 decoder->dest[0] = decoder->picture_dest[0] + offset;
1720 offset >>= (2 - decoder->chroma_format);
1721 decoder->dest[1] = decoder->picture_dest[1] + offset;
1722 decoder->dest[2] = decoder->picture_dest[2] + offset;
1723
1724 get_quantizer_scale (decoder);
1725
1726 /* ignore intra_slice and all the extra data */
1727 while (bit_buf & 0x80000000) {
1728 DUMPBITS (bit_buf, bits, 9);
1729 NEEDBITS (bit_buf, bits, bit_ptr);
1730 }
1731
1732 /* decode initial macroblock address increment */
1733 offset = 0;
1734 while (1) {
1735 if (bit_buf >= 0x08000000) {
1736 mba = MBA_5 + (UBITS (bit_buf, 6) - 2);
1737 break;
1738 } else if (bit_buf >= 0x01800000) {
1739 mba = MBA_11 + (UBITS (bit_buf, 12) - 24);
1740 break;
1741 } else switch (UBITS (bit_buf, 12)) {
1742 case 8: /* macroblock_escape */
1743 offset += 33;
1744 DUMPBITS (bit_buf, bits, 11);
1745 NEEDBITS (bit_buf, bits, bit_ptr);
1746 continue;
1747 case 15: /* macroblock_stuffing (MPEG1 only) */
1748 bit_buf &= 0xfffff;
1749 DUMPBITS (bit_buf, bits, 11);
1750 NEEDBITS (bit_buf, bits, bit_ptr);
1751 continue;
1752 default: /* error */
1753 return 1;
1754 }
1755 }
1756 DUMPBITS (bit_buf, bits, mba->len + 1);
1757 decoder->offset = (offset + mba->mba) << 4;
1758
1759 while (decoder->offset - decoder->width >= 0) {
1760 decoder->offset -= decoder->width;
1761 if (!(decoder->convert) || decoder->coding_type != B_TYPE) {
1762 decoder->dest[0] += decoder->slice_stride;
1763 decoder->dest[1] += decoder->slice_uv_stride;
1764 decoder->dest[2] += decoder->slice_uv_stride;
1765 }
1766 decoder->v_offset += 16;
1767 }
1768 if (decoder->v_offset > decoder->limit_y)
1769 return 1;
1770
1771 return 0;
1772#undef bit_buf
1773#undef bits
1774#undef bit_ptr
1775}
1776
1777void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code,
1778 const uint8_t * const buffer)
1779{
1780#define bit_buf (decoder->bitstream_buf)
1781#define bits (decoder->bitstream_bits)
1782#define bit_ptr (decoder->bitstream_ptr)
1783 cpu_state_t cpu_state;
1784
1785 bitstream_init (decoder, buffer);
1786
1787 if (slice_init (decoder, code))
1788 return;
1789
1790 if (mpeg2_cpu_state_save)
1791 mpeg2_cpu_state_save (&cpu_state);
1792
1793 while (1) {
1794 int macroblock_modes;
1795 int mba_inc;
1796 const MBAtab * mba;
1797
1798 NEEDBITS (bit_buf, bits, bit_ptr);
1799
1800 macroblock_modes = get_macroblock_modes (decoder);
1801
1802 /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */
1803 if (macroblock_modes & MACROBLOCK_QUANT)
1804 get_quantizer_scale (decoder);
1805
1806 if (macroblock_modes & MACROBLOCK_INTRA) {
1807
1808 int DCT_offset, DCT_stride;
1809 int offset;
1810 uint8_t * dest_y;
1811
1812 if (decoder->concealment_motion_vectors) {
1813 if (decoder->picture_structure == FRAME_PICTURE)
1814 motion_fr_conceal (decoder);
1815 else
1816 motion_fi_conceal (decoder);
1817 } else {
1818 decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0;
1819 decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0;
1820 decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0;
1821 decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0;
1822 }
1823
1824 if (macroblock_modes & DCT_TYPE_INTERLACED) {
1825 DCT_offset = decoder->stride;
1826 DCT_stride = decoder->stride * 2;
1827 } else {
1828 DCT_offset = decoder->stride * 8;
1829 DCT_stride = decoder->stride;
1830 }
1831
1832 offset = decoder->offset;
1833 dest_y = decoder->dest[0] + offset;
1834 slice_intra_DCT (decoder, 0, dest_y, DCT_stride);
1835 slice_intra_DCT (decoder, 0, dest_y + 8, DCT_stride);
1836 slice_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride);
1837 slice_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride);
1838 if (likely (decoder->chroma_format == 0)) {
1839 slice_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1),
1840 decoder->uv_stride);
1841 slice_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1),
1842 decoder->uv_stride);
1843 if (decoder->coding_type == D_TYPE) {
1844 NEEDBITS (bit_buf, bits, bit_ptr);
1845 DUMPBITS (bit_buf, bits, 1);
1846 }
1847 } else if (likely (decoder->chroma_format == 1)) {
1848 uint8_t * dest_u = decoder->dest[1] + (offset >> 1);
1849 uint8_t * dest_v = decoder->dest[2] + (offset >> 1);
1850 DCT_stride >>= 1;
1851 DCT_offset >>= 1;
1852 slice_intra_DCT (decoder, 1, dest_u, DCT_stride);
1853 slice_intra_DCT (decoder, 2, dest_v, DCT_stride);
1854 slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride);
1855 slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride);
1856 } else {
1857 uint8_t * dest_u = decoder->dest[1] + offset;
1858 uint8_t * dest_v = decoder->dest[2] + offset;
1859 slice_intra_DCT (decoder, 1, dest_u, DCT_stride);
1860 slice_intra_DCT (decoder, 2, dest_v, DCT_stride);
1861 slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride);
1862 slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride);
1863 slice_intra_DCT (decoder, 1, dest_u + 8, DCT_stride);
1864 slice_intra_DCT (decoder, 2, dest_v + 8, DCT_stride);
1865 slice_intra_DCT (decoder, 1, dest_u + DCT_offset + 8,
1866 DCT_stride);
1867 slice_intra_DCT (decoder, 2, dest_v + DCT_offset + 8,
1868 DCT_stride);
1869 }
1870 } else {
1871
1872 motion_parser_t * parser;
1873
1874 parser =
1875 decoder->motion_parser[macroblock_modes >> MOTION_TYPE_SHIFT];
1876 MOTION_CALL (parser, macroblock_modes);
1877
1878 if (macroblock_modes & MACROBLOCK_PATTERN) {
1879 int coded_block_pattern;
1880 int DCT_offset, DCT_stride;
1881
1882 if (macroblock_modes & DCT_TYPE_INTERLACED) {
1883 DCT_offset = decoder->stride;
1884 DCT_stride = decoder->stride * 2;
1885 } else {
1886 DCT_offset = decoder->stride * 8;
1887 DCT_stride = decoder->stride;
1888 }
1889
1890 coded_block_pattern = get_coded_block_pattern (decoder);
1891
1892 if (likely (decoder->chroma_format == 0)) {
1893 int offset = decoder->offset;
1894 uint8_t * dest_y = decoder->dest[0] + offset;
1895 if (coded_block_pattern & 1)
1896 slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride);
1897 if (coded_block_pattern & 2)
1898 slice_non_intra_DCT (decoder, 0, dest_y + 8,
1899 DCT_stride);
1900 if (coded_block_pattern & 4)
1901 slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset,
1902 DCT_stride);
1903 if (coded_block_pattern & 8)
1904 slice_non_intra_DCT (decoder, 0,
1905 dest_y + DCT_offset + 8,
1906 DCT_stride);
1907 if (coded_block_pattern & 16)
1908 slice_non_intra_DCT (decoder, 1,
1909 decoder->dest[1] + (offset >> 1),
1910 decoder->uv_stride);
1911 if (coded_block_pattern & 32)
1912 slice_non_intra_DCT (decoder, 2,
1913 decoder->dest[2] + (offset >> 1),
1914 decoder->uv_stride);
1915 } else if (likely (decoder->chroma_format == 1)) {
1916 int offset;
1917 uint8_t * dest_y;
1918
1919 coded_block_pattern |= bit_buf & (3 << 30);
1920 DUMPBITS (bit_buf, bits, 2);
1921
1922 offset = decoder->offset;
1923 dest_y = decoder->dest[0] + offset;
1924 if (coded_block_pattern & 1)
1925 slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride);
1926 if (coded_block_pattern & 2)
1927 slice_non_intra_DCT (decoder, 0, dest_y + 8,
1928 DCT_stride);
1929 if (coded_block_pattern & 4)
1930 slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset,
1931 DCT_stride);
1932 if (coded_block_pattern & 8)
1933 slice_non_intra_DCT (decoder, 0,
1934 dest_y + DCT_offset + 8,
1935 DCT_stride);
1936
1937 DCT_stride >>= 1;
1938 DCT_offset = (DCT_offset + offset) >> 1;
1939 if (coded_block_pattern & 16)
1940 slice_non_intra_DCT (decoder, 1,
1941 decoder->dest[1] + (offset >> 1),
1942 DCT_stride);
1943 if (coded_block_pattern & 32)
1944 slice_non_intra_DCT (decoder, 2,
1945 decoder->dest[2] + (offset >> 1),
1946 DCT_stride);
1947 if (coded_block_pattern & (2 << 30))
1948 slice_non_intra_DCT (decoder, 1,
1949 decoder->dest[1] + DCT_offset,
1950 DCT_stride);
1951 if (coded_block_pattern & (1 << 30))
1952 slice_non_intra_DCT (decoder, 2,
1953 decoder->dest[2] + DCT_offset,
1954 DCT_stride);
1955 } else {
1956 int offset;
1957 uint8_t * dest_y, * dest_u, * dest_v;
1958
1959 coded_block_pattern |= bit_buf & (63 << 26);
1960 DUMPBITS (bit_buf, bits, 6);
1961
1962 offset = decoder->offset;
1963 dest_y = decoder->dest[0] + offset;
1964 dest_u = decoder->dest[1] + offset;
1965 dest_v = decoder->dest[2] + offset;
1966
1967 if (coded_block_pattern & 1)
1968 slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride);
1969 if (coded_block_pattern & 2)
1970 slice_non_intra_DCT (decoder, 0, dest_y + 8,
1971 DCT_stride);
1972 if (coded_block_pattern & 4)
1973 slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset,
1974 DCT_stride);
1975 if (coded_block_pattern & 8)
1976 slice_non_intra_DCT (decoder, 0,
1977 dest_y + DCT_offset + 8,
1978 DCT_stride);
1979
1980 if (coded_block_pattern & 16)
1981 slice_non_intra_DCT (decoder, 1, dest_u, DCT_stride);
1982 if (coded_block_pattern & 32)
1983 slice_non_intra_DCT (decoder, 2, dest_v, DCT_stride);
1984 if (coded_block_pattern & (32 << 26))
1985 slice_non_intra_DCT (decoder, 1, dest_u + DCT_offset,
1986 DCT_stride);
1987 if (coded_block_pattern & (16 << 26))
1988 slice_non_intra_DCT (decoder, 2, dest_v + DCT_offset,
1989 DCT_stride);
1990 if (coded_block_pattern & (8 << 26))
1991 slice_non_intra_DCT (decoder, 1, dest_u + 8,
1992 DCT_stride);
1993 if (coded_block_pattern & (4 << 26))
1994 slice_non_intra_DCT (decoder, 2, dest_v + 8,
1995 DCT_stride);
1996 if (coded_block_pattern & (2 << 26))
1997 slice_non_intra_DCT (decoder, 1,
1998 dest_u + DCT_offset + 8,
1999 DCT_stride);
2000 if (coded_block_pattern & (1 << 26))
2001 slice_non_intra_DCT (decoder, 2,
2002 dest_v + DCT_offset + 8,
2003 DCT_stride);
2004 }
2005 }
2006
2007 decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
2008 decoder->dc_dct_pred[2] = 16384;
2009 }
2010
2011 NEXT_MACROBLOCK;
2012
2013 NEEDBITS (bit_buf, bits, bit_ptr);
2014 mba_inc = 0;
2015 while (1) {
2016 if (bit_buf >= 0x10000000) {
2017 mba = MBA_5 + (UBITS (bit_buf, 5) - 2);
2018 break;
2019 } else if (bit_buf >= 0x03000000) {
2020 mba = MBA_11 + (UBITS (bit_buf, 11) - 24);
2021 break;
2022 } else switch (UBITS (bit_buf, 11)) {
2023 case 8: /* macroblock_escape */
2024 mba_inc += 33;
2025 /* pass through */
2026 case 15: /* macroblock_stuffing (MPEG1 only) */
2027 DUMPBITS (bit_buf, bits, 11);
2028 NEEDBITS (bit_buf, bits, bit_ptr);
2029 continue;
2030 default: /* end of slice, or error */
2031 if (mpeg2_cpu_state_restore)
2032 mpeg2_cpu_state_restore (&cpu_state);
2033 return;
2034 }
2035 }
2036 DUMPBITS (bit_buf, bits, mba->len);
2037 mba_inc += mba->mba;
2038
2039 if (mba_inc) {
2040 decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
2041 decoder->dc_dct_pred[2] = 16384;
2042
2043 if (decoder->coding_type == P_TYPE) {
2044 do {
2045 MOTION_CALL (decoder->motion_parser[0],
2046 MACROBLOCK_MOTION_FORWARD);
2047 NEXT_MACROBLOCK;
2048 } while (--mba_inc);
2049 } else {
2050 do {
2051 MOTION_CALL (decoder->motion_parser[4], macroblock_modes);
2052 NEXT_MACROBLOCK;
2053 } while (--mba_inc);
2054 }
2055 }
2056 }
2057#undef bit_buf
2058#undef bits
2059#undef bit_ptr
2060}
diff --git a/apps/plugins/mpegplayer/video_out.h b/apps/plugins/mpegplayer/video_out.h
new file mode 100644
index 0000000000..342c551972
--- /dev/null
+++ b/apps/plugins/mpegplayer/video_out.h
@@ -0,0 +1,58 @@
1/*
2 * video_out.h
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24struct mpeg2_sequence_s;
25struct mpeg2_convert_init_s;
26typedef struct {
27 int (* convert) (int stage, void * id,
28 const struct mpeg2_sequence_s * sequence,
29 int stride, uint32_t accel, void * arg,
30 struct mpeg2_convert_init_s * result);
31} vo_setup_result_t;
32
33typedef struct vo_instance_s vo_instance_t;
34struct vo_instance_s {
35 int (* setup) (vo_instance_t * instance, unsigned int width,
36 unsigned int height, unsigned int chroma_width,
37 unsigned int chroma_height, vo_setup_result_t * result);
38 void (* setup_fbuf) (vo_instance_t * instance, uint8_t ** buf, void ** id);
39 void (* set_fbuf) (vo_instance_t * instance, uint8_t ** buf, void ** id);
40 void (* start_fbuf) (vo_instance_t * instance,
41 uint8_t * const * buf, void * id);
42 void (* draw) (vo_instance_t * instance, uint8_t * const * buf, void * id);
43 void (* discard) (vo_instance_t * instance,
44 uint8_t * const * buf, void * id);
45 void (* close) (vo_instance_t * instance);
46};
47
48typedef vo_instance_t * vo_open_t (void);
49
50typedef struct {
51 char * name;
52 vo_open_t * open;
53} vo_driver_t;
54
55void vo_accel (uint32_t accel);
56
57/* return NULL terminated array of all drivers */
58vo_driver_t const * vo_drivers (void);
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
new file mode 100644
index 0000000000..786d9d0e14
--- /dev/null
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -0,0 +1,285 @@
1/*
2 * video_out_null.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "mpeg2dec_config.h"
25
26#include "plugin.h"
27
28extern struct plugin_api* rb;
29
30#include "mpeg2.h"
31#include "video_out.h"
32
33static int starttick;
34
35#define CSUB_X 2
36#define CSUB_Y 2
37
38static int image_x;
39static int image_y;
40static int image_width;
41static int image_height;
42static int image_chroma_x;
43static int image_chroma_y;
44
45#if (LCD_DEPTH == 16) && \
46 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
47
48#define RYFAC (31*257)
49#define GYFAC (63*257)
50#define BYFAC (31*257)
51#define RVFAC 11170 /* 31 * 257 * 1.402 */
52#define GVFAC (-11563) /* 63 * 257 * -0.714136 */
53#define GUFAC (-5572) /* 63 * 257 * -0.344136 */
54#define BUFAC 14118 /* 31 * 257 * 1.772 */
55
56#define ROUNDOFFS (127*257)
57
58/* Draw a partial YUV colour bitmap - taken from the Rockbox JPEG viewer */
59void yuv_bitmap_part(unsigned char * const src[3],
60 int src_x, int src_y, int stride,
61 int x, int y, int width, int height)
62{
63 fb_data *dst, *dst_end;
64
65 /* nothing to draw? */
66 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
67 || (x + width <= 0) || (y + height <= 0))
68 return;
69
70 /* clipping */
71 if (x < 0)
72 {
73 width += x;
74 src_x -= x;
75 x = 0;
76 }
77 if (y < 0)
78 {
79 height += y;
80 src_y -= y;
81 y = 0;
82 }
83 if (x + width > LCD_WIDTH)
84 width = LCD_WIDTH - x;
85 if (y + height > LCD_HEIGHT)
86 height = LCD_HEIGHT - y;
87
88 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
89 dst_end = dst + LCD_WIDTH * height;
90
91 do
92 {
93 fb_data *dst_row = dst;
94 fb_data *row_end = dst_row + width;
95 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
96 int y, u, v;
97 int red, green, blue;
98 unsigned rbits, gbits, bbits;
99
100 if (CSUB_Y) /* colour */
101 {
102 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
103 const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y)
104 + (src_x/CSUB_X);
105 const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y)
106 + (src_x/CSUB_X);
107 int xphase = src_x % CSUB_X;
108 int rc, gc, bc;
109
110 u = *usrc++ - 128;
111 v = *vsrc++ - 128;
112 rc = RVFAC * v + ROUNDOFFS;
113 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
114 bc = BUFAC * u + ROUNDOFFS;
115
116 do
117 {
118 y = *ysrc++;
119 red = RYFAC * y + rc;
120 green = GYFAC * y + gc;
121 blue = BYFAC * y + bc;
122
123 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
124 {
125 if (red < 0)
126 red = 0;
127 else
128 red = (RYFAC*255+ROUNDOFFS);
129 }
130 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
131 {
132 if (green < 0)
133 green = 0;
134 else
135 green = (GYFAC*255+ROUNDOFFS);
136 }
137 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
138 {
139 if (blue < 0)
140 blue = 0;
141 else
142 blue = (BYFAC*255+ROUNDOFFS);
143 }
144 rbits = ((unsigned)red) >> 16 ;
145 gbits = ((unsigned)green) >> 16 ;
146 bbits = ((unsigned)blue) >> 16 ;
147#if LCD_PIXELFORMAT == RGB565
148 *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
149#elif LCD_PIXELFORMAT == RGB565SWAPPED
150 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | bbits);
151#endif
152
153 if (++xphase >= CSUB_X)
154 {
155 u = *usrc++ - 128;
156 v = *vsrc++ - 128;
157 rc = RVFAC * v + ROUNDOFFS;
158 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
159 bc = BUFAC * u + ROUNDOFFS;
160 xphase = 0;
161 }
162 }
163 while (dst_row < row_end);
164 }
165 else /* monochrome */
166 {
167 do
168 {
169 y = *ysrc++;
170 red = RYFAC * y + ROUNDOFFS; /* blue == red */
171 green = GYFAC * y + ROUNDOFFS;
172 rbits = ((unsigned)red) >> 16;
173 gbits = ((unsigned)green) >> 16;
174#if LCD_PIXELFORMAT == RGB565
175 *dst_row++ = (rbits << 11) | (gbits << 5) | rbits;
176#elif LCD_PIXELFORMAT == RGB565SWAPPED
177 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | rbits);
178#endif
179 }
180 while (dst_row < row_end);
181 }
182
183 src_y++;
184 dst += LCD_WIDTH;
185 }
186 while (dst < dst_end);
187}
188#endif
189
190static void rockbox_draw_frame (vo_instance_t * instance,
191 uint8_t * const * buf, void * id)
192{
193 char str[80];
194 static int frame=0;
195 int ticks,fps;
196
197 (void)id;
198 (void)instance;
199
200#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO) && \
201 !defined(SIMULATOR)
202 rb->lcd_yuv_blit(buf,
203 0,0,image_width,
204 image_x,image_y,image_width,image_height);
205#elif (LCD_DEPTH == 16) && \
206 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
207 yuv_bitmap_part(buf,0,0,image_width,
208 image_x,image_y,image_width,image_height);
209 rb->lcd_update_rect(image_x,image_y,image_width,image_height);
210#endif
211
212 if (starttick==0) starttick=*rb->current_tick-1; /* Avoid divby0 */
213
214 /* Calculate fps */
215 frame++;
216 if ((frame % 125) == 0) {
217 ticks=(*rb->current_tick)-starttick;
218
219 fps=(frame*1000)/ticks;
220 rb->snprintf(str,sizeof(str),"%d.%d",(fps/10),fps%10);
221 rb->lcd_putsxy(0,0,str);
222
223 rb->lcd_update_rect(0,0,80,8);
224 }
225}
226
227vo_instance_t static_instance;
228
229static vo_instance_t * internal_open (int setup (vo_instance_t *, unsigned int,
230 unsigned int, unsigned int,
231 unsigned int,
232 vo_setup_result_t *),
233 void draw (vo_instance_t *,
234 uint8_t * const *, void *))
235{
236 vo_instance_t * instance;
237
238 instance = (vo_instance_t *) &static_instance;
239 if (instance == NULL)
240 return NULL;
241
242 instance->setup = setup;
243 instance->setup_fbuf = NULL;
244 instance->set_fbuf = NULL;
245 instance->start_fbuf = NULL;
246 instance->draw = draw;
247 instance->discard = NULL;
248 //instance->close = (void (*) (vo_instance_t *)) free;
249
250 return instance;
251}
252
253static int rockbox_setup (vo_instance_t * instance, unsigned int width,
254 unsigned int height, unsigned int chroma_width,
255 unsigned int chroma_height,
256 vo_setup_result_t * result)
257{
258 (void)instance;
259
260 result->convert = NULL;
261
262 image_width=width;
263 image_height=height;
264 image_chroma_x=image_width/chroma_width;
265 image_chroma_y=image_height/chroma_height;
266
267 if (image_width >= LCD_WIDTH) {
268 image_x = 0;
269 } else {
270 image_x = (LCD_WIDTH-image_width)/2;
271 }
272
273 if (image_height >= LCD_HEIGHT) {
274 image_y = 0;
275 } else {
276 image_y = (LCD_HEIGHT-image_height)/2;
277 }
278
279 return 0;
280}
281
282vo_instance_t * vo_rockbox_open (void)
283{
284 return internal_open (rockbox_setup, rockbox_draw_frame);
285}
diff --git a/apps/plugins/mpegplayer/vlc.h b/apps/plugins/mpegplayer/vlc.h
new file mode 100644
index 0000000000..7098ee0f9b
--- /dev/null
+++ b/apps/plugins/mpegplayer/vlc.h
@@ -0,0 +1,429 @@
1/*
2 * vlc.h
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#define GETWORD(bit_buf,shift,bit_ptr) \
25do { \
26 bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \
27 bit_ptr += 2; \
28} while (0)
29
30static inline void bitstream_init (mpeg2_decoder_t * decoder,
31 const uint8_t * start)
32{
33 decoder->bitstream_buf =
34 (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3];
35 decoder->bitstream_ptr = start + 4;
36 decoder->bitstream_bits = -16;
37}
38
39/* make sure that there are at least 16 valid bits in bit_buf */
40#define NEEDBITS(bit_buf,bits,bit_ptr) \
41do { \
42 if (unlikely (bits > 0)) { \
43 GETWORD (bit_buf, bits, bit_ptr); \
44 bits -= 16; \
45 } \
46} while (0)
47
48/* remove num valid bits from bit_buf */
49#define DUMPBITS(bit_buf,bits,num) \
50do { \
51 bit_buf <<= (num); \
52 bits += (num); \
53} while (0)
54
55/* take num bits from the high part of bit_buf and zero extend them */
56#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num)))
57
58/* take num bits from the high part of bit_buf and sign extend them */
59#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num)))
60
61typedef struct {
62 uint8_t modes;
63 uint8_t len;
64} MBtab;
65
66typedef struct {
67 uint8_t delta;
68 uint8_t len;
69} MVtab;
70
71typedef struct {
72 int8_t dmv;
73 uint8_t len;
74} DMVtab;
75
76typedef struct {
77 uint8_t cbp;
78 uint8_t len;
79} CBPtab;
80
81typedef struct {
82 uint8_t size;
83 uint8_t len;
84} DCtab;
85
86typedef struct {
87 uint8_t run;
88 uint8_t level;
89 uint8_t len;
90} DCTtab;
91
92typedef struct {
93 uint8_t mba;
94 uint8_t len;
95} MBAtab;
96
97
98#define INTRA MACROBLOCK_INTRA
99#define QUANT MACROBLOCK_QUANT
100
101static const MBtab MB_I [] = {
102 {INTRA|QUANT, 2}, {INTRA, 1}
103};
104
105#define MC MACROBLOCK_MOTION_FORWARD
106#define CODED MACROBLOCK_PATTERN
107
108static const MBtab MB_P [] = {
109 {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5},
110 {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3},
111 {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
112 {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
113 {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
114 {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
115 {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
116 {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}
117};
118
119#define FWD MACROBLOCK_MOTION_FORWARD
120#define BWD MACROBLOCK_MOTION_BACKWARD
121#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD
122
123static const MBtab MB_B [] = {
124 {0, 0}, {INTRA|QUANT, 6},
125 {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6},
126 {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5},
127 {INTRA, 5}, {INTRA, 5},
128 {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4},
129 {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4},
130 {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
131 {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
132 {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
133 {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
134 {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
135 {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
136 {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
137 {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
138 {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
139 {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
140 {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
141 {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}
142};
143
144#undef INTRA
145#undef QUANT
146#undef MC
147#undef CODED
148#undef FWD
149#undef BWD
150#undef INTER
151
152
153static const MVtab MV_4 [] = {
154 { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2}
155};
156
157static const MVtab MV_10 [] = {
158 { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10},
159 { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10},
160 {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9},
161 { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7},
162 { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7},
163 { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}
164};
165
166
167static const DMVtab DMV_2 [] = {
168 { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
169};
170
171
172static const CBPtab CBP_7 [] = {
173 {0x11, 7}, {0x12, 7}, {0x14, 7}, {0x18, 7},
174 {0x21, 7}, {0x22, 7}, {0x24, 7}, {0x28, 7},
175 {0x3f, 6}, {0x3f, 6}, {0x30, 6}, {0x30, 6},
176 {0x09, 6}, {0x09, 6}, {0x06, 6}, {0x06, 6},
177 {0x1f, 5}, {0x1f, 5}, {0x1f, 5}, {0x1f, 5},
178 {0x10, 5}, {0x10, 5}, {0x10, 5}, {0x10, 5},
179 {0x2f, 5}, {0x2f, 5}, {0x2f, 5}, {0x2f, 5},
180 {0x20, 5}, {0x20, 5}, {0x20, 5}, {0x20, 5},
181 {0x07, 5}, {0x07, 5}, {0x07, 5}, {0x07, 5},
182 {0x0b, 5}, {0x0b, 5}, {0x0b, 5}, {0x0b, 5},
183 {0x0d, 5}, {0x0d, 5}, {0x0d, 5}, {0x0d, 5},
184 {0x0e, 5}, {0x0e, 5}, {0x0e, 5}, {0x0e, 5},
185 {0x05, 5}, {0x05, 5}, {0x05, 5}, {0x05, 5},
186 {0x0a, 5}, {0x0a, 5}, {0x0a, 5}, {0x0a, 5},
187 {0x03, 5}, {0x03, 5}, {0x03, 5}, {0x03, 5},
188 {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5},
189 {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4},
190 {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4},
191 {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4},
192 {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4},
193 {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
194 {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
195 {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
196 {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
197 {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
198 {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
199 {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
200 {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}
201};
202
203static const CBPtab CBP_9 [] = {
204 {0, 0}, {0x00, 9}, {0x39, 9}, {0x36, 9},
205 {0x37, 9}, {0x3b, 9}, {0x3d, 9}, {0x3e, 9},
206 {0x17, 8}, {0x17, 8}, {0x1b, 8}, {0x1b, 8},
207 {0x1d, 8}, {0x1d, 8}, {0x1e, 8}, {0x1e, 8},
208 {0x27, 8}, {0x27, 8}, {0x2b, 8}, {0x2b, 8},
209 {0x2d, 8}, {0x2d, 8}, {0x2e, 8}, {0x2e, 8},
210 {0x19, 8}, {0x19, 8}, {0x16, 8}, {0x16, 8},
211 {0x29, 8}, {0x29, 8}, {0x26, 8}, {0x26, 8},
212 {0x35, 8}, {0x35, 8}, {0x3a, 8}, {0x3a, 8},
213 {0x33, 8}, {0x33, 8}, {0x3c, 8}, {0x3c, 8},
214 {0x15, 8}, {0x15, 8}, {0x1a, 8}, {0x1a, 8},
215 {0x13, 8}, {0x13, 8}, {0x1c, 8}, {0x1c, 8},
216 {0x25, 8}, {0x25, 8}, {0x2a, 8}, {0x2a, 8},
217 {0x23, 8}, {0x23, 8}, {0x2c, 8}, {0x2c, 8},
218 {0x31, 8}, {0x31, 8}, {0x32, 8}, {0x32, 8},
219 {0x34, 8}, {0x34, 8}, {0x38, 8}, {0x38, 8}
220};
221
222
223static const DCtab DC_lum_5 [] = {
224 {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
225 {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
226 {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
227 {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}
228};
229
230static const DCtab DC_chrom_5 [] = {
231 {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
232 {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
233 {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
234 {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}
235};
236
237static const DCtab DC_long [] = {
238 {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
239 {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
240 {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6},
241 {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9}
242};
243
244
245static const DCTtab DCT_16 [] = {
246 {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
247 {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
248 {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
249 {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
250 { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
251 { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
252 { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
253 { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
254};
255
256static const DCTtab DCT_15 [] = {
257 { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
258 { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
259 { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
260 { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
261 { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
262 { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
263 { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
264 { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
265 { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
266 { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
267 { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
268 { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
269};
270
271static const DCTtab DCT_13 [] = {
272 { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
273 { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
274 { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
275 { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
276 { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
277 { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
278 { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
279 { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
280 { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
281 { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
282 { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
283 { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
284};
285
286static const DCTtab DCT_B14_10 [] = {
287 { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
288 { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
289};
290
291static const DCTtab DCT_B14_8 [] = {
292 { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
293 { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
294 { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
295 { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
296 { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
297 { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
298 { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
299 { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
300 { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
301};
302
303static const DCTtab DCT_B14AC_5 [] = {
304 { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
305 { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
306 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
307 {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
308 {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
309 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
310 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
311};
312
313static const DCTtab DCT_B14DC_5 [] = {
314 { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
315 { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
316 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
317 { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
318 { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
319 { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
320 { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
321};
322
323static const DCTtab DCT_B15_10 [] = {
324 { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
325 { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
326};
327
328static const DCTtab DCT_B15_8 [] = {
329 { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
330 { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
331 { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
332 { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
333 { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
334 { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
335 { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
336 { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
337 { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
338 { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
339 { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
340 { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
341 { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
342 { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
343 { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
344 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
345 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
346 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
347 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
348 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
349 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
350 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
351 { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
352 {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
353 {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
354 {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
355 {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
356 { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
357 { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
358 { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
359 { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
360 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
361 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
362 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
363 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
364 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
365 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
366 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
367 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
368 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
369 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
370 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
371 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
372 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
373 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
374 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
375 { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
376 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
377 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
378 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
379 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
380 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
381 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
382 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
383 { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
384 { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
385 { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
386 { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
387 { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
388 { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
389 { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
390 { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
391 { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
392};
393
394
395static const MBAtab MBA_5 [] = {
396 {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4},
397 {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
398 {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
399 {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}
400};
401
402static const MBAtab MBA_11 [] = {
403 {32, 11}, {31, 11}, {30, 11}, {29, 11},
404 {28, 11}, {27, 11}, {26, 11}, {25, 11},
405 {24, 11}, {23, 11}, {22, 11}, {21, 11},
406 {20, 10}, {20, 10}, {19, 10}, {19, 10},
407 {18, 10}, {18, 10}, {17, 10}, {17, 10},
408 {16, 10}, {16, 10}, {15, 10}, {15, 10},
409 {14, 8}, {14, 8}, {14, 8}, {14, 8},
410 {14, 8}, {14, 8}, {14, 8}, {14, 8},
411 {13, 8}, {13, 8}, {13, 8}, {13, 8},
412 {13, 8}, {13, 8}, {13, 8}, {13, 8},
413 {12, 8}, {12, 8}, {12, 8}, {12, 8},
414 {12, 8}, {12, 8}, {12, 8}, {12, 8},
415 {11, 8}, {11, 8}, {11, 8}, {11, 8},
416 {11, 8}, {11, 8}, {11, 8}, {11, 8},
417 {10, 8}, {10, 8}, {10, 8}, {10, 8},
418 {10, 8}, {10, 8}, {10, 8}, {10, 8},
419 { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
420 { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
421 { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
422 { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
423 { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
424 { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
425 { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
426 { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
427 { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
428 { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
429};
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 7b937a90a9..0b5ec06c40 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -21,4 +21,4 @@ wav,viewers/wav2wv, 00 00 00 00 00 00
21wav,viewers/mp3_encoder, 00 00 00 00 00 00 21wav,viewers/mp3_encoder, 00 00 00 00 00 00
22wav,viewers/wavplay,60 7F 05 35 3F 00 22wav,viewers/wavplay,60 7F 05 35 3F 00
23bmp,rocks/rockpaint, 01 10 01 10 01 10 23bmp,rocks/rockpaint, 01 10 01 10 01 10
24 24m2v,viewers/mpegplayer,60 7F 05 35 3F 00
diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c
index 52fde25bf0..875bf8ffa0 100644
--- a/firmware/drivers/lcd-ipod.c
+++ b/firmware/drivers/lcd-ipod.c
@@ -400,6 +400,237 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
400 (void)stride; 400 (void)stride;
401} 401}
402 402
403#define CSUB_X 2
404#define CSUB_Y 2
405
406#define RYFAC (31*257)
407#define GYFAC (63*257)
408#define BYFAC (31*257)
409#define RVFAC 11170 /* 31 * 257 * 1.402 */
410#define GVFAC (-11563) /* 63 * 257 * -0.714136 */
411#define GUFAC (-5572) /* 63 * 257 * -0.344136 */
412#define BUFAC 14118 /* 31 * 257 * 1.772 */
413
414#define ROUNDOFFS (127*257)
415
416/* Performance function to blit a YUV bitmap directly to the LCD */
417void lcd_yuv_blit(unsigned char * const src[3],
418 int src_x, int src_y, int stride,
419 int x, int y, int width, int height)
420{
421 int y0, x0, y1, x1;
422 int h;
423
424 /* nothing to draw? */
425 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
426 || (x + width <= 0) || (y + height <= 0))
427 return;
428
429 /* clipping */
430 if (x < 0)
431 {
432 width += x;
433 src_x -= x;
434 x = 0;
435 }
436 if (y < 0)
437 {
438 height += y;
439 src_y -= y;
440 y = 0;
441 }
442 if (x + width > LCD_WIDTH)
443 width = LCD_WIDTH - x;
444 if (y + height > LCD_HEIGHT)
445 height = LCD_HEIGHT - y;
446
447 /* calculate the drawing region */
448#if CONFIG_LCD == LCD_IPODNANO
449 y0 = x; /* start horiz */
450 x0 = y; /* start vert */
451 y1 = (x + width) - 1; /* max horiz */
452 x1 = (y + height) - 1; /* max vert */
453#elif CONFIG_LCD == LCD_IPODCOLOR
454 y0 = y; /* start vert */
455 x0 = (LCD_WIDTH - 1) - x; /* start horiz */
456 y1 = (y + height) - 1; /* end vert */
457 x1 = (x0 - width) + 1; /* end horiz */
458#endif
459
460 /* setup the drawing region */
461 if (lcd_type == 0) {
462 lcd_cmd_data(0x12, y0); /* start vert */
463 lcd_cmd_data(0x13, x0); /* start horiz */
464 lcd_cmd_data(0x15, y1); /* end vert */
465 lcd_cmd_data(0x16, x1); /* end horiz */
466 } else {
467 /* swap max horiz < start horiz */
468 if (y1 < y0) {
469 int t;
470 t = y0;
471 y0 = y1;
472 y1 = t;
473 }
474
475 /* swap max vert < start vert */
476 if (x1 < x0) {
477 int t;
478 t = x0;
479 x0 = x1;
480 x1 = t;
481 }
482
483 /* max horiz << 8 | start horiz */
484 lcd_cmd_data(LCD_CNTL_HORIZ_RAM_ADDR_POS, (y1 << 8) | y0);
485 /* max vert << 8 | start vert */
486 lcd_cmd_data(LCD_CNTL_VERT_RAM_ADDR_POS, (x1 << 8) | x0);
487
488 /* start vert = max vert */
489#if CONFIG_LCD == LCD_IPODCOLOR
490 x0 = x1;
491#endif
492
493 /* position cursor (set AD0-AD15) */
494 /* start vert << 8 | start horiz */
495 lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
496
497 /* start drawing */
498 lcd_send_lo(0x0);
499 lcd_send_lo(LCD_CNTL_WRITE_TO_GRAM);
500 }
501
502 h=0;
503 while (1) {
504 int pixels_to_write;
505 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
506 const unsigned char *row_end = ysrc + width;
507 int y, u, v;
508 int red, green, blue;
509 unsigned rbits, gbits, bbits;
510 fb_data pixel1,pixel2;
511
512 if (h==0) {
513 while ((inl(0x70008a20) & 0x4000000) == 0);
514 outl(0x0, 0x70008a24);
515
516 if (height == 0) break;
517
518 pixels_to_write = (width * height) * 2;
519 h = height;
520
521 /* calculate how much we can do in one go */
522 if (pixels_to_write > 64000) {
523 h = (64000/2) / width;
524 pixels_to_write = (width * h) * 2;
525 }
526
527 height -= h;
528 outl(0x10000080, 0x70008a20);
529 outl((pixels_to_write - 1) | 0xc0010000, 0x70008a24);
530 outl(0x34000000, 0x70008a20);
531 }
532
533 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
534 const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y)
535 + (src_x/CSUB_X);
536 const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y)
537 + (src_x/CSUB_X);
538 int rc, gc, bc;
539
540 u = *usrc++ - 128;
541 v = *vsrc++ - 128;
542 rc = RVFAC * v + ROUNDOFFS;
543 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
544 bc = BUFAC * u + ROUNDOFFS;
545
546 do
547 {
548 y = *ysrc++;
549 red = RYFAC * y + rc;
550 green = GYFAC * y + gc;
551 blue = BYFAC * y + bc;
552
553 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
554 {
555 if (red < 0)
556 red = 0;
557 else
558 red = (RYFAC*255+ROUNDOFFS);
559 }
560 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
561 {
562 if (green < 0)
563 green = 0;
564 else
565 green = (GYFAC*255+ROUNDOFFS);
566 }
567 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
568 {
569 if (blue < 0)
570 blue = 0;
571 else
572 blue = (BYFAC*255+ROUNDOFFS);
573 }
574 rbits = ((unsigned)red) >> 16 ;
575 gbits = ((unsigned)green) >> 16 ;
576 bbits = ((unsigned)blue) >> 16 ;
577
578 pixel1 = swap16((rbits << 11) | (gbits << 5) | bbits);
579
580 y = *ysrc++;
581 red = RYFAC * y + rc;
582 green = GYFAC * y + gc;
583 blue = BYFAC * y + bc;
584
585 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
586 {
587 if (red < 0)
588 red = 0;
589 else
590 red = (RYFAC*255+ROUNDOFFS);
591 }
592 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
593 {
594 if (green < 0)
595 green = 0;
596 else
597 green = (GYFAC*255+ROUNDOFFS);
598 }
599 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
600 {
601 if (blue < 0)
602 blue = 0;
603 else
604 blue = (BYFAC*255+ROUNDOFFS);
605 }
606 rbits = ((unsigned)red) >> 16 ;
607 gbits = ((unsigned)green) >> 16 ;
608 bbits = ((unsigned)blue) >> 16 ;
609
610 pixel2 = swap16((rbits << 11) | (gbits << 5) | bbits);
611
612 u = *usrc++ - 128;
613 v = *vsrc++ - 128;
614 rc = RVFAC * v + ROUNDOFFS;
615 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
616 bc = BUFAC * u + ROUNDOFFS;
617
618 while ((inl(0x70008a20) & 0x1000000) == 0);
619
620 /* output 2 pixels */
621 outl((pixel2<<16)|pixel1, 0x70008b00);
622 }
623 while (ysrc < row_end);
624
625 src_y++;
626 h--;
627 }
628
629 while ((inl(0x70008a20) & 0x4000000) == 0);
630 outl(0x0, 0x70008a24);
631}
632
633
403/* Update a fraction of the display. */ 634/* Update a fraction of the display. */
404void lcd_update_rect(int x, int y, int width, int height) 635void lcd_update_rect(int x, int y, int width, int height)
405{ 636{
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 38561a725e..32a958af2a 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -71,6 +71,12 @@ extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string,
71 int style); 71 int style);
72extern void lcd_icon(int icon, bool enable); 72extern void lcd_icon(int icon, bool enable);
73 73
74#if CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO
75void lcd_yuv_blit(unsigned char * const src[3],
76 int src_x, int src_y, int stride,
77 int x, int y, int width, int height);
78#endif
79
74#if defined(SIMULATOR) || defined(HAVE_LCD_BITMAP) 80#if defined(SIMULATOR) || defined(HAVE_LCD_BITMAP)
75/* performance function */ 81/* performance function */
76extern void lcd_blit(const fb_data* data, int x, int by, int width, 82extern void lcd_blit(const fb_data* data, int x, int by, int width,