ReactOS  0.4.13-dev-544-gede3fdd
libmpg123.c File Reference
#include "mpg123lib_intern.h"
#include "icy2utf8.h"
#include "debug.h"
#include "gapless.h"
#include "sample.h"
Include dependency graph for libmpg123.c:

Go to the source code of this file.

Macros

#define FORCE_ACCURATE
 
#define SEEKFRAME(mh)   ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
 
#define track_need_init(mh)   ((mh)->num < 0)
 

Functions

int attribute_align_arg mpg123_init (void)
 
void attribute_align_arg mpg123_exit (void)
 
mpg123_handle attribute_align_argmpg123_new (const char *decoder, int *error)
 
mpg123_handle attribute_align_argmpg123_parnew (mpg123_pars *mp, const char *decoder, int *error)
 
int attribute_align_arg mpg123_decoder (mpg123_handle *mh, const char *decoder)
 
int attribute_align_arg mpg123_param (mpg123_handle *mh, enum mpg123_parms key, long val, double fval)
 
int attribute_align_arg mpg123_par (mpg123_pars *mp, enum mpg123_parms key, long val, double fval)
 
int attribute_align_arg mpg123_getparam (mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval)
 
int attribute_align_arg mpg123_getpar (mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval)
 
int attribute_align_arg mpg123_getstate (mpg123_handle *mh, enum mpg123_state key, long *val, double *fval)
 
