Revert "RFC: Get rid of mpegplayer plugin"

This reverts commit d25d24812e.

Change-Id: I1563223e343fb1e2eda72a45823b38350025ff93
This commit is contained in:
Solomon Peachy 2022-10-13 11:04:12 -04:00
parent 418169aff8
commit 9d3d925295
60 changed files with 21189 additions and 5 deletions

View file

@ -0,0 +1,33 @@
Aaron Holtzman <aholtzma@ess.engr.uvic.ca> started the project and
made the initial working implementation.
Michel Lespinasse <walken@zoy.org> did major changes for speed and
mpeg conformance and is the current maintainer. Most of the current
code was (re)written by him.
Other contributors include:
Bruno Barreyra <barreyra@ufl.edu> - build fixes
Gildas Bazin <gbazin@netcourrier.com> - mingw32 port
Alexander W. Chin <alexc@newt.phys.unsw.edu.au> - progressive_seq fix
Stephen Crowley <stephenc@dns2.digitalpassage.com> - build fixes
Didier Gautheron <dgautheron@magic.fr> - bug fixes
Ryan C. Gordon <icculus@lokigames.com> - SDL support
Peter Gubanov <peter@elecard.net.ru> - MMX IDCT scheduling
Håkan Hjort <d95hjort@dtek.chalmers.se> - Solaris fixes, mlib code
Nicolas Joly <njoly@pasteur.fr> - assorted bug fixes
Gerd Knorr <kraxel@goldbach.in-berlin.de> - Xv support
David I. Lehn <dlehn@vt.edu> - motion_comp mmx code
Olie Lho <ollie@sis.com.tw> - MMX yuv2rgb routine
David S. Miller <davem@redhat.com> - sparc VIS optimizations
Rick Niles <niles@scyld.com> - build fixes
Real Ouellet <realo@sympatico.ca> - g200 fixes
Bajusz Peter <hyp-x@inf.bme.hu> - motion comp fixes
Franck Sicard <Franck.Sicard@miniruth.solsoft.fr> - x11 fixes
Brion Vibber <brion@gizmo.usc.edu> - x11 fixes
Martin Vogt <mvogt@rhrk.uni-kl.de> - reentrancy fixes
Fredrik Vraalsen <vraalsen@cs.uiuc.edu> - general hackage and stuff
(let me know if I forgot anyone)
Thanks to David Schleef for creating me an account on his ppc g4
machine and making it possible for me to work on the altivec code.

View file

