int processAudioMsg(AudioMsgQueuePtr pMsgQ, AudioMsgQueuePtr pStatusQ) { AudioMsgPtr pMsg = pMsgQ->pop(false); if (pMsg) { switch (pMsg->getType()) { case AudioMsg::AUDIO: { AudioBufferPtr pBuffer = pMsg->getAudioBuffer(); AudioMsgPtr pStatusMsg(new AudioMsg); pStatusMsg->setAudioTime(pMsg->getAudioTime()); pStatusQ->push(AudioMsgPtr(pStatusMsg)); return pBuffer->getNumFrames(); } case AudioMsg::SEEK_DONE: { AudioMsgPtr pStatusMsg(new AudioMsg); pStatusMsg->setSeekDone(pMsg->getSeekSeqNum(), pMsg->getSeekTime()); pStatusQ->push(AudioMsgPtr(pStatusMsg)); return -1; } default: pStatusQ->push(pMsg); return 0; } } else { return 0; } }
void AudioEngine::addBuffers(float *pDest, AudioBufferPtr pSrc) { int numFrames = pSrc->getNumFrames(); short * pData = pSrc->getData(); for(int i = 0; i < numFrames*getChannels(); ++i) { pDest[i] += pData[i]/32768.0f; } }
bool CacheReader::decode() { AC_TRACE << "CacheReader::decode(" << _myCurFrame << " of " << _myCacheItem->getNumFrames() << "frames )"; if (_myCurFrame == _myCacheItem->getNumFrames()) { return true; } AudioBufferPtr myBuffer = _myCacheItem->getBuffer(_myCurFrame); _myCurFrame += myBuffer->getNumFrames(); _mySampleSink->queueSamples(myBuffer); return (_myCurFrame == _myCacheItem->getNumFrames()); }
void AudioDecoderThread::decodePacket(AVPacket* pPacket) { char* pDecodedData = 0; AVPacket* pTempPacket = new AVPacket; av_init_packet(pTempPacket); pTempPacket->data = pPacket->data; pTempPacket->size = pPacket->size; AVFrame* pDecodedFrame; pDecodedFrame = avcodec_alloc_frame(); while (pTempPacket->size > 0) { int gotFrame = 0; int bytesDecoded; int bytesConsumed = avcodec_decode_audio4(m_pStream->codec, pDecodedFrame, &gotFrame, pTempPacket); if (gotFrame) { bytesDecoded = av_samples_get_buffer_size(0, m_pStream->codec->channels, pDecodedFrame->nb_samples, m_pStream->codec->sample_fmt, 1); pDecodedData = (char*)(pDecodedFrame->data[0]); } else { bytesDecoded = 0; } // This is triggered for some strange/broken videos. // AVG_ASSERT(bytesConsumed != 0); if (bytesConsumed < 0) { // Error decoding -> throw away current packet. bytesDecoded = 0; pTempPacket->size = 0; } else { pTempPacket->data += bytesConsumed; pTempPacket->size -= bytesConsumed; } if (bytesDecoded > 0) { int framesDecoded = bytesDecoded/(m_pStream->codec->channels* getBytesPerSample(m_InputSampleFormat)); AudioBufferPtr pBuffer; bool bNeedsResample = (m_InputSampleRate != m_AP.m_SampleRate || m_InputSampleFormat != AV_SAMPLE_FMT_S16 || m_pStream->codec->channels != m_AP.m_Channels); bool bIsPlanar = false; #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 27, 0) bIsPlanar = av_sample_fmt_is_planar((AVSampleFormat)m_InputSampleFormat); if (bIsPlanar) { char* pPackedData = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); planarToInterleaved(pPackedData, pDecodedFrame, m_pStream->codec->channels, framesDecoded); pBuffer = resampleAudio(pPackedData, framesDecoded, av_get_packed_sample_fmt((AVSampleFormat)m_InputSampleFormat)); av_free(pPackedData); bNeedsResample = false; } #endif if (bNeedsResample) { pBuffer = resampleAudio(pDecodedData, framesDecoded, m_InputSampleFormat); } else if (!bIsPlanar) { pBuffer = AudioBufferPtr(new AudioBuffer(framesDecoded, m_AP)); memcpy(pBuffer->getData(), pDecodedData, bytesDecoded); } m_LastFrameTime += float(pBuffer->getNumFrames())/m_AP.m_SampleRate; pushAudioMsg(pBuffer, m_LastFrameTime); } } #if LIBAVCODEC_VERSION_MAJOR > 53 avcodec_free_frame(&pDecodedFrame); delete pDecodedFrame; #endif delete pTempPacket; }