int attribute_align_arg mpg123_eq (mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
 
double attribute_align_arg mpg123_geteq (mpg123_handle *mh, enum mpg123_channels channel, int band)
 
int attribute_align_arg mpg123_open (mpg123_handle *mh, const char *path)
 
int attribute_align_arg mpg123_open_fd (mpg123_handle *mh, int fd)
 
int attribute_align_arg mpg123_open_handle (mpg123_handle *mh, void *iohandle)
 
int attribute_align_arg mpg123_open_feed (mpg123_handle *mh)
 
int attribute_align_arg mpg123_replace_reader (mpg123_handle *mh, ssize_t(*r_read)(int, void *, size_t), off_t(*r_lseek)(int, off_t, int))
 
int attribute_align_arg mpg123_replace_reader_handle (mpg123_handle *mh, ssize_t(*r_read)(void *, void *, size_t), off_t(*r_lseek)(void *, off_t, int), void(*cleanup)(void *))
 
int decode_update (mpg123_handle *mh)
 
size_t attribute_align_arg mpg123_safe_buffer (void)
 
size_t attribute_align_arg mpg123_outblock (mpg123_handle *mh)
 
static int get_next_frame (mpg123_handle *mh)
 
static int zero_byte (mpg123_handle *fr)
 
static void decode_the_frame (mpg123_handle *fr)
 
int attribute_align_arg mpg123_framebyframe_decode (mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
 
int attribute_align_arg mpg123_framebyframe_next (mpg123_handle *mh)
 
int attribute_align_arg mpg123_decode_frame (mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
 
int attribute_align_arg mpg123_read (mpg123_handle *mh, unsigned char *out, size_t size, size_t *done)
 
int attribute_align_arg mpg123_feed (mpg123_handle *mh, const unsigned char *in, size_t size)
 
int attribute_align_arg mpg123_decode (mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done)
 
long attribute_align_arg mpg123_clip (mpg123_handle *mh)
 
static int init_track (mpg123_handle *mh)
 
int attribute_align_arg mpg123_info (mpg123_handle *mh, struct mpg123_frameinfo *mi)
 
int attribute_align_arg mpg123_getformat2 (mpg123_handle *mh, long *rate, int *channels, int *encoding, int clear_flag)
 
int attribute_align_arg mpg123_getformat (mpg123_handle *mh, long *rate, int *channels, int *encoding)
 
off_t attribute_align_arg mpg123_timeframe (mpg123_handle *mh, double seconds)
 
off_t attribute_align_arg mpg123_tell (mpg123_handle *mh)
 
off_t attribute_align_arg mpg123_tellframe (mpg123_handle *mh)
 
off_t attribute_align_arg mpg123_tell_stream (mpg123_handle *mh)
 
static int do_the_seek (mpg123_handle *mh)
 
off_t attribute_align_arg mpg123_seek (mpg123_handle *mh, off_t sampleoff, int whence)
 
off_t attribute_align_arg mpg123_feedseek (mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
 
off_t attribute_align_arg mpg123_seek_frame (mpg123_handle *mh, off_t offset, int whence)
 
int attribute_align_arg mpg123_set_filesize (mpg123_handle *mh, off_t size)
 
off_t attribute_align_arg mpg123_framelength (mpg123_handle *mh)
 
off_t attribute_align_arg mpg123_length (mpg123_handle *mh)
 
int attribute_align_arg mpg123_scan (mpg123_handle *mh)
 
int attribute_align_arg mpg123_meta_check (mpg123_handle *mh)
 
void attribute_align_arg mpg123_meta_free (mpg123_handle *mh)
 
int attribute_align_arg mpg123_id3 (mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2)
 
int attribute_align_arg mpg123_icy (mpg123_handle *mh, char **icy_meta)
 
char *attribute_align_arg mpg123_icy2utf8 (const char *icy_text)
 
enum mpg123_text_encoding attribute_align_arg mpg123_enc_from_id3 (unsigned char id3_enc_byte)
 
int mpg123_store_utf8 (mpg123_string *sb, enum mpg123_text_encoding enc, const unsigned char *source, size_t source_size)
 
int attribute_align_arg mpg123_index (mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill)
 
int attribute_align_arg mpg123_set_index (mpg123_handle *mh, off_t *offsets, off_t step, size_t fill)
 
int attribute_align_arg mpg123_close (mpg123_handle *mh)
 
void attribute_align_arg mpg123_delete (mpg123_handle *mh)
 
const char *attribute_align_arg mpg123_plain_strerror (int errcode)
 
int attribute_align_arg mpg123_errcode (mpg123_handle *mh)
 
const char *attribute_align_arg mpg123_strerror (mpg123_handle *mh)
 

Variables

static int initialized = 0
 
static const charmpg123_error []
 

Macro Definition Documentation

◆ FORCE_ACCURATE

#define FORCE_ACCURATE

Definition at line 15 of file libmpg123.c.

◆ SEEKFRAME

#define SEEKFRAME (   mh)    ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)

Definition at line 18 of file libmpg123.c.

◆ track_need_init

#define track_need_init (   mh)    ((mh)->num < 0)

Definition at line 999 of file libmpg123.c.

Function Documentation

◆ decode_the_frame()

static void decode_the_frame ( mpg123_handle fr)
static

Definition at line 707 of file libmpg123.c.

708 {
709  size_t needed_bytes = decoder_synth_bytes(fr, frame_expect_outsamples(fr));
710  fr->clip += (fr->do_layer)(fr);
711  /*fprintf(stderr, "frame %"OFF_P": got %"SIZE_P" / %"SIZE_P"\n", fr->num,(size_p)fr->buffer.fill, (size_p)needed_bytes);*/
712  /* There could be less data than promised.
713  Also, then debugging, we look out for coding errors that could result in _more_ data than expected. */
714 #ifdef DEBUG
715  if(fr->buffer.fill != needed_bytes)
716  {
717 #endif
718  if(fr->buffer.fill < needed_bytes)
719  {
720  if(VERBOSE2)
721  fprintf(stderr, "Note: broken frame %li, filling up with %"SIZE_P" zeroes, from %"SIZE_P"\n", (long)fr->num, (size_p)(needed_bytes-fr->buffer.fill), (size_p)fr->buffer.fill);
722 
723  /*
724  One could do a loop with individual samples instead... but zero is zero
725  Actually, that is wrong: zero is mostly a series of null bytes,
726  but we have funny 8bit formats that have a different opinion on zero...
727  Unsigned 16 or 32 bit formats are handled later.
728  */
729  memset( fr->buffer.data + fr->buffer.fill, zero_byte(fr), needed_bytes - fr->buffer.fill );
730 
731  fr->buffer.fill = needed_bytes;
732 #ifndef NO_NTOM
733  /* ntom_val will be wrong when the decoding wasn't carried out completely */
734  ntom_set_ntom(fr, fr->num+1);
735 #endif
736  }
737 #ifdef DEBUG
738  else
739  {
740  if(NOQUIET)
741  error2("I got _more_ bytes than expected (%"SIZE_P" / %"SIZE_P"), that should not be possible!", (size_p)fr->buffer.fill, (size_p)needed_bytes);
742  }
743  }
744 #endif
745  postprocess_buffer(fr);
746 }
#define frame_expect_outsamples
Definition: intsym.h:185
struct outbuffer buffer
Definition: frame.h:265
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define postprocess_buffer
Definition: intsym.h:220
#define decoder_synth_bytes
Definition: intsym.h:216
#define VERBOSE2
static int zero_byte(mpg123_handle *fr)
Definition: libmpg123.c:694
#define error2(s, a, b)
Definition: debug.h:110
int(* do_layer)(mpg123_handle *)
Definition: frame.h:201
unsigned long size_p
Definition: compat.h:138
#define NOQUIET
#define SIZE_P
Definition: compat.h:137
FILE * stderr
#define memset(x, y, z)
Definition: compat.h:39
#define ntom_set_ntom
Definition: intsym.h:21

Referenced by mpg123_decode(), mpg123_decode_frame(), and mpg123_framebyframe_decode().

◆ decode_update()

int decode_update ( mpg123_handle mh)

Definition at line 506 of file libmpg123.c.

507 {
508  long native_rate;
509  int b;
510 
511  if(mh->num < 0)
512  {
513  if(!(mh->p.flags & MPG123_QUIET)) error("decode_update() has been called before reading the first MPEG frame! Internal programming error.");
514 
516  return MPG123_ERR;
517  }
518 
520  native_rate = frame_freq(mh);
521 
522  b = frame_output_format(mh); /* Select the new output format based on given constraints. */
523  if(b < 0) return MPG123_ERR;
524 
525  if(b == 1) mh->new_format = 1; /* Store for later... */
526 
527  debug3("updating decoder structure with native rate %li and af.rate %li (new format: %i)", native_rate, mh->af.rate, mh->new_format);
528  if(mh->af.rate == native_rate) mh->down_sample = 0;
529  else if(mh->af.rate == native_rate>>1) mh->down_sample = 1;
530  else if(mh->af.rate == native_rate>>2) mh->down_sample = 2;
531  else mh->down_sample = 3; /* flexible (fixed) rate */
532  switch(mh->down_sample)
533  {
534  case 0:
535  case 1:
536  case 2:
538  /* With downsampling I get less samples per frame */
539  mh->outblock = outblock_bytes(mh, (mh->spf>>mh->down_sample));
540  break;
541 #ifndef NO_NTOM
542  case 3:
543  {
544  if(synth_ntom_set_step(mh) != 0) return -1;
545  if(frame_freq(mh) > mh->af.rate)
546  {
547  mh->down_sample_sblimit = SBLIMIT * mh->af.rate;
548  mh->down_sample_sblimit /= frame_freq(mh);
549  }
550  else mh->down_sample_sblimit = SBLIMIT;
551  mh->outblock = outblock_bytes(mh,
552  ( ( NTOM_MUL-1+mh->spf
553  * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh))
554  )/NTOM_MUL ));
555  }
556  break;
557 #endif
558  }
559 
560  if(!(mh->p.flags & MPG123_FORCE_MONO))
561  {
562  if(mh->af.channels == 1) mh->single = SINGLE_MIX;
563  else mh->single = SINGLE_STEREO;
564  }
565  else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1;
566  if(set_synth_functions(mh) != 0) return -1;;
567 
568  /* The needed size of output buffer may have changed. */
569  if(frame_outbuffer(mh) != MPG123_OK) return -1;
570 
571  do_rva(mh);
572  debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample);
573 
574  return 0;
575 }
struct mpg123_pars_struct p
Definition: frame.h:287
#define error(str)
Definition: mkdosfs.c:1605
#define SINGLE_STEREO
Definition: frame.h:187
#define SBLIMIT
#define NTOM_MUL
Definition: decode.h:32
#define outblock_bytes
Definition: intsym.h:219
#define debug3(s, a, b, c)
Definition: debug.h:54
#define set_synth_functions
Definition: intsym.h:222
int down_sample_sblimit
Definition: frame.h:193
#define b
Definition: ke_i.h:79
#define frame_outbuffer
Definition: intsym.h:170
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define synth_ntom_set_step
Definition: intsym.h:143
struct audioformat af
Definition: frame.h:266
#define do_rva
Definition: intsym.h:179
#define frame_freq
Definition: intsym.h:229
#define frame_output_format
Definition: intsym.h:171
#define SINGLE_MIX
Definition: frame.h:190

Referenced by do_the_seek(), and get_next_frame().

◆ do_the_seek()

static int do_the_seek ( mpg123_handle mh)
static

Definition at line 1136 of file libmpg123.c.

1137 {
1138  int b;
1139  off_t fnum = SEEKFRAME(mh);
1140  mh->buffer.fill = 0;
1141 
1142  /* If we are inside the ignoreframe - firstframe window, we may get away without actual seeking. */
1143  if(mh->num < mh->firstframe)
1144  {
1145  mh->to_decode = FALSE; /* In any case, don't decode the current frame, perhaps ignore instead. */
1146  if(mh->num > fnum) return MPG123_OK;
1147  }
1148 
1149  /* If we are already there, we are fine either for decoding or for ignoring. */
1150  if(mh->num == fnum && (mh->to_decode || fnum < mh->firstframe)) return MPG123_OK;
1151  /* We have the frame before... just go ahead as normal. */
1152  if(mh->num == fnum-1)
1153  {
1154  mh->to_decode = FALSE;
1155  return MPG123_OK;
1156  }
1157 
1158  /* OK, real seeking follows... clear buffers and go for it. */
1159  frame_buffers_reset(mh);
1160 #ifndef NO_NTOM
1161  if(mh->down_sample == 3)
1162  {
1163  ntom_set_ntom(mh, fnum);
1164  debug3("fixed ntom for frame %"OFF_P" to %lu, num=%"OFF_P, (off_p)fnum, mh->ntom_val[0], (off_p)mh->num);
1165  }
1166 #endif
1167  b = mh->rd->seek_frame(mh, fnum);
1168  if(mh->header_change > 1)
1169  {
1170  if(decode_update(mh) < 0) return MPG123_ERR;
1171  mh->header_change = 0;
1172  }
1173  debug1("seek_frame returned: %i", b);
1174  if(b<0) return b;
1175  /* Only mh->to_ignore is TRUE. */
1176  if(mh->num < mh->firstframe) mh->to_decode = FALSE;
1177 
1178  mh->playnum = mh->num;
1179  return 0;
1180 }
int decode_update(mpg123_handle *mh)
Definition: libmpg123.c:506
__kernel_off_t off_t
Definition: linux.h:201
struct outbuffer buffer
Definition: frame.h:265
#define debug3(s, a, b, c)
Definition: debug.h:54
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
unsigned long ntom_val[2]
Definition: frame.h:148
#define SEEKFRAME(mh)
Definition: libmpg123.c:18
#define frame_buffers_reset
Definition: intsym.h:174
long off_p
Definition: compat.h:130
struct reader * rd
Definition: frame.h:285
#define debug1(s, a)
Definition: debug.h:52
#define OFF_P
Definition: compat.h:129
#define ntom_set_ntom
Definition: intsym.h:21

Referenced by mpg123_seek(), and mpg123_seek_frame().

◆ get_next_frame()

static int get_next_frame ( mpg123_handle mh)
static

Definition at line 592 of file libmpg123.c.

593 {
594  int change = mh->decoder_change;
595  /* Ensure we got proper decoder for ignoring frames.
596  Header can be changed from seeking around. But be careful: Only after at
597  least one frame got read, decoder update makes sense. */
598  if(mh->header_change > 1 && mh->num >= 0)
599  {
600  change = 1;
601  mh->header_change = 0;
602  debug("starting with big header change");
603  if(decode_update(mh) < 0)
604  return MPG123_ERR;
605  }
606 
607  do
608  {
609  int b;
610  /* Decode & discard some frame(s) before beginning. */
611  if(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe)
612  {
613  debug1("ignoring frame %li", (long)mh->num);
614  /* Decoder structure must be current! decode_update has been called before... */
615  (mh->do_layer)(mh); mh->buffer.fill = 0;
616 #ifndef NO_NTOM
617  /* The ignored decoding may have failed. Make sure ntom stays consistent. */
618  if(mh->down_sample == 3) ntom_set_ntom(mh, mh->num+1);
619 #endif
620  mh->to_ignore = mh->to_decode = FALSE;
621  }
622  /* Read new frame data; possibly breaking out here for MPG123_NEED_MORE. */
623  debug("read frame");
624  mh->to_decode = FALSE;
625  b = read_frame(mh); /* That sets to_decode only if a full frame was read. */
626  debug4("read of frame %li returned %i (to_decode=%i) at sample %li", (long)mh->num, b, mh->to_decode, (long)mpg123_tell(mh));
627  if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */
628  else if(b <= 0)
629  {
630  /* More sophisticated error control? */
631  if(b==0 || (mh->rdat.filelen >= 0 && mh->rdat.filepos == mh->rdat.filelen))
632  { /* We simply reached the end. */
633  mh->track_frames = mh->num + 1;
634  debug("What about updating/checking gapless sample count here?");
635  return MPG123_DONE;
636  }
637  else return MPG123_ERR; /* Some real error. */
638  }
639  /* Now, there should be new data to decode ... and also possibly new stream properties */
640  if(mh->header_change > 1)
641  {
642  debug("big header change");
643  change = 1;
644  mh->header_change = 0;
645  /* Need to update decoder structure right away since frame might need to
646  be decoded on next loop iteration for properly ignoring its output. */
647  if(decode_update(mh) < 0)
648  return MPG123_ERR;
649  }
650  /* Now some accounting: Look at the numbers and decide if we want this frame. */
651  ++mh->playnum;
652  /* Plain skipping without decoding, only when frame is not ignored on next cycle. */
653  if(mh->num < mh->firstframe || (mh->p.doublespeed && (mh->playnum % mh->p.doublespeed)))
654  {
655  if(!(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe))
656  {
657  frame_skip(mh);
658  /* Should one fix NtoM here or not?
659  It is not work the trouble for doublespeed, but what with leading frames? */
660  }
661  }
662  /* Or, we are finally done and have a new frame. */
663  else break;
664  } while(1);
665 
666  /* If we reach this point, we got a new frame ready to be decoded.
667  All other situations resulted in returns from the loop. */
668  if(change)
669  {
670  mh->decoder_change = 0;
671  if(mh->fresh)
672  {
673 #ifdef GAPLESS
674  int b=0;
675  /* Prepare offsets for gapless decoding. */
676  debug1("preparing gapless stuff with native rate %li", frame_freq(mh));
678  frame_set_frameseek(mh, mh->num);
679 #endif
680  mh->fresh = 0;
681 #ifdef GAPLESS
682  /* Could this possibly happen? With a real big gapless offset... */
683  if(mh->num < mh->firstframe) b = get_next_frame(mh);
684  if(b < 0) return b; /* Could be error, need for more, new format... */
685 #endif
686  }
687  }
688  return MPG123_OK;
689 }
int decode_update(mpg123_handle *mh)
Definition: libmpg123.c:506
struct mpg123_pars_struct p
Definition: frame.h:287
off_t attribute_align_arg mpg123_tell(mpg123_handle *mh)
Definition: libmpg123.c:1089
#define debug4(s, a, b, c, d)
Definition: debug.h:55
struct outbuffer buffer
Definition: frame.h:265
struct reader_data rdat
Definition: frame.h:286
#define frame_skip
Definition: intsym.h:186
off_t track_frames
Definition: frame.h:244
#define b
Definition: ke_i.h:79
int(* do_layer)(mpg123_handle *)
Definition: frame.h:201
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
void frame_gapless_realinit(mpg123_handle *fr)
#define read_frame
Definition: intsym.h:231
static int get_next_frame(mpg123_handle *mh)
Definition: libmpg123.c:592
#define frame_set_frameseek
Definition: intsym.h:191
#define debug(msg)
Definition: key_call.c:71
#define frame_freq
Definition: intsym.h:229
#define debug1(s, a)
Definition: debug.h:52
#define ntom_set_ntom
Definition: intsym.h:21

Referenced by init_track(), mpg123_decode(), mpg123_decode_frame(), and mpg123_framebyframe_next().

◆ init_track()

static int init_track ( mpg123_handle mh)
static

Definition at line 1001 of file libmpg123.c.

1002 {
1003  if(track_need_init(mh))
1004  {
1005  /* Fresh track, need first frame for basic info. */
1006  int b = get_next_frame(mh);
1007  if(b < 0) return b;
1008  }
1009  return 0;
1010 }
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
static int get_next_frame(mpg123_handle *mh)
Definition: libmpg123.c:592
#define track_need_init(mh)
Definition: libmpg123.c:999

Referenced by mpg123_feedseek(), mpg123_framelength(), mpg123_getformat2(), mpg123_info(), mpg123_length(), mpg123_scan(), mpg123_seek(), mpg123_seek_frame(), and mpg123_timeframe().

◆ zero_byte()

static int zero_byte ( mpg123_handle fr)
static

Definition at line 694 of file libmpg123.c.

695 {
696 #ifndef NO_8BIT
697  return fr->af.encoding & MPG123_ENC_8 ? fr->conv16to8[0] : 0;
698 #else
699  return 0; /* All normal signed formats have the zero here (even in byte form -- that may be an assumption for your funny machine...). */
700 #endif
701 }
unsigned char * conv16to8
Definition: frame.h:134
struct audioformat af
Definition: frame.h:266

Referenced by decode_the_frame(), test_trailing_slash(), and test_urlcacheA().

Variable Documentation

◆ initialized

int initialized = 0
static

Definition at line 20 of file libmpg123.c.

Referenced by mpg123_init(), and mpg123_parnew().

◆ mpg123_error

const char* mpg123_error[]
static

Definition at line 1630 of file libmpg123.c.

Referenced by mpg123_plain_strerror().