add missing files

This commit is contained in:
dborth 2009-08-12 06:06:50 +00:00
parent 43dac50e75
commit 31e8f79474
35 changed files with 18638 additions and 0 deletions

4
smpeg/src/audio/AUTHORS Normal file
View file

@ -0,0 +1,4 @@
jwj95@eve.kaist.ac.kr
jwj95@nownuri.net Woo-jae Jung

481
smpeg/src/audio/COPYING.LIB Normal file
View file

@ -0,0 +1,481 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View file

@ -0,0 +1,354 @@
/*
SMPEG - SDL MPEG Player Library
Copyright (C) 1999 Loki Entertainment Software
- Modified by Michel Darricau from eProcess <mdarricau@eprocess.fr> for popcorn -
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* A class based on the MPEG stream class, used to parse and play audio */
//using namespace std;
#include "MPEGaudio.h"
#include "MPEGstream.h"
MPEGaudio:: MPEGaudio(MPEGstream *stream, bool initSDL) : sdl_audio(initSDL)
{
/* Initialize MPEG audio */
mpeg = stream;
initialize();
/* Just be paranoid. If all goes well, this will be set to true */
valid_stream = false;
/* Analyze the MPEG audio stream */
if ( loadheader() ) {
SDL_AudioSpec wanted;
WantedSpec(&wanted);
/* Calculate the samples per frame */
samplesperframe = 32*wanted.channels;
if( layer == 3 ) {
samplesperframe *= 18;
if ( version == 0 ) {
samplesperframe *= 2;
}
} else {
samplesperframe *= SCALEBLOCK;
if ( layer == 2 ) {
samplesperframe *= 3;
}
}
if ( sdl_audio ) {
/* Open the audio, get actual audio hardware format and convert */
bool audio_active;
SDL_AudioSpec actual;
audio_active = (SDL_OpenAudio(&wanted, &actual) == 0);
if ( audio_active ) {
ActualSpec(&actual);
valid_stream = true;
} else {
SetError(SDL_GetError());
}
SDL_PauseAudio(0);
} else { /* The stream is always valid if we don't initialize SDL */
valid_stream = true;
}
Volume(100);
}
/* For using system timestamp */
for (int i=0; i<N_TIMESTAMPS; i++)
timestamp[i] = -1;
}
MPEGaudio:: ~MPEGaudio()
{
#ifdef THREADED_AUDIO
/* Stop the decode thread */
StopDecoding();
#endif
/* Remove ourselves from the mixer hooks */
Stop();
if ( sdl_audio ) {
/* Close up the audio so others may play */
SDL_CloseAudio();
}
}
bool
MPEGaudio:: WantedSpec(SDL_AudioSpec *wanted)
{
wanted->freq = frequencies[version][frequency];
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
wanted->format = AUDIO_S16LSB;
#else
wanted->format = AUDIO_S16MSB;
#endif
if ( outputstereo ) {
wanted->channels = 2;
} else {
wanted->channels = 1;
}
wanted->samples = 4096;
wanted->callback = Play_MPEGaudioSDL;
wanted->userdata = this;
return true;
}
void
MPEGaudio:: ActualSpec(const SDL_AudioSpec *actual)
{
/* Splay can optimize some of the conversion */
if ( actual->channels == 1 && outputstereo ) {
forcetomonoflag = true;
}
if ( actual->channels == 2 && !outputstereo ) {
forcetostereoflag = true;
samplesperframe *= 2;
}
/* FIXME: Create an audio conversion block */
if ( (actual->freq/100) == ((frequencies[version][frequency]/2)/100) ) {
downfrequency = 1;
} else if ( actual->freq != frequencies[version][frequency] ) {
#ifdef VERBOSE_WARNINGS
fprintf(stderr, "Warning: wrong audio frequency (wanted %d, got %d)\n",
frequencies[version][frequency], actual->freq);
#else
;
#endif
}
if ( actual->format != AUDIO_S16SYS )
{
if ( (actual->format^0x1000) == AUDIO_S16SYS ) {
swapendianflag = true;
} else {
fprintf(stderr, "Warning: incorrect audio format\n");
}
}
rate_in_s=((double)((actual->format&0xFF)/8)*actual->channels*actual->freq);
stereo=((actual->channels-1) > 0);
}
#ifdef THREADED_AUDIO
void
MPEGaudio:: StartDecoding(void)
{
decoding = true;
/* Create the ring buffer to hold audio */
if ( ! ring ) {
ring = new MPEG_ring(samplesperframe*2);
}
if ( ! decode_thread ) {
decode_thread = SDL_CreateThread(Decode_MPEGaudio, this);
}
}
void
MPEGaudio:: StopDecoding(void)
{
decoding = false;
if ( decode_thread ) {
force_exit = true;
if( ring ) ring->ReleaseThreads();
SDL_WaitThread(decode_thread, NULL);
decode_thread = NULL;
}
if ( ring ) {
delete ring;
ring = NULL;
}
}
#endif
/* MPEG actions */
double
MPEGaudio:: Time(void)
{
double now;
if ( frag_time ) {
now = (play_time + (double)(SDL_GetTicks() - frag_time)/1000.0);
} else {
now = play_time;
}
return now;
}
void
MPEGaudio:: Play(void)
{
ResetPause();
if ( valid_stream ) {
#ifdef THREADED_AUDIO
StartDecoding();
#endif
playing = true;
}
}
void
MPEGaudio:: Stop(void)
{
if ( valid_stream ) {
if ( sdl_audio )
SDL_LockAudio();
playing = false;
if ( sdl_audio )
SDL_UnlockAudio();
}
ResetPause();
}
void
MPEGaudio:: Rewind(void)
{
Stop();
#ifdef THREADED_AUDIO
/* Stop the decode thread */
StopDecoding();
#endif
clearrawdata();
decodedframe = 0;
currentframe = 0;
frags_playing = 0;
}
void
MPEGaudio:: ResetSynchro(double time)
{
play_time = time;
frag_time = 0;
/* Reinit the timestamp FIFO */
for (int i=0; i<N_TIMESTAMPS; i++)
timestamp[i] = -1;
}
void
MPEGaudio:: Skip(float seconds)
{
/* Called only when there is no timestamp info in the MPEG */
printf("Audio: Skipping %f seconds...\n", seconds);
while(seconds > 0)
{
seconds -= (float) samplesperframe / ((float) frequencies[version][frequency]*(1+inputstereo));
if(!loadheader()) break;
}
}
void
MPEGaudio:: Volume(int vol)
{
if ( (vol >= 0) && (vol <= 100) ) {
volume = (vol*SDL_MIX_MAXVOLUME)/100;
}
}
/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name in popcorn */
MPEGstatus
MPEGaudio:: GetStatus(void)
{
if ( valid_stream ) {
/* Has decoding stopped because of end of stream? */
if ( mpeg->eof() && (decodedframe <= currentframe) ) {
return(MPEG_STOPPED);
}
/* Have we been told to play? */
if ( playing ) {
return(MPEG_PLAYING);
} else {
return(MPEG_STOPPED);
}
} else {
return(MPEG_ERROR);
}
}
bool
MPEGaudio:: GetAudioInfo(MPEG_AudioInfo *info)
{
if ( info ) {
info->mpegversion = version;
info->mode = mode;
info->frequency = frequencies[version][frequency];
info->layer = layer;
info->bitrate = bitrate[version][layer-1][bitrateindex];
info->current_frame = currentframe;
}
return true;
}
bool
MPEGaudio:: fillbuffer(int size)
{
bitindex=0;
_buffer_pos = mpeg->pos;
return(mpeg->copy_data(_buffer, size) > 0);
};
void
MPEGaudio:: sync(void)
{
bitindex=(bitindex+7)&0xFFFFFFF8;
}
bool
MPEGaudio:: issync(void)
{
return (bitindex&7) != 0;
}
int
MPEGaudio::getbyte(void)
{
int r=(unsigned char)_buffer[bitindex>>3];
bitindex+=8;
return r;
}
int
MPEGaudio::getbit(void)
{
register int r=(_buffer[bitindex>>3]>>(7-(bitindex&7)))&1;
bitindex++;
return r;
}
int
MPEGaudio::getbits8(void)
{
register unsigned short a;
{ int offset=bitindex>>3;
a=(((unsigned char)_buffer[offset])<<8) | ((unsigned char)_buffer[offset+1]);
}
a<<=(bitindex&7);
bitindex+=8;
return (int)((unsigned int)(a>>8));
}
int
MPEGaudio::getbits9(int bits)
{
register unsigned short a;
{ int offset=bitindex>>3;
a=(((unsigned char)_buffer[offset])<<8) | ((unsigned char)_buffer[offset+1]);
}
a<<=(bitindex&7);
bitindex+=bits;
return (int)((unsigned int)(a>>(16-bits)));
}

4
smpeg/src/audio/README Normal file
View file

@ -0,0 +1,4 @@
This code is based on Splay 0.8.2, available from:
http://my.netian.com/~polarb/

View file

@ -0,0 +1,60 @@
mpegsound README.LIB(International)
MPEG/WAVE player library
This library have NO WARRANTY. You can use this under Library GPL.
This library uses part from vplay, maplay 1.2 for linux, maplay 1.2+ for Win95.
This is library which can make program play MPEG-1/2 audio and Wave file easily.
Detail is in ChangeLog
CAUTION
The current implementation was tested with little endian architecture.
Bigendian is implemented. But I don't test.
Hackers... please help me!
What's the difference?
For example;
unsigned char a[4]={0x11,0x22,0x33,0x44};
unsigned int *b=(unsigned int *)&a;
Little endian (Intel) : 0x44332211
Big endian : 0x11223344
The classes 'mpegtoraw' and 'bitwindow' are endian dependent.
OTHER ENDIAN PROBLEM
Some machines can access integer type variables when they are aligned
at 4-bytes. If endian problem is solved. It cause serious problem.
I have exploited the linear properties of 2 and 3 dimensional arrays.
like for example;
int a[4][4];
a[1][0]==a[0][4] is true.
Of course, It may occur boundary problem. But it may make player faster!
IMPROVED
Using mpg123 code, I improved performance of this library.
Thank you for authors of mpg123
ENGLISH PROBLEM
I release README with International (English) and Korean (my native lang)
The Korean version should be ok, but the english version have many spelling
mistakes and confusing words and sentences. Please forgive me and help me
correct the english.
PROBLEM?
Please send me bug report or patches.(Please comment where is changed)
to:
jwj95@eve.kaist.ac.kr
jwj95@nownuri.net
THANKS FOR this document.
Tommy Thorn

View file

@ -0,0 +1,64 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Bitwindow.cc
// It's bit reservior for MPEG layer 3
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "MPEGaudio.h"
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define _KEY 0
#else
#define _KEY 3
#endif
int Mpegbitwindow::getbits(int bits)
{
union
{
char store[4];
int current;
}u;
int bi;
if(!bits)return 0;
u.current=0;
bi=(bitindex&7);
// u.store[_KEY]=buffer[(bitindex>>3)&(WINDOWSIZE-1)]<<bi;
u.store[_KEY]=buffer[bitindex>>3]<<bi;
bi=8-bi;
bitindex+=bi;
while(bits)
{
if(!bi)
{
// u.store[_KEY]=buffer[(bitindex>>3)&(WINDOWSIZE-1)];
u.store[_KEY]=buffer[bitindex>>3];
bitindex+=8;
bi=8;
}
if(bits>=bi)
{
u.current<<=bi;
bits-=bi;
bi=0;
}
else
{
u.current<<=bits;
bi-=bits;
bits=0;
}
}
bitindex-=bi;
return (u.current>>8);
}

338
smpeg/src/audio/filter.cpp Normal file
View file

@ -0,0 +1,338 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Filter.cc
// Subbandsynthesis routines from maplay 1.2 for Linux
// I've modified some macros for reducing source code.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "MPEGaudio.h"
void MPEGaudio::computebuffer(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE])
{
REAL p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pa,pb,pc,pd,pe,pf;
REAL q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,qa,qb,qc,qd,qe,qf;
REAL *out1,*out2;
out1=buffer[currentcalcbuffer]+calcbufferoffset;
out2=buffer[currentcalcbuffer^1]+calcbufferoffset;
#define OUT1(v,t) out1[(32-(v))*16] =(-(out1[(v)*16]=t))
#define OUT2(v) out2[(96-(v)-32)*16]=out2[((v)-32)*16]
// compute new values via a fast cosine transform:
{
register REAL *x=fraction;
p0=x[ 0]+x[31];p1=x[ 1]+x[30];p2=x[ 2]+x[29];p3=x[ 3]+x[28];
p4=x[ 4]+x[27];p5=x[ 5]+x[26];p6=x[ 6]+x[25];p7=x[ 7]+x[24];
p8=x[ 8]+x[23];p9=x[ 9]+x[22];pa=x[10]+x[21];pb=x[11]+x[20];
pc=x[12]+x[19];pd=x[13]+x[18];pe=x[14]+x[17];pf=x[15]+x[16];
}
q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc;
q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8;
q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe);
qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc);
qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa);
qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8);
p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4;
p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6);
p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4);
p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc;
pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe);
pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc);
q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2);
q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6);
q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa);
qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe);
p0=q0+q1;p1=hcos_4*(q0-q1);p2=q2+q3;p3=hcos_4*(q2-q3);
p4=q4+q5;p5=hcos_4*(q4-q5);p6=q6+q7;p7=hcos_4*(q6-q7);
p8=q8+q9;p9=hcos_4*(q8-q9);pa=qa+qb;pb=hcos_4*(qa-qb);
pc=qc+qd;pd=hcos_4*(qc-qd);pe=qe+qf;pf=hcos_4*(qe-qf);
{
register REAL tmp;
tmp=p6+p7;
OUT2(36)=-(p5+tmp);
OUT2(44)=-(p4+tmp);
tmp=pb+pf;
OUT1(10,tmp);
OUT1(6,pd+tmp);
tmp=pe+pf;
OUT2(46)=-(p8+pc+tmp);
OUT2(34)=-(p9+pd+tmp);
tmp+=pa+pb;
OUT2(38)=-(pd+tmp);
OUT2(42)=-(pc+tmp);
OUT1(2,p9+pd+pf);
OUT1(4,p5+p7);
OUT2(48)=-p0;
out2[0]=-(out1[0]=p1);
OUT1( 8,p3);
OUT1(12,p7);
OUT1(14,pf);
OUT2(40)=-(p2+p3);
}
{
register REAL *x=fraction;
p0=hcos_64[ 0]*(x[ 0]-x[31]);p1=hcos_64[ 1]*(x[ 1]-x[30]);
p2=hcos_64[ 2]*(x[ 2]-x[29]);p3=hcos_64[ 3]*(x[ 3]-x[28]);
p4=hcos_64[ 4]*(x[ 4]-x[27]);p5=hcos_64[ 5]*(x[ 5]-x[26]);
p6=hcos_64[ 6]*(x[ 6]-x[25]);p7=hcos_64[ 7]*(x[ 7]-x[24]);
p8=hcos_64[ 8]*(x[ 8]-x[23]);p9=hcos_64[ 9]*(x[ 9]-x[22]);
pa=hcos_64[10]*(x[10]-x[21]);pb=hcos_64[11]*(x[11]-x[20]);
pc=hcos_64[12]*(x[12]-x[19]);pd=hcos_64[13]*(x[13]-x[18]);
pe=hcos_64[14]*(x[14]-x[17]);pf=hcos_64[15]*(x[15]-x[16]);
}
q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc;
q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8;
q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe);
qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc);
qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa);
qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8);
p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4;
p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6);
p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4);
p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc;
pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe);
pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc);
q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2);
q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6);
q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa);
qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe);
p0=q0+q1;p1=hcos_4*(q0-q1);
p2=q2+q3;p3=hcos_4*(q2-q3);
p4=q4+q5;p5=hcos_4*(q4-q5);
p6=q6+q7;p7=hcos_4*(q6-q7);
p8=q8+q9;p9=hcos_4*(q8-q9);
pa=qa+qb;pb=hcos_4*(qa-qb);
pc=qc+qd;pd=hcos_4*(qc-qd);
pe=qe+qf;pf=hcos_4*(qe-qf);
{
REAL tmp;
tmp=pd+pf;
OUT1(5,p5+p7+pb+tmp);
tmp+=p9;
OUT1(1,p1+tmp);
OUT2(33)=-(p1+pe+tmp);
tmp+=p5+p7;
OUT1(3,tmp);
OUT2(35)=-(p6+pe+tmp);
tmp=pa+pb+pc+pd+pe+pf;
OUT2(39)=-(p2+p3+tmp-pc);
OUT2(43)=-(p4+p6+p7+tmp-pd);
OUT2(37)=-(p5+p6+p7+tmp-pc);
OUT2(41)=-(p2+p3+tmp-pd);
tmp=p8+pc+pe+pf;
OUT2(47)=-(p0+tmp);
OUT2(45)=-(p4+p6+p7+tmp);
tmp=pb+pf;
OUT1(11,p7+tmp);
tmp+=p3;
OUT1( 9,tmp);
OUT1( 7,pd+tmp);
OUT1(13,p7+pf);
OUT1(15,pf);
}
}
#define SAVE \
raw=(int)(r*scalefactor); \
if(raw>MAXSCALE)raw=MAXSCALE;else if(raw<MINSCALE)raw=MINSCALE; \
putraw(raw);
#define OS r=*vp * *dp++
#define XX vp+=15;r+=*vp * *dp++
#define OP r+=*--vp * *dp++
void MPEGaudio::generatesingle(void)
{
int i;
register REAL r, *vp;
register const REAL *dp;
int raw;
i=32;
dp=filter;
vp=calcbufferL[currentcalcbuffer]+calcbufferoffset;
// actual_v+actual_write_pos;
switch (calcbufferoffset)
{
case 0:for(;i;i--,vp+=15){
OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 1:for(;i;i--,vp+=15){
OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 2:for(;i;i--,vp+=15){
OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 3:for(;i;i--,vp+=15){
OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 4:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 5:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 6:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 7:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 8:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 9:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;
SAVE;}break;
case 10:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;
SAVE;}break;
case 11:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;
SAVE;}break;
case 12:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;
SAVE;}break;
case 13:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;
SAVE;}break;
case 14:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;
SAVE;}break;
case 15:for(;i;i--,vp+=31){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
}
}
#undef OS
#undef XX
#undef OP
#undef SAVE
#define SAVE \
raw=(int)(r1*scalefactor); \
if(raw>MAXSCALE)raw=MAXSCALE;else if(raw<MINSCALE)raw=MINSCALE; \
putraw(raw); \
raw=(int)(r2*scalefactor); \
if(raw>MAXSCALE)raw=MAXSCALE;else if(raw<MINSCALE)raw=MINSCALE; \
putraw(raw);
#define OS r1=*vp1 * *dp; \
r2=*vp2 * *dp++
#define XX vp1+=15;r1+=*vp1 * *dp; \
vp2+=15;r2+=*vp2 * *dp++
#define OP r1+=*--vp1 * *dp; \
r2+=*--vp2 * *dp++
void MPEGaudio::generate(void)
{
int i;
REAL r1,r2;
register REAL *vp1,*vp2;
register const REAL *dp;
int raw;
dp=filter;
vp1=calcbufferL[currentcalcbuffer]+calcbufferoffset;
vp2=calcbufferR[currentcalcbuffer]+calcbufferoffset;
// actual_v+actual_write_pos;
i=32;
switch (calcbufferoffset)
{
case 0:for(;i;i--,vp1+=15,vp2+=15){
OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 1:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 2:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 3:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 4:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 5:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 6:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 7:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 8:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 9:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;
SAVE;}break;
case 10:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;
SAVE;}break;
case 11:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;
SAVE;}break;
case 12:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;
SAVE;}break;
case 13:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;
SAVE;}break;
case 14:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;
SAVE;}break;
case 15:for(;i;i--,vp1+=31,vp2+=31){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
}
}
void MPEGaudio::subbandsynthesis(REAL *fractionL,REAL *fractionR)
{
if(downfrequency)
{
subbandsynthesis_2(fractionL,fractionR);
return;
}
computebuffer(fractionL,calcbufferL);
if(!outputstereo)generatesingle();
else
{
computebuffer(fractionR,calcbufferR);
generate();
}
if(calcbufferoffset<15)calcbufferoffset++;
else calcbufferoffset=0;
currentcalcbuffer^=1;
}

View file

@ -0,0 +1,354 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Filter.cc
// Subbandsynthesis routines from maplay 1.2 for Linux
// I've modified some macros for reducing source code.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "MPEGaudio.h"
void MPEGaudio::computebuffer_2(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE])
{
REAL p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pa,pb,pc,pd,pe,pf;
REAL q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,qa,qb,qc,qd,qe,qf;
REAL *out1,*out2;
out1=buffer[currentcalcbuffer]+calcbufferoffset;
out2=buffer[currentcalcbuffer^1]+calcbufferoffset;
#define OUT1(v,t) out1[(32-(v))*16] =(-(out1[(v)*16]=t))
#define OUT2(v) out2[(96-(v)-32)*16]=out2[((v)-32)*16]
// compute new values via a fast cosine transform:
/* {
register REAL *x=fraction;
p0=x[ 0]+x[31];p1=x[ 1]+x[30];p2=x[ 2]+x[29];p3=x[ 3]+x[28];
p4=x[ 4]+x[27];p5=x[ 5]+x[26];p6=x[ 6]+x[25];p7=x[ 7]+x[24];
p8=x[ 8]+x[23];p9=x[ 9]+x[22];pa=x[10]+x[21];pb=x[11]+x[20];
pc=x[12]+x[19];pd=x[13]+x[18];pe=x[14]+x[17];pf=x[15]+x[16];
}
q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc;
q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8;
q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe);
qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc);
qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa);
qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); */
{
register REAL *x=fraction;
q0=x[ 0]+x[15];q1=x[ 1]+x[14];q2=x[ 2]+x[13];q3=x[ 3]+x[12];
q4=x[ 4]+x[11];q5=x[ 5]+x[10];q6=x[ 6]+x[ 9];q7=x[ 7]+x[ 8];
q8=hcos_32[0]*(x[ 0]-x[15]);q9=hcos_32[1]*(x[ 1]-x[14]);
qa=hcos_32[2]*(x[ 2]-x[13]);qb=hcos_32[3]*(x[ 3]-x[12]);
qc=hcos_32[4]*(x[ 4]-x[11]);qd=hcos_32[5]*(x[ 5]-x[10]);
qe=hcos_32[6]*(x[ 6]-x[ 9]);qf=hcos_32[7]*(x[ 7]-x[ 8]);
}
p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4;
p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6);
p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4);
p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc;
pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe);
pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc);
q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2);
q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6);
q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa);
qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe);
p0=q0+q1;p1=hcos_4*(q0-q1);p2=q2+q3;p3=hcos_4*(q2-q3);
p4=q4+q5;p5=hcos_4*(q4-q5);p6=q6+q7;p7=hcos_4*(q6-q7);
p8=q8+q9;p9=hcos_4*(q8-q9);pa=qa+qb;pb=hcos_4*(qa-qb);
pc=qc+qd;pd=hcos_4*(qc-qd);pe=qe+qf;pf=hcos_4*(qe-qf);
{
register REAL tmp;
tmp=p6+p7;
OUT2(36)=-(p5+tmp);
OUT2(44)=-(p4+tmp);
tmp=pb+pf;
OUT1(10,tmp);
OUT1(6,pd+tmp);
tmp=pe+pf;
OUT2(46)=-(p8+pc+tmp);
OUT2(34)=-(p9+pd+tmp);
tmp+=pa+pb;
OUT2(38)=-(pd+tmp);
OUT2(42)=-(pc+tmp);
OUT1(2,p9+pd+pf);
OUT1(4,p5+p7);
OUT2(48)=-p0;
out2[0]=-(out1[0]=p1);
OUT1( 8,p3);
OUT1(12,p7);
OUT1(14,pf);
OUT2(40)=-(p2+p3);
}
{
register REAL *x=fraction;
/* p0=hcos_64[ 0]*(x[ 0]-x[31]);p1=hcos_64[ 1]*(x[ 1]-x[30]);
p2=hcos_64[ 2]*(x[ 2]-x[29]);p3=hcos_64[ 3]*(x[ 3]-x[28]);
p4=hcos_64[ 4]*(x[ 4]-x[27]);p5=hcos_64[ 5]*(x[ 5]-x[26]);
p6=hcos_64[ 6]*(x[ 6]-x[25]);p7=hcos_64[ 7]*(x[ 7]-x[24]);
p8=hcos_64[ 8]*(x[ 8]-x[23]);p9=hcos_64[ 9]*(x[ 9]-x[22]);
pa=hcos_64[10]*(x[10]-x[21]);pb=hcos_64[11]*(x[11]-x[20]);
pc=hcos_64[12]*(x[12]-x[19]);pd=hcos_64[13]*(x[13]-x[18]);
pe=hcos_64[14]*(x[14]-x[17]);pf=hcos_64[15]*(x[15]-x[16]); */
p0=hcos_64[ 0]*x[ 0];p1=hcos_64[ 1]*x[ 1];
p2=hcos_64[ 2]*x[ 2];p3=hcos_64[ 3]*x[ 3];
p4=hcos_64[ 4]*x[ 4];p5=hcos_64[ 5]*x[ 5];
p6=hcos_64[ 6]*x[ 6];p7=hcos_64[ 7]*x[ 7];
p8=hcos_64[ 8]*x[ 8];p9=hcos_64[ 9]*x[ 9];
pa=hcos_64[10]*x[10];pb=hcos_64[11]*x[11];
pc=hcos_64[12]*x[12];pd=hcos_64[13]*x[13];
pe=hcos_64[14]*x[14];pf=hcos_64[15]*x[15];
}
q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc;
q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8;
q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe);
qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc);
qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa);
qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8);
p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4;
p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6);
p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4);
p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc;
pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe);
pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc);
q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2);
q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6);
q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa);
qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe);
p0=q0+q1;p1=hcos_4*(q0-q1);
p2=q2+q3;p3=hcos_4*(q2-q3);
p4=q4+q5;p5=hcos_4*(q4-q5);
p6=q6+q7;p7=hcos_4*(q6-q7);
p8=q8+q9;p9=hcos_4*(q8-q9);
pa=qa+qb;pb=hcos_4*(qa-qb);
pc=qc+qd;pd=hcos_4*(qc-qd);
pe=qe+qf;pf=hcos_4*(qe-qf);
{
REAL tmp;
tmp=pd+pf;
OUT1(5,p5+p7+pb+tmp);
tmp+=p9;
OUT1(1,p1+tmp);
OUT2(33)=-(p1+pe+tmp);
tmp+=p5+p7;
OUT1(3,tmp);
OUT2(35)=-(p6+pe+tmp);
tmp=pa+pb+pc+pd+pe+pf;
OUT2(39)=-(p2+p3+tmp-pc);
OUT2(43)=-(p4+p6+p7+tmp-pd);
OUT2(37)=-(p5+p6+p7+tmp-pc);
OUT2(41)=-(p2+p3+tmp-pd);
tmp=p8+pc+pe+pf;
OUT2(47)=-(p0+tmp);
OUT2(45)=-(p4+p6+p7+tmp);
tmp=pb+pf;
OUT1(11,p7+tmp);
tmp+=p3;
OUT1( 9,tmp);
OUT1( 7,pd+tmp);
OUT1(13,p7+pf);
OUT1(15,pf);
}
}
#define SAVE \
raw=(int)(r*scalefactor); \
if(raw>MAXSCALE)raw=MAXSCALE;else if(raw<MINSCALE)raw=MINSCALE; \
putraw(raw); \
dp+=16;vp+=15+(15-14)
#define OS r=*vp * *dp++
#define XX vp+=15;r+=*vp * *dp++
#define OP r+=*--vp * *dp++
void MPEGaudio::generatesingle_2(void)
{
int i;
register REAL r, *vp;
register const REAL *dp;
int raw;
i=32/2;
dp=filter;
vp=calcbufferL[currentcalcbuffer]+calcbufferoffset;
// actual_v+actual_write_pos;
switch (calcbufferoffset)
{
case 0:for(;i;i--,vp+=15){
OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 1:for(;i;i--,vp+=15){
OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 2:for(;i;i--,vp+=15){
OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 3:for(;i;i--,vp+=15){
OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 4:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 5:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 6:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 7:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 8:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 9:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;
SAVE;}break;
case 10:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;
SAVE;}break;
case 11:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;
SAVE;}break;
case 12:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;
SAVE;}break;
case 13:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;
SAVE;}break;
case 14:for(;i;i--,vp+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;
SAVE;}break;
case 15:for(;i;i--,vp+=31){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
}
}
#undef OS
#undef XX
#undef OP
#undef SAVE
#define SAVE \
raw=(int)(r1*scalefactor); \
if(raw>MAXSCALE)raw=MAXSCALE;else if(raw<MINSCALE)raw=MINSCALE; \
putraw(raw); \
raw=(int)(r2*scalefactor); \
if(raw>MAXSCALE)raw=MAXSCALE;else if(raw<MINSCALE)raw=MINSCALE; \
putraw(raw); \
dp+=16;vp1+=15+(15-14);vp2+=15+(15-14)
#define OS r1=*vp1 * *dp; \
r2=*vp2 * *dp++
#define XX vp1+=15;r1+=*vp1 * *dp; \
vp2+=15;r2+=*vp2 * *dp++
#define OP r1+=*--vp1 * *dp; \
r2+=*--vp2 * *dp++
void MPEGaudio::generate_2(void)
{
int i;
REAL r1,r2;
register REAL *vp1,*vp2;
register const REAL *dp;
int raw;
dp=filter;
vp1=calcbufferL[currentcalcbuffer]+calcbufferoffset;
vp2=calcbufferR[currentcalcbuffer]+calcbufferoffset;
// actual_v+actual_write_pos;
i=32/2;
switch (calcbufferoffset)
{
case 0:for(;i;i--,vp1+=15,vp2+=15){
OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 1:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 2:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 3:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 4:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 5:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 6:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 7:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 8:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;
SAVE;}break;
case 9:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;
SAVE;}break;
case 10:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;
SAVE;}break;
case 11:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;
SAVE;}break;
case 12:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;
SAVE;}break;
case 13:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;
SAVE;}break;
case 14:for(;i;i--,vp1+=15,vp2+=15){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;
SAVE;}break;
case 15:for(;i;i--,vp1+=31,vp2+=31){
OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;
SAVE;}break;
}
}
void MPEGaudio::subbandsynthesis_2(REAL *fractionL,REAL *fractionR)
{
computebuffer_2(fractionL,calcbufferL);
if(!outputstereo)generatesingle_2();
else
{
computebuffer_2(fractionR,calcbufferR);
generate_2();
}
if(calcbufferoffset<15)calcbufferoffset++;
else calcbufferoffset=0;
currentcalcbuffer^=1;
}

View file

@ -0,0 +1,587 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Huffmantable.cc
// It contains initialized huffman table for MPEG layer 3
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "MPEGaudio.h"
static const unsigned int
htd01[ 7][2]={{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 2, 1},{ 0, 1},
{ 0, 17}},
htd02[ 17][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},
{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 33},
{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}},
htd03[ 17][2]={{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 1},{ 2, 1},{ 0, 17},
{ 2, 1},{ 0, 16},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 33},
{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}},
htd05[ 31][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},
{ 2, 1},{ 0, 17},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 32},
{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 3},{ 0, 19},
{ 2, 1},{ 0, 49},{ 2, 1},{ 0, 50},{ 2, 1},{ 0, 35},
{ 0, 51}},
htd06[ 31][2]={{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},{ 0, 17},
{ 6, 1},{ 2, 1},{ 0, 1},{ 2, 1},{ 0, 32},{ 0, 33},
{ 6, 1},{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34},
{ 4, 1},{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1},
{ 0, 48},{ 0, 50},{ 2, 1},{ 0, 35},{ 2, 1},{ 0, 3},
{ 0, 51}},
htd07[ 71][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},
{ 8, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},
{ 0, 2},{ 0, 33},{ 18, 1},{ 6, 1},{ 2, 1},{ 0, 18},
{ 2, 1},{ 0, 34},{ 0, 48},{ 4, 1},{ 2, 1},{ 0, 49},
{ 0, 19},{ 4, 1},{ 2, 1},{ 0, 3},{ 0, 50},{ 2, 1},
{ 0, 35},{ 0, 4},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 64},
{ 0, 65},{ 2, 1},{ 0, 20},{ 2, 1},{ 0, 66},{ 0, 36},
{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 51},{ 0, 67},
{ 0, 80},{ 4, 1},{ 2, 1},{ 0, 52},{ 0, 5},{ 0, 81},
{ 6, 1},{ 2, 1},{ 0, 21},{ 2, 1},{ 0, 82},{ 0, 37},
{ 4, 1},{ 2, 1},{ 0, 68},{ 0, 53},{ 4, 1},{ 2, 1},
{ 0, 83},{ 0, 84},{ 2, 1},{ 0, 69},{ 0, 85}},
htd08[ 71][2]={{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 0, 1},
{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 33},{ 0, 18},
{ 14, 1},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 2},{ 2, 1},
{ 0, 34},{ 4, 1},{ 2, 1},{ 0, 48},{ 0, 3},{ 2, 1},
{ 0, 49},{ 0, 19},{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0, 50},{ 0, 35},{ 2, 1},{ 0, 64},{ 0, 4},{ 2, 1},
{ 0, 65},{ 2, 1},{ 0, 20},{ 0, 66},{ 12, 1},{ 6, 1},
{ 2, 1},{ 0, 36},{ 2, 1},{ 0, 51},{ 0, 80},{ 4, 1},
{ 2, 1},{ 0, 67},{ 0, 52},{ 0, 81},{ 6, 1},{ 2, 1},
{ 0, 21},{ 2, 1},{ 0, 5},{ 0, 82},{ 6, 1},{ 2, 1},
{ 0, 37},{ 2, 1},{ 0, 68},{ 0, 53},{ 2, 1},{ 0, 83},
{ 2, 1},{ 0, 69},{ 2, 1},{ 0, 84},{ 0, 85}},
htd09[ 71][2]={{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},{ 2, 1},
{ 0, 1},{ 0, 17},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 32},
{ 0, 33},{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34},
{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 48},{ 0, 3},
{ 0, 49},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 50},{ 0, 35},
{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 65},{ 0, 20},{ 4, 1},
{ 2, 1},{ 0, 64},{ 0, 51},{ 2, 1},{ 0, 66},{ 0, 36},
{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 4},{ 0, 80},
{ 0, 67},{ 2, 1},{ 0, 52},{ 0, 81},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0, 21},{ 0, 82},{ 2, 1},{ 0, 37},{ 0, 68},
{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 84},{ 0, 83},
{ 2, 1},{ 0, 53},{ 2, 1},{ 0, 69},{ 0, 85}},
htd10[127][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},
{ 10, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},
{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 28, 1},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 49},
{ 0, 19},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 3},{ 0, 50},
{ 2, 1},{ 0, 35},{ 0, 64},{ 4, 1},{ 2, 1},{ 0, 65},
{ 0, 20},{ 4, 1},{ 2, 1},{ 0, 4},{ 0, 51},{ 2, 1},
{ 0, 66},{ 0, 36},{ 28, 1},{ 10, 1},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0, 80},{ 0, 5},{ 0, 96},{ 2, 1},{ 0, 97},
{ 0, 22},{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 67},
{ 0, 52},{ 0, 81},{ 2, 1},{ 0, 21},{ 2, 1},{ 0, 82},
{ 0, 37},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 54},{ 0,113},
{ 20, 1},{ 8, 1},{ 2, 1},{ 0, 23},{ 4, 1},{ 2, 1},
{ 0, 68},{ 0, 83},{ 0, 6},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0, 53},{ 0, 69},{ 0, 98},{ 2, 1},{ 0,112},{ 2, 1},
{ 0, 7},{ 0,100},{ 14, 1},{ 4, 1},{ 2, 1},{ 0,114},
{ 0, 39},{ 6, 1},{ 2, 1},{ 0, 99},{ 2, 1},{ 0, 84},
{ 0, 85},{ 2, 1},{ 0, 70},{ 0,115},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0, 55},{ 0,101},{ 2, 1},{ 0, 86},{ 0,116},
{ 6, 1},{ 2, 1},{ 0, 71},{ 2, 1},{ 0,102},{ 0,117},
{ 4, 1},{ 2, 1},{ 0, 87},{ 0,118},{ 2, 1},{ 0,103},
{ 0,119}},
htd11[127][2]={{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 0, 1},
{ 8, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},
{ 0, 2},{ 0, 18},{ 24, 1},{ 8, 1},{ 2, 1},{ 0, 33},
{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},{ 4, 1},
{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1},{ 0, 50},
{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},{ 2, 1},
{ 0, 65},{ 0, 20},{ 30, 1},{ 16, 1},{ 10, 1},{ 4, 1},
{ 2, 1},{ 0, 66},{ 0, 36},{ 4, 1},{ 2, 1},{ 0, 51},
{ 0, 67},{ 0, 80},{ 4, 1},{ 2, 1},{ 0, 52},{ 0, 81},
{ 0, 97},{ 6, 1},{ 2, 1},{ 0, 22},{ 2, 1},{ 0, 6},
{ 0, 38},{ 2, 1},{ 0, 98},{ 2, 1},{ 0, 21},{ 2, 1},
{ 0, 5},{ 0, 82},{ 16, 1},{ 10, 1},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0, 37},{ 0, 68},{ 0, 96},{ 2, 1},{ 0, 99},
{ 0, 54},{ 4, 1},{ 2, 1},{ 0,112},{ 0, 23},{ 0,113},
{ 16, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 7},{ 0,100},
{ 0,114},{ 2, 1},{ 0, 39},{ 4, 1},{ 2, 1},{ 0, 83},
{ 0, 53},{ 2, 1},{ 0, 84},{ 0, 69},{ 10, 1},{ 4, 1},
{ 2, 1},{ 0, 70},{ 0,115},{ 2, 1},{ 0, 55},{ 2, 1},
{ 0,101},{ 0, 86},{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0, 85},{ 0, 87},{ 0,116},{ 2, 1},{ 0, 71},{ 0,102},
{ 4, 1},{ 2, 1},{ 0,117},{ 0,118},{ 2, 1},{ 0,103},
{ 0,119}},
htd12[127][2]={{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},{ 2, 1},
{ 0, 17},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 32},{ 0, 2},
{ 16, 1},{ 4, 1},{ 2, 1},{ 0, 33},{ 0, 18},{ 4, 1},
{ 2, 1},{ 0, 34},{ 0, 49},{ 2, 1},{ 0, 19},{ 2, 1},
{ 0, 48},{ 2, 1},{ 0, 3},{ 0, 64},{ 26, 1},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0, 50},{ 0, 35},{ 2, 1},{ 0, 65},
{ 0, 51},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 20},{ 0, 66},
{ 2, 1},{ 0, 36},{ 2, 1},{ 0, 4},{ 0, 80},{ 4, 1},
{ 2, 1},{ 0, 67},{ 0, 52},{ 2, 1},{ 0, 81},{ 0, 21},
{ 28, 1},{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 82},
{ 0, 37},{ 2, 1},{ 0, 83},{ 0, 53},{ 4, 1},{ 2, 1},
{ 0, 96},{ 0, 22},{ 0, 97},{ 4, 1},{ 2, 1},{ 0, 98},
{ 0, 38},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 6},
{ 0, 68},{ 2, 1},{ 0, 84},{ 0, 69},{ 18, 1},{ 10, 1},
{ 4, 1},{ 2, 1},{ 0, 99},{ 0, 54},{ 4, 1},{ 2, 1},
{ 0,112},{ 0, 7},{ 0,113},{ 4, 1},{ 2, 1},{ 0, 23},
{ 0,100},{ 2, 1},{ 0, 70},{ 0,114},{ 10, 1},{ 6, 1},
{ 2, 1},{ 0, 39},{ 2, 1},{ 0, 85},{ 0,115},{ 2, 1},
{ 0, 55},{ 0, 86},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,101},
{ 0,116},{ 2, 1},{ 0, 71},{ 0,102},{ 4, 1},{ 2, 1},
{ 0,117},{ 0, 87},{ 2, 1},{ 0,118},{ 2, 1},{ 0,103},
{ 0,119}},
htd13[511][2]={{ 2, 1},{ 0, 0},{ 6, 1},{ 2, 1},{ 0, 16},{ 2, 1},
{ 0, 1},{ 0, 17},{ 28, 1},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0, 32},{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 3},
{ 0, 49},{ 6, 1},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 50},
{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},{ 0, 65},
{ 70, 1},{ 28, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0, 20},
{ 2, 1},{ 0, 51},{ 0, 66},{ 4, 1},{ 2, 1},{ 0, 36},
{ 0, 80},{ 2, 1},{ 0, 67},{ 0, 52},{ 4, 1},{ 2, 1},
{ 0, 81},{ 0, 21},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 82}, // 60
{ 2, 1},{ 0, 37},{ 2, 1},{ 0, 68},{ 0, 83},{ 14, 1},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 96},{ 0, 6},{ 2, 1},
{ 0, 97},{ 0, 22},{ 4, 1},{ 2, 1},{ 0,128},{ 0, 8},
{ 0,129},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 53},
{ 0, 98},{ 2, 1},{ 0, 38},{ 0, 84},{ 4, 1},{ 2, 1},
{ 0, 69},{ 0, 99},{ 2, 1},{ 0, 54},{ 0,112},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0, 7},{ 0, 85},{ 0,113},{ 2, 1},
{ 0, 23},{ 2, 1},{ 0, 39},{ 0, 55},{ 72, 1},{ 24, 1},
{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 24},{ 0,130},{ 2, 1},
{ 0, 40},{ 4, 1},{ 2, 1},{ 0,100},{ 0, 70},{ 0,114}, // 120
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,132},{ 0, 72},{ 2, 1},
{ 0,144},{ 0, 9},{ 2, 1},{ 0,145},{ 0, 25},{ 24, 1},
{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,115},{ 0,101},
{ 2, 1},{ 0, 86},{ 0,116},{ 4, 1},{ 2, 1},{ 0, 71},
{ 0,102},{ 0,131},{ 6, 1},{ 2, 1},{ 0, 56},{ 2, 1},
{ 0,117},{ 0, 87},{ 2, 1},{ 0,146},{ 0, 41},{ 14, 1},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,103},{ 0,133},{ 2, 1},
{ 0, 88},{ 0, 57},{ 2, 1},{ 0,147},{ 2, 1},{ 0, 73},
{ 0,134},{ 6, 1},{ 2, 1},{ 0,160},{ 2, 1},{ 0,104},
{ 0, 10},{ 2, 1},{ 0,161},{ 0, 26},{ 68, 1},{ 24, 1}, // 180
{ 12, 1},{ 4, 1},{ 2, 1},{ 0,162},{ 0, 42},{ 4, 1},
{ 2, 1},{ 0,149},{ 0, 89},{ 2, 1},{ 0,163},{ 0, 58},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 74},{ 0,150},{ 2, 1},
{ 0,176},{ 0, 11},{ 2, 1},{ 0,177},{ 0, 27},{ 20, 1},
{ 8, 1},{ 2, 1},{ 0,178},{ 4, 1},{ 2, 1},{ 0,118},
{ 0,119},{ 0,148},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,135},
{ 0,120},{ 0,164},{ 4, 1},{ 2, 1},{ 0,105},{ 0,165},
{ 0, 43},{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 90},
{ 0,136},{ 0,179},{ 2, 1},{ 0, 59},{ 2, 1},{ 0,121},
{ 0,166},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,106},{ 0,180}, // 240
{ 0,192},{ 4, 1},{ 2, 1},{ 0, 12},{ 0,152},{ 0,193},
{ 60, 1},{ 22, 1},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 28},
{ 2, 1},{ 0,137},{ 0,181},{ 2, 1},{ 0, 91},{ 0,194},
{ 4, 1},{ 2, 1},{ 0, 44},{ 0, 60},{ 4, 1},{ 2, 1},
{ 0,182},{ 0,107},{ 2, 1},{ 0,196},{ 0, 76},{ 16, 1},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,168},{ 0,138},{ 2, 1},
{ 0,208},{ 0, 13},{ 2, 1},{ 0,209},{ 2, 1},{ 0, 75},
{ 2, 1},{ 0,151},{ 0,167},{ 12, 1},{ 6, 1},{ 2, 1},
{ 0,195},{ 2, 1},{ 0,122},{ 0,153},{ 4, 1},{ 2, 1},
{ 0,197},{ 0, 92},{ 0,183},{ 4, 1},{ 2, 1},{ 0, 29}, // 300
{ 0,210},{ 2, 1},{ 0, 45},{ 2, 1},{ 0,123},{ 0,211},
{ 52, 1},{ 28, 1},{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 61},
{ 0,198},{ 4, 1},{ 2, 1},{ 0,108},{ 0,169},{ 2, 1},
{ 0,154},{ 0,212},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,184},
{ 0,139},{ 2, 1},{ 0, 77},{ 0,199},{ 4, 1},{ 2, 1},
{ 0,124},{ 0,213},{ 2, 1},{ 0, 93},{ 0,224},{ 10, 1},
{ 4, 1},{ 2, 1},{ 0,225},{ 0, 30},{ 4, 1},{ 2, 1},
{ 0, 14},{ 0, 46},{ 0,226},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0,227},{ 0,109},{ 2, 1},{ 0,140},{ 0,228},{ 4, 1},
{ 2, 1},{ 0,229},{ 0,186},{ 0,240},{ 38, 1},{ 16, 1}, // 360
{ 4, 1},{ 2, 1},{ 0,241},{ 0, 31},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0,170},{ 0,155},{ 0,185},{ 2, 1},{ 0, 62},
{ 2, 1},{ 0,214},{ 0,200},{ 12, 1},{ 6, 1},{ 2, 1},
{ 0, 78},{ 2, 1},{ 0,215},{ 0,125},{ 2, 1},{ 0,171},
{ 2, 1},{ 0, 94},{ 0,201},{ 6, 1},{ 2, 1},{ 0, 15},
{ 2, 1},{ 0,156},{ 0,110},{ 2, 1},{ 0,242},{ 0, 47},
{ 32, 1},{ 16, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,216},
{ 0,141},{ 0, 63},{ 6, 1},{ 2, 1},{ 0,243},{ 2, 1},
{ 0,230},{ 0,202},{ 2, 1},{ 0,244},{ 0, 79},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0,187},{ 0,172},{ 2, 1},{ 0,231}, // 420
{ 0,245},{ 4, 1},{ 2, 1},{ 0,217},{ 0,157},{ 2, 1},
{ 0, 95},{ 0,232},{ 30, 1},{ 12, 1},{ 6, 1},{ 2, 1},
{ 0,111},{ 2, 1},{ 0,246},{ 0,203},{ 4, 1},{ 2, 1},
{ 0,188},{ 0,173},{ 0,218},{ 8, 1},{ 2, 1},{ 0,247},
{ 4, 1},{ 2, 1},{ 0,126},{ 0,127},{ 0,142},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0,158},{ 0,174},{ 0,204},{ 2, 1},
{ 0,248},{ 0,143},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0,219},{ 0,189},{ 2, 1},{ 0,234},{ 0,249},{ 4, 1},
{ 2, 1},{ 0,159},{ 0,235},{ 2, 1},{ 0,190},{ 2, 1},
{ 0,205},{ 0,250},{ 14, 1},{ 4, 1},{ 2, 1},{ 0,221}, // 480
{ 0,236},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,233},{ 0,175},
{ 0,220},{ 2, 1},{ 0,206},{ 0,251},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0,191},{ 0,222},{ 2, 1},{ 0,207},{ 0,238},
{ 4, 1},{ 2, 1},{ 0,223},{ 0,239},{ 2, 1},{ 0,255},
{ 2, 1},{ 0,237},{ 2, 1},{ 0,253},{ 2, 1},{ 0,252},
{ 0,254}},
htd15[511][2]={{ 16, 1},{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},
{ 0, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},
{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 50, 1},{ 16, 1},
{ 6, 1},{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 49},
{ 6, 1},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 3},{ 0, 64},
{ 2, 1},{ 0, 50},{ 0, 35},{ 14, 1},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0, 4},{ 0, 20},{ 0, 65},{ 4, 1},{ 2, 1},
{ 0, 51},{ 0, 66},{ 2, 1},{ 0, 36},{ 0, 67},{ 10, 1},
{ 6, 1},{ 2, 1},{ 0, 52},{ 2, 1},{ 0, 80},{ 0, 5},
{ 2, 1},{ 0, 81},{ 0, 21},{ 4, 1},{ 2, 1},{ 0, 82}, // 60
{ 0, 37},{ 4, 1},{ 2, 1},{ 0, 68},{ 0, 83},{ 0, 97},
{ 90, 1},{ 36, 1},{ 18, 1},{ 10, 1},{ 6, 1},{ 2, 1},
{ 0, 53},{ 2, 1},{ 0, 96},{ 0, 6},{ 2, 1},{ 0, 22},
{ 0, 98},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 84},{ 2, 1},
{ 0, 69},{ 0, 99},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 54},
{ 2, 1},{ 0,112},{ 0, 7},{ 2, 1},{ 0,113},{ 0, 85},
{ 4, 1},{ 2, 1},{ 0, 23},{ 0,100},{ 2, 1},{ 0,114},
{ 0, 39},{ 24, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0, 70},{ 0,115},{ 2, 1},{ 0, 55},{ 0,101},{ 4, 1},
{ 2, 1},{ 0, 86},{ 0,128},{ 2, 1},{ 0, 8},{ 0,116}, // 120
{ 4, 1},{ 2, 1},{ 0,129},{ 0, 24},{ 2, 1},{ 0,130},
{ 0, 40},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 71},
{ 0,102},{ 2, 1},{ 0,131},{ 0, 56},{ 4, 1},{ 2, 1},
{ 0,117},{ 0, 87},{ 2, 1},{ 0,132},{ 0, 72},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0,144},{ 0, 25},{ 0,145},{ 4, 1},
{ 2, 1},{ 0,146},{ 0,118},{ 2, 1},{ 0,103},{ 0, 41},
{ 92, 1},{ 36, 1},{ 18, 1},{ 10, 1},{ 4, 1},{ 2, 1},
{ 0,133},{ 0, 88},{ 4, 1},{ 2, 1},{ 0, 9},{ 0,119},
{ 0,147},{ 4, 1},{ 2, 1},{ 0, 57},{ 0,148},{ 2, 1},
{ 0, 73},{ 0,134},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,104}, // 180
{ 2, 1},{ 0,160},{ 0, 10},{ 2, 1},{ 0,161},{ 0, 26},
{ 4, 1},{ 2, 1},{ 0,162},{ 0, 42},{ 2, 1},{ 0,149},
{ 0, 89},{ 26, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0,163},
{ 2, 1},{ 0, 58},{ 0,135},{ 4, 1},{ 2, 1},{ 0,120},
{ 0,164},{ 2, 1},{ 0, 74},{ 0,150},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0,105},{ 0,176},{ 0,177},{ 4, 1},{ 2, 1},
{ 0, 27},{ 0,165},{ 0,178},{ 14, 1},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0, 90},{ 0, 43},{ 2, 1},{ 0,136},{ 0,151},
{ 2, 1},{ 0,179},{ 2, 1},{ 0,121},{ 0, 59},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0,106},{ 0,180},{ 2, 1},{ 0, 75}, // 240
{ 0,193},{ 4, 1},{ 2, 1},{ 0,152},{ 0,137},{ 2, 1},
{ 0, 28},{ 0,181},{ 80, 1},{ 34, 1},{ 16, 1},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0, 91},{ 0, 44},{ 0,194},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0, 11},{ 0,192},{ 0,166},{ 2, 1},
{ 0,167},{ 0,122},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,195},
{ 0, 60},{ 4, 1},{ 2, 1},{ 0, 12},{ 0,153},{ 0,182},
{ 4, 1},{ 2, 1},{ 0,107},{ 0,196},{ 2, 1},{ 0, 76},
{ 0,168},{ 20, 1},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,138},
{ 0,197},{ 4, 1},{ 2, 1},{ 0,208},{ 0, 92},{ 0,209},
{ 4, 1},{ 2, 1},{ 0,183},{ 0,123},{ 2, 1},{ 0, 29}, // 300
{ 2, 1},{ 0, 13},{ 0, 45},{ 12, 1},{ 4, 1},{ 2, 1},
{ 0,210},{ 0,211},{ 4, 1},{ 2, 1},{ 0, 61},{ 0,198},
{ 2, 1},{ 0,108},{ 0,169},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0,154},{ 0,184},{ 0,212},{ 4, 1},{ 2, 1},{ 0,139},
{ 0, 77},{ 2, 1},{ 0,199},{ 0,124},{ 68, 1},{ 34, 1},
{ 18, 1},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,213},{ 0, 93},
{ 4, 1},{ 2, 1},{ 0,224},{ 0, 14},{ 0,225},{ 4, 1},
{ 2, 1},{ 0, 30},{ 0,226},{ 2, 1},{ 0,170},{ 0, 46},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,185},{ 0,155},{ 2, 1},
{ 0,227},{ 0,214},{ 4, 1},{ 2, 1},{ 0,109},{ 0, 62}, // 360
{ 2, 1},{ 0,200},{ 0,140},{ 16, 1},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0,228},{ 0, 78},{ 2, 1},{ 0,215},{ 0,125},
{ 4, 1},{ 2, 1},{ 0,229},{ 0,186},{ 2, 1},{ 0,171},
{ 0, 94},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,201},{ 0,156},
{ 2, 1},{ 0,241},{ 0, 31},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0,240},{ 0,110},{ 0,242},{ 2, 1},{ 0, 47},{ 0,230},
{ 38, 1},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,216},
{ 0,243},{ 2, 1},{ 0, 63},{ 0,244},{ 6, 1},{ 2, 1},
{ 0, 79},{ 2, 1},{ 0,141},{ 0,217},{ 2, 1},{ 0,187},
{ 0,202},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,172},{ 0,231}, // 420
{ 2, 1},{ 0,126},{ 0,245},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0,157},{ 0, 95},{ 2, 1},{ 0,232},{ 0,142},{ 2, 1},
{ 0,246},{ 0,203},{ 34, 1},{ 18, 1},{ 10, 1},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0, 15},{ 0,174},{ 0,111},{ 2, 1},
{ 0,188},{ 0,218},{ 4, 1},{ 2, 1},{ 0,173},{ 0,247},
{ 2, 1},{ 0,127},{ 0,233},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0,158},{ 0,204},{ 2, 1},{ 0,248},{ 0,143},{ 4, 1},
{ 2, 1},{ 0,219},{ 0,189},{ 2, 1},{ 0,234},{ 0,249},
{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,159},{ 0,220},
{ 2, 1},{ 0,205},{ 0,235},{ 4, 1},{ 2, 1},{ 0,190}, // 480
{ 0,250},{ 2, 1},{ 0,175},{ 0,221},{ 14, 1},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0,236},{ 0,206},{ 0,251},{ 4, 1},
{ 2, 1},{ 0,191},{ 0,237},{ 2, 1},{ 0,222},{ 0,252},
{ 6, 1},{ 4, 1},{ 2, 1},{ 0,207},{ 0,253},{ 0,238},
{ 4, 1},{ 2, 1},{ 0,223},{ 0,254},{ 2, 1},{ 0,239},
{ 0,255}},
htd16[511][2]={{ 2, 1},{ 0, 0},{ 6, 1},{ 2, 1},{ 0, 16},{ 2, 1},
{ 0, 1},{ 0, 17},{ 42, 1},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0, 32},{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 10, 1},
{ 6, 1},{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},
{ 2, 1},{ 0, 49},{ 0, 19},{ 10, 1},{ 4, 1},{ 2, 1},
{ 0, 50},{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},
{ 0, 65},{ 6, 1},{ 2, 1},{ 0, 20},{ 2, 1},{ 0, 51},
{ 0, 66},{ 4, 1},{ 2, 1},{ 0, 36},{ 0, 80},{ 2, 1},
{ 0, 67},{ 0, 52},{138, 1},{ 40, 1},{ 16, 1},{ 6, 1},
{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 21},{ 0, 81},{ 4, 1}, // 60
{ 2, 1},{ 0, 82},{ 0, 37},{ 4, 1},{ 2, 1},{ 0, 68},
{ 0, 53},{ 0, 83},{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0, 96},{ 0, 6},{ 0, 97},{ 2, 1},{ 0, 22},{ 0, 98},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 84},{ 2, 1},
{ 0, 69},{ 0, 99},{ 4, 1},{ 2, 1},{ 0, 54},{ 0,112},
{ 0,113},{ 40, 1},{ 18, 1},{ 8, 1},{ 2, 1},{ 0, 23},
{ 2, 1},{ 0, 7},{ 2, 1},{ 0, 85},{ 0,100},{ 4, 1},
{ 2, 1},{ 0,114},{ 0, 39},{ 4, 1},{ 2, 1},{ 0, 70},
{ 0,101},{ 0,115},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 55},
{ 2, 1},{ 0, 86},{ 0, 8},{ 2, 1},{ 0,128},{ 0,129}, // 120
{ 6, 1},{ 2, 1},{ 0, 24},{ 2, 1},{ 0,116},{ 0, 71},
{ 2, 1},{ 0,130},{ 2, 1},{ 0, 40},{ 0,102},{ 24, 1},
{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,131},{ 0, 56},
{ 2, 1},{ 0,117},{ 0,132},{ 4, 1},{ 2, 1},{ 0, 72},
{ 0,144},{ 0,145},{ 6, 1},{ 2, 1},{ 0, 25},{ 2, 1},
{ 0, 9},{ 0,118},{ 2, 1},{ 0,146},{ 0, 41},{ 14, 1},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,133},{ 0, 88},{ 2, 1},
{ 0,147},{ 0, 57},{ 4, 1},{ 2, 1},{ 0,160},{ 0, 10},
{ 0, 26},{ 8, 1},{ 2, 1},{ 0,162},{ 2, 1},{ 0,103},
{ 2, 1},{ 0, 87},{ 0, 73},{ 6, 1},{ 2, 1},{ 0,148}, // 180
{ 2, 1},{ 0,119},{ 0,134},{ 2, 1},{ 0,161},{ 2, 1},
{ 0,104},{ 0,149},{220, 1},{126, 1},{ 50, 1},{ 26, 1},
{ 12, 1},{ 6, 1},{ 2, 1},{ 0, 42},{ 2, 1},{ 0, 89},
{ 0, 58},{ 2, 1},{ 0,163},{ 2, 1},{ 0,135},{ 0,120},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,164},{ 0, 74},{ 2, 1},
{ 0,150},{ 0,105},{ 4, 1},{ 2, 1},{ 0,176},{ 0, 11},
{ 0,177},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 27},{ 0,178},
{ 2, 1},{ 0, 43},{ 2, 1},{ 0,165},{ 0, 90},{ 6, 1},
{ 2, 1},{ 0,179},{ 2, 1},{ 0,166},{ 0,106},{ 4, 1},
{ 2, 1},{ 0,180},{ 0, 75},{ 2, 1},{ 0, 12},{ 0,193}, // 240
{ 30, 1},{ 14, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,181},
{ 0,194},{ 0, 44},{ 4, 1},{ 2, 1},{ 0,167},{ 0,195},
{ 2, 1},{ 0,107},{ 0,196},{ 8, 1},{ 2, 1},{ 0, 29},
{ 4, 1},{ 2, 1},{ 0,136},{ 0,151},{ 0, 59},{ 4, 1},
{ 2, 1},{ 0,209},{ 0,210},{ 2, 1},{ 0, 45},{ 0,211},
{ 18, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 30},{ 0, 46},
{ 0,226},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,121},{ 0,152},
{ 0,192},{ 2, 1},{ 0, 28},{ 2, 1},{ 0,137},{ 0, 91},
{ 14, 1},{ 6, 1},{ 2, 1},{ 0, 60},{ 2, 1},{ 0,122},
{ 0,182},{ 4, 1},{ 2, 1},{ 0, 76},{ 0,153},{ 2, 1}, // 300
{ 0,168},{ 0,138},{ 6, 1},{ 2, 1},{ 0, 13},{ 2, 1},
{ 0,197},{ 0, 92},{ 4, 1},{ 2, 1},{ 0, 61},{ 0,198},
{ 2, 1},{ 0,108},{ 0,154},{ 88, 1},{ 86, 1},{ 36, 1},
{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,139},{ 0, 77},
{ 2, 1},{ 0,199},{ 0,124},{ 4, 1},{ 2, 1},{ 0,213},
{ 0, 93},{ 2, 1},{ 0,224},{ 0, 14},{ 8, 1},{ 2, 1},
{ 0,227},{ 4, 1},{ 2, 1},{ 0,208},{ 0,183},{ 0,123},
{ 6, 1},{ 4, 1},{ 2, 1},{ 0,169},{ 0,184},{ 0,212},
{ 2, 1},{ 0,225},{ 2, 1},{ 0,170},{ 0,185},{ 24, 1},
{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,155},{ 0,214}, // 360
{ 0,109},{ 2, 1},{ 0, 62},{ 0,200},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0,140},{ 0,228},{ 0, 78},{ 4, 1},{ 2, 1},
{ 0,215},{ 0,229},{ 2, 1},{ 0,186},{ 0,171},{ 12, 1},
{ 4, 1},{ 2, 1},{ 0,156},{ 0,230},{ 4, 1},{ 2, 1},
{ 0,110},{ 0,216},{ 2, 1},{ 0,141},{ 0,187},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0,231},{ 0,157},{ 2, 1},{ 0,232},
{ 0,142},{ 4, 1},{ 2, 1},{ 0,203},{ 0,188},{ 0,158},
{ 0,241},{ 2, 1},{ 0, 31},{ 2, 1},{ 0, 15},{ 0, 47},
{ 66, 1},{ 56, 1},{ 2, 1},{ 0,242},{ 52, 1},{ 50, 1},
{ 20, 1},{ 8, 1},{ 2, 1},{ 0,189},{ 2, 1},{ 0, 94}, // 420
{ 2, 1},{ 0,125},{ 0,201},{ 6, 1},{ 2, 1},{ 0,202},
{ 2, 1},{ 0,172},{ 0,126},{ 4, 1},{ 2, 1},{ 0,218},
{ 0,173},{ 0,204},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,174},
{ 2, 1},{ 0,219},{ 0,220},{ 2, 1},{ 0,205},{ 0,190},
{ 6, 1},{ 4, 1},{ 2, 1},{ 0,235},{ 0,237},{ 0,238},
{ 6, 1},{ 4, 1},{ 2, 1},{ 0,217},{ 0,234},{ 0,233},
{ 2, 1},{ 0,222},{ 4, 1},{ 2, 1},{ 0,221},{ 0,236},
{ 0,206},{ 0, 63},{ 0,240},{ 4, 1},{ 2, 1},{ 0,243},
{ 0,244},{ 2, 1},{ 0, 79},{ 2, 1},{ 0,245},{ 0, 95},
{ 10, 1},{ 2, 1},{ 0,255},{ 4, 1},{ 2, 1},{ 0,246}, // 480
{ 0,111},{ 2, 1},{ 0,247},{ 0,127},{ 12, 1},{ 6, 1},
{ 2, 1},{ 0,143},{ 2, 1},{ 0,248},{ 0,249},{ 4, 1},
{ 2, 1},{ 0,159},{ 0,250},{ 0,175},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0,251},{ 0,191},{ 2, 1},{ 0,252},{ 0,207},
{ 4, 1},{ 2, 1},{ 0,253},{ 0,223},{ 2, 1},{ 0,254},
{ 0,239}},
htd24[512][2]={{ 60, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},
{ 2, 1},{ 0, 1},{ 0, 17},{ 14, 1},{ 6, 1},{ 4, 1},
{ 2, 1},{ 0, 32},{ 0, 2},{ 0, 33},{ 2, 1},{ 0, 18},
{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},{ 14, 1},
{ 4, 1},{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1},
{ 0, 50},{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},
{ 0, 65},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 20},{ 0, 51},
{ 2, 1},{ 0, 66},{ 0, 36},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0, 67},{ 0, 52},{ 0, 81},{ 6, 1},{ 4, 1},{ 2, 1},
{ 0, 80},{ 0, 5},{ 0, 21},{ 2, 1},{ 0, 82},{ 0, 37}, // 60
{250+85, 1},{ 98, 1},{ 34, 1},{ 18, 1},{ 10, 1},{ 4, 1},
{ 2, 1},{ 0, 68},{ 0, 83},{ 2, 1},{ 0, 53},{ 2, 1},
{ 0, 96},{ 0, 6},{ 4, 1},{ 2, 1},{ 0, 97},{ 0, 22},
{ 2, 1},{ 0, 98},{ 0, 38},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0, 84},{ 0, 69},{ 2, 1},{ 0, 99},{ 0, 54},{ 4, 1},
{ 2, 1},{ 0,113},{ 0, 85},{ 2, 1},{ 0,100},{ 0, 70},
{ 32, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0,114},{ 2, 1},
{ 0, 39},{ 0, 55},{ 2, 1},{ 0,115},{ 4, 1},{ 2, 1},
{ 0,112},{ 0, 7},{ 0, 23},{ 10, 1},{ 4, 1},{ 2, 1},
{ 0,101},{ 0, 86},{ 4, 1},{ 2, 1},{ 0,128},{ 0, 8}, // 120
{ 0,129},{ 4, 1},{ 2, 1},{ 0,116},{ 0, 71},{ 2, 1},
{ 0, 24},{ 0,130},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},
{ 0, 40},{ 0,102},{ 2, 1},{ 0,131},{ 0, 56},{ 4, 1},
{ 2, 1},{ 0,117},{ 0, 87},{ 2, 1},{ 0,132},{ 0, 72},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,145},{ 0, 25},{ 2, 1},
{ 0,146},{ 0,118},{ 4, 1},{ 2, 1},{ 0,103},{ 0, 41},
{ 2, 1},{ 0,133},{ 0, 88},{ 92, 1},{ 34, 1},{ 16, 1},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,147},{ 0, 57},{ 2, 1},
{ 0,148},{ 0, 73},{ 4, 1},{ 2, 1},{ 0,119},{ 0,134},
{ 2, 1},{ 0,104},{ 0,161},{ 8, 1},{ 4, 1},{ 2, 1}, // 180
{ 0,162},{ 0, 42},{ 2, 1},{ 0,149},{ 0, 89},{ 4, 1},
{ 2, 1},{ 0,163},{ 0, 58},{ 2, 1},{ 0,135},{ 2, 1},
{ 0,120},{ 0, 74},{ 22, 1},{ 12, 1},{ 4, 1},{ 2, 1},
{ 0,164},{ 0,150},{ 4, 1},{ 2, 1},{ 0,105},{ 0,177},
{ 2, 1},{ 0, 27},{ 0,165},{ 6, 1},{ 2, 1},{ 0,178},
{ 2, 1},{ 0, 90},{ 0, 43},{ 2, 1},{ 0,136},{ 0,179},
{ 16, 1},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,144},{ 2, 1},
{ 0, 9},{ 0,160},{ 2, 1},{ 0,151},{ 0,121},{ 4, 1},
{ 2, 1},{ 0,166},{ 0,106},{ 0,180},{ 12, 1},{ 6, 1},
{ 2, 1},{ 0, 26},{ 2, 1},{ 0, 10},{ 0,176},{ 2, 1}, // 240
{ 0, 59},{ 2, 1},{ 0, 11},{ 0,192},{ 4, 1},{ 2, 1},
{ 0, 75},{ 0,193},{ 2, 1},{ 0,152},{ 0,137},{ 67, 1},
{ 34, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 28},
{ 0,181},{ 2, 1},{ 0, 91},{ 0,194},{ 4, 1},{ 2, 1},
{ 0, 44},{ 0,167},{ 2, 1},{ 0,122},{ 0,195},{ 10, 1},
{ 6, 1},{ 2, 1},{ 0, 60},{ 2, 1},{ 0, 12},{ 0,208},
{ 2, 1},{ 0,182},{ 0,107},{ 4, 1},{ 2, 1},{ 0,196},
{ 0, 76},{ 2, 1},{ 0,153},{ 0,168},{ 16, 1},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0,138},{ 0,197},{ 2, 1},{ 0, 92},
{ 0,209},{ 4, 1},{ 2, 1},{ 0,183},{ 0,123},{ 2, 1}, // 300
{ 0, 29},{ 0,210},{ 9, 1},{ 4, 1},{ 2, 1},{ 0, 45},
{ 0,211},{ 2, 1},{ 0, 61},{ 0,198},{ 85,250},{ 4, 1}, // 306 -
{ 2, 1},{ 0,108},{ 0,169},{ 2, 1},{ 0,154},{ 0,212},
{ 32, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,184},
{ 0,139},{ 2, 1},{ 0, 77},{ 0,199},{ 4, 1},{ 2, 1},
{ 0,124},{ 0,213},{ 2, 1},{ 0, 93},{ 0,225},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0, 30},{ 0,226},{ 2, 1},{ 0,170},
{ 0,185},{ 4, 1},{ 2, 1},{ 0,155},{ 0,227},{ 2, 1},
{ 0,214},{ 0,109},{ 20, 1},{ 10, 1},{ 6, 1},{ 2, 1},
{ 0, 62},{ 2, 1},{ 0, 46},{ 0, 78},{ 2, 1},{ 0,200}, // 360
{ 0,140},{ 4, 1},{ 2, 1},{ 0,228},{ 0,215},{ 4, 1},
{ 2, 1},{ 0,125},{ 0,171},{ 0,229},{ 10, 1},{ 4, 1},
{ 2, 1},{ 0,186},{ 0, 94},{ 2, 1},{ 0,201},{ 2, 1},
{ 0,156},{ 0,110},{ 8, 1},{ 2, 1},{ 0,230},{ 2, 1},
{ 0, 13},{ 2, 1},{ 0,224},{ 0, 14},{ 4, 1},{ 2, 1},
{ 0,216},{ 0,141},{ 2, 1},{ 0,187},{ 0,202},{ 74, 1},
{ 2, 1},{ 0,255},{ 64, 1},{ 58, 1},{ 32, 1},{ 16, 1},
{ 8, 1},{ 4, 1},{ 2, 1},{ 0,172},{ 0,231},{ 2, 1},
{ 0,126},{ 0,217},{ 4, 1},{ 2, 1},{ 0,157},{ 0,232},
{ 2, 1},{ 0,142},{ 0,203},{ 8, 1},{ 4, 1},{ 2, 1}, // 420
{ 0,188},{ 0,218},{ 2, 1},{ 0,173},{ 0,233},{ 4, 1},
{ 2, 1},{ 0,158},{ 0,204},{ 2, 1},{ 0,219},{ 0,189},
{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,234},{ 0,174},
{ 2, 1},{ 0,220},{ 0,205},{ 4, 1},{ 2, 1},{ 0,235},
{ 0,190},{ 2, 1},{ 0,221},{ 0,236},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0,206},{ 0,237},{ 2, 1},{ 0,222},{ 0,238},
{ 0, 15},{ 4, 1},{ 2, 1},{ 0,240},{ 0, 31},{ 0,241},
{ 4, 1},{ 2, 1},{ 0,242},{ 0, 47},{ 2, 1},{ 0,243},
{ 0, 63},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,244},
{ 0, 79},{ 2, 1},{ 0,245},{ 0, 95},{ 4, 1},{ 2, 1}, // 480
{ 0,246},{ 0,111},{ 2, 1},{ 0,247},{ 2, 1},{ 0,127},
{ 0,143},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,248},{ 0,249},
{ 4, 1},{ 2, 1},{ 0,159},{ 0,175},{ 0,250},{ 8, 1},
{ 4, 1},{ 2, 1},{ 0,251},{ 0,191},{ 2, 1},{ 0,252},
{ 0,207},{ 4, 1},{ 2, 1},{ 0,253},{ 0,223},{ 2, 1},
{ 0,254},{ 0,239}},
htd32[ 31][2]={{ 2, 1},{ 0, 0},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 8},
{ 0, 4},{ 2, 1},{ 0, 1},{ 0, 2},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0, 12},{ 0, 10},{ 2, 1},{ 0, 3},{ 0, 6},
{ 6, 1},{ 2, 1},{ 0, 9},{ 2, 1},{ 0, 5},{ 0, 7},
{ 4, 1},{ 2, 1},{ 0, 14},{ 0, 13},{ 2, 1},{ 0, 15},
{ 0, 11}},
htd33[ 31][2]={{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 1},
{ 2, 1},{ 0, 2},{ 0, 3},{ 4, 1},{ 2, 1},{ 0, 4},
{ 0, 5},{ 2, 1},{ 0, 6},{ 0, 7},{ 8, 1},{ 4, 1},
{ 2, 1},{ 0, 8},{ 0, 9},{ 2, 1},{ 0, 10},{ 0, 11},
{ 4, 1},{ 2, 1},{ 0, 12},{ 0, 13},{ 2, 1},{ 0, 14},
{ 0, 15}};
const HUFFMANCODETABLE MPEGaudio::ht[HTN]=
{
{ 0, 0-1, 0-1, 0, 0, htd33},
{ 1, 2-1, 2-1, 0, 7,htd01},
{ 2, 3-1, 3-1, 0, 17,htd02},
{ 3, 3-1, 3-1, 0, 17,htd03},
{ 4, 0-1, 0-1, 0, 0, htd33},
{ 5, 4-1, 4-1, 0, 31,htd05},
{ 6, 4-1, 4-1, 0, 31,htd06},
{ 7, 6-1, 6-1, 0, 71,htd07},
{ 8, 6-1, 6-1, 0, 71,htd08},
{ 9, 6-1, 6-1, 0, 71,htd09},
{10, 8-1, 8-1, 0,127,htd10},
{11, 8-1, 8-1, 0,127,htd11},
{12, 8-1, 8-1, 0,127,htd12},
{13,16-1,16-1, 0,511,htd13},
{14, 0-1, 0-1, 0, 0, htd33},
{15,16-1,16-1, 0,511,htd15},
{16,16-1,16-1, 1,511,htd16},
{17,16-1,16-1, 2,511,htd16},
{18,16-1,16-1, 3,511,htd16},
{19,16-1,16-1, 4,511,htd16},
{20,16-1,16-1, 6,511,htd16},
{21,16-1,16-1, 8,511,htd16},
{22,16-1,16-1,10,511,htd16},
{23,16-1,16-1,13,511,htd16},
{24,16-1,16-1, 4,512,htd24},
{25,16-1,16-1, 5,512,htd24},
{26,16-1,16-1, 6,512,htd24},
{27,16-1,16-1, 7,512,htd24},
{28,16-1,16-1, 8,512,htd24},
{29,16-1,16-1, 9,512,htd24},
{30,16-1,16-1,11,512,htd24},
{31,16-1,16-1,13,512,htd24},
{32, 1-1,16-1, 0, 31,htd32},
{33, 1-1,16-1, 0, 31,htd33}
};

View file

@ -0,0 +1,111 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Mpeglayer1.cc
// It's for MPEG Layer 1
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "MPEGaudio.h"
#if defined(_WIN32) && defined(_MSC_VER)
// disable warnings about double to float conversions
#pragma warning(disable: 4244 4305)
#endif
// Tables for layer 1
static const REAL factortable[15] =
{
0.0,
(1.0/2.0) * (4.0/3.0), (1.0/4.0) * (8.0/7.0),
(1.0/8.0) * (16.0/15.0), (1.0/16.0) * (32.0/31.0),
(1.0/32.0) * (64.0/63.0), (1.0/64.0) * (128.0/127.0),
(1.0/128.0) * (256.0/255.0), (1.0/256.0) * (512.0/511.0),
(1.0/512.0) * (1024.0/1023.0), (1.0/1024.0) * (2048.0/2047.0),
(1.0/2048.0) * (4096.0/4095.0), (1.0/4096.0) * (8192.0/8191.0),
(1.0/8192.0) * (16384.0/16383.0), (1.0/16384.0) * (32768.0/32767.0)
};
static const REAL offsettable[15] =
{
0.0,
((1.0/2.0)-1.0) * (4.0/3.0), ((1.0/4.0)-1.0) * (8.0/7.0),
((1.0/8.0)-1.0) * (16.0/15.0), ((1.0/16.0)-1.0) * (32.0/31.0),
((1.0/32.0)-1.0) * (64.0/63.0), ((1.0/64.0)-1.0) * (128.0/127.0),
((1.0/128.0)-1.0) * (256.0/255.0), ((1.0/256.0)-1.0) * (512.0/511.0),
((1.0/512.0)-1.0) * (1024.0/1023.0), ((1.0/1024.0)-1.0) * (2048.0/2047.0),
((1.0/2048.0)-1.0) * (4096.0/4095.0), ((1.0/4096.0)-1.0) * (8192.0/8191.0),
((1.0/8192.0)-1.0) * (16384.0/16383.0), ((1.0/16384.0)-1.0) * (32768.0/32767.0)
};
// Mpeg layer 1
void MPEGaudio::extractlayer1(void)
{
REAL fraction[MAXCHANNEL][MAXSUBBAND];
REAL scalefactor[MAXCHANNEL][MAXSUBBAND];
int bitalloc[MAXCHANNEL][MAXSUBBAND],
sample[MAXCHANNEL][MAXSUBBAND];
register int i,j;
int s=stereobound,l;
// Bitalloc
for(i=0;i<s;i++)
{
bitalloc[LS][i]=getbits(4);
bitalloc[RS][i]=getbits(4);
}
for(;i<MAXSUBBAND;i++)
bitalloc[LS][i]=
bitalloc[RS][i]=getbits(4);
// Scale index
if(inputstereo)
for(i=0;i<MAXSUBBAND;i++)
{
if(bitalloc[LS][i])scalefactor[LS][i]=scalefactorstable[getbits(6)];
if(bitalloc[RS][i])scalefactor[RS][i]=scalefactorstable[getbits(6)];
}
else
for(i=0;i<MAXSUBBAND;i++)
if(bitalloc[LS][i])scalefactor[LS][i]=scalefactorstable[getbits(6)];
for(l=0;l<SCALEBLOCK;l++)
{
// Sample
for(i=0;i<s;i++)
{
if((j=bitalloc[LS][i]))sample[LS][i]=getbits(j+1);
if((j=bitalloc[RS][i]))sample[RS][i]=getbits(j+1);
}
for(;i<MAXSUBBAND;i++)
if((j=bitalloc[LS][i]))sample[LS][i]=sample[RS][i]=getbits(j+1);
// Fraction
if(outputstereo)
for(i=0;i<MAXSUBBAND;i++)
{
if((j=bitalloc[LS][i]))
fraction[LS][i]=(REAL(sample[LS][i])*factortable[j]+offsettable[j])
*scalefactor[LS][i];
else fraction[LS][i]=0.0;
if((j=bitalloc[RS][i]))
fraction[RS][i]=(REAL(sample[RS][i])*factortable[j]+offsettable[j])
*scalefactor[RS][i];
else fraction[RS][i]=0.0;
}
else
for(i=0;i<MAXSUBBAND;i++)
if((j=bitalloc[LS][i]))
fraction[LS][i]=(REAL(sample[LS][i])*factortable[j]+offsettable[j])
*scalefactor[LS][i];
else fraction[LS][i]=0.0;
subbandsynthesis(fraction[LS],fraction[RS]);
}
}

View file

@ -0,0 +1,766 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Mpeglayer2.cc
// It's for MPEG Layer 2
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(_WIN32) && defined(_MSC_VER)
// disable warnings about double to float conversions
#pragma warning(disable: 4244 4305)
#endif
#include "MPEGaudio.h"
#define MAXTABLE 2
// Tables for layer 2
static const int bitalloclengthtable[MAXTABLE][MAXSUBBAND]=
{{4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},
{4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3, 3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2}};
static const REAL group5bits[27*3]=
{
-2.0/3.0, -2.0/3.0, -2.0/3.0,
0.0, -2.0/3.0, -2.0/3.0,
2.0/3.0, -2.0/3.0, -2.0/3.0,
-2.0/3.0, 0.0, -2.0/3.0,
0.0, 0.0, -2.0/3.0,
2.0/3.0, 0.0, -2.0/3.0,
-2.0/3.0, 2.0/3.0, -2.0/3.0,
0.0, 2.0/3.0, -2.0/3.0,
2.0/3.0, 2.0/3.0, -2.0/3.0,
-2.0/3.0, -2.0/3.0, 0.0,
0.0, -2.0/3.0, 0.0,
2.0/3.0, -2.0/3.0, 0.0,
-2.0/3.0, 0.0, 0.0,
0.0, 0.0, 0.0,
2.0/3.0, 0.0, 0.0,
-2.0/3.0, 2.0/3.0, 0.0,
0.0, 2.0/3.0, 0.0,
2.0/3.0, 2.0/3.0, 0.0,
-2.0/3.0, -2.0/3.0, 2.0/3.0,
0.0, -2.0/3.0, 2.0/3.0,
2.0/3.0, -2.0/3.0, 2.0/3.0,
-2.0/3.0, 0.0, 2.0/3.0,
0.0, 0.0, 2.0/3.0,
2.0/3.0, 0.0, 2.0/3.0,
-2.0/3.0, 2.0/3.0, 2.0/3.0,
0.0, 2.0/3.0, 2.0/3.0,
2.0/3.0, 2.0/3.0, 2.0/3.0
};
static const REAL group7bits[125*3]=
{
-0.8,-0.8,-0.8, -0.4,-0.8,-0.8, 0.0,-0.8,-0.8, 0.4,-0.8,-0.8, 0.8,-0.8,-0.8,
-0.8,-0.4,-0.8, -0.4,-0.4,-0.8, 0.0,-0.4,-0.8, 0.4,-0.4,-0.8, 0.8,-0.4,-0.8,
-0.8, 0.0,-0.8, -0.4, 0.0,-0.8, 0.0, 0.0,-0.8, 0.4, 0.0,-0.8, 0.8, 0.0,-0.8,
-0.8, 0.4,-0.8, -0.4, 0.4,-0.8, 0.0, 0.4,-0.8, 0.4, 0.4,-0.8, 0.8, 0.4,-0.8,
-0.8, 0.8,-0.8, -0.4, 0.8,-0.8, 0.0, 0.8,-0.8, 0.4, 0.8,-0.8, 0.8, 0.8,-0.8,
-0.8,-0.8,-0.4, -0.4,-0.8,-0.4, 0.0,-0.8,-0.4, 0.4,-0.8,-0.4, 0.8,-0.8,-0.4,
-0.8,-0.4,-0.4, -0.4,-0.4,-0.4, 0.0,-0.4,-0.4, 0.4,-0.4,-0.4, 0.8,-0.4,-0.4,
-0.8, 0.0,-0.4, -0.4, 0.0,-0.4, 0.0, 0.0,-0.4, 0.4, 0.0,-0.4, 0.8, 0.0,-0.4,
-0.8, 0.4,-0.4, -0.4, 0.4,-0.4, 0.0, 0.4,-0.4, 0.4, 0.4,-0.4, 0.8, 0.4,-0.4,
-0.8, 0.8,-0.4, -0.4, 0.8,-0.4, 0.0, 0.8,-0.4, 0.4, 0.8,-0.4, 0.8, 0.8,-0.4,
-0.8,-0.8, 0.0, -0.4,-0.8, 0.0, 0.0,-0.8, 0.0, 0.4,-0.8, 0.0, 0.8,-0.8, 0.0,
-0.8,-0.4, 0.0, -0.4,-0.4, 0.0, 0.0,-0.4, 0.0, 0.4,-0.4, 0.0, 0.8,-0.4, 0.0,
-0.8, 0.0, 0.0, -0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.0, 0.0, 0.8, 0.0, 0.0,
-0.8, 0.4, 0.0, -0.4, 0.4, 0.0, 0.0, 0.4, 0.0, 0.4, 0.4, 0.0, 0.8, 0.4, 0.0,
-0.8, 0.8, 0.0, -0.4, 0.8, 0.0, 0.0, 0.8, 0.0, 0.4, 0.8, 0.0, 0.8, 0.8, 0.0,
-0.8,-0.8, 0.4, -0.4,-0.8, 0.4, 0.0,-0.8, 0.4, 0.4,-0.8, 0.4, 0.8,-0.8, 0.4,
-0.8,-0.4, 0.4, -0.4,-0.4, 0.4, 0.0,-0.4, 0.4, 0.4,-0.4, 0.4, 0.8,-0.4, 0.4,
-0.8, 0.0, 0.4, -0.4, 0.0, 0.4, 0.0, 0.0, 0.4, 0.4, 0.0, 0.4, 0.8, 0.0, 0.4,
-0.8, 0.4, 0.4, -0.4, 0.4, 0.4, 0.0, 0.4, 0.4, 0.4, 0.4, 0.4, 0.8, 0.4, 0.4,
-0.8, 0.8, 0.4, -0.4, 0.8, 0.4, 0.0, 0.8, 0.4, 0.4, 0.8, 0.4, 0.8, 0.8, 0.4,
-0.8,-0.8, 0.8, -0.4,-0.8, 0.8, 0.0,-0.8, 0.8, 0.4,-0.8, 0.8, 0.8,-0.8, 0.8,
-0.8,-0.4, 0.8, -0.4,-0.4, 0.8, 0.0,-0.4, 0.8, 0.4,-0.4, 0.8, 0.8,-0.4, 0.8,
-0.8, 0.0, 0.8, -0.4, 0.0, 0.8, 0.0, 0.0, 0.8, 0.4, 0.0, 0.8, 0.8, 0.0, 0.8,
-0.8, 0.4, 0.8, -0.4, 0.4, 0.8, 0.0, 0.4, 0.8, 0.4, 0.4, 0.8, 0.8, 0.4, 0.8,
-0.8, 0.8, 0.8, -0.4, 0.8, 0.8, 0.0, 0.8, 0.8, 0.4, 0.8, 0.8, 0.8, 0.8, 0.8
};
static const REAL group10bits[729*3]=
{
-8.0/9.0,-8.0/9.0,-8.0/9.0, -6.0/9.0,-8.0/9.0,-8.0/9.0, -4.0/9.0,-8.0/9.0,-8.0/9.0,
-2.0/9.0,-8.0/9.0,-8.0/9.0, 0.0,-8.0/9.0,-8.0/9.0, 2.0/9.0,-8.0/9.0,-8.0/9.0,
4.0/9.0,-8.0/9.0,-8.0/9.0, 6.0/9.0,-8.0/9.0,-8.0/9.0, 8.0/9.0,-8.0/9.0,-8.0/9.0,
-8.0/9.0,-6.0/9.0,-8.0/9.0, -6.0/9.0,-6.0/9.0,-8.0/9.0, -4.0/9.0,-6.0/9.0,-8.0/9.0,
-2.0/9.0,-6.0/9.0,-8.0/9.0, 0.0,-6.0/9.0,-8.0/9.0, 2.0/9.0,-6.0/9.0,-8.0/9.0,
4.0/9.0,-6.0/9.0,-8.0/9.0, 6.0/9.0,-6.0/9.0,-8.0/9.0, 8.0/9.0,-6.0/9.0,-8.0/9.0,
-8.0/9.0,-4.0/9.0,-8.0/9.0, -6.0/9.0,-4.0/9.0,-8.0/9.0, -4.0/9.0,-4.0/9.0,-8.0/9.0,
-2.0/9.0,-4.0/9.0,-8.0/9.0, 0.0,-4.0/9.0,-8.0/9.0, 2.0/9.0,-4.0/9.0,-8.0/9.0,
4.0/9.0,-4.0/9.0,-8.0/9.0, 6.0/9.0,-4.0/9.0,-8.0/9.0, 8.0/9.0,-4.0/9.0,-8.0/9.0,
-8.0/9.0,-2.0/9.0,-8.0/9.0, -6.0/9.0,-2.0/9.0,-8.0/9.0, -4.0/9.0,-2.0/9.0,-8.0/9.0,
-2.0/9.0,-2.0/9.0,-8.0/9.0, 0.0,-2.0/9.0,-8.0/9.0, 2.0/9.0,-2.0/9.0,-8.0/9.0,
4.0/9.0,-2.0/9.0,-8.0/9.0, 6.0/9.0,-2.0/9.0,-8.0/9.0, 8.0/9.0,-2.0/9.0,-8.0/9.0,
-8.0/9.0, 0.0,-8.0/9.0, -6.0/9.0, 0.0,-8.0/9.0, -4.0/9.0, 0.0,-8.0/9.0,
-2.0/9.0, 0.0,-8.0/9.0, 0.0, 0.0,-8.0/9.0, 2.0/9.0, 0.0,-8.0/9.0,
4.0/9.0, 0.0,-8.0/9.0, 6.0/9.0, 0.0,-8.0/9.0, 8.0/9.0, 0.0,-8.0/9.0,
-8.0/9.0, 2.0/9.0,-8.0/9.0, -6.0/9.0, 2.0/9.0,-8.0/9.0, -4.0/9.0, 2.0/9.0,-8.0/9.0,
-2.0/9.0, 2.0/9.0,-8.0/9.0, 0.0, 2.0/9.0,-8.0/9.0, 2.0/9.0, 2.0/9.0,-8.0/9.0,
4.0/9.0, 2.0/9.0,-8.0/9.0, 6.0/9.0, 2.0/9.0,-8.0/9.0, 8.0/9.0, 2.0/9.0,-8.0/9.0,
-8.0/9.0, 4.0/9.0,-8.0/9.0, -6.0/9.0, 4.0/9.0,-8.0/9.0, -4.0/9.0, 4.0/9.0,-8.0/9.0,
-2.0/9.0, 4.0/9.0,-8.0/9.0, 0.0, 4.0/9.0,-8.0/9.0, 2.0/9.0, 4.0/9.0,-8.0/9.0,
4.0/9.0, 4.0/9.0,-8.0/9.0, 6.0/9.0, 4.0/9.0,-8.0/9.0, 8.0/9.0, 4.0/9.0,-8.0/9.0,
-8.0/9.0, 6.0/9.0,-8.0/9.0, -6.0/9.0, 6.0/9.0,-8.0/9.0, -4.0/9.0, 6.0/9.0,-8.0/9.0,
-2.0/9.0, 6.0/9.0,-8.0/9.0, 0.0, 6.0/9.0,-8.0/9.0, 2.0/9.0, 6.0/9.0,-8.0/9.0,
4.0/9.0, 6.0/9.0,-8.0/9.0, 6.0/9.0, 6.0/9.0,-8.0/9.0, 8.0/9.0, 6.0/9.0,-8.0/9.0,
-8.0/9.0, 8.0/9.0,-8.0/9.0, -6.0/9.0, 8.0/9.0,-8.0/9.0, -4.0/9.0, 8.0/9.0,-8.0/9.0,
-2.0/9.0, 8.0/9.0,-8.0/9.0, 0.0, 8.0/9.0,-8.0/9.0, 2.0/9.0, 8.0/9.0,-8.0/9.0,
4.0/9.0, 8.0/9.0,-8.0/9.0, 6.0/9.0, 8.0/9.0,-8.0/9.0, 8.0/9.0, 8.0/9.0,-8.0/9.0,
-8.0/9.0,-8.0/9.0,-6.0/9.0, -6.0/9.0,-8.0/9.0,-6.0/9.0, -4.0/9.0,-8.0/9.0,-6.0/9.0,
-2.0/9.0,-8.0/9.0,-6.0/9.0, 0.0,-8.0/9.0,-6.0/9.0, 2.0/9.0,-8.0/9.0,-6.0/9.0,
4.0/9.0,-8.0/9.0,-6.0/9.0, 6.0/9.0,-8.0/9.0,-6.0/9.0, 8.0/9.0,-8.0/9.0,-6.0/9.0,
-8.0/9.0,-6.0/9.0,-6.0/9.0, -6.0/9.0,-6.0/9.0,-6.0/9.0, -4.0/9.0,-6.0/9.0,-6.0/9.0,
-2.0/9.0,-6.0/9.0,-6.0/9.0, 0.0,-6.0/9.0,-6.0/9.0, 2.0/9.0,-6.0/9.0,-6.0/9.0,
4.0/9.0,-6.0/9.0,-6.0/9.0, 6.0/9.0,-6.0/9.0,-6.0/9.0, 8.0/9.0,-6.0/9.0,-6.0/9.0,
-8.0/9.0,-4.0/9.0,-6.0/9.0, -6.0/9.0,-4.0/9.0,-6.0/9.0, -4.0/9.0,-4.0/9.0,-6.0/9.0,
-2.0/9.0,-4.0/9.0,-6.0/9.0, 0.0,-4.0/9.0,-6.0/9.0, 2.0/9.0,-4.0/9.0,-6.0/9.0,
4.0/9.0,-4.0/9.0,-6.0/9.0, 6.0/9.0,-4.0/9.0,-6.0/9.0, 8.0/9.0,-4.0/9.0,-6.0/9.0,
-8.0/9.0,-2.0/9.0,-6.0/9.0, -6.0/9.0,-2.0/9.0,-6.0/9.0, -4.0/9.0,-2.0/9.0,-6.0/9.0,
-2.0/9.0,-2.0/9.0,-6.0/9.0, 0.0,-2.0/9.0,-6.0/9.0, 2.0/9.0,-2.0/9.0,-6.0/9.0,
4.0/9.0,-2.0/9.0,-6.0/9.0, 6.0/9.0,-2.0/9.0,-6.0/9.0, 8.0/9.0,-2.0/9.0,-6.0/9.0,
-8.0/9.0, 0.0,-6.0/9.0, -6.0/9.0, 0.0,-6.0/9.0, -4.0/9.0, 0.0,-6.0/9.0,
-2.0/9.0, 0.0,-6.0/9.0, 0.0, 0.0,-6.0/9.0, 2.0/9.0, 0.0,-6.0/9.0,
4.0/9.0, 0.0,-6.0/9.0, 6.0/9.0, 0.0,-6.0/9.0, 8.0/9.0, 0.0,-6.0/9.0,
-8.0/9.0, 2.0/9.0,-6.0/9.0, -6.0/9.0, 2.0/9.0,-6.0/9.0, -4.0/9.0, 2.0/9.0,-6.0/9.0,
-2.0/9.0, 2.0/9.0,-6.0/9.0, 0.0, 2.0/9.0,-6.0/9.0, 2.0/9.0, 2.0/9.0,-6.0/9.0,
4.0/9.0, 2.0/9.0,-6.0/9.0, 6.0/9.0, 2.0/9.0,-6.0/9.0, 8.0/9.0, 2.0/9.0,-6.0/9.0,
-8.0/9.0, 4.0/9.0,-6.0/9.0, -6.0/9.0, 4.0/9.0,-6.0/9.0, -4.0/9.0, 4.0/9.0,-6.0/9.0,
-2.0/9.0, 4.0/9.0,-6.0/9.0, 0.0, 4.0/9.0,-6.0/9.0, 2.0/9.0, 4.0/9.0,-6.0/9.0,
4.0/9.0, 4.0/9.0,-6.0/9.0, 6.0/9.0, 4.0/9.0,-6.0/9.0, 8.0/9.0, 4.0/9.0,-6.0/9.0,
-8.0/9.0, 6.0/9.0,-6.0/9.0, -6.0/9.0, 6.0/9.0,-6.0/9.0, -4.0/9.0, 6.0/9.0,-6.0/9.0,
-2.0/9.0, 6.0/9.0,-6.0/9.0, 0.0, 6.0/9.0,-6.0/9.0, 2.0/9.0, 6.0/9.0,-6.0/9.0,
4.0/9.0, 6.0/9.0,-6.0/9.0, 6.0/9.0, 6.0/9.0,-6.0/9.0, 8.0/9.0, 6.0/9.0,-6.0/9.0,
-8.0/9.0, 8.0/9.0,-6.0/9.0, -6.0/9.0, 8.0/9.0,-6.0/9.0, -4.0/9.0, 8.0/9.0,-6.0/9.0,
-2.0/9.0, 8.0/9.0,-6.0/9.0, 0.0, 8.0/9.0,-6.0/9.0, 2.0/9.0, 8.0/9.0,-6.0/9.0,
4.0/9.0, 8.0/9.0,-6.0/9.0, 6.0/9.0, 8.0/9.0,-6.0/9.0, 8.0/9.0, 8.0/9.0,-6.0/9.0,
-8.0/9.0,-8.0/9.0,-4.0/9.0, -6.0/9.0,-8.0/9.0,-4.0/9.0, -4.0/9.0,-8.0/9.0,-4.0/9.0,
-2.0/9.0,-8.0/9.0,-4.0/9.0, 0.0,-8.0/9.0,-4.0/9.0, 2.0/9.0,-8.0/9.0,-4.0/9.0,
4.0/9.0,-8.0/9.0,-4.0/9.0, 6.0/9.0,-8.0/9.0,-4.0/9.0, 8.0/9.0,-8.0/9.0,-4.0/9.0,
-8.0/9.0,-6.0/9.0,-4.0/9.0, -6.0/9.0,-6.0/9.0,-4.0/9.0, -4.0/9.0,-6.0/9.0,-4.0/9.0,
-2.0/9.0,-6.0/9.0,-4.0/9.0, 0.0,-6.0/9.0,-4.0/9.0, 2.0/9.0,-6.0/9.0,-4.0/9.0,
4.0/9.0,-6.0/9.0,-4.0/9.0, 6.0/9.0,-6.0/9.0,-4.0/9.0, 8.0/9.0,-6.0/9.0,-4.0/9.0,
-8.0/9.0,-4.0/9.0,-4.0/9.0, -6.0/9.0,-4.0/9.0,-4.0/9.0, -4.0/9.0,-4.0/9.0,-4.0/9.0,
-2.0/9.0,-4.0/9.0,-4.0/9.0, 0.0,-4.0/9.0,-4.0/9.0, 2.0/9.0,-4.0/9.0,-4.0/9.0,
4.0/9.0,-4.0/9.0,-4.0/9.0, 6.0/9.0,-4.0/9.0,-4.0/9.0, 8.0/9.0,-4.0/9.0,-4.0/9.0,
-8.0/9.0,-2.0/9.0,-4.0/9.0, -6.0/9.0,-2.0/9.0,-4.0/9.0, -4.0/9.0,-2.0/9.0,-4.0/9.0,
-2.0/9.0,-2.0/9.0,-4.0/9.0, 0.0,-2.0/9.0,-4.0/9.0, 2.0/9.0,-2.0/9.0,-4.0/9.0,
4.0/9.0,-2.0/9.0,-4.0/9.0, 6.0/9.0,-2.0/9.0,-4.0/9.0, 8.0/9.0,-2.0/9.0,-4.0/9.0,
-8.0/9.0, 0.0,-4.0/9.0, -6.0/9.0, 0.0,-4.0/9.0, -4.0/9.0, 0.0,-4.0/9.0,
-2.0/9.0, 0.0,-4.0/9.0, 0.0, 0.0,-4.0/9.0, 2.0/9.0, 0.0,-4.0/9.0,
4.0/9.0, 0.0,-4.0/9.0, 6.0/9.0, 0.0,-4.0/9.0, 8.0/9.0, 0.0,-4.0/9.0,
-8.0/9.0, 2.0/9.0,-4.0/9.0, -6.0/9.0, 2.0/9.0,-4.0/9.0, -4.0/9.0, 2.0/9.0,-4.0/9.0,
-2.0/9.0, 2.0/9.0,-4.0/9.0, 0.0, 2.0/9.0,-4.0/9.0, 2.0/9.0, 2.0/9.0,-4.0/9.0,
4.0/9.0, 2.0/9.0,-4.0/9.0, 6.0/9.0, 2.0/9.0,-4.0/9.0, 8.0/9.0, 2.0/9.0,-4.0/9.0,
-8.0/9.0, 4.0/9.0,-4.0/9.0, -6.0/9.0, 4.0/9.0,-4.0/9.0, -4.0/9.0, 4.0/9.0,-4.0/9.0,
-2.0/9.0, 4.0/9.0,-4.0/9.0, 0.0, 4.0/9.0,-4.0/9.0, 2.0/9.0, 4.0/9.0,-4.0/9.0,
4.0/9.0, 4.0/9.0,-4.0/9.0, 6.0/9.0, 4.0/9.0,-4.0/9.0, 8.0/9.0, 4.0/9.0,-4.0/9.0,
-8.0/9.0, 6.0/9.0,-4.0/9.0, -6.0/9.0, 6.0/9.0,-4.0/9.0, -4.0/9.0, 6.0/9.0,-4.0/9.0,
-2.0/9.0, 6.0/9.0,-4.0/9.0, 0.0, 6.0/9.0,-4.0/9.0, 2.0/9.0, 6.0/9.0,-4.0/9.0,
4.0/9.0, 6.0/9.0,-4.0/9.0, 6.0/9.0, 6.0/9.0,-4.0/9.0, 8.0/9.0, 6.0/9.0,-4.0/9.0,
-8.0/9.0, 8.0/9.0,-4.0/9.0, -6.0/9.0, 8.0/9.0,-4.0/9.0, -4.0/9.0, 8.0/9.0,-4.0/9.0,
-2.0/9.0, 8.0/9.0,-4.0/9.0, 0.0, 8.0/9.0,-4.0/9.0, 2.0/9.0, 8.0/9.0,-4.0/9.0,
4.0/9.0, 8.0/9.0,-4.0/9.0, 6.0/9.0, 8.0/9.0,-4.0/9.0, 8.0/9.0, 8.0/9.0,-4.0/9.0,
-8.0/9.0,-8.0/9.0,-2.0/9.0, -6.0/9.0,-8.0/9.0,-2.0/9.0, -4.0/9.0,-8.0/9.0,-2.0/9.0,
-2.0/9.0,-8.0/9.0,-2.0/9.0, 0.0,-8.0/9.0,-2.0/9.0, 2.0/9.0,-8.0/9.0,-2.0/9.0,
4.0/9.0,-8.0/9.0,-2.0/9.0, 6.0/9.0,-8.0/9.0,-2.0/9.0, 8.0/9.0,-8.0/9.0,-2.0/9.0,
-8.0/9.0,-6.0/9.0,-2.0/9.0, -6.0/9.0,-6.0/9.0,-2.0/9.0, -4.0/9.0,-6.0/9.0,-2.0/9.0,
-2.0/9.0,-6.0/9.0,-2.0/9.0, 0.0,-6.0/9.0,-2.0/9.0, 2.0/9.0,-6.0/9.0,-2.0/9.0,
4.0/9.0,-6.0/9.0,-2.0/9.0, 6.0/9.0,-6.0/9.0,-2.0/9.0, 8.0/9.0,-6.0/9.0,-2.0/9.0,
-8.0/9.0,-4.0/9.0,-2.0/9.0, -6.0/9.0,-4.0/9.0,-2.0/9.0, -4.0/9.0,-4.0/9.0,-2.0/9.0,
-2.0/9.0,-4.0/9.0,-2.0/9.0, 0.0,-4.0/9.0,-2.0/9.0, 2.0/9.0,-4.0/9.0,-2.0/9.0,
4.0/9.0,-4.0/9.0,-2.0/9.0, 6.0/9.0,-4.0/9.0,-2.0/9.0, 8.0/9.0,-4.0/9.0,-2.0/9.0,
-8.0/9.0,-2.0/9.0,-2.0/9.0, -6.0/9.0,-2.0/9.0,-2.0/9.0, -4.0/9.0,-2.0/9.0,-2.0/9.0,
-2.0/9.0,-2.0/9.0,-2.0/9.0, 0.0,-2.0/9.0,-2.0/9.0, 2.0/9.0,-2.0/9.0,-2.0/9.0,
4.0/9.0,-2.0/9.0,-2.0/9.0, 6.0/9.0,-2.0/9.0,-2.0/9.0, 8.0/9.0,-2.0/9.0,-2.0/9.0,
-8.0/9.0, 0.0,-2.0/9.0, -6.0/9.0, 0.0,-2.0/9.0, -4.0/9.0, 0.0,-2.0/9.0,
-2.0/9.0, 0.0,-2.0/9.0, 0.0, 0.0,-2.0/9.0, 2.0/9.0, 0.0,-2.0/9.0,
4.0/9.0, 0.0,-2.0/9.0, 6.0/9.0, 0.0,-2.0/9.0, 8.0/9.0, 0.0,-2.0/9.0,
-8.0/9.0, 2.0/9.0,-2.0/9.0, -6.0/9.0, 2.0/9.0,-2.0/9.0, -4.0/9.0, 2.0/9.0,-2.0/9.0,
-2.0/9.0, 2.0/9.0,-2.0/9.0, 0.0, 2.0/9.0,-2.0/9.0, 2.0/9.0, 2.0/9.0,-2.0/9.0,
4.0/9.0, 2.0/9.0,-2.0/9.0, 6.0/9.0, 2.0/9.0,-2.0/9.0, 8.0/9.0, 2.0/9.0,-2.0/9.0,
-8.0/9.0, 4.0/9.0,-2.0/9.0, -6.0/9.0, 4.0/9.0,-2.0/9.0, -4.0/9.0, 4.0/9.0,-2.0/9.0,
-2.0/9.0, 4.0/9.0,-2.0/9.0, 0.0, 4.0/9.0,-2.0/9.0, 2.0/9.0, 4.0/9.0,-2.0/9.0,
4.0/9.0, 4.0/9.0,-2.0/9.0, 6.0/9.0, 4.0/9.0,-2.0/9.0, 8.0/9.0, 4.0/9.0,-2.0/9.0,
-8.0/9.0, 6.0/9.0,-2.0/9.0, -6.0/9.0, 6.0/9.0,-2.0/9.0, -4.0/9.0, 6.0/9.0,-2.0/9.0,
-2.0/9.0, 6.0/9.0,-2.0/9.0, 0.0, 6.0/9.0,-2.0/9.0, 2.0/9.0, 6.0/9.0,-2.0/9.0,
4.0/9.0, 6.0/9.0,-2.0/9.0, 6.0/9.0, 6.0/9.0,-2.0/9.0, 8.0/9.0, 6.0/9.0,-2.0/9.0,
-8.0/9.0, 8.0/9.0,-2.0/9.0, -6.0/9.0, 8.0/9.0,-2.0/9.0, -4.0/9.0, 8.0/9.0,-2.0/9.0,
-2.0/9.0, 8.0/9.0,-2.0/9.0, 0.0, 8.0/9.0,-2.0/9.0, 2.0/9.0, 8.0/9.0,-2.0/9.0,
4.0/9.0, 8.0/9.0,-2.0/9.0, 6.0/9.0, 8.0/9.0,-2.0/9.0, 8.0/9.0, 8.0/9.0,-2.0/9.0,
-8.0/9.0,-8.0/9.0, 0.0, -6.0/9.0,-8.0/9.0, 0.0, -4.0/9.0,-8.0/9.0, 0.0,
-2.0/9.0,-8.0/9.0, 0.0, 0.0,-8.0/9.0, 0.0, 2.0/9.0,-8.0/9.0, 0.0,
4.0/9.0,-8.0/9.0, 0.0, 6.0/9.0,-8.0/9.0, 0.0, 8.0/9.0,-8.0/9.0, 0.0,
-8.0/9.0,-6.0/9.0, 0.0, -6.0/9.0,-6.0/9.0, 0.0, -4.0/9.0,-6.0/9.0, 0.0,
-2.0/9.0,-6.0/9.0, 0.0, 0.0,-6.0/9.0, 0.0, 2.0/9.0,-6.0/9.0, 0.0,
4.0/9.0,-6.0/9.0, 0.0, 6.0/9.0,-6.0/9.0, 0.0, 8.0/9.0,-6.0/9.0, 0.0,
-8.0/9.0,-4.0/9.0, 0.0, -6.0/9.0,-4.0/9.0, 0.0, -4.0/9.0,-4.0/9.0, 0.0,
-2.0/9.0,-4.0/9.0, 0.0, 0.0,-4.0/9.0, 0.0, 2.0/9.0,-4.0/9.0, 0.0,
4.0/9.0,-4.0/9.0, 0.0, 6.0/9.0,-4.0/9.0, 0.0, 8.0/9.0,-4.0/9.0, 0.0,
-8.0/9.0,-2.0/9.0, 0.0, -6.0/9.0,-2.0/9.0, 0.0, -4.0/9.0,-2.0/9.0, 0.0,
-2.0/9.0,-2.0/9.0, 0.0, 0.0,-2.0/9.0, 0.0, 2.0/9.0,-2.0/9.0, 0.0,
4.0/9.0,-2.0/9.0, 0.0, 6.0/9.0,-2.0/9.0, 0.0, 8.0/9.0,-2.0/9.0, 0.0,
-8.0/9.0, 0.0, 0.0, -6.0/9.0, 0.0, 0.0, -4.0/9.0, 0.0, 0.0,
-2.0/9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0/9.0, 0.0, 0.0,
4.0/9.0, 0.0, 0.0, 6.0/9.0, 0.0, 0.0, 8.0/9.0, 0.0, 0.0,
-8.0/9.0, 2.0/9.0, 0.0, -6.0/9.0, 2.0/9.0, 0.0, -4.0/9.0, 2.0/9.0, 0.0,
-2.0/9.0, 2.0/9.0, 0.0, 0.0, 2.0/9.0, 0.0, 2.0/9.0, 2.0/9.0, 0.0,
4.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 2.0/9.0, 0.0,
-8.0/9.0, 4.0/9.0, 0.0, -6.0/9.0, 4.0/9.0, 0.0, -4.0/9.0, 4.0/9.0, 0.0,
-2.0/9.0, 4.0/9.0, 0.0, 0.0, 4.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 0.0,
4.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 0.0,
-8.0/9.0, 6.0/9.0, 0.0, -6.0/9.0, 6.0/9.0, 0.0, -4.0/9.0, 6.0/9.0, 0.0,
-2.0/9.0, 6.0/9.0, 0.0, 0.0, 6.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 0.0,
4.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 0.0,
-8.0/9.0, 8.0/9.0, 0.0, -6.0/9.0, 8.0/9.0, 0.0, -4.0/9.0, 8.0/9.0, 0.0,
-2.0/9.0, 8.0/9.0, 0.0, 0.0, 8.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 0.0,
4.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 0.0,
-8.0/9.0,-8.0/9.0, 2.0/9.0, -6.0/9.0,-8.0/9.0, 2.0/9.0, -4.0/9.0,-8.0/9.0, 2.0/9.0,
-2.0/9.0,-8.0/9.0, 2.0/9.0, 0.0,-8.0/9.0, 2.0/9.0, 2.0/9.0,-8.0/9.0, 2.0/9.0,
4.0/9.0,-8.0/9.0, 2.0/9.0, 6.0/9.0,-8.0/9.0, 2.0/9.0, 8.0/9.0,-8.0/9.0, 2.0/9.0,
-8.0/9.0,-6.0/9.0, 2.0/9.0, -6.0/9.0,-6.0/9.0, 2.0/9.0, -4.0/9.0,-6.0/9.0, 2.0/9.0,
-2.0/9.0,-6.0/9.0, 2.0/9.0, 0.0,-6.0/9.0, 2.0/9.0, 2.0/9.0,-6.0/9.0, 2.0/9.0,
4.0/9.0,-6.0/9.0, 2.0/9.0, 6.0/9.0,-6.0/9.0, 2.0/9.0, 8.0/9.0,-6.0/9.0, 2.0/9.0,
-8.0/9.0,-4.0/9.0, 2.0/9.0, -6.0/9.0,-4.0/9.0, 2.0/9.0, -4.0/9.0,-4.0/9.0, 2.0/9.0,
-2.0/9.0,-4.0/9.0, 2.0/9.0, 0.0,-4.0/9.0, 2.0/9.0, 2.0/9.0,-4.0/9.0, 2.0/9.0,
4.0/9.0,-4.0/9.0, 2.0/9.0, 6.0/9.0,-4.0/9.0, 2.0/9.0, 8.0/9.0,-4.0/9.0, 2.0/9.0,
-8.0/9.0,-2.0/9.0, 2.0/9.0, -6.0/9.0,-2.0/9.0, 2.0/9.0, -4.0/9.0,-2.0/9.0, 2.0/9.0,
-2.0/9.0,-2.0/9.0, 2.0/9.0, 0.0,-2.0/9.0, 2.0/9.0, 2.0/9.0,-2.0/9.0, 2.0/9.0,
4.0/9.0,-2.0/9.0, 2.0/9.0, 6.0/9.0,-2.0/9.0, 2.0/9.0, 8.0/9.0,-2.0/9.0, 2.0/9.0,
-8.0/9.0, 0.0, 2.0/9.0, -6.0/9.0, 0.0, 2.0/9.0, -4.0/9.0, 0.0, 2.0/9.0,
-2.0/9.0, 0.0, 2.0/9.0, 0.0, 0.0, 2.0/9.0, 2.0/9.0, 0.0, 2.0/9.0,
4.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 0.0, 2.0/9.0,
-8.0/9.0, 2.0/9.0, 2.0/9.0, -6.0/9.0, 2.0/9.0, 2.0/9.0, -4.0/9.0, 2.0/9.0, 2.0/9.0,
-2.0/9.0, 2.0/9.0, 2.0/9.0, 0.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 2.0/9.0,
4.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 2.0/9.0,
-8.0/9.0, 4.0/9.0, 2.0/9.0, -6.0/9.0, 4.0/9.0, 2.0/9.0, -4.0/9.0, 4.0/9.0, 2.0/9.0,
-2.0/9.0, 4.0/9.0, 2.0/9.0, 0.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0, 2.0/9.0,
4.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0, 2.0/9.0,
-8.0/9.0, 6.0/9.0, 2.0/9.0, -6.0/9.0, 6.0/9.0, 2.0/9.0, -4.0/9.0, 6.0/9.0, 2.0/9.0,
-2.0/9.0, 6.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 2.0/9.0,
4.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 2.0/9.0,
-8.0/9.0, 8.0/9.0, 2.0/9.0, -6.0/9.0, 8.0/9.0, 2.0/9.0, -4.0/9.0, 8.0/9.0, 2.0/9.0,
-2.0/9.0, 8.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 2.0/9.0,
4.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 2.0/9.0,
-8.0/9.0,-8.0/9.0, 4.0/9.0, -6.0/9.0,-8.0/9.0, 4.0/9.0, -4.0/9.0,-8.0/9.0, 4.0/9.0,
-2.0/9.0,-8.0/9.0, 4.0/9.0, 0.0,-8.0/9.0, 4.0/9.0, 2.0/9.0,-8.0/9.0, 4.0/9.0,
4.0/9.0,-8.0/9.0, 4.0/9.0, 6.0/9.0,-8.0/9.0, 4.0/9.0, 8.0/9.0,-8.0/9.0, 4.0/9.0,
-8.0/9.0,-6.0/9.0, 4.0/9.0, -6.0/9.0,-6.0/9.0, 4.0/9.0, -4.0/9.0,-6.0/9.0, 4.0/9.0,
-2.0/9.0,-6.0/9.0, 4.0/9.0, 0.0,-6.0/9.0, 4.0/9.0, 2.0/9.0,-6.0/9.0, 4.0/9.0,
4.0/9.0,-6.0/9.0, 4.0/9.0, 6.0/9.0,-6.0/9.0, 4.0/9.0, 8.0/9.0,-6.0/9.0, 4.0/9.0,
-8.0/9.0,-4.0/9.0, 4.0/9.0, -6.0/9.0,-4.0/9.0, 4.0/9.0, -4.0/9.0,-4.0/9.0, 4.0/9.0,
-2.0/9.0,-4.0/9.0, 4.0/9.0, 0.0,-4.0/9.0, 4.0/9.0, 2.0/9.0,-4.0/9.0, 4.0/9.0,
4.0/9.0,-4.0/9.0, 4.0/9.0, 6.0/9.0,-4.0/9.0, 4.0/9.0, 8.0/9.0,-4.0/9.0, 4.0/9.0,
-8.0/9.0,-2.0/9.0, 4.0/9.0, -6.0/9.0,-2.0/9.0, 4.0/9.0, -4.0/9.0,-2.0/9.0, 4.0/9.0,
-2.0/9.0,-2.0/9.0, 4.0/9.0, 0.0,-2.0/9.0, 4.0/9.0, 2.0/9.0,-2.0/9.0, 4.0/9.0,
4.0/9.0,-2.0/9.0, 4.0/9.0, 6.0/9.0,-2.0/9.0, 4.0/9.0, 8.0/9.0,-2.0/9.0, 4.0/9.0,
-8.0/9.0, 0.0, 4.0/9.0, -6.0/9.0, 0.0, 4.0/9.0, -4.0/9.0, 0.0, 4.0/9.0,
-2.0/9.0, 0.0, 4.0/9.0, 0.0, 0.0, 4.0/9.0, 2.0/9.0, 0.0, 4.0/9.0,
4.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 0.0, 4.0/9.0,
-8.0/9.0, 2.0/9.0, 4.0/9.0, -6.0/9.0, 2.0/9.0, 4.0/9.0, -4.0/9.0, 2.0/9.0, 4.0/9.0,
-2.0/9.0, 2.0/9.0, 4.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0,
4.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0,
-8.0/9.0, 4.0/9.0, 4.0/9.0, -6.0/9.0, 4.0/9.0, 4.0/9.0, -4.0/9.0, 4.0/9.0, 4.0/9.0,
-2.0/9.0, 4.0/9.0, 4.0/9.0, 0.0, 4.0/9.0, 4.0/9.0, 2.0/9.0, 4.0/9.0, 4.0/9.0,
4.0/9.0, 4.0/9.0, 4.0/9.0, 6.0/9.0, 4.0/9.0, 4.0/9.0, 8.0/9.0, 4.0/9.0, 4.0/9.0,
-8.0/9.0, 6.0/9.0, 4.0/9.0, -6.0/9.0, 6.0/9.0, 4.0/9.0, -4.0/9.0, 6.0/9.0, 4.0/9.0,
-2.0/9.0, 6.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0,
4.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0,
-8.0/9.0, 8.0/9.0, 4.0/9.0, -6.0/9.0, 8.0/9.0, 4.0/9.0, -4.0/9.0, 8.0/9.0, 4.0/9.0,
-2.0/9.0, 8.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0,
4.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0,
-8.0/9.0,-8.0/9.0, 6.0/9.0, -6.0/9.0,-8.0/9.0, 6.0/9.0, -4.0/9.0,-8.0/9.0, 6.0/9.0,
-2.0/9.0,-8.0/9.0, 6.0/9.0, 0.0,-8.0/9.0, 6.0/9.0, 2.0/9.0,-8.0/9.0, 6.0/9.0,
4.0/9.0,-8.0/9.0, 6.0/9.0, 6.0/9.0,-8.0/9.0, 6.0/9.0, 8.0/9.0,-8.0/9.0, 6.0/9.0,
-8.0/9.0,-6.0/9.0, 6.0/9.0, -6.0/9.0,-6.0/9.0, 6.0/9.0, -4.0/9.0,-6.0/9.0, 6.0/9.0,
-2.0/9.0,-6.0/9.0, 6.0/9.0, 0.0,-6.0/9.0, 6.0/9.0, 2.0/9.0,-6.0/9.0, 6.0/9.0,
4.0/9.0,-6.0/9.0, 6.0/9.0, 6.0/9.0,-6.0/9.0, 6.0/9.0, 8.0/9.0,-6.0/9.0, 6.0/9.0,
-8.0/9.0,-4.0/9.0, 6.0/9.0, -6.0/9.0,-4.0/9.0, 6.0/9.0, -4.0/9.0,-4.0/9.0, 6.0/9.0,
-2.0/9.0,-4.0/9.0, 6.0/9.0, 0.0,-4.0/9.0, 6.0/9.0, 2.0/9.0,-4.0/9.0, 6.0/9.0,
4.0/9.0,-4.0/9.0, 6.0/9.0, 6.0/9.0,-4.0/9.0, 6.0/9.0, 8.0/9.0,-4.0/9.0, 6.0/9.0,
-8.0/9.0,-2.0/9.0, 6.0/9.0, -6.0/9.0,-2.0/9.0, 6.0/9.0, -4.0/9.0,-2.0/9.0, 6.0/9.0,
-2.0/9.0,-2.0/9.0, 6.0/9.0, 0.0,-2.0/9.0, 6.0/9.0, 2.0/9.0,-2.0/9.0, 6.0/9.0,
4.0/9.0,-2.0/9.0, 6.0/9.0, 6.0/9.0,-2.0/9.0, 6.0/9.0, 8.0/9.0,-2.0/9.0, 6.0/9.0,
-8.0/9.0, 0.0, 6.0/9.0, -6.0/9.0, 0.0, 6.0/9.0, -4.0/9.0, 0.0, 6.0/9.0,
-2.0/9.0, 0.0, 6.0/9.0, 0.0, 0.0, 6.0/9.0, 2.0/9.0, 0.0, 6.0/9.0,
4.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 0.0, 6.0/9.0,
-8.0/9.0, 2.0/9.0, 6.0/9.0, -6.0/9.0, 2.0/9.0, 6.0/9.0, -4.0/9.0, 2.0/9.0, 6.0/9.0,
-2.0/9.0, 2.0/9.0, 6.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0,
4.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0,
-8.0/9.0, 4.0/9.0, 6.0/9.0, -6.0/9.0, 4.0/9.0, 6.0/9.0, -4.0/9.0, 4.0/9.0, 6.0/9.0,
-2.0/9.0, 4.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0,
4.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0,
-8.0/9.0, 6.0/9.0, 6.0/9.0, -6.0/9.0, 6.0/9.0, 6.0/9.0, -4.0/9.0, 6.0/9.0, 6.0/9.0,
-2.0/9.0, 6.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0,
4.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0,
-8.0/9.0, 8.0/9.0, 6.0/9.0, -6.0/9.0, 8.0/9.0, 6.0/9.0, -4.0/9.0, 8.0/9.0, 6.0/9.0,
-2.0/9.0, 8.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0,
4.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0,
-8.0/9.0,-8.0/9.0, 8.0/9.0, -6.0/9.0,-8.0/9.0, 8.0/9.0, -4.0/9.0,-8.0/9.0, 8.0/9.0,
-2.0/9.0,-8.0/9.0, 8.0/9.0, 0.0,-8.0/9.0, 8.0/9.0, 2.0/9.0,-8.0/9.0, 8.0/9.0,
4.0/9.0,-8.0/9.0, 8.0/9.0, 6.0/9.0,-8.0/9.0, 8.0/9.0, 8.0/9.0,-8.0/9.0, 8.0/9.0,
-8.0/9.0,-6.0/9.0, 8.0/9.0, -6.0/9.0,-6.0/9.0, 8.0/9.0, -4.0/9.0,-6.0/9.0, 8.0/9.0,
-2.0/9.0,-6.0/9.0, 8.0/9.0, 0.0,-6.0/9.0, 8.0/9.0, 2.0/9.0,-6.0/9.0, 8.0/9.0,
4.0/9.0,-6.0/9.0, 8.0/9.0, 6.0/9.0,-6.0/9.0, 8.0/9.0, 8.0/9.0,-6.0/9.0, 8.0/9.0,
-8.0/9.0,-4.0/9.0, 8.0/9.0, -6.0/9.0,-4.0/9.0, 8.0/9.0, -4.0/9.0,-4.0/9.0, 8.0/9.0,
-2.0/9.0,-4.0/9.0, 8.0/9.0, 0.0,-4.0/9.0, 8.0/9.0, 2.0/9.0,-4.0/9.0, 8.0/9.0,
4.0/9.0,-4.0/9.0, 8.0/9.0, 6.0/9.0,-4.0/9.0, 8.0/9.0, 8.0/9.0,-4.0/9.0, 8.0/9.0,
-8.0/9.0,-2.0/9.0, 8.0/9.0, -6.0/9.0,-2.0/9.0, 8.0/9.0, -4.0/9.0,-2.0/9.0, 8.0/9.0,
-2.0/9.0,-2.0/9.0, 8.0/9.0, 0.0,-2.0/9.0, 8.0/9.0, 2.0/9.0,-2.0/9.0, 8.0/9.0,
4.0/9.0,-2.0/9.0, 8.0/9.0, 6.0/9.0,-2.0/9.0, 8.0/9.0, 8.0/9.0,-2.0/9.0, 8.0/9.0,
-8.0/9.0, 0.0, 8.0/9.0, -6.0/9.0, 0.0, 8.0/9.0, -4.0/9.0, 0.0, 8.0/9.0,
-2.0/9.0, 0.0, 8.0/9.0, 0.0, 0.0, 8.0/9.0, 2.0/9.0, 0.0, 8.0/9.0,
4.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 0.0, 8.0/9.0,
-8.0/9.0, 2.0/9.0, 8.0/9.0, -6.0/9.0, 2.0/9.0, 8.0/9.0, -4.0/9.0, 2.0/9.0, 8.0/9.0,
-2.0/9.0, 2.0/9.0, 8.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0,
4.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0,
-8.0/9.0, 4.0/9.0, 8.0/9.0, -6.0/9.0, 4.0/9.0, 8.0/9.0, -4.0/9.0, 4.0/9.0, 8.0/9.0,
-2.0/9.0, 4.0/9.0, 8.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0,
4.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0,
-8.0/9.0, 6.0/9.0, 8.0/9.0, -6.0/9.0, 6.0/9.0, 8.0/9.0, -4.0/9.0, 6.0/9.0, 8.0/9.0,
-2.0/9.0, 6.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0,
4.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0,
-8.0/9.0, 8.0/9.0, 8.0/9.0, -6.0/9.0, 8.0/9.0, 8.0/9.0, -4.0/9.0, 8.0/9.0, 8.0/9.0,
-2.0/9.0, 8.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0,
4.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0
};
static const REAL *grouptableA[16] =
{ 0,group5bits,group7bits,group10bits,0,0,0,0,0,0,0,0,0,0,0,0};
static const REAL *grouptableB1[16] =
{ 0,group5bits,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
static const REAL *grouptableB234[16] =
{ 0,group5bits,group7bits,0,group10bits,0,0,0,0,0,0,0,0,0,0,0};
static const int codelengthtableA[16] =
{ 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
static const int codelengthtableB1[16] =
{ 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
static const int codelengthtableB2[16] =
{ 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 };
static const int codelengthtableB3[8] = { 0, 5, 7, 3, 10, 4, 5, 16 };
static const int codelengthtableB4[4] = { 0, 5, 7, 16 };
static const REAL factortableA[16] =
{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/8.0,
1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0,
1.0/128.0, 1.0/256.0, 1.0/512.0, 1.0/1024.0,
1.0/2048.0, 1.0/4096.0, 1.0/8192.0, 1.0/16384.0 };
static const REAL factortableB1[16] =
{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/8.0,
1.0/16.0, 1.0/32.0, 1.0/64.0, 1.0/128.0,
1.0/256.0, 1.0/512.0, 1.0/1024.0, 1.0/2048.0,
1.0/4096.0, 1.0/8192.0, 1.0/16384.0, 1.0/32768.0 };
static const REAL factortableB2[16] =
{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/4.0,
1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32.0,
1.0/64.0, 1.0/128.0, 1.0/256.0, 1.0/512.0,
1.0/1024.0, 1.0/2048.0, 1.0/4096.0, 1.0/32768.0 };
static const REAL factortableB3[8] =
{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/4.0, 1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32768.0 };
static const REAL factortableB4[4] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/32768.0 };
static const REAL ctableA[16]=
{ 0.0, 1.33333333333, 1.60000000000, 1.77777777777,
1.06666666666, 1.03225806452, 1.01587301587, 1.00787401575,
1.00392156863, 1.00195694716, 1.00097751711, 1.00048851979,
1.00024420024, 1.00012208522, 1.00006103888, 1.00003051851};
static const REAL ctableB1[16]=
{ 0.0, 1.33333333333, 1.14285714286, 1.06666666666,
1.03225806452, 1.01587301587, 1.00787401575, 1.00392156863,
1.00195694716, 1.00097751711, 1.00048851979, 1.00024420024,
1.00012208522, 1.00006103888, 1.00003051851, 1.00001525902};
static const REAL ctableB2[16] =
{ 0.0, 1.33333333333, 1.60000000000, 1.14285714286,
1.77777777777, 1.06666666666, 1.03225806452, 1.01587301587,
1.00787401575, 1.00392156863, 1.00195694716, 1.00097751711,
1.00048851979, 1.00024420024, 1.00012208522, 1.00001525902};
static const REAL ctableB3[8] =
{ 0.0, 1.33333333333, 1.60000000000, 1.14285714286,
1.77777777777, 1.06666666666, 1.03225806452, 1.00001525902 };
static const REAL ctableB4[4] =
{ 0.0, 1.33333333333, 1.60000000000, 1.00001525902 };
static const REAL dtableA[16]=
{ 0.0, 0.50000000000, 0.50000000000, 0.50000000000,
0.12500000000, 0.06250000000, 0.03125000000, 0.01562500000,
0.00781250000, 0.00390625000, 0.00195312500, 0.00097656250,
0.00048828125, 0.00024414063, 0.00012207031, 0.00006103516};
static const REAL dtableB1[16]=
{ 0.0, 0.50000000000, 0.25000000000, 0.12500000000,
0.06250000000, 0.03125000000, 0.01562500000, 0.00781250000,
0.00390625000, 0.00195312500, 0.00097656250, 0.00048828125,
0.00024414063, 0.00012207031, 0.00006103516, 0.00003051758};
static const REAL dtableB2[16]=
{ 0.0, 0.50000000000, 0.50000000000, 0.25000000000,
0.50000000000, 0.12500000000, 0.06250000000, 0.03125000000,
0.01562500000, 0.00781250000, 0.00390625000, 0.00195312500,
0.00097656250, 0.00048828125, 0.00024414063, 0.00003051758};
static const REAL dtableB3[8]=
{ 0.0, 0.50000000000, 0.50000000000, 0.25000000000,
0.50000000000, 0.12500000000, 0.06250000000, 0.00003051758};
static const REAL dtableB4[4]=
{0.0, 0.50000000000, 0.50000000000, 0.00003051758};
// Mpeg layer 2
void MPEGaudio::extractlayer2(void)
{
REAL fraction[MAXCHANNEL][3][MAXSUBBAND];
unsigned int bitalloc[MAXCHANNEL][MAXSUBBAND],
scaleselector[MAXCHANNEL][MAXSUBBAND];
REAL scalefactor[2][3][MAXSUBBAND];
const REAL *group[MAXCHANNEL][MAXSUBBAND];
unsigned int codelength[MAXCHANNEL][MAXSUBBAND];
REAL factor[MAXCHANNEL][MAXSUBBAND];
REAL c[MAXCHANNEL][MAXSUBBAND],d[MAXCHANNEL][MAXSUBBAND];
int s=stereobound,n=subbandnumber;
// Bitalloc
{
register int i;
register const int *t=bitalloclengthtable[tableindex];
for(i=0;i<s;i++,t++)
{
bitalloc[LS][i]=getbits(*t);
bitalloc[RS][i]=getbits(*t);
}
for(;i<n;i++,t++)
bitalloc[LS][i]=bitalloc[RS][i]=getbits(*t);
}
// Scale selector
if(inputstereo)
for(register int i=0;i<n;i++)
{
if(bitalloc[LS][i])scaleselector[LS][i]=getbits(2);
if(bitalloc[RS][i])scaleselector[RS][i]=getbits(2);
}
else
for(register int i=0;i<n;i++)
if(bitalloc[LS][i])scaleselector[LS][i]=getbits(2);
// Scale index
{
register int i,j;
for(i=0;i<n;i++)
{
if((j=bitalloc[LS][i]))
{
if(!tableindex)
{
group[LS][i]=grouptableA[j];
codelength[LS][i]=codelengthtableA[j];
factor[LS][i]=factortableA[j];
c[LS][i]=ctableA[j];
d[LS][i]=dtableA[j];
}
else
{
if(i<=2)
{
group[LS][i]=grouptableB1[j];
codelength[LS][i]=codelengthtableB1[j];
factor[LS][i]=factortableB1[j];
c[LS][i]=ctableB1[j];
d[LS][i]=dtableB1[j];
}
else
{
group[LS][i]=grouptableB234[j];
if(i<=10)
{
codelength[LS][i]=codelengthtableB2[j];
factor[LS][i]=factortableB2[j];
c[LS][i]=ctableB2[j];
d[LS][i]=dtableB2[j];
}
else if(i<=22)
{
codelength[LS][i]=codelengthtableB3[j];
factor[LS][i]=factortableB3[j];
c[LS][i]=ctableB3[j];
d[LS][i]=dtableB3[j];
}
else
{
codelength[LS][i]=codelengthtableB4[j];
factor[LS][i]=factortableB4[j];
c[LS][i]=ctableB4[j];
d[LS][i]=dtableB4[j];
}
}
}
switch(scaleselector[LS][i])
{
case 0:scalefactor[LS][0][i]=scalefactorstable[getbits(6)];
scalefactor[LS][1][i]=scalefactorstable[getbits(6)];
scalefactor[LS][2][i]=scalefactorstable[getbits(6)];
break;
case 1:scalefactor[LS][0][i]=
scalefactor[LS][1][i]=scalefactorstable[getbits(6)];
scalefactor[LS][2][i]=scalefactorstable[getbits(6)];
break;
case 2:scalefactor[LS][0][i]=
scalefactor[LS][1][i]=
scalefactor[LS][2][i]=scalefactorstable[getbits(6)];
break;
case 3:scalefactor[LS][0][i]=scalefactorstable[getbits(6)];
scalefactor[LS][1][i]=
scalefactor[LS][2][i]=scalefactorstable[getbits(6)];
break;
}
}
if(inputstereo && (j=bitalloc[RS][i]))
{
if(!tableindex)
{
group[RS][i]=grouptableA[j];
codelength[RS][i]=codelengthtableA[j];
factor[RS][i]=factortableA[j];
c[RS][i]=ctableA[j];
d[RS][i]=dtableA[j];
}
else
{
if(i<=2)
{
group[RS][i]=grouptableB1[j];
codelength[RS][i]=codelengthtableB1[j];
factor[RS][i]=factortableB1[j];
c[RS][i]=ctableB1[j];
d[RS][i]=dtableB1[j];
}
else
{
group[RS][i]=grouptableB234[j];
if(i<=10)
{
codelength[RS][i]=codelengthtableB2[j];
factor[RS][i]=factortableB2[j];
c[RS][i]=ctableB2[j];
d[RS][i]=dtableB2[j];
}
else if(i<=22)
{
codelength[RS][i]=codelengthtableB3[j];
factor[RS][i]=factortableB3[j];
c[RS][i]=ctableB3[j];
d[RS][i]=dtableB3[j];
}
else
{
codelength[RS][i]=codelengthtableB4[j];
factor[RS][i]=factortableB4[j];
c[RS][i]=ctableB4[j];
d[RS][i]=dtableB4[j];
}
}
}
switch(scaleselector[RS][i])
{
case 0 : scalefactor[RS][0][i]=scalefactorstable[getbits(6)];
scalefactor[RS][1][i]=scalefactorstable[getbits(6)];
scalefactor[RS][2][i]=scalefactorstable[getbits(6)];
break;
case 1 : scalefactor[RS][0][i]=
scalefactor[RS][1][i]=scalefactorstable[getbits(6)];
scalefactor[RS][2][i]=scalefactorstable[getbits(6)];
break;
case 2 : scalefactor[RS][0][i]=
scalefactor[RS][1][i]=
scalefactor[RS][2][i]=scalefactorstable[getbits(6)];
break;
case 3 : scalefactor[RS][0][i]=scalefactorstable[getbits(6)];
scalefactor[RS][1][i]=
scalefactor[RS][2][i]=scalefactorstable[getbits(6)];
break;
}
}
}
}
// Read Sample
{
register int i;
for(int l=0;l<SCALEBLOCK;l++)
{
// Read Sample
for(i=0;i<s;i++)
{
if(bitalloc[LS][i])
{
if(group[LS][i])
{
register const REAL *s;
int code=getbits(codelength[LS][i]);
code+=code<<1;
if (code > 2184) {
//printf("fraction LS OverFlow code %d -> 2184 (1)\n", code);
code=2184;
}
s=group[LS][i]+code;
fraction[LS][0][i]=s[0];
fraction[LS][1][i]=s[1];
fraction[LS][2][i]=s[2];
}
else
{
fraction[LS][0][i]=
REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0;
fraction[LS][1][i]=
REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0;
fraction[LS][2][i]=
REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0;
}
}
else fraction[LS][0][i]=fraction[LS][1][i]=fraction[LS][2][i]=0.0;
if(inputstereo && bitalloc[RS][i])
{
if(group[RS][i])
{
const REAL *s;
int code=getbits(codelength[RS][i]);
code+=code<<1;
if (code > 2184) {
//printf("fraction LS OverFlow code %d -> 2184 (2)\n", code);
code=2184;
}
s=group[RS][i]+code;
fraction[RS][0][i]=s[0];
fraction[RS][1][i]=s[1];
fraction[RS][2][i]=s[2];
}
else
{
fraction[RS][0][i]=
REAL(getbits(codelength[RS][i]))*factor[RS][i]-1.0;
fraction[RS][1][i]=
REAL(getbits(codelength[RS][i]))*factor[RS][i]-1.0;
fraction[RS][2][i]=
REAL(getbits(codelength[RS][i]))*factor[RS][i]-1.0;
}
}
else fraction[RS][0][i]=fraction[RS][1][i]=fraction[RS][2][i]=0.0;
}
for(;i<n;i++)
{
if(bitalloc[LS][i])
{
if(group[LS][i])
{
register const REAL *s;
int code=getbits(codelength[LS][i]);
code+=code<<1;
s=group[LS][i]+code;
fraction[LS][0][i]=fraction[RS][0][i]=s[0];
fraction[LS][1][i]=fraction[RS][1][i]=s[1];
fraction[LS][2][i]=fraction[RS][2][i]=s[2];
}
else
{
fraction[LS][0][i]=fraction[RS][0][i]=
REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0;
fraction[LS][1][i]=fraction[RS][1][i]=
REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0;
fraction[LS][2][i]=fraction[RS][2][i]=
REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0;
}
}
else fraction[LS][0][i]=fraction[LS][1][i]=fraction[LS][2][i]=
fraction[RS][0][i]=fraction[RS][1][i]=fraction[RS][2][i]=0.0;
}
//Fraction
if(outputstereo)
for(i=0;i<n;i++)
{
if(bitalloc[LS][i])
{
if(!group[LS][i])
{
fraction[LS][0][i]=(fraction[LS][0][i]+d[LS][i])*c[LS][i];
fraction[LS][1][i]=(fraction[LS][1][i]+d[LS][i])*c[LS][i];
fraction[LS][2][i]=(fraction[LS][2][i]+d[LS][i])*c[LS][i];
}
register REAL t=scalefactor[LS][l>>2][i];
fraction[LS][0][i]*=t;
fraction[LS][1][i]*=t;
fraction[LS][2][i]*=t;
}
if(bitalloc[RS][i])
{
if(!group[RS][i])
{
fraction[RS][0][i]=(fraction[RS][0][i]+d[RS][i])*c[RS][i];
fraction[RS][1][i]=(fraction[RS][1][i]+d[RS][i])*c[RS][i];
fraction[RS][2][i]=(fraction[RS][2][i]+d[RS][i])*c[RS][i];
}
register REAL t=scalefactor[RS][l>>2][i];
fraction[RS][0][i]*=t;
fraction[RS][1][i]*=t;
fraction[RS][2][i]*=t;
}
}
else
for(i=0;i<n;i++)
if(bitalloc[LS][i])
{
if(!group[LS][i])
{
fraction[LS][0][i]=(fraction[LS][0][i]+d[LS][i])*c[LS][i];
fraction[LS][1][i]=(fraction[LS][1][i]+d[LS][i])*c[LS][i];
fraction[LS][2][i]=(fraction[LS][2][i]+d[LS][i])*c[LS][i];
}
register REAL t=scalefactor[LS][l>>2][i];
fraction[LS][0][i]*=t;
fraction[LS][1][i]*=t;
fraction[LS][2][i]*=t;
}
for(;i<MAXSUBBAND;i++)
fraction[LS][0][i]=fraction[LS][1][i]=fraction[LS][2][i]=
fraction[RS][0][i]=fraction[RS][1][i]=fraction[RS][2][i]=0.0;
for(i=0;i<3;i++)
subbandsynthesis(fraction[LS][i],fraction[RS][i]);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,194 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Mpegtable.cc
// It has tables for MPEG layer 1, 2 and a part of layer 3
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _MSC_VER
#pragma warning(disable:4305)
#endif
#include "MPEGaudio.h"
// For header
const int MPEGaudio::frequencies[2][3]=
{
{44100,48000,32000}, // MPEG 1
{22050,24000,16000} // MPEG 2
};
const int MPEGaudio::bitrate[2][3][15]=
{
// MPEG 1
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}},
// MPEG 2
{{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}}
};
// Mpeg general table
const REAL MPEGaudio::scalefactorstable[64] =
{
2.00000000000000, 1.58740105196820, 1.25992104989487, 1.00000000000000,
0.79370052598410, 0.62996052494744, 0.50000000000000, 0.39685026299205,
0.31498026247372, 0.25000000000000, 0.19842513149602, 0.15749013123686,
0.12500000000000, 0.09921256574801, 0.07874506561843, 0.06250000000000,
0.04960628287401, 0.03937253280921, 0.03125000000000, 0.02480314143700,
0.01968626640461, 0.01562500000000, 0.01240157071850, 0.00984313320230,
0.00781250000000, 0.00620078535925, 0.00492156660115, 0.00390625000000,
0.00310039267963, 0.00246078330058, 0.00195312500000, 0.00155019633981,
0.00123039165029, 0.00097656250000, 0.00077509816991, 0.00061519582514,
0.00048828125000, 0.00038754908495, 0.00030759791257, 0.00024414062500,
0.00019377454248, 0.00015379895629, 0.00012207031250, 0.00009688727124,
0.00007689947814, 0.00006103515625, 0.00004844363562, 0.00003844973907,
0.00003051757813, 0.00002422181781, 0.00001922486954, 0.00001525878906,
0.00001211090890, 0.00000961243477, 0.00000762939453, 0.00000605545445,
0.00000480621738, 0.00000381469727, 0.00000302772723, 0.00000240310869,
0.00000190734863, 0.00000151386361, 0.00000120155435, 0.00000000000000
};
const REAL MPEGaudio::filter[512]=
{
0.000000000, -0.000442505, 0.003250122, -0.007003784,
0.031082153, -0.078628540, 0.100311279, -0.572036743,
1.144989014, 0.572036743, 0.100311279, 0.078628540,
0.031082153, 0.007003784, 0.003250122, 0.000442505,
-0.000015259, -0.000473022, 0.003326416, -0.007919312,
0.030517578, -0.084182739, 0.090927124, -0.600219727,
1.144287109, 0.543823242, 0.108856201, 0.073059082,
0.031478882, 0.006118774, 0.003173828, 0.000396729,
-0.000015259, -0.000534058, 0.003387451, -0.008865356,
0.029785156, -0.089706421, 0.080688477, -0.628295898,
1.142211914, 0.515609741, 0.116577148, 0.067520142,
0.031738281, 0.005294800, 0.003082275, 0.000366211,
-0.000015259, -0.000579834, 0.003433228, -0.009841919,
0.028884888, -0.095169067, 0.069595337, -0.656219482,
1.138763428, 0.487472534, 0.123474121, 0.061996460,
0.031845093, 0.004486084, 0.002990723, 0.000320435,
-0.000015259, -0.000625610, 0.003463745, -0.010848999,
0.027801514, -0.100540161, 0.057617188, -0.683914185,
1.133926392, 0.459472656, 0.129577637, 0.056533813,
0.031814575, 0.003723145, 0.002899170, 0.000289917,
-0.000015259, -0.000686646, 0.003479004, -0.011886597,
0.026535034, -0.105819702, 0.044784546, -0.711318970,
1.127746582, 0.431655884, 0.134887695, 0.051132202,
0.031661987, 0.003005981, 0.002792358, 0.000259399,
-0.000015259, -0.000747681, 0.003479004, -0.012939453,
0.025085449, -0.110946655, 0.031082153, -0.738372803,
1.120223999, 0.404083252, 0.139450073, 0.045837402,
0.031387329, 0.002334595, 0.002685547, 0.000244141,
-0.000030518, -0.000808716, 0.003463745, -0.014022827,
0.023422241, -0.115921021, 0.016510010, -0.765029907,
1.111373901, 0.376800537, 0.143264771, 0.040634155,
0.031005859, 0.001693726, 0.002578735, 0.000213623,
-0.000030518, -0.000885010, 0.003417969, -0.015121460,
0.021575928, -0.120697021, 0.001068115, -0.791213989,
1.101211548, 0.349868774, 0.146362305, 0.035552979,
0.030532837, 0.001098633, 0.002456665, 0.000198364,
-0.000030518, -0.000961304, 0.003372192, -0.016235352,
0.019531250, -0.125259399, -0.015228271, -0.816864014,
1.089782715, 0.323318481, 0.148773193, 0.030609131,
0.029937744, 0.000549316, 0.002349854, 0.000167847,
-0.000030518, -0.001037598, 0.003280640, -0.017349243,
0.017257690, -0.129562378, -0.032379150, -0.841949463,
1.077117920, 0.297210693, 0.150497437, 0.025817871,
0.029281616, 0.000030518, 0.002243042, 0.000152588,
-0.000045776, -0.001113892, 0.003173828, -0.018463135,
0.014801025, -0.133590698, -0.050354004, -0.866363525,
1.063217163, 0.271591187, 0.151596069, 0.021179199,
0.028533936, -0.000442505, 0.002120972, 0.000137329,
-0.000045776, -0.001205444, 0.003051758, -0.019577026,
0.012115479, -0.137298584, -0.069168091, -0.890090942,
1.048156738, 0.246505737, 0.152069092, 0.016708374,
0.027725220, -0.000869751, 0.002014160, 0.000122070,
-0.000061035, -0.001296997, 0.002883911, -0.020690918,
0.009231567, -0.140670776, -0.088775635, -0.913055420,
1.031936646, 0.221984863, 0.151962280, 0.012420654,
0.026840210, -0.001266479, 0.001907349, 0.000106812,
-0.000061035, -0.001388550, 0.002700806, -0.021789551,
0.006134033, -0.143676758, -0.109161377, -0.935195923,
1.014617920, 0.198059082, 0.151306152, 0.008316040,
0.025909424, -0.001617432, 0.001785278, 0.000106812,
-0.000076294, -0.001480103, 0.002487183, -0.022857666,
0.002822876, -0.146255493, -0.130310059, -0.956481934,
0.996246338, 0.174789429, 0.150115967, 0.004394531,
0.024932861, -0.001937866, 0.001693726, 0.000091553,
-0.000076294, -0.001586914, 0.002227783, -0.023910522,
-0.000686646, -0.148422241, -0.152206421, -0.976852417,
0.976852417, 0.152206421, 0.148422241, 0.000686646,
0.023910522, -0.002227783, 0.001586914, 0.000076294,
-0.000091553, -0.001693726, 0.001937866, -0.024932861,
-0.004394531, -0.150115967, -0.174789429, -0.996246338,
0.956481934, 0.130310059, 0.146255493, -0.002822876,
0.022857666, -0.002487183, 0.001480103, 0.000076294,
-0.000106812, -0.001785278, 0.001617432, -0.025909424,
-0.008316040, -0.151306152, -0.198059082, -1.014617920,
0.935195923, 0.109161377, 0.143676758, -0.006134033,
0.021789551, -0.002700806, 0.001388550, 0.000061035,
-0.000106812, -0.001907349, 0.001266479, -0.026840210,
-0.012420654, -0.151962280, -0.221984863, -1.031936646,
0.913055420, 0.088775635, 0.140670776, -0.009231567,
0.020690918, -0.002883911, 0.001296997, 0.000061035,
-0.000122070, -0.002014160, 0.000869751, -0.027725220,
-0.016708374, -0.152069092, -0.246505737, -1.048156738,
0.890090942, 0.069168091, 0.137298584, -0.012115479,
0.019577026, -0.003051758, 0.001205444, 0.000045776,
-0.000137329, -0.002120972, 0.000442505, -0.028533936,
-0.021179199, -0.151596069, -0.271591187, -1.063217163,
0.866363525, 0.050354004, 0.133590698, -0.014801025,
0.018463135, -0.003173828, 0.001113892, 0.000045776,
-0.000152588, -0.002243042, -0.000030518, -0.029281616,
-0.025817871, -0.150497437, -0.297210693, -1.077117920,
0.841949463, 0.032379150, 0.129562378, -0.017257690,
0.017349243, -0.003280640, 0.001037598, 0.000030518,
-0.000167847, -0.002349854, -0.000549316, -0.029937744,
-0.030609131, -0.148773193, -0.323318481, -1.089782715,
0.816864014, 0.015228271, 0.125259399, -0.019531250,
0.016235352, -0.003372192, 0.000961304, 0.000030518,
-0.000198364, -0.002456665, -0.001098633, -0.030532837,
-0.035552979, -0.146362305, -0.349868774, -1.101211548,
0.791213989, -0.001068115, 0.120697021, -0.021575928,
0.015121460, -0.003417969, 0.000885010, 0.000030518,
-0.000213623, -0.002578735, -0.001693726, -0.031005859,
-0.040634155, -0.143264771, -0.376800537, -1.111373901,
0.765029907, -0.016510010, 0.115921021, -0.023422241,
0.014022827, -0.003463745, 0.000808716, 0.000030518,
-0.000244141, -0.002685547, -0.002334595, -0.031387329,
-0.045837402, -0.139450073, -0.404083252, -1.120223999,
0.738372803, -0.031082153, 0.110946655, -0.025085449,
0.012939453, -0.003479004, 0.000747681, 0.000015259,
-0.000259399, -0.002792358, -0.003005981, -0.031661987,
-0.051132202, -0.134887695, -0.431655884, -1.127746582,
0.711318970, -0.044784546, 0.105819702, -0.026535034,
0.011886597, -0.003479004, 0.000686646, 0.000015259,
-0.000289917, -0.002899170, -0.003723145, -0.031814575,
-0.056533813, -0.129577637, -0.459472656, -1.133926392,
0.683914185, -0.057617188, 0.100540161, -0.027801514,
0.010848999, -0.003463745, 0.000625610, 0.000015259,
-0.000320435, -0.002990723, -0.004486084, -0.031845093,
-0.061996460, -0.123474121, -0.487472534, -1.138763428,
0.656219482, -0.069595337, 0.095169067, -0.028884888,
0.009841919, -0.003433228, 0.000579834, 0.000015259,
-0.000366211, -0.003082275, -0.005294800, -0.031738281,
-0.067520142, -0.116577148, -0.515609741, -1.142211914,
0.628295898, -0.080688477, 0.089706421, -0.029785156,
0.008865356, -0.003387451, 0.000534058, 0.000015259,
-0.000396729, -0.003173828, -0.006118774, -0.031478882,
-0.073059082, -0.108856201, -0.543823242, -1.144287109,
0.600219727, -0.090927124, 0.084182739, -0.030517578,
0.007919312, -0.003326416, 0.000473022, 0.000015259
};
REAL MPEGaudio::hcos_64[16],
MPEGaudio::hcos_32[ 8],
MPEGaudio::hcos_16[ 4],
MPEGaudio::hcos_8 [ 2],
MPEGaudio::hcos_4;

View file

@ -0,0 +1,516 @@
/* MPEG/WAVE Sound library
(C) 1997 by Jung woo-jae */
// Mpegtoraw.cc
// Server which get mpeg format and put raw format.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "MPEGaudio.h"
#include "MPEGstream.h"
#if defined(_WIN32)
#include <windows.h>
#endif
#define MY_PI 3.14159265358979323846
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define _KEY 0
#else
#define _KEY 3
#endif
int MPEGaudio::getbits( int bits )
{
union
{
char store[4];
int current;
} u;
int bi;
if( ! bits )
return 0;
u.current = 0;
bi = (bitindex & 7);
u.store[ _KEY ] = _buffer[ bitindex >> 3 ] << bi;
bi = 8 - bi;
bitindex += bi;
while( bits )
{
if( ! bi )
{
u.store[ _KEY ] = _buffer[ bitindex >> 3 ];
bitindex += 8;
bi = 8;
}
if( bits >= bi )
{
u.current <<= bi;
bits -= bi;
bi = 0;
}
else
{
u.current <<= bits;
bi -= bits;
bits = 0;
}
}
bitindex -= bi;
return( u.current >> 8 );
}
// Convert mpeg to raw
// Mpeg headder class
void MPEGaudio::initialize()
{
static bool initialized = false;
register int i;
register REAL *s1,*s2;
REAL *s3,*s4;
last_speed = 0;
stereo = true;
forcetomonoflag = false;
forcetostereoflag = false;
swapendianflag = false;
downfrequency = 0;
scalefactor=SCALE;
calcbufferoffset=15;
currentcalcbuffer=0;
s1 = calcbufferL[0];
s2 = calcbufferR[0];
s3 = calcbufferL[1];
s4 = calcbufferR[1];
for(i=CALCBUFFERSIZE-1;i>=0;i--)
{
calcbufferL[0][i]=calcbufferL[1][i]=
calcbufferR[0][i]=calcbufferR[1][i]=0.0;
}
if( ! initialized )
{
for(i=0;i<16;i++) hcos_64[i] = (float)
(1.0/(2.0*cos(MY_PI*double(i*2+1)/64.0)));
for(i=0;i< 8;i++) hcos_32[i] = (float)
(1.0/(2.0*cos(MY_PI*double(i*2+1)/32.0)));
for(i=0;i< 4;i++) hcos_16[i] = (float)
(1.0/(2.0*cos(MY_PI*double(i*2+1)/16.0)));
for(i=0;i< 2;i++) hcos_8 [i] = (float)
(1.0/(2.0*cos(MY_PI*double(i*2+1)/ 8.0)));
hcos_4 = (float)(1.0f / (2.0f * cos( MY_PI * 1.0 / 4.0 )));
initialized = true;
}
layer3initialize();
#ifdef THREADED_AUDIO
decode_thread = NULL;
ring = NULL;
#endif
Rewind();
ResetSynchro(0);
};
bool MPEGaudio::loadheader()
{
register int c;
bool flag;
flag = false;
do
{
if( (c = mpeg->copy_byte()) < 0 )
break;
if( c == 0xff )
{
while( ! flag )
{
if( (c = mpeg->copy_byte()) < 0 )
{
flag = true;
break;
}
if( (c & 0xf0) == 0xf0 )
{
flag = true;
break;
}
else if( c != 0xff )
{
break;
}
}
}
} while( ! flag );
if( c < 0 )
return false;
// Analyzing
c &= 0xf;
protection = c & 1;
layer = 4 - ((c >> 1) & 3);
version = (_mpegversion) ((c >> 3) ^ 1);
c = mpeg->copy_byte() >> 1;
padding = (c & 1);
c >>= 1;
frequency = (_frequency) (c&3);
if (frequency == 3)
return false;
c >>= 2;
bitrateindex = (int) c;
if( bitrateindex == 15 )
return false;
c = ((unsigned int)mpeg->copy_byte()) >> 4;
extendedmode = c & 3;
mode = (_mode) (c >> 2);
// Making information
inputstereo = (mode == single) ? 0 : 1;
forcetomonoflag = (!stereo && inputstereo);
forcetostereoflag = (stereo && !inputstereo);
if(forcetomonoflag)
outputstereo=0;
else
outputstereo=inputstereo;
channelbitrate=bitrateindex;
if(inputstereo)
{
if(channelbitrate==4)
channelbitrate=1;
else
channelbitrate-=4;
}
if(channelbitrate==1 || channelbitrate==2)
tableindex=0;
else
tableindex=1;
if(layer==1)
subbandnumber=MAXSUBBAND;
else
{
if(!tableindex)
if(frequency==frequency32000)subbandnumber=12; else subbandnumber=8;
else if(frequency==frequency48000||
(channelbitrate>=3 && channelbitrate<=5))
subbandnumber=27;
else subbandnumber=30;
}
if(mode==single)stereobound=0;
else if(mode==joint)stereobound=(extendedmode+1)<<2;
else stereobound=subbandnumber;
if(stereobound>subbandnumber)stereobound=subbandnumber;
// framesize & slots
if(layer==1)
{
framesize=(12000*bitrate[version][0][bitrateindex])/
frequencies[version][frequency];
if(frequency==frequency44100 && padding)framesize++;
framesize<<=2;
}
else
{
framesize=(144000*bitrate[version][layer-1][bitrateindex])/
(frequencies[version][frequency]<<version);
if(padding)framesize++;
if(layer==3)
{
if(version)
layer3slots=framesize-((mode==single)?9:17)
-(protection?0:2)
-4;
else
layer3slots=framesize-((mode==single)?17:32)
-(protection?0:2)
-4;
}
}
#ifdef DEBUG_AUDIO
fprintf(stderr, "MPEG %d audio layer %d (%d kbps), at %d Hz %s [%d]\n", version+1, layer, bitrate[version][layer-1][bitrateindex], frequencies[version][frequency], (mode == single) ? "mono" : "stereo", framesize);
#endif
/* Fill the buffer with new data */
if(!fillbuffer(framesize-4))
return false;
if(!protection)
{
getbyte(); // CRC, Not check!!
getbyte();
}
// Sam 7/17 - skip sequences of quickly varying frequencies
int speed = frequencies[version][frequency];
if ( speed != last_speed ) {
last_speed = speed;
if ( rawdatawriteoffset ) {
++decodedframe;
#ifndef THREADED_AUDIO
++currentframe;
#endif
}
return loadheader();
}
return true;
}
bool MPEGaudio::run( int frames, double *timestamp)
{
double last_timestamp = -1;
int totFrames = frames;
for( ; frames; frames-- )
{
if( loadheader() == false ) {
return false;
}
if (frames == totFrames && timestamp != NULL)
if (last_timestamp != mpeg->timestamp){
if (mpeg->timestamp_pos <= _buffer_pos)
last_timestamp = *timestamp = mpeg->timestamp;
}
else
*timestamp = -1;
if ( layer == 3 ) extractlayer3();
else if( layer == 2 ) extractlayer2();
else if( layer == 1 ) extractlayer1();
/* Handle swapping data endianness */
if ( swapendianflag ) {
Sint16 *p;
p = rawdata+rawdatawriteoffset;
while ( p > rawdata ) {
--p;
*p = SDL_Swap16(*p);
}
}
/* Handle expanding to stereo output */
if ( forcetostereoflag ) {
Sint16 *in, *out;
in = rawdata+rawdatawriteoffset;
rawdatawriteoffset *= 2;
out = rawdata+rawdatawriteoffset;
while ( in > rawdata ) {
--in;
*(--out) = *in;
*(--out) = *in;
}
}
// Sam 10/5 - If there is no data, don't increment frames
if ( rawdatawriteoffset ) {
++decodedframe;
#ifndef THREADED_AUDIO
++currentframe;
#endif
}
}
return(true);
}
#ifdef THREADED_AUDIO
int Decode_MPEGaudio(void *udata)
{
MPEGaudio *audio = (MPEGaudio *)udata;
double timestamp;
#if defined(_WIN32)
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
#endif
audio->force_exit = false;
while ( audio->decoding && ! audio->mpeg->eof() && !audio->force_exit ) {
audio->rawdata = (Sint16 *)audio->ring->NextWriteBuffer();
if ( audio->rawdata ) {
audio->rawdatawriteoffset = 0;
/* Sam 10/5/2000 - Added while to prevent empty buffer in ring */
while ( audio->run(1, &timestamp) &&
(audio->rawdatawriteoffset == 0) ) {
/* Keep looping */ ;
}
if((Uint32)audio->rawdatawriteoffset*2 <= audio->ring->BufferSize())
audio->ring->WriteDone(audio->rawdatawriteoffset*2, timestamp);
}
}
audio->decoding = false;
return(0);
}
#endif /* THREADED_AUDIO */
// Helper function for SDL audio
int Play_MPEGaudio(MPEGaudio *audio, Uint8 *stream, int len)
{
int volume;
long copylen;
int mixed = 0;
/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name in popcorn */
/* Bail if audio isn't playing */
if ( audio->GetStatus() != MPEG_PLAYING ) {
return(0);
}
volume = audio->volume;
/* Increment the current play time (assuming fixed frag size) */
switch (audio->frags_playing++) {
// Vivien: Well... the theorical way seems good to me :-)
case 0: /* The first audio buffer is being filled */
break;
case 1: /* The first audio buffer is starting playback */
audio->frag_time = SDL_GetTicks();
break;
default: /* A buffer has completed, filling a new one */
audio->frag_time = SDL_GetTicks();
audio->play_time += ((double)len)/audio->rate_in_s;
break;
}
/* Copy the audio data to output */
#ifdef THREADED_AUDIO
Uint8 *rbuf;
assert(audio);
assert(audio->ring);
do {
/* this is empirical, I don't realy know how to find out when
a certain piece of audio has finished playing or even if
the timestamps refer to the time when the frame starts
playing or then the frame ends playing, but as is works
quite right */
copylen = audio->ring->NextReadBuffer(&rbuf);
if ( copylen > len ) {
SDL_MixAudio(stream, rbuf, len, volume);
mixed += len;
audio->ring->ReadSome(len);
len = 0;
for (int i=0; i < N_TIMESTAMPS -1; i++)
audio->timestamp[i] = audio->timestamp[i+1];
audio->timestamp[N_TIMESTAMPS-1] = audio->ring->ReadTimeStamp();
} else {
SDL_MixAudio(stream, rbuf, copylen, volume);
mixed += copylen;
++audio->currentframe;
audio->ring->ReadDone();
//fprintf(stderr, "-");
len -= copylen;
stream += copylen;
}
if (audio->timestamp[0] != -1){
double timeshift = audio->Time() - audio->timestamp[0];
double correction = 0;
assert(audio->timestamp >= 0);
if (fabs(timeshift) > 1.0){
correction = -timeshift;
#ifdef DEBUG_TIMESTAMP_SYNC
fprintf(stderr, "audio jump %f\n", timeshift);
#endif
} else
correction = -timeshift/100;
#ifdef USE_TIMESTAMP_SYNC
audio->play_time += correction;
#endif
#ifdef DEBUG_TIMESTAMP_SYNC
fprintf(stderr, "\raudio: time:%8.3f shift:%8.4f",
audio->Time(), timeshift);
#endif
audio->timestamp[0] = -1;
}
} while ( copylen && (len > 0) && ((audio->currentframe < audio->decodedframe) || audio->decoding)
&& !audio->force_exit );
#else
/* The length is interpreted as being in samples */
len /= 2;
/* Copy in any saved data */
if ( audio->rawdatawriteoffset >= audio->rawdatareadoffset) {
copylen = (audio->rawdatawriteoffset-audio->rawdatareadoffset);
assert(copylen >= 0);
if ( copylen >= len ) {
SDL_MixAudio(stream, (Uint8 *)&audio->spillover[audio->rawdatareadoffset],
len*2, volume);
mixed += len*2;
audio->rawdatareadoffset += len;
goto finished_mixing;
}
SDL_MixAudio(stream, (Uint8 *)&audio->spillover[audio->rawdatareadoffset],
copylen*2, volume);
mixed += copylen*2;
len -= copylen;
stream += copylen*2;
}
/* Copy in any new data */
audio->rawdata = (Sint16 *)stream;
audio->rawdatawriteoffset = 0;
audio->run(len/audio->samplesperframe);
mixed += audio->rawdatawriteoffset*2;
len -= audio->rawdatawriteoffset;
stream += audio->rawdatawriteoffset*2;
/* Write a save buffer for remainder */
audio->rawdata = audio->spillover;
audio->rawdatawriteoffset = 0;
if ( audio->run(1) ) {
assert(audio->rawdatawriteoffset > len);
SDL_MixAudio(stream, (Uint8 *) audio->spillover, len*2, volume);
mixed += len*2;
audio->rawdatareadoffset = len;
} else {
audio->rawdatareadoffset = 0;
}
finished_mixing:
#endif
return(mixed);
}
void Play_MPEGaudioSDL(void *udata, Uint8 *stream, int len)
{
MPEGaudio *audio = (MPEGaudio *)udata;
Play_MPEGaudio(audio, stream, len);
}
// EOF

20
smpeg/src/video/COPYRIGHT Normal file
View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/

View file

@ -0,0 +1,609 @@
/*
SMPEG - SDL MPEG Player Library
Copyright (C) 1999 Loki Entertainment Software
- Modified by Michel Darricau from eProcess <mdarricau@eprocess.fr> for popcorn -
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
Changes to make the code reentrant:
Got rid of setjmp, longjmp
deglobalized: EOF_flag, FilmState, curVidStream, bitOffset, bitLength,
bitBuffer, sys_layer, input, seekValue, window, X Windows globals (to
xinfo), curBits, ditherType, matched_depth, totNumFrames, realTimeStart
Additional changes:
Ability to play >1 movie (w/out CONTROLS)
Make sure we do a full frame for each movie
DISABLE_DITHER #ifdef to avoid compiling dithering code
Changes to deal with non-MPEG streams
Now deals with NO_DITHER, PPM_DITHER and noDisplayFlag==1
CONTROLS version now can deal with >1 movie
-lsh@cs.brown.edu (Loring Holden)
*/
#include <limits.h>
#include <string.h>
#include "video.h"
#include "proto.h"
#include "dither.h"
#include "util.h"
#include "MPEGvideo.h"
#include "MPEGfilter.h"
/*--------------------------------------------------------------*/
/* Define buffer length. */
#define BUF_LENGTH 80000
/* TODO: Eliminate these globals so multiple movies can be played. */
/* Quiet flag (verbose). */
int quietFlag = 1;
/* Framerate, -1: specified in stream (default)
0: as fast as possible
N (N>0): N frames/sec
*/
#ifdef TIME_MPEG
int framerate = 0;
#else
int framerate = -1;
#endif
/* Flag for high quality at the expense of speed */
#ifdef QUALITY
int qualityFlag = 1;
#else
int qualityFlag = 0;
#endif
/*--------------------------------------------------------------*/
MPEGvideo::MPEGvideo(MPEGstream *stream)
{
Uint32 start_code;
MPEGstream_marker *marker;
/* Set the MPEG data stream */
mpeg = stream;
time_source = NULL;
/* Set default playback variables */
_thread = NULL;
_dst = NULL;
_mutex = NULL;
_stream = NULL;
/* Mark the data to leave the stream unchanged */
/* after parsing */
marker = mpeg->new_marker(0);
/* Get the width and height of the video */
start_code = mpeg->copy_byte();
start_code <<= 8;
start_code |= mpeg->copy_byte();
start_code <<= 8;
start_code |= mpeg->copy_byte();
while ( ! mpeg->eof() && (start_code != SEQ_START_CODE) ) {
start_code <<= 8;
start_code |= mpeg->copy_byte();
}
if ( start_code == SEQ_START_CODE ) {
Uint8 buf[4];
/* Get the width and height of the video */
mpeg->copy_data(buf, 4);
_w = (buf[0]<<4)|(buf[1]>>4); /* 12 bits of width */
_h = ((buf[1]&0xF)<<8)|buf[2]; /* 12 bits of height */
switch(buf[3]&0xF) /* 4 bits of fps */
{
case 1: _fps = 23.97f; break;
case 2: _fps = 24.00f; break;
case 3: _fps = 25.00f; break;
case 4: _fps = 29.97f; break;
case 5: _fps = 30.00f; break;
case 6: _fps = 50.00f; break;
case 7: _fps = 59.94f; break;
case 8: _fps = 60.00f; break;
case 9: _fps = 15.00f; break;
default: _fps = 30.00f; break;
}
} else {
_w = 0;
_h = 0;
_fps = 0.00;
SetError("Not a valid MPEG video stream");
}
/* Rewind back to the old position */
mpeg->seek_marker(marker);
mpeg->delete_marker(marker);
/* Keep original width and height in _ow and _oh */
_ow = _w;
_oh = _h;
/* Now round up width and height to a multiple */
/* of a macroblock size (16 pixels) to keep the */
/* video decoder happy */
_w = (_w + 15) & ~15;
_h = (_h + 15) & ~15;
/* Set the default playback area */
_dstrect.x = 0;
_dstrect.y = 0;
_dstrect.w = 0;
_dstrect.h = 0;
/* Set the source area */
_srcrect.x = 0;
_srcrect.y = 0;
_srcrect.w = _ow;
_srcrect.h = _oh;
_image = 0;
_filter = SMPEGfilter_null();
_filter_mutex = SDL_CreateMutex();
// printf("[MPEGvideo::MPEGvideo]_filter_mutex[%lx] = SDL_CreateMutex()\n",_filter_mutex);
}
MPEGvideo:: ~MPEGvideo()
{
/* Stop it before we free everything */
Stop();
/* Free actual video stream */
if( _stream )
DestroyVidStream( _stream );
/* Free overlay */
if(_image) SDL_FreeYUVOverlay(_image);
/* Release filter */
SDL_DestroyMutex(_filter_mutex);
_filter->destroy(_filter);
}
/* Simple thread play function */
int Play_MPEGvideo( void *udata )
{
MPEGvideo *mpeg = (MPEGvideo *)udata;
/* Get the time the playback started */
mpeg->_stream->realTimeStart += ReadSysClock();
#ifdef TIME_MPEG
int start_frames, stop_frames;
int total_frames;
Uint32 start_time, stop_time;
float total_time;
start_frames = mpeg->_stream->totNumFrames;
start_time = SDL_GetTicks();
#endif
mpeg->force_exit = false;
while( mpeg->playing && !mpeg->force_exit )
{
int mark = mpeg->_stream->totNumFrames;
/* make sure we do a whole frame */
while( (mark == mpeg->_stream->totNumFrames) && mpeg->playing && !mpeg->force_exit )
{
mpegVidRsrc( 0, mpeg->_stream, 0 );
}
if( mpeg->_stream->film_has_ended || mpeg->force_exit )
{
mpeg->playing = false;
}
}
/* Get the time the playback stopped */
mpeg->_stream->realTimeStart -= ReadSysClock();
#ifdef TIME_MPEG
stop_time = SDL_GetTicks();
stop_frames = mpeg->_stream->totNumFrames;
total_frames = (stop_frames-start_frames);
total_time = (float)(stop_time-start_time)/1000.0;
if ( total_time > 0 ) {
printf("%d frames in %2.2f seconds (%2.2f FPS)\n",
total_frames, total_time, (float)total_frames/total_time);
}
#endif
return(0);
}
void
MPEGvideo:: Play(void)
{
ResetPause();
if ( _stream ) {
if ( playing ) {
Stop();
}
playing = true;
#ifdef DISABLE_VIDEO_CALLBACK_THREAD
Play_MPEGvideo(this);
#else
_thread = SDL_CreateThread( Play_MPEGvideo, this );
if ( !_thread ) {
playing = false;
}
#endif
}
}
void
MPEGvideo:: Stop(void)
{
if ( _thread ) {
force_exit = true;
SDL_WaitThread(_thread, NULL);
_thread = NULL;
}
playing = false;
ResetPause();
}
void
MPEGvideo:: Rewind(void)
{
Stop();
if ( _stream ) {
/* Reinitialize vid_stream pointers */
ResetVidStream( _stream );
#ifdef ANALYSIS
init_stats();
#endif
}
}
void
MPEGvideo:: ResetSynchro(double time)
{
if( _stream )
{
_stream->_jumpFrame = -1;
_stream->realTimeStart = -time;
play_time = time;
if (time > 0) {
double oneframetime;
if (_stream->_oneFrameTime == 0)
oneframetime = 1.0 / _stream->_smpeg->_fps;
else
oneframetime = _stream->_oneFrameTime;
/* time -> frame */
_stream->totNumFrames = (int)(time / oneframetime);
/* Set Current Frame To 0 & Frame Adjust Frag Set */
_stream->current_frame = 0;
_stream->need_frameadjust=true;
}
}
}
void
MPEGvideo::Skip(float seconds)
{
int frame;
/* Called only when there is no timestamp info in the MPEG */
/* This is quite slow however */
printf("Video: Skipping %f seconds...\n", seconds);
frame = (int) (_fps * seconds);
if( _stream )
{
_stream->_jumpFrame = frame;
while( (_stream->totNumFrames < frame) &&
! _stream->film_has_ended )
{
mpegVidRsrc( 0, _stream, 0 );
}
ResetSynchro(0);
}
}
/* Michel Darricau from eProcess <mdarricau@eprocess.fr> conflict name in popcorn */
MPEGstatus
MPEGvideo:: GetStatus(void)
{
if ( _stream ) {
if( !_thread || (_stream->film_has_ended ) ) {
return MPEG_STOPPED;
} else {
return MPEG_PLAYING;
}
}
return MPEG_ERROR;
}
bool
MPEGvideo:: GetVideoInfo(MPEG_VideoInfo *info)
{
if ( info ) {
info->width = _ow;
info->height = _oh;
if ( _stream ) {
info->current_frame = _stream->current_frame;
#ifdef CALCULATE_FPS
/* Get the appropriate indices for the timestamps */
/* Calculate the frames-per-second from the timestamps */
if ( _stream->frame_time[_stream->timestamp_index] ) {
double *timestamps;
double time_diff;
int this_index;
int last_index;
timestamps = _stream->frame_time;
last_index = _stream->timestamp_index;
this_index = last_index - 1;
if ( this_index < 0 ) {
this_index = FPS_WINDOW-1;
}
time_diff = timestamps[this_index] - timestamps[last_index];
info->current_fps = (double)FPS_WINDOW / time_diff;
} else {
info->current_fps = 0.0;
}
#else
info->current_fps = _stream->totNumFrames /
(ReadSysClock() - _stream->realTimeStart);
#endif
} else {
info->current_frame = 0;
info->current_fps = 0.0;
}
}
return(!WasError());
}
/*
Returns zero if fails.
surf - Surface to play movie on.
lock - lock is held while MPEG stream is playing
callback - called on every frame, for display update
*/
bool
MPEGvideo:: SetDisplay(SDL_Surface *dst, SDL_mutex *lock,
MPEG_DisplayCallback callback)
{
_mutex = lock;
_dst = dst;
_callback = callback;
if ( _image ) {
SDL_FreeYUVOverlay(_image);
}
_image = SDL_CreateYUVOverlay(_srcrect.w, _srcrect.h, SDL_YV12_OVERLAY, dst);
if ( _image == NULL ) {
return false;
}
if ( !_dstrect.w || !_dstrect.h ) {
_dstrect.w = dst->w;
_dstrect.h = dst->h;
}
if ( !_stream ) {
decodeInitTables();
InitCrop();
InitIDCT();
_stream = NewVidStream( (unsigned int) BUF_LENGTH );
if( _stream ) {
_stream->_smpeg = this;
_stream->ditherType = FULL_COLOR_DITHER;
_stream->matched_depth = dst->format->BitsPerPixel;
if( mpegVidRsrc( 0, _stream, 1 ) == NULL ) {
SetError("Not an MPEG video stream");
return false;
}
}
if ( ! InitPictImages(_stream, _w, _h, _dst) )
return false;
}
return true;
}
/* If this is being called during play, the calling program is responsible
for clearing the old area and coordinating with the update callback.
*/
void
MPEGvideo:: MoveDisplay( int x, int y )
{
SDL_mutexP( _mutex );
_dstrect.x = x;
_dstrect.y = y;
SDL_mutexV( _mutex );
}
void
MPEGvideo:: ScaleDisplayXY( int w, int h )
{
SDL_mutexP( _mutex );
_dstrect.w = w;
_dstrect.h = h;
SDL_mutexV( _mutex );
}
void
MPEGvideo:: SetDisplayRegion(int x, int y, int w, int h)
{
SDL_mutexP( _mutex );
_srcrect.x = x;
_srcrect.y = y;
_srcrect.w = w;
_srcrect.h = h;
if(_image)
{
SDL_FreeYUVOverlay(_image);
_image = SDL_CreateYUVOverlay(_srcrect.w, _srcrect.h, SDL_YV12_OVERLAY, _dst);
/* !!! FIXME: Uhh...what if this one fails? */
}
SDL_mutexV( _mutex );
}
/* API CHANGE: This function no longer takes a destination surface and x/y
You must use SetDisplay() and MoveDisplay() to set those attributes.
*/
void
MPEGvideo:: RenderFrame( int frame )
{
_stream->need_frameadjust = true;
if( _stream->current_frame > frame ) {
mpeg->rewind_stream();
mpeg->next_packet();
Rewind();
}
_stream->_jumpFrame = frame;
while( (_stream->current_frame < frame) &&
! _stream->film_has_ended )
{
mpegVidRsrc( 0, _stream, 0 );
}
_stream->_jumpFrame = -1;
}
void
MPEGvideo:: RenderFinal(SDL_Surface *dst, int x, int y)
{
SDL_Surface *saved_dst;
int saved_x, saved_y;
/* This operation can only be performed when stopped */
Stop();
/* Set (and save) the destination and location */
saved_dst = _dst;
saved_x = _dstrect.x;
saved_y = _dstrect.y;
SetDisplay(dst, _mutex, _callback);
MoveDisplay(x, y);
if ( ! _stream->film_has_ended ) {
/* Search for the last "group of pictures" start code */
Uint32 start_code;
MPEGstream_marker * marker, * oldmarker;
marker = 0;
start_code = mpeg->copy_byte();
start_code <<= 8;
start_code |= mpeg->copy_byte();
start_code <<= 8;
start_code |= mpeg->copy_byte();
while ( ! mpeg->eof() ) {
start_code <<= 8;
start_code |= mpeg->copy_byte();
if ( start_code == GOP_START_CODE ) {
oldmarker = marker;
marker = mpeg->new_marker(-4);
if( oldmarker ) mpeg->delete_marker( oldmarker );
mpeg->garbage_collect();
}
}
/* Set the stream to the last spot marked */
if ( ! mpeg->seek_marker( marker ) ) {
mpeg->rewind_stream();
mpeg->next_packet();
}
mpeg->delete_marker( marker );
_stream->buf_length = 0;
_stream->bit_offset = 0;
/* Process all frames without displaying any */
_stream->_skipFrame = 1;
RenderFrame( INT_MAX );
mpeg->garbage_collect();
}
/* Display the frame */
DisplayFrame(_stream);
/* Restore the destination and location */
SetDisplay(saved_dst, _mutex, _callback);
MoveDisplay(saved_x, saved_y);
}
/* EOF */

4
smpeg/src/video/README Normal file
View file

@ -0,0 +1,4 @@
This code is based on mpeg_play, available from:
http://bmrc.berkeley.edu/frame/research/mpeg/

1004
smpeg/src/video/decoders.cpp Normal file

File diff suppressed because it is too large Load diff

637
smpeg/src/video/decoders.h Normal file
View file

@ -0,0 +1,637 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* decoders.h
*
* This file contains the declarations of structures required for Huffman
* decoding
*
*/
/* Include util.h for bit i/o parsing macros. */
#include "util.h"
/* Code for unbound values in decoding tables */
#define ERROR (-1)
#define DCT_ERROR 63
#define MACRO_BLOCK_STUFFING 34
#define MACRO_BLOCK_ESCAPE 35
/* Two types of DCT Coefficients */
#define DCT_COEFF_FIRST 0
#define DCT_COEFF_NEXT 1
/* Special values for DCT Coefficients */
#define END_OF_BLOCK 62
#define ESCAPE 61
/* Structure for an entry in the decoding table of
* macroblock_address_increment */
typedef struct {
int value; /* value for macroblock_address_increment */
int num_bits; /* length of the Huffman code */
} mb_addr_inc_entry;
/* Decoding table for macroblock_address_increment */
extern mb_addr_inc_entry mb_addr_inc[2048];
/* Structure for an entry in the decoding table of macroblock_type */
typedef struct {
unsigned int mb_quant; /* macroblock_quant */
unsigned int mb_motion_forward; /* macroblock_motion_forward */
unsigned int mb_motion_backward; /* macroblock_motion_backward */
unsigned int mb_pattern; /* macroblock_pattern */
unsigned int mb_intra; /* macroblock_intra */
int num_bits; /* length of the Huffman code */
} mb_type_entry;
/* Decoding table for macroblock_type in predictive-coded pictures */
extern mb_type_entry mb_type_P[64];
/* Decoding table for macroblock_type in bidirectionally-coded pictures */
extern mb_type_entry mb_type_B[64];
/* Structures for an entry in the decoding table of coded_block_pattern */
typedef struct {
unsigned int cbp; /* coded_block_pattern */
int num_bits; /* length of the Huffman code */
} coded_block_pattern_entry;
/* External declaration of coded block pattern table. */
extern const coded_block_pattern_entry coded_block_pattern[512];
/* Structure for an entry in the decoding table of motion vectors */
typedef struct {
int code; /* value for motion_horizontal_forward_code,
* motion_vertical_forward_code,
* motion_horizontal_backward_code, or
* motion_vertical_backward_code.
*/
int num_bits; /* length of the Huffman code */
} motion_vectors_entry;
/* Decoding table for motion vectors */
extern motion_vectors_entry motion_vectors[2048];
/* Structure for an entry in the decoding table of dct_dc_size */
typedef struct {
unsigned int value; /* value of dct_dc_size (luminance or chrominance) */
int num_bits; /* length of the Huffman code */
} dct_dc_size_entry;
/* External declaration of dct dc size lumiance table. */
extern const dct_dc_size_entry dct_dc_size_luminance[32];
extern const dct_dc_size_entry dct_dc_size_luminance1[16];
/* External declaration of dct dc size chrom table. */
extern const dct_dc_size_entry dct_dc_size_chrominance[32];
extern const dct_dc_size_entry dct_dc_size_chrominance1[32];
/* DCT coeff tables. */
#define RUN_MASK 0xfc00
#define LEVEL_MASK 0x03f0
#define NUM_MASK 0x000f
#define RUN_SHIFT 10
#define LEVEL_SHIFT 4
/* External declaration of dct coeff tables. */
extern const unsigned short int dct_coeff_tbl_0[256];
extern const unsigned short int dct_coeff_tbl_1[16];
extern const unsigned short int dct_coeff_tbl_2[4];
extern const unsigned short int dct_coeff_tbl_3[4];
extern const unsigned short int dct_coeff_next[256];
extern const unsigned short int dct_coeff_first[256];
#define DecodeDCTDCSizeLum(macro_val) \
{ \
unsigned int index; \
\
show_bits5(index); \
\
if (index < 31) { \
macro_val = dct_dc_size_luminance[index].value; \
flush_bits(dct_dc_size_luminance[index].num_bits); \
} \
else { \
show_bits9(index); \
index -= 0x1f0; \
macro_val = dct_dc_size_luminance1[index].value; \
flush_bits(dct_dc_size_luminance1[index].num_bits); \
} \
}
#define DecodeDCTDCSizeChrom(macro_val) \
{ \
unsigned int index; \
\
show_bits5(index); \
\
if (index < 31) { \
macro_val = dct_dc_size_chrominance[index].value; \
flush_bits(dct_dc_size_chrominance[index].num_bits); \
} \
else { \
show_bits10(index); \
index -= 0x3e0; \
macro_val = dct_dc_size_chrominance1[index].value; \
flush_bits(dct_dc_size_chrominance1[index].num_bits); \
} \
}
#ifdef NO_GRIFF_MODS
#define DecodeDCTCoeff(dct_coeff_tbl, run, level) \
{ \
unsigned int temp, index; \
unsigned int value, next32bits, flushed; \
\
/* \
* Grab the next 32 bits and use it to improve performance of \
* getting the bits to parse. Thus, calls are translated as: \
* \
* show_bitsX <--> next32bits >> (32-X) \
* get_bitsX <--> val = next32bits >> (32-flushed-X); \
* flushed += X; \
* next32bits &= bitMask[flushed]; \
* flush_bitsX <--> flushed += X; \
* next32bits &= bitMask[flushed]; \
* \
* I've streamlined the code a lot, so that we don't have to mask \
* out the low order bits and a few of the extra adds are removed. \
*/ \
show_bits32(next32bits); \
\
/* show_bits8(index); */ \
index = next32bits >> 24; \
\
if (index > 3) { \
value = dct_coeff_tbl[index]; \
run = value >> RUN_SHIFT; \
if (run != END_OF_BLOCK) { \
/* num_bits = (value & NUM_MASK) + 1; */ \
/* flush_bits(num_bits); */ \
if (run != ESCAPE) { \
/* get_bits1(value); */ \
/* if (value) level = -level; */ \
flushed = (value & NUM_MASK) + 2; \
level = (value & LEVEL_MASK) >> LEVEL_SHIFT; \
value = next32bits >> (32-flushed); \
value &= 0x1; \
if (value) level = -level; \
/* next32bits &= ((~0) >> flushed); last op before update */ \
} \
else { /* run == ESCAPE */ \
/* Get the next six into run, and next 8 into temp */ \
/* get_bits14(temp); */ \
flushed = (value & NUM_MASK) + 1; \
temp = next32bits >> (18-flushed); \
/* Normally, we'd ad 14 to flushed, but I've saved a few \
* instr by moving the add below */ \
temp &= 0x3fff; \
run = temp >> 8; \
temp &= 0xff; \
if (temp == 0) { \
/* get_bits8(level); */ \
level = next32bits >> (10-flushed); \
level &= 0xff; \
flushed += 22; \
assert(level >= 128); \
} else if (temp != 128) { \
/* Grab sign bit */ \
flushed += 14; \
level = ((int) (temp << 24)) >> 24; \
} else { \
/* get_bits8(level); */ \
level = next32bits >> (10-flushed); \
level &= 0xff; \
flushed += 22; \
level = level - 256; \
assert(level <= -128 && level >= -255); \
} \
} \
/* Update bitstream... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} \
} \
else { \
switch (index) { \
case 2: { \
/* show_bits10(index); */ \
index = next32bits >> 22; \
value = dct_coeff_tbl_2[index & 3]; \
break; \
} \
case 3: { \
/* show_bits10(index); */ \
index = next32bits >> 22; \
value = dct_coeff_tbl_3[index & 3]; \
break; \
} \
case 1: { \
/* show_bits12(index); */ \
index = next32bits >> 20; \
value = dct_coeff_tbl_1[index & 15]; \
break; \
} \
default: { /* index == 0 */ \
/* show_bits16(index); */ \
index = next32bits >> 16; \
value = dct_coeff_tbl_0[index & 255]; \
}} \
run = value >> RUN_SHIFT; \
level = (value & LEVEL_MASK) >> LEVEL_SHIFT; \
\
/* \
* Fold these operations together to make it fast... \
*/ \
/* num_bits = (value & NUM_MASK) + 1; */ \
/* flush_bits(num_bits); */ \
/* get_bits1(value); */ \
/* if (value) level = -level; */ \
\
flushed = (value & NUM_MASK) + 2; \
value = next32bits >> (32-flushed); \
value &= 0x1; \
if (value) level = -level; \
\
/* Update bitstream ... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} \
}
#else /* NO_GRIFF_MODS */
#define DecodeDCTCoeff(dct_coeff_tbl, run, level) \
{ \
unsigned int temp, index; \
unsigned int value, next32bits, flushed; \
\
/* \
* Grab the next 32 bits and use it to improve performance of \
* getting the bits to parse. Thus, calls are translated as: \
* \
* show_bitsX <--> next32bits >> (32-X) \
* get_bitsX <--> val = next32bits >> (32-flushed-X); \
* flushed += X; \
* next32bits &= bitMask[flushed]; \
* flush_bitsX <--> flushed += X; \
* next32bits &= bitMask[flushed]; \
* \
* I've streamlined the code a lot, so that we don't have to mask \
* out the low order bits and a few of the extra adds are removed. \
*/ \
show_bits32(next32bits); \
\
/* show_bits8(index); */ \
index = next32bits >> 24; \
\
if (index > 3) { \
value = dct_coeff_tbl[index]; \
run = value >> RUN_SHIFT; \
if (run != END_OF_BLOCK) { \
/* num_bits = (value & NUM_MASK) + 1; */ \
/* flush_bits(num_bits); */ \
if (run != ESCAPE) { \
/* get_bits1(value); */ \
/* if (value) level = -level; */ \
flushed = (value & NUM_MASK) + 2; \
level = (value & LEVEL_MASK) >> LEVEL_SHIFT; \
value = next32bits >> (32-flushed); \
value &= 0x1; \
if (value) level = -level; \
/* next32bits &= ((~0) >> flushed); last op before update */ \
\
/* Update bitstream... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} \
else { /* run == ESCAPE */ \
/* Get the next six into run, and next 8 into temp */ \
/* get_bits14(temp); */ \
flushed = (value & NUM_MASK) + 1; \
temp = next32bits >> (18-flushed); \
/* Normally, we'd ad 14 to flushed, but I've saved a few \
* instr by moving the add below */ \
temp &= 0x3fff; \
run = temp >> 8; \
temp &= 0xff; \
if (temp == 0) { \
/* get_bits8(level); */ \
level = next32bits >> (10-flushed); \
level &= 0xff; \
flushed += 22; \
/* CG: 12jul2000 - assert(level >= 128); */ \
if (level >= 128) { \
/* Update bitstream... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} else { \
run = END_OF_BLOCK; \
level = END_OF_BLOCK; \
} \
} else if (temp != 128) { \
/* Grab sign bit */ \
flushed += 14; \
level = ((int) (temp << 24)) >> 24; \
/* Update bitstream... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} else { \
/* get_bits8(level); */ \
level = next32bits >> (10-flushed); \
level &= 0xff; \
flushed += 22; \
level = level - 256; \
/* CG: 12jul2000 - assert(level <= -128 && level >= -255); */ \
if ( level <= -128 && level >= -255) { \
/* Update bitstream... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} else { \
run = END_OF_BLOCK; \
level = END_OF_BLOCK; \
} \
} \
} \
} \
} \
else { \
switch (index) { \
case 2: { \
/* show_bits10(index); */ \
index = next32bits >> 22; \
value = dct_coeff_tbl_2[index & 3]; \
break; \
} \
case 3: { \
/* show_bits10(index); */ \
index = next32bits >> 22; \
value = dct_coeff_tbl_3[index & 3]; \
break; \
} \
case 1: { \
/* show_bits12(index); */ \
index = next32bits >> 20; \
value = dct_coeff_tbl_1[index & 15]; \
break; \
} \
default: { /* index == 0 */ \
/* show_bits16(index); */ \
index = next32bits >> 16; \
value = dct_coeff_tbl_0[index & 255]; \
}} \
run = value >> RUN_SHIFT; \
level = (value & LEVEL_MASK) >> LEVEL_SHIFT; \
\
/* \
* Fold these operations together to make it fast... \
*/ \
/* num_bits = (value & NUM_MASK) + 1; */ \
/* flush_bits(num_bits); */ \
/* get_bits1(value); */ \
/* if (value) level = -level; */ \
\
flushed = (value & NUM_MASK) + 2; \
value = next32bits >> (32-flushed); \
value &= 0x1; \
if (value) level = -level; \
\
/* Update bitstream ... */ \
flush_bits(flushed); \
assert (flushed <= 32); \
} \
}
#endif /* NO_GRIFF_MODS */
#define DecodeDCTCoeffFirst(runval, levelval) \
{ \
DecodeDCTCoeff(dct_coeff_first, runval, levelval); \
}
#define DecodeDCTCoeffNext(runval, levelval) \
{ \
DecodeDCTCoeff(dct_coeff_next, runval, levelval); \
}
/*
*--------------------------------------------------------------
*
* DecodeMBAddrInc --
*
* Huffman Decoder for macro_block_address_increment; the location
* in which the result will be placed is being passed as argument.
* The decoded value is obtained by doing a table lookup on
* mb_addr_inc.
*
* Results:
* The decoded value for macro_block_address_increment or ERROR
* for unbound values will be placed in the location specified.
*
* Side effects:
* Bit stream is irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DecodeMBAddrInc(val) \
{ \
unsigned int index; \
show_bits11(index); \
val = mb_addr_inc[index].value; \
flush_bits(mb_addr_inc[index].num_bits); \
}
/*
*--------------------------------------------------------------
*
* DecodeMotionVectors --
*
* Huffman Decoder for the various motion vectors, including
* motion_horizontal_forward_code, motion_vertical_forward_code,
* motion_horizontal_backward_code, motion_vertical_backward_code.
* Location where the decoded result will be placed is being passed
* as argument. The decoded values are obtained by doing a table
* lookup on motion_vectors.
*
* Results:
* The decoded value for the motion vector or ERROR for unbound
* values will be placed in the location specified.
*
* Side effects:
* Bit stream is irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DecodeMotionVectors(value) \
{ \
unsigned int index; \
show_bits11(index); \
value = motion_vectors[index].code; \
flush_bits(motion_vectors[index].num_bits); \
}
/*
*--------------------------------------------------------------
*
* DecodeMBTypeB --
*
* Huffman Decoder for macro_block_type in bidirectionally-coded
* pictures;locations in which the decoded results: macroblock_quant,
* macroblock_motion_forward, macro_block_motion_backward,
* macroblock_pattern, macro_block_intra, will be placed are
* being passed as argument. The decoded values are obtained by
* doing a table lookup on mb_type_B.
*
* Results:
* The various decoded values for macro_block_type in
* bidirectionally-coded pictures or ERROR for unbound values will
* be placed in the locations specified.
*
* Side effects:
* Bit stream is irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DecodeMBTypeB(quant, motion_fwd, motion_bwd, pat, intra) \
{ \
unsigned int index; \
\
show_bits6(index); \
\
quant = mb_type_B[index].mb_quant; \
motion_fwd = mb_type_B[index].mb_motion_forward; \
motion_bwd = mb_type_B[index].mb_motion_backward; \
pat = mb_type_B[index].mb_pattern; \
intra = mb_type_B[index].mb_intra; \
flush_bits(mb_type_B[index].num_bits); \
}
/*
*--------------------------------------------------------------
*
* DecodeMBTypeI --
*
* Huffman Decoder for macro_block_type in intra-coded pictures;
* locations in which the decoded results: macroblock_quant,
* macroblock_motion_forward, macro_block_motion_backward,
* macroblock_pattern, macro_block_intra, will be placed are
* being passed as argument.
*
* Results:
* The various decoded values for macro_block_type in intra-coded
* pictures or ERROR for unbound values will be placed in the
* locations specified.
*
* Side effects:
* Bit stream is irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DecodeMBTypeI(quant, motion_fwd, motion_bwd, pat, intra) \
{ \
unsigned int index; \
static int quantTbl[4] = {ERROR, 1, 0, 0}; \
\
show_bits2(index); \
\
motion_fwd = 0; \
motion_bwd = 0; \
pat = 0; \
intra = 1; \
quant = quantTbl[index]; \
if (index) { \
flush_bits (1 + quant); \
} \
}
/*
*--------------------------------------------------------------
*
* DecodeMBTypeP --
*
* Huffman Decoder for macro_block_type in predictive-coded pictures;
* locations in which the decoded results: macroblock_quant,
* macroblock_motion_forward, macro_block_motion_backward,
* macroblock_pattern, macro_block_intra, will be placed are
* being passed as argument. The decoded values are obtained by
* doing a table lookup on mb_type_P.
*
* Results:
* The various decoded values for macro_block_type in
* predictive-coded pictures or ERROR for unbound values will be
* placed in the locations specified.
*
* Side effects:
* Bit stream is irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DecodeMBTypeP(quant, motion_fwd, motion_bwd, pat, intra) \
{ \
unsigned int index; \
\
show_bits6(index); \
\
quant = mb_type_P[index].mb_quant; \
motion_fwd = mb_type_P[index].mb_motion_forward; \
motion_bwd = mb_type_P[index].mb_motion_backward; \
pat = mb_type_P[index].mb_pattern; \
intra = mb_type_P[index].mb_intra; \
\
flush_bits(mb_type_P[index].num_bits); \
}
/*
*--------------------------------------------------------------
*
* DecodeCBP --
*
* Huffman Decoder for coded_block_pattern; location in which the
* decoded result will be placed is being passed as argument. The
* decoded values are obtained by doing a table lookup on
* coded_block_pattern.
*
* Results:
* The decoded value for coded_block_pattern or ERROR for unbound
* values will be placed in the location specified.
*
* Side effects:
* Bit stream is irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DecodeCBP(coded_bp) \
{ \
unsigned int index; \
\
show_bits9(index); \
coded_bp = coded_block_pattern[index].cbp; \
flush_bits(coded_block_pattern[index].num_bits); \
}

53
smpeg/src/video/dither.h Normal file
View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
extern int LUM_RANGE;
extern int CR_RANGE;
extern int CB_RANGE;
#define CB_BASE 1
#define CR_BASE (CB_BASE*CB_RANGE)
#define LUM_BASE (CR_BASE*CR_RANGE)
extern unsigned char pixel[256];
extern unsigned long wpixel[256];
extern int *lum_values;
extern int *cr_values;
extern int *cb_values;
#define Min(x,y) (((x) < (y)) ? (x) : (y))
#define Max(x,y) (((x) > (y)) ? (x) : (y))
#define GAMMA_CORRECTION(x) ((int)(pow((x) / 255.0, 1.0 / gammaCorrect) * 255.0))
#define CHROMA_CORRECTION256(x) ((x) >= 128 \
? 128 + Min(127, (int)(((x) - 128.0) * chromaCorrect)) \
: 128 - Min(128, (int)((128.0 - (x)) * chromaCorrect)))
#define CHROMA_CORRECTION128(x) ((x) >= 0 \
? Min(127, (int)(((x) * chromaCorrect))) \
: Max(-128, (int)(((x) * chromaCorrect))))
#define CHROMA_CORRECTION256D(x) ((x) >= 128 \
? 128.0 + Min(127.0, (((x) - 128.0) * chromaCorrect)) \
: 128.0 - Min(128.0, (((128.0 - (x)) * chromaCorrect))))
#define CHROMA_CORRECTION128D(x) ((x) >= 0 \
? Min(127.0, ((x) * chromaCorrect)) \
: Max(-128.0, ((x) * chromaCorrect)))

View file

@ -0,0 +1,121 @@
/* idctref.c, Inverse Discrete Fourier Transform, double precision */
/* Copyright (C) 1994, MPEG Software Simulation Group. All Rights Reserved. */
/*
* Disclaimer of Warranty
*
* These software programs are available to the user without any license fee or
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
* any and all warranties, whether express, implied, or statuary, including any
* implied warranties or merchantability or of fitness for a particular
* purpose. In no event shall the copyright-holder be liable for any
* incidental, punitive, or consequential damages of any kind whatsoever
* arising from the use of these programs.
*
* This disclaimer of warranty extends to the user of these programs and user's
* customers, employees, agents, transferees, successors, and assigns.
*
* The MPEG Software Simulation Group does not represent or warrant that the
* programs furnished hereunder are free of infringement of any third-party
* patents.
*
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
* are subject to royalty fees to patent holders. Many of these patents are
* general enough such that they are unavoidable regardless of implementation
* design.
*
*/
/* Perform IEEE 1180 reference (64-bit floating point, separable 8x1
* direct matrix multiply) Inverse Discrete Cosine Transform
*/
/* Here we use math.h to generate constants. Compiler results may
vary a little */
#include <math.h>
#ifndef __STDC__
#define _ANSI_ARGS_(x) ()
#else
#define _ANSI_ARGS_(x) x
#endif
#define RB "rb"
#define WB "wb"
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef PI
# ifdef M_PI
# define PI M_PI
# else
# define PI 3.14159265358979323846
# endif
#endif
/* global declarations */
void init_float_idct _ANSI_ARGS_((void));
void float_idct _ANSI_ARGS_((short *block));
/* private data */
/* cosine transform matrix for 8x1 IDCT */
static double c[8][8];
/* initialize DCT coefficient matrix */
void init_float_idct()
{
int freq, time;
double scale;
for (freq=0; freq < 8; freq++)
{
scale = (freq == 0) ? sqrt(0.125) : 0.5;
for (time=0; time<8; time++)
c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5));
}
}
/* perform IDCT matrix multiply for 8x8 coefficient block */
void float_idct( short* block )
{
int i, j, k, v;
double partial_product;
double tmp[64];
for (i=0; i<8; i++)
for (j=0; j<8; j++)
{
partial_product = 0.0;
for (k=0; k<8; k++)
partial_product+= c[k][j]*block[8*i+k];
tmp[8*i+j] = partial_product;
}
/* Transpose operation is integrated into address mapping by switching
loop order of i and j */
for (j=0; j<8; j++)
for (i=0; i<8; i++)
{
partial_product = 0.0;
for (k=0; k<8; k++)
partial_product+= c[k][i]*tmp[8*k+j];
v = (int) floor( partial_product + 0.5 );
block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v);
}
}
/* EOF */

424
smpeg/src/video/gdith.cpp Normal file
View file

@ -0,0 +1,424 @@
/*
* gdith.c --
*
* Procedures dealing with grey-scale and mono dithering,
* as well as X Windows set up procedures.
*
*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include <math.h>
#include "video.h"
#include "proto.h"
#include "dither.h"
#include "SDL_timer.h"
#ifdef USE_ATI
#include "vhar128.h"
#endif
#ifdef __STDC__
#include <stdlib.h>
#include <string.h>
#endif
/*
Changes to make the code reentrant:
X variables now passed in xinfo: display, ximage,cmap,window, gc, etc
De-globalized: ditherType, matched_depth, totNumFrames
vid_stream->film_has_ended instead of FilmState
Additional changes:
Now can name and position each movie window individually
DISABLE_DITHER cpp define - do not include dither code if defined
NOFRAMECOUNT cpp define - do not count frames when running without
controls
Short circuit InitColorDisplay if not displaying anything
ExistingWindow default now 0
-lsh@cs.brown.edu (Loring Holden)
*/
/* Frame Rate Info */
extern int framerate;
/* Video rates table */
/* Cheat on Vid rates, round to 30, and use 30 if illegal value
Except for 9, where Xing means 15, and given their popularity, we'll
be nice and do it */
static double VidRateNum[16]={ 30, 23.97, 24, 25, 29.97, 30, 50, 59.94,
60, 15, 30, 30, 30, 15, 30, 30 };
#ifdef CALCULATE_FPS
static inline void TimestampFPS( VidStream* vid_stream )
{
MPEGvideo* mpeg = (MPEGvideo*) vid_stream->_smpeg;
vid_stream->frame_time[vid_stream->timestamp_index] = mpeg->Time();
++vid_stream->timestamp_index;
if ( vid_stream->timestamp_index == FPS_WINDOW ) {
vid_stream->timestamp_index = 0;
}
}
#endif
/*
Do frame rate control. Returns _skipFrame
*/
#define LOOSE_MPEG_SCHEDULING
#ifdef LOOSE_MPEG_SCHEDULING
#define MAX_FRAME_SKIP 4
#define MAX_FUDGE_TIME (MAX_FRAME_SKIP*vid_stream->_oneFrameTime)
#else
#ifdef TIGHT_MPEG_SCHEDULING
#define MAX_FRAME_SKIP 1
#define MAX_FUDGE_TIME (MAX_FRAME_SKIP*vid_stream->_oneFrameTime)
#else
#define MAX_FRAME_SKIP 3
#define MAX_FUDGE_TIME (MAX_FRAME_SKIP*vid_stream->_oneFrameTime)
#endif /* TIGHT_MPEG_SCHEDULING */
#endif /* LOOSE_MPEG_SCHEDULING */
#define FUDGE_TIME (((MAX_FRAME_SKIP+1)/2)*vid_stream->_oneFrameTime)
/* This results in smoother framerate, but more dropped frames on
systems that can play most of the video fine, but have problems
with jerkiness in a few spots.
*/
//#define SLOW_START_SCHEDULING
#define SLOW_START_INCREMENT 0.3
/* Define this to debug the frame scheduler */
//#define DEBUG_MPEG_SCHEDULING
inline double CurrentTime( VidStream* vid_stream )
{
MPEGvideo* mpeg = (MPEGvideo*) vid_stream->_smpeg;
double now;
if ( mpeg->TimeSource() ) {
now = mpeg->TimeSource()->Time();
} else {
now = ReadSysClock() - vid_stream->realTimeStart;
}
return now;
}
int MPEGvideo::timeSync( VidStream* vid_stream )
{
static double correction = -1;
/* Update the number of frames displayed */
vid_stream->totNumFrames++;
vid_stream->current_frame++;
/* Do we need to initialize framerate? */
if ( vid_stream->rate_deal < 0 ) {
switch( framerate ) {
case -1: /* Go with stream Value */
vid_stream->rate_deal = VidRateNum[ vid_stream->picture_rate ];
break;
case 0: /* as fast as possible */
vid_stream->rate_deal = 0;
break;
default:
vid_stream->rate_deal = framerate;
break;
}
if ( vid_stream->rate_deal ) {
vid_stream->_oneFrameTime = 1.0 / vid_stream->rate_deal;
}
}
/* Update the current play time */
play_time += vid_stream->_oneFrameTime;
/* Synchronize using system timestamps */
if(vid_stream->current && vid_stream->current->show_time > 0){
#ifdef DEBUG_TIMESTAMP_SYNC
fprintf(stderr, "video: time:%.3f shift:%.3f\r",
play_time,
play_time - vid_stream->current->show_time);
#endif
if(correction == -1)
#ifdef STRANGE_SYNC_TEST
/* this forces us to maintain the offset we have at the begining
all the time, and is only usefull for testing */
correction = play_time - vid_stream->current->show_time;
#else
correction = 0;
#endif
#ifdef USE_TIMESTAMP_SYNC
play_time = vid_stream->current->show_time + correction ;
#endif
vid_stream->current->show_time = -1;
}
/* If we are looking for a particular frame... */
if( vid_stream->_jumpFrame > -1 )
{
if ( vid_stream->totNumFrames != vid_stream->_jumpFrame ) {
vid_stream->_skipFrame = 1;
} else {
vid_stream->_skipFrame = 0;
}
return vid_stream->_skipFrame;
}
/* If we're already behind, don't check timing */
if ( vid_stream->_skipFrame > 0 )
{
return --vid_stream->_skipFrame;
}
/* See if we need to skip frames, based on timing */
if ( vid_stream->rate_deal ) {
static const double TIMESLICE = 0.01; // Seconds per OS timeslice
double time_behind;
/* Calculate the frame time relative to real time */
time_behind = CurrentTime(vid_stream) - Time();
#ifdef DEBUG_MPEG_SCHEDULING
printf("Frame %d: frame time: %f, real time: %f, time behind: %f\n", vid_stream->totNumFrames, Time(), CurrentTime(vid_stream), time_behind);
#endif
/* Allow up to MAX_FUDGE_TIME of delay in output */
if ( time_behind < -TIMESLICE ) {
time_behind = -time_behind;
vid_stream->_skipCount = 0;
#ifdef DEBUG_MPEG_SCHEDULING
printf("Ahead! Sleeping %f\n", time_behind-TIMESLICE);
#endif
SDL_Delay((Uint32)((time_behind-TIMESLICE)*1000));
} else
if ( time_behind < FUDGE_TIME ) {
if ( vid_stream->_skipCount > 0 ) {
vid_stream->_skipCount /= 2;
}
#ifdef DEBUG_MPEG_SCHEDULING
printf("Just right.\n");
#endif
} else
if ( time_behind < MAX_FUDGE_TIME ) {
if ( vid_stream->_skipCount > 0 ) {
vid_stream->_skipCount--;
}
vid_stream->_skipFrame = 1+(int)(vid_stream->_skipCount/2);
#ifdef DEBUG_MPEG_SCHEDULING
printf("A little behind, skipping %d frames\n", vid_stream->_skipFrame);
#endif
} else {
/* time_behind >= MAX_FUDGE_TIME */
if ( (time_behind > (MAX_FUDGE_TIME*2)) &&
(vid_stream->_skipCount == MAX_FRAME_SKIP) ) {
#ifdef DEBUG_MPEG_SCHEDULING
printf("Way too far behind, losing time sync...\n");
#endif
#if 0 // This results in smoother video, but sync's terribly on slow machines
play_time = CurrentTime(vid_stream) - (MAX_FUDGE_TIME*2);
#endif
}
#ifdef SLOW_START_SCHEDULING
vid_stream->_skipCount += SLOW_START_INCREMENT;
#else
vid_stream->_skipCount += 1.0;
#endif
if( vid_stream->_skipCount > MAX_FRAME_SKIP ) {
vid_stream->_skipCount = MAX_FRAME_SKIP;
}
vid_stream->_skipFrame = (int)(vid_stream->_skipCount+0.9);
#ifdef DEBUG_MPEG_SCHEDULING
printf("A lot behind, skipping %d frames\n", vid_stream->_skipFrame);
#endif
}
}
return(vid_stream->_skipFrame);
}
/* Do the hard work of copying from the video stream working buffer to the
screen display and then calling the update callback.
*/
void MPEGvideo::DisplayFrame( VidStream * vid_stream )
{
SMPEG_FilterInfo info;
if ( !_image ) {
return;
}
if ( _filter_mutex )
SDL_mutexP( _filter_mutex );
/* Get a pointer to _image pixels */
if ( SDL_LockYUVOverlay( _image ) ) {
return;
}
/* Compute additionnal info for the filter */
if((_filter->flags & SMPEG_FILTER_INFO_PIXEL_ERROR) && vid_stream->current->mb_qscale)
{
register int x, y;
register Uint16 * ptr;
/* Compute quantization error for each pixel */
info.yuv_pixel_square_error = (Uint16 *) malloc(_w*_h*12/8*sizeof(Uint16));
ptr = info.yuv_pixel_square_error;
for(y = 0; y < _h; y++)
for(x = 0; x < _w; x++)
*ptr++ = (Uint16) (((Uint32) vid_stream->noise_base_matrix[x & 7][y & 7] *
vid_stream->current->mb_qscale[((y>>4) * (_w>>4)) + (x >> 4)]) >> 8);
}
if((_filter->flags & SMPEG_FILTER_INFO_MB_ERROR) && vid_stream->current->mb_qscale)
{
/* Retreive macroblock quantization error info */
info.yuv_mb_square_error = (Uint16 *)vid_stream->current->mb_qscale;
}
if( _filter )
{
SDL_Overlay src;
Uint16 pitches[3];
Uint8 *pixels[3];
/* Fill in an SDL YV12 overlay structure for the source */
#ifdef USE_ATI
vhar128_lockimage(vid_stream->ati_handle, vid_stream->current->image, &src);
#else
src.format = SDL_YV12_OVERLAY;
src.w = _w;
src.h = _h;
src.planes = 3;
pitches[0] = _w;
pitches[1] = _w / 2;
pitches[2] = _w / 2;
src.pitches = pitches;
pixels[0] = (Uint8 *)vid_stream->current->image;
pixels[1] = (Uint8 *)vid_stream->current->image + pitches[0] * _h;
pixels[2] = (Uint8 *)vid_stream->current->image + pitches[0] * _h +
pitches[1] * _h / 2;
src.pixels = pixels;
#endif
_filter->callback(_image, &src, &_srcrect, &info, _filter->data );
#ifdef USE_ATI
vhar128_unlockimage(vid_stream->ati_handle, vid_stream->current->image, &src);
#endif
}
/* Now display the image */
if ( _mutex )
SDL_mutexP( _mutex );
SDL_DisplayYUVOverlay(_image, &_dstrect);
if ( _callback )
_callback(_dst, _dstrect.x, _dstrect.y, _dstrect.w, _dstrect.h);
SDL_UnlockYUVOverlay( _image );
if( _filter )
{
if( _filter->flags & SMPEG_FILTER_INFO_PIXEL_ERROR )
free(info.yuv_pixel_square_error);
}
if ( _filter_mutex )
SDL_mutexV( _filter_mutex );
if ( _mutex )
SDL_mutexV( _mutex );
}
/*
*--------------------------------------------------------------
*
* ExecuteDisplay --
*
* Actually displays display plane in previously created window.
*
* Results:
* None.
*
* Side effects:
* Updates video frame timing control
*
*--------------------------------------------------------------
*/
void MPEGvideo::ExecuteDisplay( VidStream* vid_stream )
{
if( ! vid_stream->_skipFrame )
{
DisplayFrame(vid_stream);
#ifdef CALCULATE_FPS
TimestampFPS(vid_stream);
#endif
}
timeSync( vid_stream );
}
SMPEG_Filter *
MPEGvideo:: Filter(SMPEG_Filter * filter)
{
SMPEG_Filter * old_filter;
old_filter = _filter;
if ( _filter_mutex )
SDL_mutexP( _filter_mutex );
_filter = filter;
if ( _filter_mutex )
SDL_mutexV( _filter_mutex );
return(old_filter);
}
/* EOF */

1617
smpeg/src/video/jrevdct.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
#if defined(i386) && defined(USE_MMX)
.text
.align 4
.globl cpu_flags
.type cpu_flags,@function
cpu_flags:
pushfl
popl %eax
movl %eax,%ecx
xorl $0x040000,%eax
pushl %eax
popfl
pushfl
popl %eax
xorl %ecx,%eax
jz cpu_flags.L1 # Processor is 386
pushl %ecx
popfl
movl %ecx,%eax
xorl $0x200000,%eax
pushl %eax
popfl
pushfl
popl %eax
xorl %ecx,%eax
je cpu_flags.L1
pushl %ebx
movl $1,%eax
cpuid
movl %edx,%eax
popl %ebx
cpu_flags.L1:
ret
.Lfe1:
.size cpu_flags,.Lfe1-cpu_flags
#endif /* i386 && USE_MMX */
#ifdef __ELF__
.section .note.GNU-stack,"",%progbits
#endif

View file

@ -0,0 +1,697 @@
#if defined(i386) && defined(USE_MMX)
/*
* the input data is tranposed and each 16 bit element in the 8x8 matrix
* is left aligned:
* for example in 11...1110000 format
* If the iDCT is of I macroblock then 0.5 needs to be added to the;DC Component
* (element[0][0] of the matrix)
*/
/* extrn re_matrix */
.data
.align 16
.type preSC,@object
preSC: .short 16384,22725,21407,19266,16384,12873,8867,4520
.short 22725,31521,29692,26722,22725,17855,12299,6270
.short 21407,29692,27969,25172,21407,16819,11585,5906
.short 19266,26722,25172,22654,19266,15137,10426,5315
.short 16384,22725,21407,19266,16384,12873,8867,4520
.short 12873,17855,16819,15137,25746,20228,13933,7103
.short 17734,24598,23170,20853,17734,13933,9597,4892
.short 18081,25080,23624,21261,18081,14206,9785,4988
.size preSC,128
.align 8
.type x0005000200010001,@object
.size x0005000200010001,8
x0005000200010001:
.long 0x00010001,0x00050002
.align 8
.type x5a825a825a825a82,@object
.size x5a825a825a825a82,8
x5a825a825a825a82:
.long 0x5a825a82, 0x5a825a82
.align 8
.type x539f539f539f539f,@object
.size x539f539f539f539f,8
x539f539f539f539f:
.long 0x539f539f,0x539f539f
.align 8
.type x4546454645464546,@object
.size x4546454645464546,8
x4546454645464546:
.long 0x45464546,0x45464546
.align 8
.type x61f861f861f861f8,@object
.size x61f861f861f861f8,8
x61f861f861f861f8:
.long 0x61f861f8,0x61f861f8
.align 8
.type scratch1,@object
.size scratch1,8
scratch1:
.long 0,0
.align 8
.type scratch3,@object
.size scratch3,8
scratch3:
.long 0,0
.align 8
.type scratch5,@object
.size scratch5,8
scratch5:
.long 0,0
.align 8
.type scratch7,@object
.size scratch7,8
scratch7:
.long 0,0
.type x0,@object
.size x0,8
x0:
.long 0,0
.align 8
.text
.align 4
#ifdef __PIC__
# undef __i686 /* gcc define gets in our way */
# define MUNG(sym) sym ## @GOTOFF(%ebx)
# define INIT_PIC() \
call __i686.get_pc_thunk.bx ; \
addl $_GLOBAL_OFFSET_TABLE_, %ebx
#else
# define MUNG(sym) sym
# define INIT_PIC()
#endif
.globl IDCT_mmx
.type IDCT_mmx,@function
IDCT_mmx:
pushl %ebp
movl %esp,%ebp
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
INIT_PIC()
movl 8(%ebp),%esi /* source matrix */
leal MUNG(preSC), %ecx
/* column 0: even part
* use V4, V12, V0, V8 to produce V22..V25
*/
movq 8*12(%ecx), %mm0 /* maybe the first mul can be done together */
/* with the dequantization in iHuff module */
pmulhw 8*12(%esi), %mm0 /* V12 */
movq 8*4(%ecx), %mm1
pmulhw 8*4(%esi), %mm1 /* V4 */
movq (%ecx), %mm3
psraw $1, %mm0 /* t64=t66 */
pmulhw (%esi), %mm3 /* V0 */
movq 8*8(%ecx), %mm5 /* duplicate V4 */
movq %mm1, %mm2 /* added 11/1/96 */
pmulhw 8*8(%esi),%mm5 /* V8 */
psubsw %mm0, %mm1 /* V16 */
pmulhw MUNG(x5a825a825a825a82), %mm1 /* 23170 ->V18 */
paddsw %mm0, %mm2 /* V17 */
movq %mm2, %mm0 /* duplicate V17 */
psraw $1, %mm2 /* t75=t82 */
psraw $2, %mm0 /* t72 */
movq %mm3, %mm4 /* duplicate V0 */
paddsw %mm5, %mm3 /* V19 */
psubsw %mm5, %mm4 /* V20 ;mm5 free */
/* moved from the block below */
movq 8*10(%ecx), %mm7
psraw $1, %mm3 /* t74=t81 */
movq %mm3, %mm6 /* duplicate t74=t81 */
psraw $2, %mm4 /* t77=t79 */
psubsw %mm0, %mm1 /* V21 ; mm0 free */
paddsw %mm2, %mm3 /* V22 */
movq %mm1, %mm5 /* duplicate V21 */
paddsw %mm4, %mm1 /* V23 */
movq %mm3, 8*4(%esi) /* V22 */
psubsw %mm5, %mm4 /* V24; mm5 free */
movq %mm1, 8*12(%esi) /* V23 */
psubsw %mm2, %mm6 /* V25; mm2 free */
movq %mm4, (%esi) /* V24 */
/* keep mm6 alive all along the next block */
/* movq %mm6, 8*8(%esi) V25 */
/* column 0: odd part
* use V2, V6, V10, V14 to produce V31, V39, V40, V41
*/
/* moved above: movq 8*10(%ecx), %mm7 */
pmulhw 8*10(%esi), %mm7 /* V10 */
movq 8*6(%ecx), %mm0
pmulhw 8*6(%esi), %mm0 /* V6 */
movq 8*2(%ecx), %mm5
movq %mm7, %mm3 /* duplicate V10 */
pmulhw 8*2(%esi), %mm5 /* V2 */
movq 8*14(%ecx), %mm4
psubsw %mm0, %mm7 /* V26 */
pmulhw 8*14(%esi), %mm4 /* V14 */
paddsw %mm0, %mm3 /* V29 ; free mm0 */
movq %mm7, %mm1 /* duplicate V26 */
psraw $1, %mm3 /* t91=t94 */
pmulhw MUNG(x539f539f539f539f),%mm7 /* V33 */
psraw $1, %mm1 /* t96 */
movq %mm5, %mm0 /* duplicate V2 */
psraw $2, %mm4 /* t85=t87 */
paddsw %mm4,%mm5 /* V27 */
psubsw %mm4, %mm0 /* V28 ; free mm4 */
movq %mm0, %mm2 /* duplicate V28 */
psraw $1, %mm5 /* t90=t93 */
pmulhw MUNG(x4546454645464546),%mm0 /* V35 */
psraw $1, %mm2 /* t97 */
movq %mm5, %mm4 /* duplicate t90=t93 */
psubsw %mm2, %mm1 /* V32 ; free mm2 */
pmulhw MUNG(x61f861f861f861f8),%mm1 /* V36 */
psllw $1, %mm7 /* t107 */
paddsw %mm3, %mm5 /* V31 */
psubsw %mm3, %mm4 /* V30 ; free mm3 */
pmulhw MUNG(x5a825a825a825a82),%mm4 /* V34 */
nop
psubsw %mm1, %mm0 /* V38 */
psubsw %mm7, %mm1 /* V37 ; free mm7 */
psllw $1, %mm1 /* t114 */
/* move from the next block */
movq %mm6, %mm3 /* duplicate V25 */
/* move from the next block */
movq 8*4(%esi), %mm7 /* V22 */
psllw $1, %mm0 /* t110 */
psubsw %mm5, %mm0 /* V39 (mm5 needed for next block) */
psllw $2, %mm4 /* t112 */
/* moved from the next block */
movq 8*12(%esi), %mm2 /* V23 */
psubsw %mm0, %mm4 /* V40 */
paddsw %mm4, %mm1 /* V41; free mm0 */
/* moved from the next block */
psllw $1, %mm2 /* t117=t125 */
/* column 0: output butterfly */
/* moved above:
* movq %mm6, %mm3 duplicate V25
* movq 8*4(%esi), %mm7 V22
* movq 8*12(%esi), %mm2 V23
* psllw $1, %mm2 t117=t125
*/
psubsw %mm1, %mm6 /* tm6 */
paddsw %mm1, %mm3 /* tm8; free mm1 */
movq %mm7, %mm1 /* duplicate V22 */
paddsw %mm5, %mm7 /* tm0 */
movq %mm3, 8*8(%esi) /* tm8; free mm3 */
psubsw %mm5, %mm1 /* tm14; free mm5 */
movq %mm6, 8*6(%esi) /* tm6; free mm6 */
movq %mm2, %mm3 /* duplicate t117=t125 */
movq (%esi), %mm6 /* V24 */
paddsw %mm0, %mm2 /* tm2 */
movq %mm7, (%esi) /* tm0; free mm7 */
psubsw %mm0, %mm3 /* tm12; free mm0 */
movq %mm1, 8*14(%esi) /* tm14; free mm1 */
psllw $1, %mm6 /* t119=t123 */
movq %mm2, 8*2(%esi) /* tm2; free mm2 */
movq %mm6, %mm0 /* duplicate t119=t123 */
movq %mm3, 8*12(%esi) /* tm12; free mm3 */
paddsw %mm4, %mm6 /* tm4 */
/* moved from next block */
movq 8*5(%ecx), %mm1
psubsw %mm4, %mm0 /* tm10; free mm4 */
/* moved from next block */
pmulhw 8*5(%esi), %mm1 /* V5 */
movq %mm6, 8*4(%esi) /* tm4; free mm6 */
movq %mm0, 8*10(%esi) /* tm10; free mm0 */
/* column 1: even part
* use V5, V13, V1, V9 to produce V56..V59
*/
/* moved to prev block:
* movq 8*5(%ecx), %mm1
* pmulhw 8*5(%esi), %mm1 V5
*/
movq 8*13(%ecx), %mm7
psllw $1, %mm1 /* t128=t130 */
pmulhw 8*13(%esi), %mm7 /* V13 */
movq %mm1, %mm2 /* duplicate t128=t130 */
movq 8(%ecx), %mm3
pmulhw 8(%esi), %mm3 /* V1 */
movq 8*9(%ecx), %mm5
psubsw %mm7, %mm1 /* V50 */
pmulhw 8*9(%esi), %mm5 /* V9 */
paddsw %mm7, %mm2 /* V51 */
pmulhw MUNG(x5a825a825a825a82), %mm1 /* 23170 ->V52 */
movq %mm2, %mm6 /* duplicate V51 */
psraw $1, %mm2 /* t138=t144 */
movq %mm3, %mm4 /* duplicate V1 */
psraw $2, %mm6 /* t136 */
paddsw %mm5, %mm3 /* V53 */
psubsw %mm5, %mm4 /* V54 ;mm5 free */
movq %mm3, %mm7 /* duplicate V53 */
/* moved from next block */
movq 8*11(%ecx), %mm0
psraw $1, %mm4 /* t140=t142 */
psubsw %mm6, %mm1 /* V55 ; mm6 free */
paddsw %mm2, %mm3 /* V56 */
movq %mm4, %mm5 /* duplicate t140=t142 */
paddsw %mm1, %mm4 /* V57 */
movq %mm3, 8*5(%esi) /* V56 */
psubsw %mm1, %mm5 /* V58; mm1 free */
movq %mm4, 8*13(%esi) /* V57 */
psubsw %mm2, %mm7 /* V59; mm2 free */
movq %mm5, 8*9(%esi) /* V58 */
/* keep mm7 alive all along the next block
* movq %mm7, 8(%esi) V59
* moved above
* movq 8*11(%ecx), %mm0
*/
pmulhw 8*11(%esi), %mm0 /* V11 */
movq 8*7(%ecx), %mm6
pmulhw 8*7(%esi), %mm6 /* V7 */
movq 8*15(%ecx), %mm4
movq %mm0, %mm3 /* duplicate V11 */
pmulhw 8*15(%esi), %mm4 /* V15 */
movq 8*3(%ecx), %mm5
psllw $1, %mm6 /* t146=t152 */
pmulhw 8*3(%esi), %mm5 /* V3 */
paddsw %mm6, %mm0 /* V63 */
/* note that V15 computation has a correction step:
* this is a 'magic' constant that rebiases the results to be closer to the
* expected result. this magic constant can be refined to reduce the error
* even more by doing the correction step in a later stage when the number
* is actually multiplied by 16
*/
paddw MUNG(x0005000200010001), %mm4
psubsw %mm6, %mm3 /* V60 ; free mm6 */
psraw $1, %mm0 /* t154=t156 */
movq %mm3, %mm1 /* duplicate V60 */
pmulhw MUNG(x539f539f539f539f), %mm1 /* V67 */
movq %mm5, %mm6 /* duplicate V3 */
psraw $2, %mm4 /* t148=t150 */
paddsw %mm4, %mm5 /* V61 */
psubsw %mm4, %mm6 /* V62 ; free mm4 */
movq %mm5, %mm4 /* duplicate V61 */
psllw $1, %mm1 /* t169 */
paddsw %mm0, %mm5 /* V65 -> result */
psubsw %mm0, %mm4 /* V64 ; free mm0 */
pmulhw MUNG(x5a825a825a825a82), %mm4 /* V68 */
psraw $1, %mm3 /* t158 */
psubsw %mm6, %mm3 /* V66 */
movq %mm5, %mm2 /* duplicate V65 */
pmulhw MUNG(x61f861f861f861f8), %mm3 /* V70 */
psllw $1, %mm6 /* t165 */
pmulhw MUNG(x4546454645464546), %mm6 /* V69 */
psraw $1, %mm2 /* t172 */
/* moved from next block */
movq 8*5(%esi), %mm0 /* V56 */
psllw $1, %mm4 /* t174 */
/* moved from next block */
psraw $1, %mm0 /* t177=t188 */
nop
psubsw %mm3, %mm6 /* V72 */
psubsw %mm1, %mm3 /* V71 ; free mm1 */
psubsw %mm2, %mm6 /* V73 ; free mm2 */
/* moved from next block */
psraw $1, %mm5 /* t178=t189 */
psubsw %mm6, %mm4 /* V74 */
/* moved from next block */
movq %mm0, %mm1 /* duplicate t177=t188 */
paddsw %mm4, %mm3 /* V75 */
/* moved from next block */
paddsw %mm5, %mm0 /* tm1 */
/* location
* 5 - V56
* 13 - V57
* 9 - V58
* X - V59, mm7
* X - V65, mm5
* X - V73, mm6
* X - V74, mm4
* X - V75, mm3
* free mm0, mm1 & mm2
* moved above
* movq 8*5(%esi), %mm0 V56
* psllw $1, %mm0 t177=t188 ! new !!
* psllw $1, %mm5 t178=t189 ! new !!
* movq %mm0, %mm1 duplicate t177=t188
* paddsw %mm5, %mm0 tm1
*/
movq 8*13(%esi), %mm2 /* V57 */
psubsw %mm5, %mm1 /* tm15; free mm5 */
movq %mm0, 8(%esi) /* tm1; free mm0 */
psraw $1, %mm7 /* t182=t184 ! new !! */
/* save the store as used directly in the transpose
* movq %mm1, 120(%esi) tm15; free mm1
*/
movq %mm7, %mm5 /* duplicate t182=t184 */
psubsw %mm3, %mm7 /* tm7 */
paddsw %mm3, %mm5 /* tm9; free mm3 */
movq 8*9(%esi), %mm0 /* V58 */
movq %mm2, %mm3 /* duplicate V57 */
movq %mm7, 8*7(%esi) /* tm7; free mm7 */
psubsw %mm6, %mm3 /* tm13 */
paddsw %mm6, %mm2 /* tm3 ; free mm6 */
/* moved up from the transpose */
movq %mm3, %mm7
/* moved up from the transpose */
punpcklwd %mm1, %mm3
movq %mm0, %mm6 /* duplicate V58 */
movq %mm2, 8*3(%esi) /* tm3; free mm2 */
paddsw %mm4, %mm0 /* tm5 */
psubsw %mm4, %mm6 /* tm11; free mm4 */
/* moved up from the transpose */
punpckhwd %mm1, %mm7
movq %mm0, 8*5(%esi) /* tm5; free mm0 */
/* moved up from the transpose */
movq %mm5, %mm2
/* transpose - M4 part
* --------- ---------
* | M1 | M2 | | M1'| M3'|
* --------- --> ---------
* | M3 | M4 | | M2'| M4'|
* --------- ---------
* Two alternatives: use full mmword approach so the following code can be
* scheduled before the transpose is done without stores, or use the faster
* half mmword stores (when possible)
*/
movd %mm3, 8*9+4(%esi) /* MS part of tmt9 */
punpcklwd %mm6, %mm5
movd %mm7, 8*13+4(%esi) /* MS part of tmt13 */
punpckhwd %mm6, %mm2
movd %mm5, 8*9(%esi) /* LS part of tmt9 */
punpckhdq %mm3, %mm5 /* free mm3 */
movd %mm2, 8*13(%esi) /* LS part of tmt13 */
punpckhdq %mm7, %mm2 /* free mm7 */
/* moved up from the M3 transpose */
movq 8*8(%esi), %mm0
/* moved up from the M3 transpose */
movq 8*10(%esi), %mm1
/* moved up from the M3 transpose */
movq %mm0, %mm3
/* shuffle the rest of the data, and write it with 2 mmword writes */
movq %mm5, 8*11(%esi) /* tmt11 */
/* moved up from the M3 transpose */
punpcklwd %mm1, %mm0
movq %mm2, 8*15(%esi) /* tmt15 */
/* moved up from the M3 transpose */
punpckhwd %mm1, %mm3
/* transpose - M3 part
* moved up to previous code section
* movq 8*8(%esi), %mm0
* movq 8*10(%esi), %mm1
* movq %mm0, %mm3
* punpcklwd %mm1, %mm0
* punpckhwd %mm1, %mm3
*/
movq 8*12(%esi), %mm6
movq 8*14(%esi), %mm4
movq %mm6, %mm2
/* shuffle the data and write the lower parts of the transposed in 4 dwords */
punpcklwd %mm4, %mm6
movq %mm0, %mm1
punpckhdq %mm6, %mm1
movq %mm3, %mm7
punpckhwd %mm4, %mm2 /* free mm4 */
punpckldq %mm6, %mm0 /* free mm6 */
/* moved from next block */
movq 8*13(%esi), %mm4 /* tmt13 */
punpckldq %mm2, %mm3
punpckhdq %mm2, %mm7 /* free mm2 */
/* moved from next block */
movq %mm3, %mm5 /* duplicate tmt5 */
/* column 1: even part (after transpose)
* moved above
* movq %mm3, %mm5 duplicate tmt5
* movq 8*13(%esi), %mm4 tmt13
*/
psubsw %mm4, %mm3 /* V134 */
pmulhw MUNG(x5a825a825a825a82), %mm3 /* 23170 ->V136 */
movq 8*9(%esi), %mm6 /* tmt9 */
paddsw %mm4, %mm5 /* V135 ; mm4 free */
movq %mm0, %mm4 /* duplicate tmt1 */
paddsw %mm6, %mm0 /* V137 */
psubsw %mm6, %mm4 /* V138 ; mm6 free */
psllw $2, %mm3 /* t290 */
psubsw %mm5, %mm3 /* V139 */
movq %mm0, %mm6 /* duplicate V137 */
paddsw %mm5, %mm0 /* V140 */
movq %mm4, %mm2 /* duplicate V138 */
paddsw %mm3, %mm2 /* V141 */
psubsw %mm3, %mm4 /* V142 ; mm3 free */
movq %mm0, 8*9(%esi) /* V140 */
psubsw %mm5, %mm6 /* V143 ; mm5 free */
/* moved from next block */
movq 8*11(%esi), %mm0 /* tmt11 */
movq %mm2, 8*13(%esi) /* V141 */
/* moved from next block */
movq %mm0, %mm2 /* duplicate tmt11 */
/* column 1: odd part (after transpose) */
/* moved up to the prev block
* movq 8*11(%esi), %mm0 tmt11
* movq %mm0, %mm2 duplicate tmt11
*/
movq 8*15(%esi), %mm5 /* tmt15 */
psubsw %mm7, %mm0 /* V144 */
movq %mm0, %mm3 /* duplicate V144 */
paddsw %mm7, %mm2 /* V147 ; free mm7 */
pmulhw MUNG(x539f539f539f539f), %mm0 /* 21407-> V151 */
movq %mm1, %mm7 /* duplicate tmt3 */
paddsw %mm5, %mm7 /* V145 */
psubsw %mm5, %mm1 /* V146 ; free mm5 */
psubsw %mm1, %mm3 /* V150 */
movq %mm7, %mm5 /* duplicate V145 */
pmulhw MUNG(x4546454645464546), %mm1 /* 17734-> V153 */
psubsw %mm2, %mm5 /* V148 */
pmulhw MUNG(x61f861f861f861f8), %mm3 /* 25080-> V154 */
psllw $2, %mm0 /* t311 */
pmulhw MUNG(x5a825a825a825a82), %mm5 /* 23170-> V152 */
paddsw %mm2, %mm7 /* V149 ; free mm2 */
psllw $1, %mm1 /* t313 */
nop /* without the nop - freeze here for one clock */
movq %mm3, %mm2 /* duplicate V154 */
psubsw %mm0, %mm3 /* V155 ; free mm0 */
psubsw %mm2, %mm1 /* V156 ; free mm2 */
/* moved from the next block */
movq %mm6, %mm2 /* duplicate V143 */
/* moved from the next block */
movq 8*13(%esi), %mm0 /* V141 */
psllw $1, %mm1 /* t315 */
psubsw %mm7, %mm1 /* V157 (keep V149) */
psllw $2, %mm5 /* t317 */
psubsw %mm1, %mm5 /* V158 */
psllw $1, %mm3 /* t319 */
paddsw %mm5, %mm3 /* V159 */
/* column 1: output butterfly (after transform)
* moved to the prev block
* movq %mm6, %mm2 duplicate V143
* movq 8*13(%esi), %mm0 V141
*/
psubsw %mm3, %mm2 /* V163 */
paddsw %mm3, %mm6 /* V164 ; free mm3 */
movq %mm4, %mm3 /* duplicate V142 */
psubsw %mm5, %mm4 /* V165 ; free mm5 */
movq %mm2, MUNG(scratch7) /* out7 */
psraw $4, %mm6
psraw $4, %mm4
paddsw %mm5, %mm3 /* V162 */
movq 8*9(%esi), %mm2 /* V140 */
movq %mm0, %mm5 /* duplicate V141 */
/* in order not to perculate this line up,
* we read 72(%esi) very near to this location
*/
movq %mm6, 8*9(%esi) /* out9 */
paddsw %mm1, %mm0 /* V161 */
movq %mm3, MUNG(scratch5) /* out5 */
psubsw %mm1, %mm5 /* V166 ; free mm1 */
movq %mm4, 8*11(%esi) /* out11 */
psraw $4, %mm5
movq %mm0, MUNG(scratch3) /* out3 */
movq %mm2, %mm4 /* duplicate V140 */
movq %mm5, 8*13(%esi) /* out13 */
paddsw %mm7, %mm2 /* V160 */
/* moved from the next block */
movq 8(%esi), %mm0
psubsw %mm7, %mm4 /* V167 ; free mm7 */
/* moved from the next block */
movq 8*3(%esi), %mm7
psraw $4, %mm4
movq %mm2, MUNG(scratch1) /* out1 */
/* moved from the next block */
movq %mm0, %mm1
movq %mm4, 8*15(%esi) /* out15 */
/* moved from the next block */
punpcklwd %mm7, %mm0
/* transpose - M2 parts
* moved up to the prev block
* movq 8(%esi), %mm0
* movq 8*3(%esi), %mm7
* movq %mm0, %mm1
* punpcklwd %mm7, %mm0
*/
movq 8*5(%esi), %mm5
punpckhwd %mm7, %mm1
movq 8*7(%esi), %mm4
movq %mm5, %mm3
/* shuffle the data and write the lower parts of the trasposed in 4 dwords */
movd %mm0, 8*8(%esi) /* LS part of tmt8 */
punpcklwd %mm4, %mm5
movd %mm1, 8*12(%esi) /* LS part of tmt12 */
punpckhwd %mm4, %mm3
movd %mm5, 8*8+4(%esi) /* MS part of tmt8 */
punpckhdq %mm5, %mm0 /* tmt10 */
movd %mm3, 8*12+4(%esi) /* MS part of tmt12 */
punpckhdq %mm3, %mm1 /* tmt14 */
/* transpose - M1 parts */
movq (%esi), %mm7
movq 8*2(%esi), %mm2
movq %mm7, %mm6
movq 8*4(%esi), %mm5
punpcklwd %mm2, %mm7
movq 8*6(%esi), %mm4
punpckhwd %mm2, %mm6 /* free mm2 */
movq %mm5, %mm3
punpcklwd %mm4, %mm5
punpckhwd %mm4, %mm3 /* free mm4 */
movq %mm7, %mm2
movq %mm6, %mm4
punpckldq %mm5, %mm7 /* tmt0 */
punpckhdq %mm5, %mm2 /* tmt2 ; free mm5 */
/* shuffle the rest of the data, and write it with 2 mmword writes */
punpckldq %mm3, %mm6 /* tmt4 */
/* moved from next block */
movq %mm2, %mm5 /* duplicate tmt2 */
punpckhdq %mm3, %mm4 /* tmt6 ; free mm3 */
/* moved from next block */
movq %mm0, %mm3 /* duplicate tmt10 */
/* column 0: odd part (after transpose)
*moved up to prev block
* movq %mm0, %mm3 duplicate tmt10
* movq %mm2, %mm5 duplicate tmt2
*/
psubsw %mm4, %mm0 /* V110 */
paddsw %mm4, %mm3 /* V113 ; free mm4 */
movq %mm0, %mm4 /* duplicate V110 */
paddsw %mm1, %mm2 /* V111 */
pmulhw MUNG(x539f539f539f539f), %mm0 /* 21407-> V117 */
psubsw %mm1, %mm5 /* V112 ; free mm1 */
psubsw %mm5, %mm4 /* V116 */
movq %mm2, %mm1 /* duplicate V111 */
pmulhw MUNG(x4546454645464546), %mm5 /* 17734-> V119 */
psubsw %mm3, %mm2 /* V114 */
pmulhw MUNG(x61f861f861f861f8), %mm4 /* 25080-> V120 */
paddsw %mm3, %mm1 /* V115 ; free mm3 */
pmulhw MUNG(x5a825a825a825a82), %mm2 /* 23170-> V118 */
psllw $2, %mm0 /* t266 */
movq %mm1, (%esi) /* save V115 */
psllw $1, %mm5 /* t268 */
psubsw %mm4, %mm5 /* V122 */
psubsw %mm0, %mm4 /* V121 ; free mm0 */
psllw $1, %mm5 /* t270 */
psubsw %mm1, %mm5 /* V123 ; free mm1 */
psllw $2, %mm2 /* t272 */
psubsw %mm5, %mm2 /* V124 (keep V123) */
psllw $1, %mm4 /* t274 */
movq %mm5, 8*2(%esi) /* save V123 ; free mm5 */
paddsw %mm2, %mm4 /* V125 (keep V124) */
/* column 0: even part (after transpose) */
movq 8*12(%esi), %mm0 /* tmt12 */
movq %mm6, %mm3 /* duplicate tmt4 */
psubsw %mm0, %mm6 /* V100 */
paddsw %mm0, %mm3 /* V101 ; free mm0 */
pmulhw MUNG(x5a825a825a825a82), %mm6 /* 23170 ->V102 */
movq %mm7, %mm5 /* duplicate tmt0 */
movq 8*8(%esi), %mm1 /* tmt8 */
paddsw %mm1, %mm7 /* V103 */
psubsw %mm1, %mm5 /* V104 ; free mm1 */
movq %mm7, %mm0 /* duplicate V103 */
psllw $2, %mm6 /* t245 */
paddsw %mm3, %mm7 /* V106 */
movq %mm5, %mm1 /* duplicate V104 */
psubsw %mm3, %mm6 /* V105 */
psubsw %mm3, %mm0 /* V109; free mm3 */
paddsw %mm6, %mm5 /* V107 */
psubsw %mm6, %mm1 /* V108 ; free mm6 */
/* column 0: output butterfly (after transform) */
movq %mm1, %mm3 /* duplicate V108 */
paddsw %mm2, %mm1 /* out4 */
psraw $4, %mm1
psubsw %mm2, %mm3 /* out10 ; free mm2 */
psraw $4, %mm3
movq %mm0, %mm6 /* duplicate V109 */
movq %mm1, 8*4(%esi) /* out4 ; free mm1 */
psubsw %mm4, %mm0 /* out6 */
movq %mm3, 8*10(%esi) /* out10 ; free mm3 */
psraw $4, %mm0
paddsw %mm4, %mm6 /* out8 ; free mm4 */
movq %mm7, %mm1 /* duplicate V106 */
movq %mm0, 8*6(%esi) /* out6 ; free mm0 */
psraw $4, %mm6
movq (%esi), %mm4 /* V115 */
movq %mm6, 8*8(%esi) /* out8 ; free mm6 */
movq %mm5, %mm2 /* duplicate V107 */
movq 8*2(%esi), %mm3 /* V123 */
paddsw %mm4, %mm7 /* out0 */
/* moved up from next block */
movq MUNG(scratch3), %mm0
psraw $4, %mm7
/* moved up from next block */
movq MUNG(scratch5), %mm6
psubsw %mm4, %mm1 /* out14 ; free mm4 */
paddsw %mm3, %mm5 /* out2 */
psraw $4, %mm1
movq %mm7, (%esi) /* out0 ; free mm7 */
psraw $4, %mm5
movq %mm1, 8*14(%esi) /* out14 ; free mm1 */
psubsw %mm3, %mm2 /* out12 ; free mm3 */
movq %mm5, 8*2(%esi) /* out2 ; free mm5 */
psraw $4, %mm2
/* moved up to the prev block */
movq MUNG(scratch7), %mm4
/* moved up to the prev block */
psraw $4, %mm0
movq %mm2, 8*12(%esi) /* out12 ; free mm2 */
/* moved up to the prev block */
psraw $4, %mm6
/* move back the data to its correct place
* moved up to the prev block
* movq MUNG(scratch3), %mm0
* movq MUNG(scratch5), %mm6
* movq MUNG(scratch7), %mm4
* psraw $4, %mm0
* psraw $4, %mm6
*/
movq MUNG(scratch1), %mm1
psraw $4, %mm4
movq %mm0, 8*3(%esi) /* out3 */
psraw $4, %mm1
movq %mm6, 8*5(%esi) /* out5 */
movq %mm4, 8*7(%esi) /* out7 */
movq %mm1, 8(%esi) /* out1 */
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
movl %ebp,%esp
popl %ebp
ret
.Lfe1:
.size IDCT_mmx,.Lfe1-IDCT_mmx
#ifdef __PIC__
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
.globl __i686.get_pc_thunk.bx
.hidden __i686.get_pc_thunk.bx
.type __i686.get_pc_thunk.bx,@function
__i686.get_pc_thunk.bx:
movl (%esp), %ebx
ret
#endif
#endif /* i386 && USE_MMX */
#ifdef __ELF__
.section .note.GNU-stack,"",%progbits
#endif

View file

@ -0,0 +1,234 @@
/*
* motionvector.c --
*
* Procedures to compute motion vectors.
*
*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "util.h"
#include "video.h"
#include "proto.h"
/*
Changes to make the code reentrant:
deglobalize curVidStream
Additional changes:
none
-lsh@cs.brown.edu (Loring Holden)
*/
/*
*--------------------------------------------------------------
*
* ComputeVector --
*
* Computes motion vector given parameters previously parsed
* and reconstructed.
*
* Results:
* Reconstructed motion vector info is put into recon_* parameters
* passed to this function. Also updated previous motion vector
* information.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
#define ComputeVector(recon_right_ptr, recon_down_ptr, recon_right_prev, recon_down_prev, f, full_pel_vector, motion_h_code, motion_v_code, motion_h_r, motion_v_r) \
\
{ \
int comp_h_r, comp_v_r; \
int right_little, right_big, down_little, down_big; \
int max, min, new_vector; \
\
/* The following procedure for the reconstruction of motion vectors \
is a direct and simple implementation of the instructions given \
in the mpeg December 1991 standard draft. \
*/ \
\
if (f == 1 || motion_h_code == 0) \
comp_h_r = 0; \
else \
comp_h_r = f - 1 - motion_h_r; \
\
if (f == 1 || motion_v_code == 0) \
comp_v_r = 0; \
else \
comp_v_r = f - 1 - motion_v_r; \
\
right_little = motion_h_code * f; \
if (right_little == 0) \
right_big = 0; \
else { \
if (right_little > 0) { \
right_little = right_little - comp_h_r; \
right_big = right_little - 32 * f; \
} \
else { \
right_little = right_little + comp_h_r; \
right_big = right_little + 32 * f; \
} \
} \
\
down_little = motion_v_code * f; \
if (down_little == 0) \
down_big = 0; \
else { \
if (down_little > 0) { \
down_little = down_little - comp_v_r; \
down_big = down_little - 32 * f; \
} \
else { \
down_little = down_little + comp_v_r; \
down_big = down_little + 32 * f; \
} \
} \
\
max = 16 * f - 1; \
min = -16 * f; \
\
new_vector = recon_right_prev + right_little; \
\
if (new_vector <= max && new_vector >= min) \
*recon_right_ptr = recon_right_prev + right_little; \
/* just new_vector */ \
else \
*recon_right_ptr = recon_right_prev + right_big; \
recon_right_prev = *recon_right_ptr; \
if (full_pel_vector) \
*recon_right_ptr = *recon_right_ptr << 1; \
\
new_vector = recon_down_prev + down_little; \
if (new_vector <= max && new_vector >= min) \
*recon_down_ptr = recon_down_prev + down_little; \
/* just new_vector */ \
else \
*recon_down_ptr = recon_down_prev + down_big; \
recon_down_prev = *recon_down_ptr; \
if (full_pel_vector) \
*recon_down_ptr = *recon_down_ptr << 1; \
}
/*
*--------------------------------------------------------------
*
* ComputeForwVector --
*
* Computes forward motion vector by calling ComputeVector
* with appropriate parameters.
*
* Results:
* Reconstructed motion vector placed in recon_right_for_ptr and
* recon_down_for_ptr.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
void ComputeForwVector( int* recon_right_for_ptr, int* recon_down_for_ptr,
VidStream* the_stream )
{
Pict *picture;
Macroblock *mblock;
picture = &(the_stream->picture);
mblock = &(the_stream->mblock);
ComputeVector(recon_right_for_ptr, recon_down_for_ptr,
mblock->recon_right_for_prev,
mblock->recon_down_for_prev,
(int) picture->forw_f,
picture->full_pel_forw_vector,
mblock->motion_h_forw_code, mblock->motion_v_forw_code,
mblock->motion_h_forw_r, mblock->motion_v_forw_r);
}
/*
*--------------------------------------------------------------
*
* ComputeBackVector --
*
* Computes backward motion vector by calling ComputeVector
* with appropriate parameters.
*
* Results:
* Reconstructed motion vector placed in recon_right_back_ptr and
* recon_down_back_ptr.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
void ComputeBackVector( int* recon_right_back_ptr, int* recon_down_back_ptr,
VidStream* the_stream )
{
Pict *picture;
Macroblock *mblock;
picture = &(the_stream->picture);
mblock = &(the_stream->mblock);
ComputeVector(recon_right_back_ptr, recon_down_back_ptr,
mblock->recon_right_back_prev,
mblock->recon_down_back_prev,
(int) picture->back_f,
picture->full_pel_back_vector,
mblock->motion_h_back_code, mblock->motion_v_back_code,
mblock->motion_h_back_r, mblock->motion_v_back_r);
}
/* EOF */

View file

@ -0,0 +1,693 @@
/*
* parseblock.c --
*
* Procedures to read in the values of a block and store them
* in a place where the player can use them.
*
*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#define NO_SANITY_CHECKS
#include <assert.h>
#include <stdlib.h>
#include "util.h"
#include "video.h"
#include "proto.h"
#include "decoders.h"
#ifdef USE_MMX
extern "C" {
extern unsigned int cpu_flags(void);
extern void IDCT_mmx(DCTBLOCK data);
};
#define mmx_ok() (cpu_flags() & 0x800000)
#endif
/*
Changes to make the code reentrant:
deglobalized: curBits, bitOffset, bitLength, bitBuffer, curVidStream,
zigzag_direct now a const int variable initialized once
-lsh@cs.brown.edu (Loring Holden)
*/
/* External declarations. */
#ifdef DCPREC
extern int dcprec;
#endif
/* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
#define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
#ifdef USE_MMX
/* This is global for the ditherer as well */
int mmx_available = 0;
static const int zigzag_direct_nommx[64] = {
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
static const int zigzag_direct_mmx[64] = {
0*8+0/* 0*/, 1*8+0/* 1*/, 0*8+1/* 8*/, 0*8+2/*16*/, 1*8+1/* 9*/, 2*8+0/* 2*/, 3*8+0/* 3*/, 2*8+1/*10*/,
1*8+2/*17*/, 0*8+3/*24*/, 0*8+4/*32*/, 1*8+3/*25*/, 2*8+2/*18*/, 3*8+1/*11*/, 4*8+0/* 4*/, 5*8+0/* 5*/,
4*8+1/*12*/, 5*8+2/*19*/, 2*8+3/*26*/, 1*8+4/*33*/, 0*8+5/*40*/, 0*8+6/*48*/, 1*8+5/*41*/, 2*8+4/*34*/,
3*8+3/*27*/, 4*8+2/*20*/, 5*8+1/*13*/, 6*8+0/* 6*/, 7*8+0/* 7*/, 6*8+1/*14*/, 5*8+2/*21*/, 4*8+3/*28*/,
3*8+4/*35*/, 2*8+5/*42*/, 1*8+6/*49*/, 0*8+7/*56*/, 1*8+7/*57*/, 2*8+6/*50*/, 3*8+5/*43*/, 4*8+4/*36*/,
5*8+3/*29*/, 6*8+2/*22*/, 7*8+1/*15*/, 7*8+2/*23*/, 6*8+3/*30*/, 5*8+4/*37*/, 4*8+5/*44*/, 3*8+6/*51*/,
2*8+7/*58*/, 3*8+7/*59*/, 4*8+6/*52*/, 5*8+5/*45*/, 6*8+4/*38*/, 7*8+3/*31*/, 7*8+4/*39*/, 6*8+5/*46*/,
7*8+6/*53*/, 4*8+7/*60*/, 5*8+7/*61*/, 6*8+6/*54*/, 7*8+5/*47*/, 7*8+6/*55*/, 6*8+7/*62*/, 7*8+7/*63*/
};
static int zigzag_direct[256];
void InitIDCT(void)
{
int i;
char *use_mmx;
use_mmx = getenv("SMPEG_USE_MMX");
if ( use_mmx ) {
mmx_available = atoi(use_mmx);
} else {
mmx_available = mmx_ok();
}
if (mmx_available) {
//printf("Using MMX IDCT algorithm!\n");
for(i=0;i<64;i++) {
zigzag_direct[i]=zigzag_direct_mmx[i];
}
} else {
for(i=0;i<64;i++) {
zigzag_direct[i]=zigzag_direct_nommx[i];
}
}
while ( i < 256 )
zigzag_direct[i++] = 0;
}
#else
/* Array mapping zigzag to array pointer offset. */
const int zigzag_direct[64] =
{
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
};
void InitIDCT(void)
{
return;
}
#endif
/*
*--------------------------------------------------------------
*
* ParseReconBlock --
*
* Parse values for block structure from bitstream.
* n is an indication of the position of the block within
* the macroblock (i.e. 0-5) and indicates the type of
* block (i.e. luminance or chrominance). Reconstructs
* coefficients from values parsed and puts in
* block.dct_recon array in vid stream structure.
* sparseFlag is set when the block contains only one
* coeffictient and is used by the IDCT.
*
* Results:
*
*
* Side effects:
* Bit stream irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DCT_recon blockPtr->dct_recon
#define DCT_dc_y_past blockPtr->dct_dc_y_past
#define DCT_dc_cr_past blockPtr->dct_dc_cr_past
#define DCT_dc_cb_past blockPtr->dct_dc_cb_past
#define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
#define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
/*
* Profiling results:
* This function only takes about 0.01ms per call, but is called many
* many times, taking about 15% of the total time used by playback.
*
*--------------------------------------------------------------
*/
void ParseReconBlock( int n, VidStream* vid_stream )
{
Block *blockPtr = &vid_stream->block;
int coeffCount=0;
if (vid_stream->buf_length < 100)
correct_underflow(vid_stream);
int diff;
int size, level=0, i, run, pos, coeff;
#ifdef USE_ATI
long int *reconptr;
#else
short int *reconptr;
#endif
unsigned char *iqmatrixptr, *niqmatrixptr;
int qscale;
#ifdef USE_ATI
reconptr = DCT_recon[n];
memset(reconptr, 0, 130*sizeof(reconptr[0]));
#else
reconptr = DCT_recon[0];
#if 0
/*
* Hand coded version of memset that's a little faster...
* Old call:
* memset((char *) DCT_recon, 0, 64*sizeof(short int));
*/
{
INT32 *p;
p = (INT32 *) reconptr;
p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] =
p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = p[16] = p[17] = p[18] =
p[19] = p[20] = p[21] = p[22] = p[23] = p[24] = p[25] = p[26] = p[27] =
p[28] = p[29] = p[30] = p[31] = 0;
}
#else
memset(reconptr, 0, 64*sizeof(reconptr[0]));
#endif
#endif
if (vid_stream->mblock.mb_intra) {
if (n < 4) {
/*
* Get the luminance bits. This code has been hand optimized to
* get by the normal bit parsing routines. We get some speedup
* by grabbing the next 16 bits and parsing things locally.
* Thus, calls are translated as:
*
* show_bitsX <--> next16bits >> (16-X)
* get_bitsX <--> val = next16bits >> (16-flushed-X);
* flushed += X;
* next16bits &= bitMask[flushed];
* flush_bitsX <--> flushed += X;
* next16bits &= bitMask[flushed];
*
* I've streamlined the code a lot, so that we don't have to mask
* out the low order bits and a few of the extra adds are removed.
* bsmith
*/
unsigned int next16bits, index, flushed;
show_bits16(next16bits);
index = next16bits >> (16-5);
if (index < 31) {
size = dct_dc_size_luminance[index].value;
flushed = dct_dc_size_luminance[index].num_bits;
} else {
index = next16bits >> (16-9);
index -= 0x1f0;
size = dct_dc_size_luminance1[index].value;
flushed = dct_dc_size_luminance1[index].num_bits;
}
next16bits &= bitMask[16+flushed];
if (size != 0) {
flushed += size;
diff = next16bits >> (16-flushed);
if (!(diff & bitTest[32-size])) {
diff = rBitMask[size] | (diff + 1);
}
diff <<= 3;
} else {
diff = 0;
}
flush_bits(flushed);
#ifdef USE_ATI
if ( (n == 0) && ((vid_stream->mblock.mb_address -
vid_stream->mblock.past_intra_addr) > 1) ) {
DCT_dc_y_past = diff;
} else {
DCT_dc_y_past += diff;
}
*reconptr++ = 0;
*reconptr++ = DCT_dc_y_past;
#else
if ( (n == 0) && ((vid_stream->mblock.mb_address -
vid_stream->mblock.past_intra_addr) > 1) ) {
coeff = diff + 1024;
} else {
coeff = diff + DCT_dc_y_past;
}
DCT_dc_y_past = coeff;
#endif
} else { /* n = 4 or 5 */
/*
* Get the chrominance bits. This code has been hand optimized to
* as described above
*/
unsigned int next16bits, index, flushed;
show_bits16(next16bits);
index = next16bits >> (16-5);
if (index < 31) {
size = dct_dc_size_chrominance[index].value;
flushed = dct_dc_size_chrominance[index].num_bits;
} else {
index = next16bits >> (16-10);
index -= 0x3e0;
size = dct_dc_size_chrominance1[index].value;
flushed = dct_dc_size_chrominance1[index].num_bits;
}
next16bits &= bitMask[16+flushed];
if (size != 0) {
flushed += size;
diff = next16bits >> (16-flushed);
if (!(diff & bitTest[32-size])) {
diff = rBitMask[size] | (diff + 1);
}
diff <<= 3;
} else {
diff = 0;
}
flush_bits(flushed);
#ifdef USE_ATI
*reconptr++ = 0;
if(n == 5) {
if (vid_stream->mblock.mb_address -
vid_stream->mblock.past_intra_addr > 1) {
DCT_dc_cr_past = diff;
} else {
DCT_dc_cr_past += diff;
}
*reconptr++ = DCT_dc_cr_past;
} else {
if (vid_stream->mblock.mb_address -
vid_stream->mblock.past_intra_addr > 1) {
DCT_dc_cb_past = diff;
} else {
DCT_dc_cb_past += diff;
}
*reconptr++ = DCT_dc_cb_past;
}
#else
/* We test 5 first; a result of the mixup of Cr and Cb */
coeff = diff;
if (n == 5) {
if (vid_stream->mblock.mb_address -
vid_stream->mblock.past_intra_addr > 1) {
coeff += 1024;
} else {
coeff += DCT_dc_cr_past;
}
DCT_dc_cr_past = coeff;
} else {
if (vid_stream->mblock.mb_address -
vid_stream->mblock.past_intra_addr > 1) {
coeff += 1024;
} else {
coeff += DCT_dc_cb_past;
}
DCT_dc_cb_past = coeff;
}
#endif
}
#ifndef USE_ATI
*reconptr = coeff;
#ifdef USE_MMX
if ( mmx_available ) {
*reconptr <<= 4;
}
#endif /* USE_MMX */
#endif /* USE_ATI */
pos = 0;
coeffCount = (coeff != 0);
i = 0;
if (vid_stream->picture.code_type != 4) {
qscale = vid_stream->slice.quant_scale;
iqmatrixptr = vid_stream->intra_quant_matrix[0];
while(1) {
DECODE_DCT_COEFF_NEXT(run, level);
if (run >= END_OF_BLOCK) break;
i = i + run + 1;
pos = zigzag_direct[i&0x3f];
/* quantizes and oddifies each coefficient */
if (level < 0) {
coeff = ((level<<1) * qscale *
((int) (iqmatrixptr[pos]))) / 16;
coeff += (1 - (coeff & 1));
} else {
coeff = ((level<<1) * qscale *
((int) (*(iqmatrixptr+pos)))) >> 4;
coeff -= (1 - (coeff & 1));
}
#ifdef USE_ATI
*reconptr++ = run;
*reconptr++ = coeff;
#else
#ifdef USE_MMX
if ( mmx_available )
coeff *= 16;
#endif
#ifdef QUANT_CHECK
printf ("coeff: %d\n", coeff);
#endif
reconptr[pos] = coeff;
coeffCount++;
#endif /* USE_ATI */
}
#ifdef QUANT_CHECK
printf ("\n");
#endif
#ifdef USE_ATI
/* mark end of block */
*reconptr++ = 0xFFFFFFFF;
#endif
#ifdef ANALYSIS
{
extern unsigned int *mbCoeffPtr;
mbCoeffPtr[pos]++;
}
#endif
flush_bits(2);
goto end;
}
} else { /* non-intra-coded macroblock */
niqmatrixptr = vid_stream->non_intra_quant_matrix[0];
qscale = vid_stream->slice.quant_scale;
DECODE_DCT_COEFF_FIRST(run, level);
i = run;
pos = zigzag_direct[i&0x3f];
/* quantizes and oddifies each coefficient */
if (level < 0) {
coeff = (((level<<1) - 1) * qscale *
((int) (niqmatrixptr[pos]))) / 16;
if ((coeff & 1) == 0) {coeff = coeff + 1;}
} else {
coeff = (((level<<1) + 1) * qscale *
((int) (*(niqmatrixptr+pos)))) >> 4;
coeff = (coeff-1) | 1; /* equivalent to: if ((coeff&1)==0) coeff = coeff - 1; */
}
#ifdef USE_ATI
*reconptr++ = run;
*reconptr++ = coeff;
#else
#ifdef USE_MMX
if ( mmx_available )
coeff *= 16;
#endif
reconptr[pos] = coeff;
if (coeff) {
coeffCount = 1;
}
#endif /* USE_ATI */
if (vid_stream->picture.code_type != 4) {
while(1) {
DECODE_DCT_COEFF_NEXT(run, level);
if (run >= END_OF_BLOCK) {
break;
}
i = i+run+1;
pos = zigzag_direct[i&0x3f];
if (level < 0) {
coeff = (((level<<1) - 1) * qscale *
((int) (niqmatrixptr[pos]))) / 16;
if ((coeff & 1) == 0) {coeff = coeff + 1;}
} else {
coeff = (((level<<1) + 1) * qscale *
((int) (*(niqmatrixptr+pos)))) >> 4;
coeff = (coeff-1) | 1; /* equivalent to: if ((coeff&1)==0) coeff = coeff - 1; */
}
#ifdef USE_ATI
*reconptr++ = run;
*reconptr++ = coeff;
#else
#ifdef USE_MMX
if ( mmx_available )
coeff *= 16;
#endif
reconptr[pos] = coeff;
coeffCount++;
#endif /* USE_ATI */
} /* end while */
#ifdef USE_ATI
/* mark end of block */
*reconptr++ = 0xFFFFFFFF;
#endif
#ifdef ANALYSIS
{
extern unsigned int *mbCoeffPtr;
mbCoeffPtr[pos]++;
}
#endif
flush_bits(2);
goto end;
} /* end if (vid_stream->picture.code_type != 4) */
}
end:
#ifdef USE_ATI
return;
#else
if( ! vid_stream->_skipFrame || (vid_stream->picture.code_type != B_TYPE) )
{
if( coeffCount == 1 )
{
#ifdef USE_MMX
if ( mmx_available )
IDCT_mmx(reconptr);
else
j_rev_dct_sparse (reconptr, pos);
#else
j_rev_dct_sparse (reconptr, pos);
#endif
}
else
{
#ifdef FLOATDCT
if (qualityFlag)
{
float_idct(reconptr);
}
else
#endif
#ifdef USE_MMX
if ( mmx_available )
IDCT_mmx(reconptr);
else
j_rev_dct(reconptr);
#else
j_rev_dct(reconptr);
#endif
}
}
#ifdef USE_MMX
if ( mmx_available ) {
__asm__ ("emms");
}
#endif
#endif
}
#undef DCT_recon
#undef DCT_dc_y_past
#undef DCT_dc_cr_past
#undef DCT_dc_cb_past
/*
*--------------------------------------------------------------
*
* ParseAwayBlock --
*
* Parses off block values, throwing them away.
* Used with grayscale dithering.
*
* Results:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
void ParseAwayBlock( int n, VidStream* vid_stream )
{
unsigned int diff;
unsigned int size, run;
int level;
if (vid_stream->buf_length < 100)
correct_underflow(vid_stream);
if (vid_stream->mblock.mb_intra) {
/* If the block is a luminance block... */
if (n < 4) {
/* Parse and decode size of first coefficient. */
DecodeDCTDCSizeLum(size);
/* Parse first coefficient. */
if (size != 0) {
get_bitsn(size, diff);
}
}
/* Otherwise, block is chrominance block... */
else {
/* Parse and decode size of first coefficient. */
DecodeDCTDCSizeChrom(size);
/* Parse first coefficient. */
if (size != 0) {
get_bitsn(size, diff);
}
}
}
/* Otherwise, block is not intracoded... */
else {
/* Decode and set first coefficient. */
DECODE_DCT_COEFF_FIRST(run, level);
}
/* If picture is not D type (i.e. I, P, or B)... */
if (vid_stream->picture.code_type != 4) {
/* While end of macroblock has not been reached... */
while (1) {
/* Get the dct_coeff_next */
DECODE_DCT_COEFF_NEXT(run, level);
if (run >= END_OF_BLOCK) break;
}
/* End_of_block */
flush_bits(2);
}
}
/* EOF */

215
smpeg/src/video/proto.h Normal file
View file

@ -0,0 +1,215 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifdef WIN32
#define __STDC__ 1
#endif
#ifdef __STDC__
# define P(s) s
#include <stdlib.h> /* used by almost all modules */
#else
# define P(s) ()
#endif
/* util.c */
void correct_underflow P((VidStream *vid_stream ));
int next_bits P((int num , unsigned int mask , VidStream *vid_stream ));
char *get_ext_data P((VidStream *vid_stream ));
int next_start_code P((VidStream *vid_stream));
char *get_extra_bit_info P((VidStream *vid_stream ));
/* video.c */
void init_stats P((void ));
void PrintAllStats P((VidStream *vid_stream ));
double ReadSysClock P((void ));
void PrintTimeInfo P(( VidStream *vid_stream ));
void InitCrop P((void ));
void InitIDCT P((void ));
VidStream *NewVidStream P((unsigned int buffer_len ));
void ResetVidStream P((VidStream *vid ));
void DestroyVidStream P((VidStream *astream ));
PictImage *NewPictImage P(( VidStream *vid_stream ));
bool InitPictImages P(( VidStream *vid_stream, int w, int h, SDL_Surface *dst ));
void DestroyPictImage P(( VidStream *vid_stream, PictImage *apictimage ));
VidStream *mpegVidRsrc P((TimeStamp time_stamp,VidStream *vid_stream, int first ));
void SetBFlag P((BOOLEAN val ));
void SetPFlag P((BOOLEAN val ));
/* parseblock.c */
void ParseReconBlock P((int n, VidStream *vid_stream ));
void ParseAwayBlock P((int n , VidStream *vid_stream ));
/* motionvec.c */
void ComputeForwVector P((int *recon_right_for_ptr , int *recon_down_for_ptr , VidStream *the_stream ));
void ComputeBackVector P((int *recon_right_back_ptr , int *recon_down_back_ptr, VidStream *the_stream ));
/* decoders.c */
void decodeInitTables P((void ));
void decodeDCTDCSizeLum P((unsigned int *value ));
void decodeDCTDCSizeChrom P((unsigned int *value ));
void decodeDCTCoeffFirst P((unsigned int *run , int *level ));
void decodeDCTCoeffNext P((unsigned int *run , int *level ));
/* gdith.c */
void InitColor P((void ));
/* fs2.c */
void InitFS2Dither P((void ));
void FS2DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *disp , int rows , int cols ));
/* fs2fast.c */
void InitFS2FastDither P((void ));
void FS2FastDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
/* fs4.c */
void InitFS4Dither P((void ));
void FS4DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *disp , int rows , int cols ));
/* hybrid.c */
void InitHybridDither P((void ));
void HybridDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
/* hybriderr.c */
void InitHybridErrorDither P((void ));
void HybridErrorDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
/* gray.c */
void GrayDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
void Gray2DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
void Gray16DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
void Gray216DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
void Gray32DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
void Gray232DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
/* mono.c */
void MonoThresholdImage(unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int h, int w);
void MonoDitherImage(unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int h, int w);
/* jrevdct.c */
void init_pre_idct P((void ));
void j_rev_dct_sparse P((DCTBLOCK data , int pos ));
void j_rev_dct P((DCTBLOCK data ));
void j_rev_dct_sparse P((DCTBLOCK data , int pos ));
void j_rev_dct P((DCTBLOCK data ));
/* floatdct.c */
void init_float_idct P((void ));
void float_idct P((short* block ));
/* 16bit.c */
void InitColorDither P(( int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask ));
void Color16DitherImageMod P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod ));
void Color16DitherImageMMX P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod ));
void Color32DitherImageMod P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod ));
void Color32DitherImageMMX P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod ));
void Color16DitherImageModInterlace P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod, int start ));
void Color32DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int rows , int cols ));
void ScaleColor16DitherImageMod P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod, int scale ));
void ScaleColor32DitherImageMod P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod, int scale ));
void ScaleColor16DitherImageModInterlace P((unsigned char *lum, unsigned char *cr, unsigned char *cb, unsigned char *out, int rows, int cols, int mod, int start, int scale ));
void Twox2Color32DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int rows , int cols ));
/* ordered.c */
void InitOrderedDither P((void ));
void OrderedDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
/* ordered2.c */
void InitOrdered2Dither P((void ));
void Ordered2DitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w ));
/* mb_ordered.c */
void InitMBOrderedDither P((void ));
void MBOrderedDitherImage P((unsigned char *lum , unsigned char *cr , unsigned char *cb , unsigned char *out , int h , int w, char *ditherFlags ));
void MBOrderedDitherDisplayCopy P((VidStream *vid_stream , int mb_addr , int motion_forw , int r_right_forw , int r_down_forw , int motion_back , int r_right_back , int r_down_back , unsigned char *past , unsigned char *future ));
/* readfile.c */
void SeekStream P((VidStream *vid_stream ));
void clear_data_stream P(( VidStream *vid_stream));
int get_more_data P(( VidStream *vid_stream ));
int pure_get_more_data P((unsigned int *buf_start , int max_length , int *length_ptr , unsigned int **buf_ptr, VidStream *vid_stream ));
int read_sys P(( VidStream *vid_stream, unsigned int start ));
int ReadStartCode P(( unsigned int *startCode, VidStream *vid_stream ));
int ReadPackHeader P((
double *systemClockTime,
unsigned long *muxRate,
VidStream *vid_stream ));
int ReadSystemHeader P(( VidStream *vid_stream ));
int find_start_code P(( FILE *input ));
int ReadPacket P(( unsigned char packetID, VidStream *vid_stream ));
void ReadTimeStamp P((
unsigned char *inputBuffer,
unsigned char *hiBit,
unsigned long *low4Bytes));
void ReadSTD P((
unsigned char *inputBuffer,
unsigned char *stdBufferScale,
unsigned long *stdBufferSize));
void ReadRate P((
unsigned char *inputBuffer,
unsigned long *rate));
int MakeFloatClockTime P((
unsigned char hiBit,
unsigned long low4Bytes,
double *floatClockTime));
#ifndef NOCONTROLS
/* ctrlbar.c */
double StopWatch P((int action ));
bool WindowMapped P((Display *dsp, XEvent *xev, char *window ));
bool IfEventType P((Display *dsp, XEvent *xev, char *type ));
void MakeControlBar P(( XInfo *xinfo ));
void UpdateFrameTotal P((Display *display));
void UpdateControlDisplay P((Display *display));
void ControlBar P((VidStream **vid_stream, XInfo *xinfo, int numMovies ));
void ControlLoop P((VidStream **theStream, XInfo *xinfo, int numStreams ));
#endif /* !NOCONTROLS */
#undef P

View file

@ -0,0 +1,184 @@
/*
* readfile.c --
*
* Procedures concerned with reading data and parsing
* start codes from MPEG files.
*
*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include <sys/types.h>
#ifdef __STDC__
#include <stdlib.h>
#include <string.h>
#endif
#include <string.h>
#include <signal.h>
#include "SDL_endian.h"
#include "video.h"
#include "proto.h"
#include "util.h"
#include "dither.h"
/*
Changes to make the code reentrant:
deglobalized: totNumFrames, realTimeStart, stream id vars, Prase_done,
swap, seekValue, input, EOF_flag, ReadPacket statics, sys_layer,
bitOffset, bitLength, bitBuffer, curVidStream
removed: [aud,sys,vid]Bytes
Additional changes:
get rid on ANSI C complaints about shifting
-lsh@cs.brown.edu (Loring Holden)
*/
/*
*--------------------------------------------------------------
*
* get_more_data --
*
* Called by get_more_data to read in more data from
* video MPG files (non-system-layer)
*
* Results:
* Input buffer updated, buffer length updated.
* Returns 1 if data read, 0 if EOF, -1 if error.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int
get_more_data( VidStream* vid_stream )
{
unsigned int *buf_start;
int length, num_read, i;
unsigned int request;
unsigned char *buffer, *mark;
unsigned int *lmark;
Sint32 timestamp_offset;
Uint32 data_pos;
if (vid_stream->EOF_flag) return 0;
buf_start = vid_stream->buf_start;
length = vid_stream->buf_length;
buffer = (unsigned char *) vid_stream->buffer;
if (length > 0) {
memcpy((unsigned char *) buf_start, buffer, (unsigned int) (length*4));
mark = ((unsigned char *) (buf_start + length));
}
else {
mark = (unsigned char *) buf_start;
length = 0;
}
request = (vid_stream->max_buf_length-length)*4;
data_pos = vid_stream->_smpeg->mpeg->pos;
num_read = vid_stream->_smpeg->mpeg->copy_data((Uint8 *)mark, request);
vid_stream->timestamp = vid_stream->_smpeg->mpeg->timestamp;
timestamp_offset = vid_stream->_smpeg->mpeg->timestamp_pos - data_pos;
vid_stream->timestamp_mark = (unsigned int *)(mark+timestamp_offset);
vid_stream->timestamp_used = false;
/* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
{
int num_read_rounded;
unsigned char *index;
num_read_rounded = 4*(num_read/4);
/* this can happen only if num_read<request; i.e. end of file reached */
if ( num_read_rounded < num_read ) {
num_read_rounded = 4*( num_read/4+1 );
/* fill in with zeros */
for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
/* advance to the next 4-byte boundary */
num_read = num_read_rounded;
}
}
if (num_read < 0) {
return -1;
}
if (num_read == 0) {
vid_stream->buffer = buf_start;
/* Make 32 bits after end equal to 0 and 32
* bits after that equal to seq end code
* in order to prevent messy data from infinite
* recursion.
*/
*(buf_start + length) = 0x0;
*(buf_start + length+1) = SEQ_END_CODE;
vid_stream->EOF_flag = 1;
return 0;
}
lmark = (unsigned int *) mark;
num_read = num_read/4;
for (i = 0; i < num_read; i++) {
*lmark = SDL_SwapBE32(*lmark);
lmark++;
}
vid_stream->buffer = buf_start;
vid_stream->buf_length = length + num_read;
return 1;
}
/* EOF */

499
smpeg/src/video/util.cpp Normal file
View file

@ -0,0 +1,499 @@
/*
* util.c --
*
* Miscellaneous utility procedures.
*
*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "MPEG.h"
#include <stdlib.h>
#include "video.h"
#include "proto.h"
#include "util.h"
#ifndef NOCONTROLS
#include "ctrlbar.h"
#endif
/*
Changes to make the code reentrant:
de-globalized: totNumFrames, realTimeStart, vid_stream, sys_layer,
bitOffset, bitLength, bitBuffer, curVidStream
setjmp/longjmp replaced
Additional changes:
only call DestroyVidStream up in mpegVidRsrc, not in correct_underflow
-lsh@cs.brown.edu (Loring Holden)
*/
/* Bit masks used by bit i/o operations. */
unsigned int nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
unsigned int bitMask[] = { 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
0x0000000f, 0x00000007, 0x00000003, 0x00000001};
unsigned int rBitMask[] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
unsigned int bitTest[] = { 0x80000000, 0x40000000, 0x20000000, 0x10000000,
0x08000000, 0x04000000, 0x02000000, 0x01000000,
0x00800000, 0x00400000, 0x00200000, 0x00100000,
0x00080000, 0x00040000, 0x00020000, 0x00010000,
0x00008000, 0x00004000, 0x00002000, 0x00001000,
0x00000800, 0x00000400, 0x00000200, 0x00000100,
0x00000080, 0x00000040, 0x00000020, 0x00000010,
0x00000008, 0x00000004, 0x00000002, 0x00000001};
/*
*--------------------------------------------------------------
*
* correct_underflow --
*
* Called when buffer does not have sufficient data to
* satisfy request for bits.
* Calls get_more_data, an application specific routine
* required to fill the buffer with more data.
*
* Results:
* None really.
*
* Side effects:
* buf_length and buffer fields may be changed.
*
*--------------------------------------------------------------
*/
void correct_underflow( VidStream* vid_stream )
{
int status;
status = get_more_data(vid_stream);
if (status < 0) {
if (!quietFlag) {
fprintf (stderr, "\n");
perror("Unexpected read error.");
}
exit(1);
}
else if ((status == 0) && (vid_stream->buf_length < 1)) {
if (!quietFlag) {
fprintf(stderr, "\nImproper or missing sequence end code.\n");
}
#ifdef ANALYSIS
PrintAllStats(vid_stream);
#endif
vid_stream->film_has_ended=TRUE;
return;
}
#ifdef UTIL2
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
#else
vid_stream->curBits = *vid_stream->buffer;
#endif
}
/*
*--------------------------------------------------------------
*
* next_bits --
*
* Compares next num bits to low order position in mask.
* Buffer pointer is NOT advanced.
*
* Results:
* TRUE, FALSE, or error code.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int next_bits( int num, unsigned int mask, VidStream* vid_stream )
{
unsigned int stream;
int ret_value;
#if 0
/* If no current stream, return error. */
if (vid_stream == NULL)
return NO_VID_STREAM;
#endif
/* Get next num bits, no buffer pointer advance. */
show_bitsn(num, stream);
/* Compare bit stream and mask. Set return value toTRUE if equal, FALSE if
differs.
*/
if (mask == stream) {
ret_value = TRUE;
} else ret_value = FALSE;
/* Return return value. */
return ret_value;
}
/*
*--------------------------------------------------------------
*
* get_ext_data --
*
* Assumes that bit stream is at begining of extension
* data. Parses off extension data into dynamically
* allocated space until start code is hit.
*
* Results:
* Pointer to dynamically allocated memory containing
* extension data.
*
* Side effects:
* Bit stream irreversibly parsed.
*
*--------------------------------------------------------------
*/
char* get_ext_data( VidStream* vid_stream )
{
unsigned int size, marker;
char *dataPtr;
unsigned int data;
/* Set initial ext data buffer size. */
size = EXT_BUF_SIZE;
/* Allocate ext data buffer. */
dataPtr = (char *) malloc(size);
/* Initialize marker to keep place in ext data buffer. */
marker = 0;
/* While next data is not start code... */
while (!next_bits(24, 0x000001, vid_stream)) {
/* Get next byte of ext data. */
get_bits8(data);
/* Put ext data into ext data buffer. Advance marker. */
dataPtr[marker] = (char) data;
marker++;
/* If end of ext data buffer reached, resize data buffer. */
if (marker == size) {
size += EXT_BUF_SIZE;
dataPtr = (char *) realloc(dataPtr, size);
}
}
/* Realloc data buffer to free any extra space. */
dataPtr = (char *) realloc(dataPtr, marker);
/* Return pointer to ext data buffer. */
return dataPtr;
}
/*
*--------------------------------------------------------------
*
* next_start_code --
*
* Parses off bitstream until start code reached. When done
* next 4 bytes of bitstream will be start code. Bit offset
* reset to 0.
*
* Results:
* Status code.
*
* Side effects:
* Bit stream irreversibly parsed.
*
*--------------------------------------------------------------
*/
int next_start_code( VidStream* vid_stream )
{
int state;
int byteoff;
unsigned int data;
#if 0
/* If no current stream, return error. */
if (vid_stream== NULL)
return NO_VID_STREAM;
#endif
/* If insufficient buffer length, correct underflow. */
if (vid_stream->buf_length < 4) {
correct_underflow(vid_stream);
}
/* If bit offset not zero, reset and advance buffer pointer. */
byteoff = vid_stream->bit_offset % 8;
if (byteoff != 0) {
flush_bits((8-byteoff));
}
/* Set state = 0. */
state = 0;
/* While buffer has data ... */
while(vid_stream->buf_length > 0) {
/* If insufficient data exists, correct underflow. */
if (vid_stream->buf_length < 4) {
correct_underflow(vid_stream);
}
/* If next byte is zero... */
get_bits8(data);
if (data == 0) {
/* If state < 2, advance state. */
if (state < 2) state++;
}
/* If next byte is one... */
else if (data == 1) {
/* If state == 2, advance state (i.e. start code found). */
if (state == 2) state++;
/* Otherwise, reset state to zero. */
else state = 0;
}
/* Otherwise byte is neither 1 or 0, reset state to 0. */
else {
state = 0;
}
/* If state == 3 (i.e. start code found)... */
if (state == 3) {
/* Set buffer pointer back and reset length & bit offsets so
* next bytes will be beginning of start code.
*/
vid_stream->bit_offset = vid_stream->bit_offset - 24;
#ifdef ANALYSIS
bitCount -= 24;
#endif
if (vid_stream->bit_offset < 0) {
vid_stream->bit_offset = 32 + vid_stream->bit_offset;
vid_stream->buf_length++;
vid_stream->buffer--;
#ifdef UTIL2
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
#else
vid_stream->curBits = *vid_stream->buffer;
#endif
}
else {
#ifdef UTIL2
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;
#else
vid_stream->curBits = *vid_stream->buffer;
#endif
}
#ifdef NO_GRIFF_MODS
/* Return success. */
return OK;
#else /* NO_GRIFF_MODS */
show_bits32(data);
if ( data==SEQ_START_CODE ||
data==GOP_START_CODE ||
data==PICTURE_START_CODE ||
(data>=SLICE_MIN_START_CODE && data<=SLICE_MAX_START_CODE) ||
data==EXT_START_CODE ||
data==USER_START_CODE )
{
/* Return success. */
return OK;
}
else
{
flush_bits32;
}
#endif /* NO_GRIFF_MODS */
}
}
/* Return underflow error. */
return STREAM_UNDERFLOW;
}
/*
*--------------------------------------------------------------
*
* get_extra_bit_info --
*
* Parses off extra bit info stream into dynamically
* allocated memory. Extra bit info is indicated by
* a flag bit set to 1, followed by 8 bits of data.
* This continues until the flag bit is zero. Assumes
* that bit stream set to first flag bit in extra
* bit info stream.
*
* Results:
* Pointer to dynamically allocated memory with extra
* bit info in it. Flag bits are NOT included.
*
* Side effects:
* Bit stream irreversibly parsed.
*
*--------------------------------------------------------------
*/
char* get_extra_bit_info( VidStream* vid_stream )
{
unsigned int size, marker;
char *dataPtr;
unsigned int data;
/* Get first flag bit. */
get_bits1(data);
/* If flag is false, return NULL pointer (i.e. no extra bit info). */
if (!data) return NULL;
/* Initialize size of extra bit info buffer and allocate. */
size = EXT_BUF_SIZE;
dataPtr = (char *) malloc(size);
/* Reset marker to hold place in buffer. */
marker = 0;
/* While flag bit is true. */
while (data) {
/* Get next 8 bits of data. */
get_bits8(data);
/* Place in extra bit info buffer. */
dataPtr[marker] = (char) data;
marker++;
/* If buffer is full, reallocate. */
if (marker == size) {
size += EXT_BUF_SIZE;
dataPtr = (char *) realloc(dataPtr, size);
}
/* Get next flag bit. */
get_bits1(data);
}
/* Reallocate buffer to free extra space. */
dataPtr = (char *) realloc(dataPtr, marker);
/* Return pointer to extra bit info buffer. */
return dataPtr;
}
/* EOF */

395
smpeg/src/video/util.h Normal file
View file

@ -0,0 +1,395 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
Changes to make the code reentrant:
deglobalized: curBits, curVidStream
deglobalized: bitOffset, bitLength, bitBuffer in vid_stream, not used
here
Additional changes:
-lsh@cs.brown.edu (Loring Holden)
*/
/* Status codes for bit stream i/o operations. */
#include "MPEG.h"
#define NO_VID_STREAM (-1)
#define STREAM_UNDERFLOW (-2)
#define OK 1
/* Size increment of extension data buffers. */
#define EXT_BUF_SIZE 1024
/* External declarations for bitstream i/o operations. */
extern unsigned int bitMask[];
extern unsigned int nBitMask[];
extern unsigned int rBitMask[];
extern unsigned int bitTest[];
/* Macro for updating bit counter if analysis tool is on. */
#ifdef ANALYSIS
#define UPDATE_COUNT(numbits) bitCount += numbits
#else
#define UPDATE_COUNT(numbits)
#endif
#ifdef NO_SANITY_CHECKS
#define get_bits1(result) \
{ \
UPDATE_COUNT(1); \
result = ((vid_stream->curBits & 0x80000000) != 0); \
vid_stream->curBits <<= 1; \
vid_stream->bit_offset++; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset = 0; \
vid_stream->buffer++; \
vid_stream->curBits = *vid_stream->buffer; \
vid_stream->buf_length--; \
} \
}
#define get_bits2(result) \
{ \
UPDATE_COUNT(2); \
vid_stream->bit_offset += 2; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset -= 32; \
vid_stream->buffer++; \
vid_stream->buf_length--; \
if (vid_stream->bit_offset) { \
vid_stream->curBits |= \
(*vid_stream->buffer >> (2 - vid_stream->bit_offset)); \
} \
result = ((vid_stream->curBits & 0xc0000000) >> 30); \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset; \
} \
\
result = ((vid_stream->curBits & 0xc0000000) >> 30); \
vid_stream->curBits <<= 2; \
}
#define get_bitsX(num, mask, shift, result) \
{ \
UPDATE_COUNT(num); \
vid_stream->bit_offset += num; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset -= 32; \
vid_stream->buffer++; \
vid_stream->buf_length--; \
if (vid_stream->bit_offset) { \
vid_stream->curBits |= (*vid_stream->buffer >> \
(num - vid_stream->bit_offset)); \
} \
result = ((vid_stream->curBits & mask) >> shift); \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset; \
} \
else { \
result = ((vid_stream->curBits & mask) >> shift); \
vid_stream->curBits <<= num; \
} \
}
#else
#define get_bits1(result) \
{ \
/* Check for underflow. */ \
\
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
UPDATE_COUNT(1); \
result = ((vid_stream->curBits & 0x80000000) != 0); \
vid_stream->curBits <<= 1; \
vid_stream->bit_offset++; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset = 0; \
vid_stream->buffer++; \
vid_stream->curBits = *vid_stream->buffer; \
vid_stream->buf_length--; \
} \
}
#define get_bits2(result) \
{ \
/* Check for underflow. */ \
\
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
UPDATE_COUNT(2); \
vid_stream->bit_offset += 2; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset -= 32; \
vid_stream->buffer++; \
vid_stream->buf_length--; \
if (vid_stream->bit_offset) { \
vid_stream->curBits |= (*vid_stream->buffer >> \
(2 - vid_stream->bit_offset)); \
} \
result = ((vid_stream->curBits & 0xc0000000) >> 30); \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset; \
} \
\
result = ((vid_stream->curBits & 0xc0000000) >> 30); \
vid_stream->curBits <<= 2; \
}
#define get_bitsX(num, mask, shift, result) \
{ \
/* Check for underflow. */ \
\
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
UPDATE_COUNT(num); \
vid_stream->bit_offset += num; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset -= 32; \
vid_stream->buffer++; \
vid_stream->buf_length--; \
if (vid_stream->bit_offset) { \
vid_stream->curBits |= (*vid_stream->buffer >> \
(num - vid_stream->bit_offset)); \
} \
result = ((vid_stream->curBits & mask) >> shift); \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset; \
} \
else { \
result = ((vid_stream->curBits & mask) >> shift); \
vid_stream->curBits <<= num; \
} \
}
#endif
#define get_bits3(result) get_bitsX(3, 0xe0000000, 29, result)
#define get_bits4(result) get_bitsX(4, 0xf0000000, 28, result)
#define get_bits5(result) get_bitsX(5, 0xf8000000, 27, result)
#define get_bits6(result) get_bitsX(6, 0xfc000000, 26, result)
#define get_bits7(result) get_bitsX(7, 0xfe000000, 25, result)
#define get_bits8(result) get_bitsX(8, 0xff000000, 24, result)
#define get_bits9(result) get_bitsX(9, 0xff800000, 23, result)
#define get_bits10(result) get_bitsX(10, 0xffc00000, 22, result)
#define get_bits11(result) get_bitsX(11, 0xffe00000, 21, result)
#define get_bits12(result) get_bitsX(12, 0xfff00000, 20, result)
#define get_bits14(result) get_bitsX(14, 0xfffc0000, 18, result)
#define get_bits16(result) get_bitsX(16, 0xffff0000, 16, result)
#define get_bits18(result) get_bitsX(18, 0xffffc000, 14, result)
#define get_bits32(result) get_bitsX(32, 0xffffffff, 0, result)
#define get_bitsn(num, result) get_bitsX((num), nBitMask[num], (32-(num)), result)
#ifdef NO_SANITY_CHECKS
#define show_bits32(result) \
{ \
if (vid_stream->bit_offset) { \
result = vid_stream->curBits | (*(vid_stream->buffer+1) >> \
(32 - vid_stream->bit_offset)); \
} \
else { \
result = vid_stream->curBits; \
} \
}
#define show_bitsX(num, mask, shift, result) \
{ \
int bO; \
bO = vid_stream->bit_offset + num; \
if (bO > 32) { \
bO -= 32; \
result = ((vid_stream->curBits & mask) >> shift) | \
(*(vid_stream->buffer+1) >> (shift + (num - bO))); \
} \
else { \
result = ((vid_stream->curBits & mask) >> shift); \
} \
}
#else
#define show_bits32(result) \
{ \
/* Check for underflow. */ \
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
if (vid_stream->bit_offset) { \
result = vid_stream->curBits | (*(vid_stream->buffer+1) >> \
(32 - vid_stream->bit_offset)); \
} \
else { \
result = vid_stream->curBits; \
} \
}
#define show_bitsX(num, mask, shift, result) \
{ \
int bO; \
\
/* Check for underflow. */ \
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
bO = vid_stream->bit_offset + num; \
if (bO > 32) { \
bO -= 32; \
result = ((vid_stream->curBits & mask) >> shift) | \
(*(vid_stream->buffer+1) >> (shift + (num - bO))); \
} \
else { \
result = ((vid_stream->curBits & mask) >> shift); \
} \
}
#endif
#define show_bits1(result) show_bitsX(1, 0x80000000, 31, result)
#define show_bits2(result) show_bitsX(2, 0xc0000000, 30, result)
#define show_bits3(result) show_bitsX(3, 0xe0000000, 29, result)
#define show_bits4(result) show_bitsX(4, 0xf0000000, 28, result)
#define show_bits5(result) show_bitsX(5, 0xf8000000, 27, result)
#define show_bits6(result) show_bitsX(6, 0xfc000000, 26, result)
#define show_bits7(result) show_bitsX(7, 0xfe000000, 25, result)
#define show_bits8(result) show_bitsX(8, 0xff000000, 24, result)
#define show_bits9(result) show_bitsX(9, 0xff800000, 23, result)
#define show_bits10(result) show_bitsX(10, 0xffc00000, 22, result)
#define show_bits11(result) show_bitsX(11, 0xffe00000, 21, result)
#define show_bits12(result) show_bitsX(12, 0xfff00000, 20, result)
#define show_bits13(result) show_bitsX(13, 0xfff80000, 19, result)
#define show_bits14(result) show_bitsX(14, 0xfffc0000, 18, result)
#define show_bits15(result) show_bitsX(15, 0xfffe0000, 17, result)
#define show_bits16(result) show_bitsX(16, 0xffff0000, 16, result)
#define show_bits17(result) show_bitsX(17, 0xffff8000, 15, result)
#define show_bits18(result) show_bitsX(18, 0xffffc000, 14, result)
#define show_bits19(result) show_bitsX(19, 0xffffe000, 13, result)
#define show_bits20(result) show_bitsX(20, 0xfffff000, 12, result)
#define show_bits21(result) show_bitsX(21, 0xfffff800, 11, result)
#define show_bits22(result) show_bitsX(22, 0xfffffc00, 10, result)
#define show_bits23(result) show_bitsX(23, 0xfffffe00, 9, result)
#define show_bits24(result) show_bitsX(24, 0xffffff00, 8, result)
#define show_bits25(result) show_bitsX(25, 0xffffff80, 7, result)
#define show_bits26(result) show_bitsX(26, 0xffffffc0, 6, result)
#define show_bits27(result) show_bitsX(27, 0xffffffe0, 5, result)
#define show_bits28(result) show_bitsX(28, 0xfffffff0, 4, result)
#define show_bits29(result) show_bitsX(29, 0xfffffff8, 3, result)
#define show_bits30(result) show_bitsX(30, 0xfffffffc, 2, result)
#define show_bits31(result) show_bitsX(31, 0xfffffffe, 1, result)
#define show_bitsn(num,result) show_bitsX((num), (0xffffffff << (32-(num))), (32-(num)), result)
#ifdef NO_SANITY_CHECKS
#define flush_bits32 \
{ \
UPDATE_COUNT(32); \
\
vid_stream->buffer++; \
vid_stream->buf_length--; \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;\
}
#define flush_bits(num) \
{ \
vid_stream->bit_offset += num; \
\
UPDATE_COUNT(num); \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->bit_offset -= 32; \
vid_stream->buffer++; \
vid_stream->buf_length--; \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;\
} \
else { \
vid_stream->curBits <<= num; \
} \
}
#else
#define flush_bits32 \
{ \
if (vid_stream == NULL) { \
/* Deal with no vid stream here. */ \
} \
\
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
\
UPDATE_COUNT(32); \
\
vid_stream->buffer++; \
vid_stream->buf_length--; \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;\
}
#define flush_bits(num) \
{ \
if (vid_stream== NULL) { \
/* Deal with no vid stream here. */ \
} \
\
if (vid_stream->buf_length < 2) { \
correct_underflow(vid_stream); \
} \
\
UPDATE_COUNT(num); \
\
vid_stream->bit_offset += num; \
\
if (vid_stream->bit_offset & 0x20) { \
vid_stream->buf_length--; \
vid_stream->bit_offset -= 32; \
vid_stream->buffer++; \
vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;\
} \
else { \
vid_stream->curBits <<= num; \
} \
}
#endif
#define UTIL2

272
smpeg/src/video/vhar128.cpp Normal file
View file

@ -0,0 +1,272 @@
#ifdef USE_ATI
#include <stdio.h>
#include <vha.h>
#include <r128hap.h>
#include <ovly.h>
#include "vhar128.h"
/* #define DEBUG_R128VHA */
#define I_FRAME 1
#define P_FRAME 2
#define B_FRAME 3
#define D_FRAME 4
struct vhar128_image {
OVDESCRIPTION * overlay;
};
struct private_yuvhwdata {
OVSURFACE * surface;
};
/* Translate error code to something readable */
static void vhar128_perror(char * string, int error_code)
{
switch(error_code)
{
case VHAERR_INVALIDPARAMS:
fprintf(stderr, "%s: (ATI) Invalid parameters\n", string);
break;
case VHAERR_UNSUPPORTED:
fprintf(stderr, "%s: (ATI) Unsupported feature\n", string);
break;
case VHAERR_INVALIDHANDLE:
fprintf(stderr, "%s: (ATI) Invalid handle\n", string);
break;
case VHAERR_OUTOFMEMORY:
fprintf(stderr, "%s: (ATI) Out of memory\n", string);
break;
case VHA_OK:
fprintf(stderr, "%s: (ATI) Success\n", string);
break;
default:
fprintf(stderr, "%s: (ATI) Undocumented error\n", string);
break;
}
}
/* Check and initialize hardware */
unsigned int vhar128_new()
{
VHA_HARDWAREQUERY vhaQuery;
/* Initialize hardware access */
ATIHAP_InitHWAccess();
/* Query hardware information */
memset(&vhaQuery, 0, sizeof(VHA_HARDWAREQUERY));
vhaQuery.uSize = sizeof(VHA_HARDWAREQUERY);
vhaQuery.uCards = 0;
vhaQuery.ulCodedWidth = 0;
vhaQuery.ulCodedHeight = 0;
VHA_HardwareQuery(&vhaQuery);
#ifdef DEBUG_R128VHA
printf("VHA_HardwareQuery :\n");
printf("uHandle = %d\n", vhaQuery.uHandle);
if(vhaQuery.ulHWCaps & VHA_HWCAPS_IDCTMC)
printf("Hardware supports iScan, iDCT, and MC.\n");
if(vhaQuery.ulHWCaps & VHA_HWCAPS_SUBPIC)
printf("Hardware supports Sub-picture.\n");
printf("ulMinOvlyBuffer = %d\n", vhaQuery.ulMinOvlyBuffer);
printf("ulMaxOvlyBuffer = %d\n", vhaQuery.ulMaxOvlyBuffer);
#endif
return(vhaQuery.uHandle);
}
/* Create a new overlay */
struct vhar128_image * vhar128_newimage(unsigned int handle, unsigned long width, unsigned long height)
{
struct vhar128_image * image;
image = (struct vhar128_image *) malloc(sizeof *image);
image->overlay = (OVDESCRIPTION *) malloc(sizeof *image->overlay);
memset(image->overlay, 0, sizeof(OVDESCRIPTION));
image->overlay->uSize = sizeof(OVDESCRIPTION);
image->overlay->ulOVFormat = OV_FORMAT_YUV12;
image->overlay->uWidth = width;
image->overlay->uHeight = height;
CreateOVSurface(handle, image->overlay);
return(image);
}
/* Lock overlay */
void vhar128_lockimage(unsigned int handle, struct vhar128_image * image, SDL_Overlay * ov)
{
struct private_yuvhwdata * hwdata;
#ifdef DEBUG_R128VHA
/* show locked overlay */
SetOVSurface(handle, image->overlay);
#endif
hwdata = (struct private_yuvhwdata *) malloc(sizeof *hwdata);
hwdata->surface = (OVSURFACE *) malloc(sizeof *hwdata->surface);
hwdata->surface->uSize = sizeof(OVSURFACE);
LockOVSurface(handle, image->overlay, hwdata->surface);
/* create an SDL_Overlay from the information in the ATI overlay */
ov->format = SDL_YV12_OVERLAY;
ov->w = image->overlay->uWidth;
ov->h = image->overlay->uHeight;
ov->planes = 3;
ov->pitches = (Uint16 *) malloc(ov->planes * sizeof(Uint16));
ov->pitches[0] = hwdata->surface->uPitchPlane1;
ov->pitches[1] = hwdata->surface->uPitchPlane3;
ov->pitches[2] = hwdata->surface->uPitchPlane2;
ov->pixels = (Uint8 **) malloc(ov->planes * sizeof(void *));
ov->pixels[0] = (Uint8 *) hwdata->surface->pSurfPlane1;
ov->pixels[1] = (Uint8 *) hwdata->surface->pSurfPlane3;
ov->pixels[2] = (Uint8 *) hwdata->surface->pSurfPlane2;
ov->hwdata = hwdata;
}
/* Unlock the overlay */
void vhar128_unlockimage(unsigned int handle, struct vhar128_image * image, SDL_Overlay * ov)
{
UnlockOVSurface(handle, image->overlay, ov->hwdata->surface);
free(ov->pitches);
free(ov->pixels);
free(ov->hwdata->surface);
free(ov->hwdata);
}
/* Destroy the overlay */
void vhar128_destroyimage(unsigned int handle, struct vhar128_image * image)
{
DestroyOVSurface(handle, image->overlay);
free(image->overlay);
free(image);
}
/* Setup hardware decoding */
int vhar128_init(unsigned int handle, unsigned long width, unsigned long height, struct vhar128_image *ring[], int ring_size)
{
VHA_INIT vhaInit;
register int i;
memset(&vhaInit, 0, sizeof(VHA_INIT));
/* obtain yv12 offset and send it to vha */
for(i = 0; i < ring_size; i++)
{
vhaInit.yv12[i].ulOffsetY = ring[i]->overlay->OVOffset.ulOfsPlane1;
vhaInit.yv12[i].ulOffsetU = ring[i]->overlay->OVOffset.ulOfsPlane2;
vhaInit.yv12[i].ulOffsetV = ring[i]->overlay->OVOffset.ulOfsPlane3;
vhaInit.yv12[i].ulPitchY = ring[i]->overlay->OVOffset.uPitchPlane1;
vhaInit.yv12[i].ulPitchUV = ring[i]->overlay->OVOffset.uPitchPlane2;
}
vhaInit.ulNumYV12Buffer = ring_size;
vhaInit.uSize = sizeof(VHA_INIT);
vhaInit.ulHWSupports = VHA_HWCAPS_IDCTMC;
vhaInit.ulCodedWidth = width;
vhaInit.ulCodedHeight = height;
#ifdef DEBUG_R128VHA
/* set region for showing ATI overlay on the screen */
{
RCTL rSrc, rDst, rView;
rView.left = rView.top = 0;
rView.right = width;
rView.bottom = height;
rSrc.left = rSrc.top = 0;
rSrc.right = width;
rSrc.bottom = height;
rDst.left = 0;
rDst.top = 0;
rDst.right = width;
rDst.bottom = height;
UpdateOVPosition(handle, &rSrc, &rDst, &rView, OV_SHOW);
SetOVSurface(handle, ring[0]->overlay);
}
#endif
return(VHA_Init(handle, &vhaInit));
}
/* Setup decoding of a new picture */
int vhar128_newdecode(unsigned int handle, int back, int forw, int current)
{
VHA_NEWDECODE vhaND;
int retval;
memset(&vhaND, 0, sizeof(VHA_NEWDECODE));
vhaND.uSize = sizeof(VHA_NEWDECODE);
vhaND.BackwardRefFrame[0] = vhaND.BackwardRefFrame[1] = back;
vhaND.ForwardRefFrame[0] = vhaND.ForwardRefFrame[1] = forw;
vhaND.DecodeFrame = current;
vhaND.PictureStructure = VHA_PS_FRAME_PICTURE;
if((retval = VHA_NewDecode(handle, &vhaND)) != VHA_OK)
vhar128_perror("vhar128_newdecode", retval);
return(retval);
}
/* Send a macroblock to the hardware */
int vhar128_macroblock(unsigned int handle, int mb_x, int mb_y, int intra, int back, int forw, int mv_back_x, int mv_back_y, int mv_forw_x, int mv_forw_y, long runlevel[6][130])
{
VHA_MACROBLOCK vhaMB;
int retval;
memset(&vhaMB, 0, sizeof(VHA_MACROBLOCK));
vhaMB.ulSize = sizeof(VHA_MACROBLOCK);
memcpy(vhaMB.RunLevel, runlevel, 6*130*sizeof(long));
vhaMB.mb_x = mb_x;
vhaMB.mb_y = mb_y;
vhaMB.mbType = (intra)?VHA_MBT_INTRA:0;
if(forw) vhaMB.mbType |= VHA_MBT_MOTION_FORWARD;
if(back) vhaMB.mbType |= VHA_MBT_MOTION_BACKWARD;
vhaMB.PredictionType = VHA_PT_FRAME_BASED;
vhaMB.ScanType = SCAN_ZIG_ZAG;
vhaMB.dct_type = 0;
vhaMB.vector[0][0][0] = mv_forw_x;
vhaMB.vector[0][0][1] = mv_forw_y;
vhaMB.vector[0][1][0] = mv_back_x;
vhaMB.vector[0][1][1] = mv_back_y;
if((retval = VHA_Macroblock(handle, &vhaMB)) != VHA_OK)
vhar128_perror("vhar128_macroblock", retval);
return(retval);
}
/* Flush all macroblocks */
int vhar128_flush(unsigned int handle)
{
VHA_DECODECOMMAND vhaDC;
int retval;
memset(&vhaDC, 0, sizeof(VHA_DECODECOMMAND));
vhaDC.uSize = sizeof(VHA_DECODECOMMAND);
vhaDC.ulCommand = VHA_CMD_FLUSH;
if((retval = VHA_DecodeCommand(handle, &vhaDC)) != VHA_OK)
vhar128_perror("vhar128_flush", retval);
return(retval);
}
/* Close hardware decoding */
void vhar128_close(unsigned int handle)
{
VHA_Close(handle);
}
/* Close hardware access */
void vhar128_delete()
{
ATIHAP_CloseHWAccess();
}
#endif

30
smpeg/src/video/vhar128.h Normal file
View file

@ -0,0 +1,30 @@
/* ATI Rage128 video hardware acceleration */
#ifndef _VHAR128_H_
#define _VHAR128_H_
#include "SDL.h"
#ifdef __cplusplus
extern "C" {
#endif
struct vhar128_image;
unsigned int vhar128_new();
int vhar128_init(unsigned int handle, unsigned long width, unsigned long height, struct vhar128_image *ring[], int ring_size);
int vhar128_newdecode(unsigned int handle, int back, int forw, int current);
int vhar128_macroblock(unsigned int handle, int mb_x, int mb_y, int intra, int back, int forw, int mv_back_x, int mv_back_y, int mv_forw_x, int mv_forw_y, long runlevel[6][130]);
int vhar128_flush(unsigned int handle);
void vhar128_close(unsigned int handle);
void vhar128_delete();
struct vhar128_image * vhar128_newimage(unsigned int handle, unsigned long width, unsigned long height);
void vhar128_lockimage(unsigned int handle, struct vhar128_image * image, SDL_Overlay * surface);
void vhar128_unlockimage(unsigned int handle, struct vhar128_image * image, SDL_Overlay * surface);
void vhar128_destroyimage(unsigned int handle, struct vhar128_image * image);
#ifdef __cplusplus
};
#endif
#endif /* _VHAR128_H_ */

4682
smpeg/src/video/video.cpp Normal file

File diff suppressed because it is too large Load diff

460
smpeg/src/video/video.h Normal file
View file

@ -0,0 +1,460 @@
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* Portions of this software Copyright (c) 1995 Brown University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement
* is hereby granted, provided that the above copyright notice and the
* following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef MPEG_LIB_VIDEO_HEADER
#define MPEG_LIB_VIDEO_HEADER
#include <stdio.h>
/*
Changes to make the code reentrant:
deglobalized: ditherFlags, totNumFrames, realTimeStart, matched_depth,
filename, ditherType, curBits, ReconPMBlock statics, stream id
variables, Parse_done, swap, seekValue, input, EOF_flag, ReadPacket
statics, sys_layer, curVidStream, curVidStream, jmb_buf env (removed)
X globals now in xinfo: ditherType, visual, depth (also name), hints,
owncmFlag, et al
now const: scan
film_has_ended instead of FilmState
Additional changes:
if DISABLE_DITHER defined, don't compile dithering code
-lsh@cs.brown.edu (Loring Holden)
*/
#include "MPEGvideo.h"
#include "MPEGaudio.h"
typedef Sint32 INT32;
typedef Sint16 INT16;
typedef Sint8 INT8;
typedef Uint32 UINT32;
typedef Uint16 UINT16;
typedef Uint8 UINT8;
/* Define Parsing error codes. */
#define SKIP_PICTURE (-10)
#define SKIP_TO_START_CODE (-1)
#define PARSE_OK 1
/* Define BOOLEAN, TRUE, and FALSE. */
#define BOOLEAN int
#define TRUE 1
#define FALSE 0
/* Set ring buffer size. */
#define RING_BUF_SIZE 5
/* Macros for picture code type. */
#define I_TYPE 1
#define P_TYPE 2
#define B_TYPE 3
#define D_TYPE 4
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
#define SEQ_START_CODE 0x000001b3
#define GOP_START_CODE 0x000001b8
#define PICTURE_START_CODE 0x00000100
#define SLICE_MIN_START_CODE 0x00000101
#define SLICE_MAX_START_CODE 0x000001af
#define EXT_START_CODE 0x000001b5
#define USER_START_CODE 0x000001b2
#define SEQUENCE_ERROR_CODE 0x000001b4
/* Number of macroblocks to process in one call to mpegVidRsrc. */
#define MB_QUANTUM 100
/* Macros used with macroblock address decoding. */
#define MB_STUFFING 34
#define MB_ESCAPE 35
/* Lock flags for pict images. */
#define DISPLAY_LOCK 0x01
#define PAST_LOCK 0x02
#define FUTURE_LOCK 0x04
#define HYBRID_DITHER 0
#define HYBRID2_DITHER 1
#define FS4_DITHER 2
#define FS2_DITHER 3
#define FS2FAST_DITHER 4
#define Twox2_DITHER 5
#define GRAY_DITHER 6
#define FULL_COLOR_DITHER 7
#define NO_DITHER 8
#define ORDERED_DITHER 9
#define MONO_DITHER 10
#define MONO_THRESHOLD 11
#define ORDERED2_DITHER 12
#define MBORDERED_DITHER 13
#define GRAY256_DITHER 14
#define PPM_DITHER 15
#define FULL_COLOR2_DITHER 16
#define GRAY2_DITHER 17
#define GRAY2562_DITHER 18
#ifdef DISABLE_DITHER
#define IS_2x2_DITHER(a) (0)
#else
#define IS_2x2_DITHER(a) ((a) == Twox2_DITHER || (a) == FULL_COLOR2_DITHER || (a) == GRAY2_DITHER || (a) == (GRAY2562_DITHER))
#endif
/* Brown - changed to const int because it is a help variable */
extern const int scan[][8];
/* Structure with reconstructed pixel values. */
typedef struct pict_image {
#ifdef USE_ATI
struct vhar128_image *image;
#else
unsigned char *image; /* YV12 format image */
unsigned char *luminance; /* Luminance plane. */
unsigned char *Cr; /* Cr plane. */
unsigned char *Cb; /* Cb plane. */
#endif
unsigned short int *mb_qscale; /* macroblock info */
int locked; /* Lock flag. */
TimeStamp show_time; /* Presentation time. */
} PictImage;
/* Group of pictures structure. */
typedef struct GoP {
BOOLEAN drop_flag; /* Flag indicating dropped frame. */
unsigned int tc_hours; /* Hour component of time code. */
unsigned int tc_minutes; /* Minute component of time code. */
unsigned int tc_seconds; /* Second component of time code. */
unsigned int tc_pictures; /* Picture counter of time code. */
BOOLEAN closed_gop; /* Indicates no pred. vectors to
previous group of pictures. */
BOOLEAN broken_link; /* B frame unable to be decoded. */
char *ext_data; /* Extension data. */
char *user_data; /* User data. */
} GoP;
/* Picture structure. */
typedef struct pict {
unsigned int temp_ref; /* Temporal reference. */
unsigned int code_type; /* Frame type: P, B, I */
unsigned int vbv_delay; /* Buffer delay. */
BOOLEAN full_pel_forw_vector; /* Forw. vectors specified in full
pixel values flag. */
unsigned int forw_r_size; /* Used for vector decoding. */
unsigned int forw_f; /* Used for vector decoding. */
BOOLEAN full_pel_back_vector; /* Back vectors specified in full
pixel values flag. */
unsigned int back_r_size; /* Used in decoding. */
unsigned int back_f; /* Used in decoding. */
char *extra_info; /* Extra bit picture info. */
char *ext_data; /* Extension data. */
char *user_data; /* User data. */
} Pict;
/* Slice structure. */
typedef struct slice {
unsigned int vert_pos; /* Vertical position of slice. */
unsigned int quant_scale; /* Quantization scale. */
char *extra_info; /* Extra bit slice info. */
} Slice;
/* Macroblock structure. */
typedef struct macroblock {
int mb_address; /* Macroblock address. */
int past_mb_addr; /* Previous mblock address. */
int motion_h_forw_code; /* Forw. horiz. motion vector code. */
unsigned int motion_h_forw_r; /* Used in decoding vectors. */
int motion_v_forw_code; /* Forw. vert. motion vector code. */
unsigned int motion_v_forw_r; /* Used in decdoinge vectors. */
int motion_h_back_code; /* Back horiz. motion vector code. */
unsigned int motion_h_back_r; /* Used in decoding vectors. */
int motion_v_back_code; /* Back vert. motion vector code. */
unsigned int motion_v_back_r; /* Used in decoding vectors. */
unsigned int cbp; /* Coded block pattern. */
BOOLEAN mb_intra; /* Intracoded mblock flag. */
BOOLEAN bpict_past_forw; /* Past B frame forw. vector flag. */
BOOLEAN bpict_past_back; /* Past B frame back vector flag. */
int past_intra_addr; /* Addr of last intracoded mblock. */
int recon_right_for_prev; /* Past right forw. vector. */
int recon_down_for_prev; /* Past down forw. vector. */
int recon_right_back_prev; /* Past right back vector. */
int recon_down_back_prev; /* Past down back vector. */
} Macroblock;
/* Block structure. */
typedef struct block {
#ifdef USE_ATI
long int dct_recon[6][130]; /* Reconstructed dct runs & levels */
#else
short int dct_recon[8][8]; /* Reconstructed dct coeff matrix. */
#endif
short int dct_dc_y_past; /* Past lum. dc dct coefficient. */
short int dct_dc_cr_past; /* Past cr dc dct coefficient. */
short int dct_dc_cb_past; /* Past cb dc dct coefficient. */
} Block;
/* Video stream structure. */
typedef struct vid_stream {
unsigned int h_size; /* Horiz. size in pixels. */
unsigned int v_size; /* Vert. size in pixels. */
unsigned int mb_height; /* Vert. size in mblocks. */
unsigned int mb_width; /* Horiz. size in mblocks. */
unsigned char aspect_ratio; /* Code for aspect ratio. */
unsigned char picture_rate; /* Code for picture rate. */
unsigned int bit_rate; /* Bit rate. */
unsigned int vbv_buffer_size; /* Minimum buffer size. */
BOOLEAN const_param_flag; /* Contrained parameter flag. */
unsigned char intra_quant_matrix[8][8]; /* Quantization matrix for
intracoded frames. */
unsigned char non_intra_quant_matrix[8][8]; /* Quanitization matrix for
non intracoded frames. */
char *ext_data; /* Extension data. */
char *user_data; /* User data. */
GoP group; /* Current group of pict. */
Pict picture; /* Current picture. */
Slice slice; /* Current slice. */
Macroblock mblock; /* Current macroblock. */
Block block; /* Current block. */
int state; /* State of decoding. */
int bit_offset; /* Bit offset in stream. */
unsigned int *buffer; /* Pointer to next byte in
buffer. */
int buf_length; /* Length of remaining buffer.*/
unsigned int *buf_start; /* Pointer to buffer start. */
/* VC - beginning of added variables for noise computation */
short noise_base_matrix[8][8]; /* Square quantization error */
/* VC - end of added variables */
/* Brown - beginning of added variables that used to be static or global */
int max_buf_length; /* Max length of buffer. */
int film_has_ended; /* Boolean - film has ended */
unsigned int num_left; /* from ReadPacket - leftover */
unsigned int leftover_bytes; /* from ReadPacket - leftover */
int EOF_flag; /* stream is EOF */
BOOLEAN Parse_done; /* from read_sys */
int right_for,down_for; /* From ReconPMBlock, video.c */
int right_half_for, down_half_for;
unsigned int curBits; /* current bits */
int matched_depth; /* depth of displayed movie */
int ditherType; /* What type of dithering */
char *ditherFlags; /* flags for MB Ordered dither*/
int totNumFrames; /* Total Number of Frames */
double realTimeStart; /* When did the movie start? */
/* Brown - end of added variables */
PictImage *past; /* Past predictive frame. */
PictImage *future; /* Future predictive frame. */
PictImage *current; /* Current frame. */
PictImage *ring[RING_BUF_SIZE]; /* Ring buffer of frames. */
/* KR - beginning of added variables */
double rate_deal;
int _skipFrame;
double _skipCount;
int _jumpFrame;
double _oneFrameTime;
MPEGvideo* _smpeg;
/* KR - end of added variables */
/* SL - beginning of added variables for FPS calculation */
//#define CALCULATE_FPS
#define FPS_WINDOW 60
#ifdef CALCULATE_FPS
double frame_time[FPS_WINDOW];
int timestamp_index;
#endif
/* SL - end of added variables */
/* begining of added variables for system stream based sync */
double timestamp;
unsigned int *timestamp_mark;
bool timestamp_used;
/* begining of added variables */
bool need_frameadjust;
int current_frame;
#ifdef USE_ATI
unsigned int ati_handle;
#endif
} VidStream;
/* Declaration of global display pointer. */
/* Quiet mode flag. */
extern int quietFlag;
/* Flag controlling the "Press return" prompt */
extern int requireKeypressFlag;
/* Flag controlling speed vs. quality */
extern int qualityFlag;
/* Gamma correction stuff */
extern int gammaCorrectFlag;
extern double gammaCorrect;
/* Chroma correction stuff */
extern int chromaCorrectFlag;
extern double chromaCorrect;
/* Definition of Contant integer scale factor. */
#define CONST_BITS 13
/* Misc DCT definitions */
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
#define GLOBAL /* a function referenced thru EXTERNs */
typedef short DCTELEM;
typedef DCTELEM DCTBLOCK[DCTSIZE2];
#ifdef ANALYSIS
extern unsigned int bitCount;
extern int showEachFlag;
extern unsigned int cacheHit[8][8];
extern unsigned int cacheMiss[8][8];
#endif
#if !defined(__MIPSEL__) && (defined(MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(__mipsel) || defined(__mipsel__))
#define __MIPSEL__ 1
#endif
#if !defined(__MIPSEB__) && (defined(MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) || defined(__mipseb) || defined(__mipseb__))
#define __MIPSEB__ 1
#endif
#if !defined(__SPARC__) && (defined(SPARC) || defined(__SPARC) || defined(__SPARC__) || defined(__sparc) || defined(__sparc__))
#define __SPARC__ 1
#endif
#if !defined(__alpha__) && (defined(ALPHA) || defined(__ALPHA) || defined(__ALPHA__) || defined(__alpha))
#define __alpha__ 1
#endif
#if !defined(__680x0__) && (defined(__680x0) || defined(__680x0__))
#define __680x0__ 1
#endif
#if !defined(__AIX__) && (defined(AIX) || defined(_AIX) || defined(__AIX) || defined(__AIX__))
#define __AIX__ 1
#endif
#if !defined(__RS6000__) && (defined(__AIX__) || defined(RS6000) || defined(_RS6000) || defined(__RS6000) || defined(__RS6000__))
#define __RS6000__ 1
#endif
#if !defined(__HPUX__) && (defined(HPUX) || defined(_HPUX) || defined(__HPUX) || defined(__HPUX__))
#define __HPUX__ 1
#endif
#if !defined(__HPUX__) && (defined(hpux) || defined(_hpux) || defined(__hpux) || defined(__hpux__))
#define __HPUX__ 1
#endif
#if !defined(__VAX__) && (defined(VAX) || defined (__VAX))
#define __VAX__ 1
#endif
#if !defined(__SCO__) && (defined(SCO) || defined(__SCO) || defined(sco) || defined(__sco__))
#define __SCO__ 1
#endif
#if defined(__i386__) || defined(__VAX__) || defined(__MIPSEL__) || defined(__alpha__) || defined(__SCO__)
#undef BIG_ENDIAN_ARCHITECTURE
#define LITTLE_ENDIAN_ARCHITECTURE 1
#endif
#if defined(__RS6000__) || defined(__SPARC__) || defined(__mc68000__) || defined(__HPUX__) || defined(__MIPSEB__) || defined(convex) || defined(__convex__) || defined(__powerpc__)
#undef LITTLE_ENDIAN_ARCHITECTURE
#define BIG_ENDIAN_ARCHITECTURE 1
#endif
#if !defined(LITTLE_ENDIAN_ARCHITECTURE) && !defined(BIG_ENDIAN_ARCHITECTURE)
#ifdef WIN32
#undef BIG_ENDIAN_ARCHITECTURE
#define LITTLE_ENDIAN_ARCHITECTURE
#else
#ifdef __BIG_ENDIAN__
#undef LITTLE_ENDIAN_ARCHITECTURE
#define BIG_ENDIAN_ARCHITECTURE 1
#else
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#undef BIG_ENDIAN_ARCHITECTURE
#define LITTLE_ENDIAN_ARCHITECTURE 1
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#undef LITTLE_ENDIAN_ARCHITECTURE
#define BIG_ENDIAN_ARCHITECTURE 1
#endif
#endif
#endif
#endif
#if !defined(LITTLE_ENDIAN_ARCHITECTURE) && !defined(BIG_ENDIAN_ARCHITECTURE)
#error Unknown endianism of architecture
#endif
#ifdef __alpha__
#define SIXTYFOUR_BIT
#endif
/* Warnings that may help in debugging MPEG streams */
//#define VERBOSE_WARNINGS
//#define VERBOSE_DEBUG
#endif /* video.h already included */