summaryrefslogtreecommitdiff
path: root/apps/codecs/libmad/layer12.h
blob: 3fe6bd8b0ffc5756f5c03cd694d12704fad66d01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id$
 */

# ifndef LIBMAD_LAYER12_H
# define LIBMAD_LAYER12_H

# include "stream.h"
# include "frame.h"

int mad_layer_I(struct mad_stream *, struct mad_frame *);
int mad_layer_II(struct mad_stream *, struct mad_frame *);

# endif
href='#n110'>110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Miscellaneous helper API declarations
 *
 * Copyright (c) 2007 Michael Sevakis
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#ifndef MPEG_MISC_H
#define MPEG_MISC_H

/* Miscellaneous helpers */
#ifndef ALIGNED_ATTR
#define ALIGNED_ATTR(x) __attribute__((aligned(x)))
#endif

#include "disk_buf.h"

/* Generic states for when things are too simple to care about naming them */
enum state_enum
{
    STATE0 = 0,
    STATE1,
    STATE2,
    STATE3,
    STATE4,
    STATE5,
    STATE6,
    STATE7,
    STATE8,
    STATE9,
};

/* Macros for comparing memory bytes to a series of constant bytes in an
   efficient manner - evaluate to true if corresponding bytes match */
#if defined (CPU_ARM)
/* ARM must load 32-bit values at addres % 4 == 0 offsets but this data
   isn't aligned nescessarily, so just byte compare */
#define CMP_3_CONST(_a, _b) \
    ({  int _x;                             \
        asm volatile (                      \
            "ldrb   %[x], [%[a], #0]  \n"   \
            "eors   %[x], %[x], %[b0] \n"   \
            "ldreqb %[x], [%[a], #1]  \n"   \
            "eoreqs %[x], %[x], %[b1] \n"   \
            "ldreqb %[x], [%[a], #2]  \n"   \
            "eoreqs %[x], %[x], %[b2] \n"   \
            : [x]"=&r"(_x)                  \
            : [a]"r"(_a),                   \
              [b0]"i"(((_b) >> 24) & 0xff), \
              [b1]"i"(((_b) >> 16) & 0xff), \
              [b2]"i"(((_b) >>  8) & 0xff)  \
        );                                  \
        _x == 0; })

#define CMP_4_CONST(_a, _b) \
    ({  int _x;                             \
        asm volatile (                      \
            "ldrb   %[x], [%[a], #0]  \n"   \
            "eors   %[x], %[x], %[b0] \n"   \
            "ldreqb %[x], [%[a], #1]  \n"   \
            "eoreqs %[x], %[x], %[b1] \n"   \
            "ldreqb %[x], [%[a], #2]  \n"   \
            "eoreqs %[x], %[x], %[b2] \n"   \
            "ldreqb %[x], [%[a], #3]  \n"   \
            "eoreqs %[x], %[x], %[b3] \n"   \
            : [x]"=&r"(_x)                  \
            : [a]"r"(_a),                   \
              [b0]"i"(((_b) >> 24) & 0xff), \
              [b1]"i"(((_b) >> 16) & 0xff), \
              [b2]"i"(((_b) >>  8) & 0xff), \
              [b3]"i"(((_b)      ) & 0xff)  \
        );                                  \
        _x == 0; })

#elif defined (CPU_COLDFIRE)
/* Coldfire can just load a 32 bit value at any offset but ASM is not the
   best way to integrate this with the C code */
#define CMP_3_CONST(a, b) \
    (((*(uint32_t *)(a) >> 8) == ((uint32_t)(b) >> 8)))

#define CMP_4_CONST(a, b) \
    ((*(uint32_t *)(a) == (b)))

#else
/* Don't know what this is - use bytewise comparisons */
#define CMP_3_CONST(a, b) \
    (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
       ((a)[1] ^ (((b) >> 16) & 0xff)) | \
       ((a)[2] ^ (((b) >>  8) & 0xff)) ) == 0)

#define CMP_4_CONST(a, b) \
    (( ((a)[0] ^ (((b) >> 24) & 0xff)) | \
       ((a)[1] ^ (((b) >> 16) & 0xff)) | \
       ((a)[2] ^ (((b) >>  8) & 0xff)) | \
       ((a)[3] ^ (((b)      ) & 0xff)) ) == 0)
#endif /* CPU_* */


/** Streams **/

