int DecoderAudio::stop() { CHECK_POINTER_INT(mQueue, -1); mQueue -> abort(); CHECK_POINTER_INT(mLoopThread, -1); LOGE("waiting on end of mLoopThread thread"); mLoopThread -> quit(); return RET_SCCESS; }
// state machine operation int DecoderAudio::start() { CHECK_POINTER_INT(mLoopThread, -1); mLoopThread -> registerRunnable(this); mLoopThread -> start(); return RET_SCCESS; }
int drvSysTick_getUptime(struct timeval* uptime) { unsigned int sysTickValue; // System Tick counter counts down! CHECK_STARTED_INT(&sInstDscr, 0); CHECK_POINTER_INT(uptime); /* Note that SysTick->VAL counts down and rolls over to SysTick->LOAD * when reaching 0 even if interrupts are disabled. * Therefore, if SysTick->VAL rolls over while reading out uptime, * try again. Could use outdated uptime otherwise. */ do { SysTick->CTRL &= ~SysTick_CTRL_COUNTFLAG_Msk; DISABLE_INTERRUPTS(); sysTickValue = SysTick->VAL; *uptime = sInstDscr.uptime; ENABLE_INTERRUPTS(); } while (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk); sysTickValue = SysTick->LOAD - sysTickValue; /* Initial code, when uptime was of type unsigned long long: * *uptime += (unsigned long long)sysTickValue * 1000000 / SystemCoreClock; * However, this invokes the function __aeabi_uldivmod() for the 64bit * integer division. Takes quite long. With a simple trick (divide * numerator and divisor by 1000) the division can be kept in the integer * range. That causes the compiler to use the UDIV instruction, which is * much faster executed than the __aeabi_uldivmod() function. */ uptime->tv_usec += sysTickValue * 1000UL / (SystemCoreClock / 1000UL); uptime->tv_sec += uptime->tv_usec / 1000000UL; uptime->tv_usec %= 1000000UL; return R_SUCCESS; }
int drvSysTick_getPeriod(unsigned int* period_us) { CHECK_STARTED_INT(&sInstDscr, 0); CHECK_POINTER_INT(period_us); *period_us = sInstDscr.period_us; return R_SUCCESS; }
int drvSysTick_getMissed(unsigned long long* missed) { CHECK_STARTED_INT(&sInstDscr, 0); CHECK_POINTER_INT(missed); *missed = sInstDscr.missed; return R_SUCCESS; }
int DecoderAudio::pause() { CHECK_POINTER_INT(mLoopThread, -1); mLoopThread->stop(); return 0; }
int DecoderAudio::decodeRender() { /* * Process some special Events * 1) BOS * 2) EOS */ AVPacket pkt; av_init_packet(&pkt); CHECK_POINTER_INT(mQueue, -1); LOGD("AudioQueue get start()"); if (mQueue -> get(&pkt, true) != PacketQueue::PQ_OP_SUCCESS) { LOGE("getAudio Packet error, thread exit!"); return -1; } LOGD("AudioQueue get end()"); if (&BOS_PKT == &pkt) { LOGI("Audio Decoder Received BOS PKT!"); /* update our clock */ pkt.pts; return 0; } else if (&EOS_PKT == &pkt) { LOGI("Audio Decoder Received EOS PKT!"); return 0; } if (pkt.pts != AV_NOPTS_VALUE) { mAudioClock = av_q2d(mStream -> time_base) * pkt.pts; } LOGD("after adjust 1 mAudioClock:%f!", mAudioClock); AVCodecContext * dec = mStream -> codec; CHECK_POINTER_INT(dec, -1); int remainBufSize = mSamplesSize, curOutputBufSize = mSamplesSize; int dataSize = 0; int16_t * outputBuf = mSamples; AVPacket dupPkt = pkt; while ((dupPkt.size > 0) && ((curOutputBufSize = remainBufSize) > 0)) { LOGD("Before avcodec_decode_audio3()"); int len = avcodec_decode_audio3(mStream -> codec, (int16_t *) outputBuf, &curOutputBufSize, &pkt); LOGD("after avcodec_decode_audio3() len:%d, curOutputBufSize:%d", len, curOutputBufSize); if ((len < 0) || (!curOutputBufSize)) { dupPkt.size = 0; break; } LOGD("After avcodec_decode_audio3()"); dupPkt.data += len; dupPkt.size -= len; remainBufSize -= curOutputBufSize; outputBuf += curOutputBufSize / (sizeof(int16_t)); dataSize += curOutputBufSize; LOGD("Audio Decoder Thread Processing"); } LOGD("Jump out of while loop"); double bytesPerSec = dec -> channels * bytesPerSample(dec -> sample_fmt) * dec -> sample_rate; mAudioClock += (double) dataSize / (double) (bytesPerSec); LOGD("after adjust 2 mAudioClock:%f, mLastClock:%f!", mAudioClock, mLastClock); // TODO: // update the delay time mTimer = (mAudioClock - mLastClock); // call handler for posting buffer to os audio driver LOGD("Before rendorHook() mTimer:%f", mTimer); rendorHook(mSamples, dataSize); long delta = now() - mLastAbsTime; LOGD("delta:%lld, mLastAbsTime:%lld, now():%lld", delta, mLastAbsTime, now()); mLastAbsTime = now(); usleep(mTimer * 1e6); mLastClock = mAudioClock; CHECK_POINTER_INT(mBuddy, -1); BuddyEvent evt; evt.type = AV_SYNC; evt.data.dData = mAudioClock; LOGD("Ready to call mBuddy's onBuddyEvent()"); mBuddy-> onBuddyEvent(this, evt); av_free_packet(&pkt); LOGD("Ready to call av_free_packet() called!"); return 0; }