diff options
author | Dave Chapman <dave@dchapman.com> | 2006-08-07 22:11:07 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2006-08-07 22:11:07 +0000 |
commit | c9d66562afc15de210854b32f30976859bce2023 (patch) | |
tree | 4fc7c506797bf96e389bd2fb68dd0e36d2735750 | |
parent | 754e173c252ab80a9e1e290bddfa126e6227ac1c (diff) | |
download | rockbox-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
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 | ||
467 | int plugin_load(const char* plugin, void* parameter) | 472 | int 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 | |||
32 | doom | 32 | doom |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /* For all the colour targets */ | ||
36 | #if defined(HAVE_LCD_COLOR) | ||
37 | mpegplayer | ||
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 @@ | |||
1 | Aaron Holtzman <aholtzma@ess.engr.uvic.ca> started the project and | ||
2 | made the initial working implementation. | ||
3 | |||
4 | Michel Lespinasse <walken@zoy.org> did major changes for speed and | ||
5 | mpeg conformance and is the current maintainer. Most of the current | ||
6 | code was (re)written by him. | ||
7 | |||
8 | Other 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 | |||
32 | Thanks to David Schleef for creating me an account on his ppc g4 | ||
33 | machine 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 | |||
10 | INCLUDES = -I$(APPSDIR) -I.. -I. $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ | ||
11 | -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR) | ||
12 | CFLAGS = $(INCLUDES) $(GCCOPTS) -O2 $(TARGET) $(EXTRA_DEFINES) \ | ||
13 | -DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN | ||
14 | |||
15 | |||
16 | ifdef APPEXTRA | ||
17 | INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA))) | ||
18 | endif | ||
19 | |||
20 | LINKFILE := $(OBJDIR)/link.lds | ||
21 | DEPFILE = $(OBJDIR)/dep-mpegplayer | ||
22 | |||
23 | # This sets up 'SRC' based on the files mentioned in SOURCES | ||
24 | include $(TOOLSDIR)/makesrc.inc | ||
25 | |||
26 | SOURCES = $(SRC) | ||
27 | OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o) | ||
28 | OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2)) | ||
29 | DIRS = . | ||
30 | |||
31 | LDS := ../plugin.lds | ||
32 | OUTPUT = $(OUTDIR)/mpegplayer.rock | ||
33 | |||
34 | all: $(OUTPUT) | ||
35 | |||
36 | ifndef 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 $< $@ | ||
45 | else | ||
46 | |||
47 | ifeq ($(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 $@ | ||
54 | ifeq ($(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 | ||
58 | else | ||
59 | @chmod -x $@ | ||
60 | endif | ||
61 | |||
62 | else # end of x11-simulator | ||
63 | ifeq ($(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 $@ | ||
70 | ifeq ($(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 | ||
74 | else | ||
75 | @chmod -x $@ | ||
76 | endif | ||
77 | |||
78 | else # end of sdl-simulator | ||
79 | ################################################### | ||
80 | # This is the win32 simulator version | ||
81 | DLLTOOLFLAGS = --export-all | ||
82 | DLLWRAPFLAGS = -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 $@ | ||
89 | ifeq ($(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 | ||
93 | else | ||
94 | @chmod -x $@ | ||
95 | endif | ||
96 | endif # end of win32-simulator | ||
97 | endif | ||
98 | endif # end of simulator section | ||
99 | |||
100 | |||
101 | include $(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 | |||
110 | clean: | ||
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 | |||
3 | ABOUT LIBMPEG2 | ||
4 | |||
5 | libmpeg2 is a free library for decoding mpeg-2 and mpeg-1 video | ||
6 | streams. It is released under the terms of the GPL license. | ||
7 | |||
8 | The 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 | |||
45 | The project homepage is at http://libmpeg2.sourceforge.net/ | ||
46 | |||
47 | |||
48 | MPEG2DEC | ||
49 | |||
50 | mpeg2dec is a test program for libmpeg2. It decodes mpeg-1 and mpeg-2 | ||
51 | video streams, and also includes a demultiplexer for mpeg-1 and mpeg-2 | ||
52 | program streams. It is purposely kept simple : it does not include | ||
53 | features like reading files from a DVD, CSS, fullscreen output, | ||
54 | navigation, etc... The main purpose of mpeg2dec is to have a simple | ||
55 | test bed for libmpeg2. | ||
56 | |||
57 | The libmpeg2 source code is always distributed in the mpeg2dec | ||
58 | package, to make it easier for people to test it. | ||
59 | |||
60 | The basic usage is to just type "mpeg2dec file" where file is a | ||
61 | demultiplexed mpeg video file. | ||
62 | |||
63 | The "-s" option must be used for multiplexed (audio and video) mpeg | ||
64 | files using the "program stream" format. These files are usualy found | ||
65 | on the internet or on unencrypted DVDs. | ||
66 | |||
67 | The "-t" option must be used for multiplexed (audio and video) mpeg | ||
68 | files using the "transport stream" format. These files are usualy | ||
69 | found in digital TV applications. | ||
70 | |||
71 | The "-o" option is used to select a given output module - for example | ||
72 | to redirect the output to a file. This is also used for performance | ||
73 | testing and conformance testing. | ||
74 | |||
75 | The "-c" option is used to disable all optimizations. | ||
76 | |||
77 | |||
78 | OTHER PROJECTS USING LIBMPEG2 | ||
79 | |||
80 | libmpeg2 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 | |||
123 | If you use libmpeg2 in another project, let us know ! | ||
124 | |||
125 | |||
126 | TASKS | ||
127 | |||
128 | There 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 | |||
158 | CVS SNAPSHOTS | ||
159 | |||
160 | A daily snapshot is created using "make distcheck" every night and | ||
161 | uploaded to http://libmpeg2.sourceforge.net/files/mpeg2dec-snapshot.tar.gz . | ||
162 | It is easier to use than the CVS repository, because you do not need | ||
163 | to have the right versions of automake, autoconf and libtool | ||
164 | installed. It might be convenient when working on a libmpeg2 port for | ||
165 | example. | ||
166 | |||
167 | |||
168 | CVS REPOSITORY | ||
169 | |||
170 | The latest libmpeg2 and mpeg2dec source code can always be found by | ||
171 | anonymous 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 | |||
177 | You can also browse the latest changes online at | ||
178 | http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/libmpeg2/mpeg2dec/ | ||
179 | |||
180 | The other CVS modules are mpeg2dec-streams for the test suite, and | ||
181 | mpeg2dec-livid for the CVS history of the project while it was still | ||
182 | hosted on the linuxvideo.org servers. | ||
183 | |||
184 | |||
185 | MAILING LISTS | ||
186 | |||
187 | See the subscription information at http://libmpeg2.sourceforge.net/lists.html | ||
188 | |||
189 | libmpeg2-devel | ||
190 | |||
191 | This is the main mailing list for technical discussion about | ||
192 | libmpeg2. Anyone wanting to work on libmpeg2, or maybe just stay | ||
193 | informed about the development process, should probably subscribe to | ||
194 | this list. | ||
195 | |||
196 | libmpeg2-checkins | ||
197 | |||
198 | All libmpeg2 checkins are announced there. This is a good way to keep | ||
199 | track of what goes into CVS. | ||
200 | |||
201 | libmpeg2-announce | ||
202 | |||
203 | This is a very low traffic mailing list, only for announcements of new | ||
204 | versions 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 @@ | |||
1 | Library: libmpeg2 from mpeg2dec-0.4.0b (Released 2004-01-21) | ||
2 | Imported: 2006-08-06 by Dave Chapman | ||
3 | |||
4 | |||
5 | This directory contains a local version of libmpeg2 imported into | ||
6 | Rockbox for MPEG video decoding. | ||
7 | |||
8 | |||
9 | LICENSING INFORMATION | ||
10 | |||
11 | mpeg2dec and libmpeg2 are licensed under Version 2 of the GNU General | ||
12 | Public License. | ||
13 | |||
14 | |||
15 | IMPORT DETAILS | ||
16 | |||
17 | The following files were imported from the mpeg2dec-0.4.0b | ||
18 | distribution. Minor changes were made to enable compilation in | ||
19 | Rockbox and TABs were replaced by spaces to comply with the Rockbox | ||
20 | coding guidelines. | ||
21 | |||
22 | AUTHORS | ||
23 | README | ||
24 | SOURCES | ||
25 | attributes.h | ||
26 | cpu_accel.c | ||
27 | cpu_state.c | ||
28 | decode.c | ||
29 | header.c | ||
30 | idct.c | ||
31 | motion_comp.c | ||
32 | mpeg2.h | ||
33 | mpeg2_internal.h | ||
34 | slice.c | ||
35 | video_out.h | ||
36 | vlc.h | ||
37 | |||
38 | The following files are new, but based on code in mpeg2dec. | ||
39 | |||
40 | Makefile | ||
41 | mpegplayer.c | ||
42 | video_out_rockbox.c | ||
43 | mpeg2dec_config.h | ||
44 | alloc.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 @@ | |||
1 | alloc.c | ||
2 | cpu_accel.c | ||
3 | cpu_state.c | ||
4 | decode.c | ||
5 | header.c | ||
6 | idct.c | ||
7 | motion_comp.c | ||
8 | slice.c | ||
9 | video_out_rockbox.c | ||
10 | mpegplayer.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 | |||
28 | extern struct plugin_api* rb; | ||
29 | |||
30 | long mem_ptr; | ||
31 | long bufsize; | ||
32 | unsigned char* mallocbuf; | ||
33 | |||
34 | void mpeg2_alloc_init(unsigned char* buf, int mallocsize) | ||
35 | { | ||
36 | mem_ptr = 0; | ||
37 | bufsize = mallocsize; | ||
38 | mallocbuf = buf; | ||
39 | |||
40 | return; | ||
41 | } | ||
42 | |||
43 | void * 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 | |||
60 | void 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 | |||
67 | void *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 | ||
34 | static 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 | |||
115 | static sigjmp_buf jmpbuf; | ||
116 | static volatile sig_atomic_t canjump = 0; | ||
117 | |||
118 | static 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 | ||
130 | static 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 | ||
160 | static 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 | ||
196 | static 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 | |||
209 | uint32_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 | |||
35 | void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; | ||
36 | void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; | ||
37 | |||
38 | #ifdef ARCH_X86 | ||
39 | static 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 | |||
60 | static 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 | |||
87 | static 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 | |||
115 | void 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 | |||
28 | extern struct plugin_api* rb; | ||
29 | |||
30 | #include "mpeg2.h" | ||
31 | #include "attributes.h" | ||
32 | #include "mpeg2_internal.h" | ||
33 | |||
34 | static int mpeg2_accels = 0; | ||
35 | |||
36 | #define BUFFER_SIZE (1194 * 1024) | ||
37 | |||
38 | const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec) | ||
39 | { | ||
40 | return &(mpeg2dec->info); | ||
41 | } | ||
42 | |||
43 | static 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 | |||
75 | static 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 | |||
111 | void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end) | ||
112 | { | ||
113 | mpeg2dec->buf_start = start; | ||
114 | mpeg2dec->buf_end = end; | ||
115 | } | ||
116 | |||
117 | int mpeg2_getpos (mpeg2dec_t * mpeg2dec) | ||
118 | { | ||
119 | return mpeg2dec->buf_end - mpeg2dec->buf_start; | ||
120 | } | ||
121 | |||
122 | static 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 | |||
137 | mpeg2_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 | |||
152 | mpeg2_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 | |||
217 | mpeg2_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 | |||
299 | int 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 | |||
315 | int 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 | |||
334 | void 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 | |||
356 | void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf) | ||
357 | { | ||
358 | mpeg2dec->custom_fbuf = custom_fbuf; | ||
359 | } | ||
360 | |||
361 | void 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 | |||
367 | void 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 | |||
375 | void 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 | |||
385 | uint32_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 | |||
398 | void 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 | |||
419 | mpeg2dec_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 | |||
442 | void 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 | |||
29 | extern 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 */ | ||
43 | static 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 | |||
61 | uint8_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 | |||
69 | uint8_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 | |||
77 | void 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 | |||
117 | void 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 | |||
124 | static 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 | |||
132 | int 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 | |||
201 | static 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 | |||
249 | static 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 | |||
275 | static 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 | |||
330 | static 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 | |||
340 | static 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 | |||
358 | static 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 | |||
370 | void 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 | |||
420 | int 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 | |||
436 | void 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 | |||
444 | void 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 | |||
462 | mpeg2_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 | |||
490 | int 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 | |||
528 | static 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 | |||
577 | static 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 | |||
606 | void 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 | |||
740 | static int copyright_ext (mpeg2dec_t * mpeg2dec) | ||
741 | { | ||
742 | (void)mpeg2dec; | ||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | static 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 | |||
763 | int 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 | |||
780 | int 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 | |||
788 | static 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 | |||
810 | mpeg2_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 | |||
860 | static 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 | |||
870 | mpeg2_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 */ | ||
40 | void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); | ||
41 | void (* 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 | */ | ||
50 | uint8_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) \ | ||
55 | do { \ | ||
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) \ | ||
61 | do { \ | ||
62 | int tmp = W0 * (d0 + d1); \ | ||
63 | t0 = tmp + (W1 - W0) * d1; \ | ||
64 | t1 = tmp - (W1 + W0) * d0; \ | ||
65 | } while (0) | ||
66 | #endif | ||
67 | |||
68 | static 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 | |||
121 | static 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 | |||
162 | static 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 | |||
189 | static 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 | |||
235 | void 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 | |||
32 | mpeg2_mc_t mpeg2_mc; | ||
33 | |||
34 | void 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) \ | ||
79 | static 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 | } \ | ||
103 | static 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 | |||
122 | MC_FUNC (put,o) | ||
123 | MC_FUNC (avg,o) | ||
124 | MC_FUNC (put,x) | ||
125 | MC_FUNC (avg,x) | ||
126 | MC_FUNC (put,y) | ||
127 | MC_FUNC (avg,y) | ||
128 | MC_FUNC (put,xy) | ||
129 | MC_FUNC (avg,xy) | ||
130 | |||
131 | MPEG2_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 | |||
44 | typedef 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 | |||
66 | typedef 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 | |||
87 | typedef 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 | |||
97 | typedef struct mpeg2_fbuf_s { | ||
98 | uint8_t * buf[3]; | ||
99 | void * id; | ||
100 | } mpeg2_fbuf_t; | ||
101 | |||
102 | typedef 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 | |||
116 | typedef struct mpeg2dec_s mpeg2dec_t; | ||
117 | typedef struct mpeg2_decoder_s mpeg2_decoder_t; | ||
118 | |||
119 | typedef 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 | |||
133 | typedef 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; | ||
140 | typedef enum { | ||
141 | MPEG2_CONVERT_SET = 0, | ||
142 | MPEG2_CONVERT_STRIDE = 1, | ||
143 | MPEG2_CONVERT_START = 2 | ||
144 | } mpeg2_convert_stage_t; | ||
145 | typedef 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); | ||
149 | int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg); | ||
150 | int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride); | ||
151 | void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id); | ||
152 | void 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 | |||
164 | uint32_t mpeg2_accel (uint32_t accel); | ||
165 | mpeg2dec_t * mpeg2_init (void); | ||
166 | const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec); | ||
167 | void mpeg2_close (mpeg2dec_t * mpeg2dec); | ||
168 | |||
169 | void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end); | ||
170 | int mpeg2_getpos (mpeg2dec_t * mpeg2dec); | ||
171 | mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec); | ||
172 | |||
173 | void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset); | ||
174 | void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip); | ||
175 | void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end); | ||
176 | |||
177 | void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2); | ||
178 | |||
179 | void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3], | ||
180 | uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]); | ||
181 | void mpeg2_slice (mpeg2_decoder_t * decoder, int code, const uint8_t * buffer); | ||
182 | |||
183 | typedef 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 | |||
191 | void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason); | ||
192 | void mpeg2_free (void * buf); | ||
193 | void 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 | |||
49 | typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int); | ||
50 | |||
51 | typedef 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 | |||
58 | typedef void motion_parser_t (mpeg2_decoder_t * decoder, | ||
59 | motion_t * motion, | ||
60 | mpeg2_mc_fct * const * table); | ||
61 | |||
62 | struct 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 | |||
149 | typedef struct { | ||
150 | mpeg2_fbuf_t fbuf; | ||
151 | } fbuf_alloc_t; | ||
152 | |||
153 | struct 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 | |||
219 | typedef 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 */ | ||
227 | uint32_t mpeg2_detect_accel (void); | ||
228 | |||
229 | /* cpu_state.c */ | ||
230 | void mpeg2_cpu_state_init (uint32_t accel); | ||
231 | |||
232 | /* decode.c */ | ||
233 | mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec); | ||
234 | mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec); | ||
235 | |||
236 | /* header.c */ | ||
237 | void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec); | ||
238 | void mpeg2_reset_info (mpeg2_info_t * info); | ||
239 | int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec); | ||
240 | int mpeg2_header_gop (mpeg2dec_t * mpeg2dec); | ||
241 | mpeg2_state_t mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec); | ||
242 | int mpeg2_header_picture (mpeg2dec_t * mpeg2dec); | ||
243 | int mpeg2_header_extension (mpeg2dec_t * mpeg2dec); | ||
244 | int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec); | ||
245 | void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec); | ||
246 | void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec); | ||
247 | void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels); | ||
248 | mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec); | ||
249 | mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec); | ||
250 | void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type); | ||
251 | |||
252 | /* idct.c */ | ||
253 | void mpeg2_idct_init (uint32_t accel); | ||
254 | |||
255 | /* idct_mmx.c */ | ||
256 | void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride); | ||
257 | void mpeg2_idct_add_mmxext (int last, int16_t * block, | ||
258 | uint8_t * dest, int stride); | ||
259 | void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride); | ||
260 | void mpeg2_idct_add_mmx (int last, int16_t * block, | ||
261 | uint8_t * dest, int stride); | ||
262 | void mpeg2_idct_mmx_init (void); | ||
263 | |||
264 | /* idct_altivec.c */ | ||
265 | void mpeg2_idct_copy_altivec (int16_t * block, uint8_t * dest, int stride); | ||
266 | void mpeg2_idct_add_altivec (int last, int16_t * block, | ||
267 | uint8_t * dest, int stride); | ||
268 | void mpeg2_idct_altivec_init (void); | ||
269 | |||
270 | /* idct_alpha.c */ | ||
271 | void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, int stride); | ||
272 | void mpeg2_idct_add_mvi (int last, int16_t * block, | ||
273 | uint8_t * dest, int stride); | ||
274 | void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, int stride); | ||
275 | void mpeg2_idct_add_alpha (int last, int16_t * block, | ||
276 | uint8_t * dest, int stride); | ||
277 | void mpeg2_idct_alpha_init (void); | ||
278 | |||
279 | /* motion_comp.c */ | ||
280 | void mpeg2_mc_init (uint32_t accel); | ||
281 | |||
282 | typedef 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 | |||
294 | extern mpeg2_mc_t mpeg2_mc_c; | ||
295 | extern mpeg2_mc_t mpeg2_mc_mmx; | ||
296 | extern mpeg2_mc_t mpeg2_mc_mmxext; | ||
297 | extern mpeg2_mc_t mpeg2_mc_3dnow; | ||
298 | extern mpeg2_mc_t mpeg2_mc_altivec; | ||
299 | extern mpeg2_mc_t mpeg2_mc_alpha; | ||
300 | extern 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 | |||
32 | PLUGIN_HEADER | ||
33 | |||
34 | #ifdef USE_IRAM | ||
35 | extern char iramcopy[]; | ||
36 | extern char iramstart[]; | ||
37 | extern char iramend[]; | ||
38 | extern char iedata[]; | ||
39 | extern char iend[]; | ||
40 | #endif | ||
41 | |||
42 | struct plugin_api* rb; | ||
43 | |||
44 | #define BUFFER_SIZE 25*1024*1024 | ||
45 | |||
46 | static mpeg2dec_t * mpeg2dec; | ||
47 | static vo_open_t * output_open = NULL; | ||
48 | static vo_instance_t * output; | ||
49 | static int total_offset = 0; | ||
50 | |||
51 | extern vo_open_t vo_rockbox_open; | ||
52 | |||
53 | static 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 | |||
143 | static 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 | |||
160 | enum 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 | |||
33 | extern mpeg2_mc_t mpeg2_mc; | ||
34 | extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); | ||
35 | extern void (* mpeg2_idct_add) (int last, int16_t * block, | ||
36 | uint8_t * dest, int stride); | ||
37 | extern void (* mpeg2_cpu_state_save) (cpu_state_t * state); | ||
38 | extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state); | ||
39 | |||
40 | #include "vlc.h" | ||
41 | |||
42 | static 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 | |||
135 | static 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 | |||
159 | static 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 | |||
213 | static 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 | |||
218 | static 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 | |||
234 | static 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 | |||
262 | static 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 | |||
299 | static 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) \ | ||
337 | do { \ | ||
338 | val <<= 4; \ | ||
339 | if (unlikely (val != (int16_t) val)) \ | ||
340 | val = (SBITS (val, 1) ^ 2047) << 4; \ | ||
341 | } while (0) | ||
342 | |||
343 | static 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 | |||
454 | static 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 | |||
564 | static 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 | |||
686 | static 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 | |||
803 | static 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 | |||
931 | static 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 | |||
960 | static 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 | |||
1257 | static 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 | \ | ||
1285 | static 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 | \ | ||
1307 | static 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 | \ | ||
1349 | static 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 | \ | ||
1384 | static 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 | \ | ||
1397 | static 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 | \ | ||
1409 | static 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 | \ | ||
1435 | static 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 | \ | ||
1478 | static 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 | |||
1505 | MOTION_FUNCTIONS (420, MOTION_420, MOTION_FIELD_420, MOTION_DMV_420, | ||
1506 | MOTION_ZERO_420) | ||
1507 | MOTION_FUNCTIONS (422, MOTION_422, MOTION_FIELD_422, MOTION_DMV_422, | ||
1508 | MOTION_ZERO_422) | ||
1509 | MOTION_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 */ | ||
1513 | static 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 | |||
1532 | static 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) \ | ||
1558 | do { \ | ||
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 \ | ||
1568 | do { \ | ||
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 | |||
1592 | void 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 | |||
1694 | static 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 | |||
1777 | void 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 | |||
24 | struct mpeg2_sequence_s; | ||
25 | struct mpeg2_convert_init_s; | ||
26 | typedef 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 | |||
33 | typedef struct vo_instance_s vo_instance_t; | ||
34 | struct 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 | |||
48 | typedef vo_instance_t * vo_open_t (void); | ||
49 | |||
50 | typedef struct { | ||
51 | char * name; | ||
52 | vo_open_t * open; | ||
53 | } vo_driver_t; | ||
54 | |||
55 | void vo_accel (uint32_t accel); | ||
56 | |||
57 | /* return NULL terminated array of all drivers */ | ||
58 | vo_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 | |||
28 | extern struct plugin_api* rb; | ||
29 | |||
30 | #include "mpeg2.h" | ||
31 | #include "video_out.h" | ||
32 | |||
33 | static int starttick; | ||
34 | |||
35 | #define CSUB_X 2 | ||
36 | #define CSUB_Y 2 | ||
37 | |||
38 | static int image_x; | ||
39 | static int image_y; | ||
40 | static int image_width; | ||
41 | static int image_height; | ||
42 | static int image_chroma_x; | ||
43 | static 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 */ | ||
59 | void 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 | |||
190 | static 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 | |||
227 | vo_instance_t static_instance; | ||
228 | |||
229 | static 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 | |||
253 | static 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 | |||
282 | vo_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) \ | ||
25 | do { \ | ||
26 | bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \ | ||
27 | bit_ptr += 2; \ | ||
28 | } while (0) | ||
29 | |||
30 | static 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) \ | ||
41 | do { \ | ||
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) \ | ||
50 | do { \ | ||
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 | |||
61 | typedef struct { | ||
62 | uint8_t modes; | ||
63 | uint8_t len; | ||
64 | } MBtab; | ||
65 | |||
66 | typedef struct { | ||
67 | uint8_t delta; | ||
68 | uint8_t len; | ||
69 | } MVtab; | ||
70 | |||
71 | typedef struct { | ||
72 | int8_t dmv; | ||
73 | uint8_t len; | ||
74 | } DMVtab; | ||
75 | |||
76 | typedef struct { | ||
77 | uint8_t cbp; | ||
78 | uint8_t len; | ||
79 | } CBPtab; | ||
80 | |||
81 | typedef struct { | ||
82 | uint8_t size; | ||
83 | uint8_t len; | ||
84 | } DCtab; | ||
85 | |||
86 | typedef struct { | ||
87 | uint8_t run; | ||
88 | uint8_t level; | ||
89 | uint8_t len; | ||
90 | } DCTtab; | ||
91 | |||
92 | typedef struct { | ||
93 | uint8_t mba; | ||
94 | uint8_t len; | ||
95 | } MBAtab; | ||
96 | |||
97 | |||
98 | #define INTRA MACROBLOCK_INTRA | ||
99 | #define QUANT MACROBLOCK_QUANT | ||
100 | |||
101 | static const MBtab MB_I [] = { | ||
102 | {INTRA|QUANT, 2}, {INTRA, 1} | ||
103 | }; | ||
104 | |||
105 | #define MC MACROBLOCK_MOTION_FORWARD | ||
106 | #define CODED MACROBLOCK_PATTERN | ||
107 | |||
108 | static 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 | |||
123 | static 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 | |||
153 | static const MVtab MV_4 [] = { | ||
154 | { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} | ||
155 | }; | ||
156 | |||
157 | static 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 | |||
167 | static const DMVtab DMV_2 [] = { | ||
168 | { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} | ||
169 | }; | ||
170 | |||
171 | |||
172 | static 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 | |||
203 | static 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 | |||
223 | static 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 | |||
230 | static 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 | |||
237 | static 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 | |||
245 | static 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 | |||
256 | static 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 | |||
271 | static 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 | |||
286 | static 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 | |||
291 | static 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 | |||
303 | static 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 | |||
313 | static 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 | |||
323 | static 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 | |||
328 | static 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 | |||
395 | static 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 | |||
402 | static 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 | |||
21 | wav,viewers/mp3_encoder, 00 00 00 00 00 00 | 21 | wav,viewers/mp3_encoder, 00 00 00 00 00 00 |
22 | wav,viewers/wavplay,60 7F 05 35 3F 00 | 22 | wav,viewers/wavplay,60 7F 05 35 3F 00 |
23 | bmp,rocks/rockpaint, 01 10 01 10 01 10 | 23 | bmp,rocks/rockpaint, 01 10 01 10 01 10 |
24 | 24 | m2v,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 */ | ||
417 | void 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. */ |
404 | void lcd_update_rect(int x, int y, int width, int height) | 635 | void 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); |
72 | extern void lcd_icon(int icon, bool enable); | 72 | extern void lcd_icon(int icon, bool enable); |
73 | 73 | ||
74 | #if CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO | ||
75 | void 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 */ |
76 | extern void lcd_blit(const fb_data* data, int x, int by, int width, | 82 | extern void lcd_blit(const fb_data* data, int x, int by, int width, |