/* Convert PTS/DTS ticks to our clock ticks */
#define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / TS_SECOND)
/* Convert our clock ticks to PTS/DTS ticks */
#define TICKS_TO_TS(ts)  ((uint64_t)TS_SECOND*(ts) / CLOCK_RATE)
/* Convert timecode ticks to our clock ticks */
#define TC_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / TC_SECOND)
/* Convert our clock ticks to timecode ticks */
#define TICKS_TO_TC(stamp) ((uint64_t)TC_SECOND*(stamp) / CLOCK_RATE)
/* Convert timecode ticks to timestamp ticks */
#define TC_TO_TS(stamp) ((stamp) / 600)

/*
 * S = start position, E = end position
 *
 * pos:
 *     initialize to search start position (S)
 *
 * len:
 *     initialize to = ABS(S-E)
 *     scanning = remaining bytes in scan direction
 *
 * dir:
 *     scan direction; >= 0 == forward, < 0 == reverse
 *
 * margin:
 *     amount of data to right of cursor - initialize by stream_scan_normalize
 *
 * data:
 *     Extra data used/returned by the function implemented
 *
 * Forward scan:
 *     S      pos         E
 *     |       *<-margin->| dir->
 *     |       |<--len--->|
 *
 * Reverse scan:
 *     E      pos         S
 *     |<-len->*<-margin->| <-dir
 *     |       |          |
 */
struct stream_scan
{
    off_t   pos;    /* Initial scan position (file offset) */
    ssize_t len;    /* Maximum length of scan */
    off_t   dir;    /* Direction - >= 0; forward, < 0 backward */
    ssize_t margin; /* Used by function to track margin between position and data end */
    intptr_t data;  /* */
    struct dbuf_l2_cache l2;
};

#define SSCAN_REVERSE (-1)
#define SSCAN_FORWARD 1

/* Initializes the cursor */
void stream_scan_init(struct stream_scan *sk);

/* Ensures direction is -1 or 1 and margin is properly initialized */
void stream_scan_normalize(struct stream_scan *sk);

/* Moves a scan cursor. If amount is positive, the increment is in the scan
 * direction, otherwise opposite the scan direction */
void stream_scan_offset(struct stream_scan *sk, off_t by);

/** Time helpers **/
struct hms
{
    unsigned int hrs;
    unsigned int min;
    unsigned int sec;
    unsigned int frac;
};

void ts_to_hms(uint32_t ts, struct hms *hms);
void hms_format(char *buf, size_t bufsize, struct hms *hms);

/** Maths **/

/* Moving average */
#define AVERAGE(var, x, count) \
    ({ typeof (count) _c = (count);   \
       ((var) * (_c-1) + (x)) / (_c); })

/* Multiply two unsigned 32-bit integers yielding a 64-bit result and
 * divide by another unsigned 32-bit integer to yield a 32-bit result.
 * Rounds to nearest with saturation. */
uint32_t muldiv_uint32(uint32_t multiplicand,
                       uint32_t multiplier,
                       uint32_t divisor);


/** Lists **/

/* Does the list have any members? */
bool list_is_empty(void **list);

/* Is the item inserted into a particular list? */
bool list_is_member(void **list, void *item);

/* Removes an item from a list - returns true if item was found
 * and thus removed. */
bool list_remove_item(void **list, void *item);

/* Adds a list item, insert last, if not already present. */
void list_add_item(void **list, void *item);

/* Clears the entire list. */
void list_clear_all(void **list);

/* Enumerate all items in the array. */
typedef bool (*list_enum_callback_t)(void *item, intptr_t data);

void list_enum_items(void **list,
                     list_enum_callback_t callback,
                     intptr_t data);


/** System events **/

/* Clear event */
void mpeg_sysevent_clear(void);

/* Set to ACTION_STD_CANCEL */
void mpeg_sysevent_set(void);

/* Get event code */
long mpeg_sysevent(void);

/* Call with a system event code and used as menu callback */
int mpeg_sysevent_callback(int btn, const struct menu_item_ex *menu);

/* Handle recorded event */
void mpeg_sysevent_handle(void);


/** Buttons **/

/* Get button codes while remembering important events for later
 * processing; return of ACTION_STD_CANCEL means plugin should
 * abort and handle the event */
int mpeg_button_get(int timeout);

#endif /* MPEG_MISC_H */