blob: ae32386521c101d4f8115220184b127477ac9a68
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | #include <fcntl.h> |
5 | #include <unistd.h> |
6 | #include <pthread.h> |
7 | #include <sys/ioctl.h> |
8 | #include <dlfcn.h> |
9 | #include <sys/mman.h> |
10 | #include <cutils/properties.h> |
11 | |
12 | |
13 | |
14 | #include "aaccommon.h" |
15 | #include "aacdec.h" |
16 | #include "../../amadec/adec-armdec-mgt.h" |
17 | |
18 | |
19 | int AACDataSource = 1; |
20 | static HAACDecoder hAACDecoder; |
21 | static HAACIOBuf hAACIOBuf = NULL; |
22 | |
23 | static int mute_pcm_bytes; |
24 | /* check the normal frame size */ |
25 | static unsigned last_frm_size; |
26 | static unsigned cur_frm_size; |
27 | static int lastFrameLen ; |
28 | static int lastSampPerFrm ; |
29 | |
30 | #define FRAME_RECORD_NUM 20 |
31 | static unsigned error_count = 0; |
32 | static unsigned mute_pcm_thread; |
33 | static unsigned his_index; |
34 | static unsigned frame_length_his[FRAME_RECORD_NUM]; |
35 | |
36 | static unsigned stream_in_offset = 0; |
37 | static unsigned enable_debug_print = 0; |
38 | /* Channel definitions */ |
39 | #define FRONT_CENTER (0) |
40 | #define FRONT_LEFT (1) |
41 | #define FRONT_RIGHT (2) |
42 | #define SIDE_LEFT (3) |
43 | #define SIDE_RIGHT (4) |
44 | #define BACK_LEFT (5) |
45 | #define LFE_CHANNEL (6) |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | #define ASTREAM_DEV "/dev/uio0" |
52 | #define ASTREAM_ADDR "/sys/class/astream/astream-dev/uio0/maps/map0/addr" |
53 | #define ASTREAM_SIZE "/sys/class/astream/astream-dev/uio0/maps/map0/size" |
54 | #define ASTREAM_OFFSET "/sys/class/astream/astream-dev/uio0/maps/map0/offset" |
55 | |
56 | |
57 | |
58 | #define AIU_AIFIFO_CTRL 0x1580 |
59 | #define AIU_AIFIFO_STATUS 0x1581 |
60 | #define AIU_AIFIFO_GBIT 0x1582 |
61 | #define AIU_AIFIFO_CLB 0x1583 |
62 | #define AIU_MEM_AIFIFO_START_PTR 0x1584 |
63 | #define AIU_MEM_AIFIFO_CURR_PTR 0x1585 |
64 | #define AIU_MEM_AIFIFO_END_PTR 0x1586 |
65 | #define AIU_MEM_AIFIFO_BYTES_AVAIL 0x1587 |
66 | #define AIU_MEM_AIFIFO_CONTROL 0x1588 |
67 | #define AIU_MEM_AIFIFO_MAN_WP 0x1589 |
68 | #define AIU_MEM_AIFIFO_MAN_RP 0x158a |
69 | #define AIU_MEM_AIFIFO_LEVEL 0x158b |
70 | #define AIU_MEM_AIFIFO_BUF_CNTL 0x158c |
71 | #define AIU_MEM_AIFIFO_BUF_WRAP_COUNT 0x158d |
72 | #define AIU_MEM_AIFIFO2_BUF_WRAP_COUNT 0x158e |
73 | #define AIU_MEM_AIFIFO_MEM_CTL 0x158f |
74 | |
75 | volatile unsigned* reg_base = 0; |
76 | #define READ_MPEG_REG(reg) reg_base[reg-AIU_AIFIFO_CTRL] |
77 | #define WRITE_MPEG_REG(reg, val) reg_base[reg-AIU_AIFIFO_CTRL]=val |
78 | #define AIFIFO_READY (((READ_MPEG_REG(AIU_MEM_AIFIFO_CONTROL)&(1<<9)))) |
79 | #define min(x,y) ((x<y)?(x):(y)) |
80 | static int fd_uio = -1; |
81 | static volatile void *memmap = MAP_FAILED; |
82 | static int phys_size; |
83 | static volatile int exit_flag = 0; |
84 | static unsigned long amsysfs_get_sysfs_ulong(const char *path) |
85 | { |
86 | int fd; |
87 | char bcmd[24] = ""; |
88 | unsigned long num = 0; |
89 | if ((fd = open(path, O_RDONLY)) >= 0) { |
90 | read(fd, bcmd, sizeof(bcmd)); |
91 | num = strtoul(bcmd, NULL, 0); |
92 | close(fd); |
93 | } else { |
94 | audio_codec_print("unable to open file %s,", path); |
95 | } |
96 | return num; |
97 | } |
98 | static unsigned long get_num_infile(char *file) |
99 | { |
100 | return amsysfs_get_sysfs_ulong(file); |
101 | } |
102 | |
103 | static int uio_init() |
104 | { |
105 | int pagesize = getpagesize(); |
106 | int phys_start; |
107 | int phys_offset; |
108 | |
109 | |
110 | fd_uio = open(ASTREAM_DEV, O_RDWR); |
111 | if (fd_uio < 0) { |
112 | audio_codec_print("error open UIO 0\n"); |
113 | return -1; |
114 | } |
115 | phys_start = get_num_infile(ASTREAM_ADDR); |
116 | phys_size = get_num_infile(ASTREAM_SIZE); |
117 | phys_offset = get_num_infile(ASTREAM_OFFSET); |
118 | |
119 | audio_codec_print("add=%08x, size=%08x, offset=%08x\n", phys_start, phys_size, phys_offset); |
120 | |
121 | phys_size = (phys_size + pagesize - 1) & (~(pagesize - 1)); |
122 | memmap = mmap(NULL, phys_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_uio, 0 * pagesize); |
123 | |
124 | audio_codec_print("memmap = %x , pagesize = %x\n", memmap, pagesize); |
125 | if (memmap == MAP_FAILED) { |
126 | audio_codec_print("map /dev/uio0 failed\n"); |
127 | return -1; |
128 | } |
129 | |
130 | if (phys_offset == 0) |
131 | phys_offset = (AIU_AIFIFO_CTRL*4)&(pagesize-1); |
132 | reg_base = memmap + phys_offset; |
133 | return 0; |
134 | } |
135 | |
136 | #define EXTRA_DATA_SIZE 128 |
137 | |
138 | static inline void waiting_bits(int bits) |
139 | { |
140 | int bytes; |
141 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
142 | while (bytes * 8 < bits && !exit_flag) { |
143 | usleep(1000); |
144 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
145 | } |
146 | } |
147 | |
148 | int read_buffer(unsigned char *buffer, int size) |
149 | { |
150 | int bytes; |
151 | int len; |
152 | unsigned char *p = buffer; |
153 | int tmp; |
154 | int space; |
155 | int i; |
156 | int wait_times = 0, fifo_ready_wait = 0; |
157 | |
158 | int iii; |
159 | |
160 | iii = READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL) - EXTRA_DATA_SIZE; |
161 | if ((size >= iii)) { |
162 | return 0; |
163 | } |
164 | |
165 | // adec_print("read_buffer start while iii= %d!!\n", iii); |
166 | for (len = 0; len < size;) { |
167 | space = (size - len); |
168 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
169 | //adec_print("read_buffer start AIU_MEM_AIFIFO_BYTES_AVAIL bytes= %d!!\n", bytes); |
170 | wait_times = 0; |
171 | while (bytes == 0) { |
172 | waiting_bits((space > 128) ? 128 * 8 : (space * 8)); /*wait 32 bytes,if the space is less than 32 bytes,wait the space bits*/ |
173 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
174 | |
175 | audio_codec_print("read_buffer while AIU_MEM_AIFIFO_BYTES_AVAIL = %d!!\n", bytes); |
176 | wait_times++; |
177 | if (wait_times > 10) { |
178 | audio_codec_print("goto out!!\n"); |
179 | goto out; |
180 | } |
181 | } |
182 | bytes = min(space, bytes); |
183 | |
184 | //adec_print("read_buffer while bytes = %d!!\n", bytes); |
185 | for (i = 0; i < bytes; i++) { |
186 | while (!AIFIFO_READY) { |
187 | fifo_ready_wait++; |
188 | usleep(1000); |
189 | if (fifo_ready_wait > 100) { |
190 | audio_codec_print("FATAL err,AIFIFO is not ready,check!!\n"); |
191 | return 0; |
192 | } |
193 | } |
194 | WRITE_MPEG_REG(AIU_AIFIFO_GBIT, 8); |
195 | tmp = READ_MPEG_REG(AIU_AIFIFO_GBIT); |
196 | //adec_print("read_buffer while tmp = %d!!\n", tmp); |
197 | |
198 | *p++ = tmp & 0xff; |
199 | fifo_ready_wait = 0; |
200 | |
201 | } |
202 | len += bytes; |
203 | } |
204 | out: |
205 | stream_in_offset += len; |
206 | return len; |
207 | } |
208 | int get_audiobuf_level() |
209 | { |
210 | int level = 0; |
211 | level = READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL) - EXTRA_DATA_SIZE; |
212 | if (level < 0) { |
213 | level = 0; |
214 | } |
215 | return level; |
216 | } |
217 | |
218 | |
219 | static unsigned get_frame_size() |
220 | { |
221 | int i; |
222 | unsigned sum = 0; |
223 | unsigned valid_his_num = 0; |
224 | for (i = 0; i < FRAME_RECORD_NUM; i++) { |
225 | if (frame_length_his[i] > 0) { |
226 | valid_his_num ++; |
227 | sum += frame_length_his[i]; |
228 | } |
229 | } |
230 | |
231 | if (valid_his_num == 0) { |
232 | return 0; |
233 | } |
234 | |
235 | return sum / valid_his_num; |
236 | } |
237 | |
238 | unsigned get_audio_inbuf_latency(int bytesin) |
239 | { |
240 | int frame_size = 0; |
241 | int latency_ms = 0; |
242 | frame_size = get_frame_size(); |
243 | if (frame_size > 0) { |
244 | latency_ms = bytesin * 1024 / (frame_size * 48); |
245 | } |
246 | return latency_ms; |
247 | } |
248 | |
249 | static HAACDecoder aac_init_decoder() |
250 | { |
251 | return AACInitDecoder(); |
252 | } |
253 | static HAACIOBuf aac_init_iobuf() |
254 | { |
255 | return (HAACIOBuf)calloc(1, sizeof(AACIOBuf)); |
256 | } |
257 | #define AUDIO_BUFFER_REMAINED 128 |
258 | static void aac_refill_buffer(HAACIOBuf hIOBuf) |
259 | { |
260 | AACIOBuf *IOBuf = (AACIOBuf*)hIOBuf; |
261 | int bytes_expected; |
262 | int read_bytes; |
263 | int read_level_count = 0; |
264 | int buf_level = 0; |
265 | int retry_time = 0; |
266 | |
267 | start_read: |
268 | if (exit_flag) { |
269 | return ; |
270 | } |
271 | do { |
272 | buf_level = get_audiobuf_level(); |
273 | if (buf_level <= 0) { |
274 | break; |
275 | } |
276 | |
277 | if (IOBuf->bytesLeft > 0) { |
278 | while (IOBuf->bytesLeft > AAC_INPUTBUF_SIZE) { |
279 | ; |
280 | } |
281 | memcpy(IOBuf->readBuf, IOBuf->readPtr, IOBuf->bytesLeft); |
282 | } |
283 | |
284 | while (IOBuf->bytesLeft < 0) { |
285 | printk("IOBuf->bytesLeft < 0\n", IOBuf->bytesLeft); |
286 | } |
287 | |
288 | bytes_expected = AAC_INPUTBUF_SIZE - IOBuf->bytesLeft; |
289 | |
290 | while (bytes_expected < 0) { |
291 | printk("bytes_expected = %d\n", bytes_expected); |
292 | } |
293 | |
294 | if (bytes_expected > buf_level) { |
295 | bytes_expected = buf_level; |
296 | } |
297 | |
298 | read_bytes = read_buffer(IOBuf->readBuf + IOBuf->bytesLeft, bytes_expected); |
299 | |
300 | IOBuf->readPtr = IOBuf->readBuf; |
301 | IOBuf->bytesLeft += read_bytes; |
302 | } while (0); |
303 | if (IOBuf->bytesLeft < get_frame_size()) { |
304 | goto start_read; |
305 | } |
306 | } |
307 | |
308 | static int aac_reset_decoder(HAACDecoder hAACDecoder, HAACIOBuf hIOBuf) |
309 | { |
310 | AACIOBuf *IOBuf = (AACIOBuf*)hIOBuf; |
311 | IOBuf->readPtr = IOBuf->readBuf; |
312 | IOBuf->bytesLeft = 0; |
313 | return AACFlushCodec(hAACDecoder); |
314 | } |
315 | static int aac_decode_frame(HAACDecoder hAACDecoder, HAACIOBuf hIOBuf) |
316 | { |
317 | int err; |
318 | AACIOBuf *IOBuf = (AACIOBuf*)hIOBuf; |
319 | if (AACDataSource == 1) { |
320 | if (IOBuf->bytesLeft < AAC_INPUTBUF_SIZE / 2) { |
321 | aac_refill_buffer(IOBuf); |
322 | } |
323 | } |
324 | if (exit_flag) { |
325 | return ERR_AAC_EXIT_DECODE; |
326 | } |
327 | /* decode one AAC frame */ |
328 | err = AACDecode(hAACDecoder, &(IOBuf->readPtr), &(IOBuf->bytesLeft), (IOBuf->outBuf)); |
329 | return err; |
330 | } |
331 | int audio_dec_init(audio_decoder_operations_t *adp) |
332 | { |
333 | //printk("\n\n[%s]WFDAAC DEC BuildDate--%s BuildTime--%s", __FUNCTION__, __DATE__, __TIME__); |
334 | char value[PROPERTY_VALUE_MAX]; |
335 | if (property_get("media.wfd.debug_dec", value, NULL) > 0) { |
336 | enable_debug_print = atoi(value); |
337 | } |
338 | int err = 0, ch = 0, i; |
339 | AACFrameInfo aacFrameInfo = {0}; |
340 | audio_codec_print("helix_aac_decoder_init start \n"); |
341 | err = uio_init(); |
342 | if (err) { |
343 | return -1; |
344 | } |
345 | hAACDecoder = aac_init_decoder(); |
346 | if (!hAACDecoder) { |
347 | printk("fatal error,helix aac decoder init failed\n"); |
348 | return -1; |
349 | } |
350 | hAACIOBuf = aac_init_iobuf(); |
351 | if (!hAACIOBuf) { |
352 | printk("fatal error,helix aac decoder init iobuf failed\n"); |
353 | |
354 | return -1; |
355 | } |
356 | |
357 | return 0; |
358 | } |
359 | |
360 | /* |
361 | channel configuration mapping |
362 | ch nums position |
363 | 3 FC FL FR |
364 | 4 FC FL FR BC |
365 | 5 FC FL FR BL BR |
366 | 6 FC FL FR BL BR LFE |
367 | |
368 | */ |
369 | #define FATAL_ERR_RESET_COUNT 2000 |
370 | int audio_dec_decode(audio_decoder_operations_t *adec_ops, char *buf, int *outlen, char *inbuf, int inlen) |
371 | { |
372 | int err, i, sample_out = 0, ch; |
373 | short *pcmbuf = (short*)buf; |
374 | short *ouput = (short*)(((AACIOBuf*)hAACIOBuf)->outBuf); |
375 | int ch_num; |
376 | int sum; |
377 | unsigned ch_map_scale[6] = {2, 4, 4, 2, 2, 0}; //full scale == 8 |
378 | AACFrameInfo aacFrameInfo = {0}; |
379 | |
380 | err = aac_decode_frame(hAACDecoder, hAACIOBuf); |
381 | if (!err) { |
382 | error_count = 0; |
383 | AACGetLastFrameInfo(hAACDecoder, &aacFrameInfo); |
384 | |
385 | |
386 | /* L = (l+c)/2;R = (r+c)/2 */ |
387 | if (aacFrameInfo.nChans > 2) { //should do downmix to 2ch output. |
388 | ch_num = aacFrameInfo.nChans; |
389 | sample_out = aacFrameInfo.outputSamps / ch_num * 2 * 2; //ch_num*sample_num*16bit |
390 | if (ch_num == 3 || ch_num == 4) { |
391 | ch_map_scale[0] = 4; //50% |
392 | ch_map_scale[1] = 4;//50% |
393 | ch_map_scale[2] = 4;//50% |
394 | ch_map_scale[3] = 0; |
395 | ch_map_scale[4] = 0; |
396 | ch_map_scale[5] = 0; |
397 | } |
398 | for (i = 0; i < aacFrameInfo.outputSamps / ch_num; i++) { |
399 | sum = ((int)ouput[ch_num * i + FRONT_LEFT] * ch_map_scale[FRONT_LEFT] + (int)ouput[ch_num * i + FRONT_CENTER] * ch_map_scale[FRONT_CENTER] + (int)ouput[ch_num * i + BACK_LEFT] * ch_map_scale[BACK_LEFT]); |
400 | pcmbuf[i * 2] = sum >> 3; |
401 | sum = ((int)ouput[ch_num * i + FRONT_RIGHT] * ch_map_scale[FRONT_RIGHT] + (int)ouput[ch_num * i + FRONT_CENTER] * ch_map_scale[FRONT_CENTER] + (int)ouput[ch_num * i + BACK_LEFT] * ch_map_scale[BACK_LEFT]); |
402 | pcmbuf[2 * i + 1] = sum >> 3; |
403 | } |
404 | } else { |
405 | memcpy(pcmbuf, ouput, aacFrameInfo.outputSamps * 2); |
406 | sample_out = aacFrameInfo.outputSamps * 2; //ch_num*sample_num*16bit |
407 | } |
408 | |
409 | AACGetDecoderInfo(hAACDecoder, &aacFrameInfo); |
410 | // fmt->total_byte_parsed = aacFrameInfo.total_byte_parsed; |
411 | // fmt->total_sample_decoded = aacFrameInfo.total_sample_decoded; |
412 | // fmt->format = aacFrameInfo.format; |
413 | // fmt->bps = aacFrameInfo.bitRate; |
414 | |
415 | lastFrameLen = ((AACDecInfo*)hAACDecoder)->frame_length; |
416 | /* record the frame length into the history buffer */ |
417 | for (i = 0; i < FRAME_RECORD_NUM - 1; i++) { |
418 | frame_length_his[i] = frame_length_his[i + 1]; |
419 | } |
420 | frame_length_his[FRAME_RECORD_NUM - 1] = lastFrameLen; |
421 | unsigned abuf_level = get_audiobuf_level(); |
422 | unsigned dec_cached = ((AACIOBuf*)hAACIOBuf)->bytesLeft; |
423 | unsigned in_latency_ms = get_audio_inbuf_latency(abuf_level + dec_cached); |
424 | if (enable_debug_print) |
425 | printk("sampRateCore %d,sampRateOut %d,last frame len %d,avarge frame size %d,decode out sample %d,buf level %d,decode cached %d,total level %d ;latency %d ms \n", \ |
426 | aacFrameInfo.sampRateCore, aacFrameInfo.sampRateOut, \ |
427 | lastFrameLen, get_frame_size(), sample_out, \ |
428 | abuf_level, dec_cached, abuf_level + dec_cached, in_latency_ms); |
429 | memcpy(inbuf, &in_latency_ms, sizeof(in_latency_ms)); |
430 | lastSampPerFrm = sample_out; |
431 | adec_ops->samplerate = aacFrameInfo.sampRateOut; |
432 | adec_ops->channels = aacFrameInfo.nChans > 2 ? 2 : aacFrameInfo.nChans; |
433 | } else if (err == ERR_AAC_INDATA_UNDERFLOW) { |
434 | aac_refill_buffer(hAACIOBuf); |
435 | } |
436 | /* why add this ???? |
437 | else if (err==ERR_AAC_NCHANS_TOO_HIGH) |
438 | { |
439 | //maybe we meet zero frame |
440 | ((AACIOBuf*)hAACIOBuf)->bytesLeft =0; |
441 | sample_out =0; |
442 | } |
443 | */ |
444 | else if (err == ERR_AAC_EXIT_DECODE) { |
445 | sample_out = 0; |
446 | } else { |
447 | int frame_length; |
448 | if (ERR_AAC_SSR_GAIN_NOT_ADDED != err) { |
449 | error_count++; |
450 | } |
451 | // error, disable output, reset decoder and flush io |
452 | if (/*!mute_frame_num*/(error_count % 20) == 1) { //only print the every 20 times error |
453 | #if 0 |
454 | printk("helix aac decoder error,err num :%d,try output 40 mute frames and skip err bitstream\n", err); |
455 | printk("frame_length = %d\n", get_frame_size()); |
456 | printk("sames per frame: %d\n", lastSampPerFrm); |
457 | #endif |
458 | } |
459 | if (error_count == FATAL_ERR_RESET_COUNT) { // send to player to reset the player |
460 | printk("decoder error count FATAL_ERR_RESET_COUNT %s\n", FATAL_ERR_RESET_COUNT); |
461 | // trans_err_code(DECODE_FATAL_ERR); |
462 | } |
463 | //aac_reset_decoder(hAACDecoder, hAACIOBuf); |
464 | // AACFlushCodec(hAACDecoder); |
465 | frame_length = get_frame_size() * 2 / 3/*((AACDecInfo*)hAACDecoder)->frame_length*/; //skip 2/3 of last frame size |
466 | if (AACDataSource) { |
467 | if (frame_length > 0) { |
468 | if (((AACIOBuf*)hAACIOBuf)->bytesLeft > frame_length) { |
469 | ((AACIOBuf*)hAACIOBuf)->bytesLeft -= frame_length; |
470 | ((AACIOBuf*)hAACIOBuf)->readPtr += frame_length; |
471 | // printk("skip1 %d bytes \n",frame_length); |
472 | } else { |
473 | // printk("skip2 %d bytes \n",((AACIOBuf*)hAACIOBuf)->bytesLeft); |
474 | |
475 | ((AACIOBuf*)hAACIOBuf)->readPtr = ((AACIOBuf*)hAACIOBuf)->readBuf; |
476 | ((AACIOBuf*)hAACIOBuf)->bytesLeft = 0; |
477 | |
478 | } |
479 | } else { |
480 | if (((AACIOBuf*)hAACIOBuf)->bytesLeft > 100) { |
481 | ((AACIOBuf*)hAACIOBuf)->bytesLeft -= 100; |
482 | ((AACIOBuf*)hAACIOBuf)->readPtr += 100; |
483 | |
484 | // printk("skip3 %d bytes \n",100); |
485 | } else { |
486 | // printk("skip4 %d bytes \n",((AACIOBuf*)hAACIOBuf)->bytesLeft); |
487 | |
488 | ((AACIOBuf*)hAACIOBuf)->readPtr = ((AACIOBuf*)hAACIOBuf)->readBuf; |
489 | ((AACIOBuf*)hAACIOBuf)->bytesLeft = 0; |
490 | |
491 | } |
492 | } |
493 | } |
494 | |
495 | sample_out = 0;//lastSampPerFrm/*fmt->channel_num*2*1024*/; |
496 | mute_pcm_bytes = mute_pcm_thread; |
497 | } |
498 | if (sample_out && mute_pcm_bytes > 0) { |
499 | memset(buf, 0, sample_out); |
500 | mute_pcm_bytes -= sample_out; |
501 | } |
502 | if (!err) { |
503 | mute_pcm_thread = 0; |
504 | |
505 | } |
506 | |
507 | |
508 | *outlen = sample_out; |
509 | return stream_in_offset; |
510 | } |
511 | |
512 | int audio_dec_release(audio_decoder_operations_t *adec_ops) |
513 | { |
514 | #if 0 |
515 | if (hAACIOBuf) { |
516 | free(hAACIOBuf); |
517 | hAACIOBuf = NULL; |
518 | } |
519 | if (hAACDecoder) { |
520 | AACFreeDecoder(hAACDecoder); |
521 | hAACDecoder = NULL; |
522 | } |
523 | #endif |
524 | if (fd_uio >= 0) { |
525 | close(fd_uio); |
526 | } |
527 | fd_uio = -1; |
528 | if (memmap != NULL && memmap != MAP_FAILED) { |
529 | munmap(memmap, phys_size); |
530 | } |
531 | printk("WFDAAC audio_dec_release done \n"); |
532 | return 0; |
533 | } |
534 | int audio_dec_getinfo(audio_decoder_operations_t *adec_ops, void *pAudioInfo) |
535 | { |
536 | return 0; |
537 | } |
538 | |
539 | |
540 | void audio_set_exit_flag() |
541 | { |
542 | exit_flag = 1; |
543 | printk("adec decode exit flag set \n"); |
544 | } |
545 | |
546 | |
547 | |
548 | |
549 |