/* * Decode task call for FAAC */ static int aac_decode (codec_data_t *ptr, frame_timestamp_t *ts, int from_rtp, int *sync_frame, uint8_t *buffer, uint32_t buflen, void *userdata) { aac_codec_t *aac = (aac_codec_t *)ptr; unsigned long bytes_consummed; int bits = -1; // struct timezone tz; uint32_t freq_timestamp; freq_timestamp = ts->audio_freq_timestamp; if (ts->audio_freq != aac->m_freq) { freq_timestamp = convert_timescale(freq_timestamp, ts->audio_freq, aac->m_freq); } if (aac->m_record_sync_time) { aac->m_current_frame = 0; aac->m_record_sync_time = 0; aac->m_current_time = ts->msec_timestamp; aac->m_last_rtp_ts = ts->msec_timestamp; } else { if (aac->m_last_rtp_ts == ts->msec_timestamp) { aac->m_current_frame++; aac->m_current_time = aac->m_last_rtp_ts; aac->m_current_time += aac->m_output_frame_size * aac->m_current_frame * TO_U64(1000) / aac->m_freq; freq_timestamp += aac->m_output_frame_size * aac->m_current_frame; } else { aac->m_last_rtp_ts = ts->msec_timestamp; aac->m_current_time = ts->msec_timestamp; aac->m_current_frame = 0; } // Note - here m_current_time should pretty much always be >= rtpts. // If we're not, we most likely want to stop and resync. We don't // need to keep decoding - just decode this frame and indicate we // need a resync... That should handle fast forwards... We need // someway to handle reverses - perhaps if we're more than .5 seconds // later... } if (aac->m_faad_inited == 0) { /* * If not initialized, do so. */ unsigned long freq, chans; faacDecInit(aac->m_info, (unsigned char *)buffer, &freq, &chans); aac->m_freq = freq; aac->m_chans = chans; aac->m_faad_inited = 1; } uint8_t *buff; /* * Get an audio buffer */ if (aac->m_audio_inited == 0) { buff = aac->m_temp_buff; } else { buff = aac->m_vft->audio_get_buffer(aac->m_ifptr, freq_timestamp, aac->m_current_time); } if (buff == NULL) { //player_debug_message("Can't get buffer in aa"); return (0); } unsigned long samples; bytes_consummed = buflen; //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8); bits = faacDecDecode(aac->m_info, (unsigned char *)buffer, &bytes_consummed, (short *)buff, &samples); switch (bits) { case FAAD_OK_CHUPDATE: if (aac->m_audio_inited != 0) { int tempchans = faacDecGetProgConfig(aac->m_info, NULL); if (tempchans != aac->m_chans) { aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d", tempchans); } } // fall through... case FAAD_OK: if (aac->m_audio_inited == 0) { int tempchans = faacDecGetProgConfig(aac->m_info, NULL); if (tempchans == 0) { aac->m_resync_with_header = 1; aac->m_record_sync_time = 1; return bytes_consummed; } if (tempchans != aac->m_chans) { aa_message(LOG_NOTICE, aaclib, "chans from data is %d conf %d", tempchans, aac->m_chans); aac->m_chans = tempchans; } aac->m_vft->audio_configure(aac->m_ifptr, aac->m_freq, aac->m_chans, AUDIO_FMT_S16, aac->m_output_frame_size); uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr, freq_timestamp, aac->m_current_time); if (now != NULL) { memcpy(now, buff, tempchans * aac->m_output_frame_size * sizeof(int16_t)); } aac->m_audio_inited = 1; } /* * good result - give it to audio sync class */ #if DUMP_OUTPUT_TO_FILE fwrite(buff, aac->m_output_frame_size * 4, 1, aac->m_outfile); #endif aac->m_vft->audio_filled_buffer(aac->m_ifptr); if (aac->m_resync_with_header == 1) { aac->m_resync_with_header = 0; #ifdef DEBUG_SYNC aa_message(LOG_DEBUG, aaclib, "Back to good at "U64, aac->m_current_time); #endif } break; default: aa_message(LOG_ERR, aaclib, "Bits return is %d", bits); aac->m_resync_with_header = 1; #ifdef DEBUG_SYNC aa_message(LOG_ERR, aaclib, "Audio decode problem - at "U64, aac->m_current_time); #endif break; } return (bytes_consummed); }
/* * Decode task call for CELP */ static int celp_decode (codec_data_t *ptr, frame_timestamp_t *pts, int from_rtp, int *sync_frame, uint8_t *buffer, uint32_t buflen, void *userdata) { int usedNumBit; celp_codec_t *celp = (celp_codec_t *)ptr; uint32_t freq_ts; freq_ts = pts->audio_freq_timestamp; if (pts->audio_freq != celp->m_freq) { freq_ts = convert_timescale(freq_ts, pts->audio_freq, celp->m_freq); } if (celp->m_record_sync_time) { celp->m_current_frame = 0; celp->m_record_sync_time = 0; celp->m_current_time = pts->msec_timestamp; celp->m_last_rtp_ts = freq_ts; celp->m_current_freq_time = freq_ts; } else { if (celp->m_last_rtp_ts == pts->audio_freq_timestamp) { celp->m_current_frame++; celp->m_current_time = celp->m_last_rtp_ts; celp->m_current_time += celp->m_samples_per_frame * celp->m_current_frame * TO_U64(1000) / celp->m_freq; celp->m_current_freq_time += celp->m_samples_per_frame; } else { celp->m_last_rtp_ts = celp->m_current_freq_time = freq_ts; celp->m_current_time = pts->msec_timestamp; celp->m_current_frame = 0; } // Note - here m_current_time should pretty much always be >= rtpts. // If we're not, we most likely want to stop and resync. We don't // need to keep decoding - just decode this frame and indicate we // need a resync... That should handle fast forwards... We need // someway to handle reverses - perhaps if we're more than .5 seconds // later... } if (celp->m_celp_inited == 0) { /* * If not initialized, do so. */ // celp->m_celp_inited = 1; } //printf("buflen:%d\n",buflen); //if ( ((celp->m_last-buflen)/celp->m_last) < 0.2) return (0); if ( buflen<5) return (-1); BsBitBuffer local; local.data= (unsigned char *)buffer; local.numBit=buflen*8; local.size=buflen*8; DecLpcFrame(&local,celp->m_sampleBuf,&usedNumBit); //AudioWriteData(celp->audiFile,celp->m_sampleBuf,celp->m_output_frame_size); int chan,sample; uint8_t *now = celp->m_vft->audio_get_buffer(celp->m_ifptr, celp->m_current_freq_time, celp->m_current_time); if (now != NULL) { uint16_t *buf = (uint16_t *)now; for(chan=0;chan<celp->m_chans;chan++){ for(sample=0;sample < celp->m_output_frame_size; sample++){ buf[sample +(chan*celp->m_output_frame_size)]= (uint16_t)celp->m_sampleBuf[chan][sample]; } } } #if DUMP_OUTPUT_TO_FILE fwrite(buff, celp->m_output_frame_size * 4, 1, celp->m_outfile); #endif celp->m_vft->audio_filled_buffer(celp->m_ifptr); return bit2byte(usedNumBit); }