Convert para_fade to subcommands, rename it to para_mixer.
[paraslash.git] / aac_common.c
1 /*
2  * Copyright (C) 2006 Andre Noll <maan@tuebingen.mpg.de>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6 /*
7  * based in parts on libfaad, Copyright (C) 2003-2005 M. Bakker,
8  * Ahead Software AG
9  */
10
11 /** \file aac_common.c Common functions of aac_afh and aadcec. */
12
13 #include "para.h"
14 #include "aac.h"
15 #include "error.h"
16 #include "portable_io.h"
17
18 /**
19  * Get a new libfaad decoder handle.
20  *
21  * \return The handle returned by NeAACDecOpen().
22  */
23 NeAACDecHandle aac_open(void)
24 {
25         NeAACDecHandle h = NeAACDecOpen();
26         NeAACDecConfigurationPtr c = NeAACDecGetCurrentConfiguration(h);
27
28         c->defObjectType = LC;
29         c->outputFormat = FAAD_FMT_16BIT;
30         c->downMatrix = 0;
31         NeAACDecSetConfiguration(h, c);
32         return h;
33 }
34
35 static unsigned long aac_read_decoder_length(char *buf, int *description_len)
36 {
37         uint8_t b;
38         uint8_t numBytes = 0;
39         unsigned long length = 0;
40
41         do {
42                 b = buf[numBytes];
43                 numBytes++;
44                 length = (length << 7) | (b & 0x7F);
45         } while
46                 ((b & 0x80) && numBytes < 4);
47         *description_len = numBytes;
48         return length;
49 }
50
51 /**
52  * search for the position and the length of the decoder configuration
53  *
54  * \param buf buffer to seach
55  * \param buflen length of \a buf
56  * \param skip Upon succesful return, this contains the offset in \a buf where
57  * the decoder config starts.
58  * \param decoder_length result pointer that is filled in with the length of
59  * the decoder configuration on success.
60  *
61  * \return positive on success, negative on errors
62  */
63 int aac_find_esds(char *buf, size_t buflen, size_t *skip,
64                 unsigned long *decoder_length)
65 {
66         size_t i;
67
68         for (i = 0; i + 4 < buflen; i++) {
69                 char *p = buf + i;
70                 int description_len;
71
72                 if (p[0] != 'e' || p[1] != 's' || p[2] != 'd' || p[3] != 's')
73                         continue;
74                 i += 8;
75                 p = buf + i;
76                 PARA_INFO_LOG("found esds@%zu, next: %x\n", i, (unsigned)*p);
77                 if (*p == 3)
78                         i += 8;
79                 else
80                         i += 6;
81                 p = buf + i;
82                 PARA_INFO_LOG("next: %x\n", (unsigned)*p);
83                 if (*p != 4)
84                         continue;
85                 i += 18;
86                 p = buf + i;
87                 PARA_INFO_LOG("next: %x\n", (unsigned)*p);
88                 if (*p != 5)
89                         continue;
90                 i++;
91                 p = buf + i;
92                 *decoder_length = aac_read_decoder_length(p, &description_len);
93                 PARA_INFO_LOG("decoder length: %lu\n", *decoder_length);
94                 i += description_len;
95                 *skip = i;
96                 return 1;
97         }
98         return -E_ESDS;
99 }
100
101 /**
102  * search for the first entry in the stco table
103  *
104  * \param buf buffer to seach
105  * \param buflen length of \a buf
106  * \param skip Upon succesful return, this contains the number
107  * of bytes to skip from the input buffer.
108  *
109  * \return the position of the first entry in the table on success,
110  * -E_STCO on errors.
111  */
112 ssize_t aac_find_entry_point(char *buf, size_t buflen, size_t *skip)
113 {
114         ssize_t ret;
115         size_t i;
116
117         for (i = 0; i + 20 < buflen; i++) {
118                 char *p = buf + i;
119
120                 if (p[0] != 's' || p[1] != 't' || p[2] != 'c' || p[3] != 'o')
121                         continue;
122                 PARA_INFO_LOG("found stco@%zu\n", i);
123                 i += 12;
124                 ret = read_u32_be(buf + i); /* first offset */
125                 i += 4;
126                 PARA_INFO_LOG("entry point: %zd\n", ret);
127                 *skip = i;
128                 return ret;
129         }
130         PARA_WARNING_LOG("stco not found, buflen: %zu\n", buflen);
131         return -E_STCO;
132 }