@ -0,0 +1,204 @@
ABOUT LIBMPEG2
libmpeg2 is a free library for decoding mpeg-2 and mpeg-1 video
streams. It is released under the terms of the GPL license.
The main goals in libmpeg2 development are:
* Conformance - libmpeg2 is able to decode all mpeg streams that
conform to certain restrictions: "constrained parameters" for
mpeg-1, and "main profile" for mpeg-2. In practice, this is
what most people are using. For streams that follow these
restrictions, we believe libmpeg2 is 100% conformant to the
mpeg standards - and we have a pretty extensive test suite to
check this.
* Speed - there has been huge efforts there, and we believe
libmpeg2 is the fastest library around for what it
does. Please tell us if you find a faster one ! With typical
video streams as found on DVD's, and doing only decoding with
no display, you should be able to get about 110 fps on a
PIII/666, or 150 fps on an Athlon/950. This is less than 20
cycles per output pixel. In a real player program, the display
routines will probably take as much time as the actual
decoding !
* Portability - most of the code is written in C, and when we
use platform-specific optimizations (typically assembly
routines, currently used for the motion compensation and the
inverse cosine transform stages) we always have a generic C
routine to fall back on. This should be portable to all
architectures - at least we have heard reports from people
running this code on x86, ppc, sparc, arm and
sh4. Assembly-optimized implementations are available on x86
(MMX) and ppc (altivec) architectures. Ultrasparc (VIS) is
probably the next on the list - we'll see.
* Reuseability - we do not want libmpeg2 to include any
project-specific code, but it should still include enough
features to be used by very diverse projects. We are only
starting to get there - the best way to help here is to give
us some feedback !
The project homepage is at http://libmpeg2.sourceforge.net/
MPEG2DEC
mpeg2dec is a test program for libmpeg2. It decodes mpeg-1 and mpeg-2
video streams, and also includes a demultiplexer for mpeg-1 and mpeg-2
program streams. It is purposely kept simple : it does not include
features like reading files from a DVD, CSS, fullscreen output,
navigation, etc... The main purpose of mpeg2dec is to have a simple
test bed for libmpeg2.
The libmpeg2 source code is always distributed in the mpeg2dec
package, to make it easier for people to test it.
The basic usage is to just type "mpeg2dec file" where file is a
demultiplexed mpeg video file.
The "-s" option must be used for multiplexed (audio and video) mpeg
files using the "program stream" format. These files are usualy found
on the internet or on unencrypted DVDs.
The "-t" option must be used for multiplexed (audio and video) mpeg
files using the "transport stream" format. These files are usualy
found in digital TV applications.
The "-o" option is used to select a given output module - for example
to redirect the output to a file. This is also used for performance
testing and conformance testing.
The "-c" option is used to disable all optimizations.
OTHER PROJECTS USING LIBMPEG2
libmpeg2 is being used by various other projects, including:
* xine (http://xine.sourceforge.net/) - started as a simple
mpeg-2 audio and video decoder, but it since became a
full-featured DVD and video media player.
* VideoLAN (http://www.videolan.org/) - video streaming over an
ethernet network, can also be used as a standalone player.
* MPlayer (http://www.MPlayerHQ.hu) - another good player, it is
also very robust against damaged streams.
* movietime (http://movietime.sourceforge.net/) - still quite
young, but it looks very promising !
* mpeg2decX (http://homepage1.nifty.com/~toku/software_en.html) -
a graphical interface for mpeg2dec for macintosh osX.
* TCVP (http://tcvp.sf.net) - video and music player for unix.
* drip (http://drip.sourceforge.net/) - a DVD to DIVX transcoder.
* PoMP
(http://www.dmclab.hanyang.ac.kr/research/project/PoDS/PoDS_sw.htm) -
a research player optimized to minimize disk power consumption.
* OMS (http://www.linuxvideo.org/oms/)
* XMPS (http://xmps.sourceforge.net/)
* GStreamer (http://www.gstreamer.net/) - a framework for
streaming media; it has an mpeg2 decoding plugin based on
libmpeg2.
* mpeglib (http://mpeglib.sourceforge.net/) - a video decoding
library that usess libmpeg2 when decoding mpeg streams.
* daphne (http://daphne.rulecity.com/) - a laserdisc arcade game
simulator.
* GOPchop (http://outflux.net/unix/software/GOPchop/) - a
GOP-accurate editor for MPEG2 streams.
If you use libmpeg2 in another project, let us know !
TASKS
There are several places where we could easily use some help:
* Documentation: libmpeg2 still has no documentation. Every
project using it has had to figure things out by looking at
the header files, at the mpeg2dec sample application, and by
asking questions. Writing down a nice documentation would make
the code more easily reuseable.
* Testing: If you find any stream that does not decode right
with libmpeg2, let us know ! The best thing would be to mail
to the libmpeg2-devel mailing list. Also, it would be nice to
build a stress test so we can make sure libmpeg2 never crashes
on bad streams.
* Coding: There is a small TODO list in the mpeg2dec package,
you can have a look there ! Most items are pretty terse
though.
* Porting: If you're porting to a new architecture, you might
want to experiment with the compile flags defined in
configure.in . When you figure out whats fastest on your
platform, send us a patch !
* Assembly optimizations: We only have x86 and altivec
optimizations yet, it would be worthwhile writing routines for
other architectures, especially those that have SIMD
instruction set extensions ! Also the yuv2rgb x86 routines
could probably be optimized a lot.
CVS SNAPSHOTS
A daily snapshot is created using "make distcheck" every night and
uploaded to http://libmpeg2.sourceforge.net/files/mpeg2dec-snapshot.tar.gz .
It is easier to use than the CVS repository, because you do not need
to have the right versions of automake, autoconf and libtool
installed. It might be convenient when working on a libmpeg2 port for
example.
CVS REPOSITORY
The latest libmpeg2 and mpeg2dec source code can always be found by
anonymous CVS:
# export CVSROOT=:pserver:anonymous@cvs.libmpeg2.sourceforge.net:/cvsroot/libmpeg2
# cvs login (Just press Return when prompted for a password)
# cvs checkout mpeg2dec
You can also browse the latest changes online at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/libmpeg2/mpeg2dec/
The other CVS modules are mpeg2dec-streams for the test suite, and
mpeg2dec-livid for the CVS history of the project while it was still
hosted on the linuxvideo.org servers.
MAILING LISTS
See the subscription information at http://libmpeg2.sourceforge.net/lists.html
libmpeg2-devel
This is the main mailing list for technical discussion about
libmpeg2. Anyone wanting to work on libmpeg2, or maybe just stay
informed about the development process, should probably subscribe to
this list.
libmpeg2-checkins
All libmpeg2 checkins are announced there. This is a good way to keep
track of what goes into CVS.
libmpeg2-announce
This is a very low traffic mailing list, only for announcements of new
versions of libmpeg2. Only project administrators can post there.

View file

@ -0,0 +1,44 @@
Library: libmpeg2 from mpeg2dec-0.4.0b (Released 2004-01-21)
Imported: 2006-08-06 by Dave Chapman
This directory contains a local version of libmpeg2 imported into
Rockbox for MPEG video decoding.
LICENSING INFORMATION
mpeg2dec and libmpeg2 are licensed under Version 2 of the GNU General
Public License.
IMPORT DETAILS
The following files were imported from the mpeg2dec-0.4.0b
distribution. Minor changes were made to enable compilation in
Rockbox and TABs were replaced by spaces to comply with the Rockbox
coding guidelines.
AUTHORS
README
SOURCES
attributes.h
cpu_accel.c
cpu_state.c
decode.c
header.c
idct.c
motion_comp.c
mpeg2.h
mpeg2_internal.h
slice.c
video_out.h
vlc.h
The following files are new, but based on code in mpeg2dec.
Makefile
mpegplayer.c
video_out_rockbox.c
mpeg2dec_config.h
alloc.c

View file

@ -0,0 +1,42 @@
/*
* attributes.h
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.5
*/
/* use gcc attribs to align critical data structures */
#ifdef ATTRIBUTE_ALIGNED_MAX
#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
#else
#define ATTR_ALIGN(align)
#endif
#if defined(LIKELY) && defined (UNLIKELY)
#define likely(x) LIKELY(x)
#define unlikely(x) UNLIKELY(x)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif

View file

@ -0,0 +1,527 @@
/*
* decode.c
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.114
*/
#include "plugin.h"
#include "mpeg2dec_config.h"
#include "mpeg2.h"
#include "attributes.h"
#include "mpeg2_internal.h"
#define BUFFER_SIZE (1194 * 1024)
#if defined(CPU_COLDFIRE) || (defined(CPU_ARM) && ARM_ARCH >= 6)
/* twice as large as on other targets because coldfire uses
* a secondary, transposed buffer for optimisation */
static int16_t static_dct_block[128] IBSS_ATTR ATTR_ALIGN(16);
#define DCT_BLOCKSIZE (128 * sizeof (int16_t))
#else
static int16_t static_dct_block[64] IBSS_ATTR ATTR_ALIGN(16);
#define DCT_BLOCKSIZE (64 * sizeof (int16_t))
#endif
const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec)
{
return &mpeg2dec->info;
}
static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes)
{
uint8_t * current;
uint32_t shift;
uint8_t * limit;
uint8_t byte;
if (!bytes)
return 0;
current = mpeg2dec->buf_start;
shift = mpeg2dec->shift;
limit = current + bytes;
do
{
byte = *current++;
if (shift == 0x00000100)
{
int skipped;
mpeg2dec->shift = 0xffffff00;
skipped = current - mpeg2dec->buf_start;
mpeg2dec->buf_start = current;
return skipped;
}
shift = (shift | byte) << 8;
}
while (current < limit);
mpeg2dec->shift = shift;
mpeg2dec->buf_start = current;
return 0;
}
static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes)
{
uint8_t * current;
uint32_t shift;
uint8_t * chunk_ptr;
uint8_t * limit;
uint8_t byte;
if (!bytes)
return 0;
current = mpeg2dec->buf_start;
shift = mpeg2dec->shift;
chunk_ptr = mpeg2dec->chunk_ptr;
limit = current + bytes;
do
{
byte = *current++;
if (shift == 0x00000100)
{
int copied;
mpeg2dec->shift = 0xffffff00;
mpeg2dec->chunk_ptr = chunk_ptr + 1;
copied = current - mpeg2dec->buf_start;
mpeg2dec->buf_start = current;
return copied;
}
shift = (shift | byte) << 8;
*chunk_ptr++ = byte;
}
while (current < limit);
mpeg2dec->shift = shift;
mpeg2dec->buf_start = current;
return 0;
}
void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end)
{
mpeg2dec->buf_start = start;
mpeg2dec->buf_end = end;
}
int mpeg2_getpos (mpeg2dec_t * mpeg2dec)
{
return mpeg2dec->buf_end - mpeg2dec->buf_start;
}
static inline mpeg2_state_t seek_chunk (mpeg2dec_t * mpeg2dec)
{
int size, skipped;
size = mpeg2dec->buf_end - mpeg2dec->buf_start;
skipped = skip_chunk (mpeg2dec, size);
if (!skipped)
{
mpeg2dec->bytes_since_tag += size;
return STATE_BUFFER;
}
mpeg2dec->bytes_since_tag += skipped;
mpeg2dec->code = mpeg2dec->buf_start[-1];
return STATE_INTERNAL_NORETURN;
}
mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec)
{
while (!(mpeg2dec->code == 0xb3 ||
((mpeg2dec->code == 0xb7 || mpeg2dec->code == 0xb8 ||
!mpeg2dec->code) && mpeg2dec->sequence.width != (unsigned)-1)))
{
if (seek_chunk (mpeg2dec) == STATE_BUFFER)
return STATE_BUFFER;
}
mpeg2dec->chunk_start =
mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
mpeg2dec->user_data_len = 0;
return ((mpeg2dec->code == 0xb7) ?
mpeg2_header_end(mpeg2dec) : mpeg2_parse_header(mpeg2dec));
}
#define RECEIVED(code,state) (((state) << 8) + (code))
mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec)
{
int size_buffer, size_chunk, copied;
if (mpeg2dec->action)
{
mpeg2_state_t state;
state = mpeg2dec->action (mpeg2dec);
if (state > STATE_INTERNAL_NORETURN)
return state;
}
while (1)
{
while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) <
mpeg2dec->nb_decode_slices)
{
size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
size_chunk = mpeg2dec->chunk_buffer + BUFFER_SIZE -
mpeg2dec->chunk_ptr;
if (size_buffer <= size_chunk)
{
copied = copy_chunk (mpeg2dec, size_buffer);
if (!copied)
{
mpeg2dec->bytes_since_tag += size_buffer;
mpeg2dec->chunk_ptr += size_buffer;
return STATE_BUFFER;
}
}
else
{
copied = copy_chunk (mpeg2dec, size_chunk);
if (!copied)
{
/* filled the chunk buffer without finding a start code */
mpeg2dec->bytes_since_tag += size_chunk;
mpeg2dec->action = seek_chunk;
return STATE_INVALID;
}
}
mpeg2dec->bytes_since_tag += copied;
mpeg2_slice (&mpeg2dec->decoder, mpeg2dec->code,
mpeg2dec->chunk_start);
mpeg2dec->code = mpeg2dec->buf_start[-1];
mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
}
if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1)
break;
if (seek_chunk (mpeg2dec) == STATE_BUFFER)
return STATE_BUFFER;
}
mpeg2dec->action = mpeg2_seek_header;
switch (mpeg2dec->code)
{
case 0x00:
return mpeg2dec->state;
case 0xb3:
case 0xb7:
case 0xb8:
return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID;
default:
mpeg2dec->action = seek_chunk;
return STATE_INVALID;
}
}
mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec)
{
static int (* const process_header[9]) (mpeg2dec_t *) =
{
mpeg2_header_picture,
mpeg2_header_extension,
mpeg2_header_user_data,
mpeg2_header_sequence,
NULL,
NULL,
NULL,
NULL,
mpeg2_header_gop
};
int size_buffer, size_chunk, copied;
mpeg2dec->action = mpeg2_parse_header;
mpeg2dec->info.user_data = NULL;
mpeg2dec->info.user_data_len = 0;
while (1)
{
size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start;
size_chunk = mpeg2dec->chunk_buffer + BUFFER_SIZE -
mpeg2dec->chunk_ptr;
if (size_buffer <= size_chunk)
{
copied = copy_chunk (mpeg2dec, size_buffer);
if (!copied)
{
mpeg2dec->bytes_since_tag += size_buffer;
mpeg2dec->chunk_ptr += size_buffer;
return STATE_BUFFER;
}
}
else
{
copied = copy_chunk (mpeg2dec, size_chunk);
if (!copied)
{
/* filled the chunk buffer without finding a start code */
mpeg2dec->bytes_since_tag += size_chunk;
mpeg2dec->code = 0xb4;
mpeg2dec->action = mpeg2_seek_header;
return STATE_INVALID;
}
}
mpeg2dec->bytes_since_tag += copied;
if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec))
{
mpeg2dec->code = mpeg2dec->buf_start[-1];
mpeg2dec->action = mpeg2_seek_header;
return STATE_INVALID;
}
mpeg2dec->code = mpeg2dec->buf_start[-1];
switch (RECEIVED (mpeg2dec->code, mpeg2dec->state))
{
/* state transition after a sequence header */
case RECEIVED (0x00, STATE_SEQUENCE):
case RECEIVED (0xb8, STATE_SEQUENCE):
mpeg2_header_sequence_finalize (mpeg2dec);
break;
/* other legal state transitions */
case RECEIVED (0x00, STATE_GOP):
mpeg2_header_gop_finalize (mpeg2dec);
break;
case RECEIVED (0x01, STATE_PICTURE):
case RECEIVED (0x01, STATE_PICTURE_2ND):
mpeg2_header_picture_finalize (mpeg2dec);
mpeg2dec->action = mpeg2_header_slice_start;
break;
/* legal headers within a given state */
case RECEIVED (0xb2, STATE_SEQUENCE):
case RECEIVED (0xb2, STATE_GOP):
case RECEIVED (0xb2, STATE_PICTURE):
case RECEIVED (0xb2, STATE_PICTURE_2ND):
case RECEIVED (0xb5, STATE_SEQUENCE):
case RECEIVED (0xb5, STATE_PICTURE):
case RECEIVED (0xb5, STATE_PICTURE_2ND):
mpeg2dec->chunk_ptr = mpeg2dec->chunk_start;
continue;
default:
mpeg2dec->action = mpeg2_seek_header;
return STATE_INVALID;
}
mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
mpeg2dec->user_data_len = 0;
return mpeg2dec->state;
}
}
int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg)
{
mpeg2_convert_init_t convert_init;
int error;
error = convert (MPEG2_CONVERT_SET, NULL, &mpeg2dec->sequence, 0,
arg, &convert_init);
if (!error)
{
mpeg2dec->convert = convert;
mpeg2dec->convert_arg = arg;
mpeg2dec->convert_id_size = convert_init.id_size;
mpeg2dec->convert_stride = 0;
}
return error;
}
int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride)
{
if (!mpeg2dec->convert)
{
if (stride < (int) mpeg2dec->sequence.width)
stride = mpeg2dec->sequence.width;
mpeg2dec->decoder.stride_frame = stride;
}
else
{
mpeg2_convert_init_t convert_init;
stride = mpeg2dec->convert(MPEG2_CONVERT_STRIDE, NULL,
&mpeg2dec->sequence, stride,
mpeg2dec->convert_arg,
&convert_init);
mpeg2dec->convert_id_size = convert_init.id_size;
mpeg2dec->convert_stride = stride;
}
return stride;
}
void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS], void * id)
{
mpeg2_fbuf_t * fbuf;
if (mpeg2dec->custom_fbuf)
{
if (mpeg2dec->state == STATE_SEQUENCE)
{
mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1];
mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0];
}
mpeg2_set_fbuf (mpeg2dec, (mpeg2dec->decoder.coding_type ==
PIC_FLAG_CODING_TYPE_B));
fbuf = mpeg2dec->fbuf[0];
}
else
{
fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index].fbuf;
mpeg2dec->alloc_index_user = ++mpeg2dec->alloc_index;
}
fbuf->buf[0] = buf[0];
#if MPEG2_COLOR
fbuf->buf[1] = buf[1];
fbuf->buf[2] = buf[2];
#endif
fbuf->id = id;
}
void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf)
{
mpeg2dec->custom_fbuf = custom_fbuf;
}
void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip)
{
mpeg2dec->first_decode_slice = 1;
mpeg2dec->nb_decode_slices = skip ? 0 : (0xb0 - 1);
}
void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end)
{
start = (start < 1) ? 1 : (start > 0xb0) ? 0xb0 : start;
end = (end < start) ? start : (end > 0xb0) ? 0xb0 : end;
mpeg2dec->first_decode_slice = start;
mpeg2dec->nb_decode_slices = end - start;
}
void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2)
{
mpeg2dec->tag_previous = mpeg2dec->tag_current;
mpeg2dec->tag2_previous = mpeg2dec->tag2_current;
mpeg2dec->tag_current = tag;
mpeg2dec->tag2_current = tag2;
mpeg2dec->num_tags++;
mpeg2dec->bytes_since_tag = 0;
}
void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset)
{
mpeg2dec->buf_start = mpeg2dec->buf_end = NULL;
mpeg2dec->num_tags = 0;
mpeg2dec->shift = 0xffffff00;
mpeg2dec->code = 0xb4;
mpeg2dec->action = mpeg2_seek_header;
mpeg2dec->state = STATE_INVALID;
mpeg2dec->first = 1;
mpeg2_reset_info(&mpeg2dec->info);
mpeg2dec->info.gop = NULL;
mpeg2dec->info.user_data = NULL;
mpeg2dec->info.user_data_len = 0;
if (full_reset)
{
mpeg2dec->info.sequence = NULL;
mpeg2_header_state_init (mpeg2dec);
}
}
mpeg2dec_t * mpeg2_init (void)
{
mpeg2dec_t * mpeg2dec;
mpeg2_idct_init ();
mpeg2dec = (mpeg2dec_t *)mpeg2_bufalloc(sizeof (mpeg2dec_t),
MPEG2_ALLOC_MPEG2DEC);
if (mpeg2dec == NULL)
return NULL;
mpeg2dec->decoder.DCTblock = static_dct_block;
rb->memset (mpeg2dec->decoder.DCTblock, 0, DCT_BLOCKSIZE);
DEBUGF("DCTblock: %p\n", mpeg2dec->decoder.DCTblock);
mpeg2dec->chunk_buffer = (uint8_t *)mpeg2_bufalloc(BUFFER_SIZE + 4,
MPEG2_ALLOC_CHUNK);
mpeg2dec->sequence.width = (unsigned)-1;
mpeg2_reset (mpeg2dec, 1);
return mpeg2dec;
}
void mpeg2_close (mpeg2dec_t * mpeg2dec)
{
mpeg2_header_state_init (mpeg2dec);
#if 0
/* These are dedicated buffers in rockbox */
mpeg2_free (mpeg2dec->chunk_buffer);
mpeg2_free (mpeg2dec);
#endif
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,274 @@
/*
* idct.c
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.36
*/
#include "plugin.h"
#include "mpeg2dec_config.h"
#include "mpeg2.h"
#include "attributes.h"
#include "mpeg2_internal.h"
#if defined(CPU_COLDFIRE) || defined (CPU_ARM)
#define IDCT_ASM
#endif
#ifndef IDCT_ASM
#define W1 2841 /* 2048 * sqrt (2) * cos (1 * pi / 16) */
#define W2 2676 /* 2048 * sqrt (2) * cos (2 * pi / 16) */
#define W3 2408 /* 2048 * sqrt (2) * cos (3 * pi / 16) */
#define W5 1609 /* 2048 * sqrt (2) * cos (5 * pi / 16) */
#define W6 1108 /* 2048 * sqrt (2) * cos (6 * pi / 16) */
#define W7 565 /* 2048 * sqrt (2) * cos (7 * pi / 16) */
/*
* In legal streams, the IDCT output should be between -384 and +384.
* In corrupted streams, it is possible to force the IDCT output to go
* to +-3826 - this is the worst case for a column IDCT where the
* column inputs are 16-bit values.
*/
#define CLIP(i) \
({ typeof (i) _i = (i); \
if ((_i & 0xff) != _i) \
_i = ~(_i >> (8*sizeof(_i) - 1)); \
_i; })
#if 0
#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
do { \
t0 = W0 * d0 + W1 * d1; \
t1 = W0 * d1 - W1 * d0; \
} while (0)
#else
#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
do { \
int tmp = W0 * (d0 + d1); \
t0 = tmp + (W1 - W0) * d1; \
t1 = tmp - (W1 + W0) * d0; \
} while (0)
#endif
static inline void idct_row (int16_t * const block)
{
int d0, d1, d2, d3;
int a0, a1, a2, a3, b0, b1, b2, b3;
int t0, t1, t2, t3;
/* shortcut */
if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] |
((int32_t *)block)[3])))
{
uint32_t tmp = (uint16_t) (block[0] >> 1);
tmp |= tmp << 16;
((int32_t *)block)[0] = tmp;
((int32_t *)block)[1] = tmp;
((int32_t *)block)[2] = tmp;
((int32_t *)block)[3] = tmp;
return;
}
d0 = (block[0] << 11) + 2048;
d1 = block[1];
d2 = block[2] << 11;
d3 = block[3];
t0 = d0 + d2;
t1 = d0 - d2;
BUTTERFLY (t2, t3, W6, W2, d3, d1);
a0 = t0 + t2;
a1 = t1 + t3;
a2 = t1 - t3;
a3 = t0 - t2;
d0 = block[4];
d1 = block[5];
d2 = block[6];
d3 = block[7];
BUTTERFLY (t0, t1, W7, W1, d3, d0);
BUTTERFLY (t2, t3, W3, W5, d1, d2);
b0 = t0 + t2;
b3 = t1 + t3;
t0 -= t2;
t1 -= t3;
b1 = ((t0 + t1) >> 8) * 181;
b2 = ((t0 - t1) >> 8) * 181;
block[0] = (a0 + b0) >> 12;
block[1] = (a1 + b1) >> 12;
block[2] = (a2 + b2) >> 12;
block[3] = (a3 + b3) >> 12;
block[4] = (a3 - b3) >> 12;
block[5] = (a2 - b2) >> 12;
block[6] = (a1 - b1) >> 12;
block[7] = (a0 - b0) >> 12;
}
static inline void idct_col (int16_t * const block)
{
int d0, d1, d2, d3;
int a0, a1, a2, a3, b0, b1, b2, b3;
int t0, t1, t2, t3;
d0 = (block[8*0] << 11) + 65536;
d1 = block[8*1];
d2 = block[8*2] << 11;
d3 = block[8*3];
t0 = d0 + d2;
t1 = d0 - d2;
BUTTERFLY (t2, t3, W6, W2, d3, d1);
a0 = t0 + t2;
a1 = t1 + t3;
a2 = t1 - t3;
a3 = t0 - t2;
d0 = block[8*4];
d1 = block[8*5];
d2 = block[8*6];
d3 = block[8*7];
BUTTERFLY (t0, t1, W7, W1, d3, d0);
BUTTERFLY (t2, t3, W3, W5, d1, d2);
b0 = t0 + t2;
b3 = t1 + t3;
t0 -= t2;
t1 -= t3;
b1 = ((t0 + t1) >> 8) * 181;
b2 = ((t0 - t1) >> 8) * 181;
block[8*0] = (a0 + b0) >> 17;
block[8*1] = (a1 + b1) >> 17;
block[8*2] = (a2 + b2) >> 17;
block[8*3] = (a3 + b3) >> 17;
block[8*4] = (a3 - b3) >> 17;
block[8*5] = (a2 - b2) >> 17;
block[8*6] = (a1 - b1) >> 17;
block[8*7] = (a0 - b0) >> 17;
}
void mpeg2_idct_copy (int16_t * block, uint8_t * dest,
const int stride)
{
int i;
for (i = 0; i < 8; i++)
idct_row (block + 8 * i);
for (i = 0; i < 8; i++)
idct_col (block + i);
do
{
dest[0] = CLIP (block[0]);
dest[1] = CLIP (block[1]);
dest[2] = CLIP (block[2]);
dest[3] = CLIP (block[3]);
dest[4] = CLIP (block[4]);
dest[5] = CLIP (block[5]);
dest[6] = CLIP (block[6]);
dest[7] = CLIP (block[7]);
((int32_t *)block)[0] = 0;
((int32_t *)block)[1] = 0;
((int32_t *)block)[2] = 0;
((int32_t *)block)[3] = 0;
dest += stride;
block += 8;
}
while (--i);
}
void mpeg2_idct_add (const int last, int16_t * block,
uint8_t * dest, const int stride)
{
int i;
if (last != 129 || (block[0] & (7 << 4)) == (4 << 4))
{
for (i = 0; i < 8; i++)
idct_row (block + 8 * i);
for (i = 0; i < 8; i++)
idct_col (block + i);
do
{
dest[0] = CLIP (block[0] + dest[0]);
dest[1] = CLIP (block[1] + dest[1]);
dest[2] = CLIP (block[2] + dest[2]);
dest[3] = CLIP (block[3] + dest[3]);
dest[4] = CLIP (block[4] + dest[4]);
dest[5] = CLIP (block[5] + dest[5]);
dest[6] = CLIP (block[6] + dest[6]);
dest[7] = CLIP (block[7] + dest[7]);
((int32_t *)block)[0] = 0;
((int32_t *)block)[1] = 0;
((int32_t *)block)[2] = 0;
((int32_t *)block)[3] = 0;
dest += stride;
block += 8;
}
while (--i);
}
else
{
int DC = (block[0] + 64) >> 7;
block[0] = block[63] = 0;
i = 8;
do
{
dest[0] = CLIP (DC + dest[0]);
dest[1] = CLIP (DC + dest[1]);
dest[2] = CLIP (DC + dest[2]);
dest[3] = CLIP (DC + dest[3]);
dest[4] = CLIP (DC + dest[4]);
dest[5] = CLIP (DC + dest[5]);
dest[6] = CLIP (DC + dest[6]);
dest[7] = CLIP (DC + dest[7]);
dest += stride;
}
while (--i);
}
}
#endif /* IDCT_ASM */
void mpeg2_idct_init (void)
{
int i, j;
for (i = 0; i < 64; i++)
{
j = default_mpeg2_scan_norm[i];
mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
j = default_mpeg2_scan_alt[i];
mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
}
}

View file

