Beispiel #1
0
 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;
 }
Beispiel #2
0
 // state machine operation
 int DecoderAudio::start()
 {
     CHECK_POINTER_INT(mLoopThread, -1);
     mLoopThread -> registerRunnable(this);
     mLoopThread -> start();
     return RET_SCCESS;
 }
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
int drvSysTick_getMissed(unsigned long long* missed)
{
    CHECK_STARTED_INT(&sInstDscr, 0);
    CHECK_POINTER_INT(missed);

    *missed = sInstDscr.missed;
    return R_SUCCESS;
}
Beispiel #6
0
 int DecoderAudio::pause()
 {
     CHECK_POINTER_INT(mLoopThread, -1);
     mLoopThread->stop();
     return 0;
 }
Beispiel #7
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;
    }