1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <signal.h>
11
12 #include "uvoice_types.h"
13 #include "uvoice_player.h"
14
15 #include "uvoice_os.h"
16 #include "uvoice_common.h"
17 #include "uvoice_play.h"
18
19 #include "pvmp4audiodecoder_api.h"
20
21 #define BOX_TYPE_LEN 4
22 #define DECODER_PREPARED 2
23 #define ASC_BUFF_LEN 12
24
25 #define MP4_ES_DESC_TAG 0x03
26 #define MP4_DEC_CFG_DESC_TAG 0x04
27 #define MP4_DEC_SPEC_DESC_TAG 0x05
28
29 #define MP4_DECODE_NEXT 0
30 #define MP4_DECODE_STOP 1
31 #define MP4_DECODE_END 2
32
33 typedef struct {
34 uint32_t box_size;
35 char box_type[BOX_TYPE_LEN];
36 }box_header_t;
37
38 typedef struct {
39 char major_brand[BOX_TYPE_LEN];
40 int minor_version;
41 char compatible_brands[12];
42 }box_ftyp_t;
43
44 typedef struct {
45 uint32_t box_size;
46 char box_type[BOX_TYPE_LEN];
47 uint8_t version;
48 uint8_t flags[3];
49 uint32_t creation_time;
50 uint32_t modification_time;
51 uint32_t time_scale;
52 uint32_t duration;
53 uint32_t rate;
54 uint8_t reserved[10];
55 uint8_t matrix[36];
56 uint32_t preview_time;
57 uint32_t post_time;
58 uint32_t selection_time;
59 uint32_t selection_duration;
60 uint32_t current_time;
61 uint32_t next_track_id;
62 }box_mvhd_t;
63
64 typedef struct {
65 uint8_t version;
66 uint8_t flag[3];
67 uint32_t entry_num;
68 }box_stco_t;
69
70 typedef struct {
71 uint8_t version;
72 uint8_t flag[3];
73 uint32_t entry_num;
74 }box_stsc_t;
75
76 typedef struct {
77 uint32_t chunk_id;
78 uint32_t samples;
79 uint32_t id;
80 }entry_info_t;
81
82 typedef struct {
83 uint8_t version;
84 uint8_t flag[3];
85 uint32_t sample_size;
86 uint32_t sample_count;
87 }box_stsz_t;
88
89 typedef struct {
90 uint32_t sample_len;
91 uint32_t sample_off;
92 }sample_info_t;
93
94 typedef struct {
95 char decoder_status;
96 char decoder_find; /* bit 0 esds, bit 1 stsz, bit 2 mdat*/
97 char seek_head;
98 char resv;
99
100 uint32_t audio_spec_config_len;
101 uint8_t audio_spec_config_info[ASC_BUFF_LEN];
102 uint32_t sample_count;
103 uint32_t *sample_size_info;
104 uint32_t sample_index;
105 uint32_t unproc_size;
106
107 uint32_t sample_rate;
108 uint32_t frame_length;
109 int channels;
110 }m4a_decoder_t;
111
112 static tPVMP4AudioDecoderExternal g_dec_ext;
113 static void *dec_mem = NULL;
114 static uint32_t dec_mem_len = 0;
115 static media_decoder_t *g_aac_mdecoder = NULL;
116
aac_dec_init(int channels)117 static int aac_dec_init(int channels)
118 {
119 int status = 0;
120
121 if (dec_mem == NULL) {
122 dec_mem_len = PVMP4AudioDecoderGetMemRequirements();
123 dec_mem = malloc(dec_mem_len);
124 if (0 == dec_mem) {
125 return -1;
126 }
127 memset(dec_mem, 0, dec_mem_len);
128 }
129 else {
130 memset(dec_mem, 0, dec_mem_len);
131 }
132
133 memset(&g_dec_ext, 0, sizeof(tPVMP4AudioDecoderExternal));
134
135 g_dec_ext.inputBufferCurrentLength = 0;
136 g_dec_ext.remainderBits = 0;
137 g_dec_ext.inputBufferMaxLength = PVMP4AUDIODECODER_INBUFSIZE;
138 g_dec_ext.outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
139 g_dec_ext.desiredChannels = (int)channels;
140 g_dec_ext.aacPlusEnabled = TRUE;
141
142 status = PVMP4AudioDecoderInitLibrary(&g_dec_ext, dec_mem);
143 return status;
144 }
145
aac_dec_deinit()146 static int aac_dec_deinit()
147 {
148 if (NULL != dec_mem) {
149 snd_free(dec_mem);
150 dec_mem = NULL;
151 }
152
153 dec_mem_len = 0;
154
155 return 0;
156 }
157
aac_decoder_config(const uint8_t * in_buffer,uint32_t in_size,int * samplerate,int * channels,int * framelength)158 static int aac_decoder_config(const uint8_t *in_buffer, uint32_t in_size, int *samplerate, int *channels, int *framelength)
159 {
160 int status = 0;
161
162 g_dec_ext.pInputBuffer = in_buffer;
163 g_dec_ext.inputBufferCurrentLength = in_size;
164 g_dec_ext.pOutputBuffer = NULL;
165
166 status = PVMP4AudioDecoderConfig(&g_dec_ext, dec_mem);
167
168 *samplerate = g_dec_ext.samplingRate;
169 *channels = g_dec_ext.encodedChannels;
170
171 aac_dec_init(*channels);
172 g_dec_ext.pInputBuffer = in_buffer;
173 g_dec_ext.inputBufferCurrentLength = in_size;
174 g_dec_ext.pOutputBuffer = NULL;
175
176 status = PVMP4AudioDecoderConfig(&g_dec_ext, dec_mem);
177
178 *framelength = g_dec_ext.frameLength;
179
180 return status;
181 }
182
aac_decoder_frame(const uint8_t * in_buffer,uint32_t * in_size,uint8_t * out_buffer,uint32_t * out_size)183 static int aac_decoder_frame(const uint8_t *in_buffer, uint32_t *in_size, uint8_t *out_buffer, uint32_t *out_size)
184 {
185 int status = 0;
186
187 g_dec_ext.pInputBuffer = in_buffer;
188 g_dec_ext.pOutputBuffer = out_buffer;
189
190 g_dec_ext.inputBufferCurrentLength = *in_size;
191 g_dec_ext.inputBufferUsedLength = 0;
192
193 status = PVMP4AudioDecodeFrame(&g_dec_ext, dec_mem);
194
195 if (MP4AUDEC_SUCCESS == status || SUCCESS == status) {
196 *in_size -= g_dec_ext.inputBufferUsedLength;
197 *out_size = g_dec_ext.frameLength * g_dec_ext.desiredChannels;
198
199 return status;
200 } else if (MP4AUDEC_INCOMPLETE_FRAME == status) {
201
202 } else {
203 *in_size = 0;
204 }
205
206 return status;
207 }
208
find_box_head(const char * box_type,const uint8_t * in_buf,uint32_t size)209 static int find_box_head(const char *box_type, const uint8_t *in_buf, uint32_t size)
210 {
211 char *f;
212 uint32_t i = 0;
213 int flag = 1;
214
215 if (size < strlen(box_type)) {
216 return -1;
217 }
218
219 do {
220 f = (char *)in_buf + i;
221 i++;
222 flag = memcmp(box_type, f, strlen(box_type));
223 } while ((i < size) && (flag));
224
225 if (flag != 0) {
226 return -1;
227 }
228
229 return i - 1 + strlen(box_type);
230 }
231
m4aac_get_sample_size_info(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)232 static int m4aac_get_sample_size_info(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
233 {
234 int i = 0;
235 int offset = 0;
236 int count = 0;
237 uint32_t *sample_size = NULL;
238 int boxtype_offset = 0;
239 uint32_t *sample_size_buf = NULL;
240
241 m4adec->sample_index = 0;
242
243 offset = find_box_head("stsz", buffer, buff_size);
244 if ((offset < 0) || (offset >= buff_size)) {
245 m4adec->unproc_size = buff_size - BOX_TYPE_LEN + 1;
246 return 0;
247 }
248
249 boxtype_offset = offset;
250
251 if (buff_size - offset < sizeof(box_stsz_t)) {
252 m4adec->unproc_size = buff_size - boxtype_offset;
253 return 0;
254 }
255
256 box_stsz_t *stsz = (box_stsz_t *)(buffer + offset);
257 memcpy(&count, &stsz->sample_count, sizeof(int));
258 count = UINT32_BIG_2_LIT(count);
259
260 offset += sizeof(box_stsz_t);
261 sample_size_buf = (uint32_t *)((uint32_t)buffer + offset);
262 sample_size = (uint32_t *)calloc(count * sizeof(uint32_t) + 256, 1);
263
264 m4adec->sample_count = count;
265
266 count = MIN(m4adec->sample_count, (buff_size - offset) / sizeof(int));
267
268 for (i = 0; i < count; i++) {
269 memcpy(&sample_size[i], sample_size_buf + i, sizeof(int));
270 sample_size[i] = UINT32_BIG_2_LIT(sample_size[i]);
271 }
272
273 m4adec->sample_size_info = sample_size;
274 m4adec->sample_index = count;
275
276 offset += count * sizeof(int);
277
278 m4adec->unproc_size = buff_size - offset;
279
280 return 0;
281 }
282
m4aac_get_sample_size_remain(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)283 static int m4aac_get_sample_size_remain(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
284 {
285 int i = 0;
286 int offset = 0;
287 int count = 0;
288 uint32_t *sample_size = NULL;
289 int boxtype_offset = 0;
290 uint32_t *sample_size_buf = NULL;
291
292 sample_size_buf = (uint32_t *)buffer;
293 sample_size = m4adec->sample_size_info;
294
295 count = MIN(m4adec->sample_count - m4adec->sample_index, (buff_size) / sizeof(int));
296
297 for (i = 0; i < count; i++) {
298 memcpy(&sample_size[i + m4adec->sample_index], sample_size_buf + i, sizeof(int));
299 sample_size[i + m4adec->sample_index] = UINT32_BIG_2_LIT(sample_size[i + m4adec->sample_index]);
300 }
301
302 m4adec->sample_index += count;
303
304 offset += count * sizeof(int);
305
306 m4adec->unproc_size = buff_size - offset;
307
308 return 0;
309 }
310
m4aac_get_mdat(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)311 static int m4aac_get_mdat(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
312 {
313 int offset = 0;
314
315 offset = find_box_head("mdat", buffer, buff_size);
316 if (offset < 0) {
317 m4adec->unproc_size = buff_size - BOX_TYPE_LEN + 1;
318 return -1;
319 }
320
321 m4adec->unproc_size = buff_size - offset;
322 return 0;
323 }
324
convert_to_local_endian(short * buffer,uint32_t samples,char * out_buffer)325 static void convert_to_local_endian(short *buffer, uint32_t samples, char *out_buffer)
326 {
327 int i;
328
329 for (i = 0; i < samples; i++)
330 {
331 out_buffer[i * 2] = (char)(buffer[i] & 0xFF);
332 out_buffer[i * 2 + 1] = (char)((buffer[i] >> 8) & 0xFF);
333 }
334 }
335
pcm_output(m4a_decoder_t * m4adec,uint8_t * in_buf,uint32_t samples)336 static void pcm_output(m4a_decoder_t *m4adec, uint8_t *in_buf, uint32_t samples)
337 {
338 media_decoder_t *mdecoder = g_aac_mdecoder;
339 media_pcminfo_t pcm_info;
340 memset(&pcm_info, 0, sizeof(pcm_info));
341
342 if (!mdecoder->running) {
343 M_LOGD("samplerate %d, channels %d, samples %d\n",
344 m4adec->sample_rate,
345 m4adec->channels,
346 samples);
347
348 pcm_info.rate = m4adec->sample_rate;
349 if (mdecoder->stere_enable) {
350 pcm_info.frames = samples * m4adec->channels;
351 pcm_info.channels = m4adec->channels;
352 } else {
353 pcm_info.channels = 1;
354 pcm_info.frames = samples;
355 }
356 pcm_info.bits = 16;
357 mdecoder->message(mdecoder->priv, PLAYER_MSG_PCM_INFO, &pcm_info);
358
359 media_info_t media_info;
360 memset(&media_info, 0, sizeof(media_info_t));
361 media_info.bitrate = 0;
362 mdecoder->message(mdecoder->priv, PLAYER_MSG_MEDIA_INFO, &media_info);
363 mdecoder->running = 1;
364 }
365
366 if (mdecoder->output &&
367 mdecoder->output(mdecoder->priv, in_buf, samples * 2)) {
368 M_LOGE("output failed !\n");
369 return -1;
370 }
371 }
372
m4aac_decode_sample(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)373 static int m4aac_decode_sample(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
374 {
375 int ret = 0;
376 int offset = 0;
377 int i = 0;
378
379 uint32_t start_sample = m4adec->sample_index;
380 uint32_t sample_count = m4adec->sample_count;
381 uint32_t *sample_size_info = m4adec->sample_size_info;
382
383 uint8_t *readPtr = NULL;
384 uint8_t *sample_buffer = NULL;
385 uint8_t *sample_addr = (uint8_t *)buffer;
386 uint32_t dec_size = 0;
387 uint32_t out_size = 0;
388
389 offset = 0;
390 sample_buffer = malloc(m4adec->frame_length * 4);
391 for (i = start_sample; i < sample_count; i++) {
392 m4adec->sample_index = i;
393 offset += sample_size_info[i];
394 if (buff_size < offset) {
395 m4adec->unproc_size = buff_size - offset + sample_size_info[i];
396 free(sample_buffer);
397 return 0;
398 }
399
400 dec_size = sample_size_info[i];
401 out_size = 0;
402 memset(sample_buffer, 0, m4adec->frame_length * 4);
403
404 aac_decoder_frame(sample_addr, &dec_size, sample_buffer, &out_size);
405
406 if (out_size != 0) {
407 pcm_output(m4adec, sample_buffer, out_size);
408 }
409
410 sample_addr += sample_size_info[i];
411 }
412
413 m4adec->sample_index = sample_count;
414 m4adec->unproc_size = 0;
415 free(sample_buffer);
416
417 return 0;
418 }
419
m4aac_get_audio_config(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)420 static int m4aac_get_audio_config(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
421 {
422 int i = 0;
423 int flag = 0;
424 int offset = 0;
425 int esds_size = 0;
426 int boxtype_offset = 0;
427 int next_offset = 0;
428 int asc_size = 0;
429
430 offset = find_box_head("esds", buffer, buff_size);
431 if ((offset < 0) || (offset >= buff_size)) {
432 m4adec->unproc_size = BOX_TYPE_LEN - 1;
433 return -1;
434 }
435
436 boxtype_offset = offset;
437
438 if (buff_size - offset < 10) {
439 goto config_exit;
440 }
441
442 offset += 4;
443 if (*(buffer + offset) != MP4_ES_DESC_TAG) {
444 goto config_exit;
445 }
446 offset += 1;
447 esds_size = *(buffer + offset);
448 if (esds_size == 0x80) {
449 offset += 3;
450 esds_size = *(buffer + offset);
451 }
452 if (buff_size - offset < esds_size) {
453 goto config_exit;
454 }
455 offset += 1;
456 for (i = 0; i < esds_size; i++) {
457 if (*(buffer + offset + i) == MP4_DEC_CFG_DESC_TAG) {
458 flag = MP4_DEC_CFG_DESC_TAG;
459 }
460 else if ((*(buffer + offset + i) == MP4_DEC_SPEC_DESC_TAG) && (flag == MP4_DEC_CFG_DESC_TAG)) {
461 asc_size = *(buffer + offset + i + 1);
462 if (asc_size == 0x80) {
463 next_offset = 3;
464 asc_size = *(buffer + offset + i + 1 + next_offset);
465 }
466 if ((asc_size > ASC_BUFF_LEN) || (i + 1 + next_offset + asc_size > esds_size)) {
467 continue;
468 }
469 memcpy(m4adec->audio_spec_config_info, buffer + offset + i + 2 + next_offset, asc_size);
470
471 offset += i + 2 + next_offset + asc_size;
472 m4adec->audio_spec_config_len = asc_size;
473 m4adec->unproc_size = buff_size - offset;
474 return 0;
475 }
476 }
477 config_exit:
478 m4adec->unproc_size = buff_size - boxtype_offset;
479 return -1;
480 }
481
482 /* esds stsz mdat */
m4aac_get_audio_info(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)483 static int m4aac_get_audio_info(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
484 {
485 const char *f;
486 int i = 0;
487 int j = 0;
488 int flag = 1;
489 const char *box_type[3] = { "esds", "stsz", "mdat" };
490
491 if (buff_size < strlen(box_type[0])) {
492 return -1;
493 }
494
495 do {
496 f = (const char *)buffer + i;
497 i++;
498 for (j = 0; j < 3; j++) {
499 if ((m4adec->decoder_find & (1 << j)) != 0) {
500 continue;
501 }
502 flag = memcmp(box_type[j], f, strlen(box_type[j]));
503 if (flag == 0) {
504 if (j != 2) {
505 m4adec->decoder_status = j;
506 }
507
508 m4adec->decoder_find |= 1 << j;
509
510 m4adec->unproc_size = buff_size - (i - 1);
511 return 0;
512 }
513 }
514
515 } while (i < buff_size);
516
517 return -1;
518 }
519
m4a_decode_buffer(m4a_decoder_t * m4adec,const uint8_t * buffer,uint32_t buff_size)520 static int m4a_decode_buffer(m4a_decoder_t *m4adec, const uint8_t *buffer, uint32_t buff_size)
521 {
522 uint32_t len = 0;
523 int ret = 0;
524
525 unsigned long samplerate = 0;
526 uint8_t channels = 0;
527
528 static int decode_status = -1;
529 static uint32_t sample_index = 0;
530 static uint32_t *sample_size_info = NULL;
531 static uint32_t sample_count = 0;
532
533 m4adec->unproc_size = 0;
534
535 switch (m4adec->decoder_status)
536 {
537 case -1:
538 m4aac_get_audio_info(m4adec, buffer, buff_size);
539 return MP4_DECODE_NEXT;
540 break;
541
542 case 0:
543 ret = m4aac_get_audio_config(m4adec, buffer, buff_size);
544 if (ret < 0) {
545 return MP4_DECODE_NEXT;
546 }
547
548 ret = aac_decoder_config(m4adec->audio_spec_config_info, m4adec->audio_spec_config_len, &m4adec->sample_rate, &m4adec->channels, &m4adec->frame_length);
549 if (ret != 0) {
550 M_LOGE("aac_decoder_config fail, ret %d\n", ret);
551 return MP4_DECODE_STOP;
552 }
553
554 m4adec->decoder_find |= 1;
555
556 if (m4adec->decoder_find == 3) {
557 m4adec->decoder_status = 3;
558 }
559 else if (m4adec->decoder_find == 7) {
560 m4adec->decoder_status = 3;
561 m4adec->seek_head = 1;
562 }
563 else {
564 m4adec->decoder_status = 1;
565 }
566 return MP4_DECODE_NEXT;
567
568 case 1:
569 ret = m4aac_get_sample_size_info(m4adec, buffer, buff_size);
570 if (m4adec->sample_count == 0) {
571 return MP4_DECODE_NEXT;
572 }
573 if (m4adec->sample_count == m4adec->sample_index) {
574 m4adec->sample_index = 0;
575 m4adec->decoder_find |= 2;
576
577 if (m4adec->decoder_find == 3) {
578 m4adec->decoder_status = 3;
579 }
580 else if (m4adec->decoder_find == 7) {
581 m4adec->decoder_status = 3;
582 m4adec->seek_head = 1;
583 }
584 else {
585 m4adec->decoder_status = 0;
586 }
587 return MP4_DECODE_NEXT;
588 }
589
590 m4adec->decoder_status = 2;
591 return MP4_DECODE_NEXT;
592
593 case 2:
594 ret = m4aac_get_sample_size_remain(m4adec, buffer, buff_size);
595 if (m4adec->sample_count == m4adec->sample_index) {
596 m4adec->sample_index = 0;
597
598 m4adec->decoder_find |= 2;
599
600 if (m4adec->decoder_find == 3) {
601 m4adec->decoder_status = 3;
602 }
603 else if (m4adec->decoder_find == 7) {
604 m4adec->decoder_status = 3;
605 m4adec->seek_head = 1;
606 }
607 else {
608 m4adec->decoder_status = 0;
609 }
610 }
611
612 return MP4_DECODE_NEXT;
613
614 case 3:
615 ret = m4aac_get_mdat(m4adec, buffer, buff_size);
616 if (ret == 0) {
617 m4adec->decoder_status = 4;
618 }
619
620 return MP4_DECODE_NEXT;
621
622 case 4:
623 ret = m4aac_decode_sample(m4adec, buffer, buff_size);
624 if (m4adec->sample_count == m4adec->sample_index) {
625 free(m4adec->sample_size_info);
626 m4adec->sample_size_info = NULL;
627 return MP4_DECODE_END;
628 }
629
630 return MP4_DECODE_NEXT;
631
632 default:
633 break;
634 }
635
636 return MP4_DECODE_STOP;
637 }
638
m4a_decoder_process(void * priv,const uint8_t * buffer,int nbytes)639 static int m4a_decoder_process(void *priv, const uint8_t *buffer, int nbytes)
640 {
641 media_decoder_t *mdecoder = priv;
642 m4a_decoder_t *m4adec;
643 int ret = 0;
644 int unproc_size = 0;
645
646 if (!mdecoder) {
647 M_LOGE("mdecoder null !\n");
648 return -1;
649 }
650
651 g_aac_mdecoder = mdecoder;
652
653 m4adec = mdecoder->decoder;
654 if (!m4adec) {
655 M_LOGE("pvm4adec null !\n");
656 return -1;
657 }
658
659 ret = m4a_decode_buffer(m4adec, buffer, nbytes);
660 mdecoder->unproc_size = m4adec->unproc_size;
661
662 if (ret == MP4_DECODE_END) {
663 ret = 0;
664 }
665
666 return ret;
667 }
668
m4a_decoder_action(void * priv,player_action_t action,void * arg)669 static int m4a_decoder_action(void *priv, player_action_t action, void *arg)
670 {
671 return 0;
672 }
673
pvm4a_decoder_create(media_decoder_t * mdecoder)674 int pvm4a_decoder_create(media_decoder_t *mdecoder)
675 {
676 m4a_decoder_t *m4adec;
677 int a1 = 0;
678
679 if (!mdecoder) {
680 M_LOGE("mdecoder null !\n");
681 return -1;
682 }
683
684 m4adec = snd_zalloc(sizeof(m4a_decoder_t), AFM_MAIN);
685 if (!m4adec) {
686 M_LOGE("alloc pvm4a decoder failed !\n");
687 return -1;
688 }
689
690 g_aac_mdecoder = mdecoder;
691
692 mdecoder->decode = m4a_decoder_process;
693 mdecoder->action = m4a_decoder_action;
694 mdecoder->decoder = m4adec;
695
696 aac_dec_init(1);
697
698 M_LOGD("pvm4a decoder create\n");
699 return 0;
700 }
701
pvm4a_decoder_release(media_decoder_t * mdecoder)702 int pvm4a_decoder_release(media_decoder_t *mdecoder)
703 {
704 m4a_decoder_t *m4adec;
705 if (!mdecoder) {
706 M_LOGE("mdecoder null !\n");
707 return -1;
708 }
709 m4adec = mdecoder->decoder;
710 if (!m4adec) {
711 M_LOGE("pvm4a_decoder null !\n");
712 return -1;
713 }
714
715 aac_dec_deinit();
716
717 snd_free(m4adec);
718 mdecoder->decode = NULL;
719 mdecoder->action = NULL;
720 g_aac_mdecoder = NULL;
721
722 M_LOGD("pvm4a decoder release\n");
723 return 0;
724 }
725
726
727