@ -0,0 +1,443 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Michael Sevakis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
.global mpeg2_idct_copy
.type mpeg2_idct_copy, %function
.global mpeg2_idct_add
.type mpeg2_idct_add, %function
/* Custom calling convention:
* r0 contains block pointer and is non-volatile
* all non-volatile c context saved and restored on its behalf
*/
.idct:
add r12, r0, #128
1:
ldrsh r1, [r0, #0] /* d0 */
ldrsh r2, [r0, #2] /* d1 */
ldrsh r3, [r0, #4] /* d2 */
ldrsh r4, [r0, #6] /* d3 */
ldrsh r5, [r0, #8] /* d0 */
ldrsh r6, [r0, #10] /* d1 */
ldrsh r7, [r0, #12] /* d2 */
ldrsh r8, [r0, #14] /* d3 */
orrs r9, r2, r3
orreqs r9, r4, r5
orreqs r9, r6, r7
cmpeq r8, #0
bne 2f
mov r1, r1, asl #15
bic r1, r1, #0x8000
orr r1, r1, r1, lsr #16
str r1, [r0], #4
str r1, [r0], #4
str r1, [r0], #4
str r1, [r0], #4
cmp r0, r12
blo 1b
b 3f
2:
mov r1, r1, asl #11 /* r1 = d0 = (block[0] << 11) + 2048 */
add r1, r1, #2048
add r1, r1, r3, asl #11 /* r1 = t0 = d0 + (block[2] << 11) */
sub r3, r1, r3, asl #12 /* r3 = t1 = d0 - (block[2] << 11) */
add r9, r2, r4 /* r9 = tmp = (d1+d3)*(1108/4) */
add r10, r9, r9, asl #2
add r10, r10, r9, asl #4
add r9, r10, r9, asl #8
add r10, r2, r2, asl #4 /* r2 = t2 = tmp + (d1*(1568/32)*8) */
add r2, r10, r2, asl #5
add r2, r9, r2, asl #3
add r10, r4, r4, asl #2 /* r4 = t3 = tmp - (d3*(3784/8)*2) */
rsb r10, r10, r4, asl #6
add r4, r4, r10, asl #3
sub r4, r9, r4, asl #1
/* t2 & t3 are 1/4 final value here */
add r1, r1, r2, asl #2 /* r1 = a0 = t0 + t2 */
sub r2, r1, r2, asl #3 /* r2 = a3 = t0 - t2 */
add r3, r3, r4, asl #2 /* r3 = a1 = t1 + t3 */
sub r4, r3, r4, asl #3 /* r4 = a2 = t1 - t3 */
add r9, r8, r5 /* r9 = tmp = 565*(d3 + d0) */
add r10, r9, r9, asl #4
add r10, r10, r10, asl #5
add r9, r10, r9, asl #2
add r10, r5, r5, asl #4 /* r5 = t0 = tmp + (((2276/4)*d0)*4) */
add r10, r10, r10, asl #5
add r5, r10, r5, asl #3
add r5, r9, r5, asl #2
add r10, r8, r8, asl #2 /* r8 = t1 = tmp - (((3406/2)*d3)*2) */
add r10, r10, r10, asl #4
add r10, r10, r8, asl #7
rsb r8, r8, r10, asl #3
sub r8, r9, r8, asl #1
add r9, r6, r7 /* r9 = tmp = (2408/8)*(d1 + d2) */
add r10, r9, r9, asl #3
add r10, r10, r10, asl #5
add r9, r10, r9, asl #2
add r10, r7, r7, asl #3 /* r7 = t2 = (tmp*8) - 799*d2 */
add r10, r10, r7, asl #4
rsb r7, r7, r10, asl #5
rsb r7, r7, r9, asl #3
sub r10, r6, r6, asl #4 /* r6 = t3 = (tmp*8) - 4017*d1 */
sub r10, r10, r6, asl #6
add r10, r10, r6, asl #12
add r6, r10, r6
rsb r6, r6, r9, asl #3
/* t0 = r5, t1 = r8, t2 = r7, t3 = r6*/
add r9, r5, r7 /* r9 = b0 = t0 + t2 */
add r10, r8, r6 /* r10 = b3 = t1 + t3 */
sub r5, r5, r7 /* t0 -= t2 */
sub r8, r8, r6 /* t1 -= t3 */
add r6, r5, r8 /* r6 = t0 + t1 */
sub r7, r5, r8 /* r7 = t0 - t1 */
add r11, r6, r6, asr #2 /* r6 = b1 = r6*(181/128) */
add r11, r11, r11, asr #5
add r6, r11, r6, asr #3
add r11, r7, r7, asr #2 /* r7 = b2 = r7*(181/128) */
add r11, r11, r11, asr #5
add r7, r11, r7, asr #3
/* r1 = a0, r3 = a1, r4 = a2, r2 = a3 */
/* r9 = b0, r6 = b1*2, r7 = b2*2, r10 = b3 */
add r5, r1, r9 /* block[0] = (a0 + b0) >> 12 */
mov r5, r5, asr #12
strh r5, [r0], #2
add r8, r3, r6, asr #1 /* block[1] = (a1 + b1) >> 12 */
mov r8, r8, asr #12
strh r8, [r0], #2
add r5, r4, r7, asr #1 /* block[2] = (a2 + b2) >> 12 */
mov r5, r5, asr #12
strh r5, [r0], #2
add r8, r2, r10 /* block[3] = (a3 + b3) >> 12 */
mov r8, r8, asr #12
strh r8, [r0], #2
sub r5, r2, r10 /* block[4] = (a3 - b3) >> 12 */
mov r5, r5, asr #12
strh r5, [r0], #2
sub r8, r4, r7, asr #1 /* block[5] = (a2 - b2) >> 12 */
mov r8, r8, asr #12
strh r8, [r0], #2
sub r5, r3, r6, asr #1 /* block[6] = (a1 - b1) >> 12 */
mov r5, r5, asr #12
strh r5, [r0], #2
sub r8, r1, r9 /* block[7] = (a0 - b0) >> 12 */
mov r8, r8, asr #12
strh r8, [r0], #2
cmp r0, r12
blo 1b
3:
sub r0, r0, #128
add r12, r0, #16
4:
ldrsh r1, [r0, #0*8] /* d0 */
ldrsh r2, [r0, #2*8] /* d1 */
ldrsh r3, [r0, #4*8] /* d2 */
ldrsh r4, [r0, #6*8] /* d3 */
ldrsh r5, [r0, #8*8] /* d0 */
ldrsh r6, [r0, #10*8] /* d1 */
ldrsh r7, [r0, #12*8] /* d2 */
ldrsh r8, [r0, #14*8] /* d3 */
mov r1, r1, asl #11 /* r1 = d0 = (block[0] << 11) + 2048 */
add r1, r1, #65536
add r1, r1, r3, asl #11 /* r1 = t0 = d0 + d2:(block[2] << 11) */
sub r3, r1, r3, asl #12 /* r3 = t1 = d0 - d2:(block[2] << 11) */
add r9, r2, r4 /* r9 = tmp = (d1+d3)*(1108/4) */
add r10, r9, r9, asl #2
add r10, r10, r9, asl #4
add r9, r10, r9, asl #8
add r11, r2, r2, asl #4 /* r2 = t2 = tmp + (d1*(1568/32)*8) */
add r2, r11, r2, asl #5
add r2, r9, r2, asl #3
add r10, r4, r4, asl #2 /* r4 = t3 = tmp - (d3*(3784/8)*2) */
rsb r10, r10, r4, asl #6
add r4, r4, r10, asl #3
sub r4, r9, r4, asl #1
/* t2 & t3 are 1/4 final value here */
add r1, r1, r2, asl #2 /* r1 = a0 = t0 + t2 */
sub r2, r1, r2, asl #3 /* r2 = a3 = t0 - t2 */
add r3, r3, r4, asl #2 /* r3 = a1 = t1 + t3 */
sub r4, r3, r4, asl #3 /* r4 = a2 = t1 - t3 */
add r9, r8, r5 /* r9 = tmp = 565*(d3 + d0) */
add r10, r9, r9, asl #4
add r10, r10, r10, asl #5
add r9, r10, r9, asl #2
add r10, r5, r5, asl #4 /* r5 = t0 = tmp + (((2276/4)*d0)*4) */
add r10, r10, r10, asl #5
add r5, r10, r5, asl #3
add r5, r9, r5, asl #2
add r10, r8, r8, asl #2 /* r8 = t1 = tmp - (((3406/2)*d3)*2) */
add r10, r10, r10, asl #4
add r10, r10, r8, asl #7
rsb r8, r8, r10, asl #3
sub r8, r9, r8, asl #1
add r9, r6, r7 /* r9 = tmp = (2408/8)*(d1 + d2) */
add r10, r9, r9, asl #3
add r10, r10, r10, asl #5
add r9, r10, r9, asl #2
add r10, r7, r7, asl #3 /* r7 = t2 = (tmp*8) - 799*d2 */
add r10, r10, r7, asl #4
rsb r7, r7, r10, asl #5
rsb r7, r7, r9, asl #3
sub r10, r6, r6, asl #4 /* r6 = t3 = (tmp*8) - 4017*d1 */
sub r10, r10, r6, asl #6
add r10, r10, r6, asl #12
add r6, r10, r6
rsb r6, r6, r9, asl #3
/* t0=r5, t1=r8, t2=r7, t3=r6*/
add r9, r5, r7 /* r9 = b0 = t0 + t2 */
add r10, r8, r6 /* r10 = b3 = t1 + t3 */
sub r5, r5, r7 /* t0 -= t2 */
sub r8, r8, r6 /* t1 -= t3 */
add r6, r5, r8 /* r6 = t0 + t1 */
sub r7, r5, r8 /* r7 = t0 - t1 */
add r11, r6, r6, asr #2 /* r6 = b1 = r5*(181/128) */
add r11, r11, r11, asr #5
add r6, r11, r6, asr #3
add r11, r7, r7, asr #2 /* r7 = b2 = r6*(181/128) */
add r11, r11, r11, asr #5
add r7, r11, r7, asr #3
/* r1 = a0, r3 = a1, r4 = a2, r2 = a3 */
/* r9 = b0, r6 = b1*2, r7 = b2*2, r10 = b3 */
add r5, r1, r9 /* block[0] = (a0 + b0) >> 17 */
mov r5, r5, asr #17
strh r5, [r0, #0*8]
add r8, r3, r6, asr #1 /* block[1] = (a1 + b1) >> 17 */
mov r8, r8, asr #17
strh r8, [r0, #2*8]
add r5, r4, r7, asr #1 /* block[2] = (a2 + b2) >> 17 */
mov r5, r5, asr #17
strh r5, [r0, #4*8]
add r8, r2, r10 /* block[3] = (a3 + b3) >> 17 */
mov r8, r8, asr #17
strh r8, [r0, #6*8]
sub r5, r2, r10 /* block[4] = (a3 - b3) >> 17 */
mov r5, r5, asr #17
strh r5, [r0, #8*8]
sub r8, r4, r7, asr #1 /* block[5] = (a2 - b2) >> 17 */
mov r8, r8, asr #17
strh r8, [r0, #10*8]
sub r5, r3, r6, asr #1 /* block[6] = (a1 - b1) >> 17 */
mov r5, r5, asr #17
strh r5, [r0, #12*8]
sub r8, r1, r9 /* block[7] = (a0 - b0) >> 17 */
mov r8, r8, asr #17
strh r8, [r0, #14*8]
add r0, r0, #2
cmp r0, r12
blo 4b
sub r0, r0, #16
bx lr
mpeg2_idct_copy:
stmfd sp!, { r1-r2, r4-r11, lr }
bl .idct
ldmfd sp!, { r1-r2 }
mov r11, #0
add r12, r0, #128
1:
ldrsh r3, [r0, #0]
ldrsh r4, [r0, #2]
ldrsh r5, [r0, #4]
ldrsh r6, [r0, #6]
ldrsh r7, [r0, #8]
ldrsh r8, [r0, #10]
ldrsh r9, [r0, #12]
ldrsh r10, [r0, #14]
cmp r3, #255
mvnhi r3, r3, asr #31
strb r3, [r1, #0]
str r11, [r0], #4
cmp r4, #255
mvnhi r4, r4, asr #31
strb r4, [r1, #1]
cmp r5, #255
mvnhi r5, r5, asr #31
strb r5, [r1, #2]
str r11, [r0], #4
cmp r6, #255
mvnhi r6, r6, asr #31
strb r6, [r1, #3]
cmp r7, #255
mvnhi r7, r7, asr #31
strb r7, [r1, #4]
str r11, [r0], #4
cmp r8, #255
mvnhi r8, r8, asr #31
strb r8, [r1, #5]
cmp r9, #255
mvnhi r9, r9, asr #31
strb r9, [r1, #6]
str r11, [r0], #4
cmp r10, #255
mvnhi r10, r10, asr #31
strb r10, [r1, #7]
add r1, r1, r2
cmp r0, r12
blo 1b
ldmpc regs=r4-r11
mpeg2_idct_add:
cmp r0, #129
mov r0, r1
ldreqsh r1, [r0, #0]
bne 1f
and r1, r1, #0x70
cmp r1, #0x40
bne 3f
1:
stmfd sp!, { r2-r11, lr }
bl .idct
ldmfd sp!, { r1-r2 }
mov r11, #0
add r12, r0, #128
2:
ldrb r3, [r1, #0]
ldrb r4, [r1, #1]
ldrb r5, [r1, #2]
ldrb r6, [r1, #3]
ldrsh r7, [r0, #0]
ldrsh r8, [r0, #2]
ldrsh r9, [r0, #4]
ldrsh r10, [r0, #6]
add r7, r7, r3
ldrb r3, [r1, #4]
cmp r7, #255
mvnhi r7, r7, asr #31
strb r7, [r1, #0]
ldrsh r7, [r0, #8]
add r8, r8, r4
ldrb r4, [r1, #5]
cmp r8, #255
mvnhi r8, r8, asr #31
strb r8, [r1, #1]
ldrsh r8, [r0, #10]
add r9, r9, r5
ldrb r5, [r1, #6]
cmp r9, #255
mvnhi r9, r9, asr #31
strb r9, [r1, #2]
ldrsh r9, [r0, #12]
add r10, r10, r6
ldrb r6, [r1, #7]
cmp r10, #255
mvnhi r10, r10, asr #31
strb r10, [r1, #3]
ldrsh r10, [r0, #14]
str r11, [r0], #4
add r7, r7, r3
cmp r7, #255
mvnhi r7, r7, asr #31
strb r7, [r1, #4]
str r11, [r0], #4
add r8, r8, r4
cmp r8, #255
mvnhi r8, r8, asr #31
strb r8, [r1, #5]
str r11, [r0], #4
add r9, r9, r5
cmp r9, #255
mvnhi r9, r9, asr #31
strb r9, [r1, #6]
add r10, r10, r6
cmp r10, #255
mvnhi r10, r10, asr #31
strb r10, [r1, #7]
str r11, [r0], #4
add r1, r1, r2
cmp r0, r12
blo 2b
ldmpc regs=r4-r11
3:
stmfd sp!, { r4-r5, lr }
ldrsh r1, [r0, #0] /* r1 = block[0] */
mov r4, #0
strh r4, [r0, #0] /* block[0] = 0 */
strh r4, [r0, #126] /* block[63] = 0 */
add r1, r1, #64 /* r1 = DC << 7 */
add r0, r2, r3, asl #3
4:
ldrb r4, [r2, #0]
ldrb r5, [r2, #1]
ldrb r12, [r2, #2]
ldrb lr, [r2, #3]
add r4, r4, r1, asr #7
cmp r4, #255
mvnhi r4, r4, asr #31
strb r4, [r2, #0]
add r5, r5, r1, asr #7
cmp r5, #255
mvnhi r5, r5, asr #31
strb r5, [r2, #1]
add r12, r12, r1, asr #7
cmp r12, #255
mvnhi r12, r12, asr #31
strb r12, [r2, #2]
add lr, lr, r1, asr #7
cmp lr, #255
mvnhi lr, lr, asr #31
strb lr, [r2, #3]
ldrb r4, [r2, #4]
ldrb r5, [r2, #5]
ldrb r12, [r2, #6]
ldrb lr, [r2, #7]
add r4, r4, r1, asr #7
cmp r4, #255
mvnhi r4, r4, asr #31
strb r4, [r2, #4]
add r5, r5, r1, asr #7
cmp r5, #255
mvnhi r5, r5, asr #31
strb r5, [r2, #5]
add r12, r12, r1, asr #7
cmp r12, #255
mvnhi r12, r12, asr #31
strb r12, [r2, #6]
add lr, lr, r1, asr #7
cmp lr, #255
mvnhi lr, lr, asr #31
strb lr, [r2, #7]
add r2, r2, r3
cmp r2, r0
blo 4b
ldmpc regs=r4-r5

View file

@ -0,0 +1,297 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 by Jens Arnold
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
.global mpeg2_idct_copy
.type mpeg2_idct_copy, %function
.global mpeg2_idct_add
.type mpeg2_idct_add, %function
/* Custom calling convention:
* r0 contains block pointer and is non-volatile
* all non-volatile c context saved and restored on its behalf
*/
.idct:
str lr, [sp, #-4]! @ lr is used
add r1, r0, #128 @ secondary, transposed temp buffer
mov r14, #8 @ loop counter
.row_loop:
ldmia r0!, {r2, r3, r10, r11} @ fetch f0, f2, f4, f6, f1, f3, f5, f7
ldrd r4, L_W1357 @ load W1, W3, W5, W7
smuad r6, r4, r10 @ b0 = W1 * f1 + W3 * f3
smultt r7, r5, r10 @ -b1 = W7 * f3
smulbt r8, r4, r10 @ -b2 = W1 * f3
smusdx r9, r10, r5 @ b3 = f1 * W7 - f3 * W5
smlabb r7, r4, r11, r7 @ -b1 += W1 * f5
rsb r8, r8, #0 @ b2 = -b2
smlabb r8, r5, r10, r8 @ b2 += W5 * f1
smlad r6, r5, r11, r6 @ b0 += W5 * f5 + W7 * f7
smlabt r7, r5, r11, r7 @ -b1 += W5 * f7
smlatb r8, r5, r11, r8 @ b2 += W7 * f5
smlsdx r9, r11, r4, r9 @ b3 += f5 * W3 - f7 * W1
rsb r7, r7, #0 @ b1 = -b1
smlatb r7, r4, r10, r7 @ b1 += W3 * f1
smlatt r8, r4, r11, r8 @ b2 += W3 * f7
ldrd r4, L_W0246 @ load W0, W2, W4, W6
add r2, r2, #1 @ f0 += 1
smulbb r10, r5, r3 @ a0' = W4 * f4
smultt r12, r5, r3 @ a3' = W6 * f6
smultt r3, r4, r3 @ -a2' = W2 * f6
rsb r11, r10, #0 @ a1' = -W4 * f4
smlabb r10, r4, r2, r10 @ a0' += W0 * f0
smlabb r11, r4, r2, r11 @ a1' += W0 * f0
smlatt r12, r4, r2, r12 @ a3' += W2 * f2
rsb r3, r3, #0 @ a2' = -a2'
smlatt r3, r5, r2, r3 @ a2' += W6 * f2
add r10, r10, r12 @ a0 = a0' + a3'
sub r12, r10, r12, lsl #1 @ a3 = a0 - 2 * a3'
add r11, r11, r3 @ a1 = a1' + a2'
sub r3, r11, r3, lsl #1 @ a2 = a1 - 2 * a2'
subs r14, r14, #1 @ decrease loop count
@ Special store order for making the column pass calculate columns in
@ the order 0-2-1-3-4-6-5-7, allowing for uxtab16 use in later stages.
sub r2, r10, r6 @ block[7] = (a0 - b0)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #7*16]
sub r2, r11, r7 @ block[6] = (a1 - b1)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #5*16]
sub r2, r3, r8 @ block[5] = (a2 - b2)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #6*16]
sub r2, r12, r9 @ block[4] = (a3 - b3)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #4*16]
add r2, r12, r9 @ block[3] = (a3 + b3)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #3*16]
add r2, r3, r8 @ block[2] = (a2 + b2)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #1*16]
add r2, r11, r7 @ block[1] = (a1 + b1)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1, #2*16]
add r2, r10, r6 @ block[0] = (a0 + b0)
mov r2, r2, asr #12 @ >> 12
strh r2, [r1], #2 @ advance to next temp column
bne .row_loop
b .col_start
@placed here because of ldrd's offset limit
L_W1357:
.short 2841
.short 2408
.short 1609
.short 565
L_W0246:
.short 2048
.short 2676
.short 2048
.short 1108
.col_start:
@ r0 now points to the temp buffer, where we need it.
sub r1, r1, #128+16 @ point r1 back to the input block
mov r14, #8 @ loop counter
.col_loop:
ldmia r0!, {r2, r3, r10, r11} @ fetch f0, f2, f4, f6, f1, f3, f5, f7
ldrd r4, L_W1357 @ load W1, W3, W5, W7
smuad r6, r4, r10 @ b0 = W1 * f1 + W3 * f3
smultt r7, r5, r10 @ -b1 = W7 * f3
smulbt r8, r4, r10 @ -b2 = W1 * f3
smusdx r9, r10, r5 @ b3 = f1 * W7 - f3 * W5
smlabb r7, r4, r11, r7 @ -b1 += W1 * f5
rsb r8, r8, #0 @ b2 = -b2
smlabb r8, r5, r10, r8 @ b2 += W5 * f1
smlad r6, r5, r11, r6 @ b0 += W5 * f5 + W7 * f7
smlabt r7, r5, r11, r7 @ -b1 += W5 * f7
smlatb r8, r5, r11, r8 @ b2 += W7 * f5
smlsdx r9, r11, r4, r9 @ b3 += f5 * W3 - f7 * W1
rsb r7, r7, #0 @ b1 = -b1
smlatb r7, r4, r10, r7 @ b1 += W3 * f1
smlatt r8, r4, r11, r8 @ b2 += W3 * f7
ldrd r4, L_W0246 @ load W0, W2, W4, W6
add r2, r2, #32 @ DC offset: 0.5
smulbb r10, r5, r3 @ a0' = W4 * f4
smultt r12, r5, r3 @ a3' = W6 * f6
smultt r3, r4, r3 @ -a2' = W2 * f6
rsb r11, r10, #0 @ a1' = -W4 * f4
smlabb r10, r4, r2, r10 @ a0' += W0 * f0
smlabb r11, r4, r2, r11 @ a1' += W0 * f0
smlatt r12, r4, r2, r12 @ a3' += W2 * f2
rsb r3, r3, #0 @ a2' = -a2'
smlatt r3, r5, r2, r3 @ a2' += W6 * f2
add r10, r10, r12 @ a0 = a0' + a3'
sub r12, r10, r12, lsl #1 @ a3 = a0 - 2 * a3'
add r11, r11, r3 @ a1 = a1' + a2'
sub r3, r11, r3, lsl #1 @ a2 = a1 - 2 * a2'
subs r14, r14, #1 @ decrease loop count
sub r2, r10, r6 @ block[7] = (a0 - b0)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #7*16]
sub r2, r11, r7 @ block[6] = (a1 - b1)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #6*16]
sub r2, r3, r8 @ block[5] = (a2 - b2)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #5*16]
sub r2, r12, r9 @ block[4] = (a3 - b3)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #4*16]
add r2, r12, r9 @ block[3] = (a3 + b3)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #3*16]
add r2, r3, r8 @ block[2] = (a2 + b2)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #2*16]
add r2, r11, r7 @ block[1] = (a1 + b1)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1, #1*16]
add r2, r10, r6 @ block[0] = (a0 + b0)
mov r2, r2, asr #17 @ >> 17
strh r2, [r1], #2 @ advance to next column
bne .col_loop
sub r0, r0, #256 @ point r0 back to the input block
ldr pc, [sp], #4
mpeg2_idct_copy:
stmfd sp!, {r1-r2, r4-r11, lr}
bl .idct
ldmfd sp!, {r1-r2}
add r3, r0, #128
mov r8, #0
mov r9, #0
mov r10, #0
mov r11, #0
1: @ idct data is in order 0-2-1-3-4-6-5-7,
ldmia r0, {r4-r7} @ see above
stmia r0!, {r8-r11}
usat16 r4, #8, r4
usat16 r5, #8, r5
orr r4, r4, r5, lsl #8
usat16 r6, #8, r6
usat16 r7, #8, r7
orr r5, r6, r7, lsl #8
strd r4, [r1] @ r4, r5
add r1, r1, r2
cmp r0, r3
blo 1b
ldmfd sp!, {r4-r11, pc}
mpeg2_idct_add:
cmp r0, #129
mov r0, r1
ldreqsh r1, [r0, #0]
bne 1f
and r1, r1, #0x70
cmp r1, #0x40
bne 3f
1:
stmfd sp!, {r2-r11, lr}
bl .idct
ldmfd sp!, {r1-r2}
add r3, r0, #128
mov r10, #0
mov r11, #0
mov r12, #0
mov lr, #0
ldrd r8, [r1] @ r8, r9
2: @ idct data is in order 0-2-1-3-4-6-5-7,
ldmia r0, {r4-r7} @ see above
stmia r0!, {r10-r12, lr}
uxtab16 r4, r4, r8
uxtab16 r5, r5, r8, ror #8
usat16 r4, #8, r4
usat16 r5, #8, r5
orr r4, r4, r5, lsl #8
uxtab16 r6, r6, r9
uxtab16 r7, r7, r9, ror #8
usat16 r6, #8, r6
usat16 r7, #8, r7
orr r5, r6, r7, lsl #8
strd r4, [r1] @ r4, r5
add r1, r1, r2
cmp r0, r3
ldrlod r8, [r1] @ r8, r9
blo 2b
ldmfd sp!, {r4-r11, pc}
3:
stmfd sp!, {r4, lr}
ldrsh r4, [r0, #0] @ r4 = block[0]
mov r12, #0
strh r12, [r0, #0] @ block[0] = 0
strh r12, [r0, #126] @ block[63] = 0
add r4, r4, #64
mov r4, r4, asr #7 @ r4 = DC
mov r4, r4, lsl #16 @ spread to 2 halfwords
orr r4, r4, r4, lsr #16
ldrd r0, [r2] @ r0, r1
add r12, r2, r3, asl #3
4:
uxtab16 lr, r4, r0, ror #8
uxtab16 r0, r4, r0
usat16 lr, #8, lr
usat16 r0, #8, r0
orr r0, r0, lr, lsl #8
uxtab16 lr, r4, r1, ror #8
uxtab16 r1, r4, r1
usat16 lr, #8, lr
usat16 r1, #8, r1
orr r1, r1, lr, lsl #8
strd r0, [r2] @ r0, r1
add r2, r2, r3
cmp r2, r12
ldrlod r0, [r2] @ r0, r1
blo 4b
ldmfd sp!, {r4, pc}

View file

@ -0,0 +1,575 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Jens Arnold
* Based on the work of Karim Boucher and Rani Hod
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
.global mpeg2_idct_copy
.type mpeg2_idct_copy, @function
.global mpeg2_idct_add
.type mpeg2_idct_add, @function
/* The IDCT itself.
* Input: %a0: block pointer
* Caller must save all registers. */
.align 2
.idct:
move.l %a0, %a6
move.l #0, %macsr | signed integer mode
move.l #((2048<<16)+2841), %a0 | W0, W1
move.l #((2676<<16)+2408), %a1 | W2, W3
move.l #((2048<<16)+1609), %a2 | W4, W5
move.l #((1108<<16)+ 565), %a3 | W6, W7
lea.l (128,%a6), %a4 | secondary, transposed temp buffer
moveq.l #8, %d3 | loop counter
.row_loop:
movem.l (%a6), %d0-%d2/%a5 | fetch (f0, f2, f4, f6, f1, f3, f5, f7)
mac.w %a0l, %d2u, %acc0 | %acc0 = W1 * f1
mac.w %a1l, %d2l, %acc0 | + W3 * f3
mac.w %a2l, %a5u, %acc0 | + W5 * f5
mac.w %a3l, %a5l, %acc0 | + W7 * f7
mac.w %a1l, %d2u, %acc1 | %acc1 = W3 * f1
msac.w %a3l, %d2l, %acc1 | - W7 * f3
msac.w %a0l, %a5u, %acc1 | - W1 * f5
msac.w %a2l, %a5l, %acc1 | - W5 * f7
mac.w %a2l, %d2u, %acc2 | %acc2 = W5 * f1
msac.w %a0l, %d2l, %acc2 | - W1 * f3
mac.w %a3l, %a5u, %acc2 | + W7 * f5
mac.w %a1l, %a5l, %acc2 | + W3 * f7
mac.w %a3l, %d2u, %acc3 | %acc3 = W7 * f1
msac.w %a2l, %d2l, %acc3 | - W5 * f3
mac.w %a1l, %a5u, %acc3 | + W3 * f5
msac.w %a0l, %a5l, %acc3 | - W1 * f7
lea.l (16,%a6), %a6 | Advance to next row; put here to fill EMAC latency
add.l #(1<<16), %d0 | f0 += 1;
movclr.l %acc0, %d4 | b0
movclr.l %acc1, %d5 | b1
movclr.l %acc2, %d6 | b2
movclr.l %acc3, %d7 | b3
mac.w %a0u, %d0u, %acc0 | %acc0 = W0 * f0
mac.w %a2u, %d1u, %acc0 | + W4 * f4
move.l %acc0, %acc3
mac.w %a1u, %d0l, %acc0 | + W2 * f2
mac.w %a3u, %d1l, %acc0 | + W6 * f6
mac.w %a0u, %d0u, %acc1 | %acc1 = W0 * f0
msac.w %a2u, %d1u, %acc1 | - W4 * f4
move.l %acc1, %acc2
mac.w %a3u, %d0l, %acc1 | + W6 * f2
msac.w %a1u, %d1l, %acc1 | - W2 * f6
| ^ move.l %acc1, %acc2 %acc2 = W0 * f0 - W4 * f4
msac.w %a3u, %d0l, %acc2 | - W6 * f2
mac.w %a1u, %d1l, %acc2 | + W2 * f6
| ^ move.l %acc0, %acc3 %acc3 = W0 * f0 + W4 * f4
msac.w %a1u, %d0l, %acc3 | - W2 * f2
msac.w %a3u, %d1l, %acc3 | - W6 * f6
moveq.l #12, %d1 | shift amount
move.l %acc0, %d0 | block[7] = (a0
sub.l %d4,%d0 | - b0)
asr.l %d1, %d0 | >> 12
move.w %d0, (7*16,%a4)
move.l %acc1, %d0 | block[6] = (a1
sub.l %d5,%d0 | - b1)
asr.l %d1, %d0 | >> 12
move.w %d0, (6*16,%a4)
move.l %acc2, %d0 | block[5] = (a2
sub.l %d6,%d0 | - b2)
asr.l %d1, %d0 | >> 12
move.w %d0, (5*16,%a4)
move.l %acc3, %d0 | block[4] = (a3
sub.l %d7,%d0 | - b3)
asr.l %d1, %d0 | >> 12
move.w %d0, (4*16,%a4)
movclr.l %acc3, %d0 | block[3] = (a3
add.l %d7, %d0 | + b3)
asr.l %d1, %d0 | >> 12
move.w %d0, (3*16,%a4)
movclr.l %acc2, %d0 | block[2] = (a2
add.l %d6, %d0 | + b2)
asr.l %d1, %d0 | >> 12
move.w %d0, (2*16,%a4)
movclr.l %acc1, %d0 | block[1] = (a1
add.l %d5, %d0 | + b1)
asr.l %d1, %d0 | >> 12
move.w %d0, (1*16,%a4)
movclr.l %acc0, %d0 | block[0] = (a0
add.l %d4, %d0 | + b0)
asr.l %d1, %d0 | >> 12
move.w %d0, (%a4)+ | advance to next temp column
subq.l #1, %d3 | loop 8 times
bne.w .row_loop
| %a6 now points to the temp buffer, where we need it.
lea.l (-16-128,%a4), %a4 | point %a4 back to the input block
moveq.l #8, %d3 | loop counter
.col_loop:
movem.l (%a6), %d0-%d2/%a5 | fetch (f0, f2, f4, f6, f1, f3, f5, f7)
mac.w %a0l, %d2u, %acc0 | %acc0 = W1 * f1
mac.w %a1l, %d2l, %acc0 | + W3 * f3
mac.w %a2l, %a5u, %acc0 | + W5 * f5
mac.w %a3l, %a5l, %acc0 | + W7 * f7
mac.w %a1l, %d2u, %acc1 | %acc1 = W3 * f1
msac.w %a3l, %d2l, %acc1 | - W7 * f3
msac.w %a0l, %a5u, %acc1 | - W1 * f5
msac.w %a2l, %a5l, %acc1 | - W5 * f7
mac.w %a2l, %d2u, %acc2 | %acc2 = W5 * f1
msac.w %a0l, %d2l, %acc2 | - W1 * f3
mac.w %a3l, %a5u, %acc2 | + W7 * f5
mac.w %a1l, %a5l, %acc2 | + W3 * f7
mac.w %a3l, %d2u, %acc3 | %acc3 = W7 * f1
msac.w %a2l, %d2l, %acc3 | - W5 * f3
mac.w %a1l, %a5u, %acc3 | + W3 * f5
msac.w %a0l, %a5l, %acc3 | - W1 * f7
lea.l (16,%a6), %a6 | Advance to next row; put here to fill EMAC latency
add.l #(32<<16), %d0 | DC offset: 0.5
movclr.l %acc0, %d4 | b0
movclr.l %acc1, %d5 | b1
movclr.l %acc2, %d6 | b2
movclr.l %acc3, %d7 | b3
mac.w %a0u, %d0u, %acc0 | %acc0 = W0 * f0
mac.w %a2u, %d1u, %acc0 | + W4 * f4
move.l %acc0, %acc3
mac.w %a1u, %d0l, %acc0 | + W2 * f2
mac.w %a3u, %d1l, %acc0 | + W6 * f6
mac.w %a0u, %d0u, %acc1 | %acc1 = W0 * f0
msac.w %a2u, %d1u, %acc1 | - W4 * f4
move.l %acc1, %acc2
mac.w %a3u, %d0l, %acc1 | + W6 * f2
msac.w %a1u, %d1l, %acc1 | - W2 * f6
| ^ move.l %acc1, %acc2 %acc2 = W0 * f0 - W4 * f4
msac.w %a3u, %d0l, %acc2 | - W6 * f2
mac.w %a1u, %d1l, %acc2 | + W2 * f6
| ^ move.l %acc0, %acc3 %acc3 = W0 * f0 + W4 * f4
msac.w %a1u, %d0l, %acc3 | - W2 * f2
msac.w %a3u, %d1l, %acc3 | - W6 * f6
moveq.l #17, %d1 | shift amount
move.l %acc0, %d0 | block[7] = (a0
sub.l %d4,%d0 | - b0)
asr.l %d1, %d0 | >> 17
move.w %d0, (7*16,%a4)
move.l %acc1, %d0 | block[6] = (a1
sub.l %d5,%d0 | - b1)
asr.l %d1, %d0 | >> 17
move.w %d0, (6*16,%a4)
move.l %acc2, %d0 | block[5] = (a2
sub.l %d6,%d0 | - b2)
asr.l %d1, %d0 | >> 17
move.w %d0, (5*16,%a4)
move.l %acc3, %d0 | block[4] = (a3
sub.l %d7,%d0 | - b3)
asr.l %d1, %d0 | >> 17
move.w %d0, (4*16,%a4)
movclr.l %acc3, %d0 | block[3] = (a3
add.l %d7, %d0 | + b3)
asr.l %d1, %d0 | >> 17
move.w %d0, (3*16,%a4)
movclr.l %acc2, %d0 | block[2] = (a2
add.l %d6, %d0 | + b2)
asr.l %d1, %d0 | >> 17
move.w %d0, (2*16,%a4)
movclr.l %acc1, %d0 | block[1] = (a1
add.l %d5, %d0 | + b1)
asr.l %d1, %d0 | >> 17
move.w %d0, (1*16,%a4)
movclr.l %acc0, %d0 | block[0] = (a0
add.l %d4, %d0 | + b0)
asr.l %d1, %d0 | >> 17
move.w %d0, (%a4)+ | advance to next column
subq.l #1, %d3 | loop 8 times
bne.w .col_loop
rts
.align 2
mpeg2_idct_copy:
lea.l (-11*4,%sp), %sp
movem.l %d2-%d7/%a2-%a6, (%sp) | save some registers
move.l (11*4+4,%sp), %a0 | %a0 - block pointer for idct
bsr.w .idct | apply idct to block
movem.l (11*4+4,%sp), %a0-%a2 | %a0 - block pointer
| %a1 - destination pointer
| %a2 - stride
move.l #255, %d1 | preload constant for clipping
moveq.l #8, %d4 | loop counter
.copy_clip_loop:
move.w (%a0), %d0 | load block[0]
ext.l %d0 | sign extend
cmp.l %d1, %d0 | overflow?
bls.b 1f
spl.b %d0 | yes: set appropriate limit value in low byte
1:
move.b %d0, %d2 | collect output bytes 0..3 in %d2
lsl.l #8, %d2
move.w (2,%a0), %d0 | load block[1]
ext.l %d0 | sign extend
cmp.l %d1, %d0 | overflow?
bls.b 1f
spl.b %d0 | yes: set appropriate limit value in low byte
1:
move.b %d0, %d2 | collect output bytes 0..3 in %d2
lsl.l #8, %d2
clr.l (%a0)+ | clear block[0] and block[1],
| %a0 now pointing to block[2]
move.w (%a0), %d0 | do b2 and b3
ext.l %d0
cmp.l %d1, %d0
bls.b 1f
spl.b %d0
1:
move.b %d0, %d2
lsl.l #8, %d2
move.w (2,%a0), %d0
ext.l %d0
cmp.l %d1, %d0
bls.b 1f
spl.b %d0
1:
move.b %d0, %d2
clr.l (%a0)+
move.w (%a0), %d0 | do b4 and b5
ext.l %d0
cmp.l %d1, %d0
bls.b 1f
spl.b %d0
1:
move.b %d0, %d3
lsl.l #8, %d3
move.w (2,%a0), %d0
ext.l %d0
cmp.l %d1, %d0
bls.b 1f
spl.b %d0
1:
move.b %d0, %d3
lsl.l #8, %d3
clr.l (%a0)+
move.w (%a0), %d0 | do b6 and b7
ext.l %d0
cmp.l %d1, %d0
bls.b 1f
spl.b %d0
1:
move.b %d0, %d3
lsl.l #8, %d3
move.w (2,%a0), %d0
ext.l %d0
cmp.l %d1, %d0
bls.b 1f
spl.b %d0
1:
move.b %d0, %d3
clr.l (%a0)+
movem.l %d2-%d3, (%a1) | write all 8 output bytes at once
add.l %a2, %a1 | advance output pointer
subq.l #1, %d4 | loop 8 times
bne.w .copy_clip_loop
movem.l (%sp), %d2-%d7/%a2-%a6
lea.l (11*4,%sp), %sp
rts
.align 2
mpeg2_idct_add:
lea.l (-11*4,%sp), %sp
movem.l %d2-%d7/%a2-%a6, (%sp)
movem.l (11*4+4,%sp), %d0/%a0-%a2 | %d0 - last value
| %a0 - block pointer
| %a1 - destination pointer
| %a2 - stride
cmp.l #129, %d0 | last == 129 ?
bne.b .idct_add | no: perform idct + addition
move.w (%a0), %d0
ext.l %d0 | ((block[0]
asr.l #4, %d0 | >> 4)
and.l #7, %d0 | & 7)
subq.l #4, %d0 | - 4 == 0 ?
bne.w .dc_add | no: just perform addition
.idct_add:
bsr.w .idct | apply idct
movem.l (11*4+8,%sp), %a0-%a2 | reload arguments %a0..%a2
move.l #255, %d2 | preload constant for clipping
clr.l %d3 | used for splitting input words into bytes
moveq.l #8, %d4 | loop counter
.add_clip_loop:
movem.l (%a1), %d6-%d7 | fetch (b0 b1 b2 b3) (b4 b5 b6 b7)
swap %d6 | (b2 b3 b0 b1)
swap %d7 | (b6 b7 b4 b5)
move.w (2,%a0), %d0 | load block[1]
ext.l %d0 | sign extend
move.b %d6, %d3 | copy b1
lsr.l #8, %d6 | prepare 1st buffer for next byte
add.l %d3, %d0 | add b1
cmp.l %d2, %d0 | overflow ?
bls.b 1f
spl.b %d0 | yes: set appropriate limit value in low byte
1:
move.w (%a0), %d1 | load block[0]
ext.l %d1 | sign extend
move.b %d6, %d3 | copy b0
lsr.l #8, %d6 | prepare 1st buffer for next byte
add.l %d3, %d1 | add b0
cmp.l %d2, %d1 | overflow ?
bls.b 1f
spl.b %d1 | yes: set appropriate limit value in low byte
1:
move.b %d1, %d5 | collect output bytes 0..3 in %d5
lsl.l #8, %d5
move.b %d0, %d5
lsl.l #8, %d5
clr.l (%a0)+ | clear block[0] and block[1]
| %a0 now pointing to block[2]
move.w (2,%a0), %d0 | do b3 and b2
ext.l %d0
move.b %d6, %d3
lsr.l #8, %d6
add.l %d3, %d0
cmp.l %d2, %d0
bls.b 1f
spl.b %d0
1:
move.w (%a0), %d1
ext.l %d1
add.l %d6, %d1
cmp.l %d2, %d1
bls.b 1f
spl.b %d1
1:
move.b %d1, %d5
lsl.l #8, %d5
move.b %d0, %d5
clr.l (%a0)+
move.w (2,%a0), %d0 | do b5 and b4
ext.l %d0
move.b %d7, %d3
lsr.l #8, %d7
add.l %d3, %d0
cmp.l %d2, %d0
bls.b 1f
spl.b %d0
1:
move.w (%a0), %d1
ext.l %d1
move.b %d7, %d3
lsr.l #8, %d7
add.l %d3, %d1
cmp.l %d2, %d1
bls.b 1f
spl.b %d1
1:
move.b %d1, %d6
lsl.l #8, %d6
move.b %d0, %d6
lsl.l #8, %d6
clr.l (%a0)+
move.w (2,%a0), %d0 | do b7 and b6
ext.l %d0
move.b %d7, %d3
lsr.l #8, %d7
add.l %d3, %d0
cmp.l %d2, %d0
bls.b 1f
spl.b %d0
1:
move.w (%a0), %d1
ext.l %d1
add.l %d7, %d1
cmp.l %d2, %d1
bls.b 1f
spl.b %d1
1:
move.b %d1, %d6
lsl.l #8, %d6
move.b %d0, %d6
clr.l (%a0)+
movem.l %d5-%d6, (%a1) | write all 8 output bytes at once
add.l %a2, %a1 | advance output pointer
subq.l #1, %d4 | loop 8 times
bne.w .add_clip_loop
bra.w .idct_add_end
.dc_add:
move.w (%a0), %d0
ext.l %d0 | %d0 = (block[0]
add.l #64, %d0 | + 64)
asr.l #7, %d0 | >> 7
clr.w (%a0) | clear block[0]
clr.w (63*2,%a0) | and block[63]
move.l %d0, %a0 | DC value in %a0
move.l #255, %d2 | preload constant for clipping
clr.l %d3 | for splitting input words into bytes
moveq.l #8, %d4 | loop counter
.dc_clip_loop:
movem.l (%a1), %d6-%d7 | (b0 b1 b2 b3) (b4 b5 b6 b7)
swap %d6 | (b2 b3 b0 b1)
swap %d7 | (b6 b7 b4 b5)
move.l %a0, %d0 | copy DC
move.b %d6, %d3 | copy b1
lsr.l #8, %d6 | prepare 1st buffer for next byte
add.l %d3, %d0 | add b1
cmp.l %d2, %d0 | overflow ?
bls.b 1f
spl.b %d0 | yes: set appropriate limit value in low byte
1:
move.l %a0, %d1 | copy DC
move.b %d6, %d3 | copy b0
lsr.l #8, %d6 | prepare 1st buffer for next byte
add.l %d3, %d1 | add b0
cmp.l %d2, %d1 | overflow ?
bls.b 1f
spl.b %d1 | yes: set appropriate limit value in low byte
1:
move.b %d1, %d5 | collect output bytes 0..3 in %d5
lsl.l #8, %d5
move.b %d0, %d5
lsl.l #8, %d5
move.l %a0, %d0 | do b3 and b2
move.b %d6, %d3
lsr.l #8, %d6
add.l %d3, %d0
cmp.l %d2, %d0
bls.b 1f
spl.b %d0
1:
move.l %a0, %d1
add.l %d6, %d1
cmp.l %d2, %d1
bls.b 1f
spl.b %d1
1:
move.b %d1, %d5
lsl.l #8, %d5
move.b %d0, %d5
move.l %a0, %d0 | do b5 and b4
move.b %d7, %d3
lsr.l #8, %d7
add.l %d3, %d0
cmp.l %d2, %d0
bls.b 1f
spl.b %d0
1:
move.l %a0, %d1
move.b %d7, %d3
lsr.l #8, %d7
add.l %d3, %d1
cmp.l %d2, %d1
bls.b 1f
spl.b %d1
1:
move.b %d1, %d6 | do b7 and b6
lsl.l #8, %d6
move.b %d0, %d6
lsl.l #8, %d6
move.l %a0, %d0
move.b %d7, %d3
lsr.l #8, %d7
add.l %d3, %d0
cmp.l %d2, %d0
bls.b 1f
spl.b %d0
1:
move.l %a0, %d1
add.l %d7, %d1
cmp.l %d2, %d1
bls.b 1f
spl.b %d1
1:
move.b %d1, %d6
lsl.l #8, %d6
move.b %d0, %d6
movem.l %d5-%d6, (%a1) | write all 8 output bytes at once
add.l %a2, %a1 | advance output pointer
subq.l #1, %d4 | loop 8 times
bne.w .dc_clip_loop
.idct_add_end:
movem.l (%sp), %d2-%d7/%a2-%a6
lea.l (11*4,%sp), %sp
rts

View file

@ -0,0 +1,66 @@
/*
* motion_comp.c
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.17 - lost compatibility previously to
* provide simplified and CPU-optimized motion compensation.
*/
#include "plugin.h"
#include "mpeg2dec_config.h"
#include "mpeg2.h"
#include "attributes.h"
#include "mpeg2_internal.h"
/* These are defined in their respective target files - motion_comp_X.c */
extern mpeg2_mc_fct MC_put_o_16;
extern mpeg2_mc_fct MC_put_o_8;
extern mpeg2_mc_fct MC_put_x_16;
extern mpeg2_mc_fct MC_put_x_8;
extern mpeg2_mc_fct MC_put_y_16;
extern mpeg2_mc_fct MC_put_y_8;
extern mpeg2_mc_fct MC_put_xy_16;
extern mpeg2_mc_fct MC_put_xy_8;
extern mpeg2_mc_fct MC_avg_o_16;
extern mpeg2_mc_fct MC_avg_o_8;
extern mpeg2_mc_fct MC_avg_x_16;
extern mpeg2_mc_fct MC_avg_x_8;
extern mpeg2_mc_fct MC_avg_y_16;
extern mpeg2_mc_fct MC_avg_y_8;
extern mpeg2_mc_fct MC_avg_xy_16;
extern mpeg2_mc_fct MC_avg_xy_8;
const mpeg2_mc_t mpeg2_mc =
{
{
MC_put_o_16, MC_put_x_16, MC_put_y_16, MC_put_xy_16,
MC_put_o_8, MC_put_x_8, MC_put_y_8, MC_put_xy_8
},
{
MC_avg_o_16, MC_avg_x_16, MC_avg_y_16, MC_avg_xy_16,
MC_avg_o_8, MC_avg_x_8, MC_avg_y_8, MC_avg_xy_8
}
};

View file

@ -0,0 +1,86 @@
/*
* motion_comp.h
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
*/
#define avg2(a,b) ((a+b+1)>>1)
#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
#define predict_o(i) (ref[i])
#define predict_x(i) (avg2 (ref[i], ref[i+1]))
#define predict_y(i) (avg2 (ref[i], (ref+stride)[i]))
#define predict_xy(i) (avg4 (ref[i], ref[i+1], \
(ref+stride)[i], (ref+stride)[i+1]))
#define put(predictor,i) dest[i] = predictor (i)
#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i])
/* mc function template */
#define MC_FUNC(op, xy) \
MC_FUNC_16(op, xy) \
MC_FUNC_8(op, xy)
#define MC_FUNC_16(op, xy) \
void MC_##op##_##xy##_16 (uint8_t * dest, const uint8_t * ref, \
const int stride, int height) \
{ \
do { \
op (predict_##xy, 0); \
op (predict_##xy, 1); \
op (predict_##xy, 2); \
op (predict_##xy, 3); \
op (predict_##xy, 4); \
op (predict_##xy, 5); \
op (predict_##xy, 6); \
op (predict_##xy, 7); \
op (predict_##xy, 8); \
op (predict_##xy, 9); \
op (predict_##xy, 10); \
op (predict_##xy, 11); \
op (predict_##xy, 12); \
op (predict_##xy, 13); \
op (predict_##xy, 14); \
op (predict_##xy, 15); \
ref += stride; \
dest += stride; \
} while (--height); \
}
#define MC_FUNC_8(op, xy) \
void MC_##op##_##xy##_8 (uint8_t * dest, const uint8_t * ref, \
const int stride, int height) \
{ \
do { \
op (predict_##xy, 0); \
op (predict_##xy, 1); \
op (predict_##xy, 2); \
op (predict_##xy, 3); \
op (predict_##xy, 4); \
op (predict_##xy, 5); \
op (predict_##xy, 6); \
op (predict_##xy, 7); \
ref += stride; \
dest += stride; \
} while (--height); \
}

View file

@ -0,0 +1,39 @@
/*
* motion_comp_arm.c
* Copyright (C) 2004 AGAWA Koji <i (AT) atty (DOT) jp>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
*/
#include <inttypes.h>
#include "mpeg2.h"
#include "attributes.h"
#include "mpeg2_internal.h"
#include "motion_comp.h"
/* definitions of the actual mc functions */
/* MC_FUNC (put, o) <= ASM */
MC_FUNC (avg, o)
/* MC_FUNC (put, x) <= ASM */
MC_FUNC (avg, x)
MC_FUNC (put, y)
MC_FUNC (avg, y)
MC_FUNC (put, xy)
MC_FUNC (avg, xy)

View file

@ -0,0 +1,342 @@
@ motion_comp_arm_s.S
@ Copyright (C) 2004 AGAWA Koji <i (AT) atty (DOT) jp>
@
@ This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
@ See http://libmpeg2.sourceforge.net/ for updates.
@
@ mpeg2dec is free software; you can redistribute it and/or modify
@ it under the terms of the GNU General Public License as published by
@ the Free Software Foundation; either version 2 of the License, or
@ (at your option) any later version.
@
@ mpeg2dec is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ GNU General Public License for more details.
@
@ You should have received a copy of the GNU General Public License
@ along with this program; if not, write to the Free Software
@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@
@ $Id$
#include "config.h" /* Rockbox: ARM architecture version */
.text
@ ----------------------------------------------------------------
.align
.global MC_put_o_16
MC_put_o_16:
@@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
@@ pld [r1]
stmfd sp!, {r4-r7, lr} @ R14 is also called LR
and r4, r1, #3
ldr pc, [pc, r4, lsl #2]
.word 0
.word MC_put_o_16_align0
.word MC_put_o_16_align1
.word MC_put_o_16_align2
.word MC_put_o_16_align3
MC_put_o_16_align0:
ldmia r1, {r4-r7}
add r1, r1, r2
@@ pld [r1]
stmia r0, {r4-r7}
subs r3, r3, #1
add r0, r0, r2
bne MC_put_o_16_align0
ldmpc regs=r4-r7 @@ update PC with LR content.
.macro ADJ_ALIGN_QW shift, R0, R1, R2, R3, R4
mov \R0, \R0, lsr #(\shift)
orr \R0, \R0, \R1, lsl #(32 - \shift)
mov \R1, \R1, lsr #(\shift)
orr \R1, \R1, \R2, lsl #(32 - \shift)
mov \R2, \R2, lsr #(\shift)
orr \R2, \R2, \R3, lsl #(32 - \shift)
mov \R3, \R3, lsr #(\shift)
orr \R3, \R3, \R4, lsl #(32 - \shift)
mov \R4, \R4, lsr #(\shift)
.endm
MC_put_o_16_align1:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4-r7, r12}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_QW 8, r4, r5, r6, r7, r12
stmia r0, {r4-r7}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-r7 @@ update PC with LR content.
MC_put_o_16_align2:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4-r7, r12}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_QW 16, r4, r5, r6, r7, r12
stmia r0, {r4-r7}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-r7 @@ update PC with LR content.
MC_put_o_16_align3:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4-r7, r12}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_QW 24, r4, r5, r6, r7, r12
stmia r0, {r4-r7}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-r7 @@ update PC with LR content.
@ ----------------------------------------------------------------
.align
.global MC_put_o_8
MC_put_o_8:
@@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
@@ pld [r1]
stmfd sp!, {r4, r5, lr} @ R14 is also called LR
and r4, r1, #3
ldr pc, [pc, r4, lsl #2]
.word 0
.word MC_put_o_8_align0
.word MC_put_o_8_align1
.word MC_put_o_8_align2
.word MC_put_o_8_align3
MC_put_o_8_align0:
ldmia r1, {r4, r5}
add r1, r1, r2
@@ pld [r1]
stmia r0, {r4, r5}
add r0, r0, r2
subs r3, r3, #1
bne MC_put_o_8_align0
ldmpc regs=r4-r5 @@ update PC with LR content.
.macro ADJ_ALIGN_DW shift, R0, R1, R2
mov \R0, \R0, lsr #(\shift)
orr \R0, \R0, \R1, lsl #(32 - \shift)
mov \R1, \R1, lsr #(\shift)
orr \R1, \R1, \R2, lsl #(32 - \shift)
mov \R2, \R2, lsr #(\shift)
.endm
MC_put_o_8_align1:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4, r5, r12}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_DW 8, r4, r5, r12
stmia r0, {r4, r5}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-r5 @@ update PC with LR content.
MC_put_o_8_align2:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4, r5, r12}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_DW 16, r4, r5, r12
stmia r0, {r4, r5}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-r5 @@ update PC with LR content.
MC_put_o_8_align3:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4, r5, r12}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_DW 24, r4, r5, r12
stmia r0, {r4, r5}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-r5 @@ update PC with LR content.
@ ----------------------------------------------------------------
.macro AVG_PW rW1, rW2
mov \rW2, \rW2, lsl #24
orr \rW2, \rW2, \rW1, lsr #8
eor r9, \rW1, \rW2
#if ARM_ARCH >= 6
uhadd8 \rW2, \rW1, \rW2
#else
and \rW2, \rW1, \rW2
and r10, r9, r11
add \rW2, \rW2, r10, lsr #1
#endif
and r9, r9, r12
add \rW2, \rW2, r9
.endm
#if ARM_ARCH >= 6
#define HIGHEST_REG r9
#else
#define HIGHEST_REG r11
#endif
.align
.global MC_put_x_16
MC_put_x_16:
@@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
@@ pld [r1]
stmfd sp!, {r4-HIGHEST_REG, lr} @ R14 is also called LR
and r4, r1, #3
ldr r12, 2f
#if ARM_ARCH < 6
mvn r11, r12
#endif
ldr pc, [pc, r4, lsl #2]
2: .word 0x01010101
.word MC_put_x_16_align0
.word MC_put_x_16_align1
.word MC_put_x_16_align2
.word MC_put_x_16_align3
MC_put_x_16_align0:
ldmia r1, {r4-r8}
add r1, r1, r2
@@ pld [r1]
AVG_PW r7, r8
AVG_PW r6, r7
AVG_PW r5, r6
AVG_PW r4, r5
stmia r0, {r5-r8}
subs r3, r3, #1
add r0, r0, r2
bne MC_put_x_16_align0
ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
MC_put_x_16_align1:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4-r8}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_QW 8, r4, r5, r6, r7, r8
AVG_PW r7, r8
AVG_PW r6, r7
AVG_PW r5, r6
AVG_PW r4, r5
stmia r0, {r5-r8}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
MC_put_x_16_align2:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4-r8}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_QW 16, r4, r5, r6, r7, r8
AVG_PW r7, r8
AVG_PW r6, r7
AVG_PW r5, r6
AVG_PW r4, r5
stmia r0, {r5-r8}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
MC_put_x_16_align3:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r4-r8}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_QW 24, r4, r5, r6, r7, r8
AVG_PW r7, r8
AVG_PW r6, r7
AVG_PW r5, r6
AVG_PW r4, r5
stmia r0, {r5-r8}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r4-HIGHEST_REG @@ update PC with LR content.
@ ----------------------------------------------------------------
.align
.global MC_put_x_8
MC_put_x_8:
@@ void func(uint8_t * dest, const uint8_t * ref, int stride, int height)
@@ pld [r1]
stmfd sp!, {r6-HIGHEST_REG, lr} @ R14 is also called LR
and r6, r1, #3
ldr r12, 2f
#if ARM_ARCH < 6
mvn r11, r12
#endif
ldr pc, [pc, r6, lsl #2]
2: .word 0x01010101
.word MC_put_x_8_align0
.word MC_put_x_8_align1
.word MC_put_x_8_align2
.word MC_put_x_8_align3
MC_put_x_8_align0:
ldmia r1, {r6-r8}
add r1, r1, r2
@@ pld [r1]
AVG_PW r7, r8
AVG_PW r6, r7
stmia r0, {r7-r8}
subs r3, r3, #1
add r0, r0, r2
bne MC_put_x_8_align0
ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
MC_put_x_8_align1:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r6-r8}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_DW 8, r6, r7, r8
AVG_PW r7, r8
AVG_PW r6, r7
stmia r0, {r7-r8}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
MC_put_x_8_align2:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r6-r8}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_DW 16, r6, r7, r8
AVG_PW r7, r8
AVG_PW r6, r7
stmia r0, {r7-r8}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.
MC_put_x_8_align3:
and r1, r1, #0xFFFFFFFC
1: ldmia r1, {r6-r8}
add r1, r1, r2
@@ pld [r1]
ADJ_ALIGN_DW 24, r6, r7, r8
AVG_PW r7, r8
AVG_PW r6, r7
stmia r0, {r7-r8}
subs r3, r3, #1
add r0, r0, r2
bne 1b
ldmpc regs=r6-HIGHEST_REG @@ update PC with LR content.

View file

@ -0,0 +1,40 @@
/*
* motion_comp.c
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
*/
#include <inttypes.h>
#include "mpeg2.h"
#include "attributes.h"
#include "mpeg2_internal.h"
#include "motion_comp.h"
/* definitions of the actual mc functions */
MC_FUNC (put, o)
MC_FUNC (avg, o)
MC_FUNC (put, x)
MC_FUNC (avg, x)
MC_FUNC (put, y)
MC_FUNC (avg, y)
MC_FUNC (put, xy)
MC_FUNC (avg, xy)

View file

@ -0,0 +1,38 @@
/*
* Based on:
* motion_comp_arm.c
* Copyright (C) 2004 AGAWA Koji <i (AT) atty (DOT) jp>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <inttypes.h>
#include "mpeg2.h"
#include "attributes.h"
#include "mpeg2_internal.h"
#include "motion_comp.h"
/* definitions of the actual mc functions */
/* MC_FUNC (put, o) <= ASM */
MC_FUNC (avg, o)
/* MC_FUNC (put, x) <= ASM */
MC_FUNC (avg, x)
MC_FUNC (put, y)
MC_FUNC (avg, y)
MC_FUNC (put, xy)
MC_FUNC (avg, xy)

View file

@ -0,0 +1,436 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Jens Arnold
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
.macro LEFT8_PW dW1, dW2 | needs %d0 == 24, clobbers %d2
lsl.l #8, \dW1 | changes dW1, keeps dW2
move.l \dW2, %d2
lsr.l %d0, %d2
or.l %d2, \dW1
.endm
.macro LEFT24_PW dW1, dW2 | needs %d0 == 24, clobbers %d2
lsl.l %d0, \dW1 | changes dW1, keeps dW2
move.l \dW2, %d2
lsr.l #8, %d2
or.l %d2, \dW1
.endm
/*****************************************************************************/
.align 2
.global MC_put_o_8
.type MC_put_o_8, @function
MC_put_o_8:
movem.l (4,%sp), %a0-%a1 | dest, source
move.l %a1, %d0
and.l #3, %d0
sub.l %d0, %a1 | align source
jmp.l (2, %pc, %d0.l*4)
bra.w .po8_0
bra.w .po8_1
bra.w .po8_2
| last table entry coincides with target
.po8_3:
lea.l (-5*4,%sp), %sp
movem.l %d2-%d5/%a2, (%sp) | save some registers
move.l (5*4+12,%sp), %a2 | stride
move.l (5*4+16,%sp), %d1 | height
moveq.l #24, %d0 | shift amount
1:
movem.l (%a1), %d3-%d5
add.l %a2, %a1
LEFT24_PW %d3, %d4
lsl.l %d0, %d4
lsr.l #8, %d5
or.l %d5, %d4
movem.l %d3-%d4, (%a0)
add.l %a2, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d5/%a2
lea.l (5*4,%sp), %sp
rts
.po8_2:
lea.l (-3*4,%sp), %sp
movem.l %d2-%d4, (%sp) | save some registers
movem.l (3*4+12,%sp), %d0-%d1 | stride, height
1:
movem.l (%a1), %d2-%d4
add.l %d0, %a1
swap %d2
swap %d3
move.w %d3, %d2
swap %d4
move.w %d4, %d3
movem.l %d2-%d3, (%a0)
add.l %d0, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d4
lea.l (3*4,%sp), %sp
rts
.po8_1:
lea.l (-5*4,%sp), %sp
movem.l %d2-%d5/%a2, (%sp) | save some registers
move.l (5*4+12,%sp), %a2 | stride
move.l (5*4+16,%sp), %d1 | height
moveq.l #24, %d0 | shift amount
1:
movem.l (%a1), %d3-%d5
add.l %a2, %a1
LEFT8_PW %d3, %d4
lsl.l #8, %d4
lsr.l %d0, %d5
or.l %d5, %d4
movem.l %d3-%d4, (%a0)
add.l %a2, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d5/%a2
lea.l (5*4,%sp), %sp
rts
.po8_0:
movem.l (12,%sp), %d0-%d1 | stride, height
subq.l #4, %d0 | adjust for increment within the loop
1:
move.l (%a1)+, (%a0)+
move.l (%a1), (%a0)
add.l %d0, %a0
add.l %d0, %a1
subq.l #1, %d1
bne.s 1b
rts
/*****************************************************************************/
.align 2
.global MC_put_o_16
.type MC_put_o_16, @function
MC_put_o_16:
lea.l (-7*4,%sp), %sp
movem.l %d2-%d7/%a2, (%sp) | save some registers
movem.l (7*4+4,%sp), %a0-%a2| dest, source, stride
move.l (7*4+16,%sp), %d1 | height
move.l %a1, %d0
and.l #3, %d0
sub.l %d0, %a1
jmp.l (2, %pc, %d0.l*4)
bra.w .po16_0
bra.w .po16_1
bra.w .po16_2
| last table entry coincides with target
.po16_3:
moveq.l #24, %d0 | shift amount
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
LEFT24_PW %d3, %d4
LEFT24_PW %d4, %d5
LEFT24_PW %d5, %d6
lsl.l %d0, %d6
lsr.l #8, %d7
or.l %d7, %d6
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d7/%a2
lea.l (7*4,%sp), %sp
rts
.po16_2:
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
swap %d3
swap %d4
move.w %d4, %d3
swap %d5
move.w %d5, %d4
swap %d6
move.w %d6, %d5
swap %d7
move.w %d7, %d6
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d7/%a2
lea.l (7*4,%sp), %sp
rts
.po16_1:
moveq.l #24, %d0 | shift amount
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
LEFT8_PW %d3, %d4
LEFT8_PW %d4, %d5
LEFT8_PW %d5, %d6
lsl.l #8, %d6
lsr.l %d0, %d7
or.l %d7, %d6
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d7/%a2
lea.l (7*4,%sp), %sp
rts
.po16_0:
1:
movem.l (%a1), %d3-%d6
add.l %a2, %a1
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %d1
bne.s 1b
movem.l (%sp), %d2-%d7/%a2
lea.l (7*4,%sp), %sp
rts
/*****************************************************************************/
.macro AVG_PW dW1, dW2 | needs %d0 == 24, clobbers %d1, %d2,
move.l \dW1, %d1 | changes dW1, keeps dW2
lsl.l #8, \dW1
move.l \dW2, %d2
lsr.l %d0, %d2
or.l %d2, \dW1
move.l %d1, %d2
eor.l \dW1, %d1
and.l %d2, \dW1
move.l #0xfefefefe, %d2
and.l %d1, %d2
eor.l %d2, %d1
lsr.l #1, %d2
add.l %d2, \dW1
add.l %d1, \dW1
.endm
/*****************************************************************************/
.align 2
.global MC_put_x_8
.type MC_put_x_8, @function
MC_put_x_8:
lea.l (-6*4,%sp), %sp
movem.l %d2-%d6/%a2, (%sp) | save some registers
movem.l (6*4+4,%sp), %a0-%a2| dest, source, stride
move.l (6*4+16,%sp), %d6 | height
move.l %a1, %d0
and.l #3, %d0
sub.l %d0, %a1
jmp.l (2, %pc, %d0.l*4)
bra.w .px8_0
bra.w .px8_1
bra.w .px8_2
| last table entry coincides with target
.px8_3:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d5
add.l %a2, %a1
LEFT24_PW %d3, %d4
LEFT24_PW %d4, %d5
lsl.l %d0, %d5
AVG_PW %d3, %d4
AVG_PW %d4, %d5
movem.l %d3-%d4, (%a0)
add.l %a2, %a0
subq.l #1, %d6
bne.s 1b
movem.l (%sp), %d2-%d6/%a2
lea.l (6*4,%sp), %sp
rts
.px8_2:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d5
add.l %a2, %a1
swap %d3
swap %d4
move.w %d4, %d3
swap %d5
move.w %d5, %d4
AVG_PW %d3, %d4
AVG_PW %d4, %d5
movem.l %d3-%d4, (%a0)
add.l %a2, %a0
subq.l #1, %d6
bne.s 1b
movem.l (%sp), %d2-%d6/%a2
lea.l (6*4,%sp), %sp
rts
.px8_1:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d5
add.l %a2, %a1
LEFT8_PW %d3, %d4
LEFT8_PW %d4, %d5
lsl.l #8, %d5
AVG_PW %d3, %d4
AVG_PW %d4, %d5
movem.l %d3-%d4, (%a0)
add.l %a2, %a0
subq.l #1, %d6
bne.s 1b
movem.l (%sp), %d2-%d6/%a2
lea.l (6*4,%sp), %sp
rts
.px8_0:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d5
add.l %a2, %a1
AVG_PW %d3, %d4
AVG_PW %d4, %d5
movem.l %d3-%d4, (%a0)
add.l %a2, %a0
subq.l #1, %d6
bne.s 1b
movem.l (%sp), %d2-%d6/%a2
lea.l (6*4,%sp), %sp
rts
/*****************************************************************************/
.align 2
.global MC_put_x_16
.type MC_put_x_16, @function
MC_put_x_16:
lea.l (-8*4,%sp), %sp
movem.l %d2-%d7/%a2-%a3, (%sp) | save some registers
movem.l (8*4+4,%sp), %a0-%a3 | dest, source, stride, height
move.l %a1, %d0
and.l #3, %d0
sub.l %d0, %a1
jmp.l (2, %pc, %d0.l*4)
bra.w .px16_0
bra.w .px16_1
bra.w .px16_2
| last table entry coincides with target
.px16_3:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
LEFT24_PW %d3, %d4
LEFT24_PW %d4, %d5
LEFT24_PW %d5, %d6
LEFT24_PW %d6, %d7
lsl.l %d0, %d7
AVG_PW %d3, %d4
AVG_PW %d4, %d5
AVG_PW %d5, %d6
AVG_PW %d6, %d7
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %a3
tst.l %a3
bne.w 1b
movem.l (%sp), %d2-%d7/%a2-%a3
lea.l (8*4,%sp), %sp
rts
.px16_2:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
swap %d3
swap %d4
move.w %d4, %d3
swap %d5
move.w %d5, %d4
swap %d6
move.w %d6, %d5
swap %d7
move.w %d7, %d6
AVG_PW %d3, %d4
AVG_PW %d4, %d5
AVG_PW %d5, %d6
AVG_PW %d6, %d7
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %a3
tst.l %a3
bne.w 1b
movem.l (%sp), %d2-%d7/%a2-%a3
lea.l (8*4,%sp), %sp
rts
.px16_1:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
LEFT8_PW %d3, %d4
LEFT8_PW %d4, %d5
LEFT8_PW %d5, %d6
LEFT8_PW %d6, %d7
lsl.l #8, %d7
AVG_PW %d3, %d4
AVG_PW %d4, %d5
AVG_PW %d5, %d6
AVG_PW %d6, %d7
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %a3
tst.l %a3
bne.w 1b
movem.l (%sp), %d2-%d7/%a2-%a3
lea.l (8*4,%sp), %sp
rts
.px16_0:
moveq.l #24, %d0
1:
movem.l (%a1), %d3-%d7
add.l %a2, %a1
AVG_PW %d3, %d4
AVG_PW %d4, %d5
AVG_PW %d5, %d6
AVG_PW %d6, %d7
movem.l %d3-%d6, (%a0)
add.l %a2, %a0
subq.l #1, %a3
tst.l %a3
bne.w 1b
movem.l (%sp), %d2-%d7/%a2-%a3
lea.l (8*4,%sp), %sp
rts

View file

@ -0,0 +1,223 @@
/*
* mpeg2.h
* Copyright (C) 2000-2004 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.67
*/
#ifndef MPEG2_H
#define MPEG2_H
#include "mpeg2dec_config.h"
#define MPEG2_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c))
#define MPEG2_RELEASE MPEG2_VERSION (0, 5, 0) /* 0.5.0 */
#define SEQ_FLAG_MPEG2 1
#define SEQ_FLAG_CONSTRAINED_PARAMETERS 2
#define SEQ_FLAG_PROGRESSIVE_SEQUENCE 4
#define SEQ_FLAG_LOW_DELAY 8
#define SEQ_FLAG_COLOUR_DESCRIPTION 16
#define SEQ_MASK_VIDEO_FORMAT 0xe0
#define SEQ_VIDEO_FORMAT_COMPONENT 0x00
#define SEQ_VIDEO_FORMAT_PAL 0x20
#define SEQ_VIDEO_FORMAT_NTSC 0x40
#define SEQ_VIDEO_FORMAT_SECAM 0x60
#define SEQ_VIDEO_FORMAT_MAC 0x80
#define SEQ_VIDEO_FORMAT_UNSPECIFIED 0xa0
typedef struct mpeg2_sequence_s
{
unsigned int width, height;
unsigned int chroma_width, chroma_height;
unsigned int byte_rate;
unsigned int vbv_buffer_size;
uint32_t flags;
unsigned int picture_width, picture_height;
unsigned int display_width, display_height;
unsigned int pixel_width, pixel_height;
unsigned int frame_period;
uint8_t profile_level_id;
uint8_t colour_primaries;
uint8_t transfer_characteristics;
uint8_t matrix_coefficients;
} mpeg2_sequence_t;
#define GOP_FLAG_DROP_FRAME 1
#define GOP_FLAG_BROKEN_LINK 2
#define GOP_FLAG_CLOSED_GOP 4
typedef struct mpeg2_gop_s
{
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
uint8_t pictures;
uint32_t flags;
} mpeg2_gop_t;
#define PIC_MASK_CODING_TYPE 7
#define PIC_FLAG_CODING_TYPE_I 1
#define PIC_FLAG_CODING_TYPE_P 2
#define PIC_FLAG_CODING_TYPE_B 3
#define PIC_FLAG_CODING_TYPE_D 4
#define PIC_FLAG_TOP_FIELD_FIRST 8
#define PIC_FLAG_PROGRESSIVE_FRAME 16
#define PIC_FLAG_COMPOSITE_DISPLAY 32
#define PIC_FLAG_SKIP 64
#define PIC_FLAG_TAGS 128
#define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000
typedef struct mpeg2_picture_s
{
unsigned int temporal_reference;
unsigned int nb_fields;
uint32_t tag, tag2;
uint32_t flags;
struct
{
int x, y;
} display_offset[3];
} mpeg2_picture_t;
typedef struct mpeg2_fbuf_s
{
uint8_t * buf[MPEG2_COMPONENTS];
void * id;
} mpeg2_fbuf_t;
typedef struct mpeg2_info_s
{
const mpeg2_sequence_t * sequence;
const mpeg2_gop_t * gop;
const mpeg2_picture_t * current_picture;
const mpeg2_picture_t * current_picture_2nd;
const mpeg2_fbuf_t * current_fbuf;
const mpeg2_picture_t * display_picture;
const mpeg2_picture_t * display_picture_2nd;
const mpeg2_fbuf_t * display_fbuf;
const mpeg2_fbuf_t * discard_fbuf;
const uint8_t * user_data;
unsigned int user_data_len;
} mpeg2_info_t;
typedef struct mpeg2dec_s mpeg2dec_t;
typedef struct mpeg2_decoder_s mpeg2_decoder_t;
typedef enum
{
STATE_INTERNAL_NORETURN = -1,
STATE_BUFFER = 0,
STATE_SEQUENCE = 1,
STATE_SEQUENCE_REPEATED = 2,
STATE_SEQUENCE_MODIFIED = 3,
STATE_GOP = 4,
STATE_PICTURE = 5,
STATE_SLICE_1ST = 6,
STATE_PICTURE_2ND = 7,
STATE_SLICE = 8,
STATE_END = 9,
STATE_INVALID = 10,
STATE_INVALID_END = 11,
} mpeg2_state_t;
typedef struct mpeg2_convert_init_s
{
unsigned int id_size;
unsigned int buf_size[MPEG2_COMPONENTS];
void (* start)(void * id, const mpeg2_fbuf_t * fbuf,
const mpeg2_picture_t * picture, const mpeg2_gop_t * gop);
void (* copy)(void * id, uint8_t * const * src, unsigned int v_offset);
} mpeg2_convert_init_t;
typedef enum
{
MPEG2_CONVERT_SET = 0,
MPEG2_CONVERT_STRIDE = 1,
MPEG2_CONVERT_START = 2
} mpeg2_convert_stage_t;
typedef int mpeg2_convert_t (int stage, void * id,
const mpeg2_sequence_t * sequence, int stride,
void * arg, mpeg2_convert_init_t * result);
int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg);
int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride);
void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS],
void * id);
void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf);
mpeg2dec_t * mpeg2_init (void);
const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec);
void mpeg2_close (mpeg2dec_t * mpeg2dec);
void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end);
int mpeg2_getpos (mpeg2dec_t * mpeg2dec);
mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec);
void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset);
void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip);
void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end);
void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2);
void mpeg2_init_fbuf (mpeg2_decoder_t * decoder,
uint8_t * current_fbuf[MPEG2_COMPONENTS],
uint8_t * forward_fbuf[MPEG2_COMPONENTS],
uint8_t * backward_fbuf[MPEG2_COMPONENTS]);
void mpeg2_slice (mpeg2_decoder_t * decoder, int code, const uint8_t * buffer);
int mpeg2_guess_aspect (const mpeg2_sequence_t * sequence,
unsigned int * pixel_width,
unsigned int * pixel_height);
typedef enum
{
MPEG2_ALLOC_MPEG2DEC = 0,
MPEG2_ALLOC_CHUNK = 1,
MPEG2_ALLOC_YUV = 2,
MPEG2_ALLOC_CONVERT_ID = 3,
MPEG2_ALLOC_CONVERTED = 4,
MPEG_ALLOC_CODEC_MALLOC,
MPEG_ALLOC_CODEC_CALLOC,
MPEG_ALLOC_MPEG2_BUFFER,
MPEG_ALLOC_AUDIOBUF,
MPEG_ALLOC_PCMOUT,
MPEG_ALLOC_DISKBUF,
__MPEG_ALLOC_FIRST = -256,
} mpeg2_alloc_t;
void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason);
#if 0
void mpeg2_free (void * buf);
#endif
/* allocates a dedicated buffer and locks all previous allocation in place */
void * mpeg2_bufalloc(unsigned size, mpeg2_alloc_t reason);
/* clears all non-dedicated buffer space */
void mpeg2_mem_reset(void);
void mpeg2_alloc_init(unsigned char* buf, int mallocsize);
#endif /* MPEG2_H */

View file

@ -0,0 +1,274 @@
/*
* mpeg2_internal.h
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.89
*/
#ifndef MPEG2_INTERNAL_H
#define MPEG2_INTERNAL_H
#include "config.h" /* for Rockbox CPU_ #defines */
/* macroblock modes */
#define MACROBLOCK_INTRA 1
#define MACROBLOCK_PATTERN 2
#define MACROBLOCK_MOTION_BACKWARD 4
#define MACROBLOCK_MOTION_FORWARD 8
#define MACROBLOCK_QUANT 16
#define DCT_TYPE_INTERLACED 32
/* motion_type */
#define MOTION_TYPE_SHIFT 6
#define MC_FIELD 1
#define MC_FRAME 2
#define MC_16X8 2
#define MC_DMV 3
/* picture structure */
#define TOP_FIELD 1
#define BOTTOM_FIELD 2
#define FRAME_PICTURE 3
/* picture coding type */
#define I_TYPE 1
#define P_TYPE 2
#define B_TYPE 3
#define D_TYPE 4
typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int);
typedef struct
{
uint8_t * ref[2][MPEG2_COMPONENTS];
uint8_t ** ref2[2];
int pmv[2][2];
int f_code[2];
} motion_t;
typedef void motion_parser_t(mpeg2_decoder_t * decoder,
motion_t * motion,
mpeg2_mc_fct * const * table);
struct mpeg2_decoder_s
{
/* first, state that carries information from one macroblock to the */
/* next inside a slice, and is never used outside of mpeg2_slice() */
/* bit parsing stuff */
uint32_t bitstream_buf; /* current 32 bit working set */
int bitstream_bits; /* used bits in working set */
const uint8_t * bitstream_ptr; /* buffer with stream data */
uint8_t * dest[MPEG2_COMPONENTS];
int offset;
int stride;
int uv_stride;
int slice_stride;
int slice_uv_stride;
int stride_frame;
unsigned int limit_x;
unsigned int limit_y_16;
unsigned int limit_y_8;
unsigned int limit_y;
/* Motion vectors */
/* The f_ and b_ correspond to the forward and backward motion */
/* predictors */
motion_t b_motion;
motion_t f_motion;
motion_parser_t * motion_parser[5];
/* predictor for DC coefficients in intra blocks */
int16_t dc_dct_pred[MPEG2_COMPONENTS];
/* DCT coefficients */
int16_t * DCTblock; /* put buffer separately to have it in IRAM */
uint8_t * picture_dest[MPEG2_COMPONENTS];
void (* convert) (void * convert_id, uint8_t * const * src,
unsigned int v_offset);
void * convert_id;
int dmv_offset;
unsigned int v_offset;
/* now non-slice-specific information */
/* sequence header stuff */
uint16_t * quantizer_matrix[4];
uint16_t (* chroma_quantizer[2])[64];
uint16_t quantizer_prescale[4][32][64];
/* The width and height of the picture snapped to macroblock units */
int width;
int height;
int vertical_position_extension;
int chroma_format;
/* picture header stuff */
/* what type of picture this is (I, P, B, D) */
int coding_type;
/* picture coding extension stuff */
/* quantization factor for intra dc coefficients */
int intra_dc_precision;
/* top/bottom/both fields */
int picture_structure;
/* bool to indicate all predictions are frame based */
int frame_pred_frame_dct;
/* bool to indicate whether intra blocks have motion vectors */
/* (for concealment) */
int concealment_motion_vectors;
/* bool to use different vlc tables */
int intra_vlc_format;
/* used for DMV MC */
int top_field_first;
/* stuff derived from bitstream */
/* pointer to the zigzag scan we're supposed to be using */
const uint8_t * scan;
int second_field;
int mpeg1;
};
typedef struct
{
mpeg2_fbuf_t fbuf;
} fbuf_alloc_t;
struct mpeg2dec_s
{
mpeg2_decoder_t decoder;
mpeg2_info_t info;
uint32_t shift;
int is_display_initialized;
mpeg2_state_t (* action) (struct mpeg2dec_s * mpeg2dec);
mpeg2_state_t state;
uint32_t ext_state;
/* allocated in init - gcc has problems allocating such big structures */
uint8_t * ATTR_ALIGN(4) chunk_buffer;
/* pointer to start of the current chunk */
uint8_t * chunk_start;
/* pointer to current position in chunk_buffer */
uint8_t * chunk_ptr;
/* last start code ? */
uint8_t code;
/* picture tags */
uint32_t tag_current, tag2_current, tag_previous, tag2_previous;
int num_tags;
int bytes_since_tag;
int first;
int alloc_index_user;
int alloc_index;
uint8_t first_decode_slice;
uint8_t nb_decode_slices;
unsigned int user_data_len;
mpeg2_sequence_t new_sequence;
mpeg2_sequence_t sequence;
mpeg2_gop_t new_gop;
mpeg2_gop_t gop;
mpeg2_picture_t new_picture;
mpeg2_picture_t pictures[4];
mpeg2_picture_t * picture;
/*const*/ mpeg2_fbuf_t * fbuf[3]; /* 0: current fbuf, 1-2: prediction fbufs */
fbuf_alloc_t fbuf_alloc[3];
int custom_fbuf;
uint8_t * yuv_buf[3][MPEG2_COMPONENTS];
int yuv_index;
mpeg2_convert_t * convert;
void * convert_arg;
unsigned int convert_id_size;
int convert_stride;
void (* convert_start) (void * id, const mpeg2_fbuf_t * fbuf,
const mpeg2_picture_t * picture,
const mpeg2_gop_t * gop);
uint8_t * buf_start;
uint8_t * buf_end;
int16_t display_offset_x, display_offset_y;
int copy_matrix;
int8_t q_scale_type, scaled[4];
uint8_t quantizer_matrix[4][64];
uint8_t new_quantizer_matrix[4][64];
};
/* decode.c */
mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec);
mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec);
/* header.c */
void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec);
void mpeg2_reset_info (mpeg2_info_t * info);
int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec);
int mpeg2_header_gop (mpeg2dec_t * mpeg2dec);
int mpeg2_header_picture (mpeg2dec_t * mpeg2dec);
int mpeg2_header_extension (mpeg2dec_t * mpeg2dec);
int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec);
void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec);
void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec);
void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec);
mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec);
mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec);
void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type);
/* idct.c */
void mpeg2_idct_init (void);
void mpeg2_idct_copy(int16_t * block, uint8_t * dest,
const int stride);
void mpeg2_idct_add(const int last, int16_t * block,
uint8_t * dest, const int stride);
extern const uint8_t default_mpeg2_scan_norm[64];
extern const uint8_t default_mpeg2_scan_alt[64];
extern uint8_t mpeg2_scan_norm[64];
extern uint8_t mpeg2_scan_alt[64];
/* motion_comp.c */
void mpeg2_mc_init (void);
typedef struct
{
mpeg2_mc_fct * put [8];
mpeg2_mc_fct * avg [8];
} mpeg2_mc_t;
extern const mpeg2_mc_t mpeg2_mc;
#endif /* MPEG2_INTERNAL_H */

View file

@ -0,0 +1,15 @@
/* $Id$ */
#ifndef MPEG2DEC_CONFIG_H
#define MPEG2DEC_CONFIG_H
#define ATTRIBUTE_ALIGNED_MAX 16
#ifdef HAVE_LCD_COLOR
#define MPEG2_COLOR 1
#define MPEG2_COMPONENTS 3
#else
#define MPEG2_COLOR 0
#define MPEG2_COMPONENTS 1
#endif
#endif /* MPEG2DEC_CONFIG_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,433 @@
/*
* vlc.h
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id$
* libmpeg2 sync history:
* 2008-07-01 - CVS revision 1.12
*/
#define GETWORD(bit_buf, shift, bit_ptr) \
do { \
bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \
bit_ptr += 2; \
} while (0)
static inline void bitstream_init (mpeg2_decoder_t * decoder,
const uint8_t * start)
{
decoder->bitstream_buf =
(start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3];
decoder->bitstream_ptr = start + 4;
decoder->bitstream_bits = -16;
}
/* make sure that there are at least 16 valid bits in bit_buf */
#define NEEDBITS(bit_buf, bits, bit_ptr) \
do { \
if (unlikely (bits > 0)) { \
GETWORD (bit_buf, bits, bit_ptr); \
bits -= 16; \
} \
} while (0)
/* remove num valid bits from bit_buf */
#define DUMPBITS(bit_buf, bits, num) \
do { \
bit_buf <<= (num); \
bits += (num); \
} while (0)
/* take num bits from the high part of bit_buf and zero extend them */
#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num)))
/* take num bits from the high part of bit_buf and sign extend them */
#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num)))
typedef struct {
uint8_t modes;
uint8_t len;
} MBtab;
typedef struct {
uint8_t delta;
uint8_t len;
} MVtab;
typedef struct {
int8_t dmv;
uint8_t len;
} DMVtab;
typedef struct {
uint8_t cbp;
uint8_t len;
} CBPtab;
typedef struct {
uint8_t size;
uint8_t len;
} DCtab;
typedef struct {
uint8_t run;
uint8_t level;
uint8_t len;
} DCTtab;
typedef struct {
uint8_t mba;
uint8_t len;
} MBAtab;
#define INTRA MACROBLOCK_INTRA
#define QUANT MACROBLOCK_QUANT
static const MBtab MB_I [] ICONST_ATTR = {
{INTRA|QUANT, 2}, {INTRA, 1}
};
#define MC MACROBLOCK_MOTION_FORWARD
#define CODED MACROBLOCK_PATTERN
static const MBtab MB_P [] ICONST_ATTR = {
{INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5},
{MC, 3}, {MC, 3}, {MC, 3}, {MC, 3},
{CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
{CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}
};
#define FWD MACROBLOCK_MOTION_FORWARD
#define BWD MACROBLOCK_MOTION_BACKWARD
#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD
static const MBtab MB_B [] ICONST_ATTR = {
{0, 6}, {INTRA|QUANT, 6},
{BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6},
{INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5},
{INTRA, 5}, {INTRA, 5},
{FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4},
{FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4},
{BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
{BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
{BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
{BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}
};
#undef INTRA
#undef QUANT
#undef MC
#undef CODED
#undef FWD
#undef BWD
#undef INTER
static const MVtab MV_4 [] ICONST_ATTR = {
{ 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2}
};
static const MVtab MV_10 [] ICONST_ATTR = {
{ 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10},
{ 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10},
{11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9},
{ 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7},
{ 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7},
{ 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}
};
static const DMVtab DMV_2 [] ICONST_ATTR = {
{ 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
};
static const CBPtab CBP_7 [] ICONST_ATTR = {
{0x11, 7}, {0x12, 7}, {0x14, 7}, {0x18, 7},
{0x21, 7}, {0x22, 7}, {0x24, 7}, {0x28, 7},
{0x3f, 6}, {0x3f, 6}, {0x30, 6}, {0x30, 6},
{0x09, 6}, {0x09, 6}, {0x06, 6}, {0x06, 6},
{0x1f, 5}, {0x1f, 5}, {0x1f, 5}, {0x1f, 5},
{0x10, 5}, {0x10, 5}, {0x10, 5}, {0x10, 5},
{0x2f, 5}, {0x2f, 5}, {0x2f, 5}, {0x2f, 5},
{0x20, 5}, {0x20, 5}, {0x20, 5}, {0x20, 5},
{0x07, 5}, {0x07, 5}, {0x07, 5}, {0x07, 5},
{0x0b, 5}, {0x0b, 5}, {0x0b, 5}, {0x0b, 5},
{0x0d, 5}, {0x0d, 5}, {0x0d, 5}, {0x0d, 5},
{0x0e, 5}, {0x0e, 5}, {0x0e, 5}, {0x0e, 5},
{0x05, 5}, {0x05, 5}, {0x05, 5}, {0x05, 5},
{0x0a, 5}, {0x0a, 5}, {0x0a, 5}, {0x0a, 5},
{0x03, 5}, {0x03, 5}, {0x03, 5}, {0x03, 5},
{0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5},
{0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4},
{0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4},
{0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4},
{0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4},
{0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
{0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
{0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
{0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
{0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
{0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
{0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3},
{0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}
};
static const CBPtab CBP_9 [] ICONST_ATTR = {
{0, 9}, {0x00, 9}, {0x39, 9}, {0x36, 9},
{0x37, 9}, {0x3b, 9}, {0x3d, 9}, {0x3e, 9},
{0x17, 8}, {0x17, 8}, {0x1b, 8}, {0x1b, 8},
{0x1d, 8}, {0x1d, 8}, {0x1e, 8}, {0x1e, 8},
{0x27, 8}, {0x27, 8}, {0x2b, 8}, {0x2b, 8},
{0x2d, 8}, {0x2d, 8}, {0x2e, 8}, {0x2e, 8},
{0x19, 8}, {0x19, 8}, {0x16, 8}, {0x16, 8},
{0x29, 8}, {0x29, 8}, {0x26, 8}, {0x26, 8},
{0x35, 8}, {0x35, 8}, {0x3a, 8}, {0x3a, 8},
{0x33, 8}, {0x33, 8}, {0x3c, 8}, {0x3c, 8},
{0x15, 8}, {0x15, 8}, {0x1a, 8}, {0x1a, 8},
{0x13, 8}, {0x13, 8}, {0x1c, 8}, {0x1c, 8},
{0x25, 8}, {0x25, 8}, {0x2a, 8}, {0x2a, 8},
{0x23, 8}, {0x23, 8}, {0x2c, 8}, {0x2c, 8},
{0x31, 8}, {0x31, 8}, {0x32, 8}, {0x32, 8},
{0x34, 8}, {0x34, 8}, {0x38, 8}, {0x38, 8}
};
static const DCtab DC_lum_5 [] ICONST_ATTR = {
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
{0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
{4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}
};
static const DCtab DC_chrom_5 [] ICONST_ATTR = {
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
{3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}
};
static const DCtab DC_long [] ICONST_ATTR = {
{6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
{6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
{7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6},
{8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9}
};
static const DCTtab DCT_16 [] ICONST_ATTR = {
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{ 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
{ 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
{ 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
{ 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
};
static const DCTtab DCT_15 [] ICONST_ATTR = {
{ 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
{ 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
{ 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
{ 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
{ 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
{ 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
{ 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
{ 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
{ 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
{ 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
{ 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
{ 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
};
static const DCTtab DCT_13 [] ICONST_ATTR = {
{ 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
{ 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
{ 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
{ 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
{ 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
{ 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
{ 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
{ 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
{ 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
{ 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
{ 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
{ 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
};
static const DCTtab DCT_B14_10 [] ICONST_ATTR = {
{ 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
{ 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
};
static const DCTtab DCT_B14_8 [] ICONST_ATTR = {
{ 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12},
{ 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
{ 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
{ 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
{ 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
{ 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
{ 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
{ 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
{ 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
};
static const DCTtab DCT_B14AC_5 [] ICONST_ATTR = {
{ 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
{ 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
{129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
};
static const DCTtab DCT_B14DC_5 [] ICONST_ATTR = {
{ 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
{ 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
};
static const DCTtab DCT_B15_10 [] ICONST_ATTR = {
{ 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
{ 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
};
static const DCTtab DCT_B15_8 [] ICONST_ATTR = {
{ 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12}, { 65, 0, 12},
{ 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
{ 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
{ 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
{ 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
{ 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
{ 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
{ 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
{ 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
{ 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
{ 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
{ 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
{ 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
{ 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
{ 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
{ 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
{ 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
{ 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
{ 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
{ 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
{ 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
{ 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
};
static const MBAtab MBA_5 [] ICONST_ATTR = {
{6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}
};
static const MBAtab MBA_11 [] ICONST_ATTR = {
{32, 11}, {31, 11}, {30, 11}, {29, 11},
{28, 11}, {27, 11}, {26, 11}, {25, 11},
{24, 11}, {23, 11}, {22, 11}, {21, 11},
{20, 10}, {20, 10}, {19, 10}, {19, 10},
{18, 10}, {18, 10}, {17, 10}, {17, 10},
{16, 10}, {16, 10}, {15, 10}, {15, 10},
{14, 8}, {14, 8}, {14, 8}, {14, 8},
{14, 8}, {14, 8}, {14, 8}, {14, 8},
{13, 8}, {13, 8}, {13, 8}, {13, 8},
{13, 8}, {13, 8}, {13, 8}, {13, 8},
{12, 8}, {12, 8}, {12, 8}, {12, 8},
{12, 8}, {12, 8}, {12, 8}, {12, 8},
{11, 8}, {11, 8}, {11, 8}, {11, 8},
{11, 8}, {11, 8}, {11, 8}, {11, 8},
{10, 8}, {10, 8}, {10, 8}, {10, 8},
{10, 8}, {10, 8}, {10, 8}, {10, 8},
{ 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
{ 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
};