Merge branch 'refs/heads/t/format-signedness'
[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 }