📄 aacdecode.c
字号:
break; } if (samplerate_code >= 12) /* use the default of 44100 */ samplerate_code = 4; obj = (unsigned short)(object_type << 11); obj |= (unsigned short)(samplerate_code << 7); obj |= (unsigned short)(demux_chans << 3); /* swap bytes */ { unsigned short aa, bb; aa = bb = obj; bb >>= 8; bb |= aa << 8; obj = bb; } /* bits meaning 5 objectTypeIndex 4 samplingFrequencyIndex 4 channelsConfiguration if objectTypeIndex == 5 SBR 4 samplingFrequencyIndex extension if samplingFrequencyIndex == 15 24 samplingFrequency 5 objectTypeIndex 11 syncExtensionType if syncExtensionType == 2b7 5 objectTypeIndex */ //buffer = (unsigned char *)&obj; //buffer_size = 2; //printf("config %x %x\n", buffer[0], buffer[1]); //printf("old-style config %x %x, object_type %x\n", buffer[0], buffer[1], object_type); buffer_size = input_buf[10]; buffer = &input_buf[11]; INIT_PRINTF((M_TEXT("initializing AAC decoder library, size %x, %02x %02x %02x %02x %02x\n"), buffer_size, buffer[0],buffer[1],buffer[2],buffer[3],buffer[4])); if (faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &save_channels) < 0) { /* If some error initializing occured, skip the file */ INIT_PRINTF((M_TEXT("Error initializing AAC decoder library.\n"))); faacDecClose(hDecoder); hDecoder = NULL; return -1; } if (samplerate != demux_stipulated_samplerate) { INIT_PRINTF((M_TEXT("Demux samplerate %d differs from AAC samplerate %d\n"), demux_stipulated_samplerate, samplerate)); #ifndef SBR_DEC if (samplerate > 0) non_SBR_upsample = demux_stipulated_samplerate / samplerate; #endif } if (save_channels != demux_chans) { /* we have to use the channels that demux gives us even if it differes from what is in the AAC data */ INIT_PRINTF((M_TEXT("Demux channels %d differs from AAC channels %d\n"), demux_chans, save_channels)); } demux_stipulated_channels = ci->channels = frameInfo.channels = save_channels = demux_chans; ci->sampling_rate = frameInfo.samplerate = samplerate; //printf("sr %d, ch %d\n", ci->sampling_rate, ci->channels); bytes_read = inbuf_size; // assume that this buffer just contains header info } else { if (input_buf[4] == 'f' && input_buf[5] == 't' && input_buf[6] == 'y' && input_buf[7] == 'p') mp4file = 1; if (mp4file) { printf("MP4 parsing is not supported. Use the mp4 demux.\n"); return -1; } else { tagsize = 0; if (!memcmp(input_buf, "ID3", 3)) { /* high bit is not used */ tagsize = (input_buf[6] << 21) | (input_buf[7] << 14) | (input_buf[8] << 7) | (input_buf[9] << 0); tagsize += 10; DPRINTF((M_TEXT("found ID3 tag %d bytes long\n"), tagsize)); *out_size = 0; //printf("gobbling %d\n", tagsize); if (inbuf_size < tagsize) { gobble_amount = tagsize - inbuf_size; //printf("gobble left %d\n", gobble_amount); return inbuf_size; } else { tagsize = gobble_amount; gobble_amount = 0; return tagsize; /* done gobbling */ } } hDecoder = faacDecOpen(); /* Set the default object type and sampling_rate. This is useful for RAW AAC files */ config = faacDecGetCurrentConfiguration(hDecoder); // config->defSampleRate = def_srate; config->defSampleRate = save_samplerate; config->defObjectType = LC; config->outputFormat = FAAD_FMT_16BIT; config->downMatrix = 0; config->useOldADTSFormat = 0; config->dontUpSampleImplicitSBR = 1; faacDecSetConfiguration(hDecoder, config); /* get AAC info */ header_type = 0; if ((input_buf[0] == 0xFF) && ((input_buf[1] & 0xF6) == 0xF0)) { adts_parse(input_buf, &save_samplerate, &frame_length); header_type = ADTS; } else if (memcmp(input_buf, "ADIF", 4) == 0) { header_type = ADIF; } if ((bytes_read = faacDecInit(hDecoder, input_buf, inbuf_size, &save_samplerate, &save_channels)) < 0) { /* If some error initializing occured, skip the file */ INIT_PRINTF((M_TEXT("Error initializing AAC decoder library.\n"))); if (input_buf) free(input_buf); input_buf = NULL; faacDecClose(hDecoder); hDecoder = NULL; return -1; } /* print AAC file info */ switch (header_type) { case 0: INFO_PRINTF((M_TEXT("AAC RAW\n"))); break; case ADIF: INFO_PRINTF((M_TEXT("AAC ADIF\n"))); break; case ADTS: INFO_PRINTF((M_TEXT("AAC ADTS\n"))); break; } frameInfo.header_type = header_type; *p_outbuf = faacDecDecode(hDecoder, &frameInfo, input_buf+bytes_read, inbuf_size-bytes_read); bytes_read += frameInfo.bytesconsumed; print_channel_info(&frameInfo); } } } else { if (mp4file) { printf("mp4 not supported outside demux!\n"); } else { // I have not seen more than 1 padding byte per frame - jrl if ((*input_buf == 0) && (*(input_buf+1) == 0x21)) /* fix for raw streams that have padding */ { DPRINTF((M_TEXT("call faacDecDecode with pad byte\n"))); *p_outbuf = faacDecDecode(hDecoder, &frameInfo, input_buf+1, inbuf_size-1); bytes_read = frameInfo.bytesconsumed + 1; } else /* no padding */ { DPRINTF((M_TEXT("call faacDecDecode\n"))); *p_outbuf = faacDecDecode(hDecoder, &frameInfo, input_buf, inbuf_size); bytes_read = frameInfo.bytesconsumed; } DPRINTF((M_TEXT("after faacDecDecode bytes_read %d, channels %d\n"), bytes_read, frameInfo.channels)); //printf("channels after decode %d\n", frameInfo.channels); if (frameInfo.error > 0) { char *ss = faacDecGetErrorMessage(frameInfo.error); DPRINTF((M_TEXT("AAC Error: %s."), ss)); } } } /* set these again in case they change */ ci->sampling_rate = frameInfo.samplerate; ci->bits_per_sample = 16; ci->max_output_buffer_size = 8192; if (demux_stipulated_channels && (demux_stipulated_channels != frameInfo.channels) && (*p_outbuf != NULL)) { ci->channels = demux_stipulated_channels; // printf("demux wants %d channels, not %d\n", demux_stipulated_channels, frameInfo.channels); if ((demux_stipulated_channels == 2) && (frameInfo.channels == 1)) { int ii, jj; unsigned short *inbuf, *outbuf; inbuf = (unsigned short *)*p_outbuf; outbuf = (unsigned short *)*p_outbuf; *out_size = frameInfo.samples << 2; if ((frameInfo.samples > 0) && (outbuf != NULL)) { for (jj = 2 * (frameInfo.samples-1), ii = frameInfo.samples-1; ii >= 0; ii--, jj -= 2) { outbuf[jj ] = inbuf[ii]; outbuf[jj+1] = inbuf[ii]; } } } else if ((demux_stipulated_channels == 1) && (frameInfo.channels == 2)) { int ii, jj, sum; short *inbuf, *outbuf; inbuf = (unsigned short *)*p_outbuf; outbuf = (unsigned short *)*p_outbuf; *out_size = frameInfo.samples; if ((frameInfo.samples > 0) && (outbuf != NULL)) { for (jj = (frameInfo.samples-1) / 2, ii = frameInfo.samples-1; ii >= 0; jj--, ii -= 2) { sum = inbuf[ii] + inbuf[ii + 1]; outbuf[jj] = sum >> 1; } } } else /* not right, but what else can we do? */ { INIT_PRINTF((M_TEXT("demux wants %d channels, not %d\n"), demux_stipulated_channels, frameInfo.channels)); ci->channels = frameInfo.channels; *out_size = frameInfo.samples << 1; } } else { ci->channels = frameInfo.channels; *out_size = frameInfo.samples << 1; } if (*p_outbuf == NULL) { *out_size = 0; DPRINTF((M_TEXT("aacdecode *p_outbuf %p\n"), *p_outbuf)); } #ifndef SBR_DEC #if defined(UNDER_CE) else if (demux_stipulated_channels == 1) { if (non_SBR_upsample == 2) { int ii, jj, size = *out_size >> 1; unsigned short *inbuf, *outbuf; inbuf = (unsigned short *)*p_outbuf; outbuf = (unsigned short *)*p_outbuf; if ((frameInfo.samples > 0) && (outbuf != NULL)) { for (jj = 2 * (size-1), ii = size-1; ii >= 0; ii--, jj -= 2) { outbuf[jj ] = inbuf[ii]; outbuf[jj+1] = inbuf[ii]; } } *out_size <<= 1; ci->sampling_rate = frameInfo.samplerate * non_SBR_upsample; } else if (non_SBR_upsample == 4) { int ii, jj, size = *out_size >> 1; unsigned short *inbuf, *outbuf; inbuf = (unsigned short *)*p_outbuf; outbuf = (unsigned short *)*p_outbuf; if ((frameInfo.samples > 0) && (outbuf != NULL)) { for (jj = 4 * (size-1), ii = size-1; ii >= 0; ii--, jj -= 4) { outbuf[jj ] = inbuf[ii]; outbuf[jj+1] = inbuf[ii]; outbuf[jj+2] = inbuf[ii]; outbuf[jj+3] = inbuf[ii]; } } *out_size <<= 2; ci->sampling_rate = frameInfo.samplerate * non_SBR_upsample; } else if (non_SBR_upsample > 0) /* not right, FIXIT */ { INIT_PRINTF((M_TEXT("demux wants sampling rate change %xx\n"), non_SBR_upsample)); } } else if (demux_stipulated_channels == 2) /* stereo */ { if (non_SBR_upsample == 2) { int ii, jj, size = *out_size >> 1; unsigned short *inbuf, *outbuf; inbuf = (unsigned short *)*p_outbuf; outbuf = (unsigned short *)*p_outbuf; if ((frameInfo.samples > 0) && (outbuf != NULL)) { for (jj = 2 * (size-2), ii = size-2; ii >= 0; ii -= 2, jj -= 4) { outbuf[jj ] = inbuf[ii]; outbuf[jj+2] = inbuf[ii]; outbuf[jj+1] = inbuf[ii+1]; outbuf[jj+3] = inbuf[ii+1]; } } *out_size <<= 1; ci->sampling_rate = frameInfo.samplerate * non_SBR_upsample; } else if (non_SBR_upsample == 4) { int ii, jj, size = *out_size >> 1; unsigned short *inbuf, *outbuf; short *soutbuf; inbuf = (unsigned short *)*p_outbuf; outbuf = (unsigned short *)*p_outbuf; soutbuf = (signed short *)*p_outbuf; if ((frameInfo.samples > 0) && (outbuf != NULL)) { for (jj = 4 * (size-2), ii = size-2; ii >= 0; ii -= 2, jj -= 8) { outbuf[jj ] = inbuf[ii]; outbuf[jj+2] = inbuf[ii]; outbuf[jj+4] = inbuf[ii]; outbuf[jj+6] = inbuf[ii]; outbuf[jj+1] = inbuf[ii+1]; outbuf[jj+3] = inbuf[ii+1]; outbuf[jj+5] = inbuf[ii+1]; outbuf[jj+7] = inbuf[ii+1]; } /* very inexpensive 2-tap anti-aliasing filter */ non_SBR_ups_save[3] = soutbuf[(4*size)-1]; non_SBR_ups_save[2] = soutbuf[(4*size)-2]; for (jj = 1; jj < 3; jj += 2) { soutbuf[jj ] = (non_SBR_ups_save[1] + ((int)(soutbuf[jj ]))) >> 1; soutbuf[jj-1] = (non_SBR_ups_save[0] + ((int)(soutbuf[jj-1]))) >> 1; } non_SBR_ups_save[1] = non_SBR_ups_save[3]; non_SBR_ups_save[0] = non_SBR_ups_save[2]; for (jj = 3; jj < (4*size); jj += 2) { outbuf[jj ] = ((int)(soutbuf[jj-2]) + (int)(soutbuf[jj ])) >> 1; outbuf[jj-1] = ((int)(soutbuf[jj-3]) + (int)(soutbuf[jj-1])) >> 1; } } *out_size <<= 2; ci->sampling_rate = frameInfo.samplerate * non_SBR_upsample; } else if (non_SBR_upsample > 0) /* not right, FIXIT */ { INIT_PRINTF((M_TEXT("demux wants unsupported sampling rate change %xx\n"), non_SBR_upsample)); } } #endif #endif else if (frameInfo.channels > 2) /* do multichannel downmix with AAC rules */ { if (*out_size > 0) { undownmixed_number_of_channels = frameInfo.channels; if (downmix_buffer == NULL) open_downmix(*out_size, 2); if (downmix_buffer != NULL) *p_outbuf = (char *)downmix_to_stereo((short *)*p_outbuf, out_size); } ci->channels = 2; } frame_number++; return bytes_read;}void init_aac(void){ gobble_amount = 0; mp4file = 0; frame_number = 0; INIT_PRINTF((M_TEXT("int_aac: enter saved sr %d, ch %d\n"), save_samplerate, save_channels)); if (save_samplerate == 0) { frameInfo.samplerate = 44100; save_samplerate = frameInfo.samplerate; } else frameInfo.samplerate = save_samplerate; if (save_channels == 0) { frameInfo.channels = 2; save_channels = frameInfo.channels; } else frameInfo.channels = save_channels; sampleId = 0; #ifndef SBR_DEC non_SBR_upsample = 0; #endif}void close_aac(void){ save_samplerate = frameInfo.samplerate; save_channels = frameInfo.channels; INIT_PRINTF((M_TEXT("close_aac: enter sr %d, ch %d\n"), save_samplerate, save_channels)); faacDecClose(hDecoder); hDecoder = NULL; mp4file = 0; #ifndef SBR_DEC non_SBR_upsample = 0; #endif close_downmix();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -