summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/AUTHORS78
-rw-r--r--DOCS/ChangeLog479
-rw-r--r--DOCS/ChangeLog.mpeg232
-rw-r--r--DOCS/INSTALL29
-rw-r--r--DOCS/LIRC54
-rw-r--r--DOCS/MPlayer-FAQ120
-rw-r--r--DOCS/MTRR38
-rw-r--r--DOCS/OpenDivX30
-rw-r--r--DOCS/README271
-rw-r--r--DOCS/SOUNDCARDS21
-rw-r--r--DOCS/SPEED40
-rw-r--r--DOCS/TODO30
-rw-r--r--DOCS/inttypes.h13
-rw-r--r--DOCS/mplayer.1190
-rw-r--r--Makefile82
-rwxr-xr-xTOOLS/GL-test/compile.sh2
-rw-r--r--TOOLS/GL-test/gltest.c189
-rw-r--r--TOOLS/asfinfo.c255
-rwxr-xr-xTOOLS/c1
-rw-r--r--TOOLS/movinfo.c124
-rwxr-xr-xTVout/Mon-640x4003
-rwxr-xr-xTVout/Mon-640x4803
-rwxr-xr-xTVout/TV-640x5122
-rwxr-xr-xTVout/TV-640x5283
-rwxr-xr-xTVout/TV-704x5283
-rwxr-xr-xTVout/TV-704x5763
-rwxr-xr-xTVout/TV-720x5763
-rwxr-xr-xTVout/clean.sh13
-rwxr-xr-xTVout/cloning14
-rwxr-xr-xTVout/compile.sh15
-rw-r--r--TVout/con2fb/con2fb.c79
-rw-r--r--TVout/fbset.db34
-rw-r--r--TVout/fbset/INSTALL20
-rw-r--r--TVout/fbset/Makefile41
-rw-r--r--TVout/fbset/fb.h497
-rw-r--r--TVout/fbset/fb.modes.5228
-rw-r--r--TVout/fbset/fbset.8242
-rw-r--r--TVout/fbset/fbset.c1054
-rw-r--r--TVout/fbset/fbset.h82
-rwxr-xr-xTVout/fbset/modeline2fb150
-rw-r--r--TVout/fbset/modes.l136
-rw-r--r--TVout/fbset/modes.y175
-rwxr-xr-xTVout/independ16
-rw-r--r--TVout/matroxset/Makefile10
-rw-r--r--TVout/matroxset/fb.h502
-rw-r--r--TVout/matroxset/matroxfb.h32
-rw-r--r--TVout/matroxset/matroxset.c162
-rwxr-xr-xTVout/matroxset/normal12
-rwxr-xr-xTVout/matroxset/swapit5
-rwxr-xr-xTVout/matroxset/swapped12
-rwxr-xr-xTVout/modules8
-rw-r--r--alaw.c29
-rw-r--r--asfheader.c183
-rw-r--r--aviheader.c89
-rw-r--r--aviparse.c336
-rw-r--r--aviprint.c88
-rw-r--r--aviwrite.c161
-rw-r--r--codecctrl.c198
-rw-r--r--codecs.c150
-rw-r--r--config.h70
-rw-r--r--config.mak14
-rwxr-xr-xconfigure783
-rw-r--r--demux_asf.c268
-rw-r--r--demux_avi.c276
-rw-r--r--demux_mpg.c228
-rw-r--r--demuxer.c285
-rw-r--r--dll_init.c164
-rw-r--r--drivers/3dfx.h154
-rw-r--r--drivers/Makefile22
-rw-r--r--drivers/README40
-rw-r--r--drivers/mga_vid.c877
-rw-r--r--drivers/mga_vid.h48
-rw-r--r--drivers/mga_vid_test.c221
-rw-r--r--drivers/sis_vid.c645
-rw-r--r--drivers/sis_vid.h37
-rw-r--r--help_avp.h32
-rw-r--r--help_mp.h44
-rw-r--r--liba52/srfftp.h303
-rw-r--r--libmpeg2/Makefile35
-rw-r--r--libmpeg2/attributes.h31
-rw-r--r--libmpeg2/decode.c319
-rw-r--r--libmpeg2/header.c273
-rw-r--r--libmpeg2/idct.c289
-rw-r--r--libmpeg2/idct_mlib.c47
-rw-r--r--libmpeg2/idct_mmx.c706
-rw-r--r--libmpeg2/mm_accel.h30
-rw-r--r--libmpeg2/mmx.h255
-rw-r--r--libmpeg2/motion_comp.c125
-rw-r--r--libmpeg2/motion_comp_mlib.c180
-rw-r--r--libmpeg2/motion_comp_mmx.c1025
-rw-r--r--libmpeg2/mpeg2.h57
-rw-r--r--libmpeg2/mpeg2_internal.h220
-rw-r--r--libmpeg2/slice.c1797
-rw-r--r--libmpeg2/sse.h256
-rw-r--r--libmpeg2/stats.c316
-rw-r--r--libmpeg2/vlc.h425
-rw-r--r--libvo/Attic/SHIT/video_out_gl.c.V3-sux538
-rw-r--r--libvo/Attic/SHIT/video_out_gl.c.diff64
-rw-r--r--libvo/Attic/SHIT/video_out_odivx.c.OLD183
-rw-r--r--libvo/Attic/SHIT/video_out_sdl.c-1.1.4574
-rw-r--r--libvo/Attic/SHIT/video_out_x11.c.OLD518
-rw-r--r--libvo/Attic/SHIT/video_out_x11.c.thread466
-rw-r--r--libvo/Makefile37
-rw-r--r--libvo/config.mak6
-rw-r--r--libvo/mga_common.c220
-rw-r--r--libvo/mmx.h706
-rw-r--r--libvo/rgb15to16mmx.c42
-rw-r--r--libvo/video_out.c201
-rw-r--r--libvo/video_out.h195
-rw-r--r--libvo/video_out_internal.h43
-rw-r--r--libvo/vo_3dfx.c478
-rw-r--r--libvo/vo_gl.c515
-rw-r--r--libvo/vo_md5.c106
-rw-r--r--libvo/vo_mga.c127
-rw-r--r--libvo/vo_null.c85
-rw-r--r--libvo/vo_odivx.c234
-rw-r--r--libvo/vo_pgm.c115
-rw-r--r--libvo/vo_sdl.c607
-rw-r--r--libvo/vo_syncfb.c446
-rw-r--r--libvo/vo_syncfb.c.OLD434
-rw-r--r--libvo/vo_x11.c476
-rw-r--r--libvo/vo_xmga.c319
-rw-r--r--libvo/vo_xv.c457
-rw-r--r--libvo/wskeys.h103
-rw-r--r--libvo/yuv2rgb.c414
-rw-r--r--libvo/yuv2rgb.h43
-rw-r--r--libvo/yuv2rgb_mlib.c87
-rw-r--r--libvo/yuv2rgb_mmx.c419
-rw-r--r--linux/getch2.c215
-rw-r--r--linux/getch2.h20
-rw-r--r--linux/keycodes.h36
-rw-r--r--linux/shmem.c83
-rw-r--r--linux/shmem.h4
-rw-r--r--linux/timer-lx.c49
-rw-r--r--linux/timer.h6
-rw-r--r--lirc_mp.c143
-rw-r--r--lirc_mp.h23
-rw-r--r--loader/Makefile30
-rw-r--r--loader/afl.c763
-rw-r--r--loader/com.h66
-rw-r--r--loader/config.h74
-rw-r--r--loader/driver.c223
-rw-r--r--loader/elfdll.c305
-rw-r--r--loader/ext.c565
-rw-r--r--loader/loader.h286
-rw-r--r--loader/module.c618
-rw-r--r--loader/pe_image.c936
-rw-r--r--loader/pe_resource.c391
-rw-r--r--loader/registry.c421
-rw-r--r--loader/registry.h24
-rw-r--r--loader/resource.c478
-rw-r--r--loader/stubs.s36
-rw-r--r--loader/vfl.c330
-rw-r--r--loader/win32.c1706
-rw-r--r--loader/win32.h1
-rw-r--r--loader/wine/avifmt.h246
-rw-r--r--loader/wine/basetsd.h145
-rw-r--r--loader/wine/config.h442
-rw-r--r--loader/wine/debugtools.h93
-rw-r--r--loader/wine/driver.h112
-rw-r--r--loader/wine/elfdll.h14
-rw-r--r--loader/wine/heap.h56
-rw-r--r--loader/wine/ldt.h98
-rw-r--r--loader/wine/mmreg.h104
-rw-r--r--loader/wine/module.h198
-rw-r--r--loader/wine/msacm.h942
-rw-r--r--loader/wine/msacmdrv.h203
-rw-r--r--loader/wine/ntdef.h101
-rw-r--r--loader/wine/pe_image.h81
-rw-r--r--loader/wine/poppack.h15
-rw-r--r--loader/wine/pshpack1.h13
-rw-r--r--loader/wine/pshpack2.h12
-rw-r--r--loader/wine/pshpack4.h15
-rw-r--r--loader/wine/pshpack8.h12
-rw-r--r--loader/wine/vfw.h654
-rw-r--r--loader/wine/winbase.h1791
-rw-r--r--loader/wine/windef.h656
-rw-r--r--loader/wine/windows.h38
-rw-r--r--loader/wine/winerror.h1658
-rw-r--r--loader/wine/winestring.h13
-rw-r--r--loader/wine/winnt.h2665
-rw-r--r--loader/wine/winreg.h57
-rw-r--r--loader/wine/winuser.h2929
-rw-r--r--loader/wineacm.h55
-rw-r--r--mp3lib/Makefile34
-rw-r--r--mp3lib/config.mak6
-rw-r--r--mp3lib/d_cpu.h17
-rw-r--r--mp3lib/d_cpu.s94
-rw-r--r--mp3lib/dct12.c139
-rw-r--r--mp3lib/dct36.c264
-rw-r--r--mp3lib/dct36_3dnow.s499
-rw-r--r--mp3lib/dct64.c313
-rw-r--r--mp3lib/dct64_3dnow.s706
-rw-r--r--mp3lib/dct64_i386.c314
-rw-r--r--mp3lib/decod386.c194
-rw-r--r--mp3lib/decode_3dnow.s265
-rw-r--r--mp3lib/decode_i586.s321
-rw-r--r--mp3lib/equalizer.c79
-rw-r--r--mp3lib/huffman.h332
-rw-r--r--mp3lib/l2tables.h154
-rw-r--r--mp3lib/layer2.c295
-rw-r--r--mp3lib/layer3.c1703
-rw-r--r--mp3lib/mp3.h31
-rw-r--r--mp3lib/mpg123.h125
-rw-r--r--mp3lib/sr1.c489
-rw-r--r--mp3lib/tabinit.c89
-rw-r--r--mplayer.c1957
-rw-r--r--parse_es.c106
-rw-r--r--stream.c203
-rw-r--r--tvision.c152
-rw-r--r--vcd_read.h122
-rw-r--r--version.h1
-rw-r--r--videodev.h283
-rw-r--r--xa/xa_gsm.c988
-rw-r--r--xa/xa_gsm.h6
-rw-r--r--xa/xa_gsm_int.h114
216 files changed, 58871 insertions, 0 deletions
diff --git a/DOCS/AUTHORS b/DOCS/AUTHORS
new file mode 100644
index 0000000000..d1ae5a9737
--- /dev/null
+++ b/DOCS/AUTHORS
@@ -0,0 +1,78 @@
+ AUTHORS:
+ ~~~~~~~~
+
+====================== The MPlayer project: ===========================
+
+Arpád Gereöffy (A'rpi/ESP-team): <arpi@thot.banki.hu>
+- player code (mpeg stream demultiplexer and avi/asf parser, A-V sync, seek...)
+- mp3lib, based on mpg123 sources [MP3 audio decoder]
+- getch2 [keyboard handler]
+- some changes in libmpeg2 code (progressive frames, bitrate & fps support)
+- libvo improvements: adding OpenGL support, bugfix in mga driver...
+- YUY2 support into mga_vid driver (for DivX/MPEG4)
+- YUY2, RGB/BGR 15/16/24/32 support into libvo drivers (for AVI codecs)
+- scripts in the TVout directory (allows using TVout on Matrox G400 DH on fb)
+- hacking DivX/Mpeg4 VfW codecs to get YUV output
+- opendivx decoder speed optimizations (see opendivx/ChangeLog)
+
+Zoltán Ponekker (Pontscho/Fresh!): <pontscho@makacs.poliod.hu>
+- configure script and Makefiles for easy compile
+- GUI system (coming soon!)
+- 3DNow! support into mp3lib
+- various X11 driver changes (keyboard handling, fullscreen, bpp detect, etc)
+- libvo: adding xmga driver (similar to Xv but works under X3.3.x)
+
+Gábor Lénárt (LGB): <lgb@supervisor.hu>
+- testing and some improvements in mpeg player's user interface (options)
+- ./configure script improvements
+
+Gabucino: <gabucino@k2.jozsef.kando.hu>
+- web design, docs improvements/updating
+- testing, (Open)DivX encoding, picture quality comparsions
+
+Dariusz Pietrzak: <dariush@ajax.umcs.lublin.pl>
+- mailing lists hosting (see README for details)
+
+Main testers:
+ Gabucino
+ Balazs Tibor (Tibcu)
+ Sasi Peter (SaPe)
+ Christoph H. Lampert
+
+========================== The Codecs: ===================================
+
+Aaron Holtzman: <aholtzma@engr.uvic.ca>
+- ac3dec (and libac3) author [AC3 audio decoder]
+- mga_vid driver [Matrox G200/G400 YUV Back-end Scaler]
+- mpeg2dec [Fast MPEG1/MPEG2 video decoder, currently used in player]
+
+Michel Lespinasse: <walken@zoy.org>
+- did large libmpeg2 changes for better speed and mpeg conformance
+
+Eugene Kuznetsov: <divx@euro.ru>
+- avifile author [AVI player library for linux, using Win32 VfW/ACM codecs]
+- technical help about AVI and ASF formats, and how to get YUV using VfW...
+
+Project Mayo: [http://www.projectmayo.com]
+- the OpenDivX codec authors
+
+Michael Hipp:
+- mpg123 author [free mpeg audio player, isn't used directly but in mp3lib]
+
+Mark Podlipec:
+- xanim author [i'm using its aLaw audio decoder]
+
+Jutta Degener and Carsten Bormann:
+- xa_gsm.c authors [MS-GSM audio codec]
+
+Their code is not used in current player version, but I've got some ideas or
+other technical help from:
+
+John F. McGowan http://www.jmcgowan.com/
+- AVI FAQ author/collector. [site with many useful docs on codecs and avi fmt]
+
+Dirk Farin: <farin@ti.uni-mannheim.de>
+- dvdview author [MPEG1/MPEG2 video decoder, used in v0.5-v0.8]
+
+Adam Williams: <broadcast@earthling.net>
+- libmpeg3 (and xmovie) author [MPEG1/MPEG2 video decoder, used in v0.1-v0.4]
diff --git a/DOCS/ChangeLog b/DOCS/ChangeLog
new file mode 100644
index 0000000000..3daeaea322
--- /dev/null
+++ b/DOCS/ChangeLog
@@ -0,0 +1,479 @@
+ChangeLog:
+~~~~~~~~~~
+
+v0.12-pre1: [ not yet released ]
+ - ffmpeg included into source tree
+
+===========================================================================
+Note: If you've sent patches not applied in pre22, please send them again!
+/|\ (I've got tons of mails last weeks, and can't re-read all of them)
+/~\ Please include in the Subject: MPLAYER-PATCH
+===========================================================================
+
+*** 0.11 release is coming SOON!!! ***
+
+v0.11-pre25: small fixes again :(
+ - DOCS updated (email address changed from arpi@* -> maillist)
+ - LIRC fix, mplayer_lirc changed back to mplayer [Andreas Ackermann]
+ - stream.c: unsigned int fixes, required for some strange .asf files
+ - asfheader.c: using w=h=b=1 for audio_concealment_none
+ - VCD-related stuff moved from stream.c to vcd_read.c
+
+v0.11-pre24: small fixes again :(
+ - DOCS/LIRC changed: users *must* enable lirc support manually, it is
+ not autodetected yet. (./configure --enable-lirc)
+ - the {prefix} bug fixed by Gabucino
+ - added manpage by Gabucino
+ - manpage -vo fixes by A'rpi
+
+v0.11-pre23: lirc support, text updates, mailinglists
+ - added "-ni" option to force usage of the non-interleaved AVI parser
+ - DOCS/* updated by Gabucino
+ - new homepage by Gabucino
+ - mplayer users & announce mailing lists by Dariusz Pietrzak (see README)
+ - LIRC support by Andreas Ackermann (see DOCS/LIRC)
+ enable with ./configure --enable-lirc
+ TODO: ./configure should detect LIRC installed and better Makefile handling
+ - added AVI_NINI parser for broken (no index) non-interleaved files
+
+v0.11-pre22: last fixes, release is coming soon!
+ - non-interleaved avi EOF bug fixed [thanks to DC-1 for help]
+ - "You" strings in Makefile after make dep bug fixed... [thx to DC-1]
+ - SDL disabled by default. You have to ./configure --enable-sdl to enable.
+ - homepage updated by Gabucino
+ - homepage updated by A'rpi
+ - FAQ updated by A'rpi
+
+fork() -> 0.12pre1
+
+v0.11-pre21: mpeg1 pp, stereo fix
+ - "Skip chunk xxxx" messages moved from -v to -v -v -v debug level...
+ [thanks to Christoph H. Lampert]
+ - divx postprocess filter works for mpeg1 files too! (-divxq 1/3/7/31)
+ - mpeg layer-2 audio fixed - it's stereo again!!!
+ - audio select() detection: if detected audio buffer size == 0, then
+ exit with message "recompile mplayer with #undef HAVE_AUDIO_SELECT"...
+ - syncfb driver added to the source tree, under drivers/
+ (it's very similar to mga_vid, but has syncronization to screen and
+ de-interlace features)
+ - draw_slice in syncfb finished for G400 cards (plays mpeg 1/2, opendivx)
+ (de-interlacing has been disabled, because it's buggy now)
+
+v0.11-pre20: NI-AVI support, small fixes & patches...
+ - asf parser: flag 0x40 (explicit packet size) implemented [Marvin]
+ - new option to select DSP device: -dsp (default: /dev/dsp) [Pontscho]
+ - option -o changed to -vo
+ - ./configure: applied patches [LGB,Ian Kumlien,Magnus Pfeffer]
+ - avi chunk_id->ds mapper moved to demux_avi_select_stream()
+ - added non-interleaved .AVI parser
+ - added non-interleaved .AVI detection (if a_pos-v_pos distance > 1MB)
+
+v0.11-pre19: small fixes...
+ - vo_xmga.c: G200 draw_slice fixed
+ xmga + mga: common part (draw_frame & draw_slice) moved to mga_common.c
+ - some independent code (asfinfo.c and GL-test) moved to the new TOOLS subdir
+ - movinfo.c added to TOOLS (small util to dump .mov file structure)
+ - AVI & ASF stream id detection changed: now using IDs from the header
+ (but still can be overriden by -aid or -vid) [Christoph H. Lampert]
+ - native MS-GSM audio codec ported from avifile source (-afm 6)
+ [thanks for the testfile to Christoph H. Lampert]
+ - README updated (input & codec lists)
+ - implemented .asf audio descrambling [Dirk Vornheder & Einon]
+ -> that weird_al_yankovic asf is not so weird now :)
+ - AUTHORS file changed
+
+v0.11-pre18: patch release :)
+ - skip broken .asf fragments (for better seeking)
+ - seeking code cleanup in sources (now it's in a switch(){})
+ - opendivx encoding bitrate option changed from -divxq to -br
+ (for the divx -> divx re-encoding)
+ - TO DO section moved to file TODO
+ - applied ./configure and Makefile changes patch from LGB
+ - libvo function changes by Pontscho: x11 (with -fs), xmga (bugfixed!)
+ - libvo: driver sources renamed from video_out_*.c -> vo_*.c
+ - libvo: added uninit() function to drivers
+ - libvo: fork()'ed X11 eventhandler for x11 and xmga drivers [me & Pontscho]
+ (gl and xv version is coming soon!)
+ - libvo: sdl driver now closes SDL at QUIT...
+ - small english fixes (docs & messages) [Balazs Tibor]
+
+v0.11-pre17: fixes
+ - asf "missing video stream" fixed (stream id & 0x7F) [Christoph H. Lampert]
+ - added GL-test directory, it contains source and compiler script of a
+ very simple open-gl texture updating (glTexSubImage) test program.
+ if it runs well, then mplayer -o gl should work too.
+ it works on G400+Utah-GLX, but segfaults in the G400 driver of X 4.0.2/DRI.
+ try it with different cards/drivers, and please report me the results.
+ - benchmarking in gltest.c: calculate fps and process times
+ - .asf seeking v0.01-pre0.1 :)
+
+v0.11-pre16: ACM fixed
+ - Win32/ACM audio codec fixed (most important for asf with divx audio):
+ There was an output buffer size problem with the Win32/ACM audio codec
+ at low bitrates (usually used for .asf files with divx audio)
+ Input and output buffer sizes are now queryed, problem solved :)
+ - SDL support compiling hint by Michael Durller added to the FAQ
+ - opendivx support in .asf files [Gérard Lantau]
+ - ./configure & Makefiles patch by Aaron Hope applied.
+ (adds --with-win32libdir and fixes --with-x11libdir)
+ - ./configure fixed, now it defaults to /usr/lib/win32 if detection failed
+
+v0.11-pre15: asf sync fixed
+ - asf parser: now supports other than 0x5D segments [Dirk Vornheder]
+ - new asf PTS reading: sync works now, including fps...
+ (-fps no longer required!) [thanks again to Eugene Kuznetsov for docs!]
+
+v0.11-pre14: small fixes, asf sync v0.1 :)
+ - version number incremented :)))
+ - libvo / Xv driver swapped Red-Blue fixed
+ - asf timestamps implemented - now asf A-V should be in sync if you
+ specify the correct fps at commandline (-fps), +-1 fps allowed...
+ [i haven't yet found method to get fps out from asf headers :(((]
+ - some error and consistency checking into demux_asf
+ if you see many warning! messages playing an .asf file, then contact
+ me and upload the file (first 1MB is enough if it represents the problem)
+ Don't forget: there is no public doc about the .asf file format, so
+ everything we know is suspected and can be wrong... without your help
+ we never will have working .asf player...
+ - asf fragment offset checks disabled for grouping...
+
+v0.11-pre13: libvo changes, mpeg bitrate, vcd fix, asf grouping
+ - libvo: draw_slice() interface changed, now it has src stride[3] and
+ destination rect dimension (w,h,x,y)
+ It's able to blit whole frames, not only 16-pixel slices...
+ - libmpeg2 and opendivx codec changed to use new draw_slice()
+ -> opendivx extra 64-pixel width band at right disappeared!
+ - mpeg bitrate fix: if picture->bitrate==0x3FFFF (means "unspecified" ?)
+ then using standard VCD bitrate (75*2324 bytes/sec)
+ -> fixed seeking for those mpegs with "16MBit/s" bitrate...
+ - drivers/sis_vid: video4linux interface disabled
+ - broken VCD playing fixed: stream_reset shouldn't seek to 0x0...
+ [bugreport: Kang Sun]
+ - asf_parser: grouping implemented! [test file provided by Gabucino :))]
+
+v0.11-pre12: ./configure fixes, improved odivx-encoding, streaming fixes
+ - ./configure: using /tmp/main$$.c instead /tmp.main.c, and
+ remove file after tests [SaPe]
+ - ./configure: trying the gcc optimize options and fallback to 'pentium'
+ if fails (useful for people with old gcc and new cpu :))
+ - removed -fomit-frame-pointer from OPTFLAGS at config.mak
+ - version number incremented [Gabucino]
+ - odivx encoder fix: allow long (longer than xxxx.avi) destination filenames
+ (sizeof() changed to strlen()...) [Gabucino]
+ - avi writer - overwrite disabled (exits with error message if destination
+ file already exists...) [Gabucino]
+ - use -divxq to set encoding bitrate (in bits (no kbits!) default: 780000)
+ - no audio decoding if -encode option is used
+ - audio streaming disabled if -nosound specified (setting audio_id to -2)
+ - fast Mpeg-ES detection (doesn't read the whole Mpeg-PS file)
+ - compile-time option to disable using soundcard driver's select()
+ (requires for some people with buggy/pre-alpha/etc sound driver...)
+
+v0.11-pre11: streaming fixes, asf support pre, indeo5 fix
+ - asf/asfinfo.c improved: now it dumps streams to files - need testing!
+ (it's ready to be converted to asf demuxer and intergated into MPlayer)
+ - stream.c / stream_reset() fix: now it really seek back to 0 position!
+ - .asf file format detection added (no .asf reading yet!!!)
+ - .asf demultiplexer added, changes in demuxer.c to handle fragmented packets
+ > it plays .asf video well, but still has problems with divx/wma audio. :(((
+ - indeo 5 playing fixed (removed ICDECOMPRESS_UPDATE from flags)
+ - xmga resizing problems with some window managers, so default order is
+ changed xmga,xma... to mga,xmga,...
+ - found gcc bug: compiling MPlayer with flags
+ OPTFLAGS=-O -g -march=i686 -mcpu=i686 -pipe -fomit-frame-pointer -ffast-math
+ cause image sizes negating -> mga_vid kernel driver Oops... :(((
+ - runaway.bride.sample.avi seeking segfault discovered: AC3 resync fails :(
+ - improved signal handling: module name is now printed. audio_resync added.
+ - RGB opendivx encoding implemented, now AVI->opendivx is possible.
+
+v0.11-pre10: OpenDivX encoding, streaming fixes, avi seek fixes
+ - new libvo driver: odivx (OpenDivX File Writer)
+ - AVI file writting support, new option: -encode filename
+ to encode an mpeg/vob/vcd to opendivx:
+ mplayer file1.mpg -encode file2.avi -o odivx -nosound
+ (sound encoding/copy is not yet supported)
+ - libvo: default driver priority changed to: xmga,mga,syncfb,3dfx,xv,x11,gl
+ - avi writer: index support
+ - small fixes in avi writer to be compliant (adjusted chunk/list lengths)
+ - demuxer.c: stream buffering fixes:
+ - missing {} in mplayer.c occuring audio reads when has_audio=0
+ - reordered packet reader and pack count checks -> no more unwanted EOF
+ - added 4MB buffer memory usage limit to demuxed streams
+ - CPU flags in ./configure changed:
+ k7 -> k6 (current stable gcc doesn't supports k7)
+ 386,486 -> i386,i486 [Balazs Tibor]
+ - demux_avi: index check now accepts (raw.len+1)==idx.len [Balazs Tibor]
+ - FAQ added
+
+ ** Now we are ready with planned features & urgent fixes, **
+ ** it's time to final testing and then the 0.11 release!! **
+
+v0.11-pre9: OpenDivX fixes,speedup
+ - solved OpenDivX width problem (stride=width+(Quality?0:64))
+ now -divxq 0 works, and 0 is the default
+ - libvo call moved out from my_convert_yuv() so it can be measured (cpu %)
+ - IDCT code ported from libmpeg2 -> much faster OpenDivX decoding
+
+v0.11-pre8: SDL fixes, OpenDivX support
+ - added -I/usr/X11R6/include to libvo CFLAGS
+ - (removed later: applied libvo SDL driver fixes by Jeffrey Boser)
+ - OpenDivX support, initial hack, maybe not work for you...
+ (I need testfiles, I have just only one)
+ use -divxq option to adjust quality (1..29 works), 1=default
+
+v0.11-pre7: SDL support
+ - ported SDL driver from mpeg2dec/libvo (currect CVS)
+ (it's slower than internal X11 driver, but supports software scaling!)
+ - fixed SDL driver to support -fs and pass keyboard events
+ - SDL driver changed to support YV12 and YUY2 formats instead of IYUV
+ (now works with DivX files too)
+ - 'q' (Quit) disabled in SDL fullscreen mode (because it's impossible
+ to restore screen before exiting so it gets unusable state now)
+
+v0.11-pre6: audio fix
+ - fixed video_out_xv.c compiling problems [bugreport: Kalle Mellerup]
+ - modified audio playing: always keep buffer (both internal and card's)
+ filled using select() -> -alsa audio delays should be fixed.
+ - updated DOCS/AUTHORS and DOCS/README
+
+v0.11-pre5: xmmp audio support, applied Pontscho's libvo patch
+ - xmmp audio driver support by Arthur Kleer
+ - new video_out driver by Pontscho: xmga (Matrox G200/G400 only!)
+ It does same under X 3.3.x what Xv extension does under X 4.0.x!
+ (you will have a moveable/resizeable window but see an YUV video
+ overlay in it using color keying)
+ - added keyboard event support in X11 windows [Pontscho]
+ (using mplayer_[put|get]_key() in codecctrl.c)
+
+v0.11-pre4: x11 driver fixes, 15/16bpp support
+ - version in version.h fixed :))) [Pontscho]
+ - inttypes.h moved to DOCS/ (copy back to the root if you need it)
+ - depth calculation in vo_init() changed (Pontscho's version couldn't
+ make difference between 15 and 16bpp)
+ - x11 driver now uses vo_init() instead of get_depth()
+ - yuv2mmx: 15bpp not really supported -> removed from list, now
+ conversion is done (well) by the C code -> MPEG play in 15bpp works!
+ - avi playing support added in 15bpp (memcpy)
+ - avi playing support added in 16bpp (C 15->16 converter by me)
+ - avi playing support added in 16bpp (MMX 15->16 converter by Strepto)
+ - libvo/x11: yuv2rgb used MMX code on non-MMX CPUs too!!! fixed...
+ - all x11 modes tested (and mpeg/24bpp byteorder fixed):
+ MPEG: AVI/VfW:
+ 15bpp C convert memcpy
+ 16bpp MMX/C convert MMX/C convert
+ 24bpp C convert memcpy
+ 32bpp MMX/C convert memcpy / C conv.
+ => now all the movie types are viewable using the -o x11 driver!
+
+v0.11-pre3: mpeg fixes, fullscreen support
+ - vertical.mpg serious libvo (x11,gl) segfaults fixed:
+ yuv2rgb_mmx requires one more lines that vertical image size...
+ fixed (allocating memory for width*(height+1)). [bugreport: Gabucino]
+ - Pontscho's fullscreen patch applied!
+ Using option -fs will maximize window size (for all resizeable drivers
+ including mga!) and disable window decorations (x11,Xv,gl only)
+ - simple inttypes.h included for libc5 (and glibc2.0 too?) users
+ - homepage updates (links changed ftp->http)
+
+v0.11-pre2: better user messages, mp3 codec selection, demuxer changes
+ - w32codec.zip restored at the FTP site (somehow it damaged...)
+ - added version.h, and used its content everywhere
+ - 'premature end-of-file' problem fixed: freeing audio buffers and
+ setting d_audio->id=-2 if has_audio==0 [bugreport by Dmitri Pogosyan]
+ - some more messages added if verbose>=1
+ - demuxer.c: error message printed if A or V chunk buffer is full
+ 'mplayer test.avi -aid -2' still not works without option '-nosound'
+ - adding new config.h option to set default MP3 audio codec (mpg123/l3codeca)
+ ./configure selects mp3lib only if you have 3Dnow [idea: Gabucino]
+ - automatic fallback to mp3lib/mpg123 if l3codeca.acm can't be loaded/inited
+
+v0.11-pre1: AVI sync fixes
+ - AVI audio seeking improvements: now using nBlockAlign value to seek
+ inside the chunk, so divx audio works without big delays!!!
+ - AVI PTS calculation modified: counting video PTS when skip_video_frames>0
+ so new audio PTS values will be correct. Solved many sync probs!
+ - A-V sync with AVI files fixed!
+ Now only the Desperado-trailer has 1.0 sec delay after seeking.
+ - fixed AVI sync in -bps mode too! :) (perfect except that Desperado avi)
+
+v0.10: The new year release!
+ - testing
+ - docs changed
+ - it's time to release and remove the old buggy 0.09 version...
+ - release!!!
+
+v0.10-pre8: libvo/x11 changes
+ - libvo: x11/xv driver separated to x11 and xv drivers
+ - libvo: DUMMY_VO_FUNC removed from driver sources
+ - libvo: default driver order changed, because some users with software-only
+ opengl though that this 'slow' player can only play at 1-3fps :)
+
+v0.10-pre7: libmpeg2 interface changes, display size/area changes, AVI fixes
+ - libmpeg2/decode.c modified:
+ - removed unused OMS and mpeg2dec stuff
+ - decode_data rewritten, now works like parse_es.c
+ => doesn't copy any data -> faster and less memory usage
+ - mplayer.c sends code 0x1FF after every frame, so libmpeg2 knows
+ when has to display it
+ - mplayer.c: in_frame flag fixes, didn't work well with mpeg2 streams
+ (because there is a 0x1B2 chunk between 0x100 and 0x101)
+ - 'picture' changed from static to shmem-allocated
+ -> better picture after codec restart (tested with JapAd.mpg)
+ -> keep information of the header changes (after init)
+ - mpeg image size changed, now only the real part of frame is displayed
+ (no more green strip at the bottom)
+ - picture struct: new fields: display_picture_width/height
+ - image buffer allocation (shmem) is done by decode.c instead of libvo
+ - new option: -xy <value> (resize both x/y direction)
+ if value<=8 -> x_scale = y_scale = value
+ else -> x_size=value y_size=aspectratio*x_size
+ - mplayer.c: video output moved out from avi/mpg init sections and
+ now it's common code (added movie_size_x/y variables and out_fmt global)
+ - new keys:
+ ESC => quit
+ + and - => adjust audio delay +- 0.1 second
+ k => kill/restart the mpeg codec process (for testing)
+ - codec control interface changed: wait for syncword after (re)start
+ to avoid receiving old frames => it's stable again!
+ - removed (now unused) allocate/free image buffer code from libvo
+ - mplayer: new internal variable for video format: has_video
+ 0 = none (unused yet)
+ 1 = mpeg 1/2 video
+ 2 = win32/VfW video codec
+ - config.h has defaults for bps-based AVI sync and ALSA timer code options:
+ #undef AVI_SYNC_BPS => now it's disabled by default!!! use -bps to enable
+ #define ALSA_TIMER => now it's enabled by default!!! use -noalsa to dis.
+ - help updated
+ - prints max compressed framesize at exit (both avi & mpeg)
+ - AVI audio seeking fixed: some ACM codecs (divx audio and ms-adpcm)
+ can't seek inside a chunk, they are only able to play whole chunks.
+ Current audio seeking has changed to seek inside the chunk only if the
+ codec supports it (only internal codecs and ACM/mp3 allows it).
+ - AVI: audio delay correction if can't seek inside the chunk
+
+v0.10-pre6: mpeg signal & EOF fixes
+ - ./configure: k6_mtrr (2.4.test11+) added [Pontscho]
+ - `term destroys if mplayer (mpg) called from mc.ext` bug fixed:
+ added sighandler to the 3rd process (mpeg codec) to avoid sig. recursion
+ - better output at exit (handled now by exit_player())
+ - mpeg EOF problem (codec restart) fixed: added EOF detection to parse_es.c
+ - internal flag 'current_module' added to get more info at segfaults
+ (contains module number where the segfault occured)
+ - audio detection changed: using afm=4 (Win32/ACM) for MP3 audio (AVI files)
+ (you MUST have l3codeca.acm at /usr/lib/win32, or you have to use '-afm 1')
+
+v0.10-pre5: flipping fixed
+ - AVI image flipping reworked:
+ - new flag: avi_header.flipped, TRUE if upside-down
+ - image flipping code removed/disabled from libvo modules
+ - duplicate flip_page() calls removed (overload with x11 and mga)
+ - aLaw audio codec (AVI id 0x06) added (uses code from xanim source)
+
+v0.10-pre4: test release, small fixes
+ - video_out driver <-> codec incompatibility message changed
+ - fixed the config.format bug in drivers/mga_vid_test, so it works again!
+ [thanks to David Whysong]
+ - libmpeg2 upgraded
+
+v0.10-pre3: test release, verbose mode, new docs
+ - new option: -v = increment verbose level
+ (debug printf's changed to verbose level-dependent)
+ - default level: 0, only some informal output
+ - init debug: 1, some basic debug infos, avi header, function values
+ - player debug: 2, print avi indexes, chunk inputs, more debug infos
+ - parser debug: 3, prints everything related to input parsers
+ to increment verbose level, use multiple -v options (-v -v -v for level-3)
+ - bitrate calculation for AVI files
+ - README rewritten, added Troubleshooting and Bugreports sections
+ - TVout directory added (only the scripts)
+
+v0.10-pre2: bugfix test release, bps-sync enabled
+ - avi: supporting both 0-based and movi-based index types (autodetect)
+ - avi: tested with VBR audio: plays well with -mc 0 option, seek doesn't
+ work yet [thanks to Alan Chen for testfile]
+ - avi: A-V sync to avg. byte/sec implemented (again) and enabled by default
+ (disable with -nobps if you want)
+ - ./configire: 3rd name ('kni') of the P3 added. Where is the compatibility?
+ - useless '\' removed from libac3/Makefile [Otvos Ferenc]
+
+v0.10-pre1: test release, players merged!!!
+ - avip and mpegp has been merged to a single binary called 'mplayer'
+ - file type detection (AVI/MPEG-PS/MPEG-ES/Other)
+ - no redundant code (common code for common jobs)
+ - big format-dependent codes moved to functions (separated files)
+ - better error messages, removed some debug stuff, code cleanups
+ - old libmpeg2 version removed from source tree
+ - help texts merged (help_avi+help_mpg -> help_mp)
+ - new options: -x <x> -y <y> = scale image (if selected driver supports)
+ if value<=8 then image size will be multiplied by value, otherwise
+ image size will be scaled to <value> pixels.
+ For example:
+ 2x ZOOM: mplayer -x 2 -y 2 test.mpg
+ 800x600: mplayer -x 800 -y 600 test.mpg
+ [default values are still configurable at compile-time, see config.h]
+ - TV project (not finished) codebase added (see tvision.c, or: make tvision)
+
+v0.09: Beta release [same as 0.09-pre3]
+ - version changed in the files
+ - docs updated
+
+v0.09-pre3: bugfix test-release, X11 support testing
+ - fixed the if [ -z $pparam ] bug in ./configure [Christian Birchinger]
+ - many changes in AVI seek code, resulting near-perfect seeking now!
+ current method calc absolute audio position, so with VBR audio it
+ doesn't work yet...
+ - avip: Xv support (YUY2 image format)
+ - avip: X11 support (24 & 32 bpp only, BGR format)
+ I need a very fast 15->16bpp converter for 16bpp support... anyone helps?
+
+v0.09-pre2: bugfix test-release
+ - removed unnecessary code from libmpeg2/header.c
+ Walken told me that standard mpg/vob streams must NOT use framerate
+ and bitrate extension... and the ext. id check is done by the caller.
+ - CRC support to mp3lib's mpeg audio layer-2 decoder
+ thanks for bugreport & testfile to Samson
+
+v0.09-pre1: bugfix test-release
+ - imported new libmpeg2 files (under testing...)
+ - GL renderer flickering bug fixed (MMX missing emms() between yuv2rgb and
+ glTexSubImage(), bug triggered by new Utah-GLX code)
+ [thanks for Christian Birchinger]
+
+v0.08: Index support, avi seeking, DLL loader fix, compilation fixes
+ - Added support for chunk index usage (disable with -noidx option)
+ - Removed code optimization flags from loader/Makefile because
+ it segfaults if compile optimized code (it does some hacks with
+ pointers, maybe the reordered code confuses it)
+ - added new tool called aviparse (read and check avi file structure)
+ - indexed and raw chunk info comparing, bad chunks dropped
+ - termcap usage is optional (for those debian users without termcap)
+ - #if HAVE_* fixed (to #ifdef HAVE_*)
+ - ./configure supports new /proc/cpuinfo (2.4.0-test11)
+ - sse is called 'sse' again
+ - 'flags' field renamed to 'features'
+ - Xv benchmark results added to DOCS/SPEED
+ - avi seeking (and other goodies, pause etc) implemented
+ no PTS resync after seek yet.
+ - default video_out driver changed from 'mga' to the first available driver
+ new driver priority: mga_vid, opengl, x11
+
+v0.07: Easier compile
+ - Added Pontscho's ./configure script (it's modified a lot)
+ - Updated makefiles, and tested a lot :)
+ - Updated DOCS/INSTALL
+
+v0.06: Better codec selection
+ - avi audio&video codec selection moved to new codecs.c file,
+ loader/driver.c and loader/afl.c modified for this
+ - yuv support fixed, codecs.c setup flags to handle yuv properly
+ yuv works fine with divx, mpeg4, cvid, and upside-down iv50
+ - DOCS/INSTALL updated
+ - DOCS/SPEED updated, DivX benchmarks added
+
+v0.05: Merged with MPEGplayer 0.90pre6, first public release of AVI player
+ - code merged with mpegplayer, new Makefile, some small modifications
+ - docs updated and moved to DOCS
+
+v0.04: YUV support, some code cleanup, preview-release
+
+v0.01: first version based on new MPEGplayer's codebase.
diff --git a/DOCS/ChangeLog.mpeg b/DOCS/ChangeLog.mpeg
new file mode 100644
index 0000000000..265a57c16b
--- /dev/null
+++ b/DOCS/ChangeLog.mpeg
@@ -0,0 +1,232 @@
+ChangeLog:
+~~~~~~~~~~
+v0.2: [first public release]
+- parser: add support for VOB files (audio format still has problems...)
+- libmpeg3: improvements in file-type detector, supporting mpegs with RIFF hdr
+- libmpeg3: improvements on mpeg3_read_program() to handle damaged files better
+- libmpeg3: new functions for separated PTS access: mpeg3_audio_pts() and
+ mpeg3_video_pts(), they return timestamp in seconds, format: double
+- play: new audio-video sync method, using timestamps from streams.
+ much better, even on very damaged files!
+- play: measuring of audio buffer size instead constant hard-wired value
+- libmpeg3: more improvements to handle better strange files...
+- play: drop timestamp correction if > 2 seconds (good for concatenated files)
+
+v0.3:
+- much better audio-video sync, using limited timestamp correction
+- TVout directory added, with tools & scripts to setup TVout on Matrox cards
+ (it is able to play mpegs fullscreen on TV without using X)
+
+v0.5:
+- integrating dvdview for video decoding
+ (still using libmpeg3 for system stream parsing and audio decoding)
+ -> not works... some variable randomly changes (uninitialized pointers
+ in dvdview??? c++/c mixing problem?)
+
+v0.6:
+- new player from scratch, using my mp3lib for audio, parser.c for demuxing.
+ integrated dvdview is still buggy...
+
+v0.7: [second edition]
+- dvdview as separated process, using FIFOs for communication.
+- some fixes in dvdview/system/sysdec1.cc, improved re-syncing on reset
+- double-buffering support into dvdview's mga_vid class (and some
+ changes in the mga_vid kernel module too!)
+- EOF problem solved
+- background playing option (using MGA Color-Keying and xsetroot)
+- rebuild README, added Standard Disclaimer section
+
+v0.71:
+- better missing-stream detection (counting only the real packets)
+- check for file and missing streams before fork()
+- fixed ugly byteorder bug when reading header dword
+- new system stream sync method (doesn't requires SYSTEM_HEADER_START_CODE)
+- seeking (byte or second pos), works *only* with streams with immediate
+ SYSTEM_HEADER frames.
+
+v0.8: [seeking works]
+- implementing own video packet reader -> disabling the whole streaming part
+ of dvdview.
+- saving system headers, and re-sent after starting dvdview (seeking/resync)
+ -> allow seeking in single-header mpeg files (contact2.mpg)
+- advanced resync and seek_sec method, using video-packet type-checks
+- fix read() problem, when not enough bytes available in fifo (see man 2 read)
+- removed unused objects (postproc,options,streaming) from dvdview's Makefile
+ (smaller executable, faster compile)
+- sec. and bytepos seek fixed, works well now.
+- simple console gui, using my getch2 (from mailer3 source) for keyboard.
+ allows seek,pause,quit functions (for testing only)
+ it's time to begin develop some nice GUI with skins, plugins etc :)
+- improved runtime seeking, added force_redraw variable, and PTS audio
+ correction after every seek.
+
+v0.81:
+- fps fixed (other than 25fps supported again)
+- EOF handling fixed again
+- nosound support (currently only system streams supported, not video-only)
+ also see -nosound commandline option
+- mga_vid: changed mmap() to allow double buffering in 704x528
+- mga_vid: double buffering is optional from now (dvdview option -db )
+* it successfully plays .VOB files (without sound)
+- PTS/DTS support in mpeg-2 system streams (.vob files)
+- PCM audio (48kHz stereo, unsigned, swapped byteorder) playing implemented
+* it "plays" .VOB files with PCM sound, but it's too sloooooow :(((
+- some optimization of dvdview's bitstream handler (see FillBits & GetBitsFast)
+
+v0.82: [VOB support]
+- updated dvdview from current CVS version (1.2.0-pre) -> about 25% faster!!!
+* it's now fast enough for VOB playback
+- AC3 audio support (using Aaron Holtzman's libac3 from ac3dec package)
+- new, simpler Makefile for libac3
+- re-organized text files (README splitted to ChangeLog and AUTHORS)
+
+v0.83: [ALSA support]
+- some timing code to fix audio syncing with ALSA drivers (test it! I can't)
+ use -alsa cmdline option to enable this experimental code!
+- cmdline option (-abs) for overriding audio buffer size (default: measured)
+ why is it needed? some audio drivers has bad implementaion of select(),
+ so measuring buffer size gives false result.
+ if you hear sound before picture window appears, then you should use this!
+
+v0.84:
+- multiple DVD audio channels/streams support (use -aid option to select chn.)
+- cmdline option for maximum PTS time correction (-mc <value>)
+- PTS sync code moved to frame display loop -> more precise timing
+ now it sync audio after every 5 decoded frames
+- cmdline option for override frame rate (-fps <rate>)
+ some .VOB files has bad frame rate value in headers (why? any ideas?)
+- ac3 audio seeking works (some hack in libac3's parse.c)
+
+v0.85: [first non-experimental release]
+- directory structure changed
+- better documentation, added new INSTALL
+- every Makefile uses OPTFLAGS environment variable, see INSTALL
+- help (run mpg12play without any parameters or with -h/--help)
+- fixed byte seeking (-sb)
+- allow selecting mpeg audio channel, see -aid (streams 0x1C0-1DF)
+- allow selecting video channel, see -vid (0x1E0-1EF)
+- allow audio format override, see -afm
+- new streaming system (with 4k buffering)
+- initial VCD (Video CD) support, use -vcd to select track, and give
+ device name as filename (e.g.: mpg12play -vcd 2 /dev/cdrom)
+ Problems with dual streaming, it's very slow! reads every sectors twice...
+- VCD cache system... -> solved dual (A+V) streaming slowdown
+
+v0.86: [cleanup]
+- last_frame_* thing removed + control fifo read() fixed -> better and
+ linear (no seek-back) resync if dvdview dies
+- better nosound timing (uses -alsa timer), seeking works
+- resync_to_pts eliminated (using new max_pts_correction)
+- cleanups, error checks, small fixes in the whole player.c
+- removed some unused old code
+- exit code moved to exit_player(), removed redundancy, fixed kill order
+
+v0.87:
+- i've found the reason of bad fps value with some vob files...
+ the fps is correct, but the dvdview doesn't decode all the frames
+ (reads repeat_first_field flag but don't rely on it)
+- new demuxer code: read & demux input stream only at once, and uses two
+ memory FIFO-s for packages. also new reader code, everyting named ds_*()
+ The new demuxer can autodetect video and audio stream ids, if not
+ specified with -aid / -vid option, and better implementation of -afm
+- vcd cache is optional (and disabled by default), because unneccesary with
+ new demux/streaming code
+
+v0.90pre:
+- new codec added: mpeg2dec by Aaron Holtzman
+ after doing some fixes (see at bottom), it's able to play mpeg1/mpeg2 video
+- FIFO API changed: after frame_complete command (0x0) the codec must
+ send the fps*10000 and the length*100 value. length is 1.00 for a simple
+ frame, and >=1 for mpeg2 fields (eliminates the fps problem)
+ Now, using mpeg2dec we are able to play .vob files with correct fps timing!
+- better AC3 resync after seek (new func. in libac3: ac3_bitstream_reset())
+ using ac3_decode_frame() instead ds_fill_buffer() when syncing PTS
+
+v0.90pre2:
+- mpeg2dec integrated into player binary
+- using pipe() instead of named pipes
+- using shared memory (mmap(...MAP_ANON...)) for packet transfer to codec
+- stream_select() thing removed
+- some optimization in demuxer code
+- measuring codec CPU usage (relative to video time!!!, so it can be >100%
+ on a slow system) This value must be <=100% for continous video playback.
+
+v0.90pre3:
+- ugly bug fixed causing packet loss at codec restarting
+ (i wrote control_fifo instead of control_fifo2 into codec controller)
+- video init part moved to the player
+- using shared memory for image buffers to avoid green flashes when
+ codec restarted...
+- new shared memory allocation code (the mmap() thing worked only with
+ kernel 2.4.x). thanx to LGB for the info and help... see linux/shmem.[ch]
+- config.h moved, Makefiles changed a bit (added libvo path, thanx to LGB)
+ you may select CPU extensions (3Dnow/MMX/SSE) *only* at config.h
+- meaningfull error messages if video stream cannot be synced
+ (many user asked about "missing video stream" error...)
+
+v0.90pre4:
+- included new mpeg2dec source (with SSE idct code)
+
+v0.90pre5:
+- libvo: OpenGL video renderer code by me
+- included new mpeg2dec and ac3dec from today CVS snapshot
+- new docs: SPEED and MTRR
+- seq. head processing and video init code moved into player.c, just
+ before fork()'ing, so the child inherits all this info!
+- removed all sequenceheader[] code, it's unneeded now
+- source cleanup, removed some debug printf()'s, old comments
+- EOF problem seems to be solved (maybe at the cleanup???)
+- implemented bitrate (and free framerate) reading into mpeg2dec/header.c
+- seeking skip times are better, based on bitrate
+
+
+Changed in libac3 source:
+~~~~~~~~~~~~~~~~~~~~~~~~~
+- ac3.h replaced with the old version from v0.6.0
+- decode.c modified to fit my interface
+- stats.h: use stats_* functions only if DEBUG defined
+
+Changed in libmpeg2 source:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- header.c: implemented repeat_first_field thing (see picture.repeat_count)
+- HACK_MODE set to 1 (default is 0, which works only with mpeg2 streams)
+- decode.c: some changes added, active only if MPG12PLAY #defined
+- header.c: implemented bitrate (and free framerate) reading
+
+Changed in libvo source:
+~~~~~~~~~~~~~~~~~~~~~~~~
+- fixed bug in mga_vid vo module: used dest_width/height instead src_*
+ (dst is important only for the card, we need (for memory, etc) the src size!)
+- added OpenGL video renderer (based on x11 rendere and Pontscho's opengl code)
+
+Changed in DVDview source:
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+main.cc: replaced with my code
+Makefile: removed unneccesary objects, added optimization flags
+output/out_mgavid.cc & .hh: added double-buffering and color-keying support
+system/userpack.cc & .hh: new code, by me (interface to my packet reader)
+video12/vdecoder.hh: added GetSeqHeader() function (for accessing FPS value)
+video12/vdecoder.cc: commented out calls to PrintDataBin() (debug info only)
+
+TODO:
+~~~~~
+- multiple video packets (whole frame) transfer to codec - DONE
+- B-frame skipping (DVD for slow systems)
+- VCD support - DONE
+- DVD Audio downsampling (for 44kHz cards)
+- SEEKing in VOB files with AC3 sound (some hack needed in libac3) - DONE
+- own AC3 frame reader -> better resync after seek - DONE
+- player source is really ugly now... it's time to some cleanup - DONE?
+- seek/resync without immediate SYSTEM_HEADER frames. - DONE
+- end of file detecion !!! - DONE - NOT done (see matrix.vob!) - DONE
+- other than 25fps movies - DONE
+- test with mono sound - DONE (currently playing as stereo)
+- nosound (no audio card or no audio stream) - DONE
+- .vob support (non-crypted DVD/mpeg2 stream) - DONE
+- AC3 and PCM audio support - DONE
+- audio-only and video-only file support
+- nice GUI (something new written in gtk or modify xmovie's gui)
+- Xv support - DONE (libvo has it)
+- easier compile, maybe new ./configure and makefiles - DONE?
+- decss support (encrypted dvd)
+- test speed with pgcc (does it worth?)
diff --git a/DOCS/INSTALL b/DOCS/INSTALL
new file mode 100644
index 0000000000..c81b5abda3
--- /dev/null
+++ b/DOCS/INSTALL
@@ -0,0 +1,29 @@
+ =======================================================================
+ * HOW TO COMPILE MOVIE PLAYER COMPONENTS * (C) 2000. A'rpi/ESP-team *
+ =======================================================================
+
+Pontscho/Fresh! did some script and makefiles so compiling is much
+easier now. If you find a bug in that, please contact us:
+ pontscho@makacs.poliod.hu
+ arpi@esp-team.scene.hu
+
+1. The Player: (mplayer)
+~~~~~~~~~~~~~~
+ ./configure
+[* check config.h and config.mak files! *]
+ make dep
+ make
+ make install
+
+2. Drivers: (mga_vid.o)
+~~~~~~~~~~~~~~~~~~~~~~~
+ cd drivers
+ make
+ mknod /dev/mga_vid c 178 0
+ chmod go+rw /dev/mga_vid
+
+3. Matrox G400 DH TV-out tools:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ cd TVout
+ ./compile.sh
+
diff --git a/DOCS/LIRC b/DOCS/LIRC
new file mode 100644
index 0000000000..831ede3c66
--- /dev/null
+++ b/DOCS/LIRC
@@ -0,0 +1,54 @@
+
+LIRC support for MPlayer
+ written by Andreas Ackermann in 2/2001
+ contact: acki@acki-netz.de
+
+o What is LIRC?
+
+ Linux Infrared Remote Control - use an easy to build home-brewn IR-receiver,
+ an (almost) arbitrary remote control and control your linux box with it!
+ More about it at www.lirc.org.
+
+o MPlayer and LIRC
+
+ If you have installed the lirc-package, you can compile MPlayer with LIRC
+ support using ./configure --enable-lirc
+ You should do 'make distclean' before re-compile with 'make dep;make'
+
+ If everything went fine, MPlayer will print a message like
+ LIRC init was successful.
+ on startup. If an error occurs it will tell you. If it doens't tell you
+ anything about LIRC there's no support compiled in. That's it :-)
+
+ The application name for MPlayer is - oh wonder - mplayer.
+ It understands the following commands:
+
+ PAUSE - pause playing. Any other keystroke will continue replay.
+ QUIT - exit mplayer
+ RWND - 10 secs back
+ FRWND - 60 secs back
+ FWD - skip 10 secs
+ FFWD - skip 60 secs
+
+ Don't forget to enable the repeat flag for RWND/FWD in .lircrc. Here's an
+ excerpt from my .lircrc:
+
+ begin
+ remote = CU-SX070
+ prog = mplayer
+ button = Tape_Play
+ repeat = 1
+ config = FFWD
+ end
+
+ begin
+ remote = CU-SX070
+ prog = mplayer
+ button = Tape_Stop
+ config = QUIT
+ end
+
+ Enjoy
+
+ -Andreas
+
diff --git a/DOCS/MPlayer-FAQ b/DOCS/MPlayer-FAQ
new file mode 100644
index 0000000000..40d3ae414d
--- /dev/null
+++ b/DOCS/MPlayer-FAQ
@@ -0,0 +1,120 @@
+Yes, this is the MPlayer FAQ.
+=============================
+
+About:
+~~~~~~
+Many people asked same questions so I decided to write this stuff.
+I know that people will never read this but at least i try to
+pull down number of these mails.
+And from now i can say that "read the fuckin' FAQ!" :-)
+
+Let's ask!
+~~~~~~~~~~
+Q: SDL output doesn't work or compile. Problem is ....
+A: It works only with SDL v1.1.7 (and maybe newer)
+ It does NOT work with 1.1.6, 1.1.5 1.1.4 1.1.3 1.0.4 etc, don't ask.
+
+Q: I am still having trouble compiling with SDL support. gcc says something
+ about "undefined reference to `SDL_EnableKeyRepeat'" What's now?
+A: Where did you install the SDL library? If you installed in /usr/local
+ (the default) then edit the top level config.mak and add
+ "-L/usr/local/lib " after "X_LIBS=" Now type make. You're done!
+
+Q: I have problem ... with the SDL driver.
+A: It's very experimental & buggy code, and it's UNSUPPORTED by us.
+ Please do NOT report bugs or ask features relating to SDL.
+ But you can improve it, and send us patches!
+
+Q: It doesn't compile, and it misses uint64_t inttypes.h and similar things...
+A: copy DOCS/inttypes.h to MPlayer directory (cp DOCS/inttypes.h .)
+ try again... if fail, contact me
+
+Q: I have Pentium III but ./configure doesn't detect SSE
+A: Only kernel versions 2.4.x supports SSE
+
+Q: fullscreen option (-fs) and/or -xy doesn't work with x11 driver (-vo x11)
+A: x11 driver doesn't support scaling, and it can't change screen resolution.
+ Yes, I know that it should be but I have no time to write software
+ scaling routines and experiencing with XVidMode extension...
+ You can do it yourself, just press ALT,CTRL,- or ALT,CTRL,+ simultaneously,
+ see X-server docs for details.
+
+Q: audio goes out of sync playing .avi file
+A: try with -bps or -nobps option
+ if still bad, send me (upload to ftp) that file, I'll check.
+
+Q: what is the meaning of numbers in the status line?
+A: see:
+ A: 2.1 V: 2.2 A-V: -0.167 ct: 0.042 57 41% 0% 2.6% 0
+ - A: audio position in seconds
+ - V: video position in seconds
+ - A-V: audio-video difference in seconds (delay)
+ - ct: total A-V sync correction done
+ - frames played (counting from last seek)
+ - video codec cpu usage in percent (for mpeg it includes video_out too!)
+ - video_out cpu usage for avi, 0 for mpg (see above)
+ - audio codec cpu usage in percent
+ - dropped bad frames (mpg only)
+ Most of them are for debug purposes, and will be removed soon.
+
+Q: Why is video_out cpu usage zero (0%) for mpeg files?
+A: It's not zero, but it's built in into codec, so can't be measured separated.
+ You should try to play the file using -vo null and then -vo ... and check
+ the difference to see video_out speed...
+
+Q: OpenGL (-vo gl) output doesn't work (hangup/black window/X11 errors)
+A: your opengl driver doesn't support dynamic texture chanegs (glTexSubImage)
+ it's known not to work with X 4.0.x DRI drivers and nVidia's binary shit.
+ it's known to work with Utah-GLX and Matrox G400 card.
+ it will not work with 3DFX cards because the 256x256 texture size limit.
+
+Q: I have g200/g400, how to compile/use mga_vid driver?
+A: read INSTALL and README...
+
+Q: What's XMMP? (it's XMMS or XMPS but mispelled?)
+A: It's a new project, see www.frozenproductions.com for details
+
+Q: There are error messages about file not found /usr/lib/win32/....
+A: Download & install w32codec.zip from *our* FTP
+ (avifile's codec package has different DLL set)
+
+Q: It wants to load l3codeca.acm, but I don't have such file.
+A: You should use w32codec.zip from MPlayer FTP, instead of avifile's pack!
+
+Q: ...... works with avifile/aviplay while doesn't with MPlayer
+A: MPlayer != avifile
+ The only common thing between these players is the Win32 DLL loader.
+ The codecs (dll) sets, syncronization, demultiplexing etc is totaly
+ different and shouldn't be compared.
+ If something works with aviplay it doesn't mean that MPlayer should do
+ it and vice versa. You should contact me, I'll fix the bug!!!
+
+Q: Indeo 3.x/4.x movies are viewed upside-down!!!?
+A: It's a known bug (really it's a bug/limitation of the DLL codec)
+
+Q: Indeo 3.x,4.x video doesn't work at 32bpp resolutions (16,24 bpp are ok)
+A: It's a known bug (really it's a bug/limitation of the DLL codec)
+
+Q: I've got 'MPlayer interrupted by signal 11' in module audio_setup or
+ decode_audio.
+A: It's a damaged file with bad mp3 audio stream. Try it with -afm 4
+
+Q: It aborts with signal 11 playing a file with IMA-ADPCM audio.
+A: This codec isn't yet supported!
+
+Q: Why do you enjoy making that much pre-releases?
+A: Download one and you'll know!
+
+Q: Are there rpm/deb/... packages of MPlayer?
+A: Not yet.
+
+Q: Are there any mailing lists on MPlayer?
+A: Yes! See README on how to subscribe them!
+
+Q: I've found a nasty bug when I tried to play my favourite video!!
+ Who should I inform?
+A: Inform the MPlayer-users mailing list about your problem. *ALWAYS*
+ read the README about what information we NEED to identify your problem.
+ Use the developers addresses (specified in AUTHORS) only if you want to
+ flame, or want to ask for a date. ;)
+
diff --git a/DOCS/MTRR b/DOCS/MTRR
new file mode 100644
index 0000000000..2a4d383462
--- /dev/null
+++ b/DOCS/MTRR
@@ -0,0 +1,38 @@
+Setting up MTRR for X11 or mga_vid:
+===================================
+
+1. find the base address
+~~~~~~~~~~~~~~~~~~~~~~~~
+You have 3 cases to find it:
+
+- from X11 startup messages, for example:
+(--) SVGA: PCI: Matrox MGA G400 AGP rev 4, Memory @ 0xd8000000, 0xd4000000
+(--) SVGA: Linear framebuffer at 0xD8000000
+
+- from /proc/pci (use lspci -v command):
+01:00.0 VGA compatible controller: Matrox Graphics, Inc.: Unknown device 0525
+ Memory at d8000000 (32-bit, prefetchable)
+
+- from mga_vid kernel driver messages (use dmesg):
+mga_mem_base = d8000000
+
+2. find memory size
+~~~~~~~~~~~~~~~~~~~
+This is much easier, just convert video ram size to hexadecimal, or
+use this table:
+ 1 MB 0x100000
+ 2 MB 0x200000
+ 4 MB 0x400000
+ 8 MB 0x800000
+ 16 MB 0x1000000
+ 32 MB 0x2000000
+
+3. setting up mtrr
+~~~~~~~~~~~~~~~~~~
+You know base address and memory size, let's setup mtrr registers!
+
+ For example, for the matrox card above (base=0xd8000000) with 32MB
+ ram (size=0x2000000) just execute:
+echo "base=0xd8000000 size=0x2000000 type=write-combining" >| /proc/mtrr
+
+(older K6-2's [around 266Mhz, stepping 0] may not support MTRR.)
diff --git a/DOCS/OpenDivX b/DOCS/OpenDivX
new file mode 100644
index 0000000000..e7494b80a0
--- /dev/null
+++ b/DOCS/OpenDivX
@@ -0,0 +1,30 @@
+
+OpenDivX support in MPlayer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+See http://www.projectmayo.com for details on Open DivX codecs.
+It's an opensource DivX-like video codec written for windows.
+I did a fast hack to get it compile under linux (it has some
+dependency on windows header files and some visualc extensions).
+
+Decoder:
+~~~~~~~~
+Now it's used for AVI files with fourcc 'dvx1'
+You can adjust Quality level using the -divxq option. Valid values:
+
+ postprcc_level = 0 ----> no post processing (fastest)
+ postproc_level = 1 ~ 9 ----> horizontal Y deblocking only
+ postproc_level = 10 ~ 19 ----> hor. + ver. Y deblocking
+ postproc_level = 20 ~ 29 ----> hor. + ver. Y and hor. C deblocking
+ postproc_level = 30 ~ 39 ----> hor. + ver. Y and hor.+ver. C deblocking
+ postproc_level = 40 ~ 49 ----> h+v Y, h+v C deblock and Y deringing
+ postproc_level = 50 ~ 59 ----> h+v Y, h+v C deblock and Y+C deringing
+
+Note: last level (Chroma deringing) sometimes crashes.
+
+Encoder:
+~~~~~~~~
+There is a very alpha hack to convert mpeg video into OpenDivX .avi files.
+You should disable audio, and select 'odivx' video device as output:
+ mplayer input.mpg -nosound -vo odivx -encode output.avi
+Yes, I know that it's unusable now, it's only for testing purposes.
diff --git a/DOCS/README b/DOCS/README
new file mode 100644
index 0000000000..cfc9671cd6
--- /dev/null
+++ b/DOCS/README
@@ -0,0 +1,271 @@
+MoviePlayer v0.11 (C) 2000-2001. by Arpad Gereoffy (A'rpi/ESP-team)
+================= * See the file AUTHORS for the complete list! *
+
+About:
+~~~~~~
+Yes. Yet another movie player for linux.
+What is the special with this? It works, at least for me :)
+I've tried lots of players under linux (mtv,xmps,dvdview,livid/oms,VideoLAN,
+xine,xanim,avifile,xmmp) but they all have some problem. Mostly with
+special files or with audio/video sync. Most of them is unable to play
+both mpeg1, mpeg2 and avi (DivX) files. Many players have image quality
+or speed problems too. So I've decided to write/modify one...
+
+Short history:
+- mpg12play v0.1 has born, using libmpeg3 from www.heroinewarrior.com
+- mpg12play 2nd generation (v0.5-), using dvdview by Dirk Farin
+- mpg12play 3nd generation (v0.9-), using libmpeg2 (mpeg2dec) by Aaron Holtzman
+- mplayer has born, containing mpg12play 0.90pre5 and a new simple avi player
+- mplayer 0.10, mpeg and avi player in a single binary
+- mplayer 0.11: added .asf file support, and OpenDivX en/decoding
+
+As you see, I didn't write any codecs, just some players. But I spent
+a lot of time finding the best way to parse bad damaged input files
+(both mpg and avi) and to do perfect A-V sync with seeking ability.
+My player is rock solid playing damaged mpeg files (useful for some VCDs),
+and it plays bad AVI files which are unplayable with the famous
+windows media player. Even AVI files without index chunk are playable!
+As you see, stability and quality are the most important things for me,
+speed has lower priority, but is still very important.
+
+What about the GUI?
+I'm not a GUI programmer. I hate GUIs, I like the pure black 80x25 console.
+So the player has only keyboard control from the controlling console/xterm now.
+But there is a GUI development for the player, coordinated by Pontscho/Fresh!
+It's still under development, but it will be merged and released soon.
+BTW he needs some nice skins, if you are a good graphician, contact him!!!
+
+Win32 codecs?
+Yes, we are using Win32 (Video for Windows) codecs for AVI/ASF decoding.
+They must be installed to the /usr/lib/win32/ directory, with all lower case.
+You can grab the codecs package from
+ ftp://thot.banki.hu/esp-team/linux/MPlayer/w32codec.zip
+or can be found in your C:\WINDOWS\SYSTEM\ dir, see codecs.c for filenames.
+Some people asked why don't we use ActiveMovie/DirectShow codecs. The reason is
+simple: we'd have to emulate the whole DirectX architecture and implement the
+(patented!) COM interface to be able to use them. BTW the old VfW DivX codec
+is faster than the new .AX version, but it has no quality/CPU setting
+option (this is an improper name, since it doesn't affect the decoder. If
+it's set to 1 or higher, it applies a filter which decreases blockiness and
+eats away CPU cycles).
+
+Supported input formats:
+~~~~~~~~~~~~~~~~~~~~~~~~
+- VCD (Video CD) directly from CD-ROM or from CDRwin's .bin image file
+- MPEG 1/2 System Stream (PS/VOB) and Elementary Stream (ES) file formats
+- RIFF AVI file format
+- ASF 1.0 file format
+
+Supported audio codecs:
+~~~~~~~~~~~~~~~~~~~~~~~
+- PCM (uncompressed) audio (8/16 bit, mono/stereo)
+- MPEG layer 2/3 audio (using mp3lib, based on mpg123)
+- AC3 audio (using ac3dec/libac3)
+- Win32 ACM audio codecs (the *.ACM files) [Only in the AVI player]
+ tested with: DivX audio, MS-ADPCM
+- aLaw audio (using code from xanim)
+- MS-GSM audio (using modified xa_gsm.c from avifile)
+
+Supported video codecs:
+~~~~~~~~~~~~~~~~~~~~~~~
+- MPEG 1 and MPEG 2 video decoder (using mpeg2dec/libmpeg2, supports
+ 3DNow! and MMX)
+- Win32 ICM (VfW) video codecs (for example DivX using DIVXC32.DLL)
+- OpenDivX encore & decore (see ProjectMayo)
+
+Supported video output devices:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- mga: Matrox G200/G400 hardware YUV overlay via the mga_vid device
+ (Some people reported that G200 is broken :( if you are a programmer
+ and you have a G200, please check it and fix if you can!)
+- xmga: Matrox G200/G400 overlay (mga_vid) in X11 window
+ (Xv emulation on X 3.3.x !)
+- x11: X11 optionally with SHM extension
+- xv: X11 using overlays with the Xvideo extension (hardware YUV & scaling)
+- gl: OpenGL renderer, requires Utah-GLX or DRI or nVidia's new driver
+- syncfb: Matrox G400 YUV support on framebuffer (not tested, maybe broken)
+- 3dfx: Voodoo2/3 hardware YUV (/dev/3dfx) support (not yet tested, maybe broken)
+- sdl: SDL v1.1.7 driver (slower than 'x11', but supports software scaling)
+- null: Null output (for speed tests/benchmarking)
+- pgm: PGM file output (for testing purposes)
+- md5: MD5sum output (for mpeg conformance tests)
+NOTE: not all are available for AVI files
+
+Supported audio output devices:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- OSS driver
+- ALSA driver with OSS emulation
+- ESD with the esddsp utility
+
+Speed:
+~~~~~~
+Most of time-critical parts are optimized for MMX/SSE/3DNow!.
+You can improve rendering speed by setting up MTRR registers, see doc in MTRR.
+Some benchmark results can be found in the doc file SPEED.
+
+Usage:
+~~~~~~
+ mplayer [options] [-vo driver] [path/]filename
+
+ Options:
+ see mplayer -h for options
+ see mplayer -vo help for available output drivers
+
+ Keys:
+ <- or -> seek backward/forward 10 seconds
+ up or down seek backward/forward 1 minute
+ p or SPACE pause movie (press any key to continue)
+ q or ^C stop playing and quit program
+
+ Examples:
+ mplayer -vo x11 /mnt/Films/Contact/contact2.mpg
+ mplayer -afm 3 /mnt/DVDtrailers/alien4.vob
+ mplayer -vcd 2 /dev/cdrom
+ mplayer -alsa -abs 65536 -delay -0.4 -nobps ~/movies/test.avi
+
+ Note: for using Matrox YUV driver (-vo mga or xmga), you have to first
+ load the driver: insmod drivers/mga_vid.o
+
+License:
+~~~~~~~~
+Since MPlayer incorporates a lot of code from other projects, this isn't
+decided yet.
+We're going for GPL (will be pretty hard, though).
+
+TV output:
+~~~~~~~~~~
+If you have a Matrox G400 Dual-Head card, you can watch movies on TV,
+using TV-out feature of the second head. You must have matroxfb support
+enabled in your kernel (2.4.x kernels). You don't need X11 for this!
+Tested only with PAL TV!
+
+ cd TVout
+ ./modules
+ ./cloning or ./independ
+ ./TV-704x528 (or another TV* script)
+
+Sending bugreports:
+~~~~~~~~~~~~~~~~~~~
+First please read all the docs in this package, most of the problems are
+described somewhere. At least read the Troubleshooting section!
+We don't like answering questions which are already answered in this
+readme or other docs.
+You should try the latest test (pre) release version too, maybe your bug
+is already fixed, but the new version hasn't been released.
+If you couldn't solve the problem, then send a quality bugreport
+via E-Mail to the MPlayer-users list : mplayer@alan.umcs.lublin.pl
+
+*NEVER* send attached AVIs, MPEGs, or any big files to this list!!!
+Upload them to ftp://thot.banki.hu/incoming , and inform the list about
+your upload.
+
+Please include these:
+- your kernel version number ('uname -a')
+- linux distribution and glibc version (example: Slackware 7.1 + glibc 2.1.3)
+- gcc and binutils version ('gcc -v' and 'as --version')
+- your X11 version (example: X 4.0.2 + DRI snapshot2001jan12)
+- video card vendor/model (example: Matrox G400 MAX AGP)
+- CPU vendor and type (example: Intel Celeron2-566 at 850MHz)
+
+Also include the required logs (as attachment, may be compressed zip/gz/bz2)
+depending the problem type (see bellow at Troubleshooting section).
+
+To log output to a file, use the &> shell operator. For example:
+ ./configure &>configure.log
+ mplayer -v test.avi &>play.log
+
+If we ask you for the file, then you have two choices:
+- upload the file to ftp://thot.banki.hu/incoming (at least a few megabytes)
+- send the exact URL of the file, and we'll download it soon.
+
+Please do not ask for features already listed in the TODO!
+
+Troubleshooting:
+~~~~~~~~~~~~~~~~
+1. Please read the docs first...
+
+2. If you have compiling problems:
+ - if you are an experienced programmer, please try to fix it, and send
+ us the patch
+ - if gcc reports problems around inttypes.h, try to copy DOCS/inttypes.h
+ to the directory where the error occured. (or upgrade glibc to 2.1/newer)
+ - if gcc reports problems around video_out_gl.c, try disabling OpenGL
+ support: ./configure --disable-gl (you have broken OpenGL headers/libs)
+ - if you are a user, send us a bugreport (see above), including these:
+ - output of ./configure
+ - output of make dep and make
+ - config.h and all of config.mak files
+ Note: many users reported that SSE was not detected while running on P3.
+ Current stable 2.2.x kernels does NOT support SSE, so you can't use it
+ without patches or using the 2.4.x series.
+
+3. If you have a problem with the player, please run it with -v option, and
+ send the output of it, with a detailed description of the problem.
+ - can't play AVI files: check that codec .DLL and .ACM files are installed to
+ /usr/lib/win32/ and are all lowercase (divxc32.dll instead of DivXc32.DLL)
+
+4. If you have a file-specific problem (can't play a special file,
+ crashes with it or similar) then please run with -v -v -v (debug level 3).
+ Send us the output and the problem description via email bugreport.
+ We may ask you to upload the file.
+ - if it segfaults with an AVI file with MP3 audio, try with -afm 1 or -afm 4
+ - if it's still bad, try with -nosound
+
+5. If you have problem with display driver, please first check the list above,
+ many of them isn't yet capable to AVI playing, and some of them are
+ untested and/or unfinished.
+
+6. If you have speed problems (too slow playing), then please first check that:
+ - you don't use OpenGL driver while have software-only opengl (DRI disabled,
+ or not yet installed, conflicting libs installed, or your hardware not
+ supported etc...)
+ - you have set up MTRR registers properly (many new cards are really
+ slow without setting up MTRR registers. it's NOT done by X 3.3.x! Also,
+ there are older K6-2's, which lack MTRR support /stepping=0/).
+ - you have a fast machine (don't report that your 386 can't play DivX)
+ - try with Null output (-vo null) and check CPU usage (first % value)
+
+7. sound-related problems:
+ - maybe your card doesn't support 48kHz playback and the movie requires it.
+ - try player with the -noalsa option
+ - delayed audio with some AVI files: try with -bps or -nobps option!
+ - if you experienced delayed audio, try to compensate with -delay or -abs.
+ you can specify audio card's buffer size in bytes with -abs option, or
+ specify audio delay in seconds (positive/negative float) with -delay
+ for example: mplayer -alsa -delay -0.75 test.avi
+ mplayer -abs 65536 -delay 0.3 test.mpg
+ - to play AVI files with VBR MP3 audio use the -mc 0 option!
+ - no sound at all: check that you have working OSS driver (/dev/dsp),
+ and it isn't used by another program (for example esd, xmms etc.)
+
+8. unsupported codecs (AVI files):
+ We may add support for your movie, but we need the following things:
+ - the codec DLL file: find it in your WINDOWS directory. In the SYSTEM.INI
+ there will be a listing of the installed codecs (vids.<codecname>=DLLfile)
+ - a sample file encoded with that codec.
+
+
+Download:
+~~~~~~~~~
+Download: ftp://thot.banki.hu/esp-team/linux/MPlayer/
+ or: http://thot.banki.hu/esp-ftp/linux/MPlayer/
+Homepage: http://thot.banki.hu/esp-team/MPlayer.html
+
+Mailing lists:
+~~~~~~~~~~~~~~
+There are two public mailing lists on MPlayer. Subscribing can be achieved by
+writing to the following addresses, and specifying "subscribe" in the Subject,
+or message body.
+
+- MPlayer-users
+ Write an e-mail to mplayer-request@alan.umcs.lublin.pl
+- MPlayer-announce
+ Write an e-mail to mplayer-announce-request@alan.umcs.lublin.pl
+
+Special thanks to Dariusz Pietrzak for the list hosting!
+
+Standard Disclaimer:
+~~~~~~~~~~~~~~~~~~~~
+Use only at your own risk! There may be errors and inaccuracies that could
+be damaging to your system or your eye. Proceed with caution, and although
+this is highly unlikely, I don't take any responsibility for that!
diff --git a/DOCS/SOUNDCARDS b/DOCS/SOUNDCARDS
new file mode 100644
index 0000000000..8c396c32f5
--- /dev/null
+++ b/DOCS/SOUNDCARDS
@@ -0,0 +1,21 @@
+Recommended options for better sound sync:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(first try without these, maybe it works well without 'hacking' defaults)
+
+ALSA: -alsa -abs 65536
+
+Aureal Vortex2: -alsa -abs 65536 -delay -0.5
+
+SB Live!: kernel 2.2.x: -alsa
+ 2.4.x: nothing
+
+OSS/Free: please contact me for good parameters
+
+
+... and not use your soundcard by other application ( for ex. XMMS ) ...
+... and use very-very high speed hdd or CDROM and CPU ...
+
+
+ Pontscho/fresh!mindworkz
+ pontscho@makacs.poliod.hu \ No newline at end of file
diff --git a/DOCS/SPEED b/DOCS/SPEED
new file mode 100644
index 0000000000..d15285cb4a
--- /dev/null
+++ b/DOCS/SPEED
@@ -0,0 +1,40 @@
+Some benchmark values
+=====================
+
+Test system: Abit BE6-2 mb, Intel Celeron2-566 @ 850Mhz, Matrox G400 MAX
+Linux: Slackware 7.0, kernel 2.4.0-test8, glibc 2.1.2
+
+MPEG 1/2 Video codec CPU usage in percent (%) :
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1. Setup: mga_vid YUV, MMX idct, no mtrr settings
+2. Setup: mga_vid YUV, SSE idct, with mtrr settings
+3. Setup: Utah-GLX OpenGL + software C YUV->RGB, SSE idct
+4. Setup: X11 Shm (32bpp) + software MMX YUV->RGB, SSE idct, with mtrr
+5. Setup: null output (codec speed only)
+6. Setup: X11 4.0.1e + Xv extension, SSE idct, with mtrr
+
+ 1. 2. 3. 4. 5. 6.
+ DolbyDigitalBroadway.vob: 60% 35% 78% 67% 26% 47%
+ matrix.vob (trailer): 51% 30% 62% 56% 23% 40%
+ PAL (352x288/25) mpeg1: 16% 9% 30% 13% 7% 8%
+ 3D anim (30fps mpeg1): 20% 14% 35% 25% 12% 14%
+
+Win32 Video codec CPU usage in percent (%) :
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(All tests with YUV/YUY2 output format to null device)
+ DivX 720x416/30fps 27%
+ DivX 704x320/25fps 24%
+ DivX 640x352/24fps 22%
+ DivX 480x204/24fps 12%
+ IV50 320x240/15fps 7%
+
+Audio codec CPU usage in percent (%) :
+~~~~~~~~~~~~~~~~~~~~~
+ Mpeg layer-2 audio (VCD): 1.2%
+ PCM audio (DVD, 48khz): 1.3%
+ AC3 audio (DVD, 2.0 mode) 4.1%
+ AC3 audio (DVD, 5.1 mode) 6.5%
+ AC3 audio (DivX, 5.1 mode) 3.5%
+ MP3 audio (mp3lib) 2.8%
+ MP3 audio (l3codeca.dll) 1.8%
+ DivX audio (divxa32.dll) 3.3%
diff --git a/DOCS/TODO b/DOCS/TODO
new file mode 100644
index 0000000000..f2fae7e80d
--- /dev/null
+++ b/DOCS/TODO
@@ -0,0 +1,30 @@
+TO DO:
+~~~~~~
+Urgent:
+- asterix.avi audio delays after 5-10 mins (bps mode only)
+- PAUSE doesn't work in the X11 and SDL windows (because no Check X Events)
+- SDL fullscreen problems at quit/eof - DONE?
+- finish ASF seeking
+- fix vo_syncfb - DONE for G400
+
+Fix compilation problems:
+- SDL version detection into ./configure - DONE (disabled :))
+
+Libvo features:
+- framebuffer and svgalib support (both)
+- DGA support (LGB?)
+- real fullscreen (black bands at unused areas) support - DONE for xmga & x11
+- fix X4.0.x/DRI OpenGL (doesn't work, at least mga & tdfx & nvidia)
+- change libmpeg2 & libvo interface to be compatible with libmpeg2-0.2.0 release
+
+Player features:
+- libcss support
+- subtitles support (.sub files)
+- show movie length / position in percent
+- show current frame number [Gabucino]
+- seek_to_frame and seek_to_index options
+- fix mp3lib to avoid segfault with some damaged .avi files (workaround: -afm 4)
+- integrating the gui?
+- support for more codecs (sample .avi files and .dll needed!) - HELP!
+- support for MPEG TS (transport streams) and PES format - I need sample files!
+- verify valid range of numeric options (like '-xy 0')
diff --git a/DOCS/inttypes.h b/DOCS/inttypes.h
new file mode 100644
index 0000000000..b1e93879e4
--- /dev/null
+++ b/DOCS/inttypes.h
@@ -0,0 +1,13 @@
+
+// fallback if the user doesn't have inttypes.h (libc5 systems)
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef signed long long int64_t;
+
diff --git a/DOCS/mplayer.1 b/DOCS/mplayer.1
new file mode 100644
index 0000000000..fd89c47651
--- /dev/null
+++ b/DOCS/mplayer.1
@@ -0,0 +1,190 @@
+.\" MPlayer (C) 2000-2001 Arpad Gereoffy <arpi@esp-team.scene.hu>
+.\" This manpage was/is done by Gabucino
+.\" Manpage v1.1
+.\"
+.TH MPlayer 0.11
+.SH NAME
+mplayer \- Movie Player for Linux
+.SH SYNOPSIS
+.B mplayer
+.RB [ \-vo\ output\ driver ]
+.RB [ \-vcd\ track\ number ]
+.RB [ \-sb\ byte\ position ]
+.RB [ \-nosound\ ]
+.RB [ \-abs\ seconds ]
+.RB [ \-delay\ secs ]
+.RB [ \-bps\ value ]
+.RB [ \-noalsa\ ]
+.RB [ \-aid\ id ]
+.RB [ \-vid\ id ]
+.RB [ \-fps\ rate ]
+.RB [ \-mc\ seconds/5f ]
+.RB [ \-afm\ audio\ decoder ]
+.RB [ \-fs\ ]
+.RB [ \-x\ x ]
+.RB [ \-y\ y ]
+.RB [ \-xy\ factor ]
+.RB [ \-dsp\ device ]
+.RB [ \-divxq\ quality ]
+.I file
+.PP
+.SH DESCRIPTION
+.I mplayer
+Yes. Yet another movie player for linux.
+What is the special with this? It works, at least for me :)
+I've tried lots of players under linux (mtv,xmps,dvdview,livid/oms,VideoLAN,
+xine,xanim,avifile,xmmp) but they all have some problem. Mostly with
+special files or with audio/video sync. Most of them is unable to play
+both mpeg1, mpeg2 and avi (DivX) files. Many players have image quality
+or speed problems too. So I've decided to write/modify one...
+.LP
+.SH "GENERAL OPTIONS"
+.TP
+.I NOTE
+MPlayer works out-of-the-box, so you generally don't have to mess with
+any options.
+.TP
+.BI \-vo\ output\ driver
+select output driver
+
+you can get the list of available drivers executing
+.I mplayer -vo help
+
+.TP
+.BI \-vcd\ track
+play video cd track from device instead of plain file
+.TP
+.BI \-nosound
+don't play sound
+.TP
+.B \-fs
+fullscreen playing (only gl, xmga and xv drivers)
+
+.I NOTE
+The X11 driver doesn't support fullscreen and scaling.
+However, you can do it yourself, just press ALT,CTRL,-
+or ALT,CTRL,+ simultaneously, see X-server docs for details.
+.TP
+.B \-x\ x
+scale image to x width [if driver suppports!]
+.TP
+.B \-y\ y
+scale image to y height
+.TP
+.B \-xy\ factor
+scale image by <factor>
+.TP
+.B \-dsp\ device
+select another DSP output device
+.TP
+.B \-divxq\ quality
+apply postprocess filter on decoded image.
+You need a STRONG CPU in order to use this!
+The supported formats and settings are:
+
+ MPEG1 1, 3, 7, 31
+ OpenDivX 1-59 (maybe less/more)
+ DivX not YET supported
+
+.I NOTE
+You can use this with OpenDivX encoding too! See ALPHA/BETA CODE section.
+.IP
+.SH KEYBOARD CONTROL
+.TP
+.I NOTE
+These keys may/may not work, depending on your video output driver.
+.TP
+ <- or -> seek backward/forward 10 seconds
+
+up or down seek backward/forward 1 minute
+
+p or SPACE pause movie (press any key)
+
+q or ESC stop playing and quit program
+
++ or - adjust audio delay by +/- 0.1 second
+.IP
+.SH "ADVANCED OPTIONS"
+.TP
+.I NOTE
+These options can help you solve your particular problem.. Also, see the DOCS!
+.TP
+.B \-afm <1-5>
+force audio format 1:MPEG 2:PCM 3:AC3 4:Win32 5:aLaw
+
+.I NOTE
+With DivX AVIs with MP3 audio, you can choose whether to use MP3LIB (option 1),
+or Win32 DLL l3codeca.acm (option 4) (default). On CPUs with the 3DNow!
+instruction set, the first gives more performance. Your mileage may vary.
+.TP
+.BI \-sb\ position
+seek to byte position
+.TP
+.BI \-abs\ bytes
+audio buffer size (in bytes, default: measuring)
+.TP
+.B \-delay\ secs
+audio delay in seconds (may be +/- float value)
+.TP
+.B \-bps
+use avg. byte/sec value for A-V sync (AVI)
+.TP
+.B \-noalsa
+disable timing code
+.TP
+.B \-aid\ id
+select audio channel [MPG: 0-31 AVI: 1-99]
+.TP
+.B \-vid\ id
+select video channel [MPG: 0-15 AVI: -- ]
+.TP
+.B \-fps\ value
+force frame rate (if value is wrong in the header)
+.TP
+.B \-mc\ seconds/5frame
+maximum sync correction per 5 frames (in seconds)
+.TP
+.B \-ni
+force usage of non-interleaved AVI parser
+.IP
+.SH "ALPHA/BETA CODE"
+.TP
+.I NOTE
+These are included in this manpage just for completeness! If you don't
+know what are these, you DON'T need these! In either case, double-check DOCS!
+.TP
+.B \-br\ rate
+used with '-vo odivx' .
+Specifies the bitrate to encode OpenDivx at
+(in bits! e.g: 780000).
+.TP
+.B \-encode\ file
+used with '-vo odivx' .
+Specifies the output OpenDivX file. Won't overwrite.
+.IP
+.SH "EXAMPLES"
+Just launch it! :)
+.LP
+.SH BUGS
+Possibly. Check DOCS.
+
+Bugreports should be addressed to the MPlayer-users mailing list
+(mplayer@alan.umcs.lublin.pl) ! If you want to submit a bugreport
+(which we love to receive!), please double-check the README, and
+tell us all that we need to know to identify your problem.
+
+.LP
+.SH AUTHORS
+Check DOCS/AUTHORS !
+
+MPlayer is (C) 2000-2001
+.I Arpad Gereoffy <arpi@thot.banki.hu>
+
+This manpage is maintained by
+.I Gabucino.
+.LP
+.SH STANDARD DISCLAIMER
+Use only at your own risk! There may be errors and inaccuracies that could
+be damaging to your system or your eye. Proceed with caution, and although
+this is highly unlikely, the author doesn't take any responsibility for that!
+.\" end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..ebbdf1636d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,82 @@
+# LINUX Makefile made by A'rpi / Astral
+# Some cleanup by LGB: * 'make -C dir' instead of 'cd dir;make;cd..'
+# * for loops instead of linear sequence of make directories
+# * some minor problems with make clean and distclean were corrected
+
+include config.mak
+
+PRG = mplayer
+PRG_AVIP = aviparse
+PRG_TV = tvision
+prefix = /usr/local
+BINDIR = ${prefix}/bin
+# BINDIR = /usr/local/bin
+SRCS = linux/getch2.c linux/timer-lx.c linux/shmem.c xa/xa_gsm.c lirc_mp.c
+OBJS = linux/getch2.o linux/timer-lx.o linux/shmem.o xa/xa_gsm.o lirc_mp.o
+CFLAGS = $(OPTFLAGS) -Iloader -Ilibvo # -Wall
+A_LIBS = -Lmp3lib -lMP3 -Llibac3 -lac3
+VO_LIBS = -Llibvo -lvo $(X_LIBS)
+
+.SUFFIXES: .c .o
+
+# .PHONY: all clean
+
+all: $(PRG)
+# $(PRG_AVIP)
+
+.c.o:
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+COMMONLIBS = libvo/libvo.a libac3/libac3.a mp3lib/libMP3.a
+
+loader/libloader.a:
+ $(MAKE) -C loader
+
+libmpeg2/libmpeg2.a:
+ $(MAKE) -C libmpeg2
+
+libvo/libvo.a:
+ $(MAKE) -C libvo
+
+libac3/libac3.a:
+ $(MAKE) -C libac3
+
+mp3lib/libMP3.a:
+ $(MAKE) -C mp3lib
+
+opendivx/libdecore.a:
+ $(MAKE) -C opendivx
+
+encore/libencore.a:
+ $(MAKE) -C encore
+
+$(PRG): mplayer.o $(OBJS) loader/libloader.a libmpeg2/libmpeg2.a opendivx/libdecore.a $(COMMONLIBS) encore/libencore.a
+ $(CC) $(CFLAGS) -o $(PRG) mplayer.o $(OBJS) $(XMM_LIBS) $(LIRC_LIBS) $(A_LIBS) -lm $(TERMCAP_LIB) -Lloader -lloader -ldl -Llibmpeg2 -lmpeg2 -Lopendivx -ldecore $(VO_LIBS) -Lencore -lencore -lpthread
+
+$(PRG_AVIP): aviparse.o $(OBJS) loader/libloader.a $(COMMONLIBS)
+ $(CC) $(CFLAGS) -o $(PRG_AVIP) aviparse.o $(OBJS) $(A_LIBS) -lm $(TERMCAP_LIB) -Lloader -lloader -ldl $(VO_LIBS) -lpthread
+
+$(PRG_TV): tvision.o $(OBJS) $(COMMONLIBS)
+ $(CC) $(CFLAGS) -o $(PRG_TV) tvision.o $(OBJS) -lm $(TERMCAP_LIB) $(VO_LIBS)
+
+install: $(PRG)
+ strip $(PRG)
+ cp $(PRG) $(BINDIR)
+ install -m 644 DOCS/mplayer.1 $(prefix)/man/man1/mplayer.1
+
+clean:
+ rm -f *.o *~ $(OBJS)
+
+distclean:
+ @for a in mp3lib libac3 libmpeg2 opendivx encore libvo loader drivers drivers/syncfb ; do $(MAKE) -C $$a distclean ; done
+ makedepend
+ rm -f *~ $(PRG) $(PRG_AVIP) $(PRG_TV) $(OBJS) *.o *.a Makefile.bak
+
+dep: depend
+
+depend:
+ @for a in mp3lib libac3 libmpeg2 libvo opendivx encore ; do $(MAKE) -C $$a dep ; done
+# cd loader;make dep;cd ..
+ makedepend -- $(CFLAGS) -- mplayer.c aviparse.c tvision.c $(SRCS) &>/dev/null
+
+# DO NOT DELETE
diff --git a/TOOLS/GL-test/compile.sh b/TOOLS/GL-test/compile.sh
new file mode 100755
index 0000000000..2bb40def0a
--- /dev/null
+++ b/TOOLS/GL-test/compile.sh
@@ -0,0 +1,2 @@
+
+gcc -g -O4 gltest.c ../../linux/timer-lx.o -o gltest -L/usr/X11/lib -lglut -lGL -lGLU -lX11 -lXext -lXmu -lXi -lm
diff --git a/TOOLS/GL-test/gltest.c b/TOOLS/GL-test/gltest.c
new file mode 100644
index 0000000000..e8c6d33146
--- /dev/null
+++ b/TOOLS/GL-test/gltest.c
@@ -0,0 +1,189 @@
+// OpenGL glTexSubImage() test/benchmark prg (C) 2001. by A'rpi/ESP-team
+
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <inttypes.h>
+
+// pixel size: 3 or 4
+#define BYTES_PP 3
+
+// blit by lines (defined) or frames (not defined)
+#define FAST_BLIT
+
+static uint32_t image_width=720; // DVD size
+static uint32_t image_height=576;
+
+static uint32_t image_format;
+static uint32_t image_bpp;
+static uint32_t image_bytes;
+
+static uint32_t texture_width=512;
+static uint32_t texture_height=512;
+
+static unsigned char *ImageData=NULL;
+
+static GLvoid resize(int x,int y){
+ printf("Resize: %dx%d\n",x,y);
+ glViewport( 0, 0, x, y );
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, image_width, image_height, 0, -1,1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+float akarmi=0;
+
+int counter=0;
+float gen_time=0;
+float up_time=0;
+float render_time=0;
+
+unsigned char sintable[4096];
+
+extern float GetRelativeTime();
+
+static void redraw(void)
+{
+// glClear(GL_COLOR_BUFFER_BIT);
+ int x,y,i;
+ unsigned char *d=ImageData;
+ int dstride=BYTES_PP*image_width;
+
+ GetRelativeTime();
+
+ // generate some image:
+ for(y=0;y<image_height;y++){
+ int y1=2048*sin(akarmi*0.36725+y*0.0165);
+ int y2=2048*sin(akarmi*0.45621+y*0.02753);
+ int y3=2048*sin(akarmi*0.15643+y*0.03732);
+ for(x=0;x<image_width;x++){
+ d[0]=sintable[(y1+x*135)&4095];
+ d[1]=sintable[(y2+x*62)&4095];
+ d[2]=sintable[(y3+x*23)&4095];
+ d+=BYTES_PP;
+ }
+ }
+
+ gen_time+=GetRelativeTime();
+
+#ifdef FAST_BLIT
+ // upload texture:
+ for(i=0;i<image_height;i++){
+ glTexSubImage2D( GL_TEXTURE_2D, // target
+ 0, // level
+ 0, // x offset
+ i, // y offset
+ image_width, // width
+ 1, // height
+ (BYTES_PP==4)?GL_RGBA:GL_RGB, // format
+ GL_UNSIGNED_BYTE, // type
+ ImageData+i*dstride ); // *pixels
+ }
+#else
+ glTexSubImage2D( GL_TEXTURE_2D, // target
+ 0, // level
+ 0, // x offset
+ 0, // y offset
+ image_width, // width
+ image_height, // height
+ (BYTES_PP==4)?GL_RGBA:GL_RGB, // format
+ GL_UNSIGNED_BYTE, // type
+ ImageData ); // *pixels
+#endif
+
+ up_time+=GetRelativeTime();
+
+ glColor3f(1,1,1);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0,0);glVertex2i(0,0);
+ glTexCoord2f(0,1);glVertex2i(0,texture_height);
+ glTexCoord2f(1,1);glVertex2i(texture_width,texture_height);
+ glTexCoord2f(1,0);glVertex2i(texture_width,0);
+ glEnd();
+
+ glFinish();
+ glutSwapBuffers();
+
+ render_time+=GetRelativeTime();
+
+ ++counter;
+ { float total=gen_time+up_time+render_time;
+ if(total>2.0){
+ printf("%8.3f fps (gen: %2d%% upload: %2d%% render: %2d%%)\n",
+ (float)counter/total,
+ (int)(100.0*gen_time/total),
+ (int)(100.0*up_time/total),
+ (int)(100.0*render_time/total)
+ );
+ gen_time=up_time=render_time=0;
+ counter=0;
+ } }
+
+}
+
+static GLvoid IdleFunc(){
+ akarmi+=0.1;
+ glutPostRedisplay();
+}
+
+int
+main(int argc, char **argv)
+{
+ int i;
+
+ glutInit(&argc, argv);
+ glutInitWindowSize(640, 480);
+ glutInitDisplayMode(GLUT_DOUBLE);
+ (void) glutCreateWindow("csg");
+
+ glutDisplayFunc(redraw);
+ glutReshapeFunc(resize);
+ glutIdleFunc(IdleFunc);
+
+ texture_width=32;
+ while(texture_width<image_width) texture_width*=2;
+ while(texture_width<image_height) texture_width*=2;
+ texture_height=texture_width;
+
+ image_bpp=8*BYTES_PP;
+ image_bytes=BYTES_PP;
+
+ ImageData=malloc(texture_width*texture_height*image_bytes);
+ memset(ImageData,128,texture_width*texture_height*image_bytes);
+
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDisable(GL_CULL_FACE);
+
+ glEnable(GL_TEXTURE_2D);
+
+ printf("Creating %dx%d texture...\n",texture_width,texture_height);
+
+#if 1
+// glBindTexture(GL_TEXTURE_2D, texture_id);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+#ifdef TEXTUREFORMAT_32BPP
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture_width, texture_height, 0,
+#else
+ glTexImage2D(GL_TEXTURE_2D, 0, BYTES_PP, texture_width, texture_height, 0,
+#endif
+ (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, ImageData);
+#endif
+
+ resize(640,480);
+
+ glClearColor( 1.0f,0.0f,1.0f,0.0f );
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ for(i=0;i<4096;i++) sintable[i]=128+127*sin(2.0*3.14159265*i/4096.0);
+
+ glutMainLoop();
+ return 0; /* ANSI C requires main to return int. */
+}
diff --git a/TOOLS/asfinfo.c b/TOOLS/asfinfo.c
new file mode 100644
index 0000000000..3e26bfe18a
--- /dev/null
+++ b/TOOLS/asfinfo.c
@@ -0,0 +1,255 @@
+#define SAVE_STREAMS
+
+// simple ASF header display program by A'rpi/ESP-team
+// .asf fileformat docs from http://divx.euro.ru
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct __attribute__((packed))
+{
+ long biSize; // sizeof(BITMAPINFOHEADER)
+ long biWidth;
+ long biHeight;
+ short biPlanes; // unused
+ short biBitCount;
+ long biCompression; // fourcc of image
+ long biSizeImage; // size of image. For uncompressed images
+ // ( biCompression 0 or 3 ) can be zero.
+
+
+ long biXPelsPerMeter; // unused
+ long biYPelsPerMeter; // unused
+ long biClrUsed; // valid only for palettized images.
+ // Number of colors in palette.
+ long biClrImportant;
+} BITMAPINFOHEADER;
+
+typedef struct
+{
+ short wFormatTag; // value that identifies compression format
+ short nChannels;
+ long nSamplesPerSec;
+ long nAvgBytesPerSec;
+ short nBlockAlign; // size of a data sample
+ short wBitsPerSample;
+ short cbSize; // size of format-specific data
+} WAVEFORMATEX;
+
+typedef struct __attribute__((packed)) {
+ unsigned char guid[16];
+ unsigned long long size;
+} ASF_obj_header_t;
+
+typedef struct __attribute__((packed)) {
+ ASF_obj_header_t objh;
+ unsigned int cno; // number of subchunks
+ unsigned char v1; // unknown (0x01)
+ unsigned char v2; // unknown (0x02)
+} ASF_header_t;
+
+typedef struct __attribute__((packed)) {
+ unsigned char client[16]; // Client GUID
+ unsigned long long file_size;
+ unsigned long long creat_time; //File creation time FILETIME 8
+ unsigned long long packets; //Number of packets UINT64 8
+ unsigned long long end_timestamp; //Timestamp of the end position UINT64 8
+ unsigned long long duration; //Duration of the playback UINT64 8
+ unsigned long start_timestamp; //Timestamp of the start position UINT32 4
+ unsigned long unk1; //Unknown, maybe reserved ( usually contains 0 ) UINT32 4
+ unsigned long flags; //Unknown, maybe flags ( usually contains 2 ) UINT32 4
+ unsigned long packetsize; //Size of packet, in bytes UINT32 4
+ unsigned long packetsize2; //Size of packet ( confirm ) UINT32 4
+ unsigned long frame_size; //Size of uncompressed video frame UINT32 4
+} ASF_file_header_t;
+
+typedef struct __attribute__((packed)) {
+ unsigned char type[16]; // Stream type (audio/video) GUID 16
+ unsigned char concealment[16]; // Audio error concealment type GUID 16
+ unsigned long long unk1; // Unknown, maybe reserved ( usually contains 0 ) UINT64 8
+ unsigned long type_size; //Total size of type-specific data UINT32 4
+ unsigned long stream_size; //Size of stream-specific data UINT32 4
+ unsigned short stream_no; //Stream number UINT16 2
+ unsigned long unk2; //Unknown UINT32 4
+} ASF_stream_header_t;
+
+typedef struct __attribute__((packed)) {
+ unsigned char streamno;
+ unsigned char seq;
+ unsigned long x;
+ unsigned char flag;
+} ASF_segmhdr_t;
+
+
+ASF_header_t asfh;
+ASF_obj_header_t objh;
+ASF_file_header_t fileh;
+ASF_stream_header_t streamh;
+unsigned char buffer[8192];
+
+int i;
+
+char* chunk_type(unsigned char* guid){
+ switch(*((unsigned int*)guid)){
+ case 0xF8699E40: return "guid_audio_stream";
+ case 0xBC19EFC0: return "guid_video_stream";
+ case 0x49f1a440: return "guid_audio_conceal_none";
+ case 0xbfc3cd50: return "guid_audio_conceal_interleave";
+ case 0x75B22630: return "guid_header";
+ case 0x75b22636: return "guid_data_chunk";
+ case 0x33000890: return "guid_index_chunk";
+ case 0xB7DC0791: return "guid_stream_header";
+ case 0xD6E229D1: return "guid_header_2_0";
+ case 0x8CABDCA1: return "guid_file_header";
+ }
+ return NULL;
+}
+
+void print_wave_header(WAVEFORMATEX *h){
+
+ printf("======= WAVE Format =======\n");
+
+ printf("Format Tag: %d (0x%X)\n",h->wFormatTag,h->wFormatTag);
+ printf("Channels: %d\n",h->nChannels);
+ printf("Samplerate: %d\n",h->nSamplesPerSec);
+ printf("avg byte/sec: %d\n",h->nAvgBytesPerSec);
+ printf("Block align: %d\n",h->nBlockAlign);
+ printf("bits/sample: %d\n",h->wBitsPerSample);
+ printf("cbSize: %d\n",h->cbSize);
+
+ switch(h->wFormatTag){
+ case 0x01: printf("Audio in PCM format\n");break;
+ case 0x50: printf("Audio in MPEG Layer 1/2 format\n");break;
+ case 0x55: printf("Audio in MPEG Layer-3 format\n");break; // ACM
+ case 0x02: printf("Audio in MS ADPCM format\n");break; // ACM
+ case 0x11: printf("Audio in IMA ADPCM format\n");break; // ACM
+ case 0x31:
+ case 0x32: printf("Audio in MS GSM 6.10 format\n");break; // ACM
+ case 0x160:
+ case 0x161: printf("Audio in DivX WMA format\n");break; // ACM
+ default: printf("Audio in UNKNOWN (id=0x%X) format\n",h->wFormatTag);
+ }
+
+ printf("===========================\n");
+
+
+}
+
+void print_video_header(BITMAPINFOHEADER *h){
+ printf("======= VIDEO Format ======\n");
+ printf(" biSize %d\n", h->biSize);
+ printf(" biWidth %d\n", h->biWidth);
+ printf(" biHeight %d\n", h->biHeight);
+ printf(" biPlanes %d\n", h->biPlanes);
+ printf(" biBitCount %d\n", h->biBitCount);
+ printf(" biCompression %d='%.4s'\n", h->biCompression, &h->biCompression);
+ printf(" biSizeImage %d\n", h->biSizeImage);
+ printf("===========================\n");
+}
+
+FILE* streams[128];
+
+int main(int argc,char* argv[]){
+FILE *f=fopen(argc>1?argv[1]:"Alice Deejay - Back In My Life.asf","rb");
+
+if(!f){ printf("file not found\n");exit(1);}
+
+//printf("sizeof=%d\n",sizeof(objh));
+//printf("sizeof=%d\n",sizeof(asfh));
+
+fread(&asfh,sizeof(asfh),1,f); // header obj
+//for(i=0;i<16;i++) printf("%02X ",asfh.objh.guid[i]);
+printf("[%s] %d (subchunks: %d)\n",chunk_type(asfh.objh.guid),(int) asfh.objh.size,asfh.cno);
+
+while(fread(&objh,sizeof(objh),1,f)>0){
+ int pos=ftell(f);
+// for(i=0;i<16;i++) printf("%02X ",objh.guid[i]);
+ printf("0x%08X [%s] %d\n",pos-sizeof(objh), chunk_type(objh.guid),(int) objh.size);
+ switch(*((unsigned int*)&objh.guid)){
+ case 0xB7DC0791: // guid_stream_header
+ fread(&streamh,sizeof(streamh),1,f);
+ printf("stream type: %s\n",chunk_type(streamh.type));
+ printf("stream concealment: %s\n",chunk_type(streamh.concealment));
+ printf("type: %d bytes, stream: %d bytes ID: %d\n",(int)streamh.type_size,(int)streamh.stream_size,(int)streamh.stream_no);
+ printf("FILEPOS=0x%X\n",ftell(f));
+ // type-specific data:
+ fread(buffer,streamh.type_size,1,f);
+ switch(*((unsigned int*)&streamh.type)){
+ case 0xF8699E40: // guid_audio_stream
+ print_wave_header((WAVEFORMATEX*)buffer);
+ break;
+ case 0xBC19EFC0: // guid_video_stream
+ print_video_header((BITMAPINFOHEADER*)&buffer[4+4+1+2]);
+ break;
+ }
+ // stream-specific data:
+ fread(buffer,streamh.stream_size,1,f);
+ break;
+// case 0xD6E229D1: return "guid_header_2_0";
+ case 0x8CABDCA1: // guid_file_header
+ fread(&fileh,sizeof(fileh),1,f);
+ printf("packets: %d flags: %d pack_size: %d frame_size: %d\n",(int)fileh.packets,(int)fileh.flags,(int)fileh.packetsize,(int)fileh.frame_size);
+ break;
+ case 0x75b22636: // guid_data_chunk
+ { int endp=pos+objh.size-sizeof(objh);
+ unsigned char* packet=malloc((int)fileh.packetsize);
+ int fpos;
+ fseek(f,26,SEEK_CUR);
+ while((fpos=ftell(f))<endp){
+ fread(packet,(int)fileh.packetsize,1,f);
+ if(packet[0]==0x82){
+ unsigned char flags=packet[3];
+ unsigned char* p=&packet[5];
+ unsigned long time;
+ unsigned short duration;
+ int segs=1;
+ int seg;
+ int padding=0;
+ if(flags&8){
+ padding=p[0];++p;
+ } else
+ if(flags&16){
+ padding=p[0]|(p[1]<<8);p+=2;
+ }
+ time=*((unsigned long*)p);p+=4;
+ duration=*((unsigned short*)p);p+=2;
+ if(flags&1){
+ segs=p[0]-0x80;++p;
+ }
+ printf("%08X: flag=%02X segs=%d pad=%d time=%d dur=%d\n",
+ fpos,flags,segs,padding,time,duration);
+ for(seg=0;seg<segs;seg++){
+ ASF_segmhdr_t* sh=(ASF_segmhdr_t*)p;
+ int len=0;
+ p+=sizeof(ASF_segmhdr_t);
+ if(sh->flag&8) p+=8;// else
+ if(sh->flag&1) ++p;
+ if(flags&1){
+ len=*((unsigned short*)p);p+=2;
+ }
+ printf(" seg #%d: streamno=%d seq=%d flag=%02X len=%d\n",seg,sh->streamno&0x7F,sh->seq,sh->flag,len);
+#ifdef SAVE_STREAMS
+ if(!streams[sh->streamno&0x7F]){
+ char name[256];
+ sprintf(name,"stream%02X.dat",sh->streamno&0x7F);
+ streams[sh->streamno&0x7F]=fopen(name,"wb");
+ }
+ fwrite(p,len,1,streams[sh->streamno&0x7F]);
+#endif
+ p+=len;
+ }
+ } else
+ printf("%08X: UNKNOWN %02X %02X %02X %02X %02X...\n",fpos,packet[0],packet[1],packet[2],packet[3],packet[4]);
+ }
+ }
+ break;
+
+// case 0x33000890: return "guid_index_chunk";
+
+ }
+ fseek(f,pos+objh.size-sizeof(objh),SEEK_SET);
+}
+
+
+}
+
diff --git a/TOOLS/c b/TOOLS/c
new file mode 100755
index 0000000000..5ba26feeb6
--- /dev/null
+++ b/TOOLS/c
@@ -0,0 +1 @@
+gcc movinfo.c -o movinfo
diff --git a/TOOLS/movinfo.c b/TOOLS/movinfo.c
new file mode 100644
index 0000000000..3c3c3ddd9e
--- /dev/null
+++ b/TOOLS/movinfo.c
@@ -0,0 +1,124 @@
+// show QuickTime .mov file structure (C) 2001. by A'rpi/ESP-team
+
+#include <stdio.h>
+#include <stdlib.h>
+
+unsigned int read_dword(FILE *f){
+ unsigned char atom_size_b[4];
+ if(fread(&atom_size_b,4,1,f)<=0) return -1;
+ return (atom_size_b[0]<<24)|(atom_size_b[1]<<16)|(atom_size_b[2]<<8)|atom_size_b[3];
+}
+
+void lschunks(FILE *f,int level,unsigned int endpos){
+ unsigned int atom_size;
+ unsigned int atom_type;
+ int pos;
+ while(endpos==0 || ftell(f)<endpos){
+ pos=ftell(f);
+ atom_size=read_dword(f);// if(fread(&atom_size_b,4,1,f)<=0) break;
+ if(fread(&atom_type,4,1,f)<=0) break;
+
+ if(atom_size<8) break; // error
+
+ printf("%08X: %*s %.4s (%08X) %d\n",pos,level*2,"",&atom_type,atom_type,atom_size);
+
+ if(atom_type==0x64737473) { // stsd
+ unsigned int tmp;
+ unsigned int count;
+ int i;
+ fread(&tmp,4,1,f);
+ count=read_dword(f);// fread(&count,4,1,f);
+ printf("desc count = %d\n",count);
+ for(i=0;i<count;i++){
+ unsigned int len;
+ unsigned int format;
+ len=read_dword(f); // fread(&len,4,1,f);
+ fread(&format,4,1,f);
+ printf(" desc #%d: %.4s (%d)\n",i+1,&format,len);
+ fseek(f,len-8,SEEK_CUR);
+ }
+ }
+
+ if(atom_type==0x6F637473) { // stco
+ int len,i;
+ read_dword(f);
+ len=read_dword(f);
+ printf("Chunk table size :%d\n",len);
+ for(i=0;i<len;i++) printf(" chunk #%d: 0x%X\n",i+1,read_dword(f));
+ }
+
+
+ if(atom_type==0x73747473) { // stts
+ int len,i;
+ read_dword(f);
+ len=read_dword(f);
+ printf("T->S table size :%d\n",len);
+ for(i=0;i<len;i++){
+ int num=read_dword(f);
+ int dur=read_dword(f);
+ printf("%5d samples: %d duration\n",num,dur);
+ }
+ }
+
+ if(atom_type==0x63737473) { // stsc
+ int len,i;
+ read_dword(f);
+ len=read_dword(f);
+ printf("S->C table size :%d\n",len);
+ for(i=0;i<len;i++){
+ int first=read_dword(f);
+ int spc=read_dword(f);
+ int sdid=read_dword(f);
+ printf(" chunk %d... %d s/c desc: %d\n",first,spc,sdid);
+ }
+ }
+
+ if(atom_type==0x7A737473) { // stsz
+ int len,i,ss;
+ read_dword(f);
+ ss=read_dword(f);
+ len=read_dword(f);
+ printf("Sample size table len: %d\n",len);
+ if(ss){
+ printf(" common sample size: %d bytes\n",ss);
+ } else {
+ for(i=0;i<len;i++) printf(" sample #%d: %d bytes\n",i+1,read_dword(f));
+ }
+ }
+
+
+#if 1
+ switch(atom_type){
+ case 0x75716D72: // rmqu
+ case 0x65657266: // free JUNK
+ case 0x64686B74: // tkhd Track header
+ case 0x61746475: // udta User data
+ case 0x7461646D: // mdat Movie data
+ case 0x64737473: // stsd Sample description
+ case 0x6F637473: // stco Chunk offset table
+ case 0x73747473: // stts Sample time table
+ case 0x63737473: // stsc Sample->Chunk mapping table
+ case 0x7A737473: // stsz Sample size table
+ break;
+ default: lschunks(f,level+1,pos+atom_size);
+ }
+#else
+ switch(atom_type){
+ case 0x766F6F6D: // moov
+ case 0x61726D72: // rmra
+ case 0x61646D72: // rmda
+ lschunks(f,level+1,pos+atom_size);
+ }
+#endif
+ fseek(f,pos+atom_size,SEEK_SET);
+ }
+}
+
+int main(int argc,char* argv[]){
+int pos;
+FILE *f=fopen(argc>1?argv[1]:"Akira.mov","rb");
+if(!f) return 1;
+
+lschunks(f,0,0);
+
+}
diff --git a/TVout/Mon-640x400 b/TVout/Mon-640x400
new file mode 100755
index 0000000000..84238371cb
--- /dev/null
+++ b/TVout/Mon-640x400
@@ -0,0 +1,3 @@
+
+fbset/fbset -fb /dev/fb1 -db fbset.db 640x400-60
+
diff --git a/TVout/Mon-640x480 b/TVout/Mon-640x480
new file mode 100755
index 0000000000..6d7d257b8e
--- /dev/null
+++ b/TVout/Mon-640x480
@@ -0,0 +1,3 @@
+
+fbset/fbset -fb /dev/fb1 -db fbset.db 640x480-60
+
diff --git a/TVout/TV-640x512 b/TVout/TV-640x512
new file mode 100755
index 0000000000..aa3924e27a
--- /dev/null
+++ b/TVout/TV-640x512
@@ -0,0 +1,2 @@
+
+fbset/fbset -fb /dev/fb0 -left 60 -right 0 -upper 70 -lower 39 -hslen 76 -vslen 4 -xres 640 -yres 512 -bcast true
diff --git a/TVout/TV-640x528 b/TVout/TV-640x528
new file mode 100755
index 0000000000..6edeb82164
--- /dev/null
+++ b/TVout/TV-640x528
@@ -0,0 +1,3 @@
+
+fbset/fbset -fb /dev/fb0 -left 40 -right 0 -upper 63 -lower 29 -hslen 56 -vslen 4 -xres 640 -yres 528 -vxres 640 -vyres 528 -depth 32 -laced false -bcast true
+
diff --git a/TVout/TV-704x528 b/TVout/TV-704x528
new file mode 100755
index 0000000000..2554239e10
--- /dev/null
+++ b/TVout/TV-704x528
@@ -0,0 +1,3 @@
+
+fbset/fbset -fb /dev/fb0 -left 40 -right 0 -upper 63 -lower 29 -hslen 56 -vslen 4 -xres 640 -yres 528 -vxres 704 -vyres 528 -depth 32 -laced false -bcast true
+
diff --git a/TVout/TV-704x576 b/TVout/TV-704x576
new file mode 100755
index 0000000000..9585e6e5f1
--- /dev/null
+++ b/TVout/TV-704x576
@@ -0,0 +1,3 @@
+
+fbset/fbset -fb /dev/fb0 -left 42 -right 0 -upper 29 -lower 20 -hslen 46 -vslen 4 -xres 704 -yres 576 -vxres 704 -vyres 576 -depth 32 -laced false -bcast true
+
diff --git a/TVout/TV-720x576 b/TVout/TV-720x576
new file mode 100755
index 0000000000..fb5272a8c3
--- /dev/null
+++ b/TVout/TV-720x576
@@ -0,0 +1,3 @@
+
+fbset/fbset -fb /dev/fb0 -left 18 -right 0 -upper 39 -lower 10 -hslen 46 -vslen 4 -xres 720 -yres 576 -vxres 720 -vyres 576 -depth 32 -laced false -bcast true
+
diff --git a/TVout/clean.sh b/TVout/clean.sh
new file mode 100755
index 0000000000..56d7fd13b6
--- /dev/null
+++ b/TVout/clean.sh
@@ -0,0 +1,13 @@
+
+# Compile TVout tools
+
+rm -f con2fb/con2fb
+
+cd matroxset
+make clean
+cd ..
+
+cd fbset
+make clean
+cd ..
+
diff --git a/TVout/cloning b/TVout/cloning
new file mode 100755
index 0000000000..c8c545c254
--- /dev/null
+++ b/TVout/cloning
@@ -0,0 +1,14 @@
+
+# SETUP TVout
+# Same picture on TV & Monitor
+
+# CRTC1 -> TVout & Monitor
+matroxset/matroxset -f /dev/fb1 -m 0
+matroxset/matroxset -f /dev/fb0 -m 3
+
+# Enable TV
+matroxset/matroxset 1
+
+# Keep consoles on CRTC1
+con2fb/con2fb /dev/fb0 /dev/tty1
+con2fb/con2fb /dev/fb0 /dev/tty2
diff --git a/TVout/compile.sh b/TVout/compile.sh
new file mode 100755
index 0000000000..51160101bd
--- /dev/null
+++ b/TVout/compile.sh
@@ -0,0 +1,15 @@
+
+# Compile TVout tools
+
+cd con2fb
+gcc con2fb.c -o con2fb
+cd ..
+
+cd matroxset
+make
+cd ..
+
+cd fbset
+make
+cd ..
+
diff --git a/TVout/con2fb/con2fb.c b/TVout/con2fb/con2fb.c
new file mode 100644
index 0000000000..8ca7a9deaa
--- /dev/null
+++ b/TVout/con2fb/con2fb.c
@@ -0,0 +1,79 @@
+/* this is userspace utility which allows you to redirect console to another fb device
+ * You can specify devices & consoles by both numbers and devices. Framebuffers numbers
+ * are zero based (/dev/fb0 ... ), consoles begins with 1 (/dev/tty1 ... )
+ */
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char* argv[]) {
+ struct fb_con2fbmap c2m;
+ char* fbPath;
+ u_int32_t con, fb;
+ char* e;
+ char* progname = strrchr(argv[0], '/');
+ int f;
+
+ if (progname)
+ progname++;
+ else
+ progname = argv[0];
+ if (argc < 3) {
+ fprintf(stderr, "usage: %s fbdev console\n", progname);
+ return 1;
+ }
+ fb = strtoul(argv[1], &e, 10);
+ if (*e) {
+ struct stat sbf;
+
+ if (stat(argv[1], &sbf)) {
+ fprintf(stderr, "%s: are you sure that %s can be used to describe fbdev?\n", progname, argv[1]);
+ return 1;
+ }
+ if (!S_ISCHR(sbf.st_mode)) {
+ fprintf(stderr, "%s: %s must be character device\n", progname, argv[1]);
+ return 1;
+ }
+ fb = sbf.st_rdev & 0xFF;
+ if (fb >= 32)
+ fb >>= 5;
+ fbPath = argv[1];
+ } else
+ fbPath = "/dev/fb0";
+ con = strtoul(argv[2], &e, 10);
+ if (*e) {
+ struct stat sbf;
+
+ if (stat(argv[2], &sbf)) {
+ fprintf(stderr, "%s: are you sure that %s can be used to describe vt?\n", progname, argv[2]);
+ return 1;
+ }
+ if (!S_ISCHR(sbf.st_mode)) {
+ fprintf(stderr, "%s: %s must be character device\n", progname, argv[2]);
+ return 1;
+ }
+ con = sbf.st_rdev & 0xFF;
+ }
+ c2m.console = con;
+ c2m.framebuffer = fb;
+ f = open(fbPath, O_RDWR);
+ if (f < 0) {
+ fprintf(stderr, "%s: Cannot open %s\n", progname, fbPath);
+ return 1;
+ }
+ if (ioctl(f, FBIOPUT_CON2FBMAP, &c2m)) {
+ fprintf(stderr, "%s: Cannot set console mapping\n", progname);
+ close(f);
+ return 1;
+ }
+ close(f);
+ return 0;
+}
+
+
diff --git a/TVout/fbset.db b/TVout/fbset.db
new file mode 100644
index 0000000000..0dff5fb377
--- /dev/null
+++ b/TVout/fbset.db
@@ -0,0 +1,34 @@
+
+# FBset mode database
+
+mode "640x480" # H: 33.78 kHz, V: 67.56 Hz
+ geometry 640 480 640 480 4
+ timings 35242 24 64 17 1 112 2
+endmode
+
+mode "640x480-60"
+ # D: 25.176 MHz, H: 31.469 kHz, V: 59.942 Hz
+ geometry 640 480 640 480 16
+ timings 39721 48 16 33 10 96 2
+ hsync high
+ accel true
+# rgba 5/11,6/5,5/0,0/0
+endmode
+
+mode "640x400-60"
+ # D: 25.176 MHz, H: 31.469 kHz, V: 59.942 Hz
+ geometry 640 400 640 400 16
+ timings 39721 48 16 33 10 96 2
+ hsync high
+ accel true
+# rgba 5/11,6/5,5/0,0/0
+endmode
+
+mode "vga70"
+ # H: 31.113 kHz, V: 69.294 Hz
+ geometry 640 400 640 400 4
+ timings 35242 64 96 35 12 112 2
+# vsync high
+# csync high
+endmode
+
diff --git a/TVout/fbset/INSTALL b/TVout/fbset/INSTALL
new file mode 100644
index 0000000000..87780aa30d
--- /dev/null
+++ b/TVout/fbset/INSTALL
@@ -0,0 +1,20 @@
+
+
+ FBSET INSTALLATION GUIDE
+
+
+Change the current directory to the directory containing the fbset sources and
+type
+
+ make install
+
+This will create the fbset binary and install it, together with the manual
+pages. It also creates the standard frame buffer special device nodes.
+
+
+The etc subdirectory contains sample frame buffer mode definitions files. Copy
+one of them to /etc/fb.modes and edit it to your needs.
+
+
+Enjoy!
+
diff --git a/TVout/fbset/Makefile b/TVout/fbset/Makefile
new file mode 100644
index 0000000000..3a71024b01
--- /dev/null
+++ b/TVout/fbset/Makefile
@@ -0,0 +1,41 @@
+#
+# Linux Frame Buffer Device Configuration
+#
+
+CC = gcc -Wall -O2 -I.
+BISON = bison -d
+FLEX = flex
+INSTALL = install
+RM = rm -f
+
+All: fbset
+
+
+fbset: fbset.o modes.tab.o lex.yy.o
+
+fbset.o: fbset.c fbset.h fb.h
+modes.tab.o: modes.tab.c fbset.h fb.h
+lex.yy.o: lex.yy.c fbset.h modes.tab.h
+
+lex.yy.c: modes.l
+ $(FLEX) modes.l
+
+modes.tab.c: modes.y
+ $(BISON) modes.y
+
+install: fbset
+ if [ -f /sbin/fbset ]; then rm /sbin/fbset; fi
+ $(INSTALL) fbset /usr/sbin
+ $(INSTALL) fbset.8 /usr/man/man8
+ $(INSTALL) fb.modes.5 /usr/man/man5
+ if [ ! -c /dev/fb0 ]; then mknod /dev/fb0 c 29 0; fi
+ if [ ! -c /dev/fb1 ]; then mknod /dev/fb1 c 29 32; fi
+ if [ ! -c /dev/fb2 ]; then mknod /dev/fb2 c 29 64; fi
+ if [ ! -c /dev/fb3 ]; then mknod /dev/fb3 c 29 96; fi
+ if [ ! -c /dev/fb4 ]; then mknod /dev/fb4 c 29 128; fi
+ if [ ! -c /dev/fb5 ]; then mknod /dev/fb5 c 29 160; fi
+ if [ ! -c /dev/fb6 ]; then mknod /dev/fb6 c 29 192; fi
+ if [ ! -c /dev/fb7 ]; then mknod /dev/fb7 c 29 224; fi
+
+clean:
+ $(RM) *.o fbset lex.yy.c modes.tab.c modes.tab.h
diff --git a/TVout/fbset/fb.h b/TVout/fbset/fb.h
new file mode 100644
index 0000000000..b901d9e204
--- /dev/null
+++ b/TVout/fbset/fb.h
@@ -0,0 +1,497 @@
+#ifndef _LINUX_FB_H
+#define _LINUX_FB_H
+
+#include <asm/types.h>
+
+/* Definitions of frame buffers */
+
+#define FB_MAJOR 29
+
+#define FB_MODES_SHIFT 5 /* 32 modes per framebuffer */
+#define FB_NUM_MINORS 256 /* 256 Minors */
+#define FB_MAX (FB_NUM_MINORS / (1 << FB_MODES_SHIFT))
+#define GET_FB_IDX(node) (MINOR(node) >> FB_MODES_SHIFT)
+
+/* ioctls
+ 0x46 is 'F' */
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOPUT_VSCREENINFO 0x4601
+#define FBIOGET_FSCREENINFO 0x4602
+#define FBIOGETCMAP 0x4604
+#define FBIOPUTCMAP 0x4605
+#define FBIOPAN_DISPLAY 0x4606
+/* 0x4607-0x460B are defined below */
+/* #define FBIOGET_MONITORSPEC 0x460C */
+/* #define FBIOPUT_MONITORSPEC 0x460D */
+/* #define FBIOSWITCH_MONIBIT 0x460E */
+#define FBIOGET_CON2FBMAP 0x460F
+#define FBIOPUT_CON2FBMAP 0x4610
+
+#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+#define FB_TYPE_PLANES 1 /* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FB_TYPE_TEXT 3 /* Text/attributes */
+#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
+
+#define FB_AUX_TEXT_MDA 0 /* Monochrome text */
+#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
+#define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */
+#define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */
+#define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */
+
+#define FB_AUX_VGA_PLANES_VGA4 0 /* 16 color planes (EGA/VGA) */
+#define FB_AUX_VGA_PLANES_CFB4 1 /* CFB4 in planes (VGA) */
+#define FB_AUX_VGA_PLANES_CFB8 2 /* CFB8 in planes (VGA) */
+
+#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR 2 /* True color */
+#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+
+#define FB_ACCEL_NONE 0 /* no hardware accelerator */
+#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
+#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */
+#define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */
+#define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */
+#define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */
+#define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */
+#define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */
+#define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */
+#define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */
+#define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */
+#define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */
+#define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */
+#define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */
+#define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */
+#define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */
+#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */
+#define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */
+#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */
+#define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */
+#define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */
+#define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */
+#define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */
+#define FB_ACCEL_SUN_TCX 25 /* Sun tcx */
+#define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */
+
+struct fb_fix_screeninfo {
+ char id[16]; /* identification string eg "TT Builtin" */
+ char *smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 type_aux; /* Interleave for interleaved Planes */
+ __u32 visual; /* see FB_VISUAL_* */
+ __u16 xpanstep; /* zero if no hardware panning */
+ __u16 ypanstep; /* zero if no hardware panning */
+ __u16 ywrapstep; /* zero if no hardware ywrap */
+ __u32 line_length; /* length of a line in bytes */
+ char *mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ __u32 mmio_len; /* Length of Memory Mapped I/O */
+ __u32 accel; /* Type of acceleration available */
+ __u16 reserved[3]; /* Reserved for future compatibility */
+};
+
+/* Interpretation of offset for color fields: All offsets are from the right,
+ * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+ * can use the offset as right argument to <<). A pixel afterwards is a bit
+ * stream and is written to video memory as that unmodified. This implies
+ * big-endian byte order if bits_per_pixel is greater than 8.
+ */
+struct fb_bitfield {
+ __u32 offset; /* beginning of bitfield */
+ __u32 length; /* length of bitfield */
+ __u32 msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
+
+#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
+#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
+#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */
+#define FB_ACTIVATE_MASK 15
+ /* values */
+#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */
+#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */
+#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */
+
+#define FB_ACCELF_TEXT 1 /* text mode acceleration */
+
+#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
+#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
+#define FB_SYNC_EXT 4 /* external sync */
+#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
+#define FB_SYNC_BROADCAST 16 /* broadcast video timings */
+ /* vtotal = 144d/288n/576i => PAL */
+ /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN 32 /* sync on green */
+
+#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
+#define FB_VMODE_INTERLACED 1 /* interlaced */
+#define FB_VMODE_DOUBLE 2 /* double scan */
+#define FB_VMODE_MASK 255
+
+#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
+#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+
+struct fb_var_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 xres_virtual; /* virtual resolution */
+ __u32 yres_virtual;
+ __u32 xoffset; /* offset from virtual to visible */
+ __u32 yoffset; /* resolution */
+
+ __u32 bits_per_pixel; /* guess what */
+ __u32 grayscale; /* != 0 Graylevels instead of colors */
+
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+
+ __u32 nonstd; /* != 0 Non standard pixel format */
+
+ __u32 activate; /* see FB_ACTIVATE_* */
+
+ __u32 height; /* height of picture in mm */
+ __u32 width; /* width of picture in mm */
+
+ __u32 accel_flags; /* acceleration flags (hints) */
+
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ __u32 pixclock; /* pixel clock in ps (pico seconds) */
+ __u32 left_margin; /* time from sync to picture */
+ __u32 right_margin; /* time from picture to sync */
+ __u32 upper_margin; /* time from sync to picture */
+ __u32 lower_margin;
+ __u32 hsync_len; /* length of horizontal sync */
+ __u32 vsync_len; /* length of vertical sync */
+ __u32 sync; /* see FB_SYNC_* */
+ __u32 vmode; /* see FB_VMODE_* */
+ __u32 reserved[6]; /* Reserved for future compatibility */
+};
+
+struct fb_cmap {
+ __u32 start; /* First entry */
+ __u32 len; /* Number of entries */
+ __u16 *red; /* Red values */
+ __u16 *green;
+ __u16 *blue;
+ __u16 *transp; /* transparency, can be NULL */
+};
+
+struct fb_con2fbmap {
+ __u32 console;
+ __u32 framebuffer;
+};
+
+struct fb_monspecs {
+ __u32 hfmin; /* hfreq lower limit (Hz) */
+ __u32 hfmax; /* hfreq upper limit (Hz) */
+ __u16 vfmin; /* vfreq lower limit (Hz) */
+ __u16 vfmax; /* vfreq upper limit (Hz) */
+ unsigned dpms : 1; /* supports DPMS */
+};
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+
+
+struct fb_info;
+struct fb_info_gen;
+struct vm_area_struct;
+struct file;
+
+ /*
+ * Frame buffer operations
+ */
+
+struct fb_ops {
+ /* open/release and usage marking */
+ int (*fb_open)(struct fb_info *info, int user);
+ int (*fb_release)(struct fb_info *info, int user);
+ /* get non settable parameters */
+ int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+ /* get settable parameters */
+ int (*fb_get_var)(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+ /* set settable parameters */
+ int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+ /* get colormap */
+ int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+ /* set colormap */
+ int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+ /* pan display */
+ int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+ /* perform fb specific ioctl */
+ int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg, int con, struct fb_info *info);
+ /* perform fb specific mmap */
+ int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+ /* switch to/from raster image mode */
+ int (*fb_rasterimg)(struct fb_info *info, int start);
+};
+
+
+ /*
+ * This is the interface between the low-level console driver and the
+ * low-level frame buffer device
+ */
+
+struct display {
+ /* Filled in by the frame buffer device */
+
+ struct fb_var_screeninfo var; /* variable infos. yoffset and vmode */
+ /* are updated by fbcon.c */
+ struct fb_cmap cmap; /* colormap */
+ char *screen_base; /* pointer to top of virtual screen */
+ /* (virtual address) */
+ int visual;
+ int type; /* see FB_TYPE_* */
+ int type_aux; /* Interleave for interleaved Planes */
+ u_short ypanstep; /* zero if no hardware ypan */
+ u_short ywrapstep; /* zero if no hardware ywrap */
+ u_long line_length; /* length of a line in bytes */
+ u_short can_soft_blank; /* zero if no hardware blanking */
+ u_short inverse; /* != 0 text black on white as default */
+ struct display_switch *dispsw; /* low level operations */
+ void *dispsw_data; /* optional dispsw helper data */
+
+#if 0
+ struct fb_fix_cursorinfo fcrsr;
+ struct fb_var_cursorinfo *vcrsr;
+ struct fb_cursorstate crsrstate;
+#endif
+
+ /* Filled in by the low-level console driver */
+
+ struct vc_data *conp; /* pointer to console data */
+ struct fb_info *fb_info; /* frame buffer for this console */
+ int vrows; /* number of virtual rows */
+ unsigned short cursor_x; /* current cursor position */
+ unsigned short cursor_y;
+ int fgcol; /* text colors */
+ int bgcol;
+ u_long next_line; /* offset to one line below */
+ u_long next_plane; /* offset to next plane */
+ u_char *fontdata; /* Font associated to this display */
+ unsigned short _fontheightlog;
+ unsigned short _fontwidthlog;
+ unsigned short _fontheight;
+ unsigned short _fontwidth;
+ int userfont; /* != 0 if fontdata kmalloc()ed */
+ u_short scrollmode; /* Scroll Method */
+ short yscroll; /* Hardware scrolling */
+ unsigned char fgshift, bgshift;
+ unsigned short charmask; /* 0xff or 0x1ff */
+};
+
+
+struct fb_info {
+ char modename[40]; /* default video mode */
+ kdev_t node;
+ int flags;
+#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
+ struct fb_ops *fbops;
+ struct fb_monspecs monspecs;
+ struct display *disp; /* initial display variable */
+ struct vc_data *display_fg; /* Console visible on this display */
+ char fontname[40]; /* default font name */
+ int (*changevar)(int); /* tell console var has changed */
+ int (*switch_con)(int, struct fb_info*);
+ /* tell fb to switch consoles */
+ int (*updatevar)(int, struct fb_info*);
+ /* tell fb to update the vars */
+ void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */
+ /* arg = 0: unblank */
+ /* arg > 0: VESA level (arg-1) */
+
+ /* From here on everything is device dependent */
+};
+
+#ifdef MODULE
+#define FBINFO_FLAG_DEFAULT FBINFO_FLAG_MODULE
+#else
+#define FBINFO_FLAG_DEFAULT 0
+#endif
+
+ /*
+ * This structure abstracts from the underlying hardware. It is not
+ * mandatory but used by the `generic' frame buffer operations.
+ * Read drivers/video/skeletonfb.c for more information.
+ */
+
+struct fbgen_hwswitch {
+ void (*detect)(void);
+ int (*encode_fix)(struct fb_fix_screeninfo *fix, const void *par,
+ struct fb_info_gen *info);
+ int (*decode_var)(const struct fb_var_screeninfo *var, void *par,
+ struct fb_info_gen *info);
+ int (*encode_var)(struct fb_var_screeninfo *var, const void *par,
+ struct fb_info_gen *info);
+ void (*get_par)(void *par, struct fb_info_gen *info);
+ void (*set_par)(const void *par, struct fb_info_gen *info);
+ int (*getcolreg)(unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp, struct fb_info *info);
+ int (*setcolreg)(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info);
+ int (*pan_display)(const struct fb_var_screeninfo *var,
+ struct fb_info_gen *info);
+ int (*blank)(int blank_mode, struct fb_info_gen *info);
+ void (*set_disp)(const void *par, struct display *disp,
+ struct fb_info_gen *info);
+};
+
+struct fb_info_gen {
+ struct fb_info info;
+
+ /* Entries for a generic frame buffer device */
+ /* Yes, this starts looking like C++ */
+ u_int parsize;
+ struct fbgen_hwswitch *fbhw;
+
+ /* From here on everything is device dependent */
+};
+
+ /*
+ * `Generic' versions of the frame buffer device operations
+ */
+
+extern int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+extern int fbgen_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+extern int fbgen_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+extern int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+extern int fbgen_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info);
+
+ /*
+ * Helper functions
+ */
+
+extern int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
+ struct fb_info_gen *info);
+extern void fbgen_set_disp(int con, struct fb_info_gen *info);
+extern void fbgen_install_cmap(int con, struct fb_info_gen *info);
+extern int fbgen_update_var(int con, struct fb_info *info);
+extern int fbgen_switch(int con, struct fb_info *info);
+extern void fbgen_blank(int blank, struct fb_info *info);
+
+
+struct fb_videomode {
+ const char *name;
+ struct fb_var_screeninfo var;
+};
+
+
+/* drivers/char/fbmem.c */
+extern int register_framebuffer(struct fb_info *fb_info);
+extern int unregister_framebuffer(const struct fb_info *fb_info);
+extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
+ const struct fb_info *fb_info);
+extern int fbmon_dpms(const struct fb_info *fb_info);
+
+
+extern int num_registered_fb;
+extern struct fb_info *registered_fb[FB_MAX];
+extern char con2fb_map[MAX_NR_CONSOLES];
+
+/* drivers/video/fbcon.c */
+extern struct display fb_display[MAX_NR_CONSOLES];
+
+/* drivers/video/fbcmap.c */
+extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
+ int fsfromto);
+extern int fb_get_cmap(struct fb_cmap *cmap, int kspc,
+ int (*getcolreg)(u_int, u_int *, u_int *, u_int *,
+ u_int *, struct fb_info *),
+ struct fb_info *fb_info);
+extern int fb_set_cmap(struct fb_cmap *cmap, int kspc,
+ int (*setcolreg)(u_int, u_int, u_int, u_int, u_int,
+ struct fb_info *),
+ struct fb_info *fb_info);
+extern struct fb_cmap *fb_default_cmap(int len);
+extern void fb_invert_cmaps(void);
+
+/* VESA Blanking Levels */
+#define VESA_NO_BLANKING 0
+#define VESA_VSYNC_SUSPEND 1
+#define VESA_HSYNC_SUSPEND 2
+#define VESA_POWERDOWN 3
+
+#endif /* __KERNEL__ */
+
+#if 1
+
+#define FBCMD_GET_CURRENTPAR 0xDEAD0005
+#define FBCMD_SET_CURRENTPAR 0xDEAD8005
+
+#endif
+
+
+#if 1 /* Preliminary */
+
+ /*
+ * Hardware Cursor
+ */
+
+#define FBIOGET_FCURSORINFO 0x4607
+#define FBIOGET_VCURSORINFO 0x4608
+#define FBIOPUT_VCURSORINFO 0x4609
+#define FBIOGET_CURSORSTATE 0x460A
+#define FBIOPUT_CURSORSTATE 0x460B
+
+
+struct fb_fix_cursorinfo {
+ __u16 crsr_width; /* width and height of the cursor in */
+ __u16 crsr_height; /* pixels (zero if no cursor) */
+ __u16 crsr_xsize; /* cursor size in display pixels */
+ __u16 crsr_ysize;
+ __u16 crsr_color1; /* colormap entry for cursor color1 */
+ __u16 crsr_color2; /* colormap entry for cursor color2 */
+};
+
+struct fb_var_cursorinfo {
+ __u16 width;
+ __u16 height;
+ __u16 xspot;
+ __u16 yspot;
+ __u8 data[1]; /* field with [height][width] */
+};
+
+struct fb_cursorstate {
+ __s16 xoffset;
+ __s16 yoffset;
+ __u16 mode;
+};
+
+#define FB_CURSOR_OFF 0
+#define FB_CURSOR_ON 1
+#define FB_CURSOR_FLASH 2
+
+#endif /* Preliminary */
+
+#endif /* _LINUX_FB_H */
diff --git a/TVout/fbset/fb.modes.5 b/TVout/fbset/fb.modes.5
new file mode 100644
index 0000000000..0918f08f5d
--- /dev/null
+++ b/TVout/fbset/fb.modes.5
@@ -0,0 +1,228 @@
+.TH fb.modes 8 "Aug 1996" local "Linux frame buffer utils"
+.SH NAME
+fb.modes \- frame buffer modes file
+.SH DESCRIPTION
+.I /etc/fb.modes
+contains an unlimited number of video mode descriptions. The general format
+of a video mode is:
+.sp
+mode
+.RI \" name \"
+.RS
+geometry
+.RI < xres >
+.RI < yres >
+.RI < vxres >
+.RI < vyres >
+.RI < depth >
+.br
+timings
+.RI < pixclock >
+.RI < left >
+.RI < right >
+.RI < upper >
+.RI < lower >
+.RI < hslen >
+.RI < vslen >
+.br
+.B options
+.RI < value >
+.RE
+endmode
+.SH OPTIONS
+geometry options:
+.RS
+.TP
+.I xres
+visible horizontal resolution (in pixels)
+.TP
+.I yres
+visible vertical resolution (in pixels)
+.TP
+.I vxres
+virtual horizontal resolution (in pixels)
+.TP
+.I vyres
+virtual vertical resolution (in pixels)
+.TP
+.I depth
+display depth (in bits per pixel)
+.RE
+.PP
+timing options:
+.RS
+.TP
+.I pixclock
+length of one pixel (in picoseconds)
+.TP
+.I left
+left margin (in pixels)
+.TP
+.I right
+right margin (in pixels)
+.TP
+.I upper
+upper margin (in pixel lines)
+.TP
+.I lower
+lower margin (in pixel lines)
+.TP
+.I hslen
+horizontal sync length (in pixels)
+.TP
+.I vslen
+vertical sync length (in pixel lines)
+.RE
+.PP
+other options:
+.RS
+the first value of this options is the default
+.TP
+.IR \fBhsync "\ {" low | high }
+the horizontal sync polarity
+.TP
+.IR \fBvsync "\ {" low | high }
+the vertical sync polarity
+.TP
+.IR \fBcsync "\ {" low | high }
+the composite sync polarity
+.TP
+.IR \fBextsync "\ {" false | true }
+enable or disable external resync. If enabled the sync timings are not
+generated by the frame buffer device and must be provided externally
+instead. Note that this option may not be supported by every frame buffer
+device
+.TP
+.IR \fBlaced "\ {" false | true }
+enable or disable interlace. If enabled the display will be split in two
+frames, each frame contains only even and odd lines respectively. These two
+frames will be displayed alternating, this way twice the lines can be
+displayed and the vertical frequency for monitor stays the same, but the
+visible vertical frequency gets halved
+.TP
+.IR \fBdouble "\ {" false | true }
+enable or disable doublescan. If enabled every line will be displayed twice
+and this way the horizontal frequency can easily be doubled, so that the
+same resolution can be displayed on different monitors, even if the
+horizontal frequency specification differs. Note that this option may not be
+supported by every frame buffer device
+.RE
+.SH INTERNALS
+Generally a frame buffer display is organized as follows:
+.sp
+.ad c
++\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+\-\-\-+
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " ^ "\ \ \ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " | "\ " \fI5 "\ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " v "\ \ \ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
++\-\-\-#################\-\-\-+\-\-\-+
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " ^ "\ \ \ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " | "\ \ \ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " | "\ \ \ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
+.RI "| " 1 " # " \fB| " " 2 " # " 3 " | " 4 " |"
+.br
+.RB "|" "<\->" "#" "<\-\-\-\-\-\-+\-\-\-\-\-\->" "#" "<\->" "|" "<\->" "|"
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " | "\ \ \ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " | "\ " \fI6 "\ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " | "\ \ \ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ #\ \ \ \ \ \ \ " v "\ \ \ \ \ \ \ #\ \ \ |\ \ \ |"
+.br
++\-\-\-#################\-\-\-+\-\-\-+
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " ^ "\ \ \ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " | "\ " \fI7 "\ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " v "\ \ \ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
++\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+\-\-\-+
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " ^ "\ \ \ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " | "\ " \fI8 "\ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
+.RB "|\ \ \ |\ \ \ \ \ \ \ " v "\ \ \ \ \ \ \ |\ \ \ |\ \ \ |"
+.br
++\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+\-\-\-+
+.sp
+.ad n
+.RS
+.I 1
+\t left margin
+.br
+.I 2
+\t xres
+.br
+.I 3
+\t right margin
+.br
+.I 4
+\t horizontal sync len
+.br
+.I 5
+\t upper margin
+.br
+.I 6
+\t yres
+.br
+.I 7
+\t lower margin
+.br
+.I 8
+\t vertical sync len
+.RE
+.sp
+The area bordered with `#' is the visible display area. Horizontal and
+vertical frequencies can now easily be calculated, for this the sum of
+horizontal or vertical values are important
+.RS
+.sp
+htotal\ =\ left\ +\ xres\ +\ right\ +\ hslen
+.br
+vtotal\ =\ upper\ +\ yres\ +\ lower\ +\ vslen
+.sp
+.RE
+The length of one line can now be calculated with pixclock
+.RS
+.sp
+line\ =\ pixclock\ *\ htotal
+.sp
+.RE
+and we have the horizontal frequency
+.RS
+.sp
+hfreq\ =\ 1E12\ /\ line\ =\ 1E12\ /\ (pixclock\ *\ htotal)
+.sp
+.RE
+To get the vertical frequency vtotal must eventually adjusted. If the
+display is laced, vtotal must be halved or if the display is a doublescan
+one, vtotal must be doubled. Now we can calculate the length of one frame
+.RS
+.sp
+if\ (lace)\ \ \ vtotal\ /=\ 2
+.br
+if\ (double)\ vtotal\ *=\ 2
+.sp
+frame\ =\ vtotal\ *\ line
+.sp
+.RE
+and we get also the vertical frequency
+.RS
+.sp
+vfreq\ =\ 1E12\ /\ frame\ =\ hfreq\ /\ vtotal
+.sp
+.RE
+.SH SEE ALSO
+.BR fbset "(8), " fbdev (4)
diff --git a/TVout/fbset/fbset.8 b/TVout/fbset/fbset.8
new file mode 100644
index 0000000000..74e7d3c1b8
--- /dev/null
+++ b/TVout/fbset/fbset.8
@@ -0,0 +1,242 @@
+.TH fbset 8 "July 1998" local "Linux frame buffer utils"
+.SH NAME
+fbset \- show and modify frame buffer device settings
+.SH SYNOPSIS
+.B fbset
+.RI [ options ]
+.RI [ mode ]
+.SH DESCRIPTION
+.B This documentation is out of date!!
+.PP
+.B fbset
+is a system utility to show or change the settings of the frame buffer
+device. The frame buffer device provides a simple and unique interface to
+access different kinds of graphic displays.
+.PP
+Frame buffer devices are accessed via special device nodes located in the
+/dev directory. The naming scheme for these nodes is always
+.IR \fBfb < n >,
+where
+.I n
+is the number of the used frame buffer device.
+.PP
+.B fbset
+uses an own video mode database located in /etc/fb.modes. An unlimited
+number of video modes can be defined in this database. For further
+information see
+.BR fb.modes (5).
+.SH OPTIONS
+If no option is given,
+.B fbset
+will display the current frame buffer settings.
+.sp
+General options:
+.RS
+.TP
+.BR \-\-help ",\ " \-h
+display an usage information
+.TP
+.BR \-\-now ",\ " \-n
+change the video mode immediately. If no frame buffer device is given via
+.B \-fb
+, then this option is activated by default
+.TP
+.BR \-\-show ",\ " \-s
+display the video mode settings. This is default if no further option or
+only a frame buffer device via
+.B \-fb
+is given
+.TP
+.BR \-\-info ",\ " \-i
+display all available frame buffer information
+.TP
+.BR \-\-verbose ",\ " \-v
+display information what
+.B fbset
+is currently doing
+.TP
+.BR \-\-version ",\ " \-V
+display the version information about
+.B fbset
+.TP
+.BR \-\-xfree86 ",\ " \-x
+display the timing information as it's needed by XFree86
+.RE
+.PP
+Frame buffer device nodes:
+.RS
+.TP
+.BR \-fb "\ <" \fIdevice >
+.I device
+gives the frame buffer device node. If no device via
+.B \-fb
+is given,
+.I /dev/fb0
+is used
+.TP
+.RE
+.PP
+Video mode database:
+.RS
+.TP
+.BR \-db "\ <" \fIfile >
+set an alternative video mode database file (default is
+.IR /etc/fb.modes ),
+see also
+.BR fb.modes (5)
+.RE
+.PP
+Display geometry:
+.RS
+.TP
+.BR \-xres "\ <" \fIvalue >
+set visible horizontal resolution (in pixels)
+.TP
+.BR \-yres "\ <" \fIvalue >
+set visible vertical resolution (in pixels)
+.TP
+.BR \-vxres "\ <" \fIvalue >
+set virtual horizontal resolution (in pixels)
+.TP
+.BR \-vyres "\ <" \fIvalue >
+set virtual vertical resolution (in pixels)
+.TP
+.BR \-depth "\ <" \fIvalue >
+set display depth (in bits per pixel)
+.TP
+.BR \-\-geometry ",\ " \-g "\ ..."
+set all geometry parameters at once in the order
+.RI < xres >
+.RI < yres >
+.RI < vxres >
+.RI < vyres >
+.RI < depth >,
+e.g.
+.B \-g
+.I 640 400 640 400 4
+.TP
+.BR \-match "\ \ \ \ \ \ "
+make the physical resolution match the virtual resolution
+.RE
+.PP
+Display timings:
+.RS
+.TP
+.BR \-pixclock "\ <" \fIvalue >
+set the length of one pixel (in picoseconds). Note that the frame buffer
+device may only support some pixel lengths
+.TP
+.BR \-left "\ <" \fIvalue >
+set left margin (in pixels)
+.TP
+.BR \-right "\ <" \fIvalue >
+set right margin (in pixels)
+.TP
+.BR \-upper "\ <" \fIvalue >
+set upper margin (in pixel lines)
+.TP
+.BR \-lower "\ <" \fIvalue >
+set lower margin (in pixel lines)
+.TP
+.BR \-hslen "\ <" \fIvalue >
+set horizontal sync length (in pixels)
+.TP
+.BR \-vslen "\ <" \fIvalue >
+set vertical sync length (in pixel lines)
+.TP
+.BR \-\-timings ",\ " \-t "\ ..."
+set all timing parameters at once in the order
+.RI < pixclock >
+.RI < left >
+.RI < right >
+.RI < upper >
+.RI < lower >
+.RI < hslen >
+.RI < vslen >,
+e.g.
+.B \-g
+.I 35242 64 96 35 12 112 2
+.RE
+.PP
+Display flags:
+.RS
+.TP
+.IR \fB\-hsync "\ {" low | high }
+set the horizontal sync polarity
+.TP
+.IR \fB\-vsync "\ {" low | high }
+set the vertical sync polarity
+.TP
+.IR \fB\-csync "\ {" low | high }
+set the composite sync polarity
+.TP
+.IR \fB\-extsync "\ {" false | true }
+enable or disable external resync. If enabled the sync timings are not
+generated by the frame buffer device and must be provided externally
+instead. Note that this option may not be supported by every frame buffer
+device
+.TP
+.IR \fB\-bcast "\ {" false | true }
+enable or disable broadcast modes. If enabled the frame buffer generates the
+exact timings for several broadcast modes (e.g. PAL or NTSC). Note that
+this option may not be supported by every frame buffer device
+.TP
+.IR \fB\-laced "\ {" false | true }
+enable or disable interlace. If enabled the display will be split in two
+frames, each frame contains only even and odd lines respectively. These two
+frames will be displayed alternating, this way twice the lines can be
+displayed and the vertical frequency for the monitor stays the same, but the
+visible vertical frequency gets halved
+.TP
+.IR \fB\-double "\ {" false | true }
+enable or disable doublescan. If enabled every line will be displayed twice
+and this way the horizontal frequency can easily be doubled, so that the
+same resolution can be displayed on different monitors, even if the
+horizontal frequency specification differs. Note that this option may not be
+supported by every frame buffer device
+.RE
+.PP
+Display positioning:
+.RS
+.TP
+.IR \fB\-move "\ {" left | right | up | down }
+move the visible part of the display in the specified direction
+.TP
+.BR \-step "\ <" \fIvalue >
+set step size for display positioning (in pixels or pixel lines), if
+.B \-step
+is not given display will be moved 8 pixels horizontally or 2 pixel lines
+vertically
+.RE
+.SH EXAMPLE
+To set the used video mode for
+.B X
+insert the following in rc.local:
+.RS
+.sp
+.B fbset
+-fb
+.I /dev/fb0
+vga
+.sp
+.RE
+and make the used frame buffer device known to
+.BR X :
+.RS
+.sp
+.B export
+.RI FRAMEBUFFER= /dev/fb0
+.RE
+.SH FILES
+.I /dev/fb*
+.br
+.I /etc/fb.modes
+.SH SEE ALSO
+.BR fb.modes "(5), " fbdev (4)
+.SH AUTHORS
+.TP
+Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
+.TP
+Roman Zippel <zippel@fh-brandenburg.de>
+.br
+man files
diff --git a/TVout/fbset/fbset.c b/TVout/fbset/fbset.c
new file mode 100644
index 0000000000..a9da078ede
--- /dev/null
+++ b/TVout/fbset/fbset.c
@@ -0,0 +1,1054 @@
+/*
+ * Linux Frame Buffer Device Configuration
+ *
+ * © Copyright 1995-1999 by Geert Uytterhoeven
+ * (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ *
+ * Petr Vandrovec <vandrove@vc.cvut.cz>:
+ * -grayscale, -rgba, -nonstd, VGA modes reporting
+ *
+ * Brad Midgley <brad@exodus.pht.com>:
+ * -match
+ *
+ */
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+struct file;
+struct inode;
+
+#include "fb.h"
+
+#include "fbset.h"
+
+
+ /*
+ * Default Frame Buffer Special Device Node
+ */
+
+#define DEFAULT_FRAMEBUFFER "/dev/fb0"
+
+
+ /*
+ * Default Video Mode Database File
+ */
+
+#define DEFAULT_MODEDBFILE "/etc/fb.modes"
+
+
+ /*
+ * Command Line Options
+ */
+
+static const char *ProgramName;
+
+static int Opt_test = 0;
+static int Opt_show = 0;
+static int Opt_info = 0;
+static int Opt_version = 0;
+static int Opt_verbose = 0;
+static int Opt_xfree86 = 0;
+static int Opt_change = 0;
+static int Opt_all = 0;
+
+static const char *Opt_fb = NULL;
+const char *Opt_modedb = DEFAULT_MODEDBFILE;
+static const char *Opt_xres = NULL;
+static const char *Opt_yres = NULL;
+static const char *Opt_vxres = NULL;
+static const char *Opt_vyres = NULL;
+static const char *Opt_depth = NULL;
+static const char *Opt_pixclock = NULL;
+static const char *Opt_left = NULL;
+static const char *Opt_right = NULL;
+static const char *Opt_upper = NULL;
+static const char *Opt_lower = NULL;
+static const char *Opt_hslen = NULL;
+static const char *Opt_vslen = NULL;
+static const char *Opt_accel = NULL;
+static const char *Opt_hsync = NULL;
+static const char *Opt_vsync = NULL;
+static const char *Opt_csync = NULL;
+static const char *Opt_gsync = NULL;
+static const char *Opt_extsync = NULL;
+static const char *Opt_bcast = NULL;
+static const char *Opt_laced = NULL;
+static const char *Opt_double = NULL;
+static const char *Opt_move = NULL;
+static const char *Opt_step = NULL;
+static const char *Opt_modename = NULL;
+static const char *Opt_rgba = NULL;
+static const char *Opt_nonstd = NULL;
+static const char *Opt_grayscale = NULL;
+static const char *Opt_matchyres = NULL;
+
+static struct {
+ const char *name;
+ const char **value;
+ const int change;
+} Options[] = {
+ { "-fb", &Opt_fb, 0 },
+ { "-db", &Opt_modedb, 0 },
+ { "-xres", &Opt_xres, 1 },
+ { "-yres", &Opt_yres, 1 },
+ { "-vxres", &Opt_vxres, 1 },
+ { "-vyres", &Opt_vyres, 1 },
+ { "-depth", &Opt_depth, 1 },
+ { "-nonstd", &Opt_nonstd, 1},
+ { "-pixclock", &Opt_pixclock, 1 },
+ { "-left", &Opt_left, 1 },
+ { "-right", &Opt_right, 1 },
+ { "-upper", &Opt_upper, 1 },
+ { "-lower", &Opt_lower, 1 },
+ { "-hslen", &Opt_hslen, 1 },
+ { "-vslen", &Opt_vslen, 1 },
+ { "-accel", &Opt_accel, 1 },
+ { "-hsync", &Opt_hsync, 1 },
+ { "-vsync", &Opt_vsync, 1 },
+ { "-csync", &Opt_csync, 1 },
+ { "-gsync", &Opt_gsync, 1 },
+ { "-extsync", &Opt_extsync, 1 },
+ { "-bcast", &Opt_bcast, 1 },
+ { "-laced", &Opt_laced, 1 },
+ { "-double", &Opt_double, 1 },
+ { "-move", &Opt_move, 1 },
+ { "-step", &Opt_step, 1 },
+ { "-rgba", &Opt_rgba, 1 },
+ { "-grayscale", &Opt_grayscale, 1 },
+ { NULL, NULL, 0 }
+};
+
+
+ /*
+ * Video Mode Database
+ */
+
+struct VideoMode *VideoModes = NULL;
+
+
+ /*
+ * Hardware Text Modes
+ */
+
+static struct textentry {
+ __u32 id;
+ const char *name;
+} Textmodes[] = {
+ { FB_AUX_TEXT_MDA, "Monochrome text" },
+ { FB_AUX_TEXT_CGA, "CGA/EGA/VGA Color text" },
+ { FB_AUX_TEXT_S3_MMIO, "S3 MMIO fasttext" },
+ { FB_AUX_TEXT_MGA_STEP16, "MGA Millennium I step 16 text" },
+ { FB_AUX_TEXT_MGA_STEP8, "MGA step 8 text" },
+};
+
+static struct textentry VGAModes[] = {
+ { FB_AUX_VGA_PLANES_VGA4, "VGA 16 colors in 4 planes" },
+ { FB_AUX_VGA_PLANES_CFB4, "VGA 16 colors in 1 plane" },
+ { FB_AUX_VGA_PLANES_CFB8, "VGA 256 colors in 4 planes" },
+ /* last entry has name == NULL */
+ { 0, NULL}
+};
+
+ /*
+ * Hardware Accelerators
+ */
+
+static struct accelentry {
+ __u32 id;
+ const char *name;
+} Accelerators[] = {
+ { FB_ACCEL_NONE, "No" },
+ { FB_ACCEL_ATARIBLITT, "Atari Blitter" },
+ { FB_ACCEL_AMIGABLITT, "Amiga Blitter" },
+ { FB_ACCEL_S3_TRIO64, "S3 Trio64" },
+ { FB_ACCEL_NCR_77C32BLT, "NCR 77C32BLT" },
+ { FB_ACCEL_S3_VIRGE, "S3 ViRGE" },
+ { FB_ACCEL_ATI_MACH64GX, "ATI Mach64GX" },
+ { FB_ACCEL_DEC_TGA, "DEC 21030 TGA" },
+ { FB_ACCEL_ATI_MACH64CT, "ATI Mach64CT" },
+ { FB_ACCEL_ATI_MACH64VT, "ATI Mach64VT" },
+ { FB_ACCEL_ATI_MACH64GT, "ATI Mach64GT" },
+ { FB_ACCEL_SUN_CREATOR, "Sun Creator/Creator3D" },
+ { FB_ACCEL_SUN_CGSIX, "Sun cg6" },
+ { FB_ACCEL_SUN_LEO, "Sun leo/zx" },
+ { FB_ACCEL_IMS_TWINTURBO, "IMS Twin Turbo" },
+ { FB_ACCEL_3DLABS_PERMEDIA2, "3Dlabs Permedia 2" },
+ { FB_ACCEL_MATROX_MGA2064W, "Matrox MGA2064W (Millennium)" },
+ { FB_ACCEL_MATROX_MGA1064SG, "Matrox MGA1064SG (Mystique)" },
+ { FB_ACCEL_MATROX_MGA2164W, "Matrox MGA2164W (Millennium II)" },
+ { FB_ACCEL_MATROX_MGA2164W_AGP, "Matrox MGA2164W (Millennium II AGP)" },
+ { FB_ACCEL_MATROX_MGAG100, "Matrox G100 (Productiva G100)" },
+ { FB_ACCEL_MATROX_MGAG200, "Matrox G200 (Millennium, Mystique)" },
+ { FB_ACCEL_SUN_CG14, "Sun cg14" },
+ { FB_ACCEL_SUN_BWTWO, "Sun bw2" },
+ { FB_ACCEL_SUN_CGTHREE, "Sun cg3" },
+ { FB_ACCEL_SUN_TCX, "Sun tcx" },
+ { FB_ACCEL_MATROX_MGAG400, "Matrox G400" },
+};
+
+
+ /*
+ * Current Video Mode
+ */
+
+struct VideoMode Current;
+
+
+ /*
+ * Function Prototypes
+ */
+
+int OpenFrameBuffer(const char *name);
+void CloseFrameBuffer(int fh);
+void GetVarScreenInfo(int fh, struct fb_var_screeninfo *var);
+void SetVarScreenInfo(int fh, struct fb_var_screeninfo *var);
+void GetFixScreenInfo(int fh, struct fb_fix_screeninfo *fix);
+static void ConvertFromVideoMode(const struct VideoMode *vmode,
+ struct fb_var_screeninfo *var);
+static void ConvertToVideoMode(const struct fb_var_screeninfo *var,
+ struct VideoMode *vmode);
+static int atoboolean(const char *var);
+static void ReadModeDB(void);
+static struct VideoMode *FindVideoMode(const char *name);
+static void ModifyVideoMode(struct VideoMode *vmode);
+static void DisplayVModeInfo(struct VideoMode *vmode);
+static void DisplayFBInfo(struct fb_fix_screeninfo *fix);
+static int FillScanRates(struct VideoMode *vmode);
+static void Usage(void) __attribute__ ((noreturn));
+int main(int argc, char *argv[]);
+
+
+ /*
+ * Print an Error Message and Exit
+ */
+
+void Die(const char *fmt, ...)
+{
+ va_list ap;
+
+ fflush(stdout);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(1);
+}
+
+
+ /*
+ * Open the Frame Buffer Device
+ */
+
+int OpenFrameBuffer(const char *name)
+{
+ int fh;
+
+ if (Opt_verbose)
+ printf("Opening frame buffer device `%s'\n", name);
+
+ if ((fh = open(name, O_RDONLY)) == -1)
+ Die("open %s: %s\n", name, strerror(errno));
+ return fh;
+}
+
+
+ /*
+ * Close the Frame Buffer Device
+ */
+
+void CloseFrameBuffer(int fh)
+{
+ close(fh);
+}
+
+ /*
+ * Get the Variable Part of the Screen Info
+ */
+
+void GetVarScreenInfo(int fh, struct fb_var_screeninfo *var)
+{
+ if (ioctl(fh, FBIOGET_VSCREENINFO, var))
+ Die("ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
+}
+
+
+ /*
+ * Set (and Get) the Variable Part of the Screen Info
+ */
+
+void SetVarScreenInfo(int fh, struct fb_var_screeninfo *var)
+{
+ if (ioctl(fh, FBIOPUT_VSCREENINFO, var))
+ Die("ioctl FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+}
+
+
+ /*
+ * Get the Fixed Part of the Screen Info
+ */
+
+void GetFixScreenInfo(int fh, struct fb_fix_screeninfo *fix)
+{
+ if (ioctl(fh, FBIOGET_FSCREENINFO, fix))
+ Die("ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno));
+}
+
+
+ /*
+ * Conversion Routines
+ */
+
+static void ConvertFromVideoMode(const struct VideoMode *vmode,
+ struct fb_var_screeninfo *var)
+{
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
+ var->xres = vmode->xres;
+ var->yres = vmode->yres;
+ var->xres_virtual = vmode->vxres;
+ var->yres_virtual = vmode->vyres;
+ var->bits_per_pixel = vmode->depth;
+ var->nonstd = vmode->nonstd;
+ if (Opt_test)
+ var->activate = FB_ACTIVATE_TEST;
+ else
+ var->activate = FB_ACTIVATE_NOW;
+ if (Opt_all)
+ var->activate = FB_ACTIVATE_ALL;
+ var->accel_flags = vmode->accel_flags;
+ var->pixclock = vmode->pixclock;
+ var->left_margin = vmode->left;
+ var->right_margin = vmode->right;
+ var->upper_margin = vmode->upper;
+ var->lower_margin = vmode->lower;
+ var->hsync_len = vmode->hslen;
+ var->vsync_len = vmode->vslen;
+ if (vmode->hsync == HIGH)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (vmode->vsync == HIGH)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (vmode->csync == HIGH)
+ var->sync |= FB_SYNC_COMP_HIGH_ACT;
+ if (vmode->gsync == HIGH)
+ var->sync |= FB_SYNC_ON_GREEN;
+ if (vmode->extsync == TRUE)
+ var->sync |= FB_SYNC_EXT;
+ if (vmode->bcast == TRUE)
+ var->sync |= FB_SYNC_BROADCAST;
+ if (vmode->laced == TRUE)
+ var->vmode = FB_VMODE_INTERLACED;
+ else if (vmode->dblscan == TRUE)
+ var->vmode = FB_VMODE_DOUBLE;
+ else
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->vmode |= FB_VMODE_CONUPDATE;
+ var->red.length = vmode->red.length;
+ var->red.offset = vmode->red.offset;
+ var->green.length = vmode->green.length;
+ var->green.offset = vmode->green.offset;
+ var->blue.length = vmode->blue.length;
+ var->blue.offset = vmode->blue.offset;
+ var->transp.length = vmode->transp.length;
+ var->transp.offset = vmode->transp.offset;
+ var->grayscale = vmode->grayscale;
+}
+
+
+static void ConvertToVideoMode(const struct fb_var_screeninfo *var,
+ struct VideoMode *vmode)
+{
+ vmode->name = NULL;
+ vmode->xres = var->xres;
+ vmode->yres = var->yres;
+ vmode->vxres = var->xres_virtual;
+ vmode->vyres = var->yres_virtual;
+ vmode->depth = var->bits_per_pixel;
+ vmode->nonstd = var->nonstd;
+ vmode->accel_flags = var->accel_flags;
+ vmode->pixclock = var->pixclock;
+ vmode->left = var->left_margin;
+ vmode->right = var->right_margin;
+ vmode->upper = var->upper_margin;
+ vmode->lower = var->lower_margin;
+ vmode->hslen = var->hsync_len;
+ vmode->vslen = var->vsync_len;
+ vmode->hsync = var->sync & FB_SYNC_HOR_HIGH_ACT ? HIGH : LOW;
+ vmode->vsync = var->sync & FB_SYNC_VERT_HIGH_ACT ? HIGH : LOW;
+ vmode->csync = var->sync & FB_SYNC_COMP_HIGH_ACT ? HIGH : LOW;
+ vmode->gsync = var->sync & FB_SYNC_ON_GREEN ? TRUE : FALSE;
+ vmode->extsync = var->sync & FB_SYNC_EXT ? TRUE : FALSE;
+ vmode->bcast = var->sync & FB_SYNC_BROADCAST ? TRUE : FALSE;
+ vmode->grayscale = var->grayscale;
+ vmode->laced = FALSE;
+ vmode->dblscan = FALSE;
+ switch (var->vmode & FB_VMODE_MASK) {
+ case FB_VMODE_INTERLACED:
+ vmode->laced = TRUE;
+ break;
+ case FB_VMODE_DOUBLE:
+ vmode->dblscan = TRUE;
+ break;
+ }
+ vmode->red.length = var->red.length;
+ vmode->red.offset = var->red.offset;
+ vmode->green.length = var->green.length;
+ vmode->green.offset = var->green.offset;
+ vmode->blue.length = var->blue.length;
+ vmode->blue.offset = var->blue.offset;
+ vmode->transp.length = var->transp.length;
+ vmode->transp.offset = var->transp.offset;
+ FillScanRates(vmode);
+}
+
+
+static int atoboolean(const char *var)
+{
+ int value = 0;
+
+ if (!strcasecmp(var, "false") || !strcasecmp(var, "low") ||
+ !strcasecmp(var, "no") || !strcasecmp(var, "off") ||
+ !strcmp(var, "0"))
+ value = 0;
+ else if (!strcasecmp(var, "true") || !strcasecmp(var, "high") ||
+ !strcasecmp(var, "yes") || !strcasecmp(var, "on") ||
+ !strcmp(var, "1"))
+ value = 1;
+ else
+ Die("Invalid value `%s'\n", var);
+
+ return value;
+}
+
+
+void AddVideoMode(const struct VideoMode *vmode)
+{
+ struct VideoMode *vmode2;
+
+ if (FindVideoMode(vmode->name))
+ Die("%s:%d: Duplicate mode name `%s'\n", Opt_modedb, line,
+ vmode->name);
+ vmode2 = malloc(sizeof(struct VideoMode));
+ *vmode2 = *vmode;
+ if (!FillScanRates(vmode2))
+ Die("%s:%d: Bad video mode `%s'\n", Opt_modedb, line, vmode2->name);
+ vmode2->next = VideoModes;
+ VideoModes = vmode2;
+}
+
+
+ /*
+ * Read the Video Mode Database
+ */
+
+static void ReadModeDB(void)
+{
+ if (Opt_verbose)
+ printf("Reading mode database from file `%s'\n", Opt_modedb);
+
+ if (!(yyin = fopen(Opt_modedb, "r")))
+ Die("fopen %s: %s\n", Opt_modedb, strerror(errno));
+ yyparse();
+ fclose(yyin);
+}
+
+
+static void getColor(struct color *color, const char** opt)
+{
+ char* ptr;
+
+ color->length = 0;
+ color->offset = 0;
+ ptr = (char*)(*opt);
+ if (!ptr)
+ return;
+ color->length = strtoul(ptr, &ptr, 0);
+ if (!ptr)
+ return;
+ if (*ptr == '/')
+ color->offset = strtoul(ptr+1, &ptr, 0);
+ if (ptr) {
+ while (*ptr && isspace(*ptr))
+ ptr++;
+ if (*ptr == ',') {
+ ptr++;
+ } else if (*ptr)
+ Die("Bad RGBA syntax, rL/rO,gL/gO,bL/bO,tL/tO or rL,gL,bL,tL\n");
+ }
+ *opt = ptr;
+ return;
+}
+
+void makeRGBA(struct VideoMode *vmode, const char* opt)
+{
+ getColor(&vmode->red, &opt);
+ getColor(&vmode->green, &opt);
+ getColor(&vmode->blue, &opt);
+ getColor(&vmode->transp, &opt);
+}
+
+ /*
+ * Find a Video Mode
+ */
+
+static struct VideoMode *FindVideoMode(const char *name)
+{
+ struct VideoMode *vmode;
+
+ for (vmode = VideoModes; vmode; vmode = vmode->next)
+ if (!strcmp(name, vmode->name))
+ break;
+
+ return vmode;
+}
+
+
+ /*
+ * Modify a Video Mode
+ */
+
+static void ModifyVideoMode(struct VideoMode *vmode)
+{
+ u_int hstep = 8, vstep = 2;
+
+ if (Opt_xres)
+ vmode->xres = strtoul(Opt_xres, NULL, 0);
+ if (Opt_yres)
+ vmode->yres = strtoul(Opt_yres, NULL, 0);
+ if (Opt_vxres)
+ vmode->vxres = strtoul(Opt_vxres, NULL, 0);
+ if (Opt_vyres)
+ vmode->vyres = strtoul(Opt_vyres, NULL, 0);
+ if (Opt_depth)
+ vmode->depth = strtoul(Opt_depth, NULL, 0);
+ if (Opt_nonstd)
+ vmode->nonstd = strtoul(Opt_nonstd, NULL, 0);
+ if (Opt_accel)
+ vmode->accel_flags = atoboolean(Opt_accel) ? FB_ACCELF_TEXT : 0;
+ if (Opt_pixclock)
+ vmode->pixclock = strtoul(Opt_pixclock, NULL, 0);
+ if (Opt_left)
+ vmode->left = strtoul(Opt_left, NULL, 0);
+ if (Opt_right)
+ vmode->right = strtoul(Opt_right, NULL, 0);
+ if (Opt_upper)
+ vmode->upper = strtoul(Opt_upper, NULL, 0);
+ if (Opt_lower)
+ vmode->lower = strtoul(Opt_lower, NULL, 0);
+ if (Opt_hslen)
+ vmode->hslen = strtoul(Opt_hslen, NULL, 0);
+ if (Opt_vslen)
+ vmode->vslen = strtoul(Opt_vslen, NULL, 0);
+ if (Opt_hsync)
+ vmode->hsync = atoboolean(Opt_hsync);
+ if (Opt_vsync)
+ vmode->vsync = atoboolean(Opt_vsync);
+ if (Opt_csync)
+ vmode->csync = atoboolean(Opt_csync);
+ if (Opt_gsync)
+ vmode->gsync = atoboolean(Opt_gsync);
+ if (Opt_extsync)
+ vmode->extsync = atoboolean(Opt_extsync);
+ if (Opt_bcast)
+ vmode->bcast = atoboolean(Opt_bcast);
+ if (Opt_laced)
+ vmode->laced = atoboolean(Opt_laced);
+ if (Opt_double)
+ vmode->dblscan = atoboolean(Opt_double);
+ if (Opt_grayscale)
+ vmode->grayscale = atoboolean(Opt_grayscale);
+ if (Opt_step)
+ hstep = vstep = strtoul(Opt_step, NULL, 0);
+ if (Opt_matchyres)
+ vmode->vyres = vmode->yres;
+ if (Opt_move) {
+ if (!strcasecmp(Opt_move, "left")) {
+ if (hstep > vmode->left)
+ Die("The left margin cannot be negative\n");
+ vmode->left -= hstep;
+ vmode->right += hstep;
+ } else if (!strcasecmp(Opt_move, "right")) {
+ if (hstep > vmode->right)
+ Die("The right margin cannot be negative\n");
+ vmode->left += hstep;
+ vmode->right -= hstep;
+ } else if (!strcasecmp(Opt_move, "up")) {
+ if (vstep > vmode->upper)
+ Die("The upper margin cannot be negative\n");
+ vmode->upper -= vstep;
+ vmode->lower += vstep;
+ } else if (!strcasecmp(Opt_move, "down")) {
+ if (vstep > vmode->lower)
+ Die("The lower margin cannot be negative\n");
+ vmode->upper += vstep;
+ vmode->lower -= vstep;
+ } else
+ Die("Invalid direction `%s'\n", Opt_move);
+ }
+ if (Opt_rgba) {
+ makeRGBA(vmode, Opt_rgba);
+ }
+ if (!FillScanRates(vmode))
+ Die("Bad video mode\n");
+}
+
+
+ /*
+ * Display the Video Mode Information
+ */
+
+static void DisplayVModeInfo(struct VideoMode *vmode)
+{
+ u_int res, sstart, send, total;
+
+ puts("");
+ if (!Opt_xfree86) {
+ printf("mode \"%dx%d", vmode->xres, vmode->yres);
+ if (vmode->pixclock) {
+ printf("-%d\"\n", (int)(vmode->vrate+0.5));
+ printf(" # D: %5.3f MHz, H: %5.3f kHz, V: %5.3f Hz\n",
+ vmode->drate/1E6, vmode->hrate/1E3, vmode->vrate);
+ } else
+ puts("\"");
+ printf(" geometry %d %d %d %d %d\n", vmode->xres, vmode->yres,
+ vmode->vxres, vmode->vyres, vmode->depth);
+ printf(" timings %d %d %d %d %d %d %d\n", vmode->pixclock,
+ vmode->left, vmode->right, vmode->upper, vmode->lower,
+ vmode->hslen, vmode->vslen);
+ if (vmode->hsync)
+ puts(" hsync high");
+ if (vmode->vsync)
+ puts(" vsync high");
+ if (vmode->csync)
+ puts(" csync high");
+ if (vmode->gsync)
+ puts(" gsync true");
+ if (vmode->extsync)
+ puts(" extsync true");
+ if (vmode->bcast)
+ puts(" bcast true");
+ if (vmode->laced)
+ puts(" laced true");
+ if (vmode->dblscan)
+ puts(" double true");
+ if (vmode->nonstd)
+ printf(" nonstd %u\n", vmode->nonstd);
+ if (vmode->accel_flags)
+ puts(" accel true");
+ if (vmode->grayscale)
+ puts(" grayscale true");
+ printf(" rgba %u/%u,%u/%u,%u/%u,%u/%u\n",
+ vmode->red.length, vmode->red.offset, vmode->green.length,
+ vmode->green.offset, vmode->blue.length, vmode->blue.offset,
+ vmode->transp.length, vmode->transp.offset);
+ puts("endmode\n");
+ } else {
+ printf("Mode \"%dx%d\"\n", vmode->xres, vmode->yres);
+ if (vmode->pixclock) {
+ printf(" # D: %5.3f MHz, H: %5.3f kHz, V: %5.3f Hz\n",
+ vmode->drate/1E6, vmode->hrate/1E3, vmode->vrate);
+ printf(" DotClock %5.3f\n", vmode->drate/1E6+0.001);
+ } else
+ puts(" DotClock Unknown");
+ res = vmode->xres;
+ sstart = res+vmode->right;
+ send = sstart+vmode->hslen;
+ total = send+vmode->left;
+ printf(" HTimings %d %d %d %d\n", res, sstart, send, total);
+ res = vmode->yres;
+ sstart = res+vmode->lower;
+ send = sstart+vmode->vslen;
+ total = send+vmode->upper;
+ printf(" VTimings %d %d %d %d\n", res, sstart, send, total);
+ printf(" Flags ");
+ if (vmode->laced)
+ printf(" \"Interlace\"");
+ if (vmode->dblscan)
+ printf(" \"DoubleScan\"");
+ if (vmode->hsync)
+ printf(" \"+HSync\"");
+ else
+ printf(" \"-HSync\"");
+ if (vmode->vsync)
+ printf(" \"+VSync\"");
+ else
+ printf(" \"-VSync\"");
+ if (vmode->csync)
+ printf(" \"Composite\"");
+ if (vmode->extsync)
+ puts(" # Warning: XFree86 doesn't support extsync\n");
+ if (vmode->bcast)
+ printf(" \"bcast\"");
+ if (vmode->accel_flags)
+ puts(" # Warning: XFree86 doesn't support accel\n");
+ if (vmode->grayscale)
+ puts(" # Warning: XFree86 doesn't support grayscale\n");
+ puts("\nEndMode\n");
+ }
+}
+
+
+ /*
+ * Display the Frame Buffer Device Information
+ */
+
+static void DisplayFBInfo(struct fb_fix_screeninfo *fix)
+{
+ int i;
+
+ puts("Frame buffer device information:");
+ printf(" Name : %s\n", fix->id);
+ printf(" Address : %p\n", fix->smem_start);
+ printf(" Size : %d\n", fix->smem_len);
+ printf(" Type : ");
+ switch (fix->type) {
+ case FB_TYPE_PACKED_PIXELS:
+ puts("PACKED PIXELS");
+ break;
+ case FB_TYPE_PLANES:
+ puts("PLANES");
+ break;
+ case FB_TYPE_INTERLEAVED_PLANES:
+ printf("INTERLEAVED PLANES (%d bytes interleave)\n",
+ fix->type_aux);
+ break;
+ case FB_TYPE_TEXT:
+ for (i = 0; i < sizeof(Textmodes)/sizeof(*Textmodes); i++)
+ if (fix->type_aux == Textmodes[i].id)
+ break;
+ if (i < sizeof(Textmodes)/sizeof(*Textmodes))
+ puts(Textmodes[i].name);
+ else
+ printf("Unknown text (%d)\n", fix->type_aux);
+ break;
+ case FB_TYPE_VGA_PLANES:
+ {
+ struct textentry *t;
+
+ for (t = VGAModes; t->name; t++)
+ if (fix->type_aux == t->id)
+ break;
+ if (t->name)
+ puts(t->name);
+ else
+ printf("Unknown VGA mode (%d)\n", fix->type_aux);
+ }
+ break;
+ default:
+ printf("%d (UNKNOWN)\n", fix->type);
+ printf(" Type_aux : %d\n", fix->type_aux);
+ break;
+ }
+ printf(" Visual : ");
+ switch (fix->visual) {
+ case FB_VISUAL_MONO01:
+ puts("MONO01");
+ break;
+ case FB_VISUAL_MONO10:
+ puts("MONO10");
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ puts("TRUECOLOR");
+ break;
+ case FB_VISUAL_PSEUDOCOLOR:
+ puts("PSEUDOCOLOR");
+ break;
+ case FB_VISUAL_DIRECTCOLOR:
+ puts("DIRECTCOLOR");
+ break;
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ puts("STATIC PSEUDOCOLOR");
+ break;
+ default:
+ printf("%d (UNKNOWN)\n", fix->visual);
+ break;
+ }
+ printf(" XPanStep : %d\n", fix->xpanstep);
+ printf(" YPanStep : %d\n", fix->ypanstep);
+ printf(" YWrapStep : %d\n", fix->ywrapstep);
+ printf(" LineLength : %d\n", fix->line_length);
+ if (fix->mmio_len) {
+ printf(" MMIO Address: %p\n", fix->mmio_start);
+ printf(" MMIO Size : %d\n", fix->mmio_len);
+ }
+ printf(" Accelerator : ");
+ for (i = 0; i < sizeof(Accelerators)/sizeof(*Accelerators); i++)
+ if (fix->accel == Accelerators[i].id)
+ break;
+ if (i < sizeof(Accelerators)/sizeof(*Accelerators))
+ puts(Accelerators[i].name);
+ else
+ printf("Unknown (%d)\n", fix->accel);
+}
+
+
+ /*
+ * Calculate the Scan Rates for a Video Mode
+ */
+
+static int FillScanRates(struct VideoMode *vmode)
+{
+ u_int htotal = vmode->left+vmode->xres+vmode->right+vmode->hslen;
+ u_int vtotal = vmode->upper+vmode->yres+vmode->lower+vmode->vslen;
+
+ if (vmode->dblscan)
+ vtotal <<= 2;
+ else if (!vmode->laced)
+ vtotal <<= 1;
+
+ if (!htotal || !vtotal)
+ return 0;
+
+ if (vmode->pixclock) {
+ vmode->drate = 1E12/vmode->pixclock;
+ vmode->hrate = vmode->drate/htotal;
+ vmode->vrate = vmode->hrate/vtotal*2;
+ } else {
+ vmode->drate = 0;
+ vmode->hrate = 0;
+ vmode->vrate = 0;
+ }
+
+ return 1;
+}
+
+
+ /*
+ * Print the Usage Template and Exit
+ */
+
+static void Usage(void)
+{
+ puts(VERSION);
+ Die("\nUsage: %s [options] [mode]\n\n"
+ "Valid options:\n"
+ " General options:\n"
+ " -h, --help : display this usage information\n"
+ " --test : don't change, just test whether the mode is "
+ "valid\n"
+ " -s, --show : display video mode settings\n"
+ " -i, --info : display all frame buffer information\n"
+ " -v, --verbose : verbose mode\n"
+ " -V, --version : print version information\n"
+ " -x, --xfree86 : XFree86 compatibility mode\n"
+ " -a, --all : change all virtual consoles on this device\n"
+ " Frame buffer special device nodes:\n"
+ " -fb <device> : processed frame buffer device\n"
+ " (default is " DEFAULT_FRAMEBUFFER ")\n"
+ " Video mode database:\n"
+ " -db <file> : video mode database file\n"
+ " (default is " DEFAULT_MODEDBFILE ")\n"
+ " Display geometry:\n"
+ " -xres <value> : horizontal resolution (in pixels)\n"
+ " -yres <value> : vertical resolution (in pixels)\n"
+ " -vxres <value> : virtual horizontal resolution (in pixels)\n"
+ " -vyres <value> : virtual vertical resolution (in pixels)\n"
+ " -depth <value> : display depth (in bits per pixel)\n"
+ " -nonstd <value> : select nonstandard video mode\n"
+ " -g, --geometry ... : set all geometry parameters at once\n"
+ " -match : set virtual vertical resolution by virtual resolution\n"
+ " Display timings:\n"
+ " -pixclock <value> : pixel clock (in picoseconds)\n"
+ " -left <value> : left margin (in pixels)\n"
+ " -right <value> : right margin (in pixels)\n"
+ " -upper <value> : upper margin (in pixel lines)\n"
+ " -lower <value> : lower margin (in pixel lines)\n"
+ " -hslen <value> : horizontal sync length (in pixels)\n"
+ " -vslen <value> : vertical sync length (in pixel lines)\n"
+ " -t, --timings ... : set all timing parameters at once\n"
+ " Display flags:\n"
+ " -accel <value> : hardware text acceleration enable (false or "
+ "true)\n"
+ " -hsync <value> : horizontal sync polarity (low or high)\n"
+ " -vsync <value> : vertical sync polarity (low or high)\n"
+ " -csync <value> : composite sync polarity (low or high)\n"
+ " -gsync <value> : synch on green (false or true)\n"
+ " -extsync <value> : external sync enable (false or true)\n"
+ " -bcast <value> : broadcast enable (false or true)\n"
+ " -laced <value> : interlace enable (false or true)\n"
+ " -double <value> : doublescan enable (false or true)\n"
+ " -rgba <r,g,b,a> : recommended length of color entries\n"
+ " -grayscale <value> : grayscale enable (false or true)\n"
+ " Display positioning:\n"
+ " -move <direction> : move the visible part (left, right, up or "
+ "down)\n"
+ " -step <value> : step increment (in pixels or pixel lines)\n"
+ " (default is 8 horizontal, 2 vertical)\n",
+ ProgramName);
+}
+
+
+ /*
+ * Main Routine
+ */
+
+int main(int argc, char *argv[])
+{
+ struct VideoMode *vmode;
+ struct fb_var_screeninfo var;
+ struct fb_fix_screeninfo fix;
+ int fh = -1, i;
+
+ ProgramName = argv[0];
+
+ /*
+ * Parse the Options
+ */
+
+ while (--argc > 0) {
+ argv++;
+ if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help"))
+ Usage();
+ else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--verbose"))
+ Opt_verbose = 1;
+ else if (!strcmp(argv[0], "-V") || !strcmp(argv[0], "--version"))
+ Opt_version = 1;
+ else if (!strcmp(argv[0], "--test"))
+ Opt_test = 1;
+ else if (!strcmp(argv[0], "-s") || !strcmp(argv[0], "--show"))
+ Opt_show = 1;
+ else if (!strcmp(argv[0], "-i") || !strcmp(argv[0], "--info")) {
+ Opt_show = 1;
+ Opt_info = 1;
+ } else if (!strcmp(argv[0], "-x") || !strcmp(argv[0], "--xfree86"))
+ Opt_xfree86 = 1;
+ else if (!strcmp(argv[0], "-a") || !strcmp(argv[0], "--all"))
+ Opt_all = 1;
+ else if (!strcmp(argv[0], "-g") || !strcmp(argv[0], "--geometry")) {
+ if (argc > 5) {
+ Opt_xres = argv[1];
+ Opt_yres = argv[2];
+ Opt_vxres = argv[3];
+ Opt_vyres = argv[4];
+ Opt_depth = argv[5];
+ Opt_change = 1;
+ argc -= 5;
+ argv += 5;
+ } else
+ Usage();
+ } else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--timings")) {
+ if (argc > 7) {
+ Opt_pixclock = argv[1];
+ Opt_left = argv[2];
+ Opt_right = argv[3];
+ Opt_upper = argv[4];
+ Opt_lower = argv[5];
+ Opt_hslen = argv[6];
+ Opt_vslen = argv[7];
+ Opt_change = 1;
+ argc -= 7;
+ argv += 7;
+ } else
+ Usage();
+ } else if (!strcmp(argv[0], "-match")) {
+ Opt_matchyres = argv[0];
+ Opt_change = 1;
+ } else {
+ for (i = 0; Options[i].name; i++)
+ if (!strcmp(argv[0], Options[i].name))
+ break;
+ if (Options[i].name) {
+ if (argc-- > 1) {
+ *Options[i].value = argv[1];
+ Opt_change |= Options[i].change;
+ argv++;
+ } else
+ Usage();
+ } else if (!Opt_modename) {
+ Opt_modename = argv[0];
+ Opt_change = 1;
+ } else
+ Usage();
+ }
+ }
+
+ if (Opt_version || Opt_verbose)
+ puts(VERSION);
+
+ if (!Opt_fb)
+ Opt_fb = DEFAULT_FRAMEBUFFER;
+
+ /*
+ * Open the Frame Buffer Device
+ */
+
+ fh = OpenFrameBuffer(Opt_fb);
+
+ /*
+ * Get the Video Mode
+ */
+
+ if (Opt_modename) {
+
+ /*
+ * Read the Video Mode Database
+ */
+
+ ReadModeDB();
+
+ if (!(vmode = FindVideoMode(Opt_modename)))
+ Die("Unknown video mode `%s'\n", Opt_modename);
+
+ Current = *vmode;
+ if (Opt_verbose)
+ printf("Using video mode `%s'\n", Opt_modename);
+ } else {
+ GetVarScreenInfo(fh, &var);
+ ConvertToVideoMode(&var, &Current);
+ if (Opt_verbose)
+ printf("Using current video mode from `%s'\n", Opt_fb);
+ }
+
+ if (Opt_change) {
+
+ /*
+ * Optionally Modify the Video Mode
+ */
+
+ ModifyVideoMode(&Current);
+
+ /*
+ * Set the Video Mode
+ */
+
+ ConvertFromVideoMode(&Current, &var);
+ if (Opt_verbose)
+ printf("Setting video mode to `%s'\n", Opt_fb);
+ SetVarScreenInfo(fh, &var);
+ ConvertToVideoMode(&var, &Current);
+ }
+
+ /*
+ * Display some Video Mode Information
+ */
+
+ if (Opt_show || !Opt_change)
+ DisplayVModeInfo(&Current);
+
+ if (Opt_info) {
+ if (Opt_verbose)
+ puts("Getting further frame buffer information");
+ GetFixScreenInfo(fh, &fix);
+ DisplayFBInfo(&fix);
+ }
+
+ /*
+ * Close the Frame Buffer Device
+ */
+
+ CloseFrameBuffer(fh);
+
+ exit(0);
+}
diff --git a/TVout/fbset/fbset.h b/TVout/fbset/fbset.h
new file mode 100644
index 0000000000..9b1d2acfa0
--- /dev/null
+++ b/TVout/fbset/fbset.h
@@ -0,0 +1,82 @@
+/*
+ * Linux Frame Buffer Device Configuration
+ *
+ * © Copyright 1995-1998 by Geert Uytterhoeven
+ * (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef __GLIBC__
+#include <asm/types.h>
+#endif
+
+#define VERSION "Linux Frame Buffer Device Configuration " \
+ "Version 2.1 (23/06/1999)\n" \
+ "(C) Copyright 1995-1999 by Geert Uytterhoeven\n"
+
+#define LOW (0)
+#define HIGH (1)
+
+#define FALSE (0)
+#define TRUE (1)
+
+struct color {
+ unsigned int length;
+ unsigned int offset;
+};
+
+struct VideoMode {
+ struct VideoMode *next;
+ const char *name;
+ /* geometry */
+ __u32 xres;
+ __u32 yres;
+ __u32 vxres;
+ __u32 vyres;
+ __u32 depth;
+ __u32 nonstd;
+ /* acceleration */
+ __u32 accel_flags;
+ /* timings */
+ __u32 pixclock;
+ __u32 left;
+ __u32 right;
+ __u32 upper;
+ __u32 lower;
+ __u32 hslen;
+ __u32 vslen;
+ /* flags */
+ unsigned hsync : 1;
+ unsigned vsync : 1;
+ unsigned csync : 1;
+ unsigned gsync : 1;
+ unsigned extsync : 1;
+ unsigned bcast : 1;
+ unsigned laced : 1;
+ unsigned dblscan : 1;
+ unsigned grayscale : 1;
+ /* scanrates */
+ double drate;
+ double hrate;
+ double vrate;
+ /* RGB entries */
+ struct color red, green, blue, transp;
+};
+
+extern FILE *yyin;
+extern int line;
+extern const char *Opt_modedb;
+
+extern int yyparse(void);
+extern void Die(const char *fmt, ...) __attribute__ ((noreturn));
+extern void AddVideoMode(const struct VideoMode *vmode);
+extern void makeRGBA(struct VideoMode *vmode, const char* opt);
diff --git a/TVout/fbset/modeline2fb b/TVout/fbset/modeline2fb
new file mode 100755
index 0000000000..3a227f558c
--- /dev/null
+++ b/TVout/fbset/modeline2fb
@@ -0,0 +1,150 @@
+#!/usr/bin/perl
+
+# Simple modeline-to-fb.modes translator
+# (c) 1998 by Patrick Reynolds
+# distributed under the GNU General Public License
+
+# mapping of modeline options to fb.modes options
+%options_map = (
+ "-hsync" => "hsync low",
+ "-vsync" => "vsync low",
+ "+hsync" => "hsync high",
+ "+vsync" => "vsync high",
+ "interlace" => "laced true",
+ "doublescan" => "double true"
+);
+
+@possible_vxres = ( 640, 800, 1024, 1152, 1280, 1600, 1920, 2048 );
+
+# default settings (override with -d and -r)
+$depth = 8;
+$rounding = 128;
+
+# parse options
+while ($ARGV[0] =~ /^-/) {
+ $arg = shift;
+ if ($arg eq "-d" || $arg eq "--depth") {
+ if (!($arg = shift @ARGV)) {
+ usage("-d requires an argument");
+ }
+ $depth = $arg;
+ }
+ elsif ($arg eq "-r" || $arg eq "--rounding") {
+ if (!($arg = shift @ARGV)) {
+ usage("-r requires an argument");
+ }
+ $rounding = $arg;
+ }
+ elsif ($arg eq "-x" || $arg eq "--vxres") {
+ if (!($arg = shift @ARGV)) {
+ usage("-x requires an argument");
+ }
+ push @possible_vxres, (split/,/,$arg);
+ @possible_vxres = sort { $a <=> $b } @possible_vxres;
+ print "new vxres: " . (join ",", @possible_vxres) . "\n";
+ }
+ elsif ($arg eq "-h" || $arg eq "--help") {
+ usage();
+ }
+ else {
+ usage("unknown option: $arg");
+ }
+}
+
+# find out how much video memory is available
+open(FBSET, "fbset -i|") || die "could not detect available video memory";
+while (<FBSET>) {
+ if (/Size\s*:\s*(\d+)/) {
+ $size = $1;
+ last;
+ }
+}
+if (!$size) { die "could not detect available video memory"; }
+
+# huge kludge (hey, that rhymes!) ...
+# subtract 16384 from the available memory $size
+# why? the default 640x480 mode uses all but 16384, and when I set it
+# to use more than that, it oopses (!). So... for safety's sake, and
+# because you probably don't use those 15-25 lines anyway...
+$size -= 16384;
+
+print "# modes.fb - video mode descriptions for fbset
+#
+# See fbset(8) and fb.modes(5) for more information
+
+";
+
+$flag = 0;
+# read all XF86Config files
+while(<>) {
+ chomp;
+ next if !(($name, $clock, $xres, $xsyncstart, $xsyncend, $xfres,
+ $yres, $ysyncstart, $ysyncend, $yfres, $extra) =
+ /^\s*modeline\s+"([^"]+)"\s+([0-9.]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*(.*)$/i);
+ $flag = 1;
+
+ # timing transformations, as described in the fb HOWTO
+ $pixtime = int(1000000/$clock);
+ $left = $xfres - $xsyncend;
+ $right = $xsyncstart - $xres;
+ $hsynclen = $xsyncend - $xsyncstart;
+ $top = $yfres - $ysyncend;
+ $bottom = $ysyncstart - $yres;
+ $vsynclen = $ysyncend - $ysyncstart;
+
+ # pick a virtual X and Y resolution
+ $vxres = get_vxres($xres);
+ if ($vxres < 0) {
+ print STDERR "Could not guess a good virtual resolution for mode $name.\n";
+ print STDERR "Use the advanced options --rounding and --vxres.\n";
+ next;
+ }
+ $vyres = int($size/$vxres);
+
+ # print out our entry
+ print "mode \"$name\"\n";
+ print " geometry $xres $yres $vxres $vyres $depth\n";
+ print " timings $pixtime $left $right $top $bottom $hsynclen $vsynclen\n";
+
+ # handle extra options at the end of the modeline
+ $extra =~ tr/A-Z/a-z/;
+ @options = split/\s+/,$extra;
+ foreach (@options) {
+ if ($options_map{$_}) {
+ print " $options_map{$_}\n";
+ }
+ else {
+ print " # unknown option: $_\n";
+ }
+ }
+ print "endmode\n\n";
+}
+
+if (!$flag) {
+ print STDERR "No modelines found.\n";
+ print STDERR "Make sure the file you specified was an XF86Config file and\n";
+ print STDERR "used the single-line Modeline format.\n\n";
+ print STDERR "Use \"$0 --help\" for help.\n";
+}
+
+sub get_vxres {
+ foreach (@possible_vxres) {
+ return $_ if ($_ >= $_[0] && ($_ % $rounding) == 0);
+ }
+ return -1;
+}
+
+sub usage {
+ print STDERR "$_[0]\n" if ($_[0]);
+ print STDERR "$0 [OPTION] [FILES]\n\n";
+ print STDERR " -d,--depth depth use a certain display depth (default is 8)\n";
+ print STDERR " -h,--help what you see here\n\n";
+ print STDERR "Advanced options:\n";
+ print STDERR " -r,--rounding div vxres divisor (default is 128)\n";
+ print STDERR " -x,--vxres X,X,X,... extra possible vxres values\n\n";
+ print STDERR "[FILES] refers to one or more XF86Config files. Note that\n";
+ print STDERR "all modelines must be in single-line format.\n\n";
+ print STDERR "Example:\n";
+ print STDERR " $0 -d 16 /etc/X11/XF86Config\n";
+ exit 0;
+}
diff --git a/TVout/fbset/modes.l b/TVout/fbset/modes.l
new file mode 100644
index 0000000000..426eb5c1be
--- /dev/null
+++ b/TVout/fbset/modes.l
@@ -0,0 +1,136 @@
+
+/*
+ * Linux Frame Buffer Device Configuration
+ *
+ * © Copyright 1995-1998 by Geert Uytterhoeven
+ * (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+
+%{
+
+#define YYSTYPE long
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "fbset.h"
+#include "modes.tab.h"
+
+struct keyword {
+ const char *name;
+ int token;
+ int value;
+};
+
+static struct keyword keywords[] = {
+ { "mode", MODE, 0 },
+ { "geometry", GEOMETRY, 0 },
+ { "timings", TIMINGS, 0 },
+ { "hsync", HSYNC, 0 },
+ { "vsync", VSYNC, 0 },
+ { "csync", CSYNC, 0 },
+ { "gsync", GSYNC, 0 },
+ { "extsync", EXTSYNC, 0 },
+ { "bcast", BCAST, 0 },
+ { "laced", LACED, 0 },
+ { "double", DOUBLE, 0 },
+ { "rgba", RGBA, 0 },
+ { "nonstd", NONSTD, 0 },
+ { "accel", ACCEL, 0 },
+ { "grayscale", GRAYSCALE, 0 },
+ { "endmode", ENDMODE, 0 },
+ { "low", POLARITY, LOW },
+ { "high", POLARITY, HIGH },
+ { "false", BOOLEAN, FALSE },
+ { "true", BOOLEAN, TRUE },
+ { "", -1, 0 }
+};
+
+int line = 1;
+
+
+void yyerror(const char *s)
+{
+ Die("%s:%d: %s\n", Opt_modedb, line, s);
+}
+
+
+int yywrap(void)
+{
+ return 1;
+}
+
+
+static int FindToken(const char *s)
+{
+ int i;
+
+ for (i = 0; keywords[i].token > 0; i++)
+ if (!strcasecmp(s, keywords[i].name)) {
+ yylval = keywords[i].value;
+ return keywords[i].token;
+ }
+ Die("%s:%d: Unknown keyword `%s'\n", Opt_modedb, line, s);
+}
+
+
+static const char *CopyString(const char *s)
+{
+ int len;
+ char *s2;
+
+ len = strlen(s)-2;
+ if (!(s2 = malloc(len+1)))
+ Die("No memory\n");
+ strncpy(s2, s+1, len);
+ s2[len] = '\0';
+ return s2;
+}
+
+
+%}
+
+keyword [a-zA-Z][a-zA-Z0-9]*
+number [0-9]*
+string \"[^\"\n]*\"
+comment \#([^\n]*)
+space [ \t]+
+junk .
+
+%%
+
+{keyword} {
+ return FindToken(yytext);
+ }
+
+{number} {
+ yylval = strtoul(yytext, NULL, 0);
+ return NUMBER;
+ }
+
+{string} {
+ yylval = (unsigned long)CopyString(yytext);
+ return STRING;
+ }
+
+{comment}$ break;
+
+{space} break;
+
+\n {
+ line++;
+ break;
+ }
+
+{junk} {
+ Die("%s:%d: Invalid token `%s'\n", Opt_modedb, line, yytext);
+ }
+
+%%
diff --git a/TVout/fbset/modes.y b/TVout/fbset/modes.y
new file mode 100644
index 0000000000..27b497a00b
--- /dev/null
+++ b/TVout/fbset/modes.y
@@ -0,0 +1,175 @@
+/*
+ * Linux Frame Buffer Device Configuration
+ *
+ * © Copyright 1995-1998 by Geert Uytterhoeven
+ * (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+
+%{
+
+#define YYSTYPE long
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fb.h"
+#include "fbset.h"
+
+extern int yylex(void);
+extern void yyerror(const char *s);
+extern int line;
+
+
+static struct VideoMode VideoMode;
+
+static void ClearVideoMode(void)
+{
+ memset(&VideoMode, 0, sizeof(VideoMode));
+ VideoMode.accel_flags = FB_ACCELF_TEXT;
+}
+
+%}
+
+%start file
+
+%token MODE GEOMETRY TIMINGS HSYNC VSYNC CSYNC GSYNC EXTSYNC BCAST LACED DOUBLE
+ RGBA NONSTD ACCEL GRAYSCALE
+ ENDMODE POLARITY BOOLEAN STRING NUMBER
+
+%%
+
+file : vmodes
+ ;
+
+
+vmodes : /* empty */
+ | vmodes vmode
+ ;
+
+vmode : MODE STRING geometry timings options ENDMODE
+ {
+ VideoMode.name = (const char *)$2;
+ AddVideoMode(&VideoMode);
+ ClearVideoMode();
+ }
+ ;
+
+geometry : GEOMETRY NUMBER NUMBER NUMBER NUMBER NUMBER
+ {
+ ClearVideoMode();
+ VideoMode.xres = $2;
+ VideoMode.yres = $3;
+ VideoMode.vxres = $4;
+ VideoMode.vyres = $5;
+ VideoMode.depth = $6;
+ }
+ ;
+
+timings : TIMINGS NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
+ {
+ VideoMode.pixclock = $2;
+ VideoMode.left = $3;
+ VideoMode.right = $4;
+ VideoMode.upper = $5;
+ VideoMode.lower = $6;
+ VideoMode.hslen = $7;
+ VideoMode.vslen = $8;
+ }
+ ;
+
+options : /* empty */
+ | options hsync
+ | options vsync
+ | options csync
+ | options gsync
+ | options extsync
+ | options bcast
+ | options laced
+ | options double
+ | options rgba
+ | options nonstd
+ | options accel
+ | options grayscale
+ ;
+
+hsync : HSYNC POLARITY
+ {
+ VideoMode.hsync = $2;
+ }
+ ;
+
+vsync : VSYNC POLARITY
+ {
+ VideoMode.vsync = $2;
+ }
+ ;
+
+csync : CSYNC POLARITY
+ {
+ VideoMode.csync = $2;
+ }
+ ;
+
+gsync : GSYNC POLARITY
+ {
+ VideoMode.gsync = $2;
+ }
+ ;
+
+extsync : EXTSYNC BOOLEAN
+ {
+ VideoMode.extsync = $2;
+ }
+ ;
+
+bcast : BCAST BOOLEAN
+ {
+ VideoMode.bcast = $2;
+ }
+ ;
+
+laced : LACED BOOLEAN
+ {
+ VideoMode.laced = $2;
+ }
+ ;
+
+double : DOUBLE BOOLEAN
+ {
+ VideoMode.dblscan = $2;
+ }
+ ;
+
+rgba : RGBA STRING
+ {
+ makeRGBA(&VideoMode, (const char*)$2);
+ }
+ ;
+
+nonstd : NONSTD NUMBER
+ {
+ VideoMode.nonstd = $2;
+ }
+ ;
+
+accel : ACCEL BOOLEAN
+ {
+ VideoMode.accel_flags = $2;
+ }
+ ;
+
+grayscale : GRAYSCALE BOOLEAN
+ {
+ VideoMode.grayscale = $2;
+ }
+ ;
+
+%%
diff --git a/TVout/independ b/TVout/independ
new file mode 100755
index 0000000000..f9c78a1335
--- /dev/null
+++ b/TVout/independ
@@ -0,0 +1,16 @@
+
+# SETUP TVout
+# Independent picture on TV and Monitor
+
+# CRTC1 -> TVout
+matroxset/matroxset -f /dev/fb0 -m 2
+
+# CRTC2 -> Monitor
+matroxset/matroxset -f /dev/fb1 -m 1
+
+# Enable TV
+matroxset/matroxset 1
+
+# move tty1-2 to CRTC2
+con2fb/con2fb /dev/fb1 /dev/tty1
+con2fb/con2fb /dev/fb1 /dev/tty2
diff --git a/TVout/matroxset/Makefile b/TVout/matroxset/Makefile
new file mode 100644
index 0000000000..364b8a9e05
--- /dev/null
+++ b/TVout/matroxset/Makefile
@@ -0,0 +1,10 @@
+CFLAGS = -O2 -W -Wall
+
+all: matroxset
+
+matrox: matroxset.o
+
+matroxset.o: matroxset.c
+
+clean:
+ -rm *.o matroxset
diff --git a/TVout/matroxset/fb.h b/TVout/matroxset/fb.h
new file mode 100644
index 0000000000..7e4fbe20a3
--- /dev/null
+++ b/TVout/matroxset/fb.h
@@ -0,0 +1,502 @@
+#ifndef _LINUX_FB_H
+#define _LINUX_FB_H
+
+#include <linux/tty.h>
+#include <asm/types.h>
+
+/* Definitions of frame buffers */
+
+#define FB_MAJOR 29
+#define FB_MAX 32 /* sufficient for now */
+
+/* ioctls
+ 0x46 is 'F' */
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOPUT_VSCREENINFO 0x4601
+#define FBIOGET_FSCREENINFO 0x4602
+#define FBIOGETCMAP 0x4604
+#define FBIOPUTCMAP 0x4605
+#define FBIOPAN_DISPLAY 0x4606
+/* 0x4607-0x460B are defined below */
+/* #define FBIOGET_MONITORSPEC 0x460C */
+/* #define FBIOPUT_MONITORSPEC 0x460D */
+/* #define FBIOSWITCH_MONIBIT 0x460E */
+#define FBIOGET_CON2FBMAP 0x460F
+#define FBIOPUT_CON2FBMAP 0x4610
+#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */
+#define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank)
+
+/* next 2 lines are temporary solution, support in 2.5 will be different */
+#define FBIOGET_VT_VSCREENINFO 0x4680
+#define FBIOPUT_VT_VSCREENINFO 0x4681
+
+
+#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+#define FB_TYPE_PLANES 1 /* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FB_TYPE_TEXT 3 /* Text/attributes */
+#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
+
+#define FB_AUX_TEXT_MDA 0 /* Monochrome text */
+#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
+#define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */
+#define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */
+#define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */
+
+#define FB_AUX_VGA_PLANES_VGA4 0 /* 16 color planes (EGA/VGA) */
+#define FB_AUX_VGA_PLANES_CFB4 1 /* CFB4 in planes (VGA) */
+#define FB_AUX_VGA_PLANES_CFB8 2 /* CFB8 in planes (VGA) */
+
+#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR 2 /* True color */
+#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+
+#define FB_ACCEL_NONE 0 /* no hardware accelerator */
+#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
+#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */
+#define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */
+#define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */
+#define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */
+#define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */
+#define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */
+#define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */
+#define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */
+#define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */
+#define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */
+#define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */
+#define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */
+#define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */
+#define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */
+#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */
+#define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */
+#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */
+#define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */
+#define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */
+#define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */
+#define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */
+#define FB_ACCEL_SUN_TCX 25 /* Sun tcx */
+#define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */
+#define FB_ACCEL_NV3 27 /* nVidia RIVA 128 */
+#define FB_ACCEL_NV4 28 /* nVidia RIVA TNT */
+#define FB_ACCEL_NV5 29 /* nVidia RIVA TNT2 */
+#define FB_ACCEL_CT_6555x 30 /* C&T 6555x */
+#define FB_ACCEL_3DFX_BANSHEE 31 /* 3Dfx Banshee */
+#define FB_ACCEL_ATI_RAGE128 32 /* ATI Rage128 family */
+
+struct fb_fix_screeninfo {
+ char id[16]; /* identification string eg "TT Builtin" */
+ unsigned long smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 type_aux; /* Interleave for interleaved Planes */
+ __u32 visual; /* see FB_VISUAL_* */
+ __u16 xpanstep; /* zero if no hardware panning */
+ __u16 ypanstep; /* zero if no hardware panning */
+ __u16 ywrapstep; /* zero if no hardware ywrap */
+ __u32 line_length; /* length of a line in bytes */
+ unsigned long mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ __u32 mmio_len; /* Length of Memory Mapped I/O */
+ __u32 accel; /* Type of acceleration available */
+ __u16 reserved[3]; /* Reserved for future compatibility */
+};
+
+/* Interpretation of offset for color fields: All offsets are from the right,
+ * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+ * can use the offset as right argument to <<). A pixel afterwards is a bit
+ * stream and is written to video memory as that unmodified. This implies
+ * big-endian byte order if bits_per_pixel is greater than 8.
+ */
+struct fb_bitfield {
+ __u32 offset; /* beginning of bitfield */
+ __u32 length; /* length of bitfield */
+ __u32 msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
+
+#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
+#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
+#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */
+#define FB_ACTIVATE_MASK 15
+ /* values */
+#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */
+#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */
+#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */
+
+#define FB_ACCELF_TEXT 1 /* text mode acceleration */
+
+#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
+#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
+#define FB_SYNC_EXT 4 /* external sync */
+#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
+#define FB_SYNC_BROADCAST 16 /* broadcast video timings */
+ /* vtotal = 144d/288n/576i => PAL */
+ /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN 32 /* sync on green */
+
+#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
+#define FB_VMODE_INTERLACED 1 /* interlaced */
+#define FB_VMODE_DOUBLE 2 /* double scan */
+#define FB_VMODE_MASK 255
+
+#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
+#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+
+struct fb_var_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 xres_virtual; /* virtual resolution */
+ __u32 yres_virtual;
+ __u32 xoffset; /* offset from virtual to visible */
+ __u32 yoffset; /* resolution */
+
+ __u32 bits_per_pixel; /* guess what */
+ __u32 grayscale; /* != 0 Graylevels instead of colors */
+
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+
+ __u32 nonstd; /* != 0 Non standard pixel format */
+
+ __u32 activate; /* see FB_ACTIVATE_* */
+
+ __u32 height; /* height of picture in mm */
+ __u32 width; /* width of picture in mm */
+
+ __u32 accel_flags; /* acceleration flags (hints) */
+
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ __u32 pixclock; /* pixel clock in ps (pico seconds) */
+ __u32 left_margin; /* time from sync to picture */
+ __u32 right_margin; /* time from picture to sync */
+ __u32 upper_margin; /* time from sync to picture */
+ __u32 lower_margin;
+ __u32 hsync_len; /* length of horizontal sync */
+ __u32 vsync_len; /* length of vertical sync */
+ __u32 sync; /* see FB_SYNC_* */
+ __u32 vmode; /* see FB_VMODE_* */
+ __u32 reserved[6]; /* Reserved for future compatibility */
+};
+
+struct fb_cmap {
+ __u32 start; /* First entry */
+ __u32 len; /* Number of entries */
+ __u16 *red; /* Red values */
+ __u16 *green;
+ __u16 *blue;
+ __u16 *transp; /* transparency, can be NULL */
+};
+
+struct fb_con2fbmap {
+ __u32 console;
+ __u32 framebuffer;
+};
+
+/* VESA Blanking Levels */
+#define VESA_NO_BLANKING 0
+#define VESA_VSYNC_SUSPEND 1
+#define VESA_HSYNC_SUSPEND 2
+#define VESA_POWERDOWN 3
+
+struct fb_monspecs {
+ __u32 hfmin; /* hfreq lower limit (Hz) */
+ __u32 hfmax; /* hfreq upper limit (Hz) */
+ __u16 vfmin; /* vfreq lower limit (Hz) */
+ __u16 vfmax; /* vfreq upper limit (Hz) */
+ unsigned dpms : 1; /* supports DPMS */
+};
+
+/* next structure is only 2.2 temporary hack, 2.3 solution will be different */
+struct fb_vt_info {
+ __u32 console;
+ struct fb_var_screeninfo *info;
+};
+
+#define FB_VBLANK_VBLANKING 1 /* currently in a vertical blank */
+#define FB_VBLANK_HBLANKING 2 /* currently in a horizontal blank */
+#define FB_VBLANK_HAVE_VBLANK 4 /* vertical blanks can be detected */
+#define FB_VBLANK_HAVE_HBLANK 8 /* horizontal blanks can be detected */
+#define FB_VBLANK_HAVE_COUNT 16 /* global retrace counter is available */
+#define FB_VBLANK_HAVE_VCOUNT 32 /* the vcount field is valid */
+#define FB_VBLANK_HAVE_HCOUNT 64 /* the hcount field is valid */
+
+struct fb_vblank {
+ __u32 flags; /* FB_VBLANK flags */
+ __u32 count; /* counter of retraces since boot */
+ __s32 vcount; /* current scanline position */
+ __s32 hcount; /* current scandot position */
+ __u32 reserved[4]; /* reserved for future compatibility */
+};
+
+#ifdef __KERNEL__
+
+#if 1 /* to go away in 2.4.0 */
+extern int GET_FB_IDX(kdev_t rdev);
+#else
+#define GET_FB_IDX(node) (MINOR(node))
+#endif
+
+#include <linux/fs.h>
+#include <linux/init.h>
+
+
+struct fb_info;
+struct fb_info_gen;
+struct vm_area_struct;
+struct file;
+
+ /*
+ * Frame buffer operations
+ */
+
+struct fb_ops {
+ /* open/release and usage marking */
+ int (*fb_open)(struct fb_info *info, int user);
+ int (*fb_release)(struct fb_info *info, int user);
+ /* get non settable parameters */
+ int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+ /* get settable parameters */
+ int (*fb_get_var)(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+ /* set settable parameters */
+ int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+ /* get colormap */
+ int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+ /* set colormap */
+ int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+ /* pan display */
+ int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+ /* perform fb specific ioctl */
+ int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg, int con, struct fb_info *info);
+ /* perform fb specific mmap */
+ int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+ /* switch to/from raster image mode */
+ int (*fb_rasterimg)(struct fb_info *info, int start);
+};
+
+struct fb_info {
+ char modename[40]; /* default video mode */
+ kdev_t node;
+ int flags;
+ int open; /* Has this been open already ? */
+#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
+ struct fb_fix_screeninfo fix; /* Current fix */
+ struct fb_monspecs monspecs; /* Current Monitor specs */
+ struct fb_ops *fbops;
+ char *screen_base; /* Virtual address */
+ struct display *disp; /* initial display variable */
+ struct display *currcon;
+ struct vc_data *display_fg; /* Console visible on this display */
+ char fontname[40]; /* default font name */
+ int (*changevar)(int); /* tell console var has changed */
+ int (*switch_con)(int, struct fb_info*);
+ /* tell fb to switch consoles */
+ int (*updatevar)(int, struct fb_info*);
+ /* tell fb to update the vars */
+ void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */
+ /* arg = 0: unblank */
+ /* arg > 0: VESA level (arg-1) */
+ void *pseudo_palette; /* Fake palette of 16 colors and
+ the cursor's color for non
+ palette mode */
+ /* From here on everything is device dependent */
+ void *par;
+};
+
+#ifdef MODULE
+#define FBINFO_FLAG_DEFAULT FBINFO_FLAG_MODULE
+#else
+#define FBINFO_FLAG_DEFAULT 0
+#endif
+
+ /*
+ * This structure abstracts from the underlying hardware. It is not
+ * mandatory but used by the `generic' frame buffer operations.
+ * Read drivers/video/skeletonfb.c for more information.
+ */
+
+struct fbgen_hwswitch {
+ void (*detect)(void);
+ int (*encode_fix)(struct fb_fix_screeninfo *fix, const void *par,
+ struct fb_info_gen *info);
+ int (*decode_var)(const struct fb_var_screeninfo *var, void *par,
+ struct fb_info_gen *info);
+ int (*encode_var)(struct fb_var_screeninfo *var, const void *par,
+ struct fb_info_gen *info);
+ void (*get_par)(void *par, struct fb_info_gen *info);
+ void (*set_par)(const void *par, struct fb_info_gen *info);
+ int (*getcolreg)(unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp, struct fb_info *info);
+ int (*setcolreg)(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info);
+ int (*pan_display)(const struct fb_var_screeninfo *var,
+ struct fb_info_gen *info);
+ int (*blank)(int blank_mode, struct fb_info_gen *info);
+ void (*set_disp)(const void *par, struct display *disp,
+ struct fb_info_gen *info);
+};
+
+struct fb_info_gen {
+ struct fb_info info;
+
+ /* Entries for a generic frame buffer device */
+ /* Yes, this starts looking like C++ */
+ u_int parsize;
+ struct fbgen_hwswitch *fbhw;
+
+ /* From here on everything is device dependent */
+};
+
+ /*
+ * `Generic' versions of the frame buffer device operations
+ */
+
+extern int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+extern int fbgen_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+extern int fbgen_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+extern int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+extern int fbgen_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info);
+
+ /*
+ * Helper functions
+ */
+
+extern int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
+ struct fb_info_gen *info);
+extern void fbgen_set_disp(int con, struct fb_info_gen *info);
+extern void fbgen_install_cmap(int con, struct fb_info_gen *info);
+extern int fbgen_update_var(int con, struct fb_info *info);
+extern int fbgen_switch(int con, struct fb_info *info);
+extern void fbgen_blank(int blank, struct fb_info *info);
+
+
+/* drivers/video/fbmem.c */
+extern int register_framebuffer(struct fb_info *fb_info);
+extern int unregister_framebuffer(const struct fb_info *fb_info);
+
+extern int num_registered_fb;
+extern struct fb_info *registered_fb[FB_MAX];
+
+/* drivers/video/fbmon.c */
+extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
+ const struct fb_info *fb_info);
+extern int fbmon_dpms(const struct fb_info *fb_info);
+
+/* drivers/video/fbcmap.c */
+extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
+ int fsfromto);
+extern int fb_get_cmap(struct fb_cmap *cmap, int kspc,
+ int (*getcolreg)(u_int, u_int *, u_int *, u_int *,
+ u_int *, struct fb_info *),
+ struct fb_info *fb_info);
+extern int fb_set_cmap(struct fb_cmap *cmap, int kspc,
+ int (*setcolreg)(u_int, u_int, u_int, u_int, u_int,
+ struct fb_info *),
+ struct fb_info *fb_info);
+extern struct fb_cmap *fb_default_cmap(int len);
+extern void fb_invert_cmaps(void);
+
+struct fb_videomode {
+ const char *name; /* optional */
+ u32 refresh; /* optional */
+ u32 xres;
+ u32 yres;
+ u32 pixclock;
+ u32 left_margin;
+ u32 right_margin;
+ u32 upper_margin;
+ u32 lower_margin;
+ u32 hsync_len;
+ u32 vsync_len;
+ u32 sync;
+ u32 vmode;
+};
+
+extern int __init fb_find_mode(struct fb_var_screeninfo *var,
+ struct fb_info *info, const char *mode_option,
+ const struct fb_videomode *db,
+ unsigned int dbsize,
+ const struct fb_videomode *default_mode,
+ unsigned int default_bpp);
+
+#endif /* __KERNEL__ */
+
+#if 1
+
+#define FBCMD_GET_CURRENTPAR 0xDEAD0005
+#define FBCMD_SET_CURRENTPAR 0xDEAD8005
+
+#endif
+
+
+#if 1 /* Preliminary */
+
+ /*
+ * Hardware Cursor
+ */
+
+#define FBIOGET_FCURSORINFO 0x4607
+#define FBIOGET_VCURSORINFO 0x4608
+#define FBIOPUT_VCURSORINFO 0x4609
+#define FBIOGET_CURSORSTATE 0x460A
+#define FBIOPUT_CURSORSTATE 0x460B
+
+
+struct fb_fix_cursorinfo {
+ __u16 crsr_width; /* width and height of the cursor in */
+ __u16 crsr_height; /* pixels (zero if no cursor) */
+ __u16 crsr_xsize; /* cursor size in display pixels */
+ __u16 crsr_ysize;
+ __u16 crsr_color1; /* colormap entry for cursor color1 */
+ __u16 crsr_color2; /* colormap entry for cursor color2 */
+};
+
+struct fb_var_cursorinfo {
+ __u16 width;
+ __u16 height;
+ __u16 xspot;
+ __u16 yspot;
+ __u8 data[1]; /* field with [height][width] */
+};
+
+struct fb_cursorstate {
+ __s16 xoffset;
+ __s16 yoffset;
+ __u16 mode;
+};
+
+#define FB_CURSOR_OFF 0
+#define FB_CURSOR_ON 1
+#define FB_CURSOR_FLASH 2
+
+#endif /* Preliminary */
+
+#endif /* _LINUX_FB_H */
diff --git a/TVout/matroxset/matroxfb.h b/TVout/matroxset/matroxfb.h
new file mode 100644
index 0000000000..182d76b25a
--- /dev/null
+++ b/TVout/matroxset/matroxfb.h
@@ -0,0 +1,32 @@
+#ifndef __LINUX_MATROXFB_H__
+#define __LINUX_MATROXFB_H__
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+struct matroxioc_output_mode {
+ __u32 output; /* which output */
+#define MATROXFB_OUTPUT_PRIMARY 0x0000
+#define MATROXFB_OUTPUT_SECONDARY 0x0001
+ __u32 mode; /* which mode */
+#define MATROXFB_OUTPUT_MODE_PAL 0x0001
+#define MATROXFB_OUTPUT_MODE_NTSC 0x0002
+#define MATROXFB_OUTPUT_MODE_MONITOR 0x0080
+};
+#define MATROXFB_SET_OUTPUT_MODE _IOW('n',0xFA,sizeof(struct matroxioc_output_mode))
+#define MATROXFB_GET_OUTPUT_MODE _IOWR('n',0xFA,sizeof(struct matroxioc_output_mode))
+
+/* bitfield */
+#define MATROXFB_OUTPUT_CONN_PRIMARY (1 << MATROXFB_OUTPUT_PRIMARY)
+#define MATROXFB_OUTPUT_CONN_SECONDARY (1 << MATROXFB_OUTPUT_SECONDARY)
+/* connect these outputs to this framebuffer */
+#define MATROXFB_SET_OUTPUT_CONNECTION _IOW('n',0xF8,sizeof(__u32))
+/* which outputs are connected to this framebuffer */
+#define MATROXFB_GET_OUTPUT_CONNECTION _IOR('n',0xF8,sizeof(__u32))
+/* which outputs are available for this framebuffer */
+#define MATROXFB_GET_AVAILABLE_OUTPUTS _IOR('n',0xF9,sizeof(__u32))
+/* which outputs exist on this framebuffer */
+#define MATROXFB_GET_ALL_OUTPUTS _IOR('n',0xFB,sizeof(__u32))
+
+#endif
+
diff --git a/TVout/matroxset/matroxset.c b/TVout/matroxset/matroxset.c
new file mode 100644
index 0000000000..af989156f9
--- /dev/null
+++ b/TVout/matroxset/matroxset.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include "fb.h"
+#include "matroxfb.h"
+
+static int help(void) {
+ fprintf(stderr, "usage: matroxset [-f fbdev] [-o output] [-m] [value]\n"
+ "\n"
+ "where -f fbdev is fbdev device (default /dev/fb1)\n"
+ " -o output is output number to investigate (0=primary, 1=secondary=default)\n"
+ " -m says that CRTC->output mapping should be changed/retrieved\n"
+ " -p print information about blanking\n"
+ " value if present, value is set, if missing, value is retrieved\n"
+ "\n"
+ "For output mode, 128 means monitor, 1 = PAL TV, 2 = NTSC TV\n");
+ return 98;
+}
+
+int main(int argc, char* argv[]) {
+ char* fb = "/dev/fb1";
+ int fd;
+ struct matroxioc_output_mode mom;
+ struct fb_vblank vbl;
+ int rtn;
+ int output = MATROXFB_OUTPUT_SECONDARY;
+ int o_present = 0;
+ int m_present = 0;
+ int p_present = 0;
+ int act;
+ u_int32_t conns;
+
+ while ((rtn = getopt(argc, argv, "o:f:mhp")) != -1) {
+ switch (rtn) {
+ case 'o':
+ output = strtoul(optarg, NULL, 0);
+ o_present = 1;
+ break;
+ case 'm':
+ m_present = 1;
+ break;
+ case 'f':
+ fb = optarg;
+ break;
+ case 'p':
+ p_present = 1;
+ break;
+ case 'h':
+ return help();
+ default:
+ fprintf(stderr, "Bad commandline\n");
+ return 99;
+ }
+ }
+ act = 0;
+ if (p_present) {
+ if (m_present || o_present) {
+ fprintf(stderr, "You cannot use -p together with -m or -o\n");
+ return 95;
+ }
+ act = 4;
+ } else if (optind >= argc) {
+ if (m_present) {
+ if (o_present) {
+ fprintf(stderr, "You cannot use -m and -o together\n");
+ return 96;
+ }
+ act = 2;
+ } else {
+ mom.output = output;
+ mom.mode = 0;
+ }
+ } else {
+ if (m_present) {
+ conns = strtoul(argv[optind], NULL, 0);
+ act = 3;
+ } else {
+ mom.output = output;
+ mom.mode = strtoul(argv[optind], NULL, 0);
+ act = 1;
+ }
+ }
+ fd = open(fb, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "Cannot open %s: %s\n", fb, strerror(errno));
+ return 122;
+ }
+ switch (act) {
+ case 0:
+ rtn = ioctl(fd, MATROXFB_GET_OUTPUT_MODE, &mom);
+ if (rtn)
+ break;
+ printf("Output mode is %u\n", mom.mode);
+ break;
+ case 1:
+ rtn = ioctl(fd, MATROXFB_SET_OUTPUT_MODE, &mom);
+ break;
+ case 2:
+ rtn = ioctl(fd, MATROXFB_GET_OUTPUT_CONNECTION, &conns);
+ if (rtn)
+ break;
+ printf("This framebuffer is connected to outputs %08X\n", conns);
+ break;
+ case 3:
+ rtn = ioctl(fd, MATROXFB_SET_OUTPUT_CONNECTION, &conns);
+ break;
+ case 4:
+#if 0
+ { int i; for (i = 0; i < 1000000; i++) {
+ rtn = ioctl(fd, FBIOGET_VBLANK, &vbl);
+ if (rtn)
+ break;
+ }}
+#else
+ rtn = ioctl(fd, FBIOGET_VBLANK, &vbl);
+ if (rtn)
+ break;
+#endif
+ printf("VBlank flags: %08X\n", vbl.flags);
+ printf(" Symbolic: ");
+ {
+ static const struct { u_int32_t mask; const char* msg; } *ptr, vals[] = {
+ { FB_VBLANK_HAVE_VBLANK, "vblank" },
+ { FB_VBLANK_HAVE_HBLANK, "hblank" },
+ { FB_VBLANK_HAVE_COUNT, "field no." },
+ { FB_VBLANK_HAVE_VCOUNT, "line no." },
+ { FB_VBLANK_HAVE_HCOUNT, "column no." },
+ { FB_VBLANK_VBLANKING, "vblanking" },
+ { FB_VBLANK_HBLANKING, "hblanking" },
+ { 0, NULL }};
+ int ap = 0;
+ for (ptr = vals; ptr->msg; ptr++) {
+ if (vbl.flags & ptr->mask) {
+ if (ap) printf(", ");
+ printf(ptr->msg);
+ ap = 1;
+ }
+ }
+ if (!ap)
+ printf("none");
+ printf("\n");
+ }
+ printf("Field count: %12u\n", vbl.count);
+ printf("Vertical line: %12u\n", vbl.vcount);
+ printf("Horizontal column: %12u\n", vbl.hcount);
+ break;
+ default:
+ rtn = -1; errno = EINVAL;
+ break;
+ }
+ if (rtn) {
+ fprintf(stderr, "ioctl failed: %s\n", strerror(errno));
+ }
+ close(fd);
+ return 0;
+}
+
diff --git a/TVout/matroxset/normal b/TVout/matroxset/normal
new file mode 100755
index 0000000000..f17caf5351
--- /dev/null
+++ b/TVout/matroxset/normal
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+if [ -c /dev/fb0 ]; then
+ HEAD0=/dev/fb0
+ HEAD1=/dev/fb1
+else
+ HEAD0=/dev/fb/0
+ HEAD1=/dev/fb/1
+fi
+matroxset -f ${HEAD1} -m 0
+matroxset -f ${HEAD0} -m 1
+matroxset -f ${HEAD1} -m 2
diff --git a/TVout/matroxset/swapit b/TVout/matroxset/swapit
new file mode 100755
index 0000000000..918f54618c
--- /dev/null
+++ b/TVout/matroxset/swapit
@@ -0,0 +1,5 @@
+#! /bin/sh
+~/mga/con2fb /dev/fb0 /dev/tty4
+rmmod matroxfb_maven
+modprobe matroxfb_maven
+~/mga/con2fb /dev/fb1 /dev/tty4
diff --git a/TVout/matroxset/swapped b/TVout/matroxset/swapped
new file mode 100755
index 0000000000..c6dc7cf016
--- /dev/null
+++ b/TVout/matroxset/swapped
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+if [ -c /dev/fb0 ]; then
+ HEAD0=/dev/fb0
+ HEAD1=/dev/fb1
+else
+ HEAD0=/dev/fb/0
+ HEAD1=/dev/fb/1
+fi
+matroxset -f ${HEAD1} -m 0
+matroxset -f ${HEAD0} -m 2
+matroxset -f ${HEAD1} -m 1
diff --git a/TVout/modules b/TVout/modules
new file mode 100755
index 0000000000..2c210e97f3
--- /dev/null
+++ b/TVout/modules
@@ -0,0 +1,8 @@
+
+# Load kernel modules...
+# (you must have 2.3/2.4 kernel with matroxfb enabled!)
+
+modprobe i2c-matroxfb
+modprobe matroxfb_Ti3026
+modprobe matroxfb_crtc2
+modprobe matroxfb_maven
diff --git a/alaw.c b/alaw.c
new file mode 100644
index 0000000000..de8c43962c
--- /dev/null
+++ b/alaw.c
@@ -0,0 +1,29 @@
+// code from xanim sources...
+// (I hope that not hurt copyright :o)
+
+#define xaLONG long
+#define xaULONG unsigned long
+#define xaBYTE char
+#define xaUBYTE unsigned char
+
+xaULONG long xa_alaw_2_sign[256];
+
+void Gen_aLaw_2_Signed()
+{ xaULONG i;
+ for(i=0;i<256;i++)
+ { xaUBYTE data = (xaUBYTE)(i);
+ xaLONG d, t, seg;
+
+ data ^= 0x55;
+
+ t = (data & 0xf) << 4;
+ seg = (data & 0x70) >> 4;
+ if (seg == 0) t += 8;
+ else if (seg == 1) t += 0x108;
+ else { t += 108; t <<= seg - 1; }
+
+ d = (data & 0x80)?(t):(-t);
+ xa_alaw_2_sign[i] = (xaULONG)((xaULONG)(d) & 0xffff);
+ }
+}
+
diff --git a/asfheader.c b/asfheader.c
new file mode 100644
index 0000000000..c5e9064e7c
--- /dev/null
+++ b/asfheader.c
@@ -0,0 +1,183 @@
+// .asf fileformat docs from http://divx.euro.ru
+
+typedef struct __attribute__((packed)) {
+ unsigned char guid[16];
+ unsigned long long size;
+} ASF_obj_header_t;
+
+typedef struct __attribute__((packed)) {
+ ASF_obj_header_t objh;
+ unsigned int cno; // number of subchunks
+ unsigned char v1; // unknown (0x01)
+ unsigned char v2; // unknown (0x02)
+} ASF_header_t;
+
+typedef struct __attribute__((packed)) {
+ unsigned char client[16]; // Client GUID
+ unsigned long long file_size;
+ unsigned long long creat_time; //File creation time FILETIME 8
+ unsigned long long packets; //Number of packets UINT64 8
+ unsigned long long end_timestamp; //Timestamp of the end position UINT64 8
+ unsigned long long duration; //Duration of the playback UINT64 8
+ unsigned long start_timestamp; //Timestamp of the start position UINT32 4
+ unsigned long unk1; //Unknown, maybe reserved ( usually contains 0 ) UINT32 4
+ unsigned long flags; //Unknown, maybe flags ( usually contains 2 ) UINT32 4
+ unsigned long packetsize; //Size of packet, in bytes UINT32 4
+ unsigned long packetsize2; //Size of packet ( confirm ) UINT32 4
+ unsigned long frame_size; //Size of uncompressed video frame UINT32 4
+} ASF_file_header_t;
+
+typedef struct __attribute__((packed)) {
+ unsigned char type[16]; // Stream type (audio/video) GUID 16
+ unsigned char concealment[16]; // Audio error concealment type GUID 16
+ unsigned long long unk1; // Unknown, maybe reserved ( usually contains 0 ) UINT64 8
+ unsigned long type_size; //Total size of type-specific data UINT32 4
+ unsigned long stream_size; //Size of stream-specific data UINT32 4
+ unsigned short stream_no; //Stream number UINT16 2
+ unsigned long unk2; //Unknown UINT32 4
+} ASF_stream_header_t;
+
+
+ASF_header_t asfh;
+ASF_obj_header_t objh;
+ASF_file_header_t fileh;
+ASF_stream_header_t streamh;
+unsigned char* asf_packet=NULL;
+//int asf_video_id=-1;
+int asf_scrambling_h=1;
+int asf_scrambling_w=1;
+int asf_scrambling_b=1;
+
+int i;
+
+void asf_descrambling(unsigned char *src,int len){
+ unsigned char *dst=malloc(len);
+ unsigned char *s2=src;
+ int i=0,x,y;
+ while(len-i>=asf_scrambling_h*asf_scrambling_w*asf_scrambling_b){
+// printf("descrambling! (w=%d b=%d)\n",w,asf_scrambling_b);
+ //i+=asf_scrambling_h*asf_scrambling_w;
+ for(x=0;x<asf_scrambling_w;x++)
+ for(y=0;y<asf_scrambling_h;y++){
+ memcpy(dst+i,s2+(y*asf_scrambling_w+x)*asf_scrambling_b,asf_scrambling_b);
+ i+=asf_scrambling_b;
+ }
+ s2+=asf_scrambling_h*asf_scrambling_w*asf_scrambling_b;
+ }
+ //if(i<len) memcpy(dst+i,src+i,len-i);
+ memcpy(src,dst,i);
+ free(dst);
+}
+
+char* asf_chunk_type(unsigned char* guid){
+ switch(*((unsigned int*)guid)){
+ case 0xF8699E40: return "guid_audio_stream";
+ case 0xBC19EFC0: return "guid_video_stream";
+ case 0x49f1a440: return "guid_audio_conceal_none";
+ case 0xbfc3cd50: return "guid_audio_conceal_interleave";
+ case 0x75B22630: return "guid_header";
+ case 0x75b22636: return "guid_data_chunk";
+ case 0x33000890: return "guid_index_chunk";
+ case 0xB7DC0791: return "guid_stream_header";
+ case 0xD6E229D1: return "guid_header_2_0";
+ case 0x8CABDCA1: return "guid_file_header";
+ }
+ return NULL;
+}
+
+int asf_check_header(){
+ unsigned char asfhdrguid[16]={0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C};
+ int i;
+ stream_read(demuxer->stream,(char*) &asfh,sizeof(asfh)); // header obj
+// for(i=0;i<16;i++) printf(" %02X",temp[i]);printf("\n");
+// for(i=0;i<16;i++) printf(" %02X",asfhdrguid[i]);printf("\n");
+ if(memcmp(asfhdrguid,asfh.objh.guid,16)){
+ if(verbose) printf("ASF_check: not ASF guid!\n");
+ return 0; // not ASF guid
+ }
+ if(asfh.cno>256){
+ if(verbose) printf("ASF_check: invalid subchunks_no %d\n",(int) asfh.cno);
+ return 0; // invalid header???
+ }
+ return 1;
+}
+
+int read_asf_header(){
+ unsigned char buffer[512];
+
+#if 1
+ printf("ASF file! (subchunks: %d)\n",asfh.cno);
+while(!stream_eof(demuxer->stream)){
+ int pos,endpos;
+ pos=stream_tell(demuxer->stream);
+ stream_read(demuxer->stream,(char*) &objh,sizeof(objh));
+ if(stream_eof(demuxer->stream)) break; // EOF
+ endpos=pos+objh.size;
+// for(i=0;i<16;i++) printf("%02X ",objh.guid[i]);
+ printf("0x%08X [%s] %d\n",pos, asf_chunk_type(objh.guid),(int) objh.size);
+ switch(*((unsigned int*)&objh.guid)){
+ case 0xB7DC0791: // guid_stream_header
+ stream_read(demuxer->stream,(char*) &streamh,sizeof(streamh));
+ printf("stream type: %s\n",asf_chunk_type(streamh.type));
+ printf("stream concealment: %s\n",asf_chunk_type(streamh.concealment));
+ printf("type: %d bytes, stream: %d bytes ID: %d\n",(int)streamh.type_size,(int)streamh.stream_size,(int)streamh.stream_no);
+ printf("unk1: %lX unk2: %X\n",streamh.unk1,streamh.unk2);
+ printf("FILEPOS=0x%X\n",stream_tell(demuxer->stream));
+ // type-specific data:
+ stream_read(demuxer->stream,(char*) buffer,streamh.type_size);
+ switch(*((unsigned int*)&streamh.type)){
+ case 0xF8699E40: // guid_audio_stream
+ memcpy(avi_header.wf_ext,buffer,streamh.type_size<64?streamh.type_size:64);
+ if(verbose>=1) print_wave_header((WAVEFORMATEX*)buffer);
+ if((*((unsigned int*)&streamh.concealment))==0xbfc3cd50){
+ stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
+ asf_scrambling_h=buffer[0];
+ asf_scrambling_w=(buffer[2]<<8)|buffer[1];
+ asf_scrambling_b=(buffer[4]<<8)|buffer[3];
+ asf_scrambling_w/=asf_scrambling_b;
+ } else {
+ asf_scrambling_b=asf_scrambling_h=asf_scrambling_w=1;
+ }
+ printf("ASF audio scrambling: %d x %d x %d\n",asf_scrambling_h,asf_scrambling_w,asf_scrambling_b);
+ if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F;
+ break;
+ case 0xBC19EFC0: // guid_video_stream
+ memcpy(&avi_header.bih,&buffer[4+4+1+2],sizeof(BITMAPINFOHEADER));
+ if(verbose>=1) print_video_header((BITMAPINFOHEADER*)&buffer[4+4+1+2]);
+ //asf_video_id=streamh.stream_no & 0x7F;
+ if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
+ break;
+ }
+ // stream-specific data:
+ // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size);
+ break;
+// case 0xD6E229D1: return "guid_header_2_0";
+ case 0x8CABDCA1: // guid_file_header
+ stream_read(demuxer->stream,(char*) &fileh,sizeof(fileh));
+ printf("packets: %d flags: %d pack_size: %d frame_size: %d\n",(int)fileh.packets,(int)fileh.flags,(int)fileh.packetsize,(int)fileh.frame_size);
+ asf_packet=malloc(fileh.packetsize); // !!!
+ break;
+ case 0x75b22636: // guid_data_chunk
+ avi_header.movi_start=stream_tell(demuxer->stream)+26;
+ avi_header.movi_end=endpos;
+ if(verbose>=1) printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
+ break;
+
+// case 0x33000890: return "guid_index_chunk";
+
+ } // switch GUID
+ if(!stream_seek(demuxer->stream,endpos)) break;
+} // while EOF
+
+#if 0
+if(verbose){
+ printf("ASF duration: %d\n",(int)fileh.duration);
+ printf("ASF start pts: %d\n",(int)fileh.start_timestamp);
+ printf("ASF end pts: %d\n",(int)fileh.end_timestamp);
+}
+#endif
+
+#endif
+return 1;
+}
+
diff --git a/aviheader.c b/aviheader.c
new file mode 100644
index 0000000000..9fd8c220c1
--- /dev/null
+++ b/aviheader.c
@@ -0,0 +1,89 @@
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+void read_avi_header(int no_index){
+
+int stream_id=-1;
+
+//---- AVI header:
+avi_header.idx_size=0;
+while(1){
+ int id=stream_read_dword_le(demuxer->stream);
+ int chunksize,size2;
+ static int last_fccType=0;
+ //
+ if(stream_eof(demuxer->stream)) break;
+ //
+ if(id==mmioFOURCC('L','I','S','T')){
+ int len=stream_read_dword_le(demuxer->stream)-4; // list size
+ id=stream_read_dword_le(demuxer->stream); // list type
+ if(verbose>=2) printf("LIST %.4s len=%d\n",&id,len);
+ if(id==listtypeAVIMOVIE){
+ // found MOVI header
+ avi_header.movi_start=stream_tell(demuxer->stream);
+ avi_header.movi_end=avi_header.movi_start+len;
+ if(verbose>=1) printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
+ len=(len+1)&(~1);
+ stream_skip(demuxer->stream,len);
+ }
+ continue;
+ }
+ size2=stream_read_dword_le(demuxer->stream);
+ if(verbose>=2) printf("CHUNK %.4s len=%d\n",&id,size2);
+ chunksize=(size2+1)&(~1);
+ switch(id){
+ case ckidAVIMAINHDR: // read 'avih'
+ stream_read(demuxer->stream,(char*) &avi_header.avih,MIN(size2,sizeof(avi_header.avih)));
+ chunksize-=MIN(size2,sizeof(avi_header.avih));
+ if(verbose) print_avih(&avi_header.avih);
+ break;
+ case ckidSTREAMHEADER: { // read 'strh'
+ AVIStreamHeader h;
+ stream_read(demuxer->stream,(char*) &h,MIN(size2,sizeof(h)));
+ chunksize-=MIN(size2,sizeof(h));
+ if(h.fccType==streamtypeVIDEO) memcpy(&avi_header.video,&h,sizeof(h));else
+ if(h.fccType==streamtypeAUDIO) memcpy(&avi_header.audio,&h,sizeof(h));
+ last_fccType=h.fccType;
+ if(verbose>=1) print_strh(&h);
+ ++stream_id;
+ break; }
+ case ckidSTREAMFORMAT: { // read 'strf'
+ if(last_fccType==streamtypeVIDEO){
+ stream_read(demuxer->stream,(char*) &avi_header.bih,MIN(size2,sizeof(avi_header.bih)));
+ chunksize-=MIN(size2,sizeof(avi_header.bih));
+// init_video_codec();
+// init_video_out();
+ if(demuxer->video->id==-1) demuxer->video->id=stream_id;
+ } else
+ if(last_fccType==streamtypeAUDIO){
+ int z=(chunksize<64)?chunksize:64;
+ if(verbose>=2) printf("found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX));
+ stream_read(demuxer->stream,(char*) &avi_header.wf_ext,z);
+ chunksize-=z;
+ if(verbose>=1) print_wave_header((WAVEFORMATEX*)&avi_header.wf_ext);
+// init_audio_codec();
+// init_audio_out();
+ if(demuxer->audio->id==-1) demuxer->audio->id=stream_id;
+ }
+ break;
+ }
+ case ckidAVINEWINDEX: if(!no_index){
+ avi_header.idx_size=size2>>4;
+ if(verbose>=1) printf("Reading INDEX block, %d chunks for %d frames\n",
+ avi_header.idx_size,avi_header.avih.dwTotalFrames);
+ avi_header.idx=malloc(avi_header.idx_size<<4);
+ stream_read(demuxer->stream,(char*)avi_header.idx,avi_header.idx_size<<4);
+ chunksize-=avi_header.idx_size<<4;
+ if(verbose>=2) print_index();
+ break;
+ }
+ }
+ if(chunksize>0) stream_skip(demuxer->stream,chunksize); else
+ if(chunksize<0) printf("WARNING!!! chunksize=%d (id=%.4s)\n",chunksize,&id);
+
+}
+
+}
+
+#undef MIN
+
diff --git a/aviparse.c b/aviparse.c
new file mode 100644
index 0000000000..2fd34e9033
--- /dev/null
+++ b/aviparse.c
@@ -0,0 +1,336 @@
+// AVI Parser tool v0.1 (C) 2000. by A'rpi/ESP-team
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <signal.h>
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/cdrom.h>
+
+#include "config.h"
+
+#include "loader.h"
+#include "wine/avifmt.h"
+//#include "libvo/video_out.h"
+
+#include "linux/timer.h"
+#include "linux/shmem.h"
+
+#include "help_avp.h"
+
+#define DEBUG if(0)
+
+//static int show_packets=0;
+
+typedef struct {
+ // file:
+ MainAVIHeader avih;
+ unsigned int movi_start;
+ unsigned int movi_end;
+ // index:
+ AVIINDEXENTRY* idx;
+ int idx_size;
+ int idx_pos;
+// int a_idx;
+// int v_idx;
+ // video:
+ AVIStreamHeader video;
+ char *video_codec;
+ BITMAPINFOHEADER bih; // in format
+ BITMAPINFOHEADER o_bih; // out format
+ HIC hic;
+ void *our_out_buffer;
+ char yuv_supported; // 1 if codec support YUY2 output format
+ char yuv_hack_needed; // requires for divx & mpeg4
+ // audio:
+ AVIStreamHeader audio;
+ char *audio_codec;
+ char wf_ext[64]; // in format
+ WAVEFORMATEX wf; // out format
+ HACMSTREAM srcstream;
+ int audio_minsize;
+} avi_header_t;
+
+avi_header_t avi_header;
+
+#include "aviprint.c"
+//#include "codecs.c"
+
+//**************************************************************************//
+#include "stream.c"
+//#include "demuxer.c"
+//#include "demux_avi.c"
+
+static stream_t* stream=NULL;
+
+//**************************************************************************//
+
+extern int errno;
+static int play_in_bg=0;
+
+void exit_player(){
+// int tmp;
+ // restore terminal:
+ getch2_disable();
+ printf("\n\n");
+ if(play_in_bg) system("xsetroot -solid \\#000000");
+ exit(1);
+}
+
+void exit_sighandler(int x){
+ printf("\nmpgplay2 interrupted by signal %d\n",x);
+ exit_player();
+}
+
+
+int main(int argc,char* argv[]){
+char* filename=NULL; //"MI2-Trailer.avi";
+int i;
+//int seek_to_sec=0;
+int seek_to_byte=0;
+int f; // filedes
+int has_audio=1;
+//int audio_format=0;
+//int alsa=0;
+//int audio_buffer_size=-1;
+int audio_id=-1;
+//int video_id=-1;
+//float default_max_pts_correction=0.01f;
+//int delay_corrected=0;
+//float force_fps=0;
+//float default_fps=25;
+//float audio_delay=0;
+int stream_type;
+//int elementary_stream=0;
+int vcd_track=0;
+#ifdef VCD_CACHE
+int vcd_cache_size=128;
+#endif
+//char* video_driver="mga"; // default
+//int out_fmt=0;
+int idx_filepos=0;
+FILE *audiofile=NULL;
+FILE *videofile=NULL;
+char *audiofile_name=NULL;
+char *videofile_name=NULL;
+
+ printf("%s",banner_text);
+
+for(i=1;i<argc;i++){
+ if(strcmp(argv[i],"-afile")==0) audiofile_name=argv[++i]; else
+ if(strcmp(argv[i],"-vfile")==0) videofile_name=argv[++i]; else
+// if(strcmp(argv[i],"-sb")==0) seek_to_byte=strtol(argv[++i],NULL,0); else
+ if(strcmp(argv[i],"-aid")==0) audio_id=strtol(argv[++i],NULL,0); else
+// if(strcmp(argv[i],"-vid")==0) video_id=strtol(argv[++i],NULL,0); else
+// if(strcmp(argv[i],"-afm")==0) audio_format=strtol(argv[++i],NULL,0); else
+// if(strcmp(argv[i],"-vcd")==0) vcd_track=strtol(argv[++i],NULL,0); else
+ if(strcmp(argv[i],"-h")==0) break; else
+ if(strcmp(argv[i],"--help")==0) break; else
+ { if(filename){ printf("invalid option: %s\n",filename);exit(1);}
+ filename=argv[i];
+ }
+}
+
+if(!filename){
+ if(vcd_track) filename="/dev/cdrom";
+// else
+// filename="/4/Film/Joan of Arc [Hun DivX]/Joan of Arc - CD2.avi";
+ { printf("%s",help_text); exit(0);}
+}
+
+
+if(vcd_track){
+//============ Open VideoCD track ==============
+ f=open(filename,O_RDONLY);
+ if(f<0){ printf("Device not found!\n");return 1; }
+ vcd_read_toc(f);
+ if(!vcd_seek_to_track(f,vcd_track)){ printf("Error selecting VCD track!\n");return 1;}
+ seek_to_byte+=VCD_SECTOR_DATA*vcd_get_msf();
+ stream_type=STREAMTYPE_VCD;
+#ifdef VCD_CACHE
+ vcd_cache_init(vcd_cache_size);
+#endif
+} else {
+//============ Open plain FILE ============
+ f=open(filename,O_RDONLY);
+ if(f<0){ printf("File not found!\n");return 1; }
+ stream_type=STREAMTYPE_FILE;
+}
+
+//============ Open & Sync stream and detect file format ===============
+
+stream=new_stream(f,stream_type);
+//=============== Read AVI header:
+{ //---- RIFF header:
+ int id=stream_read_dword_le(stream); // "RIFF"
+ if(id!=mmioFOURCC('R','I','F','F')){ printf("Not RIFF format file!\n");return 1; }
+ stream_read_dword_le(stream); //filesize
+ id=stream_read_dword_le(stream); // "AVI "
+ if(id!=formtypeAVI){ printf("Not AVI file!\n");return 1; }
+}
+//---- AVI header:
+avi_header.idx_size=0;
+while(1){
+ int id=stream_read_dword_le(stream);
+ int chunksize,size2;
+ static int last_fccType=0;
+ //
+ if(stream_eof(stream)) break;
+ //
+ if(id==mmioFOURCC('L','I','S','T')){
+ int len=stream_read_dword_le(stream)-4; // list size
+ id=stream_read_dword_le(stream); // list type
+ printf("LIST %.4s len=%d\n",&id,len);
+ if(id==listtypeAVIMOVIE){
+ // found MOVI header
+ avi_header.movi_start=stream_tell(stream);
+ avi_header.movi_end=avi_header.movi_start+len;
+// printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
+ len=(len+1)&(~1);
+ stream_skip(stream,len);
+ }
+ continue;
+ }
+ size2=stream_read_dword_le(stream);
+ printf("CHUNK %.4s len=%d\n",&id,size2);
+ chunksize=(size2+1)&(~1);
+ switch(id){
+ case ckidAVIMAINHDR: // read 'avih'
+ stream_read(stream,(char*) &avi_header.avih,sizeof(avi_header.avih));
+ chunksize-=sizeof(avi_header.avih);
+ print_avih(&avi_header.avih);
+ break;
+ case ckidSTREAMHEADER: { // read 'strh'
+ AVIStreamHeader h;
+ stream_read(stream,(char*) &h,sizeof(h));
+ chunksize-=sizeof(h);
+ if(h.fccType==streamtypeVIDEO) memcpy(&avi_header.video,&h,sizeof(h));else
+ if(h.fccType==streamtypeAUDIO) memcpy(&avi_header.audio,&h,sizeof(h));
+ last_fccType=h.fccType;
+ print_strh(&h);
+ break; }
+ case ckidSTREAMFORMAT: { // read 'strf'
+ if(last_fccType==streamtypeVIDEO){
+ stream_read(stream,(char*) &avi_header.bih,sizeof(avi_header.bih));
+ chunksize-=sizeof(avi_header.bih);
+// init_video_codec();
+// init_video_out();
+ } else
+ if(last_fccType==streamtypeAUDIO){
+ int z=(chunksize<64)?chunksize:64;
+ printf("found 'wf', %d bytes of %d\n",chunksize,sizeof(WAVEFORMATEX));
+ stream_read(stream,(char*) &avi_header.wf_ext,z);
+ chunksize-=z;
+ print_wave_header((WAVEFORMATEX*)&avi_header.wf_ext);
+// init_audio_codec();
+// init_audio_out();
+ }
+ break;
+ }
+ case ckidAVINEWINDEX: {
+ avi_header.idx_size=size2>>4;
+// printf("Reading INDEX block, %d chunks for %d frames\n",
+// avi_header.idx_size,avi_header.avih.dwTotalFrames);
+ avi_header.idx=malloc(avi_header.idx_size<<4);
+ idx_filepos=stream_tell(stream);
+ stream_read(stream,(char*)avi_header.idx,avi_header.idx_size<<4);
+ chunksize-=avi_header.idx_size<<4;
+ print_index();
+ break;
+ }
+ }
+ if(chunksize>0) stream_skip(stream,chunksize); else
+ if(chunksize<0) printf("WARNING!!! chunksize=%d (id=%.4s)\n",chunksize,&id);
+
+}
+
+printf("----------------------------------------------------------------------\n");
+printf("Found movie at 0x%X - 0x%X\n",avi_header.movi_start,avi_header.movi_end);
+if(avi_header.idx_size<=0){ printf("No index block found!\n");return 0;}
+printf("Index block at 0x%X, %d entries for %d frames\n",idx_filepos,
+ avi_header.idx_size,avi_header.avih.dwTotalFrames );
+
+stream_reset(stream);
+stream_seek(stream,avi_header.movi_start);
+avi_header.idx_pos=0;
+
+if(audiofile_name) audiofile=fopen(audiofile_name,"wb");
+if(videofile_name) videofile=fopen(videofile_name,"wb");
+
+for(i=0;i<avi_header.idx_size;i++){
+#if 0
+ printf("%.4s %4X %08X %d ",
+ &avi_header.idx[i].ckid,
+ avi_header.idx[i].dwFlags,
+ avi_header.idx[i].dwChunkOffset,
+ avi_header.idx[i].dwChunkLength
+ );fflush(stdout);
+#endif
+ if(avi_header.idx[i].ckid&AVIIF_LIST){
+// printf("LIST\n");
+ } else {
+ int id,size;
+ stream_seek(stream,avi_header.movi_start+avi_header.idx[i].dwChunkOffset-4);
+ id=stream_read_dword_le(stream);
+ size=stream_read_dword_le(stream);
+ if(id!=avi_header.idx[i].ckid){
+ printf("ChunkID mismatch! raw=%.4s (0x%X) idx=%.4s (0x%X)\n",
+ &id,avi_header.movi_start+avi_header.idx[i].dwChunkOffset-4,
+ &avi_header.idx[i].ckid,idx_filepos+16*i
+ );
+ continue;
+ }
+ if(size!=avi_header.idx[i].dwChunkLength){
+ printf("ChunkSize mismatch! raw=%d (0x%X) idx=%d (0x%X)\n",
+ size,avi_header.movi_start+avi_header.idx[i].dwChunkOffset-4,
+ avi_header.idx[i].dwChunkLength,idx_filepos+16*i
+ );
+ continue;
+ }
+
+ if(id!=mmioFOURCC('J','U','N','K'))
+ if(TWOCCFromFOURCC(id)==cktypeWAVEbytes){
+ // audio
+ int aid=StreamFromFOURCC(id);
+ if(audio_id==-1) audio_id=aid;
+ if(audio_id==aid){
+ if(audiofile){
+ void* mem=malloc(size);
+ stream_read(stream,mem,size);
+ fwrite(mem,size,1,audiofile);
+ free(mem);
+ }
+ } else {
+ printf("Invalid audio stream id: %d (%.4s)\n",aid,&id);
+ }
+ } else
+ if(LOWORD(id)==aviTWOCC('0','0')){
+ // video
+ if(videofile){
+ void* mem=malloc(size);
+ stream_read(stream,mem,size);
+ fwrite(&size,4,1,videofile);
+ fwrite(mem,size,1,videofile);
+ free(mem);
+ }
+ } else {
+ // unknown
+ printf("Unknown chunk: %.4s (%X)\n",&id,id);
+ }
+
+ } // LIST or CHUNK
+
+}
+
+return 0;
+}
+
diff --git a/aviprint.c b/aviprint.c
new file mode 100644
index 0000000000..fd110008fe
--- /dev/null
+++ b/aviprint.c
@@ -0,0 +1,88 @@
+void print_avih(MainAVIHeader *h){
+ printf("======= AVI Header =======\n");
+ printf("us/frame: %d (fps=%5.3f)\n",h->dwMicroSecPerFrame,1000000.0f/(float)h->dwMicroSecPerFrame);
+ printf("max bytes/sec: %d\n",h->dwMaxBytesPerSec);
+ printf("padding: %d\n",h->dwPaddingGranularity);
+ printf("flags: (%d)%s%s%s%s%s%s\n",h->dwFlags,
+ (h->dwFlags&AVIF_HASINDEX)?" HAS_INDEX":"",
+ (h->dwFlags&AVIF_MUSTUSEINDEX)?" MUST_USE_INDEX":"",
+ (h->dwFlags&AVIF_ISINTERLEAVED)?" IS_INTERLEAVED":"",
+ (h->dwFlags&AVIF_TRUSTCKTYPE)?" TRUST_CKTYPE":"",
+ (h->dwFlags&AVIF_WASCAPTUREFILE)?" WAS_CAPTUREFILE":"",
+ (h->dwFlags&AVIF_COPYRIGHTED)?" COPYRIGHTED":""
+ );
+ printf("frames total: %d initial: %d\n",h->dwTotalFrames,h->dwInitialFrames);
+ printf("streams: %d\n",h->dwStreams);
+ printf("Suggested BufferSize: %d\n",h->dwSuggestedBufferSize);
+ printf("Size: %d x %d\n",h->dwWidth,h->dwHeight);
+}
+
+void print_strh(AVIStreamHeader *h){
+ printf("======= STREAM Header =======\n");
+ printf("Type: %.4s FCC: %.4s (%X)\n",&h->fccType,&h->fccHandler,h->fccHandler);
+ printf("Flags: %d\n",h->dwFlags);
+ printf("Priority: %d Language: %d\n",h->wPriority,h->wLanguage);
+ printf("InitialFrames: %d\n",h->dwInitialFrames);
+ printf("Rate: %d/%d = %5.3f\n",h->dwRate,h->dwScale,(float)h->dwRate/(float)h->dwScale);
+ printf("Start: %d Len: %d\n",h->dwStart,h->dwLength);
+ printf("Suggested BufferSize: %d\n",h->dwSuggestedBufferSize);
+ printf("Quality %d\n",h->dwQuality);
+ printf("Sample size: %d\n",h->dwSampleSize);
+}
+
+void print_wave_header(WAVEFORMATEX *h){
+
+ printf("======= WAVE Format =======\n");
+
+ printf("Format Tag: %d (0x%X)\n",h->wFormatTag,h->wFormatTag);
+ printf("Channels: %d\n",h->nChannels);
+ printf("Samplerate: %d\n",h->nSamplesPerSec);
+ printf("avg byte/sec: %d\n",h->nAvgBytesPerSec);
+ printf("Block align: %d\n",h->nBlockAlign);
+ printf("bits/sample: %d\n",h->wBitsPerSample);
+ printf("cbSize: %d\n",h->cbSize);
+
+ switch(h->wFormatTag){
+ case 0x01: printf("Audio in PCM format\n");break;
+ case 0x50: printf("Audio in MPEG Layer 1/2 format\n");break;
+ case 0x55: printf("Audio in MPEG Layer-3 format\n");break; // ACM
+ case 0x02: printf("Audio in MS ADPCM format\n");break; // ACM
+ case 0x11: printf("Audio in IMA ADPCM format\n");break; // ACM
+ case 0x31:
+ case 0x32: printf("Audio in MS GSM 6.10 format\n");break; // ACM
+ case 0x75: printf("Audio in VoxWare format\n");break; // DShow
+ case 0x160:
+ case 0x161: printf("Audio in DivX WMA format\n");break; // ACM
+ default: printf("Audio in UNKNOWN (id=0x%X) format\n",h->wFormatTag);
+ }
+
+}
+
+
+void print_video_header(BITMAPINFOHEADER *h){
+ printf("======= VIDEO Format ======\n");
+ printf(" biSize %d\n", h->biSize);
+ printf(" biWidth %d\n", h->biWidth);
+ printf(" biHeight %d\n", h->biHeight);
+ printf(" biPlanes %d\n", h->biPlanes);
+ printf(" biBitCount %d\n", h->biBitCount);
+ printf(" biCompression %d='%.4s'\n", h->biCompression, &h->biCompression);
+ printf(" biSizeImage %d\n", h->biSizeImage);
+ printf("===========================\n");
+}
+
+
+void print_index(){
+ int i;
+ for(i=0;i<avi_header.idx_size;i++){
+ printf("%5d: %.4s %4X %08X (%08X) %d\n",i,
+ &avi_header.idx[i].ckid,
+ avi_header.idx[i].dwFlags,
+ avi_header.idx[i].dwChunkOffset,
+ avi_header.idx[i].dwChunkOffset+avi_header.movi_start,
+ avi_header.idx[i].dwChunkLength
+ );
+ }
+}
+
+
diff --git a/aviwrite.c b/aviwrite.c
new file mode 100644
index 0000000000..6826bcce0a
--- /dev/null
+++ b/aviwrite.c
@@ -0,0 +1,161 @@
+
+void write_avi_chunk(FILE *f,unsigned int id,int len,void* data){
+
+fwrite(&id,4,1,f);
+fwrite(&len,4,1,f);
+if(len>0){
+ if(data){
+ // DATA
+ fwrite(data,len,1,f);
+ if(len&1){ // padding
+ unsigned char zerobyte=0;
+ fwrite(&zerobyte,1,1,f);
+ }
+ } else {
+ // JUNK
+ char *avi_junk_data="[= MPlayer junk data! =]";
+ if(len&1) ++len; // padding
+ while(len>0){
+ int l=strlen(avi_junk_data);
+ if(l>len) l=len;
+ fwrite(avi_junk_data,l,1,f);
+ len-=l;
+ }
+ }
+}
+
+}
+
+
+void write_avi_list(FILE *f,unsigned int id,int len){
+ unsigned int list_id=FOURCC_LIST;
+ len+=4; // list fix
+ fwrite(&list_id,4,1,f);
+ fwrite(&len,4,1,f);
+ fwrite(&id,4,1,f);
+}
+
+struct {
+ MainAVIHeader avih;
+ AVIStreamHeader video;
+ BITMAPINFOHEADER bih;
+ unsigned int movi_start;
+ unsigned int movi_end;
+ unsigned int file_end;
+} wah;
+
+void write_avi_header(FILE *f){
+ unsigned int riff[3];
+ // RIFF header:
+ riff[0]=mmioFOURCC('R','I','F','F');
+ riff[1]=wah.file_end; // filesize
+ riff[2]=formtypeAVI; // 'AVI '
+ fwrite(&riff,12,1,f);
+ // AVI header:
+ write_avi_list(f,listtypeAVIHEADER,sizeof(wah.avih)+8+12+sizeof(wah.video)+8+sizeof(wah.bih)+8);
+ write_avi_chunk(f,ckidAVIMAINHDR,sizeof(wah.avih),&wah.avih);
+ // stream header:
+ write_avi_list(f,listtypeSTREAMHEADER,sizeof(wah.video)+8+sizeof(wah.bih)+8);
+ write_avi_chunk(f,ckidSTREAMHEADER,sizeof(wah.video),&wah.video);
+ write_avi_chunk(f,ckidSTREAMFORMAT,sizeof(wah.bih),&wah.bih);
+ // JUNK:
+ write_avi_chunk(f,ckidAVIPADDING,2048-(ftell(f)&2047)-8,NULL);
+ // 'movi' header:
+ write_avi_list(f,listtypeAVIMOVIE,wah.movi_end-ftell(f)-12);
+ wah.movi_start=ftell(f);
+}
+
+// called _before_ encoding: (write placeholders and video info)
+void write_avi_header_1(FILE *f,int fcc,float fps,int width,int height){
+ int frames=8*3600*fps; // 8 hours
+
+ wah.file_end=
+ wah.movi_end=0x7f000000;
+
+ wah.avih.dwMicroSecPerFrame=1000000.0f/fps;
+ wah.avih.dwMaxBytesPerSec=fps*500000; // ?????
+ wah.avih.dwPaddingGranularity=1; // padding
+ wah.avih.dwFlags=AVIF_ISINTERLEAVED;
+ wah.avih.dwTotalFrames=frames;
+ wah.avih.dwInitialFrames=0;
+ wah.avih.dwStreams=1;
+ wah.avih.dwSuggestedBufferSize=0x10000; // 1MB
+ wah.avih.dwWidth=width;
+ wah.avih.dwHeight=height;
+ wah.avih.dwReserved[0]=
+ wah.avih.dwReserved[1]=
+ wah.avih.dwReserved[2]=
+ wah.avih.dwReserved[3]=0;
+
+ wah.video.fccType=streamtypeVIDEO;
+ wah.video.fccHandler=fcc;
+ wah.video.dwFlags=0;
+ wah.video.wPriority=0;
+ wah.video.wLanguage=0;
+ wah.video.dwInitialFrames=0;
+ wah.video.dwScale=10000;
+ wah.video.dwRate=fps*10000;
+ wah.video.dwStart=0;
+ wah.video.dwLength=frames;
+ wah.video.dwSuggestedBufferSize=0x100000; // 1MB ????
+ wah.video.dwQuality=10000;
+ wah.video.dwSampleSize=width*height*3;
+
+ wah.bih.biSize=sizeof(wah.bih); // 40 ?
+ wah.bih.biWidth=width;
+ wah.bih.biHeight=height;
+ wah.bih.biPlanes=1;
+ wah.bih.biBitCount=24;
+ wah.bih.biCompression=fcc;
+ wah.bih.biSizeImage=3*width*height;
+ wah.bih.biXPelsPerMeter=
+ wah.bih.biYPelsPerMeter=
+ wah.bih.biClrUsed=
+ wah.bih.biClrImportant=0;
+
+ write_avi_header(f);
+}
+
+void avi_fixate(){
+ // append index and fix avi headers:
+ FILE *f1=fopen(encode_name,"r+");
+ FILE *f2;
+
+ if(!f1) return; // error
+
+ fseek(f1,0,SEEK_END);
+ wah.file_end=wah.movi_end=ftell(f1);
+
+ // index:
+ if(encode_index_name && (f2=fopen(encode_index_name,"rb"))){
+ AVIINDEXENTRY idx;
+ unsigned int pos=0;
+ int frames=0;
+ write_avi_chunk(f1,ckidAVINEWINDEX,0,NULL);
+ while(fread(&idx,sizeof(idx),1,f2)>0){
+ idx.dwChunkOffset-=wah.movi_start-4;
+ fwrite(&idx,sizeof(idx),1,f1);
+ ++frames;
+ }
+ fclose(f2);
+ unlink(encode_index_name);
+ wah.file_end=ftell(f1);
+ // re-write idx1 length:
+ pos=wah.file_end-wah.movi_end-8;
+ fseek(f1,wah.movi_end+4,SEEK_SET);
+ fwrite(&pos,4,1,f1);
+ // fixup frames:
+ wah.avih.dwTotalFrames=frames;
+ wah.video.dwLength=frames;
+ }
+
+ // re-write avi header:
+ fseek(f1,0,SEEK_SET);
+ write_avi_header(f1);
+
+ fclose(f1);
+
+}
+
+
+
diff --git a/codecctrl.c b/codecctrl.c
new file mode 100644
index 0000000000..23b424308f
--- /dev/null
+++ b/codecctrl.c
@@ -0,0 +1,198 @@
+
+//#define DEBUG_SIGNALS
+#define DEBUG_SIGNALS_SLEEP ;
+//#define DEBUG_SIGNALS_SLEEP sleep(2);
+
+#ifdef DEBUG_SIGNALS
+#define DEBUG_SIG if(1)
+#else
+#define DEBUG_SIG if(0)
+#endif
+
+//======= Interprocess Comminication (IPC) between player & codec =========
+
+static int child_pid=0;
+static int codec_pid=0;
+
+// player:
+static int data_fifo=-1;
+static int control_fifo=-1;
+// codec:
+static int data_fifo2=-1;
+static int control_fifo2=-1;
+// keyboard:
+static int keyb_fifo_put=-1;
+static int keyb_fifo_get=-1;
+
+
+// SIGTERM handler of codec controller (2nd process):
+static void codec_ctrl_sighandler(int x){
+DEBUG_SIG printf("\nCTRL: received signal %d, terminating child first:\n",x);
+ // first terminate the codec:
+ //kill(child_pid,SIGTERM);
+ kill(child_pid,x);
+ usleep(50000); // 50ms must be enough
+DEBUG_SIG printf("CTRL: Sending KILL signal to child:\n");
+ kill(child_pid,SIGKILL); // worst case
+ usleep(10000);
+ // and exit
+ if(x!=SIGHUP){
+DEBUG_SIG printf("CTRL: Exiting...\n");
+ exit(0);
+ }
+}
+
+static vo_functions_t *codec_video_out_ptr=NULL;
+
+// SIGTERM handler of the codec (3nd process):
+static void codec_sighandler(int x){
+DEBUG_SIG printf("\nCHILD: received signal %d, exiting...\n",x);
+ if(x==SIGTERM){
+ //mpeg2_close(codec_video_out_ptr);
+ codec_video_out_ptr->uninit(); // closing video_out
+ }
+ exit(0);
+}
+
+
+static void make_pipe(int* pr,int* pw){
+ int temp[2];
+ if(pipe(temp)!=0) printf("Cannot make PIPE!\n");
+ *pr=temp[0];
+ *pw=temp[1];
+}
+
+static inline int my_write(int fd,unsigned char* mem,int len){
+ int total=0;
+ int len2;
+ while(len>0){
+ len2=write(fd,mem+total,len); if(len2<=0) break;
+ total+=len2;len-=len2;
+// printf("%d bytes received, %d left\n",len2,len);
+ }
+ return total;
+}
+
+static inline int my_read(int fd,unsigned char* mem,int len){
+ int total=0;
+ int len2;
+ while(len>0){
+ len2=read(fd,mem+total,len); if(len2<=0) break;
+ total+=len2;len-=len2;
+// printf("%d bytes received, %d left\n",len2,len);
+ }
+ return total;
+}
+
+
+void send_cmd(int fd,int cmd){
+ int fifo_cmd=cmd;
+ write(fd,&fifo_cmd,4);
+// fflush(control_fifo);
+}
+
+void mpeg_codec_controller(vo_functions_t *video_out){
+//================== CODEC Controller: ==========================
+ signal(SIGTERM,codec_ctrl_sighandler); // set our SIGTERM handler
+ signal(SIGHUP,codec_ctrl_sighandler); // set our SIGHUP handler
+ printf("starting video codec...\n");
+ while(1){
+ int status;
+ if((child_pid=fork())==0){
+ // child:
+ unsigned int t=0;
+ codec_video_out_ptr=video_out;
+#if 0
+ signal(SIGTERM,codec_sighandler); // set our SIGTERM handler
+ signal(SIGHUP,codec_sighandler); // set our SIGHUP handler
+#else
+ // terminate requests:
+ signal(SIGTERM,codec_sighandler); // kill
+ signal(SIGHUP,codec_sighandler); // kill -HUP / xterm closed
+ signal(SIGINT,codec_sighandler); // Interrupt from keyboard
+ signal(SIGQUIT,codec_sighandler); // Quit from keyboard
+ // fatal errors:
+ signal(SIGBUS,codec_sighandler); // bus error
+ signal(SIGSEGV,codec_sighandler); // segfault
+ signal(SIGILL,codec_sighandler); // illegal instruction
+ signal(SIGFPE,codec_sighandler); // floating point exc.
+ signal(SIGABRT,codec_sighandler); // abort()
+#endif
+
+ send_cmd(control_fifo2,0x22222222); // Send WE_ARE_READY command
+ send_cmd(control_fifo2,getpid()); // Send out PID
+ while(1){
+ unsigned int syncword=0;
+ read(data_fifo2,&syncword,4);
+ if(syncword==0x22222222) break;
+ printf("codec: drop bad frame (%X)\n",syncword);
+ }
+ //printf("codec: connection synced\n");
+
+ while(1){
+ int num_frames;
+ int len=0;
+ int len2;
+ send_cmd(control_fifo2,0x3030303);
+ len2=my_read(data_fifo2,(unsigned char*) &len,4);
+ if(len2!=4){
+ printf("FATAL: cannot read packet len from data fifo (ret=%d, errno=%d)\n",len2,errno);
+ break;
+ }
+ if(len==0){ printf("mpeg2dec: EOF, exiting...\n");break; }
+// printf("mpeg2dec: frame (%d bytes) read\n",len);
+ t-=GetTimer();
+ mpeg2_decode_data(video_out, videobuffer, videobuffer+len);
+ t+=GetTimer();
+ send_cmd(control_fifo2,0); // FRAME_COMPLETED command
+ send_cmd(control_fifo2,picture->frame_rate); // fps
+ send_cmd(control_fifo2,100+picture->repeat_count);picture->repeat_count=0;
+ send_cmd(control_fifo2,t);t=0;
+ }
+ video_out->uninit();
+ exit(0); // leave process
+ }
+ wait(&status); // Waiting for the child!
+// printf("restarting video codec...\n");
+ }
+ exit(0);
+}
+
+void mplayer_put_key(int code){
+ fd_set rfds;
+ struct timeval tv;
+
+ /* Watch stdin (fd 0) to see when it has input. */
+ FD_ZERO(&rfds);
+ FD_SET(keyb_fifo_put, &rfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ //retval = select(keyb_fifo_put+1, &rfds, NULL, NULL, &tv);
+ if(select(keyb_fifo_put+1, NULL, &rfds, NULL, &tv)){
+ write(keyb_fifo_put,&code,4);
+// printf("*** key event %d sent ***\n",code);
+ } else {
+// printf("*** key event dropped (FIFO is full) ***\n");
+ }
+}
+
+int mplayer_get_key(){
+ fd_set rfds;
+ struct timeval tv;
+ int code=-1;
+
+ /* Watch stdin (fd 0) to see when it has input. */
+ FD_ZERO(&rfds);
+ FD_SET(keyb_fifo_get, &rfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ //retval = select(keyb_fifo_put+1, &rfds, NULL, NULL, &tv);
+ if(select(keyb_fifo_put+1, &rfds, NULL, NULL, &tv)){
+ read(keyb_fifo_get,&code,4);
+// printf("*** key event %d read ***\n",code);
+ }
+ return code;
+}
+
diff --git a/codecs.c b/codecs.c
new file mode 100644
index 0000000000..1a5b39e649
--- /dev/null
+++ b/codecs.c
@@ -0,0 +1,150 @@
+//#define ANGELPOTION
+
+char* get_vids_codec_name(){
+// unsigned long fccHandler=avi_header.video.fccHandler;
+ unsigned long fccHandler=avi_header.bih.biCompression;
+ avi_header.yuv_supported=0;
+ avi_header.yuv_hack_needed=0;
+ avi_header.flipped=0;
+ switch(fccHandler){
+ case mmioFOURCC('M', 'P', 'G', '4'):
+ case mmioFOURCC('m', 'p', 'g', '4'):
+ case mmioFOURCC('M', 'P', '4', '2'):
+ case mmioFOURCC('m', 'p', '4', '2'):
+// case mmioFOURCC('M', 'P', '4', '3'):
+// case mmioFOURCC('m', 'p', '4', '3'):
+ printf("Video in Microsoft MPEG-4 format\n");
+ avi_header.yuv_supported=1;
+ avi_header.yuv_hack_needed=1;
+#ifdef ANGELPOTION
+ return "APmpg4v1.dll";
+#endif
+ return "mpg4c32.dll";
+ case mmioFOURCC('M', 'P', '4', '3'):
+ case mmioFOURCC('m', 'p', '4', '3'):
+ printf("Video in MPEG-4 v3 (really DivX) format\n");
+ avi_header.bih.biCompression=mmioFOURCC('d', 'i', 'v', '3'); // hack
+ avi_header.yuv_supported=1;
+ avi_header.yuv_hack_needed=1;
+#ifdef ANGELPOTION
+ return "APmpg4v1.dll";
+#endif
+ return "divxc32.dll";
+
+ case mmioFOURCC('D', 'I', 'V', 'X'):
+ case mmioFOURCC('d', 'i', 'v', 'x'):
+ return "DivX.dll";
+
+ case mmioFOURCC('D', 'I', 'V', '3'):
+ case mmioFOURCC('d', 'i', 'v', '3'):
+ case mmioFOURCC('D', 'I', 'V', '4'):
+ case mmioFOURCC('d', 'i', 'v', '4'):
+ case mmioFOURCC('M', 'P', '4', '1'):
+ case mmioFOURCC('m', 'p', '4', '1'):
+ printf("Video in DivX ;-) format\n");
+ avi_header.yuv_supported=1;
+ avi_header.yuv_hack_needed=1;
+#ifdef ANGELPOTION
+ return "APmpg4v1.dll";
+#endif
+ return "divxc32.dll";
+
+ case mmioFOURCC('I', 'V', '5', '0'):
+ case mmioFOURCC('i', 'v', '5', '0'):
+ printf("Video in Indeo Video 5 format\n");
+ avi_header.yuv_supported=1; // YUV pic is upside-down :(
+ return "ir50_32.dll";
+
+ case mmioFOURCC('I', 'V', '4', '1'):
+ case mmioFOURCC('i', 'v', '4', '1'):
+ printf("Video in Indeo Video 4.1 format\n");
+ avi_header.flipped=1;
+ avi_header.no_32bpp_support=1;
+ return "ir41_32.dll";
+
+ case mmioFOURCC('I', 'V', '3', '2'):
+ case mmioFOURCC('i', 'v', '3', '2'):
+ printf("Video in Indeo Video 3.2 format\n");
+ avi_header.flipped=1;
+ avi_header.no_32bpp_support=1;
+ return "ir32_32.dll";
+
+ case mmioFOURCC('c', 'v', 'i', 'd'):
+ printf("Video in Cinepak format\n");
+ avi_header.yuv_supported=1;
+ return "iccvid.dll";
+
+//*** Only 16bit .DLL available (can't load under linux) ***
+// case mmioFOURCC('V', 'C', 'R', '1'):
+// printf("Video in ATI VCR1 format\n");
+// return "ativcr1.dll";
+
+ case mmioFOURCC('V', 'C', 'R', '2'):
+ printf("Video in ATI VCR2 format\n");
+ avi_header.yuv_supported=1;
+ return "ativcr2.dll";
+
+ case mmioFOURCC('A', 'S', 'V', '1'):
+ printf("Asus ASV-1 format\n");
+// avi_header.yuv_supported=1;
+ return "asusasvd.dll";
+
+ case mmioFOURCC('A', 'S', 'V', '2'):
+ printf("Asus ASV-2 format\n");
+// avi_header.yuv_supported=1;
+ avi_header.flipped=1;
+// avi_header.bih.biCompression=mmioFOURCC('A', 'S', 'V', '1');
+// return "asusasvd.dll";
+ return "asusasv2.dll";
+
+ case mmioFOURCC('I', '2', '6', '3'):
+ case mmioFOURCC('i', '2', '6', '3'):
+ printf("Video in I263 format\n");
+ return "i263_32.drv";
+
+ case mmioFOURCC('M', 'J', 'P', 'G'):
+ printf("Video in MJPEG format\n");
+ avi_header.yuv_supported=1;
+ return "M3JPEG32.dll";
+// return "mcmjpg32.dll";
+// return "m3jpeg32.dll";
+// return "libavi_mjpeg.so";
+ }
+ printf("UNKNOWN video codec: %.4s (0x%0X)\n",&fccHandler,fccHandler);
+ printf("If you know this video format and codec, you can edit codecs.c in the source!\n");
+ printf("Please contact the author, send this movie to be supported by future version.\n");
+ return NULL;
+}
+
+char* get_auds_codec_name(){
+ int id=((WAVEFORMATEX*)avi_header.wf_ext)->wFormatTag;
+ switch (id){
+ case 0x161://DivX audio
+// ((WAVEFORMATEX*)avi_header.wf_ext)->wFormatTag=0x160; //hack
+ case 0x160://DivX audio
+ avi_header.audio_seekable=0;
+ return "divxa32.acm"; // tested, OK.
+ case 0x2://MS ADPCM
+ avi_header.audio_seekable=0;
+ return "msadp32.acm"; // tested, OK.
+ case 0x55://MPEG l3
+ avi_header.audio_seekable=1;
+ return "l3codeca.acm"; // tested, OK. faster than mp3lib on intel
+ case 0x11://IMA ADPCM
+ return "imaadp32.acm"; // segfault :(
+ case 0x31://MS GSM
+ case 0x32://MS GSM
+ return "msgsm32.acm"; // segfault :( - not req. has internal now!
+ case 0x75://VoxWare
+ return "voxmsdec.ax"; // directshow, not yet supported just a try
+// case 0x06://???
+// return "lhacm.acm";
+// return "msg711.acm";
+// return "tssoft32.acm";
+ }
+ printf("UNKNOWN audio codec: 0x%0X\n",id);
+ printf("If you know this audio format and codec, you can edit codecs.c in the source!\n");
+ printf("Please contact the author, send this movie to be supported by future version.\n");
+ return NULL;
+}
+
diff --git a/config.h b/config.h
new file mode 100644
index 0000000000..d9e8785f52
--- /dev/null
+++ b/config.h
@@ -0,0 +1,70 @@
+
+/* -------- Generated by ./configure ----------- */
+
+/* Define this to enable avg. byte/sec-based AVI sync method by default:
+ (use -bps or -nobps commandline option for run-time method selection) */
+#undef AVI_SYNC_BPS
+
+/* Undefine this if you want soundcard-only timing by default:
+ You can still change this with the -alsa or -noalsa command-line option!
+ (This function was originally impemented to solve ALSA driver's big
+ buffer problems, but it seems to be useful for every soundcard drivers) */
+#define ALSA_TIMER
+
+/* Undefine this if your soundcard driver has no working select().
+ If you have kernel Oops, player hangups, or just no audio, you should
+ try to recompile MPlayer with this option disabled! */
+#define HAVE_AUDIO_SELECT
+
+/* You have a choice for MP3 decoding: mp3lib(mpg123) or Win32(l3codeca.acm)
+ #define this if you prefer mpg123 (with 3Dnow! support) than l3codeca.acm
+ (with mmx/sse optimizations)
+ You can still change it runtime using -afm 1 (mpg123) or -afm 4 (l3codeca)*/
+#undef DEFAULT_MPG123
+
+/* XMMP support: (test code) */
+#undef USE_XMMP_AUDIO
+#define LIBDIR "/usr/local/lib"
+#define PLUGINDIR LIBDIR "/xmmp/Plugins"
+#define XMMP_AUDIO_DRIVER PLUGINDIR "/Sound/oss.so"
+
+/* LIRC (remote control, see www.lirc.org) support: */
+#undef HAVE_LIRC
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #define WORDS_BIGENDIAN */
+
+#define ARCH_X86
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// NOTE: Instead of modifying these here, use the --enable/--disable options
+// of the ./configure script! See ./configure --help for details.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/* termcap flag for getch2.c */
+#define USE_TERMCAP
+
+/* Extension defines */
+#undef HAVE_MLIB // available only on solaris
+#undef HAVE_3DNOW // only define if you have 3DNOW (AMD k6-2, AMD Athlon, iDT WinChip, etc.)
+#define HAVE_MMX // only define if you have MMX
+#define HAVE_SSE // only define if you have SSE (Intel Pentium III or Celeron II)
+
+/* libvo options */
+#define SCREEN_SIZE_X 1
+#define SCREEN_SIZE_Y 1
+#define HAVE_X11
+#undef HAVE_XV
+#define HAVE_GL
+#undef HAVE_SDL
+#undef HAVE_3DFX
+#define HAVE_MGA
+#define HAVE_SYNCFB
+
+#if defined(HAVE_GL)||defined(HAVE_X11)|defined(HAVE_XV)
+#define X11_FULLSCREEN
+#endif
+
diff --git a/config.mak b/config.mak
new file mode 100644
index 0000000000..59186c6732
--- /dev/null
+++ b/config.mak
@@ -0,0 +1,14 @@
+
+# -------- Generated by ./configure -----------
+
+AR=ar
+CC=gcc
+# OPTFLAGS=-O4 -march=i686 -mcpu=i686 -pipe -fomit-frame-pointer -ffast-math
+OPTFLAGS=-O4 -march=i686 -mcpu=i686 -pipe -ffast-math
+# LIBS=-L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib -lGL -lX11 -lXext
+X_LIBS=-L/usr/X11R6/lib -lGL -lX11 -lXext
+TERMCAP_LIB=-ltermcap
+XMM_LIBS =
+LIRC_LIBS =
+WIN32_PATH=-DWIN32_PATH=\"/usr/lib/win32\"
+
diff --git a/configure b/configure
new file mode 100755
index 0000000000..9e86268bb9
--- /dev/null
+++ b/configure
@@ -0,0 +1,783 @@
+#!/bin/sh
+
+#
+# MPlayer configurator. (C) 2000 Pontscho/fresh!mindworkz
+# pontscho@makacs.poliod.hu
+#
+# some changes by A'rpi/ESP-team:
+# - some english bugfix :)
+# - removed _??exists flags, _?? is enough...
+# - creating only config.mak files instead of whole Makefiles
+#
+# some changes by LGB (Gábor Lénárt):
+# - SOME gcc may support 'k7', so I added tests for ALL CPU type optimization
+# switches with the ability to find out the best optimization for your CPU.
+# - Help moved to the begining to avoid tests if user only wants help.
+# - A one lined help to indicate detailed help for users
+# - Fixed /tmp race (PIDs can be predicted, I added random numbers as well)
+#
+# some changes by A'rpi/ESP-team:
+# - the --win32libdir patch by Aaron Hope applied
+# - some english bugfix again :)
+# - cpu type selection changed:
+# ( k7->k6->k5-> ) || (i686->pentiumpro-> ) pentium-> i486 -> i386 -> error!
+# - cpu type for AMD/family=5 changed k6->k5
+#
+# some changes by LGB:
+# - Ehhh, AMD K6-2 returns with cpuid 5 ;-) Changing back Arpi's last change :)
+# More info: AMD K6-2 reports with family 5, duron with 6, so I attached
+# much finer CPU type detection based on Linux kernel's one :)
+# (k5: 5, model<6, k6: 5, model>=6, k7: 6, model=any)
+# - On some exit point (error) temporary files were not deleted. Fixed.
+# - $TMP and $TMP2 are renamed to $TMPC and $TMPO ;-)
+# - Some useless { ... } are removed
+#
+# some changes by A'rpi/ESP-team:
+# - added 'athlon' target for the new athlongcc [Ian Kumlien]
+# - applied _win32libdir=-L patch by Magnus Pfeffer
+#
+# --
+
+
+# LGB: Help moved here.
+
+if [ "$1" = "--help" -o "$1" = "-help" -o "$1" = "-h" ]; then
+cat << EOF
+
+usage: $0 [options]
+
+params:
+ --enable-mmx build with mmx support [autodetect]
+ --enable-3dnow build with 3dnow! support [autodetect]
+ --enable-sse build with sse support [autodetect]
+ --enable-gl build with OpenGL render support [autodetect]
+ --enable-sdl build with SDL render support [def.: disabled!]
+ --enable-mga build with mga_vid support [autodetect, if /dev/mga_vid
+ is available]
+ --enable-xmga build with mga_vid X Window support [autodetect,
+ if both /dev/mga_vid and x11 are available]
+ --enable-xv build with Xv render support for X 4.x [autodetect]
+ --enable-x11 build with X11 render support [autodetect]
+ --enable-mlib build with MLIB support ( only Solaris )
+
+ --enable-termcap use termcap database for key codes
+ --enable-xmmp use XMMP audio drivers
+ --enable-lirc enable LIRC (remote control) support
+
+ --with-x11libdir=DIR X library files are in DIR
+ --with-win32libdir=DIR windows codec files
+
+ --size-x=SIZE default screen width
+ --size-y=SIZE default screen height
+EOF
+exit 0
+fi
+
+# LGB: Some inital help
+
+echo "You can get detailed help on configure with: $0 --help"
+echo "Please wait while ./configure discovers your software and hardware environment!"
+
+# LGB: temporary files
+
+TMPC="/tmp/mplayer-conf-${RANDOM}-$$-${RANDOM}.c"
+TMPO="/tmp/mplayer-conf-${RANDOM}-$$-${RANDOM}.o"
+
+
+# ---
+
+# config files
+CCONF='config.h'
+MCONF='config.mak'
+
+# ---
+
+TAB=`echo -n -e "\t"`
+pname=`cat /proc/cpuinfo | grep 'model name' | cut -d ':' -f 2`
+pparam=`cat /proc/cpuinfo | grep 'features' | cut -d ':' -f 2`
+if [ -z "$pparam" ]; then
+ pparam=`cat /proc/cpuinfo | grep 'flags' | cut -d ':' -f 2`
+fi
+pvendor=`cat /proc/cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2`
+pfamily=`cat /proc/cpuinfo | grep 'cpu family' | cut -d ':' -f 2 | cut -d ' ' -f 2`
+pmodel=`cat /proc/cpuinfo | grep "model$TAB" | cut -d ':' -f 2 | cut -d ' ' -f 2`
+pstepping=`cat /proc/cpuinfo | grep 'stepping' | cut -d ':' -f 2 | cut -d ' ' -f 2`
+
+_mmx=no
+_3dnow=no
+_mtrr=no
+_sse=no
+_mga=no
+_gl=no
+_sdl=no
+_xv=no
+_x11=no
+_3dfx=no
+_syncfb=no
+_mlib=no
+_mpg123=no
+_xmga=no
+_lirc=no
+
+_x=1
+_y=1
+
+_gllib=
+_sdllib=
+_x11lib=
+_xvlib=
+_xlibdir=
+
+for i in `echo $pparam`; do
+
+ case "$i" in
+ 3dnow)
+ _3dnow=yes
+ _mpg123=yes
+ ;;
+ mmx)
+ _mmx=yes
+ ;;
+ mtrr)
+ _mtrr=yes
+ ;;
+ k6_mtrr)
+ _mtrr=yes
+ ;;
+ xmm)
+ _sse=yes
+ ;;
+ sse)
+ _sse=yes
+ ;;
+ kni)
+ _sse=yes
+ ;;
+ esac
+
+done
+
+if [ -e /usr/X11R6 ]; then
+ _x11libdir=-L/usr/X11R6/lib
+else
+ if [ -e /usr/X11 ]; then
+ _x11libdir=-L/usr/X11/lib
+ fi
+fi
+
+_win32libdirnotify=no
+if [ -e /usr/lib/win32 ]; then
+ _win32libdir=/usr/lib/win32
+else
+ if [ -e /usr/local/lib/win32 ]; then
+ _win32libdir=/usr/local/lib/win32
+ else
+# This is our default:
+ _win32libdir=/usr/lib/win32
+ _win32libdirnotify=yes
+ fi
+fi
+
+
+if [ -e /dev/mga_vid ]; then
+ _mga=yes
+ _syncfb=yes
+fi
+
+proc=pentium
+
+case "$pvendor" in
+ AuthenticAMD)
+ case "$pfamily" in
+ 3)
+ proc=i386
+ ;;
+ 4)
+ proc=i486
+ ;;
+ 5)
+ if [ $pmodel -ge 6 ]; then # LGB: models are: K5/SSA5 K5 K5 K5 ? ? K6 K6 K6-2 K6-3
+ proc=k6
+ else
+ proc=k5
+ fi
+ ;;
+ 6|7) # LGB: Though it seems Athlon CPUs returns with "6"
+ proc=k7
+ ;;
+ *)
+ proc=pentium
+ ;;
+ esac
+ ;;
+ GenuineIntel)
+ case "$pfamily" in
+ 3)
+ proc=i386
+ ;;
+ 4)
+ proc=i486
+ ;;
+ 5)
+ proc=pentium
+ ;;
+ 6)
+ proc=i686
+ ;;
+ *)
+ proc=pentium
+ ;;
+ esac
+ ;;
+ unknown) # added by Gabucino - upon Tibcu's request
+ case "$pfamily" in
+ 3)
+ proc=i386
+ ;;
+ 4)
+ proc=i486
+ ;;
+ *)
+ proc=pentium
+ ;;
+ esac
+ ;;
+ *)
+ proc=pentium
+ ;;
+esac
+
+# ---
+
+cat > $TMPC << EOF
+int main( void ) { return 0; }
+EOF
+
+# check that gcc supports our cpu, if not, fallback to pentium
+# LGB: check -mcpu and -march swithing step by step with enabling
+# to fall back till 386.
+
+#echo -n "Checking your GCC CPU optimalization abilities: "
+if [ "$proc" = "k7" ]; then
+# echo -n "trying k7 "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=athlon
+fi
+if [ "$proc" = "athlon" ]; then
+# echo -n "trying athlon "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=k6
+fi
+if [ "$proc" = "k6" ]; then
+# echo -n "trying k6 "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=k5
+fi
+if [ "$proc" = "k5" ]; then
+# echo -n "trying k5 "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=pentium
+fi
+if [ "$proc" = "i686" ]; then
+# echo -n "trying i686 "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=pentiumpro
+fi
+if [ "$proc" = "pentiumpro" ]; then
+# echo -n "trying pentiumpro "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=pentium
+fi
+if [ "$proc" = "pentium" ]; then
+# echo -n "trying pentium "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=i486
+fi
+if [ "$proc" = "i486" ]; then
+# echo -n "trying i486 "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=i386
+fi
+if [ "$proc" = "i386" ]; then
+# echo -n "trying i386 "
+ gcc $TMPC -o $TMPO -march=$proc -mcpu=$proc &> /dev/null || proc=error
+fi
+if [ "$proc" = "error" ]; then
+ echo
+ echo "Your gcc does not support even \"i386\" for '-march' and '-mcpu'." >&2
+ rm -f $TMPC $TMPO
+ exit
+fi
+#echo "DONE (${proc})."
+
+
+# check GL & X11 & Xext & Xv & SDL & termcap libs
+
+gcc $TMPC -o $TMPO $_x11libdir/ -lGL &> /dev/null && _gl=yes
+gcc $TMPC -o $TMPO $_x11libdir -lX11 -lXext &> /dev/null && _x11=yes
+gcc $TMPC -o $TMPO $_x11libdir -lXv &> /dev/null && _xv=yes
+gcc $TMPC -o $TMPO $_x11libdir -L/usr/local/lib/ -lpthread &> /dev/null || \
+ { echo "Lib pthread not found."; rm -f $TMPC $TMPO ; exit 1; }
+
+# SDL disabled by default (0.11pre22-) because of the compilation problems
+# this is very buggy & experimental code, use it only if you really need it!!
+_have_sdl=no
+gcc $TMPC -o $TMPO $_x11libdir -L/usr/local/lib/ -lSDL -lpthread &> /dev/null && _have_sdl=yes
+
+_termcap=no
+gcc $TMPC -o $TMPO -ltermcap &> /dev/null && _termcap=yes
+
+_binutils=no
+as libac3/downmix/downmix_i386.S -o $TMPO &> /dev/null && _binutils=yes
+
+cat > $TMPC << EOF
+#include <GL/gl.h>
+int main( void ) { return 0; }
+EOF
+
+gcc $TMPC -o $TMPO $_x11libdir/ -lGL &> /dev/null || \
+ { _gl=no; echo "GL includes not found!";}
+
+rm -f $TMPC $TMPO
+
+
+if [ $_x11 = 'yes' ]; then
+ if [ $_mga = 'yes' ]; then
+ _xmga=yes
+ fi
+fi
+
+# ---
+
+# check for the parameters.
+
+for ac_option
+do
+ case "$ac_option" in
+ --enable-sse)
+ _sse=yes
+ ;;
+ --enable-3dnow)
+ _3dnow=yes
+ ;;
+ --enable-mmx)
+ _mmx=yes
+ ;;
+ --enable-gl)
+ _gl=yes
+ ;;
+ --enable-sdl)
+ _sdl=yes
+ ;;
+ --enable-mga)
+ _mga=yes
+ ;;
+ --enable-xmga)
+ _xmga=yes
+ ;;
+ --enable-xv)
+ _xv=yes
+ ;;
+ --enable-x11)
+ _x11=yes
+ ;;
+ --enable-3dfx)
+ _3dfx=yes
+ ;;
+ --enable-syncfb)
+ _syncfb=yes
+ ;;
+ --enable-mlib)
+ _mlib=yes
+ ;;
+ --enable-termcap)
+ _termcap=yes
+ ;;
+ --enable-xmmp)
+ _xmmp=yes
+ ;;
+ --enable-lirc)
+ _lirc=yes
+ ;;
+ --disable-sse)
+ _sse=no
+ ;;
+ --disable-3dnow)
+ _3dnow=no
+ ;;
+ --disable-mmx)
+ _mmx=no
+ ;;
+ --disable-gl)
+ _gl=no
+ ;;
+ --disable-sdl)
+ _sdl=no
+ ;;
+ --disable-mga)
+ _mga=no
+ ;;
+ --disable-xmga)
+ _xmga=no
+ ;;
+ --disable-xv)
+ _xv=no
+ ;;
+ --disable-x11)
+ _x11=no
+ ;;
+ --disable-mlib)
+ _mlib=no
+ ;;
+ --disable-termcap)
+ _termcap=no
+ ;;
+ --with-x11libdir=*)
+ _x11libdir=-L`echo $ac_option | cut -d '=' -f 2`
+ ;;
+ --with-win32libdir=*)
+ _win32libdir=`echo $ac_option | cut -d '=' -f 2`
+ ;;
+ --size-x=*)
+ _x=`echo $ac_option | cut -d '=' -f 2`
+ ;;
+ --size-y=*)
+ _y=`echo $ac_option | cut -d '=' -f 2`
+ ;;
+ esac
+done
+
+# to screen.
+
+echo "Checking for cpu vendor ... $pvendor ( $pfamily:$pmodel:$pstepping )"
+echo "Checking for cpu type ... $pname"
+echo "Optimizing to ... $proc"
+echo "Checking for mmx support ... $_mmx"
+echo "Checking for 3dnow support ... $_3dnow"
+echo "Checking for sse support ... $_sse"
+echo "Checking for mtrr support ... $_mtrr"
+echo "Screen size ... ${_x}x${_y}"
+echo "Checking for X11 libs ... $_x11libdir"
+echo "Checking mga_vid device ... $_mga"
+echo "Checking for xmga ... $_xmga"
+echo "Checking for SDL ... $_sdl"
+echo "Checking for OpenGL ... $_gl"
+echo "Checking for Xv ... $_xv"
+echo "Checking for X11 ... $_x11"
+
+# write conf files.
+
+if [ $_gl = yes ]; then
+ _gllib='-lGL'
+fi
+
+if [ $_x11 = yes ]; then
+ _x11lib='-lX11 -lXext'
+fi
+
+if [ $_xv = yes ]; then
+ _xvlib='-lXv'
+fi
+
+if [ $_sdl = yes ]; then
+ _sdllib='-lSDL -lpthread'
+fi
+
+if [ "$_termcap" = "yes" ]; then
+ _termcap='#define USE_TERMCAP'
+ _libtermcap='-ltermcap'
+else
+ _termcap='#undef USE_TERMCAP'
+ _libtermcap=''
+fi
+
+if [ "$_xmmp" = "yes" ]; then
+ _xmmpaudio='#define USE_XMMP_AUDIO'
+ _xmmplibs='-Llibxmm -lxmm'
+else
+ _xmmpaudio='#undef USE_XMMP_AUDIO'
+fi
+
+if [ "$_lirc" = "yes" ]; then
+ _lircdefs='#define HAVE_LIRC'
+ _lirclibs='-llirc_client'
+else
+ _lircdefs='#undef HAVE_LIRC'
+ _lirclibs=''
+fi
+
+
+echo
+echo "Creating $MCONF"
+cat > $MCONF << EOF
+
+# -------- Generated by ./configure -----------
+
+AR=ar
+CC=gcc
+# OPTFLAGS=-O4 -march=$proc -mcpu=$proc -pipe -fomit-frame-pointer -ffast-math
+OPTFLAGS=-O4 -march=$proc -mcpu=$proc -pipe -ffast-math
+# LIBS=-L/usr/lib -L/usr/local/lib $_x11libdir $_gllib $_sdllib $_x11lib $_xvlib
+X_LIBS=$_x11libdir $_gllib $_sdllib $_x11lib $_xvlib
+TERMCAP_LIB=$_libtermcap
+XMM_LIBS = $_xmmplibs
+LIRC_LIBS = $_lirclibs
+WIN32_PATH=-DWIN32_PATH=\"$_win32libdir\"
+
+EOF
+# echo 'CFLAGS=$(OPTFLAGS) -Wall -DMPG12PLAY' >> config.mak
+
+echo "Creating $CCONF"
+
+if [ "$_mmx" = "yes" ]; then
+ _mmx='#define HAVE_MMX'
+else
+ _mmx='#undef HAVE_MMX'
+fi
+
+if [ $_3dnow = yes ]; then
+ _3dnowm='#define HAVE_3DNOW'
+else
+ _3dnowm='#undef HAVE_3DNOW'
+fi
+
+if [ $_sse = yes ]; then
+ _ssem='#define HAVE_SSE'
+else
+ _ssem='#undef HAVE_SSE'
+fi
+
+# ---
+
+_vosrc=''
+
+if [ $_mlib = yes ]; then
+ _mlib='#define HAVE_MLIB'
+ _vosrc=$_vosrc' yuv2rgb_mlib.c'
+else
+ _mlib='#undef HAVE_MLIB'
+fi
+
+# ---
+
+if [ $_gl = yes ]; then
+ _gl='#define HAVE_GL'
+ _vosrc=$_vosrc' vo_gl.c'
+else
+ _gl='#undef HAVE_GL'
+fi
+
+if [ $_sdl = yes ]; then
+ _sdldef='#define HAVE_SDL'
+ _vosrc=$_vosrc' vo_sdl.c'
+else
+ _sdldef='#undef HAVE_SDL'
+fi
+
+if [ $_x11 = yes ]; then
+ _x11='#define HAVE_X11'
+ _vosrc=$_vosrc' vo_x11.c'
+else
+ _x11='#undef HAVE_X11'
+fi
+
+if [ $_xv = yes ]; then
+ _xv='#define HAVE_XV'
+ _vosrc=$_vosrc' vo_xv.c'
+else
+ _xv='#undef HAVE_XV'
+fi
+
+# ---
+
+if [ $_mga = yes ]; then
+ _mga='#define HAVE_MGA'
+ _vosrc=$_vosrc' vo_mga.c'
+else
+ _mga='#undef HAVE_MGA'
+fi
+if [ $_xmga = yes ]; then
+ _vosrc=$_vosrc' vo_xmga.c'
+fi
+
+if [ $_syncfb = yes ]; then
+ _syncfb='#define HAVE_SYNCFB'
+ _vosrc=$_vosrc' vo_syncfb.c'
+else
+ _syncfb='#undef HAVE_SYNCFB'
+fi
+
+if [ $_3dfx = yes ]; then
+ _3dfx='#define HAVE_3DFX'
+ _vosrc=$_vosrc' vo_3dfx.c'
+else
+ _3dfx='#undef HAVE_3DFX'
+fi
+
+if [ $_mpg123 = yes ]; then
+ _mpg123='#define DEFAULT_MPG123'
+else
+ _mpg123='#undef DEFAULT_MPG123'
+fi
+
+cat > $CCONF << EOF
+
+/* -------- Generated by ./configure ----------- */
+
+/* Define this to enable avg. byte/sec-based AVI sync method by default:
+ (use -bps or -nobps commandline option for run-time method selection) */
+#undef AVI_SYNC_BPS
+
+/* Undefine this if you want soundcard-only timing by default:
+ You can still change this with the -alsa or -noalsa command-line option!
+ (This function was originally impemented to solve ALSA driver's big
+ buffer problems, but it seems to be useful for every soundcard drivers) */
+#define ALSA_TIMER
+
+/* Undefine this if your soundcard driver has no working select().
+ If you have kernel Oops, player hangups, or just no audio, you should
+ try to recompile MPlayer with this option disabled! */
+#define HAVE_AUDIO_SELECT
+
+/* You have a choice for MP3 decoding: mp3lib(mpg123) or Win32(l3codeca.acm)
+ #define this if you prefer mpg123 (with 3Dnow! support) than l3codeca.acm
+ (with mmx/sse optimizations)
+ You can still change it runtime using -afm 1 (mpg123) or -afm 4 (l3codeca)*/
+$_mpg123
+
+/* XMMP support: (test code) */
+$_xmmpaudio
+#define LIBDIR "/usr/local/lib"
+#define PLUGINDIR LIBDIR "/xmmp/Plugins"
+#define XMMP_AUDIO_DRIVER PLUGINDIR "/Sound/oss.so"
+
+/* LIRC (remote control, see www.lirc.org) support: */
+$_lircdefs
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #define WORDS_BIGENDIAN */
+
+#define ARCH_X86
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// NOTE: Instead of modifying these here, use the --enable/--disable options
+// of the ./configure script! See ./configure --help for details.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/* termcap flag for getch2.c */
+$_termcap
+
+/* Extension defines */
+$_mlib // available only on solaris
+$_3dnowm // only define if you have 3DNOW (AMD k6-2, AMD Athlon, iDT WinChip, etc.)
+$_mmx // only define if you have MMX
+$_ssem // only define if you have SSE (Intel Pentium III or Celeron II)
+
+/* libvo options */
+#define SCREEN_SIZE_X $_x
+#define SCREEN_SIZE_Y $_y
+$_x11
+$_xv
+$_gl
+$_sdldef
+$_3dfx
+$_mga
+$_syncfb
+
+#if defined(HAVE_GL)||defined(HAVE_X11)|defined(HAVE_XV)
+#define X11_FULLSCREEN
+#endif
+
+EOF
+
+echo "Creating libvo/config.mak"
+
+_voobj=`echo $_vosrc | sed -e 's/\.c/\.o/g'`
+
+cat > libvo/config.mak << EOF
+
+include ../config.mak
+
+OPTIONAL_SRCS=$_vosrc
+OPTIONAL_OBJS=$_voobj
+
+EOF
+
+echo "Creating libac3/config.mak"
+
+if [ $_sse = yes ]; then
+ _downmixc='downmix/downmix_kni.S'
+ _downmixo='downmix/downmix_kni.o'
+else
+if [ $_binutils = yes ]; then
+ _downmixc='downmix/downmix_i386.S'
+ _downmixo='downmix/downmix_i386.o'
+else
+_downmixc='downmix/downmix.c'
+_downmixo='downmix/downmix.o'
+cat << EOF
+
+!!! Warning! fallback to slow downmix.c due the old binutils.
+!!! Upgrade for better audio decoding performance.
+
+EOF
+fi
+fi
+
+cat > libac3/config.mak << EOF
+
+include ../config.mak
+
+OPTIONAL_SRCS = $_downmixc
+OPTIONAL_OBJS = $_downmixo
+
+EOF
+
+echo "Creating mp3lib/config.mak"
+
+if [ $_3dnow = yes ]; then
+ _3dnowobjectsrcs='dct36_3dnow.s dct64_3dnow.s decode_3dnow.s'
+ _3dnowobjectobjs='dct36_3dnow.o dct64_3dnow.o decode_3dnow.o'
+else
+ _3dnowobjectsrcs=
+ _3dnowobjectobjs=
+fi
+
+cat > mp3lib/config.mak << EOF
+
+include ../config.mak
+
+OPTIONAL_SRCS = $_3dnowobjectsrcs
+OPTIONAL_OBJS = $_3dnowobjectobjs
+
+EOF
+
+cat << EOF
+
+Config files successfully generated by ./configure !
+Please check config.h and config.mak files, tune CPU
+and optimization flags if you don't like these defaults.
+You can compile the program with 'make dep;make' and
+install with 'make install'. Good luck!
+
+EOF
+
+if [ $_mtrr = yes ]; then
+ echo "Please check mtrr settings at /proc/mtrr (see DOCS/MTRR)"
+ echo
+fi
+
+if [ $_sdl = no ]; then
+if [ $_have_sdl = yes ]; then
+ echo "You have libSDL installed, but SDL support is disabled by default."
+ echo "If you want to compile MPlayer with SDL support, re-run ./configure"
+ echo "with --enable-sdl. But it's very buggy & experimental code, use it"
+ echo "only if you really need it! And it works(?) *ONLY* with SDL v1.1.7 !"
+ echo "(SDL driver is NOT supported, so do NOT report bugs relating to SDL!)"
+ echo
+fi
+fi
+
+if [ $_win32libdirnotify = yes ]; then
+ echo "Missing WIN32 codecs dir at $_win32libdir !"
+ echo "Make it and copy DLL files to there! (You can get them from your windows"
+ echo "directory or download ftp://thot.banki.hu/esp-team/linux/MPlayer/w32codec.zip"
+else
+ echo "Ok, Win32 codecs directory at $_win32libdir already exists."
+fi
+
diff --git a/demux_asf.c b/demux_asf.c
new file mode 100644
index 0000000000..ed8532a7a1
--- /dev/null
+++ b/demux_asf.c
@@ -0,0 +1,268 @@
+// ASF file parser for DEMUXER v0.3 by A'rpi/ESP-team
+
+// based on asf file-format doc by Eugene [http://divx.euro.ru]
+
+//static float avi_pts_frametime=1.0f/25.0f;
+//static float avi_audio_pts=0;
+//static float avi_video_pts=0;
+
+//static int skip_video_frames=0;
+
+typedef struct __attribute__((packed)) {
+ unsigned char streamno;
+ unsigned char seq;
+ unsigned long x;
+ unsigned char flag;
+} ASF_segmhdr_t;
+
+
+static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,int id,int seq,unsigned long time,unsigned short dur,int offs){
+ int d;
+// int len;
+ int skip;
+ float pts=0;
+ unsigned char c=0;
+ demux_stream_t *ds=NULL;
+
+ if(verbose>=4) printf("demux_asf.read_packet: id=%d seq=%d len=%d\n",id,seq,len);
+
+#if 0
+ if(demux->video->id==-1) {
+ demux->video->id=asf_video_id;
+ if(verbose) printf("ASF video ID = %d\n",demux->video->id);
+ }
+ if(demux->audio->id==-1)
+ if(id!=asf_video_id && id!=demux->video->id){
+ demux->audio->id=id;
+ if(verbose) printf("ASF audio ID = %d\n",demux->audio->id);
+ }
+#endif
+
+ if(id==demux->audio->id){
+ // audio
+ ds=demux->audio;
+ } else
+ if(id==demux->video->id){
+ // video
+ ds=demux->video;
+ }
+
+ if(ds){
+ if(ds->asf_packet){
+ if(ds->asf_seq!=seq){
+ // closed segment, finalize packet:
+ if(ds==demux->audio)
+ if(asf_scrambling_h>1 && asf_scrambling_w>1)
+ asf_descrambling(ds->asf_packet->buffer,ds->asf_packet->len);
+ ds_add_packet(ds,ds->asf_packet);
+ ds->asf_packet=NULL;
+ } else {
+ // append data to it!
+ demux_packet_t* dp=ds->asf_packet;
+ if(dp->len!=offs && offs!=-1) printf("warning! fragment.len=%d BUT next fragment offset=%d \n",dp->len,offs);
+ dp->buffer=realloc(dp->buffer,dp->len+len);
+ memcpy(dp->buffer+dp->len,data,len);
+ if(verbose>=4) printf("data appended! %d+%d\n",dp->len,len);
+ dp->len+=len;
+ // we are ready now.
+ return 1;
+ }
+ }
+ // create new packet:
+ { demux_packet_t* dp;
+ if(offs>0){
+ printf("warning! broken fragment, %d bytes missing \n",offs);
+ return 0;
+ }
+ dp=new_demux_packet(len);
+ memcpy(dp->buffer,data,len);
+ dp->pts=time*0.001f;
+// if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur);
+ dp->pos=demux->filepos;
+ ds->asf_packet=dp;
+ ds->asf_seq=seq;
+ // we are ready now.
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+//static int num_elementary_packets100=0;
+//static int num_elementary_packets101=0;
+
+// return value:
+// 0 = EOF or no stream found
+// 1 = successfully read a packet
+int demux_asf_fill_buffer(demuxer_t *demux){
+unsigned int id=0;
+unsigned int len;
+int skipped=0;
+int max_packs=128;
+int ret=0;
+
+ demux->filepos=stream_tell(demux->stream);
+ if(demux->filepos>=demux->endpos){
+ demux->stream->eof=1;
+ return 0;
+ }
+
+ stream_read(demux->stream,asf_packet,(int)fileh.packetsize);
+ if(demux->stream->eof) return 0; // EOF
+
+ if(asf_packet[0]==0x82){
+ unsigned char flags=asf_packet[3];
+ unsigned char segtype=asf_packet[4];
+ unsigned char* p=&asf_packet[5];
+ unsigned char* p_end=p+(int)fileh.packetsize;
+ unsigned long time;
+ unsigned short duration;
+ int segs=1;
+ unsigned char segsizetype=0x80;
+ int seg;
+ int padding=0;
+ int plen;
+
+ if(verbose>1){
+ int i;
+ for(i=0;i<16;i++) printf(" %02X",asf_packet[i]);
+ printf("\n");
+ }
+
+ //if(segtype!=0x5d) printf("Warning! packet[4] != 0x5d \n");
+
+ // Calculate packet size (plen):
+ if(flags&0x40){
+ // Explicit (absoulte) packet size
+ plen=p[0]|(p[1]<<8); p+=2;
+ if(verbose>1)printf("Explicit packet size specified: %d \n",plen);
+ if(plen>fileh.packetsize) printf("Warning! plen>packetsize! (%d>%d) \n",plen,(int)fileh.packetsize);
+ if(flags&(8|16)){
+ padding=p[0];p++;
+ if(flags&16){ padding|=p[0]<<8; p++;}
+ if(verbose)printf("Warning! explicit=%d padding=%d \n",plen,fileh.packetsize-padding);
+ }
+ } else {
+ // Padding (relative) size
+ if(flags&8){
+ padding=p[0];++p;
+ } else
+ if(flags&16){
+ padding=p[0]|(p[1]<<8);p+=2;
+ }
+ plen=fileh.packetsize-padding;
+ }
+
+ time=*((unsigned long*)p);p+=4;
+ duration=*((unsigned short*)p);p+=2;
+ if(flags&1){
+ segsizetype=p[0] & 0xC0;
+ segs=p[0] & 0x3F;
+ ++p;
+ }
+ if(verbose>=4) printf("%08X: flag=%02X segs=%d pad=%d time=%d dur=%d\n",
+ demux->filepos,flags,segs,padding,time,duration);
+ for(seg=0;seg<segs;seg++){
+ //ASF_segmhdr_t* sh;
+ unsigned char streamno;
+ unsigned char seq;
+ int len;
+ unsigned long x;
+ unsigned char type;
+ unsigned long time2;
+
+ if(p>=p_end) printf("Warning! invalid packet 1, sig11 coming soon...\n");
+
+ if(verbose>1){
+ int i;
+ printf("seg %d:",seg);
+ for(i=0;i<16;i++) printf(" %02X",p[i]);
+ printf("\n");
+ }
+
+ streamno=p[0]&0x7F;
+ seq=p[1];
+ p+=2;
+
+ switch(segtype){
+ case 0x55:
+ x=*((unsigned char*)p);
+ p++;
+ break;
+ case 0x59:
+ x=*((unsigned short*)p);
+ p+=2;
+ break;
+ case 0x5D:
+ x=*((unsigned long*)p);
+ p+=4;
+ break;
+ default:
+ printf("Warning! unknown segtype == 0x%2X \n",segtype);
+ }
+
+ type=p[0]; p++; // 0x01: grouping 0x08: single
+
+ switch(type){
+ case 0x01:
+ //printf("grouping: %02X \n",p[0]);
+ ++p; // skip unknown byte
+ break;
+ case 0x08:
+ //printf("!!! obj_length = %d\n",*((unsigned long*)p));
+ p+=4;
+ time2=*((unsigned long*)p);p+=4;
+ break;
+ default:
+ printf("unknown segment type: 0x%02X \n",type);
+ }
+
+ if(flags&1){
+ // multiple segments
+ if(segsizetype==0x40){
+ len=*((unsigned char*)p);p++; // 1 byte
+ } else {
+ len=*((unsigned short*)p);p+=2; // 2 byte
+ }
+ } else {
+ // single segment
+ len=plen-(p-asf_packet);
+ }
+ if(len<0 || (p+len)>=p_end){
+ printf("ASF_parser: warning! segment len=%d\n",len);
+ }
+ if(verbose>=4) printf(" seg #%d: streamno=%d seq=%d type=%02X len=%d\n",seg,streamno,seq,type,len);
+
+ switch(type){
+ case 0x01:
+ // GROUPING:
+ //printf("ASF_parser: warning! grouping (flag=1) not yet supported!\n",len);
+ //printf(" total: %d \n",len);
+ while(len>0){
+ int len2=p[0];
+ p++;
+ //printf(" group part: %d bytes\n",len2);
+ demux_asf_read_packet(demux,p,len2,streamno,seq,x,duration,-1);
+ p+=len2;
+ len-=len2+1;
+ }
+ if(len!=0){
+ printf("ASF_parser: warning! groups total != len\n");
+ }
+ break;
+ case 0x08:
+ // NO GROUPING:
+ //printf("fragment offset: %d \n",sh->x);
+ demux_asf_read_packet(demux,p,len,streamno,seq,time2,duration,x);
+ p+=len;
+ break;
+ }
+
+ } // for segs
+ return 1; // success
+ }
+
+ printf("%08X: UNKNOWN TYPE %02X %02X %02X %02X %02X...\n",demux->filepos,asf_packet[0],asf_packet[1],asf_packet[2],asf_packet[3],asf_packet[4]);
+ return 0;
+}
diff --git a/demux_avi.c b/demux_avi.c
new file mode 100644
index 0000000000..d1f29f1ff8
--- /dev/null
+++ b/demux_avi.c
@@ -0,0 +1,276 @@
+// AVI file parser for DEMUXER v2.6 by A'rpi/ESP-team
+
+//static float avi_pts_frametime=1.0f/25.0f;
+static float avi_audio_pts=0;
+static float avi_video_pts=0;
+
+static int skip_video_frames=0;
+
+static inline int avi_stream_id(unsigned int id){
+ unsigned char *p=(unsigned char *)&id;
+ unsigned char a,b;
+ a=p[0]-'0'; b=p[1]-'0';
+ if(a>9 || b>9) return 100; // invalid ID
+ return a*10+b;
+}
+
+// Select ds from ID
+static inline demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){
+ int stream_id=avi_stream_id(id);
+ if(stream_id==demux->audio->id) return demux->audio;
+ if(stream_id==demux->video->id) return demux->video;
+ if(id!=mmioFOURCC('J','U','N','K')){
+ // unknown
+ if(verbose>=2) printf("Unknown chunk: %.4s (%X)\n",&id,id);
+ }
+ return NULL;
+}
+
+static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos){
+ int d;
+// int len;
+ int skip;
+ float pts=0;
+ unsigned char c=0;
+ demux_stream_t *ds=demux_avi_select_stream(demux,id);
+
+ if(verbose>=3) printf("demux_avi.read_packet: %X\n",id);
+
+ if(ds==demux->audio){
+ pts=avi_audio_pts;
+ avi_audio_pts=0;
+ } else
+ if(ds==demux->video){
+ // video
+ if(skip_video_frames>0){
+ // drop frame (seeking)
+ --skip_video_frames;
+ ds=NULL;
+ } else {
+ pts=avi_video_pts;
+ }
+ // ezt a 2 sort lehet hogy fell kell majd cserelni:
+ //avi_video_pts+=avi_pts_frametime;
+ avi_video_pts+=(float)avi_header.video.dwScale/(float)avi_header.video.dwRate;
+ avi_audio_pts=avi_video_pts;
+ }
+
+// len=stream_read_dword_le(demux->stream);
+ skip=(len+1)&(~1); // total bytes in this chunk
+
+ if(ds){
+ if(verbose>=2) printf("DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id);
+ ds_read_packet(ds,demux->stream,len,pts,idxpos);
+ skip-=len;
+ }
+ if(skip){
+ if(verbose>=2) printf("DEMUX_AVI: Skipping %d bytes from packet %04X\n",skip,id);
+ stream_skip(demux->stream,skip);
+ }
+ return ds?1:0;
+}
+
+//static int num_elementary_packets100=0;
+//static int num_elementary_packets101=0;
+
+// return value:
+// 0 = EOF or no stream found
+// 1 = successfully read a packet
+int demux_avi_fill_buffer(demuxer_t *demux){
+unsigned int id=0;
+unsigned int len;
+int skipped=0;
+int max_packs=128;
+int ret=0;
+
+do{
+ AVIINDEXENTRY *idx=NULL;
+ demux->filepos=stream_tell(demux->stream);
+ if(demux->filepos>=demux->endpos){
+ demux->stream->eof=1;
+ return 0;
+ }
+ if(stream_eof(demux->stream)) return 0;
+ if(avi_header.idx_size>0 && avi_header.idx_pos<avi_header.idx_size){
+ unsigned int pos;
+
+ //if(avi_header.idx_pos<0) printf("Fatal! idx_pos=%d\n",avi_header.idx_pos);
+
+ idx=&avi_header.idx[avi_header.idx_pos++];
+
+ //printf("[%d]",avi_header.idx_pos);fflush(stdout);
+
+ //stream_seek(demux->stream,idx.dwChunkOffset);
+ //printf("IDX pos=%X idx.pos=%X idx.size=%X idx.flags=%X\n",demux->filepos,
+ // pos-4,idx->dwChunkLength,idx->dwFlags);
+ if(idx->dwFlags&AVIIF_LIST){
+ // LIST
+ continue;
+ }
+ if(!demux_avi_select_stream(demux,idx->ckid)){
+ if(verbose>2) printf("Skip chunk %.4s (0x%X) \n",&idx->ckid,idx->ckid);
+ continue; // skip this chunk
+ }
+
+ pos=idx->dwChunkOffset+avi_header.idx_offset;
+ if(pos<avi_header.movi_start || pos>=avi_header.movi_end){
+ printf("ChunkOffset out of range! current=0x%X idx=0x%X \n",demux->filepos,pos);
+ continue;
+ }
+#if 0
+ if(pos!=demux->filepos){
+ printf("Warning! pos=0x%X idx.pos=0x%X diff=%d \n",demux->filepos,pos,pos-demux->filepos);
+ }
+#endif
+ stream_seek(demux->stream,pos);
+ id=stream_read_dword_le(demux->stream);
+ if(id!=idx->ckid){
+ printf("ChunkID mismatch! raw=%.4s idx=%.4s \n",&id,&idx->ckid);
+ continue;
+ }
+ len=stream_read_dword_le(demux->stream);
+// if((len&(~1))!=(idx->dwChunkLength&(~1))){
+// if((len)!=(idx->dwChunkLength)){
+ if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){
+ printf("ChunkSize mismatch! raw=%d idx=%d \n",len,idx->dwChunkLength);
+ continue;
+ }
+ } else {
+ id=stream_read_dword_le(demux->stream);
+ len=stream_read_dword_le(demux->stream);
+ if(id==mmioFOURCC('L','I','S','T')){
+ id=stream_read_dword_le(demux->stream); // list type
+ continue;
+ }
+ }
+ ret=demux_avi_read_packet(demux,id,len,avi_header.idx_pos-1);
+ if(!ret && skip_video_frames<=0)
+ if(--max_packs==0){
+ demux->stream->eof=1;
+ printf("demux: file doesn't contain the selected audio or video stream\n");
+ return 0;
+ }
+} while(ret!=1);
+ return 1;
+}
+
+
+// return value:
+// 0 = EOF or no stream found
+// 1 = successfully read a packet
+int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){
+unsigned int id=0;
+unsigned int len;
+int skipped=0;
+int max_packs=128;
+int ret=0;
+
+do{
+ AVIINDEXENTRY *idx=NULL;
+ int idx_pos=0;
+ demux->filepos=stream_tell(demux->stream);
+
+ if(ds==demux->video) idx_pos=avi_header.idx_pos_a++; else
+ if(ds==demux->audio) idx_pos=avi_header.idx_pos_v++; else
+ idx_pos=avi_header.idx_pos++;
+
+ if(avi_header.idx_size>0 && idx_pos<avi_header.idx_size){
+ unsigned int pos;
+ idx=&avi_header.idx[idx_pos];
+
+ if(idx->dwFlags&AVIIF_LIST){
+ // LIST
+ continue;
+ }
+ if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){
+ if(verbose>2) printf("Skip chunk %.4s (0x%X) \n",&idx->ckid,idx->ckid);
+ continue; // skip this chunk
+ }
+
+ pos=idx->dwChunkOffset+avi_header.idx_offset;
+ if(pos<avi_header.movi_start || pos>=avi_header.movi_end){
+ printf("ChunkOffset out of range! current=0x%X idx=0x%X \n",demux->filepos,pos);
+ continue;
+ }
+#if 0
+ if(pos!=demux->filepos){
+ printf("Warning! pos=0x%X idx.pos=0x%X diff=%d \n",demux->filepos,pos,pos-demux->filepos);
+ }
+#endif
+ stream_seek(demux->stream,pos);
+
+ id=stream_read_dword_le(demux->stream);
+
+ if(stream_eof(demux->stream)) return 0;
+
+ if(id!=idx->ckid){
+ printf("ChunkID mismatch! raw=%.4s idx=%.4s \n",&id,&idx->ckid);
+ continue;
+ }
+ len=stream_read_dword_le(demux->stream);
+// if((len&(~1))!=(idx->dwChunkLength&(~1))){
+// if((len)!=(idx->dwChunkLength)){
+ if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){
+ printf("ChunkSize mismatch! raw=%d idx=%d \n",len,idx->dwChunkLength);
+ continue;
+ }
+ } else return 0;
+ ret=demux_avi_read_packet(demux,id,len,idx_pos);
+ if(!ret && skip_video_frames<=0)
+ if(--max_packs==0){
+ demux->stream->eof=1;
+ printf("demux: file doesn't contain the selected audio or video stream\n");
+ return 0;
+ }
+} while(ret!=1);
+ return 1;
+}
+
+
+// return value:
+// 0 = EOF or no stream found
+// 1 = successfully read a packet
+int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){
+unsigned int id=0;
+unsigned int len;
+int skipped=0;
+int ret=0;
+int *fpos=NULL;
+
+ if(ds==demux->video) fpos=&avi_header.idx_pos_a; else
+ if(ds==demux->audio) fpos=&avi_header.idx_pos_v; else
+ return 0;
+
+ stream_seek(demux->stream,fpos[0]);
+
+do{
+
+ demux->filepos=stream_tell(demux->stream);
+ if(demux->filepos>=demux->endpos){
+ demux->stream->eof=1;
+ return 0;
+ }
+ if(stream_eof(demux->stream)) return 0;
+
+ id=stream_read_dword_le(demux->stream);
+ len=stream_read_dword_le(demux->stream);
+ if(id==mmioFOURCC('L','I','S','T')){
+ id=stream_read_dword_le(demux->stream); // list type
+ continue;
+ }
+
+ if(ds==demux_avi_select_stream(demux,id)){
+ // read it!
+ ret=demux_avi_read_packet(demux,id,len,avi_header.idx_pos-1);
+ } else {
+ // skip it!
+ int skip=(len+1)&(~1); // total bytes in this chunk
+ stream_skip(demux->stream,skip);
+ }
+
+} while(ret!=1);
+ fpos[0]=stream_tell(demux->stream);
+ return 1;
+}
+
+
diff --git a/demux_mpg.c b/demux_mpg.c
new file mode 100644
index 0000000000..f276541727
--- /dev/null
+++ b/demux_mpg.c
@@ -0,0 +1,228 @@
+// MPG/VOB file parser for DEMUXER v2.5 by A'rpi/ESP-team
+
+static unsigned int read_mpeg_timestamp(stream_t *s,int c){
+ int d,e;
+ unsigned int pts;
+ d=stream_read_word(s);
+ e=stream_read_word(s);
+ if( ((c&1)!=1) || ((d&1)!=1) || ((e&1)!=1) ) return 0; // invalid pts
+ pts=(((c>>1)&7)<<30)|((d>>1)<<15)|(e>>1);
+ if(verbose>=3) printf("{%d}",pts);
+ return pts;
+}
+
+static char dvdaudio_table[256];
+//static unsigned int packet_start_pos=0;
+
+static int demux_mpg_read_packet(demuxer_t *demux,int id){
+ int d;
+ int len;
+ unsigned char c=0;
+ unsigned int pts=0;
+ unsigned int dts=0;
+ demux_stream_t *ds=NULL;
+
+ if(verbose>=3) printf("demux_read_packet: %X\n",id);
+
+// if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
+ if(id<0x1BC || id>0x1FF) return -1;
+ if(id==0x1BE) return -1; // padding stream
+ if(id==0x1BF) return -1; // private2
+
+ len=stream_read_word(demux->stream);
+ if(verbose>=3) printf("PACKET len=%d",len);
+ if(len==0 || len>4096) return -2; // invalid packet !!!!!!
+
+ while(len>0){ // Skip stuFFing bytes
+ c=stream_read_char(demux->stream);--len;
+ if(c!=0xFF)break;
+ }
+ if((c>>6)==1){ // Read (skip) STD scale & size value
+// printf(" STD_scale=%d",(c>>5)&1);
+ d=((c&0x1F)<<8)|stream_read_char(demux->stream);
+ len-=2;
+// printf(" STD_size=%d",d);
+ c=stream_read_char(demux->stream);
+ }
+ // Read System-1 stream timestamps:
+ if((c>>4)==2){
+ pts=read_mpeg_timestamp(demux->stream,c);
+ len-=4;
+ } else
+ if((c>>4)==3){
+ pts=read_mpeg_timestamp(demux->stream,c);
+ c=stream_read_char(demux->stream);
+ if((c>>4)!=1) pts=0; //printf("{ERROR4}");
+ dts=read_mpeg_timestamp(demux->stream,c);
+ len-=4+1+4;
+ } else
+ if((c>>6)==2){
+ int pts_flags;
+ int hdrlen;
+ // System-2 (.VOB) stream:
+ if((c>>4)&3) printf("Warning! Encrypted VOB file! (DeCSS not (yet) supported)\n");
+ c=stream_read_char(demux->stream); pts_flags=c>>6;
+ c=stream_read_char(demux->stream); hdrlen=c;
+ len-=2;
+ if(verbose>=3) printf(" hdrlen=%d (len=%d)",hdrlen,len);
+ if(hdrlen>len) return -1; // invalid header length
+ if(pts_flags==2){
+ c=stream_read_char(demux->stream);
+ pts=read_mpeg_timestamp(demux->stream,c);
+ len-=5;hdrlen-=5;
+ } else
+ if(pts_flags==3){
+ c=stream_read_char(demux->stream);
+ pts=read_mpeg_timestamp(demux->stream,c);
+ c=stream_read_char(demux->stream);
+ dts=read_mpeg_timestamp(demux->stream,c);
+ len-=10;hdrlen-=10;
+ }
+ len-=hdrlen;
+ if(hdrlen>0) stream_skip(demux->stream,hdrlen); // skip header bytes
+
+ //============== DVD Audio sub-stream ======================
+ if(id==0x1BD){
+ int aid=stream_read_char(demux->stream)&0x7F;--len;
+ ds=demux->audio;
+ if(ds->id==-1) ds->id=aid;
+ if(!dvdaudio_table[aid]){
+ dvdaudio_table[aid]=1;
+ printf("DVD Audio format: %s ID=%d%s\n",
+ ((aid&0x70)==0x20)?"PCM":"AC3",aid,(ds->id==aid)?" CURRENT":"");
+ }
+ if(len<3) return -1; // invalid audio packet
+ if(ds->id!=aid){
+ // drop packet (not selected channel)
+ ds=NULL;
+ } else {
+ // READ Packet: Skip additional audio header data:
+ c=stream_read_char(demux->stream);
+ c=stream_read_char(demux->stream);
+ c=stream_read_char(demux->stream);
+ len-=3;
+ if(ds->type==-1){
+ // autodetect type
+ ds->type=((aid&0x70)==0x20)?2:3;
+ }
+ if(ds->type==2 && len>=2){
+ // read PCM header
+ int head;
+ head=stream_read_char(demux->stream); head=c<<8;
+ c=stream_read_char(demux->stream); head|=c; len-=2;
+ while(len>0 && head!=0x180){
+ head=c<<8;
+ c=stream_read_char(demux->stream);
+ head|=c;--len;
+ }
+ if(!len) printf("End of packet while searching for PCM header\n");
+ }
+ }
+ }
+
+ } else {
+ //if(c!=0x0f) printf(" {ERROR5,c=%d} \n",c);
+ }
+ if(verbose>=3) printf("\n");
+
+ if(len<=0 || len>4096) return -1; // Invalid packet size
+
+ if(id>=0x1C0 && id<=0x1DF){
+ // mpeg audio
+ int aid=id-0x1C0;
+ if(demux->audio->id==-1) demux->audio->id=aid;
+ if(demux->audio->id==aid){
+ ds=demux->audio;
+ if(ds->type==-1) ds->type=1;
+ }
+ } else
+ if(id>=0x1E0 && id<=0x1EF){
+ // mpeg video
+ int aid=id-0x1E0;
+ if(demux->video->id==-1) demux->video->id=aid;
+ if(demux->video->id==aid) ds=demux->video;
+ }
+
+ if(ds){
+ if(verbose>=2) printf("DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
+// printf("packet start = 0x%X \n",stream_tell(demux->stream)-packet_start_pos);
+ ds_read_packet(ds,demux->stream,len,pts/90000.0f,0);
+ return 1;
+ }
+ if(verbose>=2) printf("DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
+ stream_skip(demux->stream,len);
+ return 0;
+}
+
+static int num_elementary_packets100=0;
+static int num_elementary_packets101=0;
+
+int demux_mpg_es_fill_buffer(demuxer_t *demux){
+//if(demux->type==DEMUXER_TYPE_MPEG_ES)
+ // Elementary video stream
+ if(demux->stream->eof) return 0;
+ demux->filepos=stream_tell(demux->stream);
+ ds_read_packet(demux->video,demux->stream,4096,0,0);
+ return 1;
+}
+
+int demux_mpg_fill_buffer(demuxer_t *demux){
+unsigned int head=0;
+int skipped=0;
+int max_packs=128;
+int ret=0;
+
+// System stream
+do{
+ demux->filepos=stream_tell(demux->stream);
+ head=stream_read_dword(demux->stream);
+ while((head&0xffffff00)!=0x00000100){
+ if(stream_eof(demux->stream)) break;
+ head=(head<<8)|stream_read_char(demux->stream);
+ ++skipped; ++demux->filepos;
+ }
+ if(stream_eof(demux->stream)) break;
+ // sure: head=0x000001XX
+ if(demux->synced==0){
+ if(head==0x1BA) demux->synced=1;
+ } else
+ if(demux->synced==1){
+ if(head==0x1BB || (head>=0x1C0 && head<=0x1EF)){
+ demux->synced=2;
+ if(verbose) printf("system stream synced at 0x%X (%d)!\n",demux->filepos,demux->filepos);
+ } else demux->synced=0;
+ } // else
+ if(demux->synced==2){
+ ret=demux_mpg_read_packet(demux,head);
+ if(!ret)
+ if(--max_packs==0){
+ demux->stream->eof=1;
+ printf("demux: file doesn't contain the selected audio or video stream\n");
+ return 0;
+ }
+ } else {
+ if(head>=0x100 && head<0x1B0){
+ if(head==0x100)
+ ++num_elementary_packets100;
+ else
+ if(head==0x101) ++num_elementary_packets101;
+ if(verbose>=3) printf("Opps... elementary video packet found: %03X\n",head);
+ }
+#if 1
+ if(num_elementary_packets100>50 && num_elementary_packets101>50
+ && skipped>4000000){
+ if(verbose) printf("sync_mpeg_ps: seems to be ES stream...\n");
+ demux->stream->eof=1;
+ break;
+ }
+#endif
+ }
+} while(ret!=1);
+ if(verbose>=2) printf("demux: %d bad bytes skipped\n",skipped);
+ if(demux->stream->eof){
+ if(verbose>=2) printf("MPEG Stream reached EOF\n");
+ return 0;
+ }
+ return 1;
+}
+
diff --git a/demuxer.c b/demuxer.c
new file mode 100644
index 0000000000..54d0314c14
--- /dev/null
+++ b/demuxer.c
@@ -0,0 +1,285 @@
+//=================== DEMUXER v2.5 =========================
+
+#define MAX_PACKS 2048
+#define MAX_PACK_BYTES 0x400000
+
+typedef struct demux_packet_st {
+ int len;
+ float pts;
+ int pos; // pozicio indexben (AVI) ill. fileban (MPG)
+ unsigned char* buffer;
+ struct demux_packet_st* next;
+} demux_packet_t;
+
+inline demux_packet_t* new_demux_packet(int len){
+ demux_packet_t* dp=malloc(sizeof(demux_packet_t));
+ dp->len=len;
+ dp->buffer=malloc(len);
+ dp->next=NULL;
+ dp->pts=0;
+ dp->pos=0;
+ return dp;
+}
+
+inline void free_demux_packet(demux_packet_t* dp){
+ free(dp->buffer);
+ free(dp);
+}
+
+typedef struct {
+ int buffer_pos; // current buffer position
+ int buffer_size; // current buffer size
+ unsigned char* buffer; // current buffer
+ float pts; // current buffer's pts
+ int eof; // end of demuxed stream? (true if all buffer empty)
+ int pos; // position in the input stream (file)
+ int dpos; // position in the demuxed stream
+//---------------
+ int packs; // number of packets in buffer
+ int bytes; // total bytes of packets in buffer
+ demux_packet_t *first; // read to current buffer from here
+ demux_packet_t *last; // append new packets from input stream to here
+ int id; // stream ID (for multiple audio/video streams)
+ int type; // stream type (currently used only for audio)
+ struct demuxer_st *demuxer; // parent demuxer structure (stream handler)
+// ---- asf -----
+ demux_packet_t *asf_packet; // read asf fragments here
+ int asf_seq;
+} demux_stream_t;
+
+demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id){
+ demux_stream_t* ds=malloc(sizeof(demux_stream_t));
+ ds->buffer_pos=ds->buffer_size=0;
+ ds->buffer=NULL;
+ ds->pts=0;
+ ds->eof=0;
+ ds->pos=0;
+ ds->dpos=0;
+//---------------
+ ds->packs=0;
+ ds->bytes=0;
+ ds->first=ds->last=NULL;
+ ds->id=id;
+ ds->type=-1;
+ ds->demuxer=demuxer;
+//----------------
+ ds->asf_seq=-1;
+ ds->asf_packet=NULL;
+ return ds;
+}
+
+#define DEMUXER_TYPE_UNKNOWN 0
+#define DEMUXER_TYPE_MPEG_ES 1
+#define DEMUXER_TYPE_MPEG_PS 2
+#define DEMUXER_TYPE_AVI 3
+#define DEMUXER_TYPE_AVI_NI 4
+#define DEMUXER_TYPE_AVI_NINI 5
+#define DEMUXER_TYPE_ASF 6
+
+#define DEMUXER_TIME_NONE 0
+#define DEMUXER_TIME_PTS 1
+#define DEMUXER_TIME_FILE 2
+#define DEMUXER_TIME_BPS 3
+
+typedef struct demuxer_st {
+ stream_t *stream;
+ int synced; // stream synced (used by mpeg)
+ int filepos; // input stream current pos.
+ int endpos; // input stream end pos. (return EOF fi filepos>endpos)
+ int type; // mpeg system stream, mpeg elementary s., avi raw, avi indexed
+// int time_src;// time source (pts/file/bps)
+ demux_stream_t *audio;
+ demux_stream_t *video;
+} demuxer_t;
+
+demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id){
+ demuxer_t *d=malloc(sizeof(demuxer_t));
+ d->stream=stream;
+ d->synced=0;
+ d->filepos=0;
+ d->audio=new_demuxer_stream(d,a_id);
+ d->video=new_demuxer_stream(d,v_id);
+ d->type=type;
+ return d;
+}
+
+static void ds_add_packet(demux_stream_t *ds,demux_packet_t* dp){
+// demux_packet_t* dp=new_demux_packet(len);
+// stream_read(stream,dp->buffer,len);
+// dp->pts=pts; //(float)pts/90000.0f;
+// dp->pos=pos;
+ // append packet to DS stream:
+ ++ds->packs;
+ ds->bytes+=dp->len;
+ if(ds->last){
+ // next packet in stream
+ ds->last->next=dp;
+ ds->last=dp;
+ } else {
+ // first packet in stream
+ ds->first=ds->last=dp;
+ }
+ if(verbose>=2)
+ printf("DEMUX: Append packet to %s, len=%d pts=%5.3f pos=%d [packs: A=%d V=%d]\n",
+ (ds==ds->demuxer->audio)?"d_audio":"d_video",
+ dp->len,dp->pts,dp->pos,ds->demuxer->audio->packs,ds->demuxer->video->packs);
+}
+
+static void ds_read_packet(demux_stream_t *ds,stream_t *stream,int len,float pts,int pos){
+ demux_packet_t* dp=new_demux_packet(len);
+ stream_read(stream,dp->buffer,len);
+ dp->pts=pts; //(float)pts/90000.0f;
+ dp->pos=pos;
+ // append packet to DS stream:
+ ds_add_packet(ds,dp);
+}
+
+
+// return value:
+// 0 = EOF or no stream found or invalid type
+// 1 = successfully read a packet
+int demux_mpg_es_fill_buffer(demuxer_t *demux);
+int demux_mpg_fill_buffer(demuxer_t *demux);
+int demux_avi_fill_buffer(demuxer_t *demux);
+int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t *ds);
+int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t *ds);
+int demux_asf_fill_buffer(demuxer_t *demux);
+
+int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
+ // Note: parameter 'ds' can be NULL!
+ switch(demux->type){
+ case DEMUXER_TYPE_MPEG_ES: return demux_mpg_es_fill_buffer(demux);
+ case DEMUXER_TYPE_MPEG_PS: return demux_mpg_fill_buffer(demux);
+ case DEMUXER_TYPE_AVI: return demux_avi_fill_buffer(demux);
+ case DEMUXER_TYPE_AVI_NI: return demux_avi_fill_buffer_ni(demux,ds);
+ case DEMUXER_TYPE_AVI_NINI: return demux_avi_fill_buffer_nini(demux,ds);
+ case DEMUXER_TYPE_ASF: return demux_asf_fill_buffer(demux);
+ }
+ return 0;
+}
+
+// return value:
+// 0 = EOF
+// 1 = succesfull
+inline static int ds_fill_buffer(demux_stream_t *ds){
+ demuxer_t *demux=ds->demuxer;
+ if(ds->buffer) free(ds->buffer);
+ if(verbose>2){
+ if(ds==demux->audio) printf("ds_fill_buffer(d_audio) called\n");else
+ if(ds==demux->video) printf("ds_fill_buffer(d_video) called\n");else
+ printf("ds_fill_buffer(unknown 0x%X) called\n",ds);
+ }
+ while(1){
+ if(ds->packs){
+ demux_packet_t *p=ds->first;
+ // copy useful data:
+ ds->buffer=p->buffer;
+ ds->buffer_pos=0;
+ ds->buffer_size=p->len;
+ ds->pos=p->pos;
+ ds->dpos+=p->len; // !!!
+ ds->pts=p->pts;
+ // free packet:
+ ds->bytes-=p->len;
+ ds->first=p->next;
+ if(!ds->first) ds->last=NULL;
+ free(p);
+ --ds->packs;
+ return 1; //ds->buffer_size;
+ }
+ if(demux->audio->packs>=MAX_PACKS || demux->audio->bytes>=MAX_PACK_BYTES){
+ printf("\nDEMUXER: Too many (%d in %d bytes) audio packets in the buffer!\n",demux->audio->packs,demux->audio->bytes);
+ printf("(maybe you play a non-interleaved stream/file or audio codec failed)\n");
+ break;
+ }
+ if(demux->video->packs>=MAX_PACKS || demux->video->bytes>=MAX_PACK_BYTES){
+ printf("\nDEMUXER: Too many (%d in %d bytes) video packets in the buffer!\n",demux->video->packs,demux->video->bytes);
+ printf("(maybe you play a non-interleaved stream/file or video codec failed)\n");
+ break;
+ }
+ if(!demux_fill_buffer(demux,ds)) break; // EOF
+ }
+ ds->buffer_pos=ds->buffer_size=0;
+ ds->buffer=NULL;
+ if(verbose) printf("ds_fill_buffer: EOF reached (stream: %s) \n",ds==demux->audio?"audio":"video");
+ ds->eof=1;
+ return 0;
+}
+
+inline int ds_tell(demux_stream_t *ds){
+ return (ds->dpos-ds->buffer_size)+ds->buffer_pos;
+}
+
+int demux_read_data(demux_stream_t *ds,char* mem,int len){
+int x;
+int bytes=0;
+while(len>0){
+ x=ds->buffer_size-ds->buffer_pos;
+ if(x==0){
+ if(!ds_fill_buffer(ds)) return bytes;
+ } else {
+ if(x>len) x=len;
+ if(mem) memcpy(mem+bytes,&ds->buffer[ds->buffer_pos],x);
+ bytes+=x;len-=x;ds->buffer_pos+=x;
+ }
+}
+return bytes;
+}
+
+
+#if 1
+#define demux_getc(ds) (\
+ (ds->buffer_pos<ds->buffer_size) ? ds->buffer[ds->buffer_pos++] \
+ :((!ds_fill_buffer(ds))? (-1) : ds->buffer[ds->buffer_pos++] ) )
+#else
+inline static int demux_getc(demux_stream_t *ds){
+ if(ds->buffer_pos>=ds->buffer_size){
+ if(!ds_fill_buffer(ds)){
+// printf("DEMUX_GETC: EOF reached!\n");
+ return -1; // EOF
+ }
+ }
+// printf("[%02X]",ds->buffer[ds->buffer_pos]);
+ return ds->buffer[ds->buffer_pos++];
+}
+#endif
+
+void ds_free_packs(demux_stream_t *ds){
+ demux_packet_t *dp=ds->first;
+ while(dp){
+ demux_packet_t *dn=dp->next;
+ free(dp->buffer);
+ free(dp);
+ dp=dn;
+ }
+ if(ds->asf_packet){
+ // free unfinished .asf fragments:
+ free(ds->asf_packet->buffer);
+ free(ds->asf_packet);
+ ds->asf_packet=NULL;
+ }
+ ds->first=ds->last=NULL;
+ ds->packs=0; // !!!!!
+ ds->bytes=0;
+ if(ds->buffer) free(ds->buffer);
+ ds->buffer=NULL;
+ ds->buffer_pos=ds->buffer_size;
+ ds->pts=0;
+}
+
+int ds_get_packet(demux_stream_t *ds,char **start){
+ while(1){
+ int len;
+ if(ds->buffer_pos>=ds->buffer_size){
+ if(!ds_fill_buffer(ds)){
+ // EOF
+ *start = NULL;
+ return -1;
+ }
+ }
+ len=ds->buffer_size-ds->buffer_pos;
+ *start = &ds->buffer[ds->buffer_pos];
+ ds->buffer_pos+=len;
+ return len;
+ }
+}
diff --git a/dll_init.c b/dll_init.c
new file mode 100644
index 0000000000..dac4e12d9d
--- /dev/null
+++ b/dll_init.c
@@ -0,0 +1,164 @@
+// ACM audio and VfW video codecs initialization
+// based on the avifile library [http://divx.euro.ru]
+
+int init_audio_codec(){
+ HRESULT ret;
+ WAVEFORMATEX *in_fmt=(WAVEFORMATEX*)&avi_header.wf_ext;
+ unsigned long srcsize=0;
+
+ if(verbose) printf("======= Win32 (ACM) AUDIO Codec init =======\n");
+
+ avi_header.srcstream=NULL;
+
+// if(in_fmt->nSamplesPerSec==0){ printf("Bad WAVE header!\n");exit(1); }
+// MSACM_RegisterAllDrivers();
+
+ avi_header.wf.nChannels=in_fmt->nChannels;
+ avi_header.wf.nSamplesPerSec=in_fmt->nSamplesPerSec;
+ avi_header.wf.nAvgBytesPerSec=2*avi_header.wf.nSamplesPerSec*avi_header.wf.nChannels;
+ avi_header.wf.wFormatTag=WAVE_FORMAT_PCM;
+ avi_header.wf.nBlockAlign=2*in_fmt->nChannels;
+ avi_header.wf.wBitsPerSample=16;
+ avi_header.wf.cbSize=0;
+
+ win32_codec_name = avi_header.audio_codec;
+ ret=acmStreamOpen(&avi_header.srcstream,(HACMDRIVER)NULL,
+ in_fmt,&avi_header.wf,
+ NULL,0,0,0);
+ if(ret){
+ if(ret==ACMERR_NOTPOSSIBLE)
+ printf("ACM_Decoder: Unappropriate audio format\n");
+ else
+ printf("ACM_Decoder: acmStreamOpen error %d", ret);
+ avi_header.srcstream=NULL;
+ return 0;
+ }
+ if(verbose) printf("Audio codec opened OK! ;-)\n");
+
+ srcsize=in_fmt->nBlockAlign;
+ acmStreamSize(avi_header.srcstream, srcsize, &srcsize, ACM_STREAMSIZEF_SOURCE);
+ if(srcsize<OUTBURST) srcsize=OUTBURST;
+ avi_header.audio_out_minsize=srcsize; // audio output min. size
+ if(verbose) printf("Audio ACM output buffer min. size: %d\n",srcsize);
+
+ acmStreamSize(avi_header.srcstream, srcsize, &srcsize, ACM_STREAMSIZEF_DESTINATION);
+ avi_header.audio_in_minsize=srcsize; // audio input min. size
+ if(verbose) printf("Audio ACM input buffer min. size: %d\n",srcsize);
+
+ return 1;
+}
+
+
+int init_video_codec(int outfmt){
+ HRESULT ret;
+
+ if(verbose) printf("======= Win32 (VFW) VIDEO Codec init =======\n");
+
+ memset(&avi_header.o_bih, 0, sizeof(BITMAPINFOHEADER));
+ avi_header.o_bih.biSize = sizeof(BITMAPINFOHEADER);
+
+ win32_codec_name = avi_header.video_codec;
+ avi_header.hic = ICOpen( 0x63646976, avi_header.bih.biCompression, ICMODE_FASTDECOMPRESS);
+// avi_header.hic = ICOpen( 0x63646976, avi_header.bih.biCompression, ICMODE_DECOMPRESS);
+ if(!avi_header.hic){
+ printf("ICOpen failed! unknown codec / wrong parameters?\n");
+ return 0;
+ }
+
+// avi_header.bih.biBitCount=32;
+
+ ret = ICDecompressGetFormat(avi_header.hic, &avi_header.bih, &avi_header.o_bih);
+ if(ret){
+ printf("ICDecompressGetFormat failed: Error %d\n", ret);
+ return 0;
+ }
+ if(verbose) printf("ICDecompressGetFormat OK\n");
+
+// printf("ICM_DECOMPRESS_QUERY=0x%X",ICM_DECOMPRESS_QUERY);
+
+// avi_header.o_bih.biWidth=avi_header.bih.biWidth;
+// avi_header.o_bih.biCompression = 0x32315659; // mmioFOURCC('U','Y','V','Y');
+// ret=ICDecompressGetFormatSize(avi_header.hic,&avi_header.o_bih);
+// avi_header.o_bih.biCompression = 3; //0x32315659;
+// avi_header.o_bih.biCompression = mmioFOURCC('U','Y','V','Y');
+// avi_header.o_bih.biCompression = mmioFOURCC('U','Y','V','Y');
+// avi_header.o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
+// avi_header.o_bih.biPlanes=3;
+// avi_header.o_bih.biBitCount=16;
+
+ if(outfmt==IMGFMT_YUY2)
+ avi_header.o_bih.biBitCount=16;
+ else
+ avi_header.o_bih.biBitCount=outfmt&0xFF;// //24;
+
+ avi_header.o_bih.biSizeImage=avi_header.o_bih.biWidth*avi_header.o_bih.biHeight*(avi_header.o_bih.biBitCount/8);
+
+ if(!avi_header.flipped)
+ avi_header.o_bih.biHeight=-avi_header.bih.biHeight; // flip image!
+
+ if(outfmt==IMGFMT_YUY2 && !avi_header.yuv_hack_needed)
+ avi_header.o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
+
+// avi_header.o_bih.biCompression = mmioFOURCC('U','Y','V','Y');
+
+
+ if(verbose) {
+ printf("Starting decompression, format:\n");
+ printf(" biSize %d\n", avi_header.bih.biSize);
+ printf(" biWidth %d\n", avi_header.bih.biWidth);
+ printf(" biHeight %d\n", avi_header.bih.biHeight);
+ printf(" biPlanes %d\n", avi_header.bih.biPlanes);
+ printf(" biBitCount %d\n", avi_header.bih.biBitCount);
+ printf(" biCompression %d='%.4s'\n", avi_header.bih.biCompression, &avi_header.bih.biCompression);
+ printf(" biSizeImage %d\n", avi_header.bih.biSizeImage);
+ printf("Dest fmt:\n");
+ printf(" biSize %d\n", avi_header.o_bih.biSize);
+ printf(" biWidth %d\n", avi_header.o_bih.biWidth);
+ printf(" biHeight %d\n", avi_header.o_bih.biHeight);
+ printf(" biPlanes %d\n", avi_header.o_bih.biPlanes);
+ printf(" biBitCount %d\n", avi_header.o_bih.biBitCount);
+ printf(" biCompression %d='%.4s'\n", avi_header.o_bih.biCompression, &avi_header.o_bih.biCompression);
+ printf(" biSizeImage %d\n", avi_header.o_bih.biSizeImage);
+ }
+
+ ret = ICDecompressQuery(avi_header.hic, &avi_header.bih, &avi_header.o_bih);
+ if(ret){
+ printf("ICDecompressQuery failed: Error %d\n", ret);
+ return 0;
+ }
+ if(verbose) printf("ICDecompressQuery OK\n");
+
+
+ ret = ICDecompressBegin(avi_header.hic, &avi_header.bih, &avi_header.o_bih);
+ if(ret){
+ printf("ICDecompressBegin failed: Error %d\n", ret);
+ return 0;
+ }
+
+#if 0
+
+//avi_header.hic
+//ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2)
+{ int i;
+ for(i=73;i<256;i++){
+ printf("Calling ICM_USER+%d function...",i);fflush(stdout);
+ ret = ICSendMessage(avi_header.hic,ICM_USER+i,NULL,NULL);
+ printf(" ret=%d\n",ret);
+ }
+}
+#endif
+
+ avi_header.our_out_buffer = malloc(avi_header.o_bih.biSizeImage);
+ if(!avi_header.our_out_buffer){
+ printf("not enough memory for decoded picture buffer (%d bytes)\n", avi_header.o_bih.biSizeImage);
+ return 0;
+ }
+
+ if(outfmt==IMGFMT_YUY2 && avi_header.yuv_hack_needed)
+ avi_header.o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
+
+// avi_header.our_in_buffer=malloc(avi_header.video.dwSuggestedBufferSize); // FIXME!!!!
+
+ if(verbose) printf("VIDEO CODEC Init OK!!! ;-)\n");
+ return 1;
+}
diff --git a/drivers/3dfx.h b/drivers/3dfx.h
new file mode 100644
index 0000000000..0097f4f39e
--- /dev/null
+++ b/drivers/3dfx.h
@@ -0,0 +1,154 @@
+/*
+ * 3dfx.h
+ *
+ * Copyright (C) Colin Cross Apr 2000
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#define VOODOO_IO_REG_OFFSET ((unsigned long int)0x0000000)
+#define VOODOO_YUV_REG_OFFSET ((unsigned long int)0x0080100)
+#define VOODOO_AGP_REG_OFFSET ((unsigned long int)0x0080000)
+#define VOODOO_2D_REG_OFFSET ((unsigned long int)0x0100000)
+#define VOODOO_YUV_PLANE_OFFSET ((unsigned long int)0x0C00000)
+
+#define VOODOO_BLT_FORMAT_YUYV (8<<16)
+#define VOODOO_BLT_FORMAT_16 (3<<16)
+
+#define VOODOO_YUV_STRIDE (1024>>2)
+
+struct voodoo_yuv_fb_t {
+ uint32_t Y[0x0040000];
+ uint32_t U[0x0040000];
+ uint32_t V[0x0040000];
+};
+
+struct voodoo_yuv_reg_t {
+ uint32_t yuvBaseAddr;
+ uint32_t yuvStride;
+};
+
+struct voodoo_2d_reg_t {
+ uint32_t status;
+ uint32_t intCtrl;
+ uint32_t clip0Min;
+ uint32_t clip0Max;
+ uint32_t dstBaseAddr;
+ uint32_t dstFormat;
+ uint32_t srcColorkeyMin;
+ uint32_t srcColorkeyMax;
+ uint32_t dstColorkeyMin;
+ uint32_t dstColorkeyMax;
+ signed long bresError0;
+ signed long bresError1;
+ uint32_t rop;
+ uint32_t srcBaseAddr;
+ uint32_t commandExtra;
+ uint32_t lineStipple;
+ uint32_t lineStyle;
+ uint32_t pattern0Alias;
+ uint32_t pattern1Alias;;
+ uint32_t clip1Min;
+ uint32_t clip1Max;
+ uint32_t srcFormat;
+ uint32_t srcSize;
+ uint32_t srcXY;
+ uint32_t colorBack;
+ uint32_t colorFore;
+ uint32_t dstSize;
+ uint32_t dstXY;
+ uint32_t command;
+ uint32_t RESERVED1;
+ uint32_t RESERVED2;
+ uint32_t RESERVED3;
+ uint8_t launchArea[128];
+};
+
+
+struct voodoo_io_reg_t {
+ uint32_t status;
+ uint32_t pciInit0;
+ uint32_t sipMonitor;
+ uint32_t lfbMemoryConfig;
+ uint32_t miscInit0;
+ uint32_t miscInit1;
+ uint32_t dramInit0;
+ uint32_t dramInit1;
+ uint32_t agpInit;
+ uint32_t tmuGbeInit;
+ uint32_t vgaInit0;
+ uint32_t vgaInit1;
+ uint32_t dramCommand;
+ uint32_t dramData;
+ uint32_t RESERVED1;
+ uint32_t RESERVED2;
+
+ uint32_t pllCtrl0;
+ uint32_t pllCtrl1;
+ uint32_t pllCtrl2;
+ uint32_t dacMode;
+ uint32_t dacAddr;
+ uint32_t dacData;
+
+ uint32_t rgbMaxDelta;
+ uint32_t vidProcCfg;
+ uint32_t hwCurPatAddr;
+ uint32_t hwCurLoc;
+ uint32_t hwCurC0;
+ uint32_t hwCurC1;
+ uint32_t vidInFormat;
+ uint32_t vidInStatus;
+ uint32_t vidSerialParallelPort;
+ uint32_t vidInXDecimDeltas;
+ uint32_t vidInDecimInitErrs;
+ uint32_t vidInYDecimDeltas;
+ uint32_t vidPixelBufThold;
+ uint32_t vidChromaMin;
+ uint32_t vidChromaMax;
+ uint32_t vidCurrentLine;
+ uint32_t vidScreenSize;
+ uint32_t vidOverlayStartCoords;
+ uint32_t vidOverlayEndScreenCoord;
+ uint32_t vidOverlayDudx;
+ uint32_t vidOverlayDudxOffsetSrcWidth;
+ uint32_t vidOverlayDvdy;
+
+ uint32_t vga_registers_not_mem_mapped[12];
+ uint32_t vidOverlayDvdyOffset;
+ uint32_t vidDesktopStartAddr;
+ uint32_t vidDesktopOverlayStride;
+ uint32_t vidInAddr0;
+ uint32_t vidInAddr1;
+ uint32_t vidInAddr2;
+ uint32_t vidInStride;
+ uint32_t vidCurrOverlayStartAddr;
+};
+
+
+struct pioData_t {
+ short port;
+ short size;
+ int device;
+ void *value;
+};
+
+typedef struct pioData_t pioData;
+typedef struct voodoo_2d_reg_t voodoo_2d_reg;
+typedef struct voodoo_io_reg_t voodoo_io_reg;
+typedef struct voodoo_yuv_reg_t voodoo_yuv_reg;
+typedef struct voodoo_yuv_fb_t voodoo_yuv_fb;
+
diff --git a/drivers/Makefile b/drivers/Makefile
new file mode 100644
index 0000000000..67deaf85cf
--- /dev/null
+++ b/drivers/Makefile
@@ -0,0 +1,22 @@
+
+CC = gcc
+KERNEL_INCLUDES = /usr/src/linux/include
+INCLUDES = -I$(KERNEL_INCLUDES)
+CFLAGS = -g -O2 -Wall -D__KERNEL__ -DMODULE -include $(KERNEL_INCLUDES)/linux/modversions.h
+
+all: mga_vid.o mga_vid_test sis_vid.o
+
+mga_vid.o: mga_vid.c mga_vid.h
+ $(CC) $(CFLAGS) $(INCLUDES) -c $(basename $@).c
+
+sis_vid.o: sis_vid.c sis_vid.h
+ $(CC) $(CFLAGS) $(INCLUDES) -c $(basename $@).c
+
+mga_vid_test: mga_vid_test.c
+ $(CC) -g -O -Wall $(INCLUDES) -o $@ $@.c
+
+clean:
+ rm -f *.o *~
+
+distclean: clean
+ rm -f mga_vid_test
diff --git a/drivers/README b/drivers/README
new file mode 100644
index 0000000000..bea354f489
--- /dev/null
+++ b/drivers/README
@@ -0,0 +1,40 @@
+
+mga_vid - MGA G200/G400 YUV Overlay kernel module
+
+ Author:
+ Aaron Holtzman <aholtzma@ess.engr.uvic.ca>, Oct 1999
+
+ Contributions by:
+ Fredrik Vraalsen <vraalsen@cs.uiuc.edu>
+ Alan Cox <alan@lxorguk.ukuu.org.uk>
+
+ WARNING ----- WARNING
+
+This code messes with your video card and your xserver. It will probably
+lock up your box, format your hard drive, and cause your brand new g400
+MAX to spout 6 inch flames. You have been warned.
+
+ WARNING ----- WARNING
+
+What does this code do?
+
+ mga_vid is a kernel module that utilitizes the Matrox g200/g400 video
+ scaler/overlay unit to perform YUV->RGB colorspace conversion and
+ arbitrary video scaling.
+
+ mga_vid is also a monster hack.
+
+How does mga_vid work?
+
+ This kernel module sets up the BES (backend scaler) with approriate values
+ based on parameters supplied via ioctl. It also maps a chunk of video
+ memory into userspace via mmap. This memory is stolen from X (which may
+ decide to write to it later). The application can then write image data
+ directly to the frame buffer (if it knows the right padding, etc).
+
+
+How do I know if mga_vid works on my system?
+
+ There are test applications called mga_vid_test_g400 and mga_vid_test_g200.
+ Use the appropriate one for your card. This test code should draw some
+ nice 256x256 images for you if all is working well.
diff --git a/drivers/mga_vid.c b/drivers/mga_vid.c
new file mode 100644
index 0000000000..1a5bf7162e
--- /dev/null
+++ b/drivers/mga_vid.c
@@ -0,0 +1,877 @@
+// YUY2 support (see config.format) added by A'rpi/ESP-team
+
+/*
+ *
+ * mga_vid.c
+ *
+ * Copyright (C) 1999 Aaron Holtzman
+ *
+ * Module skeleton based on gutted agpgart module by Jeff Hartmann
+ * <slicer@ionet.net>
+ *
+ * Matrox MGA G200/G400 YUV Video Interface module Version 0.1.0
+ *
+ * BES == Back End Scaler
+ *
+ * This software has been released under the terms of the GNU Public
+ * license. See http://www.gnu.org/copyleft/gpl.html for details.
+ */
+
+//It's entirely possible this major conflicts with something else
+/* mknod /dev/mga_vid c 178 0 */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/videodev.h>
+
+#include "mga_vid.h"
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#define MGA_VID_MAJOR 178
+
+#define MGA_VIDMEM_SIZE mga_ram_size
+
+#ifndef PCI_DEVICE_ID_MATROX_G200_PCI
+#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520
+#endif
+
+#ifndef PCI_DEVICE_ID_MATROX_G200_AGP
+#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521
+#endif
+
+#ifndef PCI_DEVICE_ID_MATROX_G400
+#define PCI_DEVICE_ID_MATROX_G400 0x0525
+#endif
+
+MODULE_AUTHOR("Aaron Holtzman <aholtzma@engr.uvic.ca>");
+
+
+typedef struct bes_registers_s
+{
+ //BES Control
+ uint32_t besctl;
+ //BES Global control
+ uint32_t besglobctl;
+ //Luma control (brightness and contrast)
+ uint32_t beslumactl;
+ //Line pitch
+ uint32_t bespitch;
+
+ //Buffer A-1 Chroma 3 plane org
+ uint32_t besa1c3org;
+ //Buffer A-1 Chroma org
+ uint32_t besa1corg;
+ //Buffer A-1 Luma org
+ uint32_t besa1org;
+
+ //Buffer A-2 Chroma 3 plane org
+ uint32_t besa2c3org;
+ //Buffer A-2 Chroma org
+ uint32_t besa2corg;
+ //Buffer A-2 Luma org
+ uint32_t besa2org;
+
+ //Buffer B-1 Chroma 3 plane org
+ uint32_t besb1c3org;
+ //Buffer B-1 Chroma org
+ uint32_t besb1corg;
+ //Buffer B-1 Luma org
+ uint32_t besb1org;
+
+ //Buffer B-2 Chroma 3 plane org
+ uint32_t besb2c3org;
+ //Buffer B-2 Chroma org
+ uint32_t besb2corg;
+ //Buffer B-2 Luma org
+ uint32_t besb2org;
+
+ //BES Horizontal coord
+ uint32_t beshcoord;
+ //BES Horizontal inverse scaling [5.14]
+ uint32_t beshiscal;
+ //BES Horizontal source start [10.14] (for scaling)
+ uint32_t beshsrcst;
+ //BES Horizontal source ending [10.14] (for scaling)
+ uint32_t beshsrcend;
+ //BES Horizontal source last
+ uint32_t beshsrclst;
+
+
+ //BES Vertical coord
+ uint32_t besvcoord;
+ //BES Vertical inverse scaling [5.14]
+ uint32_t besviscal;
+ //BES Field 1 vertical source last position
+ uint32_t besv1srclst;
+ //BES Field 1 weight start
+ uint32_t besv1wght;
+ //BES Field 2 vertical source last position
+ uint32_t besv2srclst;
+ //BES Field 2 weight start
+ uint32_t besv2wght;
+
+} bes_registers_t;
+
+static bes_registers_t regs;
+static uint32_t mga_vid_in_use = 0;
+static uint32_t is_g400 = 0;
+static uint32_t vid_src_ready = 0;
+static uint32_t vid_overlay_on = 0;
+
+static uint8_t *mga_mmio_base = 0;
+static uint32_t mga_mem_base = 0;
+static uint32_t mga_src_base = 0;
+
+static uint32_t mga_ram_size = 0;
+
+static struct pci_dev *pci_dev;
+
+static struct video_window mga_win;
+static mga_vid_config_t mga_config;
+
+
+//All register offsets are converted to word aligned offsets (32 bit)
+//because we want all our register accesses to be 32 bits
+#define VCOUNT 0x1e20
+
+#define PALWTADD 0x3c00 // Index register for X_DATAREG port
+#define X_DATAREG 0x3c0a
+
+#define XMULCTRL 0x19
+#define BPP_8 0x00
+#define BPP_15 0x01
+#define BPP_16 0x02
+#define BPP_24 0x03
+#define BPP_32_DIR 0x04
+#define BPP_32_PAL 0x07
+
+#define XCOLMSK 0x40
+#define X_COLKEY 0x42
+#define XKEYOPMODE 0x51
+#define XCOLMSK0RED 0x52
+#define XCOLMSK0GREEN 0x53
+#define XCOLMSK0BLUE 0x54
+#define XCOLKEY0RED 0x55
+#define XCOLKEY0GREEN 0x56
+#define XCOLKEY0BLUE 0x57
+
+// Backend Scaler registers
+#define BESCTL 0x3d20
+#define BESGLOBCTL 0x3dc0
+#define BESLUMACTL 0x3d40
+#define BESPITCH 0x3d24
+#define BESA1C3ORG 0x3d60
+#define BESA1CORG 0x3d10
+#define BESA1ORG 0x3d00
+#define BESA2C3ORG 0x3d64
+#define BESA2CORG 0x3d14
+#define BESA2ORG 0x3d04
+#define BESB1C3ORG 0x3d68
+#define BESB1CORG 0x3d18
+#define BESB1ORG 0x3d08
+#define BESB2C3ORG 0x3d6C
+#define BESB2CORG 0x3d1C
+#define BESB2ORG 0x3d0C
+#define BESHCOORD 0x3d28
+#define BESHISCAL 0x3d30
+#define BESHSRCEND 0x3d3C
+#define BESHSRCLST 0x3d50
+#define BESHSRCST 0x3d38
+#define BESV1WGHT 0x3d48
+#define BESV2WGHT 0x3d4c
+#define BESV1SRCLST 0x3d54
+#define BESV2SRCLST 0x3d58
+#define BESVISCAL 0x3d34
+#define BESVCOORD 0x3d2c
+#define BESSTATUS 0x3dc4
+
+
+static void mga_vid_frame_sel(int frame)
+{
+ //we don't need the vcount protection as we're only hitting
+ //one register (and it doesn't seem to be double buffered)
+ regs.besctl = (regs.besctl & ~0x07000000) + (frame << 25);
+ writel( regs.besctl, mga_mmio_base + BESCTL );
+}
+
+
+static void mga_vid_write_regs(void)
+{
+ //Make sure internal registers don't get updated until we're done
+ writel( (readl(mga_mmio_base + VCOUNT)-1)<<16,
+ mga_mmio_base + BESGLOBCTL);
+
+ // color or coordinate keying
+ writeb( XKEYOPMODE, mga_mmio_base + PALWTADD);
+ writeb( mga_config.colkey_on, mga_mmio_base + X_DATAREG);
+ if ( mga_config.colkey_on )
+ {
+ uint32_t r=0, g=0, b=0;
+
+ writeb( XMULCTRL, mga_mmio_base + PALWTADD);
+ switch (readb (mga_mmio_base + X_DATAREG))
+ {
+ case BPP_8:
+ /* Need to look up the color index, just using
+ color 0 for now. */
+ break;
+
+ case BPP_15:
+ r = mga_config.colkey_red >> 3;
+ g = mga_config.colkey_green >> 3;
+ b = mga_config.colkey_blue >> 3;
+ break;
+
+ case BPP_16:
+ r = mga_config.colkey_red >> 3;
+ g = mga_config.colkey_green >> 2;
+ b = mga_config.colkey_blue >> 3;
+ break;
+
+ case BPP_24:
+ case BPP_32_DIR:
+ case BPP_32_PAL:
+ r = mga_config.colkey_red;
+ g = mga_config.colkey_green;
+ b = mga_config.colkey_blue;
+ break;
+ }
+
+ // Disable color keying on alpha channel
+ writeb( XCOLMSK, mga_mmio_base + PALWTADD);
+ writeb( 0x00, mga_mmio_base + X_DATAREG);
+ writeb( X_COLKEY, mga_mmio_base + PALWTADD);
+ writeb( 0x00, mga_mmio_base + X_DATAREG);
+
+ // Set up color key registers
+ writeb( XCOLKEY0RED, mga_mmio_base + PALWTADD);
+ writeb( r, mga_mmio_base + X_DATAREG);
+ writeb( XCOLKEY0GREEN, mga_mmio_base + PALWTADD);
+ writeb( g, mga_mmio_base + X_DATAREG);
+ writeb( XCOLKEY0BLUE, mga_mmio_base + PALWTADD);
+ writeb( b, mga_mmio_base + X_DATAREG);
+
+ // Set up color key mask registers
+ writeb( XCOLMSK0RED, mga_mmio_base + PALWTADD);
+ writeb( 0xff, mga_mmio_base + X_DATAREG);
+ writeb( XCOLMSK0GREEN, mga_mmio_base + PALWTADD);
+ writeb( 0xff, mga_mmio_base + X_DATAREG);
+ writeb( XCOLMSK0BLUE, mga_mmio_base + PALWTADD);
+ writeb( 0xff, mga_mmio_base + X_DATAREG);
+ }
+
+ // Backend Scaler
+ writel( regs.besctl, mga_mmio_base + BESCTL);
+ if(is_g400)
+ writel( regs.beslumactl, mga_mmio_base + BESLUMACTL);
+ writel( regs.bespitch, mga_mmio_base + BESPITCH);
+
+ writel( regs.besa1org, mga_mmio_base + BESA1ORG);
+ writel( regs.besa1corg, mga_mmio_base + BESA1CORG);
+ writel( regs.besb1org, mga_mmio_base + BESB1ORG);
+ writel( regs.besb1corg, mga_mmio_base + BESB1CORG);
+ if(is_g400)
+ {
+ writel( regs.besa1c3org, mga_mmio_base + BESA1C3ORG);
+ writel( regs.besb1c3org, mga_mmio_base + BESB1C3ORG);
+ }
+
+ writel( regs.beshcoord, mga_mmio_base + BESHCOORD);
+ writel( regs.beshiscal, mga_mmio_base + BESHISCAL);
+ writel( regs.beshsrcst, mga_mmio_base + BESHSRCST);
+ writel( regs.beshsrcend, mga_mmio_base + BESHSRCEND);
+ writel( regs.beshsrclst, mga_mmio_base + BESHSRCLST);
+
+ writel( regs.besvcoord, mga_mmio_base + BESVCOORD);
+ writel( regs.besviscal, mga_mmio_base + BESVISCAL);
+ writel( regs.besv1srclst, mga_mmio_base + BESV1SRCLST);
+ writel( regs.besv1wght, mga_mmio_base + BESV1WGHT);
+
+ //update the registers somewhere between 1 and 2 frames from now.
+ writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16),
+ mga_mmio_base + BESGLOBCTL);
+
+ printk("mga_vid: wrote BES registers\n");
+ printk("mga_vid: BESCTL = 0x%08x\n",
+ readl(mga_mmio_base + BESCTL));
+ printk("mga_vid: BESGLOBCTL = 0x%08x\n",
+ readl(mga_mmio_base + BESGLOBCTL));
+ printk("mga_vid: BESSTATUS= 0x%08x\n",
+ readl(mga_mmio_base + BESSTATUS));
+}
+
+static int mga_vid_set_config(mga_vid_config_t *config)
+{
+ int x, y, sw, sh, dw, dh;
+ int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights;
+ int frame_size;
+ x = config->x_org;
+ y = config->y_org;
+ sw = config->src_width;
+ sh = config->src_height;
+ dw = config->dest_width;
+ dh = config->dest_height;
+
+ printk("mga_vid: Setting up a %dx%d+%d+%d video window (src %dx%d) format %X\n",
+ dw, dh, x, y, sw, sh, config->format);
+
+ //FIXME check that window is valid and inside desktop
+
+ //FIXME figure out a better way to allocate memory on card
+ //allocate 2 megs
+ //mga_src_base = mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000;
+ mga_src_base = (MGA_VIDMEM_SIZE-2) * 0x100000;
+
+
+ //Setup the BES registers for a three plane 4:2:0 video source
+
+switch(config->format){
+ case MGA_VID_FORMAT_YV12:
+ regs.besctl = 1 // BES enabled
+ + (0<<6) // even start polarity
+ + (1<<10) // x filtering enabled
+ + (1<<11) // y filtering enabled
+ + (1<<16) // chroma upsampling
+ + (1<<17) // 4:2:0 mode
+ + (1<<18); // dither enabled
+
+ if(is_g400)
+ {
+ //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp
+ //disabled, rgb mode disabled
+ regs.besglobctl = (1<<5);
+ }
+ else
+ {
+ //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr
+ //in 1357, BES register update on besvcnt
+ regs.besglobctl = 0;
+ }
+ break;
+
+ case MGA_VID_FORMAT_YUY2:
+ regs.besctl = 1 // BES enabled
+ + (0<<6) // even start polarity
+ + (1<<10) // x filtering enabled
+ + (1<<11) // y filtering enabled
+ + (1<<16) // chroma upsampling
+ + (0<<17) // 4:2:2 mode
+ + (1<<18); // dither enabled
+
+ regs.besglobctl = 0; // YUY2 format selected
+ break;
+ default:
+ return -1;
+}
+
+
+ //Disable contrast and brightness control
+ regs.besglobctl = (1<<5) + (1<<7);
+ regs.beslumactl = (0x7f << 16) + (0x80<<0);
+ regs.beslumactl = 0x80<<0;
+
+ //Setup destination window boundaries
+ besleft = x > 0 ? x : 0;
+ bestop = y > 0 ? y : 0;
+ regs.beshcoord = (besleft<<16) + (x + dw-1);
+ regs.besvcoord = (bestop<<16) + (y + dh-1);
+
+ //Setup source dimensions
+ regs.beshsrclst = (sw - 1) << 16;
+ regs.bespitch = (sw + 31) & ~31 ;
+
+ //Setup horizontal scaling
+ ifactor = ((sw-1)<<14)/(dw-1);
+ ofsleft = besleft - x;
+
+ regs.beshiscal = ifactor<<2;
+ regs.beshsrcst = (ofsleft*ifactor)<<2;
+ regs.beshsrcend = regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2);
+
+ //Setup vertical scaling
+ ifactor = ((sh-1)<<14)/(dh-1);
+ ofstop = bestop - y;
+
+ regs.besviscal = ifactor<<2;
+
+ baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch;
+ frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2;
+ regs.besa1org = (uint32_t) mga_src_base + baseadrofs;
+ regs.besb1org = (uint32_t) mga_src_base + baseadrofs + frame_size;
+
+ if (is_g400)
+ baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch;
+ else
+ baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch;
+
+ regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ;
+ regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + frame_size + regs.bespitch * sh;
+ regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4);
+ regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4);
+
+ weight = ofstop * (regs.besviscal >> 2);
+ weights = weight < 0 ? 1 : 0;
+ regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2);
+ regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF);
+
+ mga_vid_write_regs();
+ return 0;
+}
+
+
+static int mga_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int frame;
+
+ switch(cmd)
+ {
+ case MGA_VID_CONFIG:
+ //FIXME remove
+ printk("vcount = %d\n",readl(mga_mmio_base + VCOUNT));
+ printk("mga_mmio_base = %p\n",mga_mmio_base);
+ printk("mga_mem_base = %08lx\n",mga_mem_base);
+ //FIXME remove
+
+ printk("mga_vid: Received configuration\n");
+
+ if(copy_from_user(&mga_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t)))
+ {
+ printk("mga_vid: failed copy from userspace\n");
+ return(-EFAULT);
+ }
+ if (is_g400)
+ mga_config.card_type = MGA_G400;
+ else
+ mga_config.card_type = MGA_G200;
+
+ mga_config.ram_size = mga_ram_size;
+
+ if (copy_to_user((mga_vid_config_t *) arg, &mga_config, sizeof(mga_vid_config_t)))
+ {
+ printk("mga_vid: failed copy to userspace\n");
+ return(-EFAULT);
+ }
+ return mga_vid_set_config(&mga_config);
+ break;
+
+ case MGA_VID_ON:
+ printk("mga_vid: Video ON\n");
+ vid_src_ready = 1;
+ if(vid_overlay_on)
+ {
+ regs.besctl |= 1;
+ mga_vid_write_regs();
+ }
+ break;
+
+ case MGA_VID_OFF:
+ printk("mga_vid: Video OFF\n");
+ vid_src_ready = 0;
+ regs.besctl &= ~1;
+ mga_vid_write_regs();
+ break;
+
+ case MGA_VID_FSEL:
+ if(copy_from_user(&frame,(int *) arg,sizeof(int)))
+ {
+ printk("mga_vid: FSEL failed copy from userspace\n");
+ return(-EFAULT);
+ }
+
+ mga_vid_frame_sel(frame);
+ break;
+
+ default:
+ printk("mga_vid: Invalid ioctl\n");
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+
+static int mga_vid_find_card(void)
+{
+ struct pci_dev *dev = NULL;
+ unsigned int card_option, temp;
+
+ if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, NULL)))
+ {
+ is_g400 = 1;
+ printk("mga_vid: Found MGA G400\n");
+ }
+ else if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, NULL)))
+ {
+ is_g400 = 0;
+ printk("mga_vid: Found MGA G200 AGP\n");
+ }
+ else if((dev = pci_find_device(PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, NULL)))
+ {
+ is_g400 = 0;
+ printk("mga_vid: Found MGA G200 PCI\n");
+ }
+ else
+ {
+ printk("mga_vid: No supported cards found\n");
+ return FALSE;
+ }
+
+ pci_dev = dev;
+
+#if LINUX_VERSION_CODE >= 0x020300
+ mga_mmio_base = ioremap_nocache(dev->resource[1].start,0x4000);
+ mga_mem_base = dev->resource[0].start;
+#else
+ mga_mmio_base = ioremap_nocache(dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK,0x4000);
+ mga_mem_base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+#endif
+ printk("mga_vid: MMIO at 0x%p\n", mga_mmio_base);
+ printk("mga_vid: Frame Buffer at 0x%08lX\n", mga_mem_base);
+
+ pci_read_config_dword(dev, 0x40, &card_option);
+ printk("OPTION word: 0x%08x\n", card_option);
+
+ temp = (card_option >> 10) & 0x17;
+
+ if (is_g400)
+ {
+ switch(temp)
+ {
+ default:
+ mga_ram_size = 16;
+ }
+ }
+ else
+ {
+ // a g200
+ switch(temp)
+ {
+ default:
+ mga_ram_size = 8;
+ }
+ }
+
+ printk("mga_vid: RAMSIZE seems to be %d MB\n", (unsigned int) mga_ram_size);
+
+ return TRUE;
+}
+
+
+static ssize_t mga_vid_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static ssize_t mga_vid_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma)
+{
+
+ printk("mga_vid: mapping video memory into userspace\n");
+ if(remap_page_range(vma->vm_start, mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ {
+ printk("mga_vid: error mapping video memory\n");
+ return(-EAGAIN);
+ }
+
+ return(0);
+}
+
+static int mga_vid_release(struct inode *inode, struct file *file)
+{
+ //Close the window just in case
+ vid_src_ready = 0;
+ regs.besctl &= ~1;
+ mga_vid_write_regs();
+ mga_vid_in_use = 0;
+
+ //FIXME put back in!
+ //MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static long long mga_vid_lseek(struct file *file, long long offset, int origin)
+{
+ return -ESPIPE;
+}
+
+static int mga_vid_open(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+
+ if(minor != 0)
+ return(-ENXIO);
+
+ if(mga_vid_in_use == 1)
+ return(-EBUSY);
+
+ mga_vid_in_use = 1;
+ //FIXME turn me back on!
+ //MOD_INC_USE_COUNT;
+ return(0);
+}
+
+#if LINUX_VERSION_CODE >= 0x020400
+static struct file_operations mga_vid_fops =
+{
+ llseek: mga_vid_lseek,
+ read: mga_vid_read,
+ write: mga_vid_write,
+ ioctl: mga_vid_ioctl,
+ mmap: mga_vid_mmap,
+ open: mga_vid_open,
+ release: mga_vid_release
+};
+#else
+static struct file_operations mga_vid_fops =
+{
+ mga_vid_lseek,
+ mga_vid_read,
+ mga_vid_write,
+ NULL,
+ NULL,
+ mga_vid_ioctl,
+ mga_vid_mmap,
+ mga_vid_open,
+ NULL,
+ mga_vid_release
+};
+#endif
+
+static long mga_v4l_read(struct video_device *v, char *buf, unsigned long count,
+ int noblock)
+{
+ return -EINVAL;
+}
+
+static long mga_v4l_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
+{
+ return -EINVAL;
+}
+
+static int mga_v4l_open(struct video_device *dev, int mode)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static void mga_v4l_close(struct video_device *dev)
+{
+ regs.besctl &= ~1;
+ mga_vid_write_regs();
+ vid_overlay_on = 0;
+ MOD_DEC_USE_COUNT;
+ return;
+}
+
+static int mga_v4l_init_done(struct video_device *dev)
+{
+ return 0;
+}
+
+static int mga_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+ switch(cmd)
+ {
+ case VIDIOCGCAP:
+ {
+ struct video_capability b;
+ strcpy(b.name, "Matrox G200/400");
+ b.type = VID_TYPE_SCALES|VID_TYPE_OVERLAY|VID_TYPE_CHROMAKEY;
+ b.channels = 0;
+ b.audios = 0;
+ b.maxwidth = 1024; /* GUESS ?? */
+ b.maxheight = 768;
+ b.minwidth = 32;
+ b.minheight = 16; /* GUESS ?? */
+ if(copy_to_user(arg,&b,sizeof(b)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGPICT:
+ {
+ /*
+ * Default values.. if we can change this we
+ * can add the feature later
+ */
+ struct video_picture vp;
+ vp.brightness = 0x8000;
+ vp.hue = 0x8000;
+ vp.colour = 0x8000;
+ vp.whiteness = 0x8000;
+ vp.depth = 8;
+ /* Format is a guess */
+ vp.palette = VIDEO_PALETTE_YUV420P;
+ if(copy_to_user(arg, &vp, sizeof(vp)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSPICT:
+ {
+ return -EINVAL;
+ }
+ case VIDIOCSWIN:
+ {
+ struct video_window vw;
+ if(copy_from_user(&vw, arg, sizeof(vw)))
+ return -EFAULT;
+ if(vw.x <0 || vw.y <0 || vw.width < 32
+ || vw.height < 16)
+ return -EINVAL;
+ memcpy(&mga_win, &vw, sizeof(mga_win));
+
+ mga_config.x_org = vw.x;
+ mga_config.y_org = vw.y;
+ mga_config.dest_width = vw.width;
+ mga_config.dest_height = vw.height;
+
+ /*
+ * May have to add
+ *
+ * #define VIDEO_WINDOW_CHROMAKEY 16
+ *
+ * to <linux/videodev.h>
+ */
+
+ //add it here for now
+ #define VIDEO_WINDOW_CHROMAKEY 16
+
+ if (vw.flags & VIDEO_WINDOW_CHROMAKEY)
+ mga_config.colkey_on = 1;
+ else
+ mga_config.colkey_on = 0;
+
+ mga_config.colkey_red = (vw.chromakey >> 24) & 0xFF;
+ mga_config.colkey_green = (vw.chromakey >> 16) & 0xFF;
+ mga_config.colkey_blue = (vw.chromakey >> 8) & 0xFF;
+ mga_vid_set_config(&mga_config);
+ return 0;
+
+ }
+ case VIDIOCGWIN:
+ {
+ if(copy_to_user(arg, &mga_win, sizeof(mga_win)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCCAPTURE:
+ {
+ int v;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ vid_overlay_on = v;
+ if(vid_overlay_on && vid_src_ready)
+ {
+ regs.besctl |= 1;
+ mga_vid_write_regs();
+ }
+ else
+ {
+ regs.besctl &= ~1;
+ mga_vid_write_regs();
+ }
+ return 0;
+ }
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static struct video_device mga_v4l_dev =
+{
+ "Matrox G200/G400",
+ VID_TYPE_CAPTURE,
+ VID_HARDWARE_BT848, /* This is a lie for now */
+ mga_v4l_open,
+ mga_v4l_close,
+ mga_v4l_read,
+ mga_v4l_write,
+ NULL,
+ mga_v4l_ioctl,
+ NULL,
+ mga_v4l_init_done,
+ NULL,
+ 0,
+ 0
+};
+
+
+
+/*
+ * Main Initialization Function
+ */
+
+
+static int mga_vid_initialize(void)
+{
+ mga_vid_in_use = 0;
+
+ printk( "Matrox MGA G200/G400 YUV Video interface v0.01 (c) Aaron Holtzman \n");
+ if(register_chrdev(MGA_VID_MAJOR, "mga_vid", &mga_vid_fops))
+ {
+ printk("mga_vid: unable to get major: %d\n", MGA_VID_MAJOR);
+ return -EIO;
+ }
+
+ if (!mga_vid_find_card())
+ {
+ printk("mga_vid: no supported devices found\n");
+ unregister_chrdev(MGA_VID_MAJOR, "mga_vid");
+ return -EINVAL;
+ }
+
+#if 0
+ if (video_register_device(&mga_v4l_dev, VFL_TYPE_GRABBER)<0)
+ {
+ printk("mga_vid: unable to register.\n");
+ unregister_chrdev(MGA_VID_MAJOR, "mga_vid");
+ if(mga_mmio_base)
+ iounmap(mga_mmio_base);
+ mga_mmio_base = 0;
+ return -EINVAL;
+ }
+#endif
+
+ return(0);
+}
+
+int init_module(void)
+{
+ return mga_vid_initialize();
+}
+
+void cleanup_module(void)
+{
+// video_unregister_device(&mga_v4l_dev);
+ if(mga_mmio_base)
+ iounmap(mga_mmio_base);
+
+ //FIXME turn off BES
+ printk("mga_vid: Cleaning up module\n");
+ unregister_chrdev(MGA_VID_MAJOR, "mga_vid");
+}
+
diff --git a/drivers/mga_vid.h b/drivers/mga_vid.h
new file mode 100644
index 0000000000..5f1a0b540d
--- /dev/null
+++ b/drivers/mga_vid.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * mga_vid.h
+ *
+ * Copyright (C) 1999 Aaron Holtzman
+ *
+ * Matrox MGA G200/G400 YUV Video Interface module Version 0.1.0
+ *
+ * BES == Back End Scaler
+ *
+ * This software has been released under the terms of the GNU Public
+ * license. See http://www.gnu.org/copyleft/gpl.html for details.
+ */
+
+#ifndef __LINUX_MGAVID_H
+#define __LINUX_MGAVID_H
+
+#include <inttypes.h>
+
+typedef struct mga_vid_config_s
+{
+uint32_t card_type;
+uint32_t ram_size;
+uint32_t src_width;
+uint32_t src_height;
+uint32_t dest_width;
+uint32_t dest_height;
+uint32_t x_org;
+uint32_t y_org;
+uint8_t colkey_on;
+uint8_t colkey_red;
+uint8_t colkey_green;
+uint8_t colkey_blue;
+uint32_t format;
+} mga_vid_config_t;
+
+#define MGA_VID_FORMAT_YV12 0x32315659
+#define MGA_VID_FORMAT_YUY2 (('Y'<<24)|('U'<<16)|('Y'<<8)|'2')
+
+#define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t)
+#define MGA_VID_ON _IO ('J', 2)
+#define MGA_VID_OFF _IO ('J', 3)
+#define MGA_VID_FSEL _IOR('J', 4, int)
+
+#define MGA_G200 0x1234
+#define MGA_G400 0x5678
+
+#endif
diff --git a/drivers/mga_vid_test.c b/drivers/mga_vid_test.c
new file mode 100644
index 0000000000..c1057a9cf7
--- /dev/null
+++ b/drivers/mga_vid_test.c
@@ -0,0 +1,221 @@
+/*
+ *
+ * mga_vid_test.c
+ *
+ * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * Sept 1999
+ *
+ * This software has been released under the terms of the GNU Public
+ * license. See http://www.gnu.org/copyleft/gpl.html for details.
+ */
+
+//#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include "mga_vid.h"
+
+mga_vid_config_t config;
+uint8_t *mga_vid_base;
+uint32_t is_g400;
+
+#define SRC_IMAGE_WIDTH 256
+#define SRC_IMAGE_HEIGHT 256
+
+uint8_t y_image[SRC_IMAGE_WIDTH * SRC_IMAGE_HEIGHT];
+uint8_t cr_image[SRC_IMAGE_WIDTH * SRC_IMAGE_HEIGHT];
+uint8_t cb_image[SRC_IMAGE_WIDTH * SRC_IMAGE_HEIGHT];
+
+
+void
+write_frame_g200(uint8_t *y,uint8_t *cr, uint8_t *cb)
+{
+ uint8_t *dest;
+ uint32_t bespitch,h,w;
+
+ dest = mga_vid_base;
+ bespitch = (config.src_width + 31) & ~31;
+
+ for(h=0; h < config.src_height; h++)
+ {
+ memcpy(dest, y, config.src_width);
+ y += config.src_width;
+ dest += bespitch;
+ }
+
+ for(h=0; h < config.src_height/2; h++)
+ {
+ for(w=0; w < config.src_width/2; w++)
+ {
+ *dest++ = *cb++;
+ *dest++ = *cr++;
+ }
+ dest += bespitch - config.src_width;
+ }
+}
+
+void
+write_frame_g400(uint8_t *y,uint8_t *cr, uint8_t *cb)
+{
+ uint8_t *dest;
+ uint32_t bespitch,h;
+
+ dest = mga_vid_base;
+ bespitch = (config.src_width + 31) & ~31;
+
+ for(h=0; h < config.src_height; h++)
+ {
+ memcpy(dest, y, config.src_width);
+ y += config.src_width;
+ dest += bespitch;
+ }
+
+ for(h=0; h < config.src_height/2; h++)
+ {
+ memcpy(dest, cb, config.src_width/2);
+ cb += config.src_width/2;
+ dest += bespitch/2;
+ }
+
+ for(h=0; h < config.src_height/2; h++)
+ {
+ memcpy(dest, cr, config.src_width/2);
+ cr += config.src_width/2;
+ dest += bespitch/2;
+ }
+}
+
+void write_frame(uint8_t *y,uint8_t *cr, uint8_t *cb)
+{
+ if(is_g400)
+ write_frame_g400(y,cr,cb);
+ else
+ write_frame_g200(y,cr,cb);
+}
+
+void
+draw_cool_pattern(void)
+{
+ int i,x,y;
+
+ i = 0;
+ for (y=0; y<config.src_height; y++) {
+ for (x=0; x<config.src_width; x++) {
+ y_image[i++] = x*x/2 + y*y/2 - 128;
+ }
+ }
+
+ i = 0;
+ for (y=0; y<config.src_height/2; y++)
+ for (x=0; x<config.src_width/2; x++)
+ {
+ cr_image[i++] = x - 128;
+ }
+
+ i = 0;
+ for (y=0; y<config.src_height/2; y++)
+ for (x=0; x<config.src_width/2; x++)
+ {
+ cb_image[i++] = y - 128;
+ }
+}
+
+void
+draw_color_blend(void)
+{
+ int i,x,y;
+
+ i = 0;
+ for (y=0; y<config.src_height; y++) {
+ for (x=0; x<config.src_width; x++) {
+ y_image[i++] = 0;
+ }
+ }
+
+ i = 0;
+ for (y=0; y<config.src_height/2; y++)
+ for (x=0; x<config.src_width/2; x++)
+ {
+ cr_image[i++] = x - 128;
+ }
+
+ i = 0;
+ for (y=0; y<config.src_height/2; y++)
+ for (x=0; x<config.src_width/2; x++)
+ {
+ cb_image[i++] = y - 128;
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int f;
+
+ f = open("/dev/mga_vid",O_RDWR);
+
+ if(f == -1)
+ {
+ fprintf(stderr,"Couldn't open driver\n");
+ exit(1);
+ }
+
+ config.src_width = SRC_IMAGE_WIDTH;
+ config.src_height= SRC_IMAGE_HEIGHT;
+ config.dest_width = SRC_IMAGE_WIDTH;
+ config.dest_height = SRC_IMAGE_HEIGHT;
+ config.x_org= 10;
+ config.y_org= 10;
+ config.colkey_on = 0;
+ config.format = MGA_VID_FORMAT_YV12;
+
+ if (ioctl(f,MGA_VID_CONFIG,&config))
+ {
+ perror("Error in config ioctl");
+ }
+
+ if (config.card_type == MGA_G200)
+ {
+ printf("Testing MGA G200 Backend Scaler with %d MB of RAM\n", config.ram_size);
+ is_g400 = 0;
+ }
+ else
+ {
+ printf("Testing MGA G400 Backend Scaler with %d MB of RAM\n", config.ram_size);
+ is_g400 = 1;
+ }
+
+ ioctl(f,MGA_VID_ON,0);
+ mga_vid_base = (uint8_t*)mmap(0,256 * 4096,PROT_WRITE,MAP_SHARED,f,0);
+ printf("mga_vid_base = %8p\n",mga_vid_base);
+
+
+ //memset(y_image,80,256 * 128);
+ //memset(cr_image,80,256/2 * 20);
+ //memset(cb_image,80,256/2 * 20);
+ write_frame(y_image,cr_image,cb_image);
+ printf("(1) There should be a green square, offset by 10 pixels from\n"
+ " the upper left corner displayed\n");
+ sleep(3);
+
+
+ draw_cool_pattern();
+ write_frame(y_image,cr_image,cb_image);
+ printf("(2) There should be a cool mosaic like pattern now.\n");
+ sleep(3);
+
+ draw_color_blend();
+ write_frame(y_image,cr_image,cb_image);
+ printf("(3) There should be a color blend with black, red, purple, blue\n"
+ " corners (starting top left going CW)\n");
+ sleep(3);
+
+ ioctl(f,MGA_VID_OFF,0);
+
+ close(f);
+ return 0;
+}
diff --git a/drivers/sis_vid.c b/drivers/sis_vid.c
new file mode 100644
index 0000000000..5b9eace81a
--- /dev/null
+++ b/drivers/sis_vid.c
@@ -0,0 +1,645 @@
+/*
+ *
+ * sis_vid.c
+ *
+ * Copyright (C) 2000 Aaron Holtzman
+ *
+ * This software has been released under the terms of the GNU Public
+ * license. See http://www.gnu.org/copyleft/gpl.html for details.
+ */
+
+// video4linux interface disabled by A'rpi/ESP-team
+
+
+//It's entirely possible this major conflicts with something else
+/* mknod /dev/mga_vid c 178 0 */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+//#include <linux/videodev.h>
+
+#include "sis_vid.h"
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#define MGA_VID_MAJOR 178
+
+
+#ifndef PCI_DEVICE_ID_SI_6323
+#define PCI_DEVICE_ID_SI_6323 0x6326
+#endif
+
+
+MODULE_AUTHOR("Aaron Holtzman <aholtzma@engr.uvic.ca>");
+
+
+typedef struct bes_registers_s
+{
+ //base address of yuv framebuffer
+ uint32_t yuv_base;
+ uint32_t u_base;
+ uint32_t v_base;
+ uint32_t fb_end;;
+
+ //frame buffer pitch
+ uint32_t pitch;
+
+ //window boundaries
+ uint32_t left;
+ uint32_t right;
+ uint32_t top;
+ uint32_t bottom;
+
+ //control registers
+ uint32_t misc_0;
+ uint32_t misc_1;
+ uint32_t misc_3;
+ uint32_t misc_4;
+
+ //key overlay mode
+ uint32_t key_mode;
+
+} bes_registers_t;
+
+static bes_registers_t regs;
+static uint32_t mga_vid_in_use = 0;
+static uint32_t vid_src_ready = 0;
+static uint32_t vid_overlay_on = 0;
+
+static uint8_t *mga_mmio_base = 0;
+static uint32_t mga_mem_base = 0;
+static uint32_t mga_src_base = 0;
+
+static uint32_t mga_ram_size = 0;
+
+static struct pci_dev *pci_dev;
+
+//static struct video_window mga_win;
+static mga_vid_config_t mga_config;
+
+
+
+// Backend Scaler registers
+
+#define MISC_0 0x98
+#define MISC_1 0x99
+#define MISC_3 0x9d
+#define MISC_4 0xb6
+
+
+
+
+static void mga_vid_frame_sel(int frame)
+{
+ //we don't need the vcount protection as we're only hitting
+ //one register (and it doesn't seem to be double buffered)
+ //regs.besctl = (regs.besctl & ~0x07000000) + (frame << 25);
+ //writel( regs.besctl, mga_mmio_base + BESCTL );
+}
+
+
+#define WRITE_REG(x,y,z) {outb((y),(x));outb((z),(x+1));}
+#define READ_REG(x,y) (outb((y),(x)),inb(x+1))
+#define VIDEO_ACCEL 0x3d4
+
+static void mga_vid_write_regs(void)
+{
+ uint32_t foo;
+
+ //unlock the video accel registers
+ WRITE_REG(VIDEO_ACCEL,0x80,0x86);
+ foo = READ_REG(VIDEO_ACCEL,0x80);
+
+ if(foo != 0xa1)
+ return; //something bad happened
+
+ //setup the horizontal window bounds
+ WRITE_REG(VIDEO_ACCEL,0x81,regs.left & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x82,regs.right & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x83,(regs.left >> 8) | ((regs.right>>4) & 0x70));
+
+ //setup the vertical window bounds
+ WRITE_REG(VIDEO_ACCEL,0x84,regs.top & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x85,regs.bottom & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x86,(regs.top >> 8) | ((regs.bottom>>4) & 0x70));
+
+ //setup the framebuffer base addresses
+ WRITE_REG(VIDEO_ACCEL,0x8a,regs.yuv_base & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x8b,(regs.yuv_base >> 8) & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x89,(regs.yuv_base >> 12) & 0xf0);
+
+ WRITE_REG(VIDEO_ACCEL,0xb7,regs.u_base & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0xb8,(regs.u_base >> 8) & 0xff);
+
+ WRITE_REG(VIDEO_ACCEL,0xba,regs.v_base & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0xbb,(regs.v_base >> 8) & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0xb9,((regs.v_base >> 12) & 0xf0) + ((regs.u_base >> 16) & 0xf));
+
+ WRITE_REG(VIDEO_ACCEL,0x8d,regs.fb_end);
+
+ //setup framebuffer pitch
+ WRITE_REG(VIDEO_ACCEL,0x8c,regs.pitch & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0x8e,(regs.pitch >> 8) & 0x0f);
+ WRITE_REG(VIDEO_ACCEL,0xbc,(regs.pitch) & 0xff);
+ WRITE_REG(VIDEO_ACCEL,0xbd,((regs.pitch) >> 8) & 0x0f);
+
+
+ //write key overlay register
+ WRITE_REG(VIDEO_ACCEL,0xa9,regs.key_mode);
+
+ WRITE_REG(VIDEO_ACCEL,0x93,0x40);
+ WRITE_REG(VIDEO_ACCEL,0x94,1);
+ WRITE_REG(VIDEO_ACCEL,0x9e,0);
+ WRITE_REG(VIDEO_ACCEL,0x9f,0);
+
+ //write config registers
+ WRITE_REG(VIDEO_ACCEL,MISC_0,regs.misc_0);
+ WRITE_REG(VIDEO_ACCEL,MISC_1,regs.misc_1);
+ WRITE_REG(VIDEO_ACCEL,MISC_3,regs.misc_3);
+ WRITE_REG(VIDEO_ACCEL,MISC_4,regs.misc_4);
+
+ //setup the video line buffer
+ WRITE_REG(VIDEO_ACCEL,0xa0,(regs.right - regs.left)/ 8);
+
+}
+
+static int mga_vid_set_config(mga_vid_config_t *config)
+{
+ uint32_t x, y, frame_size;
+
+ x = config->x_org;
+ y = config->y_org;
+
+ regs.left = x;
+ regs.right= config->src_width + x;
+ regs.top = y;
+ regs.bottom = config->src_height + y;
+
+ printk("mga_vid: Setting up a %dx%d+%d+%d video window (src %dx%d)\n",
+ config->dest_width, config->dest_height, config->x_org, config->y_org,
+ config->src_width, config->src_height);
+
+
+ regs.pitch = ((config->src_width + 31) & ~31) / 4 ;
+
+ //frame size in pixels
+ frame_size = regs.pitch * config->src_height * 4;
+
+ regs.yuv_base = (mga_src_base) >> 2;
+ regs.u_base = (mga_src_base + frame_size) >> 2;
+ regs.v_base = (mga_src_base + frame_size/4) >> 2;
+ regs.fb_end = (mga_src_base + (3*frame_size)/2) >> 14;
+
+ //disable video capture, enable video display, enable graphics display,
+ //select yuv format, odd parity
+ regs.misc_0 = (1 << 1) + (1<<6) + (1<<4);
+
+ //disable dithering, no filtering, no interrupts
+ regs.misc_1 = 0;
+
+ //select 2's complement format YUV for playback
+ regs.misc_3 = (1<<1);
+
+ //select 4:2:0 video format, + yuv4:2:2 cpu writes
+ regs.misc_4 = (1<<2);
+
+ //disable keying
+ regs.key_mode = 0xf;
+
+ mga_vid_write_regs();
+ return 0;
+}
+
+
+static int mga_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int frame;
+
+ switch(cmd)
+ {
+ case MGA_VID_CONFIG:
+ //FIXME remove
+ printk("mga_mmio_base = %p\n",mga_mmio_base);
+ printk("mga_mem_base = %08x\n",mga_mem_base);
+ //FIXME remove
+
+ printk("mga_vid: Received configuration\n");
+
+ if(copy_from_user(&mga_config,(mga_vid_config_t*) arg,sizeof(mga_vid_config_t)))
+ {
+ printk("mga_vid: failed copy from userspace\n");
+ return(-EFAULT);
+ }
+
+ mga_config.ram_size = mga_ram_size;
+ //XXX make it look like a g400
+ mga_config.card_type = MGA_G400;;
+
+ if (copy_to_user((mga_vid_config_t *) arg, &mga_config, sizeof(mga_vid_config_t)))
+ {
+ printk("mga_vid: failed copy to userspace\n");
+ return(-EFAULT);
+ }
+ return mga_vid_set_config(&mga_config);
+ break;
+
+ case MGA_VID_ON:
+ printk("mga_vid: Video ON\n");
+ vid_src_ready = 1;
+ if(vid_overlay_on)
+ {
+ //regs.besctl |= 1;
+ mga_vid_write_regs();
+ }
+ break;
+
+ case MGA_VID_OFF:
+ printk("mga_vid: Video OFF\n");
+ vid_src_ready = 0;
+ //regs.besctl &= ~1;
+ mga_vid_write_regs();
+ break;
+
+ case MGA_VID_FSEL:
+ if(copy_from_user(&frame,(int *) arg,sizeof(int)))
+ {
+ printk("mga_vid: FSEL failed copy from userspace\n");
+ return(-EFAULT);
+ }
+
+ mga_vid_frame_sel(frame);
+ break;
+
+ default:
+ printk("mga_vid: Invalid ioctl\n");
+ return (-EINVAL);
+ }
+
+ return 0;
+}
+
+
+static int mga_vid_find_card(void)
+{
+ struct pci_dev *dev = NULL;
+
+ if((dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_6323, NULL)))
+ {
+ printk("sis_vid: Found SiS 6326\n");
+ }
+ else
+ {
+ printk("sis_vid: No supported cards found\n");
+ return FALSE;
+ }
+
+ pci_dev = dev;
+
+#if LINUX_VERSION_CODE >= 0x020300
+ mga_mmio_base = ioremap_nocache(dev->resource[1].start,0x10000);
+ mga_mem_base = dev->resource[0].start;
+#else
+ mga_mmio_base = ioremap_nocache(dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK,0x10000);
+ mga_mem_base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+#endif
+ printk("mga_vid: MMIO at 0x%p\n", mga_mmio_base);
+ printk("mga_vid: Frame Buffer at 0x%08x\n", mga_mem_base);
+
+ //FIXME set ram size properly
+ mga_ram_size = 4;
+ mga_src_base = (mga_ram_size - 1) * 0x100000;
+
+ //FIXME remove
+ if(1)
+ {
+ mga_vid_config_t config ={0,0,256,256,256,256,10,10,0,0,0,0};
+
+ mga_vid_set_config(&config);
+ mga_vid_write_regs();
+ //regs.misc_0 ^= 2;
+ //mga_vid_write_regs();
+ }
+ //FIXME remove
+
+ return TRUE;
+}
+
+
+static ssize_t mga_vid_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static ssize_t mga_vid_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma)
+{
+
+ printk("mga_vid: mapping video memory into userspace\n");
+ if(remap_page_range(vma->vm_start, mga_mem_base + mga_src_base,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ {
+ printk("mga_vid: error mapping video memory\n");
+ return(-EAGAIN);
+ }
+
+ return(0);
+}
+
+static int mga_vid_release(struct inode *inode, struct file *file)
+{
+ //Close the window just in case
+ vid_src_ready = 0;
+ regs.misc_0 &= 0xed;
+ mga_vid_write_regs();
+ mga_vid_in_use = 0;
+
+ //FIXME put back in!
+ //MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static long long mga_vid_lseek(struct file *file, long long offset, int origin)
+{
+ return -ESPIPE;
+}
+
+static int mga_vid_open(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+
+ if(minor != 0)
+ return(-ENXIO);
+
+ if(mga_vid_in_use == 1)
+ return(-EBUSY);
+
+ mga_vid_in_use = 1;
+ //FIXME turn me back on!
+ //MOD_INC_USE_COUNT;
+ return(0);
+}
+
+#if LINUX_VERSION_CODE >= 0x020400
+static struct file_operations mga_vid_fops =
+{
+ llseek: mga_vid_lseek,
+ read: mga_vid_read,
+ write: mga_vid_write,
+ ioctl: mga_vid_ioctl,
+ mmap: mga_vid_mmap,
+ open: mga_vid_open,
+ release: mga_vid_release
+};
+#else
+static struct file_operations mga_vid_fops =
+{
+ mga_vid_lseek,
+ mga_vid_read,
+ mga_vid_write,
+ NULL,
+ NULL,
+ mga_vid_ioctl,
+ mga_vid_mmap,
+ mga_vid_open,
+ NULL,
+ mga_vid_release
+};
+#endif
+
+#if 0
+static long mga_v4l_read(struct video_device *v, char *buf, unsigned long count,
+ int noblock)
+{
+ return -EINVAL;
+}
+
+static long mga_v4l_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
+{
+ return -EINVAL;
+}
+
+static int mga_v4l_open(struct video_device *dev, int mode)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static void mga_v4l_close(struct video_device *dev)
+{
+ //regs.besctl &= ~1;
+ mga_vid_write_regs();
+ vid_overlay_on = 0;
+ MOD_DEC_USE_COUNT;
+ return;
+}
+
+static int mga_v4l_init_done(struct video_device *dev)
+{
+ return 0;
+}
+
+static int mga_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+ switch(cmd)
+ {
+ case VIDIOCGCAP:
+ {
+ struct video_capability b;
+ strcpy(b.name, "Matrox G200/400");
+ b.type = VID_TYPE_SCALES|VID_TYPE_OVERLAY|VID_TYPE_CHROMAKEY;
+ b.channels = 0;
+ b.audios = 0;
+ b.maxwidth = 1024; /* GUESS ?? */
+ b.maxheight = 768;
+ b.minwidth = 32;
+ b.minheight = 16; /* GUESS ?? */
+ if(copy_to_user(arg,&b,sizeof(b)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGPICT:
+ {
+ /*
+ * Default values.. if we can change this we
+ * can add the feature later
+ */
+ struct video_picture vp;
+ vp.brightness = 0x8000;
+ vp.hue = 0x8000;
+ vp.colour = 0x8000;
+ vp.whiteness = 0x8000;
+ vp.depth = 8;
+ /* Format is a guess */
+ vp.palette = VIDEO_PALETTE_YUV420P;
+ if(copy_to_user(arg, &vp, sizeof(vp)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSPICT:
+ {
+ return -EINVAL;
+ }
+ case VIDIOCSWIN:
+ {
+ struct video_window vw;
+ if(copy_from_user(&vw, arg, sizeof(vw)))
+ return -EFAULT;
+ if(vw.x <0 || vw.y <0 || vw.width < 32
+ || vw.height < 16)
+ return -EINVAL;
+ memcpy(&mga_win, &vw, sizeof(mga_win));
+
+ mga_config.x_org = vw.x;
+ mga_config.y_org = vw.y;
+ mga_config.dest_width = vw.width;
+ mga_config.dest_height = vw.height;
+
+ /*
+ * May have to add
+ *
+ * #define VIDEO_WINDOW_CHROMAKEY 16
+ *
+ * to <linux/videodev.h>
+ */
+
+ //add it here for now
+ #define VIDEO_WINDOW_CHROMAKEY 16
+
+ if (vw.flags & VIDEO_WINDOW_CHROMAKEY)
+ mga_config.colkey_on = 1;
+ else
+ mga_config.colkey_on = 0;
+
+ mga_config.colkey_red = (vw.chromakey >> 24) & 0xFF;
+ mga_config.colkey_green = (vw.chromakey >> 16) & 0xFF;
+ mga_config.colkey_blue = (vw.chromakey >> 8) & 0xFF;
+ mga_vid_set_config(&mga_config);
+ return 0;
+
+ }
+ case VIDIOCGWIN:
+ {
+ if(copy_to_user(arg, &mga_win, sizeof(mga_win)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCCAPTURE:
+ {
+ int v;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ vid_overlay_on = v;
+ if(vid_overlay_on && vid_src_ready)
+ {
+ //regs.besctl |= 1;
+ mga_vid_write_regs();
+ }
+ else
+ {
+ //regs.besctl &= ~1;
+ mga_vid_write_regs();
+ }
+ return 0;
+ }
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static struct video_device mga_v4l_dev =
+{
+ "Matrox G200/G400",
+ VID_TYPE_CAPTURE,
+ VID_HARDWARE_BT848, /* This is a lie for now */
+ mga_v4l_open,
+ mga_v4l_close,
+ mga_v4l_read,
+ mga_v4l_write,
+ NULL,
+ mga_v4l_ioctl,
+ NULL,
+ mga_v4l_init_done,
+ NULL,
+ 0,
+ 0
+};
+
+#endif
+
+/*
+ * Main Initialization Function
+ */
+
+
+static int mga_vid_initialize(void)
+{
+ mga_vid_in_use = 0;
+
+ printk( "SiS 6326 YUV Video interface v0.01 (c) Aaron Holtzman \n");
+ if(register_chrdev(MGA_VID_MAJOR, "mga_vid", &mga_vid_fops))
+ {
+ printk("sis_vid: unable to get major: %d\n", MGA_VID_MAJOR);
+ return -EIO;
+ }
+
+ if (!mga_vid_find_card())
+ {
+ printk("sis_vid: no supported devices found\n");
+ unregister_chrdev(MGA_VID_MAJOR, "mga_vid");
+ return -EINVAL;
+ }
+
+#if 0
+ if (video_register_device(&mga_v4l_dev, VFL_TYPE_GRABBER)<0)
+ {
+ printk("sis_vid: unable to register.\n");
+ unregister_chrdev(MGA_VID_MAJOR, "mga_vid");
+ if(mga_mmio_base)
+ iounmap(mga_mmio_base);
+ mga_mmio_base = 0;
+ return -EINVAL;
+ }
+#endif
+
+ return(0);
+}
+
+int init_module(void)
+{
+ return mga_vid_initialize();
+}
+
+void cleanup_module(void)
+{
+// video_unregister_device(&mga_v4l_dev);
+ if(mga_mmio_base)
+ iounmap(mga_mmio_base);
+
+ //FIXME turn off BES
+ printk("mga_vid: Cleaning up module\n");
+ unregister_chrdev(MGA_VID_MAJOR, "mga_vid");
+}
+
diff --git a/drivers/sis_vid.h b/drivers/sis_vid.h
new file mode 100644
index 0000000000..a4c42cf901
--- /dev/null
+++ b/drivers/sis_vid.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * sis_vid.h
+ *
+ * Copyright (C) 2000 Aaron Holtzman
+ *
+ * YUV Framebuffer driver for SiS 6326 cards
+ *
+ * This software has been released under the terms of the GNU Public
+ * license. See http://www.gnu.org/copyleft/gpl.html for details.
+ */
+
+#include <inttypes.h>
+
+typedef struct mga_vid_config_s
+{
+uint32_t card_type;
+uint32_t ram_size;
+uint32_t src_width;
+uint32_t src_height;
+uint32_t dest_width;
+uint32_t dest_height;
+uint32_t x_org;
+uint32_t y_org;
+uint8_t colkey_on;
+uint8_t colkey_red;
+uint8_t colkey_green;
+uint8_t colkey_blue;
+} mga_vid_config_t;
+
+#define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t)
+#define MGA_VID_ON _IO ('J', 2)
+#define MGA_VID_OFF _IO ('J', 3)
+#define MGA_VID_FSEL _IOR('J', 4, int)
+
+#define MGA_G200 0x1234
+#define MGA_G400 0x5678
diff --git a/help_avp.h b/help_avp.h
new file mode 100644
index 0000000000..23175f6d2f
--- /dev/null
+++ b/help_avp.h
@@ -0,0 +1,32 @@
+static char* banner_text=
+"\n"
+"MPlayer v0.10 [AVI parser] (C) 2000. Arpad Gereoffy <arpi@esp-team.scene.hu>\n"
+"\n";
+
+static char* help_text=
+"Usage: aviparse [options] [path/]name\n"
+"\n"
+" Options:\n"
+//" -o <driver> select output driver (see '-o help' for driver list)\n"
+//" -vcd <track> play video cd track from device instead of plain file\n"
+//" -bg play in background (X11 only!)\n"
+//" -sb <bytepos> seek to byte position\n"
+//" -ss <timepos> seek to second position (with timestamp)\n"
+//" -nosound don't play sound\n"
+//" -abs <bytes> audio buffer size (in bytes, default: measuring)\n"
+//" -delay <secs> audio delay in seconds (may be +/- float value)\n"
+//" -alsa enable timing code (works better with ALSA)\n"
+" -aid <1-99> select audio channel\n"
+" -afile <name> dump raw audio data to file\n"
+" -vfile <name> dump raw video data to file\n"
+//" -vid <0-15> select video channel\n"
+//" -fps <value> force frame rate (if value is wrong in mpeg header)\n"
+//" -mc <s/5f> maximum sync correction per 5 frames (in seconds)\n"
+//" -afm <1-3> force audio format 1:MPEG 2:PCM 3:AC3 4:Win32\n"
+//"\n"
+//" Keys:\n"
+//" <- or -> seek backward/forward 10 seconds\n"
+//" up or down seek backward/forward 1 minute\n"
+//" p or SPACE pause movie (press any key to continue)\n"
+//" q or ^C stop playing and quit program\n"
+"\n";
diff --git a/help_mp.h b/help_mp.h
new file mode 100644
index 0000000000..a8de5045fc
--- /dev/null
+++ b/help_mp.h
@@ -0,0 +1,44 @@
+static char* banner_text=
+"\n"
+"MPlayer " VERSION " (C) 2000-2001 Arpad Gereoffy <arpi@esp-team.scene.hu>\n"
+"\n";
+
+static char* help_text=
+"Usage: mplayer [options] [path/]name\n"
+"\n"
+" Options:\n"
+" -vo <driver> select output driver (see '-vo help' for driver list)\n"
+" -vcd <track> play video cd track from device instead of plain file\n"
+//" -bg play in background (X11 only!)\n"
+" -sb <bytepos> seek to byte position\n"
+//" -ss <timepos> seek to second position (with timestamp)\n"
+" -nosound don't play sound\n"
+" -abs <bytes> audio buffer size (in bytes, default: measuring)\n"
+" -delay <secs> audio delay in seconds (may be +/- float value)\n"
+#ifdef AVI_SYNC_BPS
+" -nobps do not use avg. byte/sec value for A-V sync (AVI)\n"
+#else
+" -bps use avg. byte/sec value for A-V sync (AVI)\n"
+#endif
+#ifdef ALSA_TIMER
+" -noalsa disable timing code\n"
+#else
+" -alsa enable timing code (works better with ALSA)\n"
+#endif
+" -aid <id> select audio channel [MPG: 0-31 AVI: 1-99]\n"
+" -vid <id> select video channel [MPG: 0-15 AVI: -- ]\n"
+" -fps <value> force frame rate (if value is wrong in the header)\n"
+" -mc <s/5f> maximum sync correction per 5 frames (in seconds)\n"
+" -afm <1-5> force audio format 1:MPEG 2:PCM 3:AC3 4:Win32 5:aLaw\n"
+#ifdef X11_FULLSCREEN
+" -fs fullscreen playing (only gl, xmga and xv drivers)\n"
+#endif
+" -x <x> -y <y> scale image to <x> * <y> resolution [if scalable!]\n"
+"\n"
+" Keys:\n"
+" <- or -> seek backward/forward 10 seconds\n"
+" up or down seek backward/forward 1 minute\n"
+" p or SPACE pause movie (press any key to continue)\n"
+" q or ESC stop playing and quit program\n"
+" + or - adjust audio delay by +/- 0.1 second\n"
+"\n";
diff --git a/liba52/srfftp.h b/liba52/srfftp.h
new file mode 100644
index 0000000000..ffb228eaaa
--- /dev/null
+++ b/liba52/srfftp.h
@@ -0,0 +1,303 @@
+
+/*
+ * srfftp.h
+ *
+ * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
+ *
+ * 64 and 128 point split radix fft for ac3dec
+ *
+ * The algorithm is desribed in the book:
+ * "Computational Frameworks of the Fast Fourier Transform".
+ *
+ * The ideas and the the organization of code borrowed from djbfft written by
+ * D. J. Bernstein <djb@cr.py.to>. djbff can be found at
+ * http://cr.yp.to/djbfft.html.
+ *
+ * srfftp.h is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * srfftp.h is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef SRFFTP_H__
+#define SRFFTP_H__
+
+static complex_t delta16[4] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.92387953251129, -0.38268343236509},
+ {0.70710678118655, -0.70710678118655},
+ {0.38268343236509, -0.92387953251129}};
+
+static complex_t delta16_3[4] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.38268343236509, -0.92387953251129},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.92387953251129, 0.38268343236509}};
+
+static complex_t delta32[8] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.98078528040323, -0.19509032201613},
+ {0.92387953251129, -0.38268343236509},
+ {0.83146961230255, -0.55557023301960},
+ {0.70710678118655, -0.70710678118655},
+ {0.55557023301960, -0.83146961230255},
+ {0.38268343236509, -0.92387953251129},
+ {0.19509032201613, -0.98078528040323}};
+
+static complex_t delta32_3[8] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.83146961230255, -0.55557023301960},
+ {0.38268343236509, -0.92387953251129},
+ {-0.19509032201613, -0.98078528040323},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.98078528040323, -0.19509032201613},
+ {-0.92387953251129, 0.38268343236509},
+ {-0.55557023301960, 0.83146961230255}};
+
+static complex_t delta64[16] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.99518472667220, -0.09801714032956},
+ {0.98078528040323, -0.19509032201613},
+ {0.95694033573221, -0.29028467725446},
+ {0.92387953251129, -0.38268343236509},
+ {0.88192126434836, -0.47139673682600},
+ {0.83146961230255, -0.55557023301960},
+ {0.77301045336274, -0.63439328416365},
+ {0.70710678118655, -0.70710678118655},
+ {0.63439328416365, -0.77301045336274},
+ {0.55557023301960, -0.83146961230255},
+ {0.47139673682600, -0.88192126434835},
+ {0.38268343236509, -0.92387953251129},
+ {0.29028467725446, -0.95694033573221},
+ {0.19509032201613, -0.98078528040323},
+ {0.09801714032956, -0.99518472667220}};
+
+static complex_t delta64_3[16] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.95694033573221, -0.29028467725446},
+ {0.83146961230255, -0.55557023301960},
+ {0.63439328416365, -0.77301045336274},
+ {0.38268343236509, -0.92387953251129},
+ {0.09801714032956, -0.99518472667220},
+ {-0.19509032201613, -0.98078528040323},
+ {-0.47139673682600, -0.88192126434836},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.88192126434835, -0.47139673682600},
+ {-0.98078528040323, -0.19509032201613},
+ {-0.99518472667220, 0.09801714032956},
+ {-0.92387953251129, 0.38268343236509},
+ {-0.77301045336274, 0.63439328416365},
+ {-0.55557023301960, 0.83146961230255},
+ {-0.29028467725446, 0.95694033573221}};
+
+static complex_t delta128[32] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.99879545620517, -0.04906767432742},
+ {0.99518472667220, -0.09801714032956},
+ {0.98917650996478, -0.14673047445536},
+ {0.98078528040323, -0.19509032201613},
+ {0.97003125319454, -0.24298017990326},
+ {0.95694033573221, -0.29028467725446},
+ {0.94154406518302, -0.33688985339222},
+ {0.92387953251129, -0.38268343236509},
+ {0.90398929312344, -0.42755509343028},
+ {0.88192126434836, -0.47139673682600},
+ {0.85772861000027, -0.51410274419322},
+ {0.83146961230255, -0.55557023301960},
+ {0.80320753148064, -0.59569930449243},
+ {0.77301045336274, -0.63439328416365},
+ {0.74095112535496, -0.67155895484702},
+ {0.70710678118655, -0.70710678118655},
+ {0.67155895484702, -0.74095112535496},
+ {0.63439328416365, -0.77301045336274},
+ {0.59569930449243, -0.80320753148064},
+ {0.55557023301960, -0.83146961230255},
+ {0.51410274419322, -0.85772861000027},
+ {0.47139673682600, -0.88192126434835},
+ {0.42755509343028, -0.90398929312344},
+ {0.38268343236509, -0.92387953251129},
+ {0.33688985339222, -0.94154406518302},
+ {0.29028467725446, -0.95694033573221},
+ {0.24298017990326, -0.97003125319454},
+ {0.19509032201613, -0.98078528040323},
+ {0.14673047445536, -0.98917650996478},
+ {0.09801714032956, -0.99518472667220},
+ {0.04906767432742, -0.99879545620517}};
+
+static complex_t delta128_3[32] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.98917650996478, -0.14673047445536},
+ {0.95694033573221, -0.29028467725446},
+ {0.90398929312344, -0.42755509343028},
+ {0.83146961230255, -0.55557023301960},
+ {0.74095112535496, -0.67155895484702},
+ {0.63439328416365, -0.77301045336274},
+ {0.51410274419322, -0.85772861000027},
+ {0.38268343236509, -0.92387953251129},
+ {0.24298017990326, -0.97003125319454},
+ {0.09801714032956, -0.99518472667220},
+ {-0.04906767432742, -0.99879545620517},
+ {-0.19509032201613, -0.98078528040323},
+ {-0.33688985339222, -0.94154406518302},
+ {-0.47139673682600, -0.88192126434836},
+ {-0.59569930449243, -0.80320753148065},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.80320753148065, -0.59569930449243},
+ {-0.88192126434835, -0.47139673682600},
+ {-0.94154406518302, -0.33688985339222},
+ {-0.98078528040323, -0.19509032201613},
+ {-0.99879545620517, -0.04906767432742},
+ {-0.99518472667220, 0.09801714032956},
+ {-0.97003125319454, 0.24298017990326},
+ {-0.92387953251129, 0.38268343236509},
+ {-0.85772861000027, 0.51410274419322},
+ {-0.77301045336274, 0.63439328416365},
+ {-0.67155895484702, 0.74095112535496},
+ {-0.55557023301960, 0.83146961230255},
+ {-0.42755509343028, 0.90398929312344},
+ {-0.29028467725446, 0.95694033573221},
+ {-0.14673047445536, 0.98917650996478}};
+
+#define HSQRT2 0.707106781188;
+
+#define TRANSZERO(A0,A4,A8,A12) { \
+ u_r = wTB[0].re; \
+ v_i = u_r - wTB[k*2].re; \
+ u_r += wTB[k*2].re; \
+ u_i = wTB[0].im; \
+ v_r = wTB[k*2].im - u_i; \
+ u_i += wTB[k*2].im; \
+ a_r = A0.re; \
+ a_i = A0.im; \
+ a1_r = a_r; \
+ a1_r += u_r; \
+ A0.re = a1_r; \
+ a_r -= u_r; \
+ A8.re = a_r; \
+ a1_i = a_i; \
+ a1_i += u_i; \
+ A0.im = a1_i; \
+ a_i -= u_i; \
+ A8.im = a_i; \
+ a1_r = A4.re; \
+ a1_i = A4.im; \
+ a_r = a1_r; \
+ a_r -= v_r; \
+ A4.re = a_r; \
+ a1_r += v_r; \
+ A12.re = a1_r; \
+ a_i = a1_i; \
+ a_i -= v_i; \
+ A4.im = a_i; \
+ a1_i += v_i; \
+ A12.im = a1_i; \
+ }
+
+#define TRANSHALF_16(A2,A6,A10,A14) {\
+ u_r = wTB[2].re; \
+ a_r = u_r; \
+ u_i = wTB[2].im; \
+ u_r += u_i; \
+ u_i -= a_r; \
+ a_r = wTB[6].re; \
+ a1_r = a_r; \
+ a_i = wTB[6].im; \
+ a_r = a_i - a_r; \
+ a_i += a1_r; \
+ v_i = u_r - a_r; \
+ u_r += a_r; \
+ v_r = u_i + a_i; \
+ u_i -= a_i; \
+ v_i *= HSQRT2; \
+ v_r *= HSQRT2; \
+ u_r *= HSQRT2; \
+ u_i *= HSQRT2; \
+ a_r = A2.re; \
+ a_i = A2.im; \
+ a1_r = a_r; \
+ a1_r += u_r; \
+ A2.re = a1_r; \
+ a_r -= u_r; \
+ A10.re = a_r; \
+ a1_i = a_i; \
+ a1_i += u_i; \
+ A2.im = a1_i; \
+ a_i -= u_i; \
+ A10.im = a_i; \
+ a1_r = A6.re; \
+ a1_i = A6.im; \
+ a_r = a1_r; \
+ a1_r += v_r; \
+ A6.re = a1_r; \
+ a_r -= v_r; \
+ A14.re = a_r; \
+ a_i = a1_i; \
+ a1_i -= v_i; \
+ A6.im = a1_i; \
+ a_i += v_i; \
+ A14.im = a_i; \
+ }
+
+#define TRANS(A1,A5,A9,A13,WT,WB,D,D3) { \
+ u_r = WT.re; \
+ a_r = u_r; \
+ a_r *= D.im; \
+ u_r *= D.re; \
+ a_i = WT.im; \
+ a1_i = a_i; \
+ a1_i *= D.re; \
+ a_i *= D.im; \
+ u_r -= a_i; \
+ u_i = a_r; \
+ u_i += a1_i; \
+ a_r = WB.re; \
+ a1_r = a_r; \
+ a1_r *= D3.re; \
+ a_r *= D3.im; \
+ a_i = WB.im; \
+ a1_i = a_i; \
+ a_i *= D3.re; \
+ a1_i *= D3.im; \
+ a1_r -= a1_i; \
+ a_r += a_i; \
+ v_i = u_r - a1_r; \
+ u_r += a1_r; \
+ v_r = a_r - u_i; \
+ u_i += a_r; \
+ a_r = A1.re; \
+ a_i = A1.im; \
+ a1_r = a_r; \
+ a1_r += u_r; \
+ A1.re = a1_r; \
+ a_r -= u_r; \
+ A9.re = a_r; \
+ a1_i = a_i; \
+ a1_i += u_i; \
+ A1.im = a1_i; \
+ a_i -= u_i; \
+ A9.im = a_i; \
+ a1_r = A5.re; \
+ a1_i = A5.im; \
+ a_r = a1_r; \
+ a1_r -= v_r; \
+ A5.re = a1_r; \
+ a_r += v_r; \
+ A13.re = a_r; \
+ a_i = a1_i; \
+ a1_i -= v_i; \
+ A5.im = a1_i; \
+ a_i += v_i; \
+ A13.im = a_i; \
+ }
+
+#endif
diff --git a/libmpeg2/Makefile b/libmpeg2/Makefile
new file mode 100644
index 0000000000..5e2f8e8cfc
--- /dev/null
+++ b/libmpeg2/Makefile
@@ -0,0 +1,35 @@
+
+LIBNAME = libmpeg2.a
+
+include ../config.mak
+
+SRCS = decode.c header.c idct.c idct_mmx.c motion_comp.c motion_comp_mmx.c slice.c stats.c
+OBJS = decode.o header.o idct.o idct_mmx.o motion_comp.o motion_comp_mmx.o slice.o stats.o
+CFLAGS = $(OPTFLAGS) -DMPG12PLAY
+INCLUDE = -I. -I../libvo -I..
+
+.SUFFIXES: .c .o
+
+# .PHONY: all clean
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<
+
+$(LIBNAME): $(OBJS)
+ $(AR) r $(LIBNAME) $(OBJS)
+
+all: $(LIBNAME)
+
+clean:
+ rm -f *.o *.a *~
+
+distclean:
+ makedepend
+ rm -f Makefile.bak *.o *.a *~
+
+dep: depend
+
+depend:
+ makedepend -- $(CFLAGS) -- $(SRCS) &> /dev/null
+
+# DO NOT DELETE
diff --git a/libmpeg2/attributes.h b/libmpeg2/attributes.h
new file mode 100644
index 0000000000..dfbf129411
--- /dev/null
+++ b/libmpeg2/attributes.h
@@ -0,0 +1,31 @@
+/*
+ * attributes.h
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+//use gcc attribs to align critical data structures
+
+/* maximum supported data alignment */
+#define ATTRIBUTE_ALIGNED_MAX 64
+
+#ifdef ATTRIBUTE_ALIGNED_MAX
+#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
+#else
+#define ATTR_ALIGN(align)
+#endif
diff --git a/libmpeg2/decode.c b/libmpeg2/decode.c
new file mode 100644
index 0000000000..e8bbb02112
--- /dev/null
+++ b/libmpeg2/decode.c
@@ -0,0 +1,319 @@
+/* Copyright (C) Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - Nov 1999 */
+/* Some cleanup & hacking by A'rpi/ESP-team - Oct 2000 */
+
+/* mpeg2dec version: */
+#define PACKAGE "mpeg2dec"
+//#define VERSION "0.1.7-cvs"
+#define VERSION "0.1.8-cvs"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "config.h"
+
+//#include "video_out.h"
+
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+
+#include "../linux/shmem.h"
+
+//#include "motion_comp.h"
+//#include "idct.h"
+//#include "header.h"
+//#include "slice.h"
+//#include "stats.h"
+
+#include "attributes.h"
+#ifdef __i386__
+#include "mmx.h"
+#endif
+
+//this is where we keep the state of the decoder
+//picture_t picture_data;
+//picture_t *picture=&picture_data;
+picture_t *picture=NULL;
+
+//global config struct
+mpeg2_config_t config;
+
+// the maximum chunk size is determined by vbv_buffer_size which is 224K for
+// MP@ML streams. (we make no pretenses ofdecoding anything more than that)
+//static uint8_t chunk_buffer[224 * 1024 + 4];
+//static uint32_t shift = 0;
+
+static int drop_flag = 0;
+static int drop_frame = 0;
+
+int quant_store[MBR+1][MBC+1]; // [Review]
+
+void mpeg2_init (void)
+{
+
+ printf (PACKAGE"-"VERSION" (C) 2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>\n");
+ config.flags = 0;
+#ifdef HAVE_MMX
+ config.flags |= MM_ACCEL_X86_MMX;
+#endif
+#ifdef HAVE_SSE
+ config.flags |= MM_ACCEL_X86_MMXEXT;
+#endif
+#ifdef HAVE_3DNOW
+ config.flags |= MM_ACCEL_X86_3DNOW;
+#endif
+#ifdef HAVE_MLIB
+ config.flags |= MM_ACCEL_MLIB;
+#endif
+
+ printf("libmpeg2 config flags = 0x%X\n",config.flags);
+
+ picture=shmem_alloc(sizeof(picture_t)); // !!! NEW HACK :) !!!
+
+ header_state_init (picture);
+ picture->repeat_count=0;
+
+ picture->pp_options=0;
+
+ idct_init ();
+ motion_comp_init ();
+}
+
+void mpeg2_allocate_image_buffers (picture_t * picture)
+{
+ int frame_size,buff_size;
+ unsigned char *base=NULL;
+
+ // height+1 requires for yuv2rgb_mmx code (it reads next line after last)
+ frame_size = picture->coded_picture_width * (1+picture->coded_picture_height);
+ frame_size = (frame_size+31)&(~31); // align to 32 byte boundary
+ buff_size = frame_size + (frame_size/4)*2; // 4Y + 1U + 1V
+
+ // allocate images in YV12 format
+ base = shmem_alloc(buff_size);
+ picture->throwaway_frame[0] = base;
+ picture->throwaway_frame[1] = base + frame_size * 5 / 4;
+ picture->throwaway_frame[2] = base + frame_size;
+
+ base = shmem_alloc(buff_size);
+ picture->backward_reference_frame[0] = base;
+ picture->backward_reference_frame[1] = base + frame_size * 5 / 4;
+ picture->backward_reference_frame[2] = base + frame_size;
+
+ base = shmem_alloc(buff_size);
+ picture->forward_reference_frame[0] = base;
+ picture->forward_reference_frame[1] = base + frame_size * 5 / 4;
+ picture->forward_reference_frame[2] = base + frame_size;
+
+ base = shmem_alloc(buff_size);
+ picture->pp_frame[0] = base;
+ picture->pp_frame[1] = base + frame_size * 5 / 4;
+ picture->pp_frame[2] = base + frame_size;
+
+}
+
+static void decode_reorder_frames (void)
+{
+ if (picture->picture_coding_type != B_TYPE) {
+
+ //reuse the soon to be outdated forward reference frame
+ picture->current_frame[0] = picture->forward_reference_frame[0];
+ picture->current_frame[1] = picture->forward_reference_frame[1];
+ picture->current_frame[2] = picture->forward_reference_frame[2];
+
+ //make the backward reference frame the new forward reference frame
+ picture->forward_reference_frame[0] =
+ picture->backward_reference_frame[0];
+ picture->forward_reference_frame[1] =
+ picture->backward_reference_frame[1];
+ picture->forward_reference_frame[2] =
+ picture->backward_reference_frame[2];
+
+ picture->backward_reference_frame[0] = picture->current_frame[0];
+ picture->backward_reference_frame[1] = picture->current_frame[1];
+ picture->backward_reference_frame[2] = picture->current_frame[2];
+
+ } else {
+
+ picture->current_frame[0] = picture->throwaway_frame[0];
+ picture->current_frame[1] = picture->throwaway_frame[1];
+ picture->current_frame[2] = picture->throwaway_frame[2];
+
+ }
+}
+
+static int in_slice_flag=0;
+
+static int parse_chunk (vo_functions_t * output, int code, uint8_t * buffer)
+{
+ int is_frame_done = 0;
+
+ stats_header (code, buffer);
+
+ is_frame_done = in_slice_flag && ((!code) || (code >= 0xb0));
+ if (is_frame_done) {
+ in_slice_flag = 0;
+
+ if(picture->picture_structure != FRAME_PICTURE) printf("Field! %d \n",picture->second_field);
+
+ if ( ((HACK_MODE == 2) || (picture->mpeg1))
+ && ((picture->picture_structure == FRAME_PICTURE) ||
+ (picture->second_field))
+ ) {
+ uint8_t ** bar;
+ int stride[3];
+
+ if (picture->picture_coding_type == B_TYPE)
+ bar = picture->throwaway_frame;
+ else
+ bar = picture->forward_reference_frame;
+
+ stride[0]=picture->coded_picture_width;
+ stride[1]=stride[2]=stride[0]/2;
+
+ if(picture->pp_options){
+ // apply OpenDivX postprocess filter
+ postprocess(bar, stride[0],
+ picture->pp_frame, stride[0],
+ picture->coded_picture_width, picture->coded_picture_height,
+ &quant_store[1][1], (MBC+1), picture->pp_options);
+ output->draw_slice (picture->pp_frame, stride,
+ picture->display_picture_width,
+ picture->display_picture_height, 0, 0);
+ } else {
+ output->draw_slice (bar, stride,
+ picture->display_picture_width,
+ picture->display_picture_height, 0, 0);
+ }
+
+ }
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMX) emms ();
+#endif
+ output->flip_page ();
+ }
+
+ switch (code) {
+ case 0x00: /* picture_start_code */
+ if (header_process_picture_header (picture, buffer)) {
+ printf ("bad picture header\n");
+ exit (1);
+ }
+
+ drop_frame = drop_flag && (picture->picture_coding_type == B_TYPE);
+ //decode_reorder_frames ();
+ break;
+
+ case 0xb3: /* sequence_header_code */
+ if (header_process_sequence_header (picture, buffer)) {
+ printf ("bad sequence header\n");
+ exit (1);
+ }
+ break;
+
+ case 0xb5: /* extension_start_code */
+ if (header_process_extension (picture, buffer)) {
+ printf ("bad extension\n");
+ exit (1);
+ }
+ break;
+
+ default:
+// if (code >= 0xb9) printf ("stream not demultiplexed ?\n");
+ if (code >= 0xb0) break;
+
+ if (!(in_slice_flag)) {
+ in_slice_flag = 1;
+
+ if(!(picture->second_field)) decode_reorder_frames ();
+ }
+
+ if (!drop_frame) {
+ uint8_t ** bar;
+
+ slice_process (picture, code, buffer);
+
+ if ((HACK_MODE < 2) && (!(picture->mpeg1))) {
+ uint8_t * foo[3];
+ uint8_t ** bar;
+ //frame_t * bar;
+ int stride[3];
+ int offset;
+
+ if (picture->picture_coding_type == B_TYPE)
+ bar = picture->throwaway_frame;
+ else
+ bar = picture->forward_reference_frame;
+
+ offset = (code-1) * 4 * picture->coded_picture_width;
+ if ((! HACK_MODE) && (picture->picture_coding_type == B_TYPE))
+ offset = 0;
+
+ foo[0] = bar[0] + 4 * offset;
+ foo[1] = bar[1] + offset;
+ foo[2] = bar[2] + offset;
+
+ stride[0]=picture->coded_picture_width;
+ stride[1]=stride[2]=stride[0]/2;
+
+ output->draw_slice (foo, stride,
+ picture->display_picture_width, 16, 0, (code-1)*16);
+ }
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMX) emms ();
+#endif
+
+ }
+ }
+
+ return is_frame_done;
+}
+
+
+int mpeg2_decode_data (vo_functions_t *output, uint8_t *current, uint8_t *end)
+{
+ //static uint8_t code = 0xff;
+ //static uint8_t chunk_buffer[65536];
+ //static uint8_t *chunk_ptr = chunk_buffer;
+ //static uint32_t shift = 0;
+ uint8_t code;
+ uint8_t *pos=NULL;
+ uint8_t *start=current;
+ int ret = 0;
+
+// printf("RCVD %d bytes\n",end-current);
+
+while(current<end){
+ // FIND NEXT HEAD:
+ unsigned int head=-1;
+ uint8_t c;
+ //--------------------
+ while(current<end){
+ c=current[0];
+ ++current;
+ head<<=8;
+ if(head==0x100) break; // synced
+ head|=c;
+ }
+ //--------------------
+ if(pos){
+ //if((code&0x100)!=0x100) printf("libmpeg2: FATAL! code=%X\n",code);
+ //printf("pos=%d chunk %3X size=%d next-code=%X\n",pos-start,code,current-pos,head|c);
+ ret+=parse_chunk(output, code&0xFF, pos);
+ }
+ //--------------------
+ pos=current;code=head|c;
+}
+
+ if(code==0x1FF) ret+=parse_chunk(output, 0xFF, NULL); // send 'end of frame'
+
+ return ret;
+}
+
+void mpeg2_drop (int flag)
+{
+ drop_flag = flag;
+}
+
diff --git a/libmpeg2/header.c b/libmpeg2/header.c
new file mode 100644
index 0000000000..8f5b34359e
--- /dev/null
+++ b/libmpeg2/header.c
@@ -0,0 +1,273 @@
+/*
+ * slice.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+
+// default intra quant matrix, in zig-zag order
+static uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = {
+ 8,
+ 16, 16,
+ 19, 16, 19,
+ 22, 22, 22, 22,
+ 22, 22, 26, 24, 26,
+ 27, 27, 27, 26, 26, 26,
+ 26, 27, 27, 27, 29, 29, 29,
+ 34, 34, 34, 29, 29, 29, 27, 27,
+ 29, 29, 32, 32, 34, 34, 37,
+ 38, 37, 35, 35, 34, 35,
+ 38, 38, 40, 40, 40,
+ 48, 48, 46, 46,
+ 56, 56, 58,
+ 69, 69,
+ 83
+};
+
+uint8_t scan_norm[64] ATTR_ALIGN(16) =
+{
+ // Zig-Zag scan pattern
+ 0, 1, 8,16, 9, 2, 3,10,
+ 17,24,32,25,18,11, 4, 5,
+ 12,19,26,33,40,48,41,34,
+ 27,20,13, 6, 7,14,21,28,
+ 35,42,49,56,57,50,43,36,
+ 29,22,15,23,30,37,44,51,
+ 58,59,52,45,38,31,39,46,
+ 53,60,61,54,47,55,62,63
+};
+
+uint8_t scan_alt[64] ATTR_ALIGN(16) =
+{
+ // Alternate scan pattern
+ 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
+ 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
+ 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
+ 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
+};
+
+void header_state_init (picture_t * picture)
+{
+ //FIXME we should set pointers to the real scan matrices here (mmx vs
+ //normal) instead of the ifdefs in header_process_picture_coding_extension
+
+ picture->scan = scan_norm;
+}
+
+static const int frameratecode2framerate[16] = {
+ 0, 24000*10000/1001, 24*10000,25*10000, 30000*10000/1001, 30*10000,50*10000,60000*10000/1001,
+ 60*10000, 0,0,0,0,0,0,0
+};
+
+int header_process_sequence_header (picture_t * picture, uint8_t * buffer)
+{
+ unsigned int h_size;
+ unsigned int v_size;
+ int i;
+
+ if ((buffer[6] & 0x20) != 0x20)
+ return 1; // missing marker_bit
+
+ v_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+
+ picture->display_picture_width = (v_size >> 12);
+ picture->display_picture_height = (v_size & 0xfff);
+
+ h_size = ((v_size >> 12) + 15) & ~15;
+ v_size = ((v_size & 0xfff) + 15) & ~15;
+
+ if ((h_size > 768) || (v_size > 576))
+ return 1; // size restrictions for MP@ML or MPEG1
+
+ //XXX this needs field fixups
+ picture->coded_picture_width = h_size;
+ picture->coded_picture_height = v_size;
+ picture->last_mba = ((h_size * v_size) >> 8) - 1;
+
+ // this is not used by the decoder
+ picture->aspect_ratio_information = buffer[3] >> 4;
+ picture->frame_rate_code = buffer[3] & 15;
+ picture->frame_rate = frameratecode2framerate[picture->frame_rate_code];
+
+ picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6);
+
+ if (buffer[7] & 2) {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i+7] << 7) | (buffer[i+8] >> 1);
+ buffer += 64;
+ } else {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ default_intra_quantizer_matrix [i];
+ }
+
+ if (buffer[7] & 1) {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[scan_norm[i]] =
+ buffer[i+8];
+ } else {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[i] = 16;
+ }
+
+ // MPEG1 - for testing only
+ picture->mpeg1 = 1;
+ picture->intra_dc_precision = 0;
+ picture->frame_pred_frame_dct = 1;
+ picture->q_scale_type = 0;
+ picture->concealment_motion_vectors = 0;
+ //picture->alternate_scan = 0;
+ picture->picture_structure = FRAME_PICTURE;
+ //picture->second_field = 0;
+
+ return 0;
+}
+
+static int header_process_sequence_extension (picture_t * picture,
+ uint8_t * buffer)
+{
+ // MPEG1 - for testing only
+ picture->mpeg1 = 0;
+
+ // check chroma format, size extensions, marker bit
+ if(((buffer[1]>>1)&3)!=1){
+ printf("This CHROMA format not yet supported :(\n");
+ return 1;
+ }
+ if ((buffer[1] & 1) || (buffer[2] & 0xe0)){
+ printf("Big resolution video not yet supported :(\n");
+ return 1;
+ }
+ if((buffer[3] & 0x01) != 0x01) return 1; // marker bit
+
+
+ // this is not used by the decoder
+ picture->progressive_sequence = (buffer[1] >> 3) & 1;
+
+ if (picture->progressive_sequence)
+ picture->coded_picture_height =
+ (picture->coded_picture_height + 31) & ~31;
+ picture->bitrate>>=1; // hack
+
+ return 0;
+}
+
+static int header_process_quant_matrix_extension (picture_t * picture,
+ uint8_t * buffer)
+{
+ int i;
+
+ if (buffer[0] & 8) {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i] << 5) | (buffer[i+1] >> 3);
+ buffer += 64;
+ }
+
+ if (buffer[0] & 4) {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i] << 6) | (buffer[i+1] >> 2);
+ }
+
+ return 0;
+}
+
+static int header_process_picture_coding_extension (picture_t * picture, uint8_t * buffer)
+{
+ //pre subtract 1 for use later in compute_motion_vector
+ picture->f_code[0][0] = (buffer[0] & 15) - 1;
+ picture->f_code[0][1] = (buffer[1] >> 4) - 1;
+ picture->f_code[1][0] = (buffer[1] & 15) - 1;
+ picture->f_code[1][1] = (buffer[2] >> 4) - 1;
+
+ picture->intra_dc_precision = (buffer[2] >> 2) & 3;
+ picture->picture_structure = buffer[2] & 3;
+ picture->frame_pred_frame_dct = (buffer[3] >> 6) & 1;
+ picture->concealment_motion_vectors = (buffer[3] >> 5) & 1;
+ picture->q_scale_type = (buffer[3] >> 4) & 1;
+ picture->intra_vlc_format = (buffer[3] >> 3) & 1;
+
+ if (buffer[3] & 4) // alternate_scan
+ picture->scan = scan_alt;
+ else
+ picture->scan = scan_norm;
+
+ // these are not used by the decoder
+ picture->top_field_first = buffer[3] >> 7;
+ picture->repeat_first_field = (buffer[3] >> 1) & 1;
+ picture->progressive_frame = buffer[4] >> 7;
+
+ // repeat_first implementation by A'rpi/ESP-team, based on libmpeg3:
+ if(picture->repeat_count>=100) picture->repeat_count=0;
+ if(picture->repeat_first_field){
+ if(picture->progressive_sequence){
+ if(picture->top_field_first)
+ picture->repeat_count+=200;
+ else
+ picture->repeat_count+=100;
+ } else
+ if(picture->progressive_frame){
+ picture->repeat_count+=50;
+ }
+ }
+
+ return 0;
+}
+
+int header_process_extension (picture_t * picture, uint8_t * buffer)
+{
+ switch (buffer[0] & 0xf0) {
+ case 0x10: // sequence extension
+ return header_process_sequence_extension (picture, buffer);
+
+ case 0x30: // quant matrix extension
+ return header_process_quant_matrix_extension (picture, buffer);
+
+ case 0x80: // picture coding extension
+ return header_process_picture_coding_extension (picture, buffer);
+ }
+
+ return 0;
+}
+
+int header_process_picture_header (picture_t *picture, uint8_t * buffer)
+{
+ picture->picture_coding_type = (buffer [1] >> 3) & 7;
+
+ // forward_f_code and backward_f_code - used in mpeg1 only
+ picture->f_code[0][1] = (buffer[3] >> 2) & 1;
+ picture->f_code[0][0] =
+ (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1;
+ picture->f_code[1][1] = (buffer[4] >> 6) & 1;
+ picture->f_code[1][0] = ((buffer[4] >> 3) & 7) - 1;
+
+ // move in header_process_picture_header
+ picture->second_field =
+ (picture->picture_structure != FRAME_PICTURE) &&
+ !(picture->second_field);
+
+ return 0;
+}
diff --git a/libmpeg2/idct.c b/libmpeg2/idct.c
new file mode 100644
index 0000000000..7411e176dd
--- /dev/null
+++ b/libmpeg2/idct.c
@@ -0,0 +1,289 @@
+/*
+ * idct.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * Portions of this code are from the MPEG software simulation group
+ * idct implementation. This code will be replaced with a new
+ * implementation soon.
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**********************************************************/
+/* inverse two dimensional DCT, Chen-Wang algorithm */
+/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */
+/* 32-bit integer arithmetic (8 bit coefficients) */
+/* 11 mults, 29 adds per DCT */
+/* sE, 18.8.91 */
+/**********************************************************/
+/* coefficients extended to 12 bit for IEEE1180-1990 */
+/* compliance sE, 2.1.94 */
+/**********************************************************/
+
+/* this code assumes >> to be a two's-complement arithmetic */
+/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "mm_accel.h"
+
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
+
+
+// idct main entry point
+void (*idct_block_copy) (int16_t * block, uint8_t * dest, int stride);
+void (*idct_block_add) (int16_t * block, uint8_t * dest, int stride);
+
+static void idct_block_copy_c (int16_t *block, uint8_t * dest, int stride);
+static void idct_block_add_c (int16_t *block, uint8_t * dest, int stride);
+
+static uint8_t clip_lut[1024];
+#define CLIP(i) ((clip_lut+384)[ (i)])
+
+void idct_init (void)
+{
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMXEXT) {
+ fprintf (stderr, "Using MMXEXT for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mmxext;
+ idct_block_add = idct_block_add_mmxext;
+ idct_mmx_init ();
+ } else if (config.flags & MM_ACCEL_X86_MMX) {
+ fprintf (stderr, "Using MMX for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mmx;
+ idct_block_add = idct_block_add_mmx;
+ idct_mmx_init ();
+ } else
+#endif
+#ifdef LIBMPEG2_MLIB
+ if (config.flags & MM_ACCEL_MLIB) {
+ fprintf (stderr, "Using mlib for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mlib;
+ idct_block_add = idct_block_add_mlib;
+ } else
+#endif
+ {
+ int i;
+
+ fprintf (stderr, "No accelerated IDCT transform found\n");
+ idct_block_copy = idct_block_copy_c;
+ idct_block_add = idct_block_add_c;
+ for (i = -384; i < 640; i++)
+ clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
+ }
+}
+
+/* row (horizontal) IDCT
+ *
+ * 7 pi 1
+ * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 128
+ * c[1..7] = 128*sqrt (2)
+ */
+
+static void inline idct_row (int16_t * block)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ x1 = block[4] << 11;
+ x2 = block[6];
+ x3 = block[2];
+ x4 = block[1];
+ x5 = block[7];
+ x6 = block[5];
+ x7 = block[3];
+
+ /* shortcut */
+ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) {
+ block[0] = block[1] = block[2] = block[3] = block[4] =
+ block[5] = block[6] = block[7] = block[0]<<3;
+ return;
+ }
+
+ x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x8 = W7 * (x4 + x5);
+ x4 = x8 + (W1 - W7) * x4;
+ x5 = x8 - (W1 + W7) * x5;
+ x8 = W3 * (x6 + x7);
+ x6 = x8 - (W3 - W5) * x6;
+ x7 = x8 - (W3 + W5) * x7;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2);
+ x2 = x1 - (W2 + W6) * x2;
+ x3 = x1 + (W2 - W6) * x3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ block[0] = (x7 + x1) >> 8;
+ block[1] = (x3 + x2) >> 8;
+ block[2] = (x0 + x4) >> 8;
+ block[3] = (x8 + x6) >> 8;
+ block[4] = (x8 - x6) >> 8;
+ block[5] = (x0 - x4) >> 8;
+ block[6] = (x3 - x2) >> 8;
+ block[7] = (x7 - x1) >> 8;
+}
+
+/* column (vertical) IDCT
+ *
+ * 7 pi 1
+ * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 1/1024
+ * c[1..7] = (1/1024)*sqrt (2)
+ */
+
+static void inline idct_col (int16_t *block)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ x1 = block [8*4] << 8;
+ x2 = block [8*6];
+ x3 = block [8*2];
+ x4 = block [8*1];
+ x5 = block [8*7];
+ x6 = block [8*5];
+ x7 = block [8*3];
+
+#if 0
+ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) {
+ block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] =
+ block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6;
+ return;
+ }
+#endif
+
+ x0 = (block[8*0] << 8) + 8192;
+
+ /* first stage */
+ x8 = W7 * (x4 + x5) + 4;
+ x4 = (x8 + (W1 - W7) * x4) >> 3;
+ x5 = (x8 - (W1 + W7) * x5) >> 3;
+ x8 = W3 * (x6 + x7) + 4;
+ x6 = (x8 - (W3 - W5) * x6) >> 3;
+ x7 = (x8 - (W3 + W5) * x7) >> 3;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2) + 4;
+ x2 = (x1 - (W2 + W6) * x2) >> 3;
+ x3 = (x1 + (W2 - W6) * x3) >> 3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ block[8*0] = (x7 + x1) >> 14;
+ block[8*1] = (x3 + x2) >> 14;
+ block[8*2] = (x0 + x4) >> 14;
+ block[8*3] = (x8 + x6) >> 14;
+ block[8*4] = (x8 - x6) >> 14;
+ block[8*5] = (x0 - x4) >> 14;
+ block[8*6] = (x3 - x2) >> 14;
+ block[8*7] = (x7 - x1) >> 14;
+}
+
+void idct_block_copy_c (int16_t * block, uint8_t * dest, int stride)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ idct_row (block + 8 * i);
+
+ for (i = 0; i < 8; i++)
+ idct_col (block + i);
+
+ i = 8;
+ do {
+ dest[0] = CLIP (block[0]);
+ dest[1] = CLIP (block[1]);
+ dest[2] = CLIP (block[2]);
+ dest[3] = CLIP (block[3]);
+ dest[4] = CLIP (block[4]);
+ dest[5] = CLIP (block[5]);
+ dest[6] = CLIP (block[6]);
+ dest[7] = CLIP (block[7]);
+
+ dest += stride;
+ block += 8;
+ } while (--i);
+}
+
+void idct_block_add_c (int16_t * block, uint8_t * dest, int stride)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ idct_row (block + 8 * i);
+
+ for (i = 0; i < 8; i++)
+ idct_col (block + i);
+
+ i = 8;
+ do {
+ dest[0] = CLIP (block[0] + dest[0]);
+ dest[1] = CLIP (block[1] + dest[1]);
+ dest[2] = CLIP (block[2] + dest[2]);
+ dest[3] = CLIP (block[3] + dest[3]);
+ dest[4] = CLIP (block[4] + dest[4]);
+ dest[5] = CLIP (block[5] + dest[5]);
+ dest[6] = CLIP (block[6] + dest[6]);
+ dest[7] = CLIP (block[7] + dest[7]);
+
+ dest += stride;
+ block += 8;
+ } while (--i);
+}
diff --git a/libmpeg2/idct_mlib.c b/libmpeg2/idct_mlib.c
new file mode 100644
index 0000000000..055ee75fa6
--- /dev/null
+++ b/libmpeg2/idct_mlib.c
@@ -0,0 +1,47 @@
+/*
+ * idct_mlib.c
+ * Copyright (C) 1999 Håkan Hjort <d95hjort@dtek.chalmers.se>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBMPEG2_MLIB
+
+#include <inttypes.h>
+#include <mlib_types.h>
+#include <mlib_status.h>
+#include <mlib_sys.h>
+#include <mlib_video.h>
+
+#include "mpeg2_internal.h"
+
+void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride)
+{
+ mlib_VideoIDCT8x8_U8_S16 (dest, block, stride);
+}
+
+void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride)
+{
+ // Should we use mlib_VideoIDCT_IEEE_S16_S16 here ??
+ // it's ~30% slower.
+ mlib_VideoIDCT8x8_S16_S16 (block, block);
+ mlib_VideoAddBlock_U8_S16 (dest, block, stride);
+}
+
+#endif
diff --git a/libmpeg2/idct_mmx.c b/libmpeg2/idct_mmx.c
new file mode 100644
index 0000000000..03ea5d7580
--- /dev/null
+++ b/libmpeg2/idct_mmx.c
@@ -0,0 +1,706 @@
+/*
+ * idct_mmx.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef ARCH_X86
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+#include "mmx.h"
+
+#define ROW_SHIFT 11
+#define COL_SHIFT 6
+
+#define round(bias) ((int)(((bias)+0.5) * (1<<ROW_SHIFT)))
+#define rounder(bias) {round (bias), round (bias)}
+
+
+#if 0
+// C row IDCT - its just here to document the MMXEXT and MMX versions
+static inline void idct_row (int16_t * row, int offset,
+ int16_t * table, int32_t * rounder)
+{
+ int C1, C2, C3, C4, C5, C6, C7;
+ int a0, a1, a2, a3, b0, b1, b2, b3;
+
+ row += offset;
+
+ C1 = table[1];
+ C2 = table[2];
+ C3 = table[3];
+ C4 = table[4];
+ C5 = table[5];
+ C6 = table[6];
+ C7 = table[7];
+
+ a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + *rounder;
+ a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + *rounder;
+ a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + *rounder;
+ a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + *rounder;
+
+ b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7];
+ b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7];
+ b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7];
+ b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7];
+
+ row[0] = (a0 + b0) >> ROW_SHIFT;
+ row[1] = (a1 + b1) >> ROW_SHIFT;
+ row[2] = (a2 + b2) >> ROW_SHIFT;
+ row[3] = (a3 + b3) >> ROW_SHIFT;
+ row[4] = (a3 - b3) >> ROW_SHIFT;
+ row[5] = (a2 - b2) >> ROW_SHIFT;
+ row[6] = (a1 - b1) >> ROW_SHIFT;
+ row[7] = (a0 - b0) >> ROW_SHIFT;
+}
+#endif
+
+
+// MMXEXT row IDCT
+
+#define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \
+ c4, c6, c4, c6, \
+ c1, c3, -c1, -c5, \
+ c5, c7, c3, -c7, \
+ c4, -c6, c4, -c6, \
+ -c4, c2, c4, -c2, \
+ c5, -c1, c3, -c1, \
+ c7, c3, c7, -c5 }
+
+static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4
+ pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2
+
+ pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4
+}
+
+static inline void mmxext_row (int16_t * table, int32_t * rounder)
+{
+ movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1
+ pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6
+
+ pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2
+ pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5
+
+ movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5
+ pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3
+
+ paddd_m2r (*rounder, mm3); // mm3 += rounder
+ pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7
+
+ pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6
+ paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3
+ movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7
+ paddd_r2r (mm7, mm1); // mm1 = b1 b0
+
+ paddd_m2r (*rounder, mm0); // mm0 += rounder
+ psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder
+
+ psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7
+ paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder
+
+ paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder
+ psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0
+
+ paddd_r2r (mm6, mm5); // mm5 = b3 b2
+ movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder
+
+ paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder
+ psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder
+}
+
+static inline void mmxext_row_tail (int16_t * row, int store)
+{
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+
+ packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4
+
+ // slot
+
+ movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4
+}
+
+static inline void mmxext_row_mid (int16_t * row, int store,
+ int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4
+
+ movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4
+ movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4
+
+ pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2
+
+ movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4
+ pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4
+}
+
+
+// MMX row IDCT
+
+#define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \
+ c4, c6, -c4, -c2, \
+ c1, c3, c3, -c7, \
+ c5, c7, -c1, -c5, \
+ c4, -c6, c4, -c2, \
+ -c4, c2, c4, -c6, \
+ c5, -c1, c7, -c5, \
+ c7, c3, c3, -c1 }
+
+static inline void mmx_row_head (int16_t * row, int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0
+
+ movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4
+ pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2
+
+ movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1
+ punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4
+}
+
+static inline void mmx_row (int16_t * table, int32_t * rounder)
+{
+ pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6
+ punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1
+
+ pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2
+ punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5
+
+ movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5
+ pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3
+
+ paddd_m2r (*rounder, mm3); // mm3 += rounder
+ pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7
+
+ pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6
+ paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3
+ movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7
+ paddd_r2r (mm7, mm1); // mm1 = b1 b0
+
+ paddd_m2r (*rounder, mm0); // mm0 += rounder
+ psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder
+
+ psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7
+ paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder
+
+ paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder
+ psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0
+
+ paddd_r2r (mm6, mm5); // mm5 = b3 b2
+ movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder
+
+ paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder
+ psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder
+}
+
+static inline void mmx_row_tail (int16_t * row, int store)
+{
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+
+ packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5
+
+ pslld_i2r (16, mm7); // mm7 = y7 0 y5 0
+
+ psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4
+
+ por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4
+
+ // slot
+
+ movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4
+}
+
+static inline void mmx_row_mid (int16_t * row, int store,
+ int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5
+
+ punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0
+ psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4
+
+ movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4
+ pslld_i2r (16, mm1); // mm1 = y7 0 y5 0
+
+ movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4
+ por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4
+
+ movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1
+ punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4
+
+ movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4
+ pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2
+}
+
+
+#if 0
+// C column IDCT - its just here to document the MMXEXT and MMX versions
+static inline void idct_col (int16_t * col, int offset)
+{
+// multiplication - as implemented on mmx
+#define F(c,x) (((c) * (x)) >> 16)
+
+// saturation - it helps us handle torture test cases
+#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x))
+
+ int16_t x0, x1, x2, x3, x4, x5, x6, x7;
+ int16_t y0, y1, y2, y3, y4, y5, y6, y7;
+ int16_t a0, a1, a2, a3, b0, b1, b2, b3;
+ int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12;
+
+ col += offset;
+
+ x0 = col[0*8];
+ x1 = col[1*8];
+ x2 = col[2*8];
+ x3 = col[3*8];
+ x4 = col[4*8];
+ x5 = col[5*8];
+ x6 = col[6*8];
+ x7 = col[7*8];
+
+ u04 = S (x0 + x4);
+ v04 = S (x0 - x4);
+ u26 = S (F (T2, x6) + x2); // -0.5
+ v26 = S (F (T2, x2) - x6); // -0.5
+
+ a0 = S (u04 + u26);
+ a1 = S (v04 + v26);
+ a2 = S (v04 - v26);
+ a3 = S (u04 - u26);
+
+ u17 = S (F (T1, x7) + x1); // -0.5
+ v17 = S (F (T1, x1) - x7); // -0.5
+ u35 = S (F (T3, x5) + x3); // -0.5
+ v35 = S (F (T3, x3) - x5); // -0.5
+
+ b0 = S (u17 + u35);
+ b3 = S (v17 - v35);
+ u12 = S (u17 - u35);
+ v12 = S (v17 + v35);
+ u12 = S (2 * F (C4, u12)); // -0.5
+ v12 = S (2 * F (C4, v12)); // -0.5
+ b1 = S (u12 + v12);
+ b2 = S (u12 - v12);
+
+ y0 = S (a0 + b0) >> COL_SHIFT;
+ y1 = S (a1 + b1) >> COL_SHIFT;
+ y2 = S (a2 + b2) >> COL_SHIFT;
+ y3 = S (a3 + b3) >> COL_SHIFT;
+
+ y4 = S (a3 - b3) >> COL_SHIFT;
+ y5 = S (a2 - b2) >> COL_SHIFT;
+ y6 = S (a1 - b1) >> COL_SHIFT;
+ y7 = S (a0 - b0) >> COL_SHIFT;
+
+ col[0*8] = y0;
+ col[1*8] = y1;
+ col[2*8] = y2;
+ col[3*8] = y3;
+ col[4*8] = y4;
+ col[5*8] = y5;
+ col[6*8] = y6;
+ col[7*8] = y7;
+}
+#endif
+
+
+// MMX column IDCT
+static inline void idct_col (int16_t * col, int offset)
+{
+#define T1 13036
+#define T2 27146
+#define T3 43790
+#define C4 23170
+
+ static short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1};
+ static short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2};
+ static short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3};
+ static short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4};
+ static mmx_t scratch0, scratch1;
+
+ /* column code adapted from peter gubanov */
+ /* http://www.elecard.com/peter/idct.shtml */
+
+ movq_m2r (*_T1, mm0); // mm0 = T1
+
+ movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1
+ movq_r2r (mm0, mm2); // mm2 = T1
+
+ movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7
+ pmulhw_r2r (mm1, mm0); // mm0 = T1*x1
+
+ movq_m2r (*_T3, mm5); // mm5 = T3
+ pmulhw_r2r (mm4, mm2); // mm2 = T1*x7
+
+ movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5
+ movq_r2r (mm5, mm7); // mm7 = T3-1
+
+ movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3
+ psubsw_r2r (mm4, mm0); // mm0 = v17
+
+ movq_m2r (*_T2, mm4); // mm4 = T2
+ pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3
+
+ paddsw_r2r (mm2, mm1); // mm1 = u17
+ pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5
+
+ // slot
+
+ movq_r2r (mm4, mm2); // mm2 = T2
+ paddsw_r2r (mm3, mm5); // mm5 = T3*x3
+
+ pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2
+ paddsw_r2r (mm6, mm7); // mm7 = T3*x5
+
+ psubsw_r2r (mm6, mm5); // mm5 = v35
+ paddsw_r2r (mm3, mm7); // mm7 = u35
+
+ movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6
+ movq_r2r (mm0, mm6); // mm6 = v17
+
+ pmulhw_r2r (mm3, mm2); // mm2 = T2*x6
+ psubsw_r2r (mm5, mm0); // mm0 = b3
+
+ psubsw_r2r (mm3, mm4); // mm4 = v26
+ paddsw_r2r (mm6, mm5); // mm5 = v12
+
+ movq_r2m (mm0, scratch0); // save b3
+ movq_r2r (mm1, mm6); // mm6 = u17
+
+ paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26
+ paddsw_r2r (mm7, mm6); // mm6 = b0
+
+ psubsw_r2r (mm7, mm1); // mm1 = u12
+ movq_r2r (mm1, mm7); // mm7 = u12
+
+ movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0
+ paddsw_r2r (mm5, mm1); // mm1 = u12+v12
+
+ movq_m2r (*_C4, mm0); // mm0 = C4/2
+ psubsw_r2r (mm5, mm7); // mm7 = u12-v12
+
+ movq_r2m (mm6, scratch1); // save b0
+ pmulhw_r2r (mm0, mm1); // mm1 = b1/2
+
+ movq_r2r (mm4, mm6); // mm6 = v26
+ pmulhw_r2r (mm0, mm7); // mm7 = b2/2
+
+ movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4
+ movq_r2r (mm3, mm0); // mm0 = x0
+
+ psubsw_r2r (mm5, mm3); // mm3 = v04
+ paddsw_r2r (mm5, mm0); // mm0 = u04
+
+ paddsw_r2r (mm3, mm4); // mm4 = a1
+ movq_r2r (mm0, mm5); // mm5 = u04
+
+ psubsw_r2r (mm6, mm3); // mm3 = a2
+ paddsw_r2r (mm2, mm5); // mm5 = a0
+
+ paddsw_r2r (mm1, mm1); // mm1 = b1
+ psubsw_r2r (mm2, mm0); // mm0 = a3
+
+ paddsw_r2r (mm7, mm7); // mm7 = b2
+ movq_r2r (mm3, mm2); // mm2 = a2
+
+ movq_r2r (mm4, mm6); // mm6 = a1
+ paddsw_r2r (mm7, mm3); // mm3 = a2+b2
+
+ psraw_i2r (COL_SHIFT, mm3); // mm3 = y2
+ paddsw_r2r (mm1, mm4); // mm4 = a1+b1
+
+ psraw_i2r (COL_SHIFT, mm4); // mm4 = y1
+ psubsw_r2r (mm1, mm6); // mm6 = a1-b1
+
+ movq_m2r (scratch1, mm1); // mm1 = b0
+ psubsw_r2r (mm7, mm2); // mm2 = a2-b2
+
+ psraw_i2r (COL_SHIFT, mm6); // mm6 = y6
+ movq_r2r (mm5, mm7); // mm7 = a0
+
+ movq_r2m (mm4, *(col+offset+1*8)); // save y1
+ psraw_i2r (COL_SHIFT, mm2); // mm2 = y5
+
+ movq_r2m (mm3, *(col+offset+2*8)); // save y2
+ paddsw_r2r (mm1, mm5); // mm5 = a0+b0
+
+ movq_m2r (scratch0, mm4); // mm4 = b3
+ psubsw_r2r (mm1, mm7); // mm7 = a0-b0
+
+ psraw_i2r (COL_SHIFT, mm5); // mm5 = y0
+ movq_r2r (mm0, mm3); // mm3 = a3
+
+ movq_r2m (mm2, *(col+offset+5*8)); // save y5
+ psubsw_r2r (mm4, mm3); // mm3 = a3-b3
+
+ psraw_i2r (COL_SHIFT, mm7); // mm7 = y7
+ paddsw_r2r (mm0, mm4); // mm4 = a3+b3
+
+ movq_r2m (mm5, *(col+offset+0*8)); // save y0
+ psraw_i2r (COL_SHIFT, mm3); // mm3 = y4
+
+ movq_r2m (mm6, *(col+offset+6*8)); // save y6
+ psraw_i2r (COL_SHIFT, mm4); // mm4 = y3
+
+ movq_r2m (mm7, *(col+offset+7*8)); // save y7
+
+ movq_r2m (mm3, *(col+offset+4*8)); // save y4
+
+ movq_r2m (mm4, *(col+offset+3*8)); // save y3
+}
+
+
+static int32_t rounder0[] ATTR_ALIGN(8) =
+ rounder ((1 << (COL_SHIFT - 1)) - 0.5);
+static int32_t rounder4[] ATTR_ALIGN(8) = rounder (0);
+static int32_t rounder1[] ATTR_ALIGN(8) =
+ rounder (1.25683487303); // C1*(C1/C4+C1+C7)/2
+static int32_t rounder7[] ATTR_ALIGN(8) =
+ rounder (-0.25); // C1*(C7/C4+C7-C1)/2
+static int32_t rounder2[] ATTR_ALIGN(8) =
+ rounder (0.60355339059); // C2 * (C6+C2)/2
+static int32_t rounder6[] ATTR_ALIGN(8) =
+ rounder (-0.25); // C2 * (C6-C2)/2
+static int32_t rounder3[] ATTR_ALIGN(8) =
+ rounder (0.087788325588); // C3*(-C3/C4+C3+C5)/2
+static int32_t rounder5[] ATTR_ALIGN(8) =
+ rounder (-0.441341716183); // C3*(-C5/C4+C5-C3)/2
+
+
+#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \
+static inline void idct (int16_t * block) \
+{ \
+ static int16_t table04[] ATTR_ALIGN(16) = \
+ table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \
+ static int16_t table17[] ATTR_ALIGN(16) = \
+ table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \
+ static int16_t table26[] ATTR_ALIGN(16) = \
+ table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \
+ static int16_t table35[] ATTR_ALIGN(16) = \
+ table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \
+ \
+ idct_row_head (block, 0*8, table04); \
+ idct_row (table04, rounder0); \
+ idct_row_mid (block, 0*8, 4*8, table04); \
+ idct_row (table04, rounder4); \
+ idct_row_mid (block, 4*8, 1*8, table17); \
+ idct_row (table17, rounder1); \
+ idct_row_mid (block, 1*8, 7*8, table17); \
+ idct_row (table17, rounder7); \
+ idct_row_mid (block, 7*8, 2*8, table26); \
+ idct_row (table26, rounder2); \
+ idct_row_mid (block, 2*8, 6*8, table26); \
+ idct_row (table26, rounder6); \
+ idct_row_mid (block, 6*8, 3*8, table35); \
+ idct_row (table35, rounder3); \
+ idct_row_mid (block, 3*8, 5*8, table35); \
+ idct_row (table35, rounder5); \
+ idct_row_tail (block, 5*8); \
+ \
+ idct_col (block, 0); \
+ idct_col (block, 4); \
+}
+
+
+#define COPY_MMX(offset,r0,r1,r2) \
+do { \
+ movq_m2r (*(block+offset), r0); \
+ dest += stride; \
+ movq_m2r (*(block+offset+4), r1); \
+ movq_r2m (r2, *dest); \
+ packuswb_r2r (r1, r0); \
+} while (0)
+
+static void block_copy (int16_t * block, uint8_t * dest, int stride)
+{
+ movq_m2r (*(block+0*8), mm0);
+ movq_m2r (*(block+0*8+4), mm1);
+ movq_m2r (*(block+1*8), mm2);
+ packuswb_r2r (mm1, mm0);
+ movq_m2r (*(block+1*8+4), mm3);
+ movq_r2m (mm0, *dest);
+ packuswb_r2r (mm3, mm2);
+ COPY_MMX (2*8, mm0, mm1, mm2);
+ COPY_MMX (3*8, mm2, mm3, mm0);
+ COPY_MMX (4*8, mm0, mm1, mm2);
+ COPY_MMX (5*8, mm2, mm3, mm0);
+ COPY_MMX (6*8, mm0, mm1, mm2);
+ COPY_MMX (7*8, mm2, mm3, mm0);
+ movq_r2m (mm2, *(dest+stride));
+}
+
+
+#define ADD_MMX(offset,r1,r2,r3,r4) \
+do { \
+ movq_m2r (*(dest+2*stride), r1); \
+ packuswb_r2r (r4, r3); \
+ movq_r2r (r1, r2); \
+ dest += stride; \
+ movq_r2m (r3, *dest); \
+ punpcklbw_r2r (mm0, r1); \
+ paddsw_m2r (*(block+offset), r1); \
+ punpckhbw_r2r (mm0, r2); \
+ paddsw_m2r (*(block+offset+4), r2); \
+} while (0)
+
+static void block_add (int16_t * block, uint8_t * dest, int stride)
+{
+ movq_m2r (*dest, mm1);
+ pxor_r2r (mm0, mm0);
+ movq_m2r (*(dest+stride), mm3);
+ movq_r2r (mm1, mm2);
+ punpcklbw_r2r (mm0, mm1);
+ movq_r2r (mm3, mm4);
+ paddsw_m2r (*(block+0*8), mm1);
+ punpckhbw_r2r (mm0, mm2);
+ paddsw_m2r (*(block+0*8+4), mm2);
+ punpcklbw_r2r (mm0, mm3);
+ paddsw_m2r (*(block+1*8), mm3);
+ packuswb_r2r (mm2, mm1);
+ punpckhbw_r2r (mm0, mm4);
+ movq_r2m (mm1, *dest);
+ paddsw_m2r (*(block+1*8+4), mm4);
+ ADD_MMX (2*8, mm1, mm2, mm3, mm4);
+ ADD_MMX (3*8, mm3, mm4, mm1, mm2);
+ ADD_MMX (4*8, mm1, mm2, mm3, mm4);
+ ADD_MMX (5*8, mm3, mm4, mm1, mm2);
+ ADD_MMX (6*8, mm1, mm2, mm3, mm4);
+ ADD_MMX (7*8, mm3, mm4, mm1, mm2);
+ packuswb_r2r (mm4, mm3);
+ movq_r2m (mm3, *(dest+stride));
+}
+
+
+declare_idct (mmxext_idct, mmxext_table,
+ mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid)
+
+void idct_block_copy_mmxext (int16_t * block, uint8_t * dest, int stride)
+{
+ mmxext_idct (block);
+ block_copy (block, dest, stride);
+}
+
+void idct_block_add_mmxext (int16_t * block, uint8_t * dest, int stride)
+{
+ mmxext_idct (block);
+ block_add (block, dest, stride);
+}
+
+
+declare_idct (mmx_idct, mmx_table,
+ mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid)
+
+void idct_block_copy_mmx (int16_t * block, uint8_t * dest, int stride)
+{
+ mmx_idct (block);
+ block_copy (block, dest, stride);
+}
+
+void idct_block_add_mmx (int16_t * block, uint8_t * dest, int stride)
+{
+ mmx_idct (block);
+ block_add (block, dest, stride);
+}
+
+
+void idct_mmx_init (void)
+{
+ extern uint8_t scan_norm[64];
+ extern uint8_t scan_alt[64];
+ int i, j;
+
+ // the mmx/mmxext idct uses a reordered input, so we patch scan tables
+
+ for (i = 0; i < 64; i++) {
+ j = scan_norm[i];
+ scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ j = scan_alt[i];
+ scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ }
+}
+
+#endif
diff --git a/libmpeg2/mm_accel.h b/libmpeg2/mm_accel.h
new file mode 100644
index 0000000000..133d6acb03
--- /dev/null
+++ b/libmpeg2/mm_accel.h
@@ -0,0 +1,30 @@
+/*
+ * oms_accel.h
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// generic accelerations
+#define MM_ACCEL_MLIB 0x00000001
+
+// x86 accelerations
+#define MM_ACCEL_X86_MMX 0x80000000
+#define MM_ACCEL_X86_3DNOW 0x40000000
+#define MM_ACCEL_X86_MMXEXT 0x20000000
+
+//uint32_t mm_accel (void);
diff --git a/libmpeg2/mmx.h b/libmpeg2/mmx.h
new file mode 100644
index 0000000000..bab97b8b1f
--- /dev/null
+++ b/libmpeg2/mmx.h
@@ -0,0 +1,255 @@
+/*
+ * mmx.h
+ * Copyright (C) 1997-1999 H. Dietz and R. Fisher
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * The type of an value that fits in an MMX register (note that long
+ * long constant values MUST be suffixed by LL and unsigned long long
+ * values by ULL, lest they be truncated by the compiler)
+ */
+
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+#define mmx_i2r(op,imm,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op,mem,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_r2m(op,reg,mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op,regs,regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
+#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
+#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
+
+#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
+#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
+#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
+
+#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
+#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
+#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
+#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
+
+#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
+#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
+
+#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
+#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
+#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
+#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
+#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
+#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
+
+#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
+#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
+#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
+#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
+
+#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
+#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
+#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
+#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
+
+#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
+#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
+
+#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
+#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
+
+#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
+#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
+#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
+
+#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
+#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
+
+#define por_m2r(var,reg) mmx_m2r (por, var, reg)
+#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
+
+#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
+#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
+#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
+#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
+#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
+#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
+#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
+#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
+#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
+
+#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
+#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
+#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
+#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
+#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
+#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
+
+#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
+#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
+#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
+#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
+#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
+#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
+#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
+#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
+#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
+
+#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
+#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
+#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
+#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
+#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
+#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
+
+#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
+#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
+#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
+#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
+
+#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
+#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
+#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
+#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
+
+#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
+#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
+#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
+#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
+#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
+#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
+#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
+#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
+#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
+#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
+#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
+
+#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
+#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+
+
+/* 3DNOW extensions */
+
+#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
+#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+
+
+/* AMD MMX extensions - also available in intel SSE */
+
+
+#define mmx_m2ri(op,mem,reg,imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem), "X" (imm))
+#define mmx_r2ri(op,regs,regd,imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_fetch(mem,hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+
+#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+
+#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
+#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
+#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
+#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+
+#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+
+#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+
+#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
+#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+
+#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
+#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+
+#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
+#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+
+#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
+#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+
+#define pmovmskb(mmreg,reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+
+#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
+#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+
+#define prefetcht0(mem) mmx_fetch (mem, t0)
+#define prefetcht1(mem) mmx_fetch (mem, t1)
+#define prefetcht2(mem) mmx_fetch (mem, t2)
+#define prefetchnta(mem) mmx_fetch (mem, nta)
+
+#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
+#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+
+#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
diff --git a/libmpeg2/motion_comp.c b/libmpeg2/motion_comp.c
new file mode 100644
index 0000000000..816335c6dc
--- /dev/null
+++ b/libmpeg2/motion_comp.c
@@ -0,0 +1,125 @@
+/*
+ * motion_comp.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "mm_accel.h"
+
+mc_functions_t mc_functions;
+
+void motion_comp_init (void)
+{
+
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMXEXT) {
+ fprintf (stderr, "Using MMXEXT for motion compensation\n");
+ mc_functions = mc_functions_mmxext;
+ } else if (config.flags & MM_ACCEL_X86_3DNOW) {
+ fprintf (stderr, "Using 3DNOW for motion compensation\n");
+ mc_functions = mc_functions_3dnow;
+ } else if (config.flags & MM_ACCEL_X86_MMX) {
+ fprintf (stderr, "Using MMX for motion compensation\n");
+ mc_functions = mc_functions_mmx;
+ } else
+#endif
+#ifdef LIBMPEG2_MLIB
+ if (config.flags & MM_ACCEL_MLIB) {
+ fprintf (stderr, "Using mlib for motion compensation\n");
+ mc_functions = mc_functions_mlib;
+ } else
+#endif
+ {
+ fprintf (stderr, "No accelerated motion compensation found\n");
+ mc_functions = mc_functions_c;
+ }
+}
+
+#define avg2(a,b) ((a+b+1)>>1)
+#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
+
+#define predict_(i) (ref[i])
+#define predict_x(i) (avg2 (ref[i], ref[i+1]))
+#define predict_y(i) (avg2 (ref[i], (ref+stride)[i]))
+#define predict_xy(i) (avg4 (ref[i], ref[i+1], (ref+stride)[i], (ref+stride)[i+1]))
+
+#define put(predictor,i) dest[i] = predictor (i)
+#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i])
+
+// mc function template
+
+#define MC_FUNC(op,xy) \
+static void MC_##op##_##xy##16_c (uint8_t * dest, uint8_t * ref,\
+ int stride, int height) \
+{ \
+ do { \
+ op (predict_##xy, 0); \
+ op (predict_##xy, 1); \
+ op (predict_##xy, 2); \
+ op (predict_##xy, 3); \
+ op (predict_##xy, 4); \
+ op (predict_##xy, 5); \
+ op (predict_##xy, 6); \
+ op (predict_##xy, 7); \
+ op (predict_##xy, 8); \
+ op (predict_##xy, 9); \
+ op (predict_##xy, 10); \
+ op (predict_##xy, 11); \
+ op (predict_##xy, 12); \
+ op (predict_##xy, 13); \
+ op (predict_##xy, 14); \
+ op (predict_##xy, 15); \
+ ref += stride; \
+ dest += stride; \
+ } while (--height); \
+} \
+static void MC_##op##_##xy##8_c (uint8_t * dest, uint8_t * ref, \
+ int stride, int height) \
+{ \
+ do { \
+ op (predict_##xy, 0); \
+ op (predict_##xy, 1); \
+ op (predict_##xy, 2); \
+ op (predict_##xy, 3); \
+ op (predict_##xy, 4); \
+ op (predict_##xy, 5); \
+ op (predict_##xy, 6); \
+ op (predict_##xy, 7); \
+ ref += stride; \
+ dest += stride; \
+ } while (--height); \
+}
+
+// definitions of the actual mc functions
+
+MC_FUNC (put,)
+MC_FUNC (avg,)
+MC_FUNC (put,x)
+MC_FUNC (avg,x)
+MC_FUNC (put,y)
+MC_FUNC (avg,y)
+MC_FUNC (put,xy)
+MC_FUNC (avg,xy)
+
+MOTION_COMP_EXTERN (c)
diff --git a/libmpeg2/motion_comp_mlib.c b/libmpeg2/motion_comp_mlib.c
new file mode 100644
index 0000000000..e079119eb9
--- /dev/null
+++ b/libmpeg2/motion_comp_mlib.c
@@ -0,0 +1,180 @@
+/*
+ * MC_mlib.c
+ * Copyright (C) 2000 Håkan Hjort <d95hjort@dtek.chalmers.se>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBMPEG2_MLIB
+
+#include <inttypes.h>
+#include <mlib_types.h>
+#include <mlib_status.h>
+#include <mlib_sys.h>
+#include <mlib_video.h>
+
+#include "mpeg2_internal.h"
+
+static void MC_put_16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoCopyRef_U8_U8_16x16 (dest, ref, stride);
+ else
+ mlib_VideoCopyRef_U8_U8_16x8 (dest, ref, stride);
+}
+
+static void MC_put_x16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpX_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpX_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_put_y16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_put_xy16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpXY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpXY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_put_8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoCopyRef_U8_U8_8x8 (dest, ref, stride);
+ else
+ mlib_VideoCopyRef_U8_U8_8x4 (dest, ref, stride);
+}
+
+static void MC_put_x8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpX_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpX_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_put_y8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_put_xy8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpXY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpXY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_avg_16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoCopyRefAve_U8_U8_16x16 (dest, ref, stride);
+ else
+ mlib_VideoCopyRefAve_U8_U8_16x8 (dest, ref, stride);
+}
+
+static void MC_avg_x16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpAveX_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveX_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_avg_y16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpAveY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_avg_xy16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpAveXY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveXY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_avg_8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoCopyRefAve_U8_U8_8x8 (dest, ref, stride);
+ else
+ mlib_VideoCopyRefAve_U8_U8_8x4 (dest, ref, stride);
+}
+
+static void MC_avg_x8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpAveX_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveX_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_avg_y8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpAveY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_avg_xy8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpAveXY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveXY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+MOTION_COMP_EXTERN (mlib)
+
+#endif
diff --git a/libmpeg2/motion_comp_mmx.c b/libmpeg2/motion_comp_mmx.c
new file mode 100644
index 0000000000..f635692045
--- /dev/null
+++ b/libmpeg2/motion_comp_mmx.c
@@ -0,0 +1,1025 @@
+/*
+ * motion_comp_mmx.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef ARCH_X86
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+#include "mmx.h"
+
+#define CPU_MMXEXT 0
+#define CPU_3DNOW 1
+
+
+//MMX code - needs a rewrite
+
+
+
+
+
+
+
+// some rounding constants
+mmx_t round1 = {0x0001000100010001LL};
+mmx_t round4 = {0x0002000200020002LL};
+
+/*
+ * This code should probably be compiled with loop unrolling
+ * (ie, -funroll-loops in gcc)becuase some of the loops
+ * use a small static number of iterations. This was written
+ * with the assumption the compiler knows best about when
+ * unrolling will help
+ */
+
+static inline void mmx_zero_reg ()
+{
+ // load 0 into mm0
+ pxor_r2r (mm0, mm0);
+}
+
+static inline void mmx_average_2_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2)
+{
+ //
+ // *dest = (*src1 + *src2 + 1)/ 2;
+ //
+
+ movq_m2r (*src1, mm1); // load 8 src1 bytes
+ movq_r2r (mm1, mm2); // copy 8 src1 bytes
+
+ movq_m2r (*src2, mm3); // load 8 src2 bytes
+ movq_r2r (mm3, mm4); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes
+
+ paddw_r2r (mm3, mm1); // add lows to mm1
+ paddw_m2r (round1, mm1);
+ psraw_i2r (1, mm1); // /2
+
+ paddw_r2r (mm4, mm2); // add highs to mm2
+ paddw_m2r (round1, mm2);
+ psraw_i2r (1, mm2); // /2
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1, *dest); // store result in dest
+}
+
+static inline void mmx_interp_average_2_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2)
+{
+ //
+ // *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2;
+ //
+
+ movq_m2r (*dest, mm1); // load 8 dest bytes
+ movq_r2r (mm1, mm2); // copy 8 dest bytes
+
+ movq_m2r (*src1, mm3); // load 8 src1 bytes
+ movq_r2r (mm3, mm4); // copy 8 src1 bytes
+
+ movq_m2r (*src2, mm5); // load 8 src2 bytes
+ movq_r2r (mm5, mm6); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low dest bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high dest bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src1 bytes
+
+ punpcklbw_r2r (mm0, mm5); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm6); // unpack high src2 bytes
+
+ paddw_r2r (mm5, mm3); // add lows
+ paddw_m2r (round1, mm3);
+ psraw_i2r (1, mm3); // /2
+
+ paddw_r2r (mm6, mm4); // add highs
+ paddw_m2r (round1, mm4);
+ psraw_i2r (1, mm4); // /2
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_m2r (round1, mm1);
+ psraw_i2r (1, mm1); // /2
+
+ paddw_r2r (mm4, mm2); // add highs
+ paddw_m2r (round1, mm2);
+ psraw_i2r (1, mm2); // /2
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1, *dest); // store result in dest
+}
+
+static inline void mmx_average_4_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2,
+ uint8_t * src3, uint8_t * src4)
+{
+ //
+ // *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4;
+ //
+
+ movq_m2r (*src1, mm1); // load 8 src1 bytes
+ movq_r2r (mm1, mm2); // copy 8 src1 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes
+
+ movq_m2r (*src2, mm3); // load 8 src2 bytes
+ movq_r2r (mm3, mm4); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ // now have partials in mm1 and mm2
+
+ movq_m2r (*src3, mm3); // load 8 src3 bytes
+ movq_r2r (mm3, mm4); // copy 8 src3 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ movq_m2r (*src4, mm5); // load 8 src4 bytes
+ movq_r2r (mm5, mm6); // copy 8 src4 bytes
+
+ punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes
+ punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes
+
+ paddw_r2r (mm5, mm1); // add lows
+ paddw_r2r (mm6, mm2); // add highs
+
+ // now have subtotal in mm1 and mm2
+
+ paddw_m2r (round4, mm1);
+ psraw_i2r (2, mm1); // /4
+ paddw_m2r (round4, mm2);
+ psraw_i2r (2, mm2); // /4
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1, *dest); // store result in dest
+}
+
+static inline void mmx_interp_average_4_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2,
+ uint8_t * src3, uint8_t * src4)
+{
+ //
+ // *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2;
+ //
+
+ movq_m2r (*src1, mm1); // load 8 src1 bytes
+ movq_r2r (mm1, mm2); // copy 8 src1 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes
+
+ movq_m2r (*src2, mm3); // load 8 src2 bytes
+ movq_r2r (mm3, mm4); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ // now have partials in mm1 and mm2
+
+ movq_m2r (*src3, mm3); // load 8 src3 bytes
+ movq_r2r (mm3, mm4); // copy 8 src3 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ movq_m2r (*src4, mm5); // load 8 src4 bytes
+ movq_r2r (mm5, mm6); // copy 8 src4 bytes
+
+ punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes
+ punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes
+
+ paddw_r2r (mm5, mm1); // add lows
+ paddw_r2r (mm6, mm2); // add highs
+
+ paddw_m2r (round4, mm1);
+ psraw_i2r (2, mm1); // /4
+ paddw_m2r (round4, mm2);
+ psraw_i2r (2, mm2); // /4
+
+ // now have subtotal/4 in mm1 and mm2
+
+ movq_m2r (*dest, mm3); // load 8 dest bytes
+ movq_r2r (mm3, mm4); // copy 8 dest bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low dest bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high dest bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ paddw_m2r (round1, mm1);
+ psraw_i2r (1, mm1); // /2
+ paddw_m2r (round1, mm2);
+ psraw_i2r (1, mm2); // /2
+
+ // now have end value in mm1 and mm2
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1,*dest); // store result in dest
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_avg_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_2_U8 (dest, dest, ref);
+
+ if (width == 16)
+ mmx_average_2_U8 (dest+8, dest+8, ref+8);
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_avg_16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_put_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ movq_m2r (* ref, mm1); // load 8 ref bytes
+ movq_r2m (mm1,* dest); // store 8 bytes at curr
+
+ if (width == 16)
+ {
+ movq_m2r (* (ref+8), mm1); // load 8 ref bytes
+ movq_r2m (mm1,* (dest+8)); // store 8 bytes at curr
+ }
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_put_16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+// Half pixel interpolation in the x direction
+static inline void MC_avg_x_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ mmx_interp_average_2_U8 (dest, ref, ref+1);
+
+ if (width == 16)
+ mmx_interp_average_2_U8 (dest+8, ref+8, ref+9);
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_avg_x16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_x_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_x8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_x_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_put_x_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_2_U8 (dest, ref, ref+1);
+
+ if (width == 16)
+ mmx_average_2_U8 (dest+8, ref+8, ref+9);
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_put_x16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_x_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_x8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_x_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_avg_xy_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1);
+
+ if (width == 16)
+ mmx_interp_average_4_U8 (dest+8, ref+8, ref+9,
+ ref_next+8, ref_next+9);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_avg_xy16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_xy_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_xy8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_xy_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_put_xy_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1);
+
+ if (width == 16)
+ mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_put_xy16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_xy_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_xy8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_xy_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_avg_y_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_interp_average_2_U8 (dest, ref, ref_next);
+
+ if (width == 16)
+ mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_avg_y16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_y_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_y8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_y_mmx (8, height, dest, ref, stride);
+}
+
+//-----------------------------------------------------------------------
+
+static inline void MC_put_y_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_2_U8 (dest, ref, ref_next);
+
+ if (width == 16)
+ mmx_average_2_U8 (dest+8, ref+8, ref_next+8);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_put_y16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_y_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_y8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_y_mmx (8, height, dest, ref, stride);
+}
+
+
+MOTION_COMP_EXTERN (mmx)
+
+
+
+
+
+
+
+//CPU_MMXEXT/CPU_3DNOW adaptation layer
+
+#define pavg_r2r(src,dest) \
+do { \
+ if (cpu == CPU_MMXEXT) \
+ pavgb_r2r (src, dest); \
+ else \
+ pavgusb_r2r (src, dest); \
+} while (0)
+
+#define pavg_m2r(src,dest) \
+do { \
+ if (cpu == CPU_MMXEXT) \
+ pavgb_m2r (src, dest); \
+ else \
+ pavgusb_m2r (src, dest); \
+} while (0)
+
+
+//CPU_MMXEXT code
+
+
+static inline void MC_put1_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_r2m (mm0, *dest);
+ ref += stride;
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_put1_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg1_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ pavg_m2r (*dest, mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg1_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ pavg_m2r (*dest, mm0);
+ pavg_m2r (*(dest+8), mm1);
+ movq_r2m (mm0, *dest);
+ ref += stride;
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_put2_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ pavg_m2r (*(ref+offset), mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_put2_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ pavg_m2r (*(ref+offset), mm0);
+ pavg_m2r (*(ref+offset+8), mm1);
+ movq_r2m (mm0, *dest);
+ ref += stride;
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg2_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ pavg_m2r (*(ref+offset), mm0);
+ pavg_m2r (*dest, mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg2_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ pavg_m2r (*(ref+offset), mm0);
+ pavg_m2r (*(ref+offset+8), mm1);
+ pavg_m2r (*dest, mm0);
+ pavg_m2r (*(dest+8), mm1);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static mmx_t mask_one = {0x0101010101010101LL};
+
+static inline void MC_put4_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+1), mm1);
+ movq_r2r (mm0, mm7);
+ pxor_r2r (mm1, mm7);
+ pavg_r2r (mm1, mm0);
+ ref += stride;
+
+ do {
+ movq_m2r (*ref, mm2);
+ movq_r2r (mm0, mm5);
+
+ movq_m2r (*(ref+1), mm3);
+ movq_r2r (mm2, mm6);
+
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm3, mm2);
+
+ por_r2r (mm6, mm7);
+ pxor_r2r (mm2, mm5);
+
+ pand_r2r (mm5, mm7);
+ pavg_r2r (mm2, mm0);
+
+ pand_m2r (mask_one, mm7);
+
+ psubusb_r2r (mm7, mm0);
+
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+
+ movq_r2r (mm6, mm7); // unroll !
+ movq_r2r (mm2, mm0); // unroll !
+ } while (--height);
+}
+
+static inline void MC_put4_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+stride+1), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+1), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_r2m (mm0, *dest);
+
+ movq_m2r (*(ref+8), mm0);
+ movq_m2r (*(ref+stride+9), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+9), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride+8), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ ref += stride;
+ movq_r2m (mm0, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg4_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+stride+1), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+1), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_m2r (*dest, mm1);
+ pavg_r2r (mm1, mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg4_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+stride+1), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+1), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_m2r (*dest, mm1);
+ pavg_r2r (mm1, mm0);
+ movq_r2m (mm0, *dest);
+
+ movq_m2r (*(ref+8), mm0);
+ movq_m2r (*(ref+stride+9), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+9), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride+8), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_m2r (*(dest+8), mm1);
+ pavg_r2r (mm1, mm0);
+ ref += stride;
+ movq_r2m (mm0, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static void MC_avg_16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_put_16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_16 (height, dest, ref, stride);
+}
+
+static void MC_put_8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_8 (height, dest, ref, stride);
+}
+
+static void MC_avg_x16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_avg_x8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_put_x16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_put_x8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_avg_y16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_y8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_put_y16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_put_y8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_xy16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_xy8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_put_xy16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_put_xy8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+
+MOTION_COMP_EXTERN (mmxext)
+
+
+
+static void MC_avg_16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_avg_8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_put_16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_16 (height, dest, ref, stride);
+}
+
+static void MC_put_8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_8 (height, dest, ref, stride);
+}
+
+static void MC_avg_x16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_avg_x8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_put_x16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_put_x8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_avg_y16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_avg_y8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_put_y16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_put_y8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_avg_xy16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_avg_xy8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_put_xy16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_16 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_put_xy8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_8 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+
+MOTION_COMP_EXTERN (3dnow)
+
+#endif
diff --git a/libmpeg2/mpeg2.h b/libmpeg2/mpeg2.h
new file mode 100644
index 0000000000..68f74289c8
--- /dev/null
+++ b/libmpeg2/mpeg2.h
@@ -0,0 +1,57 @@
+/*
+ * mpeg2.h
+ *
+ * Copyright (C) Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - Mar 2000
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation,
+ *
+ */
+
+#ifdef __OMS__
+#include <oms/plugin/output_video.h>
+#ifndef vo_functions_t
+#define vo_functions_t plugin_output_video_t
+#endif
+#else
+//FIXME normally I wouldn't nest includes, but we'll leave this here until I get
+//another chance to move things around
+#include "video_out.h"
+#endif
+
+#include <inttypes.h>
+#ifdef __OMS__
+#include <oms/accel.h>
+#else
+#include "mm_accel.h"
+#endif
+
+//config flags
+#define MPEG2_MLIB_ENABLE MM_ACCEL_MLIB
+#define MPEG2_MMX_ENABLE MM_ACCEL_X86_MMX
+#define MPEG2_3DNOW_ENABLE MM_ACCEL_X86_3DNOW
+#define MPEG2_SSE_ENABLE MM_ACCEL_X86_MMXEXT
+
+//typedef struct mpeg2_config_s {
+// //Bit flags that enable various things
+// uint32_t flags;
+//} mpeg2_config_t;
+
+void mpeg2_init (void);
+//void mpeg2_allocate_image_buffers (picture_t * picture);
+int mpeg2_decode_data (vo_functions_t *, uint8_t * data_start, uint8_t * data_end);
+//void mpeg2_close (vo_functions_t *);
+void mpeg2_drop (int flag);
diff --git a/libmpeg2/mpeg2_internal.h b/libmpeg2/mpeg2_internal.h
new file mode 100644
index 0000000000..290bb22450
--- /dev/null
+++ b/libmpeg2/mpeg2_internal.h
@@ -0,0 +1,220 @@
+#include <inttypes.h>
+/*
+ * mpeg2_internal.h
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+// hack mode - temporary
+// 0 = decode B pictures in a small slice buffer, display slice per slice
+// 1 = decode in a frame buffer, display slice per slice
+// 2 = decode in a frame buffer, display whole frames
+#define HACK_MODE 0
+
+// macroblock modes
+#define MACROBLOCK_INTRA 1
+#define MACROBLOCK_PATTERN 2
+#define MACROBLOCK_MOTION_BACKWARD 4
+#define MACROBLOCK_MOTION_FORWARD 8
+#define MACROBLOCK_QUANT 16
+#define DCT_TYPE_INTERLACED 32
+// motion_type
+#define MOTION_TYPE_MASK (3*64)
+#define MOTION_TYPE_BASE 64
+#define MC_FIELD (1*64)
+#define MC_FRAME (2*64)
+#define MC_16X8 (2*64)
+#define MC_DMV (3*64)
+
+//picture structure
+#define TOP_FIELD 1
+#define BOTTOM_FIELD 2
+#define FRAME_PICTURE 3
+
+//picture coding type
+#define I_TYPE 1
+#define P_TYPE 2
+#define B_TYPE 3
+#define D_TYPE 4
+
+//The picture struct contains all of the top level state
+//information (ie everything except slice and macroblock
+//state)
+typedef struct picture_s {
+ //-- sequence header stuff --
+ uint8_t intra_quantizer_matrix [64];
+ uint8_t non_intra_quantizer_matrix [64];
+
+ //The width and height of the picture snapped to macroblock units
+ int coded_picture_width;
+ int coded_picture_height;
+
+ //-- picture header stuff --
+
+ //what type of picture this is (I,P,or B) D from MPEG-1 isn't supported
+ int picture_coding_type;
+
+ //-- picture coding extension stuff --
+
+ //quantization factor for motion vectors
+ int f_code[2][2];
+ //quantization factor for intra dc coefficients
+ int intra_dc_precision;
+ //top/bottom/both fields
+ int picture_structure;
+ //bool to indicate all predictions are frame based
+ int frame_pred_frame_dct;
+ //bool to indicate whether intra blocks have motion vectors
+ // (for concealment)
+ int concealment_motion_vectors;
+ //bit to indicate which quantization table to use
+ int q_scale_type;
+ //bool to use different vlc tables
+ int intra_vlc_format;
+
+ //last macroblock in the picture
+ int last_mba;
+ //width of picture in macroblocks
+ int mb_width;
+
+ //stuff derived from bitstream
+
+ //pointer to the zigzag scan we're supposed to be using
+ uint8_t * scan;
+
+ //Pointer to the current planar frame buffer (Y,Cr,CB)
+ uint8_t * current_frame[3];
+ //storage for reference frames plus a b-frame
+ uint8_t * forward_reference_frame[3];
+ uint8_t * backward_reference_frame[3];
+ uint8_t * throwaway_frame[3];
+ uint8_t * pp_frame[3]; // postprocess
+ //uint8_t * throwaway_frame;
+
+ int pp_options; // postprocess
+
+ int second_field;
+
+ // MPEG1 - testing
+ uint8_t mpeg1;
+
+ //these things are not needed by the decoder
+ //NOTICE : this is a temporary interface, we will build a better one later.
+ int aspect_ratio_information;
+ int frame_rate_code;
+ int progressive_sequence;
+ int top_field_first; // this one is actually used for DMV MC
+ int repeat_first_field;
+ int progressive_frame;
+ // added by A'rpi/ESP-team:
+ int repeat_count;
+ int bitrate;
+ int frame_rate;
+ int display_picture_width;
+ int display_picture_height;
+} picture_t;
+
+typedef struct motion_s {
+ uint8_t * ref[2][3];
+ int pmv[2][2];
+ int f_code[2];
+} motion_t;
+
+// state that is carried from one macroblock to the next inside of a same slice
+typedef struct slice_s {
+ // bit parsing stuff
+ uint32_t bitstream_buf; // current 32 bit working set of buffer
+ int bitstream_bits; // used bits in working set
+ uint8_t * bitstream_ptr; // buffer with stream data
+
+ //Motion vectors
+ //The f_ and b_ correspond to the forward and backward motion
+ //predictors
+ motion_t b_motion;
+ motion_t f_motion;
+
+ // predictor for DC coefficients in intra blocks
+ int16_t dc_dct_pred[3];
+
+ uint16_t quantizer_scale; // remove
+} slice_t;
+
+typedef struct mpeg2_config_s {
+ //Bit flags that enable various things
+ uint32_t flags;
+} mpeg2_config_t;
+
+//The only global variable,
+//the config struct
+extern mpeg2_config_t config;
+
+
+
+// slice.c
+void header_state_init (picture_t * picture);
+int header_process_picture_header (picture_t * picture, uint8_t * buffer);
+int header_process_sequence_header (picture_t * picture, uint8_t * buffer);
+int header_process_extension (picture_t * picture, uint8_t * buffer);
+
+// idct.c
+void idct_init (void);
+
+// idct_mlib.c
+void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride);
+void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride);
+
+// idct_mmx.c
+void idct_block_copy_mmxext (int16_t *block, uint8_t * dest, int stride);
+void idct_block_add_mmxext (int16_t *block, uint8_t * dest, int stride);
+void idct_block_copy_mmx (int16_t *block, uint8_t * dest, int stride);
+void idct_block_add_mmx (int16_t *block, uint8_t * dest, int stride);
+void idct_mmx_init (void);
+
+// motion_comp.c
+void motion_comp_init (void);
+
+typedef struct mc_functions_s
+{
+ void (* put [8]) (uint8_t *dst, uint8_t *, int32_t, int32_t);
+ void (* avg [8]) (uint8_t *dst, uint8_t *, int32_t, int32_t);
+} mc_functions_t;
+
+#define MOTION_COMP_EXTERN(x) mc_functions_t mc_functions_##x = \
+{ \
+ {MC_put_16_##x, MC_put_x16_##x, MC_put_y16_##x, MC_put_xy16_##x, \
+ MC_put_8_##x, MC_put_x8_##x, MC_put_y8_##x, MC_put_xy8_##x}, \
+ {MC_avg_16_##x, MC_avg_x16_##x, MC_avg_y16_##x, MC_avg_xy16_##x, \
+ MC_avg_8_##x, MC_avg_x8_##x, MC_avg_y8_##x, MC_avg_xy8_##x} \
+};
+
+extern mc_functions_t mc_functions_c;
+extern mc_functions_t mc_functions_mmx;
+extern mc_functions_t mc_functions_mmxext;
+extern mc_functions_t mc_functions_3dnow;
+extern mc_functions_t mc_functions_mlib;
+
+// slice.c
+int slice_process (picture_t *picture, uint8_t code, uint8_t * buffer);
+
+// stats.c
+void stats_header (uint8_t code, uint8_t * buffer);
+
+#define MBC 45
+#define MBR 36
+extern int quant_store[MBR+1][MBC+1]; // [Review]
+
diff --git a/libmpeg2/slice.c b/libmpeg2/slice.c
new file mode 100644
index 0000000000..13940b3387
--- /dev/null
+++ b/libmpeg2/slice.c
@@ -0,0 +1,1797 @@
+/*
+ * slice.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+
+extern mc_functions_t mc_functions;
+extern void (* idct_block_copy) (int16_t * block, uint8_t * dest, int stride);
+extern void (* idct_block_add) (int16_t * block, uint8_t * dest, int stride);
+
+static int16_t DCTblock[64] ATTR_ALIGN(16);
+
+#include "vlc.h"
+
+static int non_linear_quantizer_scale [] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 96, 104, 112
+};
+
+static inline int get_macroblock_modes (slice_t * slice, int picture_structure,
+ int picture_coding_type,
+ int frame_pred_frame_dct)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int macroblock_modes;
+ MBtab * tab;
+
+ switch (picture_coding_type) {
+ case I_TYPE:
+
+ tab = MB_I + UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, tab->len);
+ macroblock_modes = tab->modes;
+
+ if ((! frame_pred_frame_dct) && (picture_structure == FRAME_PICTURE)) {
+ macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
+ DUMPBITS (bit_buf, bits, 1);
+ }
+
+ return macroblock_modes;
+
+ case P_TYPE:
+
+ tab = MB_P + UBITS (bit_buf, 5);
+ DUMPBITS (bit_buf, bits, tab->len);
+ macroblock_modes = tab->modes;
+
+ if (picture_structure != FRAME_PICTURE) {
+ if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ }
+ return macroblock_modes;
+ } else if (frame_pred_frame_dct) {
+ if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
+ macroblock_modes |= MC_FRAME;
+ return macroblock_modes;
+ } else {
+ if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ }
+ if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
+ macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
+ DUMPBITS (bit_buf, bits, 1);
+ }
+ return macroblock_modes;
+ }
+
+ case B_TYPE:
+
+ tab = MB_B + UBITS (bit_buf, 6);
+ DUMPBITS (bit_buf, bits, tab->len);
+ macroblock_modes = tab->modes;
+
+ if (picture_structure != FRAME_PICTURE) {
+ if (! (macroblock_modes & MACROBLOCK_INTRA)) {
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ }
+ return macroblock_modes;
+ } else if (frame_pred_frame_dct) {
+ //if (! (macroblock_modes & MACROBLOCK_INTRA))
+ macroblock_modes |= MC_FRAME;
+ return macroblock_modes;
+ } else {
+ if (macroblock_modes & MACROBLOCK_INTRA)
+ goto intra;
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
+ intra:
+ macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
+ DUMPBITS (bit_buf, bits, 1);
+ }
+ return macroblock_modes;
+ }
+
+ case D_TYPE:
+
+ DUMPBITS (bit_buf, bits, 1);
+ return MACROBLOCK_INTRA;
+
+ default:
+ return 0;
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_quantizer_scale (slice_t * slice, int q_scale_type)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+
+ int quantizer_scale_code;
+
+ quantizer_scale_code = UBITS (bit_buf, 5);
+ DUMPBITS (bit_buf, bits, 5);
+
+ if (q_scale_type)
+ return non_linear_quantizer_scale [quantizer_scale_code];
+ else
+ return quantizer_scale_code << 1;
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_motion_delta (slice_t * slice, int f_code)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+
+ int delta;
+ int sign;
+ MVtab * tab;
+
+ if (bit_buf & 0x80000000) {
+ DUMPBITS (bit_buf, bits, 1);
+ return 0;
+ } else if (bit_buf >= 0x0c000000) {
+
+ tab = MV_4 + UBITS (bit_buf, 4);
+ delta = (tab->delta << f_code) + 1;
+ bits += tab->len + f_code + 1;
+ bit_buf <<= tab->len;
+
+ sign = SBITS (bit_buf, 1);
+ bit_buf <<= 1;
+
+ if (f_code)
+ delta += UBITS (bit_buf, f_code);
+ bit_buf <<= f_code;
+
+ return (delta ^ sign) - sign;
+
+ } else {
+
+ tab = MV_10 + UBITS (bit_buf, 10);
+ delta = (tab->delta << f_code) + 1;
+ bits += tab->len + 1;
+ bit_buf <<= tab->len;
+
+ sign = SBITS (bit_buf, 1);
+ bit_buf <<= 1;
+
+ if (f_code) {
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ delta += UBITS (bit_buf, f_code);
+ DUMPBITS (bit_buf, bits, f_code);
+ }
+
+ return (delta ^ sign) - sign;
+
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int bound_motion_vector (int vector, int f_code)
+{
+#if 1
+ int limit;
+
+ limit = 16 << f_code;
+
+ if (vector >= limit)
+ return vector - 2*limit;
+ else if (vector < -limit)
+ return vector + 2*limit;
+ else return vector;
+#else
+ return (vector << (27 - f_code)) >> (27 - f_code);
+#endif
+}
+
+static inline int get_dmv (slice_t * slice)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+
+ DMVtab * tab;
+
+ tab = DMV_2 + UBITS (bit_buf, 2);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return tab->dmv;
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_coded_block_pattern (slice_t * slice)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+
+ CBPtab * tab;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ if (bit_buf >= 0x20000000) {
+
+ tab = CBP_7 - 16 + UBITS (bit_buf, 7);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return tab->cbp;
+
+ } else {
+
+ tab = CBP_9 + UBITS (bit_buf, 9);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return tab->cbp;
+ }
+
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_luma_dc_dct_diff (slice_t * slice)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ DCtab * tab;
+ int size;
+ int dc_diff;
+
+ if (bit_buf < 0xf8000000) {
+ tab = DC_lum_5 + UBITS (bit_buf, 5);
+ size = tab->size;
+ if (size) {
+ bits += tab->len + size;
+ bit_buf <<= tab->len;
+ dc_diff =
+ UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ bit_buf <<= size;
+ return dc_diff;
+ } else {
+ DUMPBITS (bit_buf, bits, 3);
+ return 0;
+ }
+ } else {
+ tab = DC_long - 0x1e0 + UBITS (bit_buf, 9);
+ size = tab->size;
+ DUMPBITS (bit_buf, bits, tab->len);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ DUMPBITS (bit_buf, bits, size);
+ return dc_diff;
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_chroma_dc_dct_diff (slice_t * slice)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ DCtab * tab;
+ int size;
+ int dc_diff;
+
+ if (bit_buf < 0xf8000000) {
+ tab = DC_chrom_5 + UBITS (bit_buf, 5);
+ size = tab->size;
+ if (size) {
+ bits += tab->len + size;
+ bit_buf <<= tab->len;
+ dc_diff =
+ UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ bit_buf <<= size;
+ return dc_diff;
+ } else {
+ DUMPBITS (bit_buf, bits, 2);
+ return 0;
+ }
+ } else {
+ tab = DC_long - 0x3e0 + UBITS (bit_buf, 10);
+ size = tab->size;
+ DUMPBITS (bit_buf, bits, tab->len + 1);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ DUMPBITS (bit_buf, bits, size);
+ return dc_diff;
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+#define SATURATE(val) \
+do { \
+ if (val > 2047) \
+ val = 2047; \
+ else if (val < -2048) \
+ val = -2048; \
+} while (0)
+
+static void get_intra_block_B14 (picture_t * picture, slice_t * slice,
+ int16_t * dest)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = slice->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+
+ i = 0;
+ mismatch = ~dest[0];
+
+ bit_buf = slice->bitstream_buf;
+ bits = slice->bitstream_bits;
+ bit_ptr = slice->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ i += tab->run;
+ if (i >= 64)
+ break; // end of block
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+
+ // if (bitstream_get (1)) val = -val;
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ // escape code
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; // illegal, but check needed to avoid buffer overflow
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = (SBITS (bit_buf, 12) *
+ quantizer_scale * quant_matrix[j]) / 16;
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; // illegal, but check needed to avoid buffer overflow
+ }
+ dest[63] ^= mismatch & 1;
+ DUMPBITS (bit_buf, bits, 2); // dump end of block code
+ slice->bitstream_buf = bit_buf;
+ slice->bitstream_bits = bits;
+ slice->bitstream_ptr = bit_ptr;
+}
+
+static void get_intra_block_B15 (picture_t * picture, slice_t * slice,
+ int16_t * dest)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = slice->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+
+ i = 0;
+ mismatch = ~dest[0];
+
+ bit_buf = slice->bitstream_buf;
+ bits = slice->bitstream_bits;
+ bit_ptr = slice->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ while (1) {
+ if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B15_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64) {
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+
+ // if (bitstream_get (1)) val = -val;
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else {
+
+ // end of block. I commented out this code because if we
+ // dont exit here we will still exit at the later test :)
+
+ //if (i >= 128) break; // end of block
+
+ // escape code
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; // illegal, but check against buffer overflow
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = (SBITS (bit_buf, 12) *
+ quantizer_scale * quant_matrix[j]) / 16;
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ }
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B15_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; // illegal, but check needed to avoid buffer overflow
+ }
+ dest[63] ^= mismatch & 1;
+ DUMPBITS (bit_buf, bits, 4); // dump end of block code
+ slice->bitstream_buf = bit_buf;
+ slice->bitstream_bits = bits;
+ slice->bitstream_ptr = bit_ptr;
+}
+
+static void get_non_intra_block (picture_t * picture, slice_t * slice,
+ int16_t * dest)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->non_intra_quantizer_matrix;
+ int quantizer_scale = slice->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+
+ i = -1;
+ mismatch = 1;
+
+ bit_buf = slice->bitstream_buf;
+ bits = slice->bitstream_bits;
+ bit_ptr = slice->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ if (bit_buf >= 0x28000000) {
+ tab = DCT_B14DC_5 - 5 + UBITS (bit_buf, 5);
+ goto entry_1;
+ } else
+ goto entry_2;
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ entry_1:
+ i += tab->run;
+ if (i >= 64)
+ break; // end of block
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5;
+
+ // if (bitstream_get (1)) val = -val;
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ }
+
+ entry_2:
+ if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ // escape code
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; // illegal, but check needed to avoid buffer overflow
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1;
+ val = (val * quantizer_scale * quant_matrix[j]) / 32;
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; // illegal, but check needed to avoid buffer overflow
+ }
+ dest[63] ^= mismatch & 1;
+ DUMPBITS (bit_buf, bits, 2); // dump end of block code
+ slice->bitstream_buf = bit_buf;
+ slice->bitstream_bits = bits;
+ slice->bitstream_ptr = bit_ptr;
+}
+
+static void get_mpeg1_intra_block (picture_t * picture, slice_t * slice,
+ int16_t * dest)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = slice->quantizer_scale;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+
+ i = 0;
+
+ bit_buf = slice->bitstream_buf;
+ bits = slice->bitstream_bits;
+ bit_ptr = slice->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ i += tab->run;
+ if (i >= 64)
+ break; // end of block
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+
+ // oddification
+ val = (val - 1) | 1;
+
+ // if (bitstream_get (1)) val = -val;
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ // escape code
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; // illegal, but check needed to avoid buffer overflow
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = SBITS (bit_buf, 8);
+ if (! (val & 0x7f)) {
+ DUMPBITS (bit_buf, bits, 8);
+ val = UBITS (bit_buf, 8) + 2 * val;
+ }
+ val = (val * quantizer_scale * quant_matrix[j]) / 16;
+
+ // oddification
+ val = (val + ~SBITS (val, 1)) | 1;
+
+ SATURATE (val);
+ dest[j] = val;
+
+ DUMPBITS (bit_buf, bits, 8);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; // illegal, but check needed to avoid buffer overflow
+ }
+ DUMPBITS (bit_buf, bits, 2); // dump end of block code
+ slice->bitstream_buf = bit_buf;
+ slice->bitstream_bits = bits;
+ slice->bitstream_ptr = bit_ptr;
+}
+
+static void get_mpeg1_non_intra_block (picture_t * picture, slice_t * slice,
+ int16_t * dest)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->non_intra_quantizer_matrix;
+ int quantizer_scale = slice->quantizer_scale;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+
+ i = -1;
+
+ bit_buf = slice->bitstream_buf;
+ bits = slice->bitstream_bits;
+ bit_ptr = slice->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ if (bit_buf >= 0x28000000) {
+ tab = DCT_B14DC_5 - 5 + UBITS (bit_buf, 5);
+ goto entry_1;
+ } else
+ goto entry_2;
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ entry_1:
+ i += tab->run;
+ if (i >= 64)
+ break; // end of block
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5;
+
+ // oddification
+ val = (val - 1) | 1;
+
+ // if (bitstream_get (1)) val = -val;
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ }
+
+ entry_2:
+ if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ // escape code
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; // illegal, but check needed to avoid buffer overflow
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = SBITS (bit_buf, 8);
+ if (! (val & 0x7f)) {
+ DUMPBITS (bit_buf, bits, 8);
+ val = UBITS (bit_buf, 8) + 2 * val;
+ }
+ val = 2 * (val + SBITS (val, 1)) + 1;
+ val = (val * quantizer_scale * quant_matrix[j]) / 32;
+
+ // oddification
+ val = (val + ~SBITS (val, 1)) | 1;
+
+ SATURATE (val);
+ dest[j] = val;
+
+ DUMPBITS (bit_buf, bits, 8);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; // illegal, but check needed to avoid buffer overflow
+ }
+ DUMPBITS (bit_buf, bits, 2); // dump end of block code
+ slice->bitstream_buf = bit_buf;
+ slice->bitstream_bits = bits;
+ slice->bitstream_ptr = bit_ptr;
+}
+
+static inline int get_macroblock_address_increment (slice_t * slice)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+
+ MBAtab * tab;
+ int mba;
+
+ mba = 0;
+
+ while (1) {
+ if (bit_buf >= 0x10000000) {
+ tab = MBA_5 - 2 + UBITS (bit_buf, 5);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return mba + tab->mba;
+ } else if (bit_buf >= 0x03000000) {
+ tab = MBA_11 - 24 + UBITS (bit_buf, 11);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return mba + tab->mba;
+ } else switch (UBITS (bit_buf, 11)) {
+ case 8: // macroblock_escape
+ mba += 33;
+ // no break here on purpose
+ case 15: // macroblock_stuffing (MPEG1 only)
+ DUMPBITS (bit_buf, bits, 11);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ break;
+ default: // end of slice, or error
+ return 0;
+ }
+ }
+
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline void slice_intra_DCT (picture_t * picture, slice_t * slice,
+ int cc, uint8_t * dest, int stride)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ //Get the intra DC coefficient and inverse quantize it
+ if (cc == 0)
+ slice->dc_dct_pred[0] += get_luma_dc_dct_diff (slice);
+ else
+ slice->dc_dct_pred[cc] += get_chroma_dc_dct_diff (slice);
+ DCTblock[0] = slice->dc_dct_pred[cc] << (3 - picture->intra_dc_precision);
+
+ if (picture->mpeg1) {
+ if (picture->picture_coding_type != D_TYPE)
+ get_mpeg1_intra_block (picture, slice, DCTblock);
+ } else if (picture->intra_vlc_format)
+ get_intra_block_B15 (picture, slice, DCTblock);
+ else
+ get_intra_block_B14 (picture, slice, DCTblock);
+ idct_block_copy (DCTblock, dest, stride);
+ memset (DCTblock, 0, sizeof (DCTblock));
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline void slice_non_intra_DCT (picture_t * picture, slice_t * slice,
+ uint8_t * dest, int stride)
+{
+ if (picture->mpeg1)
+ get_mpeg1_non_intra_block (picture, slice, DCTblock);
+ else
+ get_non_intra_block (picture, slice, DCTblock);
+ idct_block_add (DCTblock, dest, stride);
+ memset (DCTblock, 0, sizeof (DCTblock));
+}
+
+static inline void motion_block (void (** table) (uint8_t *, uint8_t *,
+ int32_t, int32_t),
+ int x_pred, int y_pred,
+ uint8_t * dest[3], int dest_offset,
+ uint8_t * src[3], int src_offset,
+ int stride, int height, int second_half)
+{
+ int xy_half;
+ uint8_t * src1;
+ uint8_t * src2;
+
+ xy_half = ((y_pred & 1) << 1) | (x_pred & 1);
+
+ src1 = src[0] + src_offset + (x_pred >> 1) + (y_pred >> 1) * stride +
+ second_half * (stride << 3);
+
+ table[xy_half] (dest[0] + dest_offset + second_half * (stride << 3),
+ src1, stride, height);
+
+ x_pred /= 2;
+ y_pred /= 2;
+
+ xy_half = ((y_pred & 1) << 1) | (x_pred & 1);
+ stride >>= 1;
+ height >>= 1;
+ src_offset >>= 1; src_offset += second_half * (stride << 2);
+ dest_offset >>= 1; dest_offset += second_half * (stride << 2);
+
+ src1 = src[1] + src_offset + (x_pred >> 1) + (y_pred >> 1) * stride;
+ src2 = src[2] + src_offset + (x_pred >> 1) + (y_pred >> 1) * stride;
+
+ table[4+xy_half] (dest[1] + dest_offset, src1, stride, height);
+ table[4+xy_half] (dest[2] + dest_offset, src2, stride, height);
+}
+
+
+static void motion_mp1 (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[0]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[0]);
+ motion->pmv[0][1] = motion_y;
+
+ if (motion->f_code[1]) {
+ motion_x <<= 1;
+ motion_y <<= 1;
+ }
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[0], offset, width, 16, 0);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_mp1_reuse (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ int motion_x, motion_y;
+
+ motion_x = motion->pmv[0][0];
+ motion_y = motion->pmv[0][1];
+
+ if (motion->f_code[1]) {
+ motion_x <<= 1;
+ motion_y <<= 1;
+ }
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[0], offset, width, 16, 0);
+}
+
+static void motion_fr_frame (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[0], offset, width, 16, 0);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fr_field (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+ int field_select;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = SBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (slice,
+ motion->f_code[1]);
+ //motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[0][1] = motion_y << 1;
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[0], offset + (field_select & width),
+ width * 2, 8, 0);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = SBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ motion_x = motion->pmv[1][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (slice,
+ motion->f_code[1]);
+ //motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion_y << 1;
+
+ motion_block (table, motion_x, motion_y, dest, offset + width,
+ motion->ref[0], offset + (field_select & width),
+ width * 2, 8, 0);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static int motion_dmv_top_field_first;
+static void motion_fr_dmv (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+ int dmv_x, dmv_y;
+ int m;
+ int other_x, other_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_x = get_dmv (slice);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (slice,
+ motion->f_code[1]);
+ //motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_y = get_dmv (slice);
+
+ motion_block (mc_functions.put, motion_x, motion_y, dest, offset,
+ motion->ref[0], offset, width * 2, 8, 0);
+
+ m = motion_dmv_top_field_first ? 1 : 3;
+ other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x;
+ other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1;
+ motion_block (mc_functions.avg, other_x, other_y, dest, offset,
+ motion->ref[0], offset + width, width * 2, 8, 0);
+
+ motion_block (mc_functions.put, motion_x, motion_y, dest, offset + width,
+ motion->ref[0], offset + width, width * 2, 8, 0);
+
+ m = motion_dmv_top_field_first ? 3 : 1;
+ other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x;
+ other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1;
+ motion_block (mc_functions.avg, other_x, other_y, dest, offset + width,
+ motion->ref[0], offset, width * 2, 8, 0);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+// like motion_frame, but reuse previous motion vectors
+static void motion_fr_reuse (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, motion->pmv[0][0], motion->pmv[0][1], dest, offset,
+ motion->ref[0], offset, width, 16, 0);
+}
+
+// like motion_frame, but use null motion vectors
+static void motion_fr_zero (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, 0, 0, dest, offset,
+ motion->ref[0], offset, width, 16, 0);
+}
+
+// like motion_frame, but parsing without actual motion compensation
+static void motion_fr_conceal (slice_t * slice, motion_t * motion)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ tmp = bound_motion_vector (tmp, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[1]);
+ tmp = bound_motion_vector (tmp, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = tmp;
+
+ DUMPBITS (bit_buf, bits, 1); // remove marker_bit
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_field (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+ int field_select;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[field_select], offset, width, 16, 0);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_16x8 (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+ int field_select;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[0][1] = motion_y;
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[field_select], offset, width, 8, 0);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[1][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[1][1] + get_motion_delta (slice, motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion_y;
+
+ motion_block (table, motion_x, motion_y, dest, offset,
+ motion->ref[field_select], offset, width, 8, 1);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static int current_field = 0;
+static void motion_fi_dmv (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int motion_x, motion_y;
+ int dmv_x, dmv_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_x = get_dmv (slice);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_y = get_dmv (slice);
+
+ motion_block (mc_functions.put, motion_x, motion_y, dest, offset,
+ motion->ref[current_field], offset, width, 16, 0);
+
+ motion_x = ((motion_x + (motion_x > 0)) >> 1) + dmv_x;
+ motion_y = ((motion_y + (motion_y > 0)) >> 1) + dmv_y +
+ 2 * current_field - 1;
+ motion_block (mc_functions.avg, motion_x, motion_y, dest, offset,
+ motion->ref[!current_field], offset, width, 16, 0);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_reuse (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, motion->pmv[0][0], motion->pmv[0][1], dest, offset,
+ motion->ref[current_field], offset, width, 16, 0);
+}
+
+static void motion_fi_zero (slice_t * slice, motion_t * motion,
+ uint8_t * dest[3], int offset, int width,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, 0, 0, dest, offset,
+ motion->ref[current_field], offset, width, 16, 0);
+}
+
+static void motion_fi_conceal (slice_t * slice, motion_t * motion)
+{
+#define bit_buf (slice->bitstream_buf)
+#define bits (slice->bitstream_bits)
+#define bit_ptr (slice->bitstream_ptr)
+ int tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ DUMPBITS (bit_buf, bits, 1); // remove field_select
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = motion->pmv[0][0] + get_motion_delta (slice, motion->f_code[0]);
+ tmp = bound_motion_vector (tmp, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = motion->pmv[0][1] + get_motion_delta (slice, motion->f_code[1]);
+ tmp = bound_motion_vector (tmp, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = tmp;
+
+ DUMPBITS (bit_buf, bits, 1); // remove marker_bit
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+#define MOTION(routine,direction,slice,dest,offset,stride) \
+do { \
+ if ((direction) & MACROBLOCK_MOTION_FORWARD) \
+ routine (&slice, &((slice).f_motion), dest, offset, stride, \
+ mc_functions.put); \
+ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \
+ routine (&slice, &((slice).b_motion), dest, offset, stride, \
+ ((direction) & MACROBLOCK_MOTION_FORWARD ? \
+ mc_functions.avg : mc_functions.put)); \
+} while (0)
+
+#define CHECK_DISPLAY \
+do { \
+ if (offset == width) { \
+ slice.f_motion.ref[0][0] += 16 * offset; \
+ slice.f_motion.ref[0][1] += 4 * offset; \
+ slice.f_motion.ref[0][2] += 4 * offset; \
+ slice.b_motion.ref[0][0] += 16 * offset; \
+ slice.b_motion.ref[0][1] += 4 * offset; \
+ slice.b_motion.ref[0][2] += 4 * offset; \
+ dest[0] += 16 * offset; \
+ dest[1] += 4 * offset; \
+ dest[2] += 4 * offset; \
+ offset = 0; ++ypos; \
+ } \
+} while (0)
+
+int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
+{
+#define bit_buf (slice.bitstream_buf)
+#define bits (slice.bitstream_bits)
+#define bit_ptr (slice.bitstream_ptr)
+ slice_t slice;
+ int macroblock_modes;
+ int width;
+ int ypos=code-1;
+ uint8_t * dest[3];
+ int offset;
+ uint8_t ** forward_ref[2];
+
+ width = picture->coded_picture_width;
+ offset = ypos * width * 4;
+
+ forward_ref[0] = picture->forward_reference_frame;
+ if (picture->picture_structure != FRAME_PICTURE) {
+ offset <<= 1;
+ forward_ref[1] = picture->forward_reference_frame;
+ current_field = (picture->picture_structure == BOTTOM_FIELD);
+ if ((picture->second_field) &&
+ (picture->picture_coding_type != B_TYPE))
+ forward_ref[picture->picture_structure == TOP_FIELD] =
+ picture->current_frame;
+ slice.f_motion.ref[1][0] = forward_ref[1][0] + offset * 4 + width;
+ slice.f_motion.ref[1][1] = forward_ref[1][1] + offset + (width >> 1);
+ slice.f_motion.ref[1][2] = forward_ref[1][2] + offset + (width >> 1);
+ slice.b_motion.ref[1][0] =
+ picture->backward_reference_frame[0] + offset * 4 + width;
+ slice.b_motion.ref[1][1] =
+ picture->backward_reference_frame[1] + offset + (width >> 1);
+ slice.b_motion.ref[1][2] =
+ picture->backward_reference_frame[2] + offset + (width >> 1);
+ }
+
+ slice.f_motion.ref[0][0] = forward_ref[0][0] + offset * 4;
+ slice.f_motion.ref[0][1] = forward_ref[0][1] + offset;
+ slice.f_motion.ref[0][2] = forward_ref[0][2] + offset;
+ slice.f_motion.f_code[0] = picture->f_code[0][0];
+ slice.f_motion.f_code[1] = picture->f_code[0][1];
+ slice.f_motion.pmv[0][0] = slice.f_motion.pmv[0][1] = 0;
+ slice.f_motion.pmv[1][0] = slice.f_motion.pmv[1][1] = 0;
+ slice.b_motion.ref[0][0] =
+ picture->backward_reference_frame[0] + offset * 4;
+ slice.b_motion.ref[0][1] =
+ picture->backward_reference_frame[1] + offset;
+ slice.b_motion.ref[0][2] =
+ picture->backward_reference_frame[2] + offset;
+ slice.b_motion.f_code[0] = picture->f_code[1][0];
+ slice.b_motion.f_code[1] = picture->f_code[1][1];
+ slice.b_motion.pmv[0][0] = slice.b_motion.pmv[0][1] = 0;
+ slice.b_motion.pmv[1][0] = slice.b_motion.pmv[1][1] = 0;
+
+ if ((! HACK_MODE) && (!picture->mpeg1) &&
+ (picture->picture_coding_type == B_TYPE))
+ offset = 0;
+
+ dest[0] = picture->current_frame[0] + offset * 4;
+ dest[1] = picture->current_frame[1] + offset;
+ dest[2] = picture->current_frame[2] + offset;
+
+ switch (picture->picture_structure) {
+ case BOTTOM_FIELD:
+ dest[0] += width;
+ dest[1] += width >> 1;
+ dest[2] += width >> 1;
+ // follow thru
+ case TOP_FIELD:
+ width <<= 1;
+ }
+
+ //reset intra dc predictor
+ slice.dc_dct_pred[0]=slice.dc_dct_pred[1]=slice.dc_dct_pred[2]=
+ 1<< (picture->intra_dc_precision + 7) ;
+
+ bitstream_init (&slice, buffer);
+
+ slice.quantizer_scale = get_quantizer_scale (&slice,
+ picture->q_scale_type);
+
+ //Ignore intra_slice and all the extra data
+ while (bit_buf & 0x80000000) {
+ DUMPBITS (bit_buf, bits, 9);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ }
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ offset = get_macroblock_address_increment (&slice) << 4;
+
+ while (1) {
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ macroblock_modes =
+ get_macroblock_modes (&slice, picture->picture_structure,
+ picture->picture_coding_type,
+ picture->frame_pred_frame_dct);
+
+ // maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ?
+ if (macroblock_modes & MACROBLOCK_QUANT)
+ slice.quantizer_scale =
+ get_quantizer_scale (&slice, picture->q_scale_type);
+
+ if (macroblock_modes & MACROBLOCK_INTRA) {
+
+ int DCT_offset, DCT_stride;
+
+ if (picture->concealment_motion_vectors) {
+ if (picture->picture_structure == FRAME_PICTURE)
+ motion_fr_conceal (&slice, &slice.f_motion);
+ else
+ motion_fi_conceal (&slice, &slice.f_motion);
+ } else {
+ slice.f_motion.pmv[0][0] = slice.f_motion.pmv[0][1] = 0;
+ slice.f_motion.pmv[1][0] = slice.f_motion.pmv[1][1] = 0;
+ slice.b_motion.pmv[0][0] = slice.b_motion.pmv[0][1] = 0;
+ slice.b_motion.pmv[1][0] = slice.b_motion.pmv[1][1] = 0;
+ }
+
+ if (macroblock_modes & DCT_TYPE_INTERLACED) {
+ DCT_offset = width;
+ DCT_stride = width * 2;
+ } else {
+ DCT_offset = width * 8;
+ DCT_stride = width;
+ }
+
+ // Decode lum blocks
+ slice_intra_DCT (picture, &slice, 0,
+ dest[0] + offset, DCT_stride);
+ slice_intra_DCT (picture, &slice, 0,
+ dest[0] + offset + 8, DCT_stride);
+ slice_intra_DCT (picture, &slice, 0,
+ dest[0] + offset + DCT_offset, DCT_stride);
+ slice_intra_DCT (picture, &slice, 0,
+ dest[0] + offset + DCT_offset + 8, DCT_stride);
+
+ // Decode chroma blocks
+ slice_intra_DCT (picture, &slice, 1,
+ dest[1] + (offset>>1), width>>1);
+ slice_intra_DCT (picture, &slice, 2,
+ dest[2] + (offset>>1), width>>1);
+
+ if (picture->picture_coding_type == D_TYPE) {
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ DUMPBITS (bit_buf, bits, 1);
+ }
+ } else {
+
+ if (picture->mpeg1) {
+ if ((macroblock_modes & MOTION_TYPE_MASK) == MC_FRAME)
+ MOTION (motion_mp1, macroblock_modes, slice,
+ dest, offset,width);
+ else {
+ // non-intra mb without forward mv in a P picture
+ slice.f_motion.pmv[0][0] = slice.f_motion.pmv[0][1] = 0;
+ slice.f_motion.pmv[1][0] = slice.f_motion.pmv[1][1] = 0;
+
+ MOTION (motion_fr_zero, MACROBLOCK_MOTION_FORWARD, slice,
+ dest, offset, width);
+ }
+ } else if (picture->picture_structure == FRAME_PICTURE)
+ switch (macroblock_modes & MOTION_TYPE_MASK) {
+ case MC_FRAME:
+ MOTION (motion_fr_frame, macroblock_modes, slice,
+ dest, offset, width);
+ break;
+
+ case MC_FIELD:
+ MOTION (motion_fr_field, macroblock_modes, slice,
+ dest, offset, width);
+ break;
+
+ case MC_DMV:
+ motion_dmv_top_field_first = picture->top_field_first;
+ MOTION (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD, slice,
+ dest, offset, width);
+ break;
+
+ case 0:
+ // non-intra mb without forward mv in a P picture
+ slice.f_motion.pmv[0][0] = slice.f_motion.pmv[0][1] = 0;
+ slice.f_motion.pmv[1][0] = slice.f_motion.pmv[1][1] = 0;
+
+ MOTION (motion_fr_zero, MACROBLOCK_MOTION_FORWARD, slice,
+ dest, offset, width);
+ break;
+ }
+ else
+ switch (macroblock_modes & MOTION_TYPE_MASK) {
+ case MC_FIELD:
+ MOTION (motion_fi_field, macroblock_modes, slice,
+ dest, offset, width);
+ break;
+
+ case MC_16X8:
+ MOTION (motion_fi_16x8, macroblock_modes, slice,
+ dest, offset, width);
+ break;
+
+ case MC_DMV:
+ motion_dmv_top_field_first = picture->top_field_first;
+ MOTION (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD, slice,
+ dest, offset, width);
+ break;
+
+ case 0:
+ // non-intra mb without forward mv in a P picture
+ slice.f_motion.pmv[0][0] = slice.f_motion.pmv[0][1] = 0;
+ slice.f_motion.pmv[1][0] = slice.f_motion.pmv[1][1] = 0;
+
+ MOTION (motion_fi_zero, MACROBLOCK_MOTION_FORWARD, slice,
+ dest, offset, width);
+ break;
+ }
+
+ //6.3.17.4 Coded block pattern
+ if (macroblock_modes & MACROBLOCK_PATTERN) {
+ int coded_block_pattern;
+ int DCT_offset, DCT_stride;
+
+ if (macroblock_modes & DCT_TYPE_INTERLACED) {
+ DCT_offset = width;
+ DCT_stride = width * 2;
+ } else {
+ DCT_offset = width * 8;
+ DCT_stride = width;
+ }
+
+ coded_block_pattern = get_coded_block_pattern (&slice);
+
+ // Decode lum blocks
+
+ if (coded_block_pattern & 0x20)
+ slice_non_intra_DCT (picture, &slice,
+ dest[0] + offset, DCT_stride);
+ if (coded_block_pattern & 0x10)
+ slice_non_intra_DCT (picture, &slice,
+ dest[0] + offset + 8, DCT_stride);
+ if (coded_block_pattern & 0x08)
+ slice_non_intra_DCT (picture, &slice,
+ dest[0] + offset + DCT_offset,
+ DCT_stride);
+ if (coded_block_pattern & 0x04)
+ slice_non_intra_DCT (picture, &slice,
+ dest[0] + offset + DCT_offset + 8,
+ DCT_stride);
+
+ // Decode chroma blocks
+
+ if (coded_block_pattern & 0x2)
+ slice_non_intra_DCT (picture, &slice,
+ dest[1] + (offset>>1), width >> 1);
+ if (coded_block_pattern & 0x1)
+ slice_non_intra_DCT (picture, &slice,
+ dest[2] + (offset>>1), width >> 1);
+ }
+
+ slice.dc_dct_pred[0]=slice.dc_dct_pred[1]=slice.dc_dct_pred[2]=
+ 1 << (picture->intra_dc_precision + 7);
+ }
+
+// printf("[%d]",slice.quantizer_scale);
+// printf("[%d,%d]",offset>>4,ypos);
+ quant_store[ypos+1][(offset>>4)+1] = slice.quantizer_scale;
+
+ offset += 16;
+ CHECK_DISPLAY;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ if (bit_buf & 0x80000000) {
+ DUMPBITS (bit_buf, bits, 1);
+ } else {
+ int mba_inc;
+
+ mba_inc = get_macroblock_address_increment (&slice);
+ if (!mba_inc)
+ break;
+
+ //reset intra dc predictor on skipped block
+ slice.dc_dct_pred[0]=slice.dc_dct_pred[1]=slice.dc_dct_pred[2]=
+ 1<< (picture->intra_dc_precision + 7);
+
+ //handling of skipped mb's differs between P_TYPE and B_TYPE
+ //pictures
+ if (picture->picture_coding_type == P_TYPE) {
+ slice.f_motion.pmv[0][0] = slice.f_motion.pmv[0][1] = 0;
+ slice.f_motion.pmv[1][0] = slice.f_motion.pmv[1][1] = 0;
+
+ do {
+ if (picture->picture_structure == FRAME_PICTURE)
+ MOTION (motion_fr_zero, MACROBLOCK_MOTION_FORWARD,
+ slice, dest, offset, width);
+ else
+ MOTION (motion_fi_zero, MACROBLOCK_MOTION_FORWARD,
+ slice, dest, offset, width);
+
+ quant_store[ypos+1][(offset>>4)+1] = slice.quantizer_scale;
+// printf("[%d,%d]",offset>>4,ypos);
+ offset += 16;
+ CHECK_DISPLAY;
+ } while (--mba_inc);
+ } else {
+ do {
+ if (picture->mpeg1)
+ MOTION (motion_mp1_reuse, macroblock_modes,
+ slice, dest, offset, width);
+ else if (picture->picture_structure == FRAME_PICTURE)
+ MOTION (motion_fr_reuse, macroblock_modes,
+ slice, dest, offset, width);
+ else
+ MOTION (motion_fi_reuse, macroblock_modes,
+ slice, dest, offset, width);
+
+ quant_store[ypos+1][(offset>>4)+1] = slice.quantizer_scale;
+// printf("[%d,%d]",offset>>4,ypos);
+ offset += 16;
+ CHECK_DISPLAY;
+ } while (--mba_inc);
+ }
+ }
+ }
+
+ return 0;
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
diff --git a/libmpeg2/sse.h b/libmpeg2/sse.h
new file mode 100644
index 0000000000..51540dca08
--- /dev/null
+++ b/libmpeg2/sse.h
@@ -0,0 +1,256 @@
+/*
+ * sse.h
+ * Copyright (C) 1999 R. Fisher
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+typedef union {
+ float sf[4]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */
+
+
+#define sse_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define sse_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define sse_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define sse_r2ri(op, regs, regd, imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2ri(op, mem, reg, subop) \
+ __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg)
+#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var)
+#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd)
+
+#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var)
+
+#define movups_m2r(var, reg) sse_m2r(movups, var, reg)
+#define movups_r2m(reg, var) sse_r2m(movups, reg, var)
+#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd)
+
+#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd)
+
+#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd)
+
+#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg)
+#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var)
+
+#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg)
+#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var)
+
+#define movss_m2r(var, reg) sse_m2r(movss, var, reg)
+#define movss_r2m(reg, var) sse_r2m(movss, reg, var)
+#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd)
+
+#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index)
+#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index)
+
+#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg)
+#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg)
+
+#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg)
+#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg)
+
+#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg)
+#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg)
+
+#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg)
+#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg)
+
+#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define movmskps(xmmreg, reg) \
+ __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg)
+
+#define addps_m2r(var, reg) sse_m2r(addps, var, reg)
+#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd)
+
+#define addss_m2r(var, reg) sse_m2r(addss, var, reg)
+#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd)
+
+#define subps_m2r(var, reg) sse_m2r(subps, var, reg)
+#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd)
+
+#define subss_m2r(var, reg) sse_m2r(subss, var, reg)
+#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd)
+
+#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg)
+#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd)
+
+#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg)
+#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd)
+
+#define divps_m2r(var, reg) sse_m2r(divps, var, reg)
+#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd)
+
+#define divss_m2r(var, reg) sse_m2r(divss, var, reg)
+#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd)
+
+#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg)
+#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd)
+
+#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg)
+#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd)
+
+#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg)
+#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd)
+
+#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg)
+#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd)
+
+#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg)
+#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd)
+
+#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg)
+#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd)
+
+#define andps_m2r(var, reg) sse_m2r(andps, var, reg)
+#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd)
+
+#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg)
+#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd)
+
+#define orps_m2r(var, reg) sse_m2r(orps, var, reg)
+#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd)
+
+#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg)
+#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd)
+
+#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg)
+#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd)
+
+#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg)
+#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd)
+
+#define minps_m2r(var, reg) sse_m2r(minps, var, reg)
+#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd)
+
+#define minss_m2r(var, reg) sse_m2r(minss, var, reg)
+#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd)
+
+#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op)
+#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op)
+
+#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0)
+#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0)
+
+#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1)
+#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1)
+
+#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2)
+#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2)
+
+#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3)
+#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3)
+
+#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4)
+#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4)
+
+#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5)
+#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5)
+
+#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6)
+#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6)
+
+#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7)
+#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7)
+
+#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op)
+#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op)
+
+#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0)
+#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0)
+
+#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1)
+#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1)
+
+#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2)
+#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2)
+
+#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3)
+#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3)
+
+#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4)
+#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4)
+
+#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5)
+#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5)
+
+#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6)
+#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6)
+
+#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7)
+#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7)
+
+#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg)
+#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd)
+
+#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg)
+#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd)
+
+#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg)
+#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd)
+
+#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg)
+#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd)
+
+#define fxrstor(mem) \
+ __asm__ __volatile__ ("fxrstor %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define fxsave(mem) \
+ __asm__ __volatile__ ("fxsave %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define stmxcsr(mem) \
+ __asm__ __volatile__ ("stmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define ldmxcsr(mem) \
+ __asm__ __volatile__ ("ldmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
diff --git a/libmpeg2/stats.c b/libmpeg2/stats.c
new file mode 100644
index 0000000000..b342bef7a2
--- /dev/null
+++ b/libmpeg2/stats.c
@@ -0,0 +1,316 @@
+/*
+ * stats.c
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+
+static int debug_level = -1;
+
+// Determine is debug output is required.
+// We could potentially have multiple levels of debug info
+static int debug_is_on (void)
+{
+ char * env_var;
+
+ if (debug_level < 0) {
+ env_var = getenv ("MPEG2_DEBUG");
+
+ if (env_var)
+ debug_level = 1;
+ else
+ debug_level = 0;
+ }
+
+ return debug_level;
+}
+
+static void stats_picture (uint8_t * buffer)
+{
+ static char * picture_coding_type_str [8] = {
+ "Invalid picture type",
+ "I-type",
+ "P-type",
+ "B-type",
+ "D (very bad)",
+ "Invalid","Invalid","Invalid"
+ };
+
+ int picture_coding_type;
+ int temporal_reference;
+ int vbv_delay;
+
+ temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6);
+ picture_coding_type = (buffer [1] >> 3) & 7;
+ vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) |
+ (buffer[3] >> 3)) & 0xffff;
+
+ fprintf (stderr, " (picture) %s temporal_reference %d, vbv_delay %d\n",
+ picture_coding_type_str [picture_coding_type],
+ temporal_reference, vbv_delay);
+}
+
+static void stats_user_data (uint8_t * buffer)
+{
+ fprintf (stderr, " (user_data)\n");
+}
+
+static void stats_sequence (uint8_t * buffer)
+{
+ static char * aspect_ratio_information_str[8] = {
+ "Invalid Aspect Ratio",
+ "1:1",
+ "4:3",
+ "16:9",
+ "2.21:1",
+ "Invalid Aspect Ratio",
+ "Invalid Aspect Ratio",
+ "Invalid Aspect Ratio"
+ };
+ static char * frame_rate_str[16] = {
+ "Invalid frame_rate_code",
+ "23.976", "24", "25" , "29.97",
+ "30" , "50", "59.94", "60" ,
+ "Invalid frame_rate_code", "Invalid frame_rate_code",
+ "Invalid frame_rate_code", "Invalid frame_rate_code",
+ "Invalid frame_rate_code", "Invalid frame_rate_code",
+ "Invalid frame_rate_code"
+ };
+
+ int horizontal_size;
+ int vertical_size;
+ int aspect_ratio_information;
+ int frame_rate_code;
+ int bit_rate_value;
+ int vbv_buffer_size_value;
+ int constrained_parameters_flag;
+ int load_intra_quantizer_matrix;
+ int load_non_intra_quantizer_matrix;
+
+ vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+ horizontal_size = vertical_size >> 12;
+ vertical_size &= 0xfff;
+ aspect_ratio_information = buffer[3] >> 4;
+ frame_rate_code = buffer[3] & 15;
+ bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6);
+ vbv_buffer_size_value = ((buffer[6] << 5) | (buffer[7] >> 3)) & 0x3ff;
+ constrained_parameters_flag = buffer[7] & 4;
+ load_intra_quantizer_matrix = buffer[7] & 2;
+ if (load_intra_quantizer_matrix)
+ buffer += 64;
+ load_non_intra_quantizer_matrix = buffer[7] & 1;
+
+ fprintf (stderr, " (seq) %dx%d %s, %s fps, %5.0f kbps, VBV %d kB%s%s%s\n",
+ horizontal_size, vertical_size,
+ aspect_ratio_information_str [aspect_ratio_information],
+ frame_rate_str [frame_rate_code],
+ bit_rate_value * 400.0 / 1000.0,
+ 2 * vbv_buffer_size_value,
+ constrained_parameters_flag ? " , CP":"",
+ load_intra_quantizer_matrix ? " , Custom Intra Matrix":"",
+ load_non_intra_quantizer_matrix ? " , Custom Non-Intra Matrix":"");
+}
+
+static void stats_sequence_error (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_error)\n");
+}
+
+static void stats_sequence_end (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_end)\n");
+}
+
+static void stats_group (uint8_t * buffer)
+{
+ fprintf (stderr, " (group)%s%s\n",
+ (buffer[4] & 0x40) ? " closed_gop" : "",
+ (buffer[4] & 0x20) ? " broken_link" : "");
+}
+
+static void stats_slice (uint8_t code, uint8_t * buffer)
+{
+ //fprintf (stderr, " (slice %d)\n", code);
+}
+
+static void stats_sequence_extension (uint8_t * buffer)
+{
+ static char * chroma_format_str[4] = {
+ "Invalid Chroma Format",
+ "4:2:0 Chroma",
+ "4:2:2 Chroma",
+ "4:4:4 Chroma"
+ };
+
+ int progressive_sequence;
+ int chroma_format;
+
+ progressive_sequence = (buffer[1] >> 3) & 1;
+ chroma_format = (buffer[1] >> 1) & 3;
+
+ fprintf (stderr, " (seq_ext) progressive_sequence %d, %s\n",
+ progressive_sequence, chroma_format_str [chroma_format]);
+}
+
+static void stats_sequence_display_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_display_extension)\n");
+}
+
+static void stats_quant_matrix_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (quant_matrix_extension)\n");
+}
+
+static void stats_copyright_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (copyright_extension)\n");
+}
+
+
+static void stats_sequence_scalable_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_scalable_extension)\n");
+}
+
+static void stats_picture_display_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (picture_display_extension)\n");
+}
+
+static void stats_picture_coding_extension (uint8_t * buffer)
+{
+ static char * picture_structure_str[4] = {
+ "Invalid Picture Structure",
+ "Top field",
+ "Bottom field",
+ "Frame Picture"
+ };
+
+ int f_code[2][2];
+ int intra_dc_precision;
+ int picture_structure;
+ int top_field_first;
+ int frame_pred_frame_dct;
+ int concealment_motion_vectors;
+ int q_scale_type;
+ int intra_vlc_format;
+ int alternate_scan;
+ int repeat_first_field;
+ int progressive_frame;
+
+ f_code[0][0] = buffer[0] & 15;
+ f_code[0][1] = buffer[1] >> 4;
+ f_code[1][0] = buffer[1] & 15;
+ f_code[1][1] = buffer[2] >> 4;
+ intra_dc_precision = (buffer[2] >> 2) & 3;
+ picture_structure = buffer[2] & 3;
+ top_field_first = buffer[3] >> 7;
+ frame_pred_frame_dct = (buffer[3] >> 6) & 1;
+ concealment_motion_vectors = (buffer[3] >> 5) & 1;
+ q_scale_type = (buffer[3] >> 4) & 1;
+ intra_vlc_format = (buffer[3] >> 3) & 1;
+ alternate_scan = (buffer[3] >> 2) & 1;
+ repeat_first_field = (buffer[3] >> 1) & 1;
+ progressive_frame = buffer[4] >> 7;
+
+ fprintf (stderr,
+ " (pic_ext) %s\n", picture_structure_str [picture_structure]);
+ fprintf (stderr,
+ " (pic_ext) forward horizontal f_code % d, forward vertical f_code % d\n",
+ f_code[0][0], f_code[0][1]);
+ fprintf (stderr,
+ " (pic_ext) backward horizontal f_code % d, backward vertical f_code % d\n",
+ f_code[1][0], f_code[1][1]);
+ fprintf (stderr,
+ " (pic_ext) intra_dc_precision %d, top_field_first %d, frame_pred_frame_dct %d\n",
+ intra_dc_precision, top_field_first, frame_pred_frame_dct);
+ fprintf (stderr,
+ " (pic_ext) concealment_motion_vectors %d, q_scale_type %d, intra_vlc_format %d\n",
+ concealment_motion_vectors, q_scale_type, intra_vlc_format);
+ fprintf (stderr,
+ " (pic_ext) alternate_scan %d, repeat_first_field %d, progressive_frame %d\n",
+ alternate_scan, repeat_first_field, progressive_frame);
+}
+
+void stats_header (uint8_t code, uint8_t * buffer)
+{
+ if (! (debug_is_on ()))
+ return;
+
+ switch (code) {
+ case 0x00:
+ stats_picture (buffer);
+ break;
+ case 0xb2:
+ stats_user_data (buffer);
+ break;
+ case 0xb3:
+ stats_sequence (buffer);
+ break;
+ case 0xb4:
+ stats_sequence_error (buffer);
+ break;
+ case 0xb5:
+ //stats_extension (buffer);
+ switch (buffer[0] >> 4) {
+ case 1:
+ stats_sequence_extension (buffer);
+ break;
+ case 2:
+ stats_sequence_display_extension (buffer);
+ break;
+ case 3:
+ stats