mpg123-1.32.8

This commit is contained in:
Ozkan Sezer
2024-10-27 08:35:50 +03:00
parent 17c20ce2a0
commit 9102165ff5
25 changed files with 326 additions and 203 deletions

View File

@@ -30,6 +30,7 @@ The creator: Michael Hipp (email: hippm@informatik.uni-tuebingen.de - please bot
Contributions/ideas Thomas Orgis era (includes backports from mhipp trunk): Contributions/ideas Thomas Orgis era (includes backports from mhipp trunk):
Bill Roberts <bill.roberts@arm.com>: PAC/BTI for aarch64
Dave Yeo <dave.r.yeo@gmail.com>: continued OS/2 fixing Dave Yeo <dave.r.yeo@gmail.com>: continued OS/2 fixing
madebr and manx: github mirror and CI madebr and manx: github mirror and CI
Vitaly Kirsanov <krokoziabla@gmail.com>: ports/cmake (optional CMake build) Vitaly Kirsanov <krokoziabla@gmail.com>: ports/cmake (optional CMake build)

View File

@@ -565,17 +565,17 @@ am__src_libmpg123_libmpg123_la_SOURCES_DIST = \
src/libmpg123/lfs_wrap.h src/libmpg123/costabs.h \ src/libmpg123/lfs_wrap.h src/libmpg123/costabs.h \
src/libmpg123/tabinit.c src/libmpg123/libmpg123.c \ src/libmpg123/tabinit.c src/libmpg123/libmpg123.c \
src/libmpg123/gapless.h src/libmpg123/mpg123lib_intern.h \ src/libmpg123/gapless.h src/libmpg123/mpg123lib_intern.h \
src/libmpg123/mangle.h src/libmpg123/getcpuflags.h \ src/libmpg123/mangle.h src/libmpg123/aarch64_defs.h \
src/libmpg123/index.h src/libmpg123/index.c \ src/libmpg123/getcpuflags.h src/libmpg123/index.h \
src/libmpg123/layer1.c src/libmpg123/layer2.c \ src/libmpg123/index.c src/libmpg123/layer1.c \
src/libmpg123/layer3.c src/libmpg123/equalizer.c \ src/libmpg123/layer2.c src/libmpg123/layer3.c \
src/libmpg123/dither.c src/libmpg123/synth_8bit.c \ src/libmpg123/equalizer.c src/libmpg123/dither.c \
src/libmpg123/synth.c src/libmpg123/synth_s32.c \ src/libmpg123/synth_8bit.c src/libmpg123/synth.c \
src/libmpg123/synth_real.c src/libmpg123/lfs_wrap.c \ src/libmpg123/synth_s32.c src/libmpg123/synth_real.c \
src/libmpg123/icy.c src/libmpg123/icy2utf8.c \ src/libmpg123/lfs_wrap.c src/libmpg123/icy.c \
src/libmpg123/feature.c src/libmpg123/ntom.c \ src/libmpg123/icy2utf8.c src/libmpg123/feature.c \
src/libmpg123/stringbuf.c src/libmpg123/getcpuflags.S \ src/libmpg123/ntom.c src/libmpg123/stringbuf.c \
src/libmpg123/getcpuflags_x86_64.S \ src/libmpg123/getcpuflags.S src/libmpg123/getcpuflags_x86_64.S \
src/libmpg123/getcpuflags_arm.c src/libmpg123/check_neon.S \ src/libmpg123/getcpuflags_arm.c src/libmpg123/check_neon.S \
src/libmpg123/synth_altivec.c src/libmpg123/dct64_altivec.c \ src/libmpg123/synth_altivec.c src/libmpg123/dct64_altivec.c \
src/libmpg123/dct64_i386.c src/libmpg123/synth_i486.c \ src/libmpg123/dct64_i386.c src/libmpg123/synth_i486.c \
@@ -2961,6 +2961,7 @@ src_compat_libcompat_dl_la_LIBADD = @LIBDL@
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/gapless.h \ @NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/gapless.h \
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/mpg123lib_intern.h \ @NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/mpg123lib_intern.h \
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/mangle.h \ @NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/mangle.h \
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/aarch64_defs.h \
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/getcpuflags.h \ @NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/getcpuflags.h \
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/index.h \ @NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/index.h \
@NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/index.c \ @NEED_LIB_TRUE@@NEED_MAINLIB_TRUE@ src/libmpg123/index.c \

11
NEWS
View File

@@ -1,3 +1,14 @@
1.32.8
------
- libmpg123:
-- Add sections to assembly to support PAC/BTI code
for aarch64 (-mbranch-protection variants), thanks to Bill Roberts
(github PR 15).
-- Prevent premature application of header info into decoding structure,
at worst having triggered out-of-bounds writes of decoded PCM data
(bug 322, again).
- out123: Show --quiet in --longhelp.
1.32.7 1.32.7
------ ------
- ports/cmake: Work around bug in CMake that does not detect FPU on - ports/cmake: Work around bug in CMake that does not detect FPU on

20
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for mpg123 1.32.7. # Generated by GNU Autoconf 2.71 for mpg123 1.32.8.
# #
# Report bugs to <maintainer@mpg123.org>. # Report bugs to <maintainer@mpg123.org>.
# #
@@ -621,8 +621,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='mpg123' PACKAGE_NAME='mpg123'
PACKAGE_TARNAME='mpg123' PACKAGE_TARNAME='mpg123'
PACKAGE_VERSION='1.32.7' PACKAGE_VERSION='1.32.8'
PACKAGE_STRING='mpg123 1.32.7' PACKAGE_STRING='mpg123 1.32.8'
PACKAGE_BUGREPORT='maintainer@mpg123.org' PACKAGE_BUGREPORT='maintainer@mpg123.org'
PACKAGE_URL='' PACKAGE_URL=''
@@ -1727,7 +1727,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures mpg123 1.32.7 to adapt to many kinds of systems. \`configure' configures mpg123 1.32.8 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1798,7 +1798,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of mpg123 1.32.7:";; short | recursive ) echo "Configuration of mpg123 1.32.8:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -2076,7 +2076,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
mpg123 configure 1.32.7 mpg123 configure 1.32.8
generated by GNU Autoconf 2.71 generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc. Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2621,7 +2621,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by mpg123 $as_me 1.32.7, which was It was created by mpg123 $as_me 1.32.8, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@@ -3991,7 +3991,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='mpg123' PACKAGE='mpg123'
VERSION='1.32.7' VERSION='1.32.8'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -22453,7 +22453,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by mpg123 $as_me 1.32.7, which was This file was extended by mpg123 $as_me 1.32.8, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -22521,7 +22521,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
mpg123 config.status 1.32.7 mpg123 config.status 1.32.8
configured by $0, generated by GNU Autoconf 2.71, configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@@ -3,7 +3,7 @@
# - devel packages for alsa, sdl, etc... to build the respective output modules. # - devel packages for alsa, sdl, etc... to build the respective output modules.
Summary: The fast console mpeg audio decoder/player. Summary: The fast console mpeg audio decoder/player.
Name: mpg123 Name: mpg123
Version: 1.32.7 Version: 1.32.8
Release: 1 Release: 1
URL: http://www.mpg123.org/ URL: http://www.mpg123.org/
License: GPL License: GPL

View File

@@ -67,6 +67,7 @@ src_libmpg123_libmpg123_la_SOURCES = \
src/libmpg123/gapless.h \ src/libmpg123/gapless.h \
src/libmpg123/mpg123lib_intern.h \ src/libmpg123/mpg123lib_intern.h \
src/libmpg123/mangle.h \ src/libmpg123/mangle.h \
src/libmpg123/aarch64_defs.h \
src/libmpg123/getcpuflags.h \ src/libmpg123/getcpuflags.h \
src/libmpg123/index.h \ src/libmpg123/index.h \
src/libmpg123/index.c src/libmpg123/index.c

View File

@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: LGPL-2.1
*
* aarch64_defs.h: Support macros for the aarch64 architectural features
*/
#ifndef SRC_LIBMPG123_AARCH64_DEFS_H_
#define SRC_LIBMPG123_AARCH64_DEFS_H_
/*
* Guard this header so arm assembly files can just include it without the need
* to if-def each instance.
*/
#ifdef __aarch64__
/*
* References:
* - https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros
* - https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst
*/
#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1
#define GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */
#else
#define GNU_PROPERTY_AARCH64_BTI 0
#endif
#if defined(__ARM_FEATURE_PAC_DEFAULT)
#define GNU_PROPERTY_AARCH64_POINTER_AUTH 2 /* bit 1 GNU Notes is for PAC support */
#else
#define GNU_PROPERTY_AARCH64_POINTER_AUTH 0
#endif
/* Add the BTI support to GNU Notes section */
#if defined(__ASSEMBLER__) && defined(__ELF__)
#if GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_POINTER_AUTH != 0
.pushsection .note.gnu.property, "a"; /* Start a new allocatable section */
.balign 8; /* align it on a byte boundry */
.long 4; /* size of "GNU\0" */
.long 0x10; /* size of descriptor */
.long 0x5; /* NT_GNU_PROPERTY_TYPE_0 */
.asciz "GNU";
.long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
.long 4; /* Four bytes of data */
.long (GNU_PROPERTY_AARCH64_BTI|GNU_PROPERTY_AARCH64_POINTER_AUTH); /* BTI or PAC is enabled */
.long 0; /* padding for 8 byte alignment */
.popsection; /* end the section */
#endif /* GNU Notes additions */
#endif /* if __ASSEMBLER__ and __ELF__ */
#endif /* __arch64__ */
#endif /* SRC_LIBMPG123_AARCH64_DEFS_H_ */

View File

@@ -6,6 +6,7 @@
initially written by Taihei Momma initially written by Taihei Momma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __aarch64__ #ifndef __aarch64__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -511,6 +511,7 @@ static void frame_fixed_reset(mpg123_handle *fr)
{ {
frame_icy_reset(fr); frame_icy_reset(fr);
INT123_open_bad(fr); INT123_open_bad(fr);
memset(&(fr->hdr), 0, sizeof(fr->hdr));
fr->to_decode = FALSE; fr->to_decode = FALSE;
fr->to_ignore = FALSE; fr->to_ignore = FALSE;
fr->metaflags = 0; fr->metaflags = 0;
@@ -524,15 +525,12 @@ static void frame_fixed_reset(mpg123_handle *fr)
fr->clip = 0; fr->clip = 0;
fr->oldhead = 0; fr->oldhead = 0;
fr->firsthead = 0; fr->firsthead = 0;
fr->lay = 0;
fr->vbr = MPG123_CBR; fr->vbr = MPG123_CBR;
fr->abr_rate = 0; fr->abr_rate = 0;
fr->track_frames = 0; fr->track_frames = 0;
fr->track_samples = -1; fr->track_samples = -1;
fr->framesize=0;
fr->mean_frames = 0; fr->mean_frames = 0;
fr->mean_framesize = 0; fr->mean_framesize = 0;
fr->freesize = 0;
fr->lastscale = -1; fr->lastscale = -1;
fr->rva.level[0] = -1; fr->rva.level[0] = -1;
fr->rva.level[1] = -1; fr->rva.level[1] = -1;
@@ -567,8 +565,7 @@ static void frame_fixed_reset(mpg123_handle *fr)
fr->icy.next = 0; fr->icy.next = 0;
#endif #endif
fr->halfphase = 0; /* here or indeed only on first-time init? */ fr->halfphase = 0; /* here or indeed only on first-time init? */
fr->error_protection = 0; fr->hdr.freeformat_framesize = fr->p.freeformat_framesize;
fr->freeformat_framesize = fr->p.freeformat_framesize;
fr->enc_delay = -1; fr->enc_delay = -1;
fr->enc_padding = -1; fr->enc_padding = -1;
memset(fr->id3buf, 0, sizeof(fr->id3buf)); memset(fr->id3buf, 0, sizeof(fr->id3buf));
@@ -627,7 +624,7 @@ int attribute_align_arg mpg123_framedata(mpg123_handle *mh, unsigned long *heade
if(header != NULL) *header = mh->oldhead; if(header != NULL) *header = mh->oldhead;
if(bodydata != NULL) *bodydata = mh->bsbuf; if(bodydata != NULL) *bodydata = mh->bsbuf;
if(bodybytes != NULL) *bodybytes = mh->framesize; if(bodybytes != NULL) *bodybytes = mh->hdr.framesize;
return MPG123_OK; return MPG123_OK;
} }
@@ -900,9 +897,9 @@ static int64_t ignoreframe(mpg123_handle *fr)
{ {
int64_t preshift = fr->p.preframes; int64_t preshift = fr->p.preframes;
/* Layer 3 _really_ needs at least one frame before. */ /* Layer 3 _really_ needs at least one frame before. */
if(fr->lay==3 && preshift < 1) preshift = 1; if(fr->hdr.lay==3 && preshift < 1) preshift = 1;
/* Layer 1 & 2 reall do not need more than 2. */ /* Layer 1 & 2 reall do not need more than 2. */
if(fr->lay!=3 && preshift > 2) preshift = 2; if(fr->hdr.lay!=3 && preshift > 2) preshift = 2;
return fr->firstframe - preshift; return fr->firstframe - preshift;
} }
@@ -949,7 +946,7 @@ void INT123_frame_set_frameseek(mpg123_handle *fr, int64_t fe)
void INT123_frame_skip(mpg123_handle *fr) void INT123_frame_skip(mpg123_handle *fr)
{ {
#ifndef NO_LAYER3 #ifndef NO_LAYER3
if(fr->lay == 3) INT123_set_pointer(fr, 1, 512); if(fr->hdr.lay == 3) INT123_set_pointer(fr, 1, 512);
#endif #endif
} }

View File

@@ -96,6 +96,33 @@ enum frame_state_flags
,FRAME_DECODER_LIVE = 0x8 /**< 1000 Decoder can be used. */ ,FRAME_DECODER_LIVE = 0x8 /**< 1000 Decoder can be used. */
}; };
// separate frame header structure for safe decoding of headers without
// modifying the main frame struct before we are sure that we can read a
// frame into it
struct frame_header
{
int lay;
// lots of flags that could share storage, should reform that
int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */
int mpeg25;
int error_protection;
int bitrate_index;
int sampling_frequency;
int padding;
int extension;
int mode;
int mode_ext;
int copyright;
int original;
int emphasis;
// Even 16 bit int is enough for MAXFRAMESIZE
int framesize; /* computed framesize */
int freeformat;
int freeformat_framesize;
// Derived from header and checked against the above.
int ssize;
};
/* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */ /* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */
struct mpg123_handle_struct struct mpg123_handle_struct
{ {
@@ -197,26 +224,12 @@ struct mpg123_handle_struct
int single; int single;
int II_sblimit; int II_sblimit;
int down_sample_sblimit; int down_sample_sblimit;
int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */
/* Many flags in disguise as integers... wasting bytes. */ /* Many flags in disguise as integers... wasting bytes. */
int mpeg25;
int down_sample; int down_sample;
int header_change; int header_change;
int lay; struct frame_header hdr;
long spf; /* cached count of samples per frame */ long spf; /* cached count of samples per frame */
int (*do_layer)(mpg123_handle *); int (*do_layer)(mpg123_handle *);
int error_protection;
int bitrate_index;
int sampling_frequency;
int padding;
int extension;
int mode;
int mode_ext;
int copyright;
int original;
int emphasis;
int framesize; /* computed framesize */
int freesize; /* free format frame size */
enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */ enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */
int64_t num; /* frame offset ... */ int64_t num; /* frame offset ... */
int64_t input_offset; /* byte offset of this frame in input stream */ int64_t input_offset; /* byte offset of this frame in input stream */
@@ -225,8 +238,6 @@ struct mpg123_handle_struct
int state_flags; int state_flags;
char silent_resync; /* Do not complain for the next n resyncs. */ char silent_resync; /* Do not complain for the next n resyncs. */
unsigned char* xing_toc; /* The seek TOC from Xing header. */ unsigned char* xing_toc; /* The seek TOC from Xing header. */
int freeformat;
long freeformat_framesize;
/* bitstream info; bsi */ /* bitstream info; bsi */
int bitindex; int bitindex;
@@ -253,7 +264,6 @@ struct mpg123_handle_struct
double mean_framesize; double mean_framesize;
int64_t mean_frames; int64_t mean_frames;
int fsizeold; int fsizeold;
int ssize;
unsigned int bitreservoir; unsigned int bitreservoir;
unsigned char bsspace[2][MAXFRAMESIZE+512+4]; /* MAXFRAMESIZE */ unsigned char bsspace[2][MAXFRAMESIZE+512+4]; /* MAXFRAMESIZE */
unsigned char *bsbuf; unsigned char *bsbuf;

View File

@@ -217,7 +217,7 @@ int INT123_do_layer1(mpg123_handle *fr)
real (*fraction)[SBLIMIT] = fr->layer1.fraction; /* fraction[2][SBLIMIT] */ real (*fraction)[SBLIMIT] = fr->layer1.fraction; /* fraction[2][SBLIMIT] */
int single = fr->single; int single = fr->single;
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32; fr->jsbound = (fr->hdr.mode == MPG_MD_JOINT_STEREO) ? (fr->hdr.mode_ext<<2)+4 : 32;
if(stereo == 1 || single == SINGLE_MIX) /* I don't see mixing handled here */ if(stereo == 1 || single == SINGLE_MIX) /* I don't see mixing handled here */
single = SINGLE_LEFT; single = SINGLE_LEFT;

View File

@@ -313,10 +313,10 @@ static void II_select_table(mpg123_handle *fr)
const struct al_table *tables[5] = { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 }; const struct al_table *tables[5] = { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
const int sblims[5] = { 27 , 30 , 8, 12 , 30 }; const int sblims[5] = { 27 , 30 , 8, 12 , 30 };
if(fr->sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */ if(fr->hdr.sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */
table = 4; table = 4;
else else
table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index]; table = translate[fr->hdr.sampling_frequency][2-fr->stereo][fr->hdr.bitrate_index];
sblim = sblims[table]; sblim = sblims[table];
fr->alloc = tables[table]; fr->alloc = tables[table];
@@ -337,7 +337,7 @@ int INT123_do_layer2(mpg123_handle *fr)
int single = fr->single; int single = fr->single;
II_select_table(fr); II_select_table(fr);
fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : fr->II_sblimit; fr->jsbound = (fr->hdr.mode == MPG_MD_JOINT_STEREO) ? (fr->hdr.mode_ext<<2)+4 : fr->II_sblimit;
if(fr->jsbound > fr->II_sblimit) if(fr->jsbound > fr->II_sblimit)
{ {

View File

@@ -135,16 +135,16 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
int powdiff = (single == SINGLE_MIX) ? 4 : 0; int powdiff = (single == SINGLE_MIX) ? 4 : 0;
const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } }; const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
const int *tab = tabs[fr->lsf]; const int *tab = tabs[fr->hdr.lsf];
{ /* First ensure we got enough bits available. */ { /* First ensure we got enough bits available. */
unsigned int needbits = 0; unsigned int needbits = 0;
needbits += tab[1]; /* main_data_begin */ needbits += tab[1]; /* main_data_begin */
needbits += stereo == 1 ? tab[2] : tab[3]; /* private */ needbits += stereo == 1 ? tab[2] : tab[3]; /* private */
if(!fr->lsf) if(!fr->hdr.lsf)
needbits += stereo*4; /* scfsi */ needbits += stereo*4; /* scfsi */
/* For each granule for each channel ... */ /* For each granule for each channel ... */
needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->lsf?1:0)+2); needbits += tab[0]*stereo*(29+tab[4]+1+22+(!fr->hdr.lsf?1:0)+2);
if(fr->bits_avail < needbits) \ if(fr->bits_avail < needbits) \
{ {
if(NOQUIET) if(NOQUIET)
@@ -162,7 +162,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
/* overwrite main_data_begin for the really available bit reservoir */ /* overwrite main_data_begin for the really available bit reservoir */
backbits(fr, tab[1]); backbits(fr, tab[1]);
if(fr->lsf == 0) if(fr->hdr.lsf == 0)
{ {
fr->wordpointer[0] = (unsigned char) (fr->bitreservoir >> 1); fr->wordpointer[0] = (unsigned char) (fr->bitreservoir >> 1);
fr->wordpointer[1] = (unsigned char) ((fr->bitreservoir & 1) << 7); fr->wordpointer[1] = (unsigned char) ((fr->bitreservoir & 1) << 7);
@@ -171,7 +171,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
/* zero "side-info" data for a silence-frame /* zero "side-info" data for a silence-frame
without touching audio data used as bit reservoir for following frame */ without touching audio data used as bit reservoir for following frame */
memset(fr->wordpointer+2, 0, fr->ssize-2); memset(fr->wordpointer+2, 0, fr->hdr.ssize-2);
/* reread the new bit reservoir offset */ /* reread the new bit reservoir offset */
si->main_data_begin = getbits(fr, tab[1]); si->main_data_begin = getbits(fr, tab[1]);
@@ -179,11 +179,11 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
/* Keep track of the available data bytes for the bit reservoir. /* Keep track of the available data bytes for the bit reservoir.
CRC is included in ssize already. */ CRC is included in ssize already. */
fr->bitreservoir = fr->bitreservoir + fr->framesize - fr->ssize; fr->bitreservoir = fr->bitreservoir + fr->hdr.framesize - fr->hdr.ssize;
/* Limit the reservoir to the max for MPEG 1.0 or 2.x . */ /* Limit the reservoir to the max for MPEG 1.0 or 2.x . */
if(fr->bitreservoir > (unsigned int) (fr->lsf == 0 ? 511 : 255)) if(fr->bitreservoir > (unsigned int) (fr->hdr.lsf == 0 ? 511 : 255))
fr->bitreservoir = (fr->lsf == 0 ? 511 : 255); fr->bitreservoir = (fr->hdr.lsf == 0 ? 511 : 255);
/* Now back into less commented territory. It's code. It works. */ /* Now back into less commented territory. It's code. It works. */
@@ -192,7 +192,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
else else
si->private_bits = getbits(fr, tab[3]); si->private_bits = getbits(fr, tab[3]);
if(!fr->lsf) for(ch=0; ch<stereo; ch++) if(!fr->hdr.lsf) for(ch=0; ch<stereo; ch++)
{ {
si->ch[ch].gr[0].scfsi = -1; si->ch[ch].gr[0].scfsi = -1;
si->ch[ch].gr[1].scfsi = getbits(fr, 4); si->ch[ch].gr[1].scfsi = getbits(fr, 4);
@@ -257,14 +257,14 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
} }
/* region_count/start parameters are implicit in this case. */ /* region_count/start parameters are implicit in this case. */
if( (!fr->lsf || (gr_info->block_type == 2)) && !fr->mpeg25) if( (!fr->hdr.lsf || (gr_info->block_type == 2)) && !fr->hdr.mpeg25)
{ {
gr_info->region1start = 36>>1; gr_info->region1start = 36>>1;
gr_info->region2start = 576>>1; gr_info->region2start = 576>>1;
} }
else else
{ {
if(fr->mpeg25) if(fr->hdr.mpeg25)
{ {
int r0c,r1c; int r0c,r1c;
if((gr_info->block_type == 2) && (!gr_info->mixed_block_flag) ) r0c = 5; if((gr_info->block_type == 2) && (!gr_info->mixed_block_flag) ) r0c = 5;
@@ -299,7 +299,7 @@ static int III_get_side_info(mpg123_handle *fr, struct III_sideinfo *si,int ster
gr_info->block_type = 0; gr_info->block_type = 0;
gr_info->mixed_block_flag = 0; gr_info->mixed_block_flag = 0;
} }
if(!fr->lsf) gr_info->preflag = get1bit(fr); if(!fr->hdr.lsf) gr_info->preflag = get1bit(fr);
gr_info->scalefac_scale = get1bit(fr); gr_info->scalefac_scale = get1bit(fr);
gr_info->count1table_select = get1bit(fr); gr_info->count1table_select = get1bit(fr);
@@ -1824,7 +1824,7 @@ int INT123_do_layer3(mpg123_handle *fr)
int stereo = fr->stereo; int stereo = fr->stereo;
int single = fr->single; int single = fr->single;
int ms_stereo,i_stereo; int ms_stereo,i_stereo;
int sfreq = fr->sampling_frequency; int sfreq = fr->hdr.sampling_frequency;
int stereo1,granules; int stereo1,granules;
if(stereo == 1) if(stereo == 1)
@@ -1837,14 +1837,14 @@ int INT123_do_layer3(mpg123_handle *fr)
else else
stereo1 = 2; stereo1 = 2;
if(fr->mode == MPG_MD_JOINT_STEREO) if(fr->hdr.mode == MPG_MD_JOINT_STEREO)
{ {
ms_stereo = (fr->mode_ext & 0x2)>>1; ms_stereo = (fr->hdr.mode_ext & 0x2)>>1;
i_stereo = fr->mode_ext & 0x1; i_stereo = fr->hdr.mode_ext & 0x1;
} }
else ms_stereo = i_stereo = 0; else ms_stereo = i_stereo = 0;
granules = fr->lsf ? 1 : 2; granules = fr->hdr.lsf ? 1 : 2;
/* quick hack to keep the music playing */ /* quick hack to keep the music playing */
/* after having seen this nasty test file... */ /* after having seen this nasty test file... */
@@ -1859,7 +1859,7 @@ int INT123_do_layer3(mpg123_handle *fr)
if(fr->pinfo) if(fr->pinfo)
{ {
fr->pinfo->maindata = sideinfo.main_data_begin; fr->pinfo->maindata = sideinfo.main_data_begin;
fr->pinfo->padding = fr->padding; fr->pinfo->padding = fr->hdr.padding;
} }
#endif #endif
for(gr=0;gr<granules;gr++) for(gr=0;gr<granules;gr++)
@@ -1880,7 +1880,7 @@ int INT123_do_layer3(mpg123_handle *fr)
, gr_info->part2_3_length, fr->bits_avail ); , gr_info->part2_3_length, fr->bits_avail );
return clip; return clip;
} }
if(fr->lsf) if(fr->hdr.lsf)
part2bits = III_get_scale_factors_2(fr, scalefacs[0],gr_info,0); part2bits = III_get_scale_factors_2(fr, scalefacs[0],gr_info,0);
else else
part2bits = III_get_scale_factors_1(fr, scalefacs[0],gr_info,0,gr); part2bits = III_get_scale_factors_1(fr, scalefacs[0],gr_info,0,gr);
@@ -1920,7 +1920,7 @@ int INT123_do_layer3(mpg123_handle *fr)
{ {
struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]); struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
long part2bits; long part2bits;
if(fr->lsf) if(fr->hdr.lsf)
part2bits = III_get_scale_factors_2(fr, scalefacs[1],gr_info,i_stereo); part2bits = III_get_scale_factors_2(fr, scalefacs[1],gr_info,i_stereo);
else else
part2bits = III_get_scale_factors_1(fr, scalefacs[1],gr_info,1,gr); part2bits = III_get_scale_factors_1(fr, scalefacs[1],gr_info,1,gr);
@@ -1970,7 +1970,7 @@ int INT123_do_layer3(mpg123_handle *fr)
} }
} }
if(i_stereo) III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->lsf); if(i_stereo) III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->hdr.lsf);
if(ms_stereo || i_stereo || (single == SINGLE_MIX) ) if(ms_stereo || i_stereo || (single == SINGLE_MIX) )
{ {

View File

@@ -457,7 +457,7 @@ int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key
theval = mh->enc_padding; theval = mh->enc_padding;
break; break;
case MPG123_DEC_DELAY: case MPG123_DEC_DELAY:
theval = mh->lay == 3 ? GAPLESS_DELAY : -1; theval = mh->hdr.lay == 3 ? GAPLESS_DELAY : -1;
break; break;
default: default:
mh->err = MPG123_BAD_KEY; mh->err = MPG123_BAD_KEY;
@@ -1241,10 +1241,10 @@ static int init_track(mpg123_handle *mh)
b = init_track(mh); \ b = init_track(mh); \
if(b < 0) return b; \ if(b < 0) return b; \
\ \
mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0); \ mi->version = mh->hdr.mpeg25 ? MPG123_2_5 : (mh->hdr.lsf ? MPG123_2_0 : MPG123_1_0); \
mi->layer = mh->lay; \ mi->layer = mh->hdr.lay; \
mi->rate = INT123_frame_freq(mh); \ mi->rate = INT123_frame_freq(mh); \
switch(mh->mode) \ switch(mh->hdr.mode) \
{ \ { \
case 0: mi->mode = MPG123_M_STEREO; break; \ case 0: mi->mode = MPG123_M_STEREO; break; \
case 1: mi->mode = MPG123_M_JOINT; break; \ case 1: mi->mode = MPG123_M_JOINT; break; \
@@ -1252,14 +1252,14 @@ static int init_track(mpg123_handle *mh)
case 3: mi->mode = MPG123_M_MONO; break; \ case 3: mi->mode = MPG123_M_MONO; break; \
default: mi->mode = 0; /* Nothing good to do here. */ \ default: mi->mode = 0; /* Nothing good to do here. */ \
} \ } \
mi->mode_ext = mh->mode_ext; \ mi->mode_ext = mh->hdr.mode_ext; \
mi->framesize = mh->framesize+4; /* Include header. */ \ mi->framesize = mh->hdr.framesize+4; /* Include header. */ \
mi->flags = 0; \ mi->flags = 0; \
if(mh->error_protection) mi->flags |= MPG123_CRC; \ if(mh->hdr.error_protection) mi->flags |= MPG123_CRC; \
if(mh->copyright) mi->flags |= MPG123_COPYRIGHT; \ if(mh->hdr.copyright) mi->flags |= MPG123_COPYRIGHT; \
if(mh->extension) mi->flags |= MPG123_PRIVATE; \ if(mh->hdr.extension) mi->flags |= MPG123_PRIVATE; \
if(mh->original) mi->flags |= MPG123_ORIGINAL; \ if(mh->hdr.original) mi->flags |= MPG123_ORIGINAL; \
mi->emphasis = mh->emphasis; \ mi->emphasis = mh->hdr.emphasis; \
mi->bitrate = INT123_frame_bitrate(mh); \ mi->bitrate = INT123_frame_bitrate(mh); \
mi->abr_rate = mh->abr_rate; \ mi->abr_rate = mh->abr_rate; \
mi->vbr = mh->vbr; \ mi->vbr = mh->vbr; \

View File

@@ -63,9 +63,10 @@ static const int tabsel_123[2][3][16] =
static const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; static const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count); static int decode_header(mpg123_handle *fr, struct frame_header *hdr, unsigned long newhead, int *freeformat_count);
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount); static void apply_header(mpg123_handle *fr, struct frame_header *hdr);
static int do_readahead(mpg123_handle *fr, unsigned long newhead); static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount, struct frame_header *nhdr);
static int do_readahead(mpg123_handle *fr, struct frame_header *nhdr, unsigned long newhead);
static int wetwork(mpg123_handle *fr, unsigned long *newheadp); static int wetwork(mpg123_handle *fr, unsigned long *newheadp);
/* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/ /* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/
@@ -73,12 +74,12 @@ static int wetwork(mpg123_handle *fr, unsigned long *newheadp);
int INT123_frame_bitrate(mpg123_handle *fr) int INT123_frame_bitrate(mpg123_handle *fr)
{ {
return tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index]; return tabsel_123[fr->hdr.lsf][fr->hdr.lay-1][fr->hdr.bitrate_index];
} }
long INT123_frame_freq(mpg123_handle *fr) long INT123_frame_freq(mpg123_handle *fr)
{ {
return freqs[fr->sampling_frequency]; return freqs[fr->hdr.sampling_frequency];
} }
/* compiler is smart enought to inline this one or should I really do it as macro...? */ /* compiler is smart enought to inline this one or should I really do it as macro...? */
@@ -141,8 +142,8 @@ static int check_lame_tag(mpg123_handle *fr)
Mono 17 9 Mono 17 9
*/ */
int lame_offset = (fr->stereo == 2) int lame_offset = (fr->stereo == 2)
? (fr->lsf ? 17 : 32) ? (fr->hdr.lsf ? 17 : 32)
: (fr->lsf ? 9 : 17); : (fr->hdr.lsf ? 9 : 17);
if(fr->p.flags & MPG123_IGNORE_INFOFRAME) goto check_lame_tag_no; if(fr->p.flags & MPG123_IGNORE_INFOFRAME) goto check_lame_tag_no;
@@ -154,7 +155,7 @@ static int check_lame_tag(mpg123_handle *fr)
for the actual data, have to check if each byte of information is present. for the actual data, have to check if each byte of information is present.
But: 4 B Info/Xing + 4 B flags is bare minimum. But: 4 B Info/Xing + 4 B flags is bare minimum.
*/ */
if(fr->framesize < lame_offset+8) goto check_lame_tag_no; if(fr->hdr.framesize < lame_offset+8) goto check_lame_tag_no;
/* only search for tag when all zero before it (apart from checksum) */ /* only search for tag when all zero before it (apart from checksum) */
for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) goto check_lame_tag_no; for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) goto check_lame_tag_no;
@@ -190,7 +191,7 @@ static int check_lame_tag(mpg123_handle *fr)
/* From now on, I have to carefully check if the announced data is actually /* From now on, I have to carefully check if the announced data is actually
there! I'm always returning 'yes', though. */ there! I'm always returning 'yes', though. */
#define check_bytes_left(n) if(fr->framesize < lame_offset+n) \ #define check_bytes_left(n) if(fr->hdr.framesize < lame_offset+n) \
goto check_lame_tag_yes goto check_lame_tag_yes
if(xing_flags & 1) /* total bitstream frames */ if(xing_flags & 1) /* total bitstream frames */
{ {
@@ -443,10 +444,10 @@ static int head_compatible(unsigned long fred, unsigned long bret)
static void halfspeed_prepare(mpg123_handle *fr) static void halfspeed_prepare(mpg123_handle *fr)
{ {
/* save for repetition */ /* save for repetition */
if(fr->p.halfspeed && fr->lay == 3) if(fr->p.halfspeed && fr->hdr.lay == 3)
{ {
debug("halfspeed - reusing old bsbuf "); debug("halfspeed - reusing old bsbuf ");
memcpy (fr->ssave, fr->bsbuf, fr->ssize); memcpy (fr->ssave, fr->bsbuf, fr->hdr.ssize);
} }
} }
@@ -462,8 +463,8 @@ static int halfspeed_do(mpg123_handle *fr)
fr->to_decode = fr->to_ignore = TRUE; fr->to_decode = fr->to_ignore = TRUE;
--fr->halfphase; --fr->halfphase;
INT123_set_pointer(fr, 0, 0); INT123_set_pointer(fr, 0, 0);
if(fr->lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->ssize); if(fr->hdr.lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->hdr.ssize);
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ if(fr->hdr.error_protection) fr->crc = getbits(fr, 16); /* skip crc */
return 1; return 1;
} }
else else
@@ -496,10 +497,11 @@ int INT123_read_frame(mpg123_handle *fr)
/* TODO: rework this thing */ /* TODO: rework this thing */
int freeformat_count = 0; int freeformat_count = 0;
unsigned long newhead; unsigned long newhead;
// Start with current frame header state as copy for roll-back ability.
struct frame_header nhdr = fr->hdr;
int64_t framepos; int64_t framepos;
int ret; int ret;
/* stuff that needs resetting if complete frame reading fails */ /* stuff that needs resetting if complete frame reading fails */
int oldsize = fr->framesize;
int oldphase = fr->halfphase; int oldphase = fr->halfphase;
/* The counter for the search-first-header loop. /* The counter for the search-first-header loop.
@@ -507,11 +509,12 @@ int INT123_read_frame(mpg123_handle *fr)
when repeatedly headers are found that do not have valid followup headers. */ when repeatedly headers are found that do not have valid followup headers. */
long headcount = 0; long headcount = 0;
fr->fsizeold=fr->framesize; /* for Layer3 */ fr->fsizeold=fr->hdr.framesize; /* for Layer3 */
if(halfspeed_do(fr) == 1) return 1; if(halfspeed_do(fr) == 1) return 1;
/* From now on, old frame data is tainted by parsing attempts. */ /* From now on, old frame data is tainted by parsing attempts. */
// Handling premature effects of decode_header now, more decoupling would be welcome.
fr->to_decode = fr->to_ignore = FALSE; fr->to_decode = fr->to_ignore = FALSE;
if( fr->p.flags & MPG123_NO_FRANKENSTEIN && if( fr->p.flags & MPG123_NO_FRANKENSTEIN &&
@@ -540,13 +543,13 @@ init_resync:
#ifdef SKIP_JUNK #ifdef SKIP_JUNK
if(!fr->firsthead && !head_check(newhead)) if(!fr->firsthead && !head_check(newhead))
{ {
ret = skip_junk(fr, &newhead, &headcount); ret = skip_junk(fr, &newhead, &headcount, &nhdr);
JUMP_CONCLUSION(ret); JUMP_CONCLUSION(ret);
} }
#endif #endif
ret = head_check(newhead); ret = head_check(newhead);
if(ret) ret = decode_header(fr, newhead, &freeformat_count); if(ret) ret = decode_header(fr, &nhdr, newhead, &freeformat_count);
JUMP_CONCLUSION(ret); /* That only continues for ret == PARSE_BAD or PARSE_GOOD. */ JUMP_CONCLUSION(ret); /* That only continues for ret == PARSE_BAD or PARSE_GOOD. */
if(ret == PARSE_BAD) if(ret == PARSE_BAD)
@@ -561,7 +564,7 @@ init_resync:
{ {
ret = fr->p.flags & MPG123_NO_READAHEAD ret = fr->p.flags & MPG123_NO_READAHEAD
? PARSE_GOOD ? PARSE_GOOD
: do_readahead(fr, newhead); : do_readahead(fr, &nhdr, newhead);
/* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */ /* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */
if(ret < 0) fr->rd->back_bytes(fr, 4); if(ret < 0) fr->rd->back_bytes(fr, 4);
JUMP_CONCLUSION(ret); JUMP_CONCLUSION(ret);
@@ -585,8 +588,8 @@ init_resync:
{ {
unsigned char *newbuf = fr->bsspace[fr->bsnum]+512; unsigned char *newbuf = fr->bsspace[fr->bsnum]+512;
/* read main data into memory */ /* read main data into memory */
debug2("read frame body of %i at %"PRIi64, fr->framesize, framepos+4); debug2("read frame body of %i at %"PRIi64, nhdr.framesize, framepos+4);
if((ret=fr->rd->read_frame_body(fr,newbuf,fr->framesize))<0) if((ret=fr->rd->read_frame_body(fr,newbuf,nhdr.framesize))<0)
{ {
/* if failed: flip back */ /* if failed: flip back */
debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error"); debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error");
@@ -597,6 +600,10 @@ init_resync:
} }
fr->bsnum = (fr->bsnum + 1) & 1; fr->bsnum = (fr->bsnum + 1) & 1;
// We read the frame body, time to apply the matching header.
// Even if erroring out later, the header state needs to match the body.
apply_header(fr, &nhdr);
if(!fr->firsthead) if(!fr->firsthead)
{ {
fr->firsthead = newhead; /* _now_ it's time to store it... the first real header */ fr->firsthead = newhead; /* _now_ it's time to store it... the first real header */
@@ -608,7 +615,7 @@ init_resync:
fr->audio_start = framepos; fr->audio_start = framepos;
/* Only check for LAME tag at beginning of whole stream /* Only check for LAME tag at beginning of whole stream
... when there indeed is one in between, it's the user's problem. */ ... when there indeed is one in between, it's the user's problem. */
if(fr->lay == 3 && check_lame_tag(fr) == 1) if(fr->hdr.lay == 3 && check_lame_tag(fr) == 1)
{ /* ...in practice, Xing/LAME tags are layer 3 only. */ { /* ...in practice, Xing/LAME tags are layer 3 only. */
if(fr->rd->forget != NULL) fr->rd->forget(fr); if(fr->rd->forget != NULL) fr->rd->forget(fr);
@@ -624,6 +631,8 @@ init_resync:
INT123_set_pointer(fr, 0, 0); INT123_set_pointer(fr, 0, 0);
// No use of nhdr from here on. It is fr->hdr now!
/* Question: How bad does the floating point value get with repeated recomputation? /* Question: How bad does the floating point value get with repeated recomputation?
Also, considering that we can play the file or parts of many times. */ Also, considering that we can play the file or parts of many times. */
if(++fr->mean_frames != 0) if(++fr->mean_frames != 0)
@@ -631,7 +640,7 @@ init_resync:
fr->mean_framesize = ((fr->mean_frames-1)*fr->mean_framesize+INT123_compute_bpf(fr)) / fr->mean_frames ; fr->mean_framesize = ((fr->mean_frames-1)*fr->mean_framesize+INT123_compute_bpf(fr)) / fr->mean_frames ;
} }
++fr->num; /* 0 for first frame! */ ++fr->num; /* 0 for first frame! */
debug4("Frame %"PRIi64" %08lx %i, next filepos=%"PRIi64, fr->num, newhead, fr->framesize, fr->rd->tell(fr)); debug4("Frame %"PRIi64" %08lx %i, next filepos=%"PRIi64, fr->num, newhead, fr->hdr.framesize, fr->rd->tell(fr));
if(!(fr->state_flags & FRAME_FRANKENSTEIN) && ( if(!(fr->state_flags & FRAME_FRANKENSTEIN) && (
(fr->track_frames > 0 && fr->num >= fr->track_frames) (fr->track_frames > 0 && fr->num >= fr->track_frames)
#ifdef GAPLESS #ifdef GAPLESS
@@ -665,7 +674,7 @@ init_resync:
if(fr->rd->forget != NULL) fr->rd->forget(fr); if(fr->rd->forget != NULL) fr->rd->forget(fr);
fr->to_decode = fr->to_ignore = TRUE; fr->to_decode = fr->to_ignore = TRUE;
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ if(fr->hdr.error_protection) fr->crc = getbits(fr, 16); /* skip crc */
/* /*
Let's check for header change after deciding that the new one is good Let's check for header change after deciding that the new one is good
@@ -712,7 +721,6 @@ read_frame_bad:
fr->silent_resync = 0; fr->silent_resync = 0;
if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER; if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER;
fr->framesize = oldsize;
fr->halfphase = oldphase; fr->halfphase = oldphase;
/* That return code might be inherited from some feeder action, or reader error. */ /* That return code might be inherited from some feeder action, or reader error. */
return ret; return ret;
@@ -726,9 +734,9 @@ read_frame_bad:
* <0: error codes, possibly from feeder buffer (NEED_MORE) * <0: error codes, possibly from feeder buffer (NEED_MORE)
* PARSE_BAD: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...) * PARSE_BAD: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...)
*/ */
static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead) static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead, int *framesize)
{ {
long i; int i;
int ret; int ret;
unsigned long head; unsigned long head;
if(!(fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED))) if(!(fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED)))
@@ -749,7 +757,7 @@ static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
if((head & HDR_SAMEMASK) == (oldhead & HDR_SAMEMASK)) if((head & HDR_SAMEMASK) == (oldhead & HDR_SAMEMASK))
{ {
fr->rd->back_bytes(fr,i+1); fr->rd->back_bytes(fr,i+1);
fr->framesize = i-3; *framesize = i-3;
return PARSE_GOOD; /* Success! */ return PARSE_GOOD; /* Success! */
} }
} }
@@ -766,8 +774,13 @@ static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
* 0: no valid header * 0: no valid header
* <0: some error * <0: some error
* You are required to do a head_check() before calling! * You are required to do a head_check() before calling!
*
* This now only operates on a frame header struct, not the full frame structure.
* The scope is limited to parsing header information and determining the size of
* the frame body to read. Everything else belongs into a later stage of applying
* header information to the main decoder frame structure.
*/ */
static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count) static int decode_header(mpg123_handle *fr, struct frame_header *fh, unsigned long newhead, int *freeformat_count)
{ {
#ifdef DEBUG /* Do not waste cycles checking the header twice all the time. */ #ifdef DEBUG /* Do not waste cycles checking the header twice all the time. */
if(!head_check(newhead)) if(!head_check(newhead))
@@ -778,43 +791,42 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
/* For some reason, the layer and sampling freq settings used to be wrapped /* For some reason, the layer and sampling freq settings used to be wrapped
in a weird conditional including MPG123_NO_RESYNC. What was I thinking? in a weird conditional including MPG123_NO_RESYNC. What was I thinking?
This information has to be consistent. */ This information has to be consistent. */
fr->lay = 4 - HDR_LAYER_VAL(newhead); fh->lay = 4 - HDR_LAYER_VAL(newhead);
if(HDR_VERSION_VAL(newhead) & 0x2) if(HDR_VERSION_VAL(newhead) & 0x2)
{ {
fr->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1; fh->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1;
fr->mpeg25 = 0; fh->mpeg25 = 0;
fr->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fr->lsf*3); fh->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fh->lsf*3);
} }
else else
{ {
fr->lsf = 1; fh->lsf = 1;
fr->mpeg25 = 1; fh->mpeg25 = 1;
fr->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead); fh->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead);
} }
#ifdef DEBUG #ifdef DEBUG
/* seen a file where this varies (old lame tag without crc, track with crc) */ /* seen a file where this varies (old lame tag without crc, track with crc) */
if((HDR_CRC_VAL(newhead)^0x1) != fr->error_protection) debug("changed crc bit!"); if((HDR_CRC_VAL(newhead)^0x1) != fh->error_protection) debug("changed crc bit!");
#endif #endif
fr->error_protection = HDR_CRC_VAL(newhead)^0x1; fh->error_protection = HDR_CRC_VAL(newhead)^0x1;
fr->bitrate_index = HDR_BITRATE_VAL(newhead); fh->bitrate_index = HDR_BITRATE_VAL(newhead);
fr->padding = HDR_PADDING_VAL(newhead); fh->padding = HDR_PADDING_VAL(newhead);
fr->extension = HDR_PRIVATE_VAL(newhead); fh->extension = HDR_PRIVATE_VAL(newhead);
fr->mode = HDR_CHANNEL_VAL(newhead); fh->mode = HDR_CHANNEL_VAL(newhead);
fr->mode_ext = HDR_CHANEX_VAL(newhead); fh->mode_ext = HDR_CHANEX_VAL(newhead);
fr->copyright = HDR_COPYRIGHT_VAL(newhead); fh->copyright = HDR_COPYRIGHT_VAL(newhead);
fr->original = HDR_ORIGINAL_VAL(newhead); fh->original = HDR_ORIGINAL_VAL(newhead);
fr->emphasis = HDR_EMPHASIS_VAL(newhead); fh->emphasis = HDR_EMPHASIS_VAL(newhead);
fr->freeformat = !(newhead & HDR_BITRATE); fh->freeformat = !(newhead & HDR_BITRATE);
fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
/* we can't use tabsel_123 for freeformat, so trying to guess framesize... */ /* we can't use tabsel_123 for freeformat, so trying to guess framesize... */
if(fr->freeformat) if(fh->freeformat)
{ {
/* when we first encounter the frame with freeformat, guess framesize */ /* when we first encounter the frame with freeformat, guess framesize */
if(fr->freeformat_framesize < 0) if(fh->freeformat_framesize < 0)
{ {
int ret; int ret;
if(fr->p.flags & MPG123_NO_READAHEAD) if(fr->p.flags & MPG123_NO_READAHEAD)
@@ -829,12 +841,12 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
if(VERBOSE3) error("You fooled me too often. Refusing to guess free format frame size _again_."); if(VERBOSE3) error("You fooled me too often. Refusing to guess free format frame size _again_.");
return PARSE_BAD; return PARSE_BAD;
} }
ret = guess_freeformat_framesize(fr, newhead); ret = guess_freeformat_framesize(fr, newhead, &(fh->framesize));
if(ret == PARSE_GOOD) if(ret == PARSE_GOOD)
{ {
fr->freeformat_framesize = fr->framesize - fr->padding; fh->freeformat_framesize = fh->framesize - fh->padding;
if(VERBOSE2) if(VERBOSE2)
fprintf(stderr, "Note: free format frame size %li\n", fr->freeformat_framesize); fprintf(stderr, "Note: free format frame size %i\n", fh->freeformat_framesize);
} }
else else
{ {
@@ -849,81 +861,109 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
/* freeformat should be CBR, so the same framesize can be used at the 2nd reading or later */ /* freeformat should be CBR, so the same framesize can be used at the 2nd reading or later */
else else
{ {
fr->framesize = fr->freeformat_framesize + fr->padding; fh->framesize = fh->freeformat_framesize + fh->padding;
} }
} }
switch(fh->lay)
{
#ifndef NO_LAYER1
case 1:
if(!fh->freeformat)
{
long fs = (long) tabsel_123[fh->lsf][0][fh->bitrate_index] * 12000;
fs /= freqs[fh->sampling_frequency];
fs = ((fs+fh->padding)<<2)-4;
fh->framesize = (int)fs;
}
break;
#endif
#ifndef NO_LAYER2
case 2:
if(!fh->freeformat)
{
debug2("bitrate index: %i (%i)", fh->bitrate_index, tabsel_123[fh->lsf][1][fh->bitrate_index] );
long fs = (long) tabsel_123[fh->lsf][1][fh->bitrate_index] * 144000;
fs /= freqs[fh->sampling_frequency];
fs += fh->padding - 4;
fh->framesize = (int)fs;
}
break;
#endif
#ifndef NO_LAYER3
case 3:
if(fh->lsf)
fh->ssize = (fh->mode == MPG_MD_MONO) ? 9 : 17;
else
fh->ssize = (fh->mode == MPG_MD_MONO) ? 17 : 32;
switch(fr->lay) if(fh->error_protection)
fh->ssize += 2;
if(!fh->freeformat)
{
long fs = (long) tabsel_123[fh->lsf][2][fh->bitrate_index] * 144000;
fs /= freqs[fh->sampling_frequency]<<(fh->lsf);
fs += fh->padding - 4;
fh->framesize = fs;
}
if(fh->framesize < fh->ssize)
{
if(NOQUIET)
error2( "Frame smaller than mandatory side info (%i < %i)!"
, fh->framesize, fh->ssize );
return PARSE_BAD;
}
break;
#endif
default:
if(NOQUIET) error1("Layer type %i not supported in this build!", fh->lay);
return PARSE_BAD;
}
if (fh->framesize > MAXFRAMESIZE)
{
if(NOQUIET) error1("Frame size too big: %d", fh->framesize+4-fh->padding);
return PARSE_BAD;
}
return PARSE_GOOD;
}
// Apply decoded header structure to frame struct, including
// main decoder function pointer.
static void apply_header(mpg123_handle *fr, struct frame_header *hdr)
{
// copy the whole struct, do some postprocessing
fr->hdr = *hdr;
fr->stereo = (fr->hdr.mode == MPG_MD_MONO) ? 1 : 2;
switch(fr->hdr.lay)
{ {
#ifndef NO_LAYER1 #ifndef NO_LAYER1
case 1: case 1:
fr->spf = 384; fr->spf = 384;
fr->do_layer = INT123_do_layer1; fr->do_layer = INT123_do_layer1;
if(!fr->freeformat)
{
long fs = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
fs /= freqs[fr->sampling_frequency];
fs = ((fs+fr->padding)<<2)-4;
fr->framesize = (int)fs;
}
break; break;
#endif #endif
#ifndef NO_LAYER2 #ifndef NO_LAYER2
case 2: case 2:
fr->spf = 1152; fr->spf = 1152;
fr->do_layer = INT123_do_layer2; fr->do_layer = INT123_do_layer2;
if(!fr->freeformat)
{
debug2("bitrate index: %i (%i)", fr->bitrate_index, tabsel_123[fr->lsf][1][fr->bitrate_index] );
long fs = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
fs /= freqs[fr->sampling_frequency];
fs += fr->padding - 4;
fr->framesize = (int)fs;
}
break; break;
#endif #endif
#ifndef NO_LAYER3 #ifndef NO_LAYER3
case 3: case 3:
fr->spf = fr->lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/ fr->spf = fr->hdr.lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/
fr->do_layer = INT123_do_layer3; fr->do_layer = INT123_do_layer3;
if(fr->lsf)
fr->ssize = (fr->stereo == 1) ? 9 : 17;
else
fr->ssize = (fr->stereo == 1) ? 17 : 32;
if(fr->error_protection)
fr->ssize += 2;
if(!fr->freeformat)
{
long fs = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
fs /= freqs[fr->sampling_frequency]<<(fr->lsf);
fs += fr->padding - 4;
fr->framesize = fs;
}
if(fr->framesize < fr->ssize)
{
if(NOQUIET)
error2( "Frame smaller than mandatory side info (%i < %i)!"
, fr->framesize, fr->ssize );
return PARSE_BAD;
}
break;
#endif #endif
break;
default: default:
if(NOQUIET) error1("Layer type %i not supported in this build!", fr->lay); // No error checking/message here, been done in decode_header().
fr->spf = 0;
return PARSE_BAD; fr->do_layer = NULL;
} }
if (fr->framesize > MAXFRAMESIZE)
{
if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding);
return PARSE_BAD;
}
return PARSE_GOOD;
} }
/* Prepare for bit reading. Two stages: /* Prepare for bit reading. Two stages:
0. Layers 1 and 2, side info for layer 3 0. Layers 1 and 2, side info for layer 3
1. Second call for possible bit reservoir for layer 3 part 2,3. 1. Second call for possible bit reservoir for layer 3 part 2,3.
@@ -935,26 +975,26 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeforma
void INT123_set_pointer(mpg123_handle *fr, int part2, long backstep) void INT123_set_pointer(mpg123_handle *fr, int part2, long backstep)
{ {
fr->bitindex = 0; fr->bitindex = 0;
if(fr->lay == 3) if(fr->hdr.lay == 3)
{ {
if(part2) if(part2)
{ {
fr->wordpointer = fr->bsbuf + fr->ssize - backstep; fr->wordpointer = fr->bsbuf + fr->hdr.ssize - backstep;
if(backstep) if(backstep)
memcpy( fr->wordpointer, fr->bsbufold+fr->fsizeold-backstep memcpy( fr->wordpointer, fr->bsbufold+fr->fsizeold-backstep
, backstep ); , backstep );
fr->bits_avail = (long)(fr->framesize - fr->ssize + backstep)*8; fr->bits_avail = (long)(fr->hdr.framesize - fr->hdr.ssize + backstep)*8;
} }
else else
{ {
fr->wordpointer = fr->bsbuf; fr->wordpointer = fr->bsbuf;
fr->bits_avail = fr->ssize*8; fr->bits_avail = fr->hdr.ssize*8;
} }
} }
else else
{ {
fr->wordpointer = fr->bsbuf; fr->wordpointer = fr->bsbuf;
fr->bits_avail = fr->framesize*8; fr->bits_avail = fr->hdr.framesize*8;
} }
} }
@@ -962,7 +1002,7 @@ void INT123_set_pointer(mpg123_handle *fr, int part2, long backstep)
double INT123_compute_bpf(mpg123_handle *fr) double INT123_compute_bpf(mpg123_handle *fr)
{ {
return (fr->framesize > 0) ? fr->framesize + 4.0 : 1.0; return (fr->hdr.framesize > 0) ? fr->hdr.framesize + 4.0 : 1.0;
} }
int attribute_align_arg mpg123_spf(mpg123_handle *mh) int attribute_align_arg mpg123_spf(mpg123_handle *mh)
@@ -978,8 +1018,8 @@ double attribute_align_arg mpg123_tpf(mpg123_handle *fr)
double tpf; double tpf;
if(fr == NULL || !fr->firsthead) return MPG123_ERR; if(fr == NULL || !fr->firsthead) return MPG123_ERR;
tpf = (double) bs[fr->lay]; tpf = (double) bs[fr->hdr.lay];
tpf /= freqs[fr->sampling_frequency] << (fr->lsf); tpf /= freqs[fr->hdr.sampling_frequency] << (fr->hdr.lsf);
return tpf; return tpf;
} }
@@ -1046,7 +1086,7 @@ int attribute_align_arg mpg123_position64(mpg123_handle *fr, int64_t no, int64_t
} }
/* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */ /* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
static int do_readahead(mpg123_handle *fr, unsigned long newhead) static int do_readahead(mpg123_handle *fr, struct frame_header *nhdr, unsigned long newhead)
{ {
unsigned long nexthead = 0; unsigned long nexthead = 0;
int hd = 0; int hd = 0;
@@ -1058,9 +1098,9 @@ static int do_readahead(mpg123_handle *fr, unsigned long newhead)
start = fr->rd->tell(fr); start = fr->rd->tell(fr);
debug2("doing ahead check with BPF %d at %"PRIi64, fr->framesize+4, start); debug2("doing ahead check with BPF %d at %"PRIi64, nhdr->framesize+4, start);
/* step framesize bytes forward and read next possible header*/ /* step framesize bytes forward and read next possible header*/
if((oret=fr->rd->skip_bytes(fr, fr->framesize))<0) if((oret=fr->rd->skip_bytes(fr, nhdr->framesize))<0)
{ {
if(oret==READER_ERROR && NOQUIET) error("cannot seek!"); if(oret==READER_ERROR && NOQUIET) error("cannot seek!");
@@ -1195,7 +1235,7 @@ static int forget_head_shift(mpg123_handle *fr, unsigned long *newheadp, int for
} }
/* watch out for junk/tags on beginning of stream by invalid header */ /* watch out for junk/tags on beginning of stream by invalid header */
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount) static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount, struct frame_header *nhdr)
{ {
int ret; int ret;
int freeformat_count = 0; int freeformat_count = 0;
@@ -1251,7 +1291,7 @@ static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount
if(++forgetcount > FORGET_INTERVAL) forgetcount = 0; if(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
if((ret=forget_head_shift(fr, &newhead, !forgetcount))<=0) return ret; if((ret=forget_head_shift(fr, &newhead, !forgetcount))<=0) return ret;
if(head_check(newhead) && (ret=decode_header(fr, newhead, &freeformat_count))) break; if(head_check(newhead) && (ret=decode_header(fr, nhdr, newhead, &freeformat_count))) break;
} while(1); } while(1);
if(ret<0) return ret; if(ret<0) return ret;

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -6,6 +6,7 @@
initially written by Taihei Monma initially written by Taihei Monma
*/ */
#include "aarch64_defs.h"
#include "mangle.h" #include "mangle.h"
#ifndef __APPLE__ #ifndef __APPLE__

View File

@@ -1910,6 +1910,7 @@ static void long_usage(int err)
fprintf(o," <a> average events per second\n"); fprintf(o," <a> average events per second\n");
fprintf(o," -t --test no output, just read and discard data (-o test)\n"); fprintf(o," -t --test no output, just read and discard data (-o test)\n");
fprintf(o," -v[*] --verbose increase verboselevel\n"); fprintf(o," -v[*] --verbose increase verboselevel\n");
fprintf(o," -q --quiet quiet mode\n");
#ifdef HAVE_SETPRIORITY #ifdef HAVE_SETPRIORITY
fprintf(o," --aggressive tries to get higher priority (nice)\n"); fprintf(o," --aggressive tries to get higher priority (nice)\n");
#endif #endif

View File

@@ -16,7 +16,7 @@
// only single spaces as separator to ease parsing by build scripts // only single spaces as separator to ease parsing by build scripts
#define MPG123_MAJOR 1 #define MPG123_MAJOR 1
#define MPG123_MINOR 32 #define MPG123_MINOR 32
#define MPG123_PATCH 7 #define MPG123_PATCH 8
// Don't get too wild with that to avoid confusing m4. No brackets. // Don't get too wild with that to avoid confusing m4. No brackets.
// Also, it should fit well into a sane file name for the tarball. // Also, it should fit well into a sane file name for the tarball.
#define MPG123_SUFFIX "" #define MPG123_SUFFIX ""