void static audioThreadEntryPoint(void* udata, uint8_t* stream, int len) { sdlargst* args = (sdlargst*)udata; DSPManager* dspman = static_cast<DSPManager*>(args->dspman); AVCodecContext* codecCtx = (AVCodecContext*)args->avcodeccontext; packetQueue* queue = args->queue; static uint8_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; static unsigned int bufLength = 0; static unsigned int bufCurrentIndex = 0; uint8_t* streamIndex = stream; int samplesLeft = len; while(samplesLeft > 0) { if(bufCurrentIndex >= bufLength) { // No more data in the buffer, get some more. int decodeSize = decodeFrame(codecCtx, buf, sizeof(buf), queue); if(decodeSize < 0) { // something went wrong... silence. bufCurrentIndex = AVCODEC_MAX_AUDIO_FRAME_SIZE; memset(buf, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE); } else { bufLength = decodeSize; } //Reset the index for the new data. bufCurrentIndex = 0; } int numberOfSamples = bufLength - bufCurrentIndex; if(numberOfSamples > samplesLeft) numberOfSamples = samplesLeft; memcpy(streamIndex, (uint8_t*)buf + bufCurrentIndex, numberOfSamples); samplesLeft -= numberOfSamples; streamIndex += numberOfSamples; bufCurrentIndex += numberOfSamples; } dspman->processAudioPCM(NULL, stream, len); if(dspman->cbuf == NULL) dspman->cbuf = new circularBuffer::circularBuffer(CIRCBUFSIZE, sizeof(uint8_t) * len); memcpy(dspman->cbuf->add(), stream, sizeof(uint8_t) * len); memcpy(stream, dspman->cbuf->pop(), sizeof(uint8_t) * len); }
void static audioThreadEntryPoint(void* udata, uint8_t* stream, int len) { sdlargst* args = (sdlargst*)udata; DSPManager* dspman = static_cast<DSPManager*>(args->dspman); AVCodecContext* codecCtx = (AVCodecContext*)args->avcodeccontext; packetQueue* queue = args->queue; SwrContext *swr; static uint8_t *buf = NULL; static unsigned int bufLength = 0; static unsigned int bufCurrentIndex = 0; uint8_t* streamIndex = stream; // Setup the resample context to ensure out samples are in the // format that SDL expectes them to be. swr = swr_alloc(); av_opt_set_int(swr, "in_channel_layout", codecCtx->channel_layout, 0); av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(swr, "in_sample_rate", codecCtx->sample_rate, 0); av_opt_set_int(swr, "out_sample_rate", codecCtx->sample_rate, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", codecCtx->sample_fmt, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); swr_init(swr); int samplesLeft = len; while(samplesLeft > 0) { if(bufCurrentIndex >= bufLength) { retry_decode: // No more data in the buffer, get some // more. Ensure we free the old buffer that we // allocated in the previous decodeFrame call. if (buf) free(buf); int decodeSize = decodeFrame(codecCtx, &buf, sizeof(buf), queue, swr); if(decodeSize < 0) { // something went wrong... try again. goto retry_decode; } else { bufLength = decodeSize; } //Reset the index for the new data. bufCurrentIndex = 0; } int numberOfSamples = bufLength - bufCurrentIndex; if(numberOfSamples > samplesLeft) numberOfSamples = samplesLeft; memcpy(streamIndex, (uint8_t*)buf + bufCurrentIndex, numberOfSamples); samplesLeft -= numberOfSamples; streamIndex += numberOfSamples; bufCurrentIndex += numberOfSamples; } dspman->processAudioPCM(NULL, stream, len); if(dspman->cbuf == NULL) dspman->cbuf = new circularBuffer::circularBuffer(CIRCBUFSIZE, sizeof(uint8_t) * len); memcpy(dspman->cbuf->add(), stream, sizeof(uint8_t) * len); memcpy(stream, dspman->cbuf->pop(), sizeof(uint8_t) * len); swr_free(&swr); }