コード例 #1
0
HeadSetDetect::~HeadSetDetect()
{
    SXLOGV("+deconstruct");
    stop();
    requestExitAndWait();
    SXLOGV("-deconstruct");
}
コード例 #2
0
int32_t AudioVUnlockDL:: DoSRC(uint8_t *inbuf, uint32_t *datasz , uint8_t *outbuf, uint32_t *outlength)
{
    uint8_t *inPtr = inbuf ;
    uint8_t *outPtr = outbuf;
    uint32_t outbuflen = *outlength;
    uint32_t dataProduce = 0;
    uint32_t count = 40;
    uint32_t dataconsumed = 0;
    pthread_mutex_lock(&mSRCMutex);
    if (mpSrcHdl == NULL)
    {
        SXLOGD("[DoSRC] SRC not created");
        pthread_mutex_unlock(&mSRCMutex);
        return -1;
    }

    while (count)
    {
        SXLOGV("count %d ,in offset %d, datasz %d, out offset %d, outlength %d ", count,inPtr - inbuf, *datasz,outPtr - outbuf, *outlength);
        int consumed_this_time = *datasz;
        mpSrcHdl->Process((int16_t *)inPtr, datasz, (int16_t *)outPtr, outlength);
        consumed_this_time -= *datasz;

        dataconsumed += consumed_this_time;
        SXLOGV("after count %d , datasz %d,  outlength%d ", count,  *datasz,*outlength);
        dataProduce += *outlength;
        if (*datasz == 0 || *outlength == 0)
        {
            break;
        }
        else
        {
            inPtr = inbuf + dataconsumed;
            outPtr = outbuf + dataProduce;
        }
        // left space in output buffer
        *outlength = outbuflen - dataProduce;
        if (*outlength == 0)
        {
            break;
        }
        count --;
    }

    pthread_mutex_unlock(&mSRCMutex);
    /*if(count == 0 && *datasz !=0 && *outlength != 0)
    {
        SXLOGD("[DoSRC] do not finish SRC *datasz %d, &outlength %d", *datasz,*outlength );
        //return -1;
    }*/
    *outlength = dataProduce;
    return dataconsumed;
}
コード例 #3
0
bool  HeadSetDetect::headsetConnect(int stateVal)
{
     if(WIRE_HEADSET==stateVal){
        SXLOGV("detect headset pluged in");
        return true;
    }else if(BIT_HEADSET_NO_MIC==stateVal) {
        SXLOGV("detect headphone pluged in");
        return true;
    }else{
        SXLOGV("default headset pluged out");
        return false;
    }
}
コード例 #4
0
status_t AudioTrackCenter::reset_flush(intptr_t trackId) {
	Mutex::Autolock autoLock(mLock);

	SXLOGV("%s, trackId:%p",__FUNCTION__, (void*)trackId);

	ssize_t index = mTrackList.indexOfKey(trackId);
	if (index < 0) {
    	return UNKNOWN_ERROR;
	}

    struct TrackInfo &info = mTrackList.editValueFor(trackId);

    info.server = 0;
    info.middleServer = 0;
    info.ts = ALooper::GetNowUs();
    info.framePlayed = 0;

#ifdef AUDIO_TRACK_CENTER_DEBUG	 
    mSysTimeUs = 0;
    mRealTimeUs = 0;
    mDeltaUs = 0;
#endif

	return OK;
}
コード例 #5
0
void HeadSetDetect::stop()
{
    SXLOGV("HeadSetDetect::stop");

    Mutex::Autolock _l(mLock);
    mActive = false;
    requestExit();
}
コード例 #6
0
status_t MyVorbisExtractor::findNextPage(
        off64_t startOffset, off64_t *pageOffset) {
    *pageOffset = startOffset;
    
#ifdef MTK_AOSP_ENHANCEMENT  
    //optimize find page process   
    char signature[2048];

    for (;;) {
      ssize_t n = mSource->readAt(*pageOffset, &signature, 2000);

        if (n < 4) {
            *pageOffset = 0;

            return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM;
        }
        int i = 0;
        int step = n-4;
        while(i<=step)
        {
            if (!memcmp(&signature[i], "OggS", 4)) {
                if ((*pageOffset + i) > startOffset) {
                    SXLOGV("skipped %lld bytes of junk to reach next frame",
                         (*pageOffset + i) - startOffset);
                }
                *pageOffset += i;
                return OK;
            }
            
            i++;
         }
        *pageOffset += n;
      
    }
#else
    for (;;) {
        char signature[4];
        ssize_t n = mSource->readAt(*pageOffset, &signature, 4);

        if (n < 4) {
            *pageOffset = 0;

            return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM;
        }

        if (!memcmp(signature, "OggS", 4)) {
            if (*pageOffset > startOffset) {
                ALOGV("skipped %lld bytes of junk to reach next frame",
                     *pageOffset - startOffset);
            }

            return OK;
        }

        ++*pageOffset;
    }
#endif                                                            
}
コード例 #7
0
intptr_t AudioTrackCenter::getTrackId(void* trackPtr, void* sinkPtr) {
	Mutex::Autolock autoLock(mLock);
    #if defined(CONFIG_MT_ENG_BUILD) 
    SXLOGV("%s, trackPtr:%p, sinkPtr:%p",__FUNCTION__, trackPtr, sinkPtr);	
    #endif
	List<TrackMaps>::iterator it = mTrackMaps.begin();
    while (it != mTrackMaps.end()) {
		if ((trackPtr && it->trackPtr == trackPtr) || (sinkPtr && it->sinkPtr == sinkPtr)) {
            SXLOGV("%s, return trackId:%p",__FUNCTION__, (void*)it->trackId);
			return it->trackId;
		}
        ++it;
    }
    #if defined(CONFIG_MT_ENG_BUILD) 
    SXLOGV("%s, no valid trackId!!",__FUNCTION__);
    #endif
	return 0;
}
コード例 #8
0
status_t AudioTrackCenter::getRealTimePosition(intptr_t trackId, int64_t *position) {
    Mutex::Autolock autoLock(mLock);

        #if defined(CONFIG_MT_ENG_BUILD) 
	SXLOGV("%s, trackId:%p",__FUNCTION__, (void*)trackId);
        #endif
    ssize_t index = mTrackList.indexOfKey(trackId);
	if (index < 0) {
    	return UNKNOWN_ERROR;
	}
	
	const struct TrackInfo info = mTrackList.valueFor(trackId);
	int64_t delayUs = ALooper::GetNowUs() - info.ts;
	delayUs = delayUs/mTimeScaled;

	*position = info.framePlayed;
	
	if (!info.framePlayed) {
	    SXLOGV("trackId = %p, server = %d, framePlayed = %lld", (void*)trackId, info.server, info.framePlayed);
	    return OK;
	}

	if (info.server) {
		uint32_t deltaFrames = (uint32_t)((delayUs*info.sampleRate)/1000000);
		if (deltaFrames > info.frameCount) {
			deltaFrames = info.frameCount;
		}
        
        if (!info.active) {
            SXLOGV("%s, trackId = %p, track is not active , set deltaFrames to 0",__FUNCTION__, (void*)trackId);
            deltaFrames = 0;
        }
		*position += deltaFrames;
	}
	
#ifdef AUDIO_TRACK_CENTER_DEBUG	 
	SXLOGD("trackId = %p, realTimeUs and sysTimeUs distance: %8.3f", (void*)trackId, countDeltaUs(((int64_t)(*position)*1000000)/info.sampleRate));
#endif
        #if defined(CONFIG_MT_ENG_BUILD) 
	SXLOGV("trackId = %p, server = %d, framePlayed = %lld, delayUs = %lld, *position:%lld", (void*)trackId, info.server, info.framePlayed, delayUs, *position);
	#endif    
    return OK;
}
コード例 #9
0
status_t  DcRemove::close()
{
    Mutex::Autolock _l(&mLock);
    SXLOGV("DcRemove::deinit");
    if (mHandle)
    {
        DCR_Close(mHandle);
        free(mHandle);
        mHandle = NULL;
    }
    return NO_ERROR;
}
コード例 #10
0
status_t AudioTrackCenter::updateServer(intptr_t trackId, uint32_t server, bool restore) {
    Mutex::Autolock autoLock(mLock);
    #if defined(CONFIG_MT_ENG_BUILD) 
	SXLOGV("%s, trackId:%p, server:%d",__FUNCTION__, (void*)trackId, server);
    #endif       
    ssize_t index = mTrackList.indexOfKey(trackId);
	if (index < 0) {
    	return UNKNOWN_ERROR;
	}

    struct TrackInfo &info = mTrackList.editValueFor(trackId);

    if (!info.active) {
        SXLOGV("%s, trackId:%p, active = %d",__FUNCTION__, (void*)trackId, info.active);
        return OK;
    }    
	
    uint32_t s;
    s = (server > info.server) ? (server - info.server) : 0;
	
    if (s && info.middleServer && s < info.afFrameCount) {
		info.middleServer  = server;
        return OK;
    }
	
    if (!restore && info.server) {
	    info.framePlayed = info.framePlayed + s;
        info.ts = ALooper::GetNowUs();
    }

    info.server = server;
	
	SXLOGV("trackId:%p, info.server:%d, info.framePlayed:%lld, info.ts:%lld",(void*)trackId, info.server, info.framePlayed, info.ts);
        
    info.middleServer  = server;
    
    return OK;   
}
コード例 #11
0
status_t AudioTrackCenter::setTimeStretch(uint32_t timeScaled) {
    Mutex::Autolock autoLock(mLock);

    SXLOGV("%s, timeScaled:%d",__FUNCTION__, timeScaled);
    
    if (timeScaled != 1 && timeScaled != 2 && timeScaled != 4) {
        return BAD_VALUE;
    }
    
    mTimeScaled = timeScaled;
    
    return OK;
    
    
}
コード例 #12
0
int HeadSetDetect::readStateFromFile()
{
    SXLOGV("readStateFromFile");
    int fd = open(HEADSET_STATE_PATH, O_RDONLY, 0);
    if(fd < 0)
    {
        SXLOGD("Fail to open file %s", HEADSET_STATE_PATH);
        return -1;
    }
    char buf[1];
    if (read(fd, buf, 1) == -1){
        SXLOGD("Can't read %s", HEADSET_STATE_PATH);
        return -1;
    }
    close(fd);
    return buf[0];
}
コード例 #13
0
status_t AudioTrackCenter::setTrackActive(intptr_t trackId, bool active) {
    Mutex::Autolock autoLock(mLock);
    #if defined(CONFIG_MT_ENG_BUILD) 
    SXLOGV("%s, trackId:%p, active:%d",__FUNCTION__, (void*)trackId, active);
   #endif  
    ssize_t index = mTrackList.indexOfKey(trackId);
	if (index < 0) {
    	return UNKNOWN_ERROR;
	}

    struct TrackInfo &info = mTrackList.editValueFor(trackId);

    info.active = active;

    return OK;

}
コード例 #14
0
ファイル: ftm_headset.cpp プロジェクト: WayWingsDev/mediatek
static void *Audio_Record_thread(void *mPtr)
{
    struct headset *hds  = (struct headset *)mPtr;
    ALOGD(TAG "%s: Start", __FUNCTION__);
    usleep(100000);
    bool dumpFlag = read_preferred_recorddump();
    //    bool dumpFlag = true;//for test
    int magLower = 0, magUpper = 0;
    read_preferred_magnitude(&magUpper, &magLower);
    int lowFreq = 1000 * (1 - 0.1); //1k
    int highFreq = 1000 * (1 + 0.1);
    short pbuffer[8192] = {0};
    short pbufferL[4096] = {0};
    short pbufferR[4096] = {0};
    unsigned int freqDataL[3] = {0}, magDataL[3] = {0};
    unsigned int freqDataR[3] = {0}, magDataR[3] = {0};
    int checkCnt = 0;
    uint32_t samplerate = 0;

    // headsetLR: Phone level test; headset: Non-Phone level test.
    return_data.headsetL.freqL = return_data.headsetR.freqL = return_data.headset.freqL = freqDataL[0];
    return_data.headsetL.freqR = return_data.headsetR.freqR = return_data.headset.freqR = freqDataR[0];
    return_data.headsetL.amplL = return_data.headsetR.amplL = return_data.headset.amplL = magDataL[0];
    return_data.headsetL.amplR = return_data.headsetR.amplR = return_data.headset.amplR = magDataR[0];

    recordInit(hds->recordDevice, &samplerate);
    while (1)
    {
        memset(pbuffer, 0, sizeof(pbuffer));
        memset(pbufferL, 0, sizeof(pbufferL));
        memset(pbufferR, 0, sizeof(pbufferR));

        int readSize  = readRecordData(pbuffer, 8192 * 2);
        for (int i = 0 ; i < 4096 ; i++)
        {
            pbufferL[i] = pbuffer[2 * i];
            pbufferR[i] = pbuffer[2 * i + 1];
        }

        if (dumpFlag)
        {
            char filenameL[] = "/data/record_headset_dataL.pcm";
            char filenameR[] = "/data/record_headset_dataR.pcm";
            FILE *fpL = fopen(filenameL, "wb+");
            FILE *fpR = fopen(filenameR, "wb+");

            if (fpL != NULL)
            {
                fwrite(pbufferL, readSize / 2, 1, fpL);
                fclose(fpL);
            }

            if (fpR != NULL)
            {
                fwrite(pbufferR, readSize / 2, 1, fpR);
                fclose(fpR);
            }
        }

        memset(freqDataL, 0, sizeof(freqDataL));
        memset(freqDataR, 0, sizeof(freqDataR));
        memset(magDataL, 0, sizeof(magDataL));
        memset(magDataR, 0, sizeof(magDataR));
        ApplyFFT256(samplerate, pbufferL, 0, freqDataL, magDataL);
        ApplyFFT256(samplerate, pbufferR, 0, freqDataR, magDataR);        
        for (int i = 0; i < 3 ; i ++)
        {
            SXLOGV("%d.freqDataL[%d]:%d,magDataL[%d]:%d", i, i, freqDataL[i], i, magDataL[i]);
            SXLOGV("%d.freqDataR[%d]:%d,magDataR[%d]:%d", i, i, freqDataR[i], i, magDataR[i]);
        }

        if (hds->isPhoneTest)
        {
            if (headset_phonetest_state == 0) // CH1
            {
                //CH1 Log
                return_data.headsetL.freqL = freqDataL[0];
                return_data.headsetL.amplL = magDataL[0];
                return_data.headsetL.freqR = freqDataR[0];
                return_data.headsetL.amplR = magDataR[0];

                if ((freqDataL[0] <= highFreq && freqDataL[0] >= lowFreq) && (magDataL[0] <= magUpper && magDataL[0] >= magLower))
                {
                    checkCnt ++;
                    if (checkCnt >= 5)
                    {
                        ALOGD("[Headset-L] freqDataL:%d,magDataL:%d,freqDataR:%d,magDataR:%d", freqDataL[0], magDataL[0], freqDataR[0], magDataR[0]);
                        checkCnt = 0;
                    }
                }
                else
                {
                    checkCnt = 0;
                }
            }
            else if (headset_phonetest_state == 1) // CH2
            {
                if ((freqDataR[0] <= highFreq && freqDataR[0] >= lowFreq) && (magDataR[0] <= magUpper && magDataR[0] >= magLower))
                {
                    checkCnt ++;
                    if (checkCnt >= 5)
                    {
                        ALOGD("[Headset-R] freqDataL:%d,magDataL:%d,freqDataR:%d,magDataR:%d", freqDataL[0], magDataL[0], freqDataR[0], magDataR[0]);
                        snprintf(hds->info, sizeof(hds->info), "Check freq pass.\n");
                        ALOGD(" @ info : %s", hds->info);
                        break;
                    }
                }
                else
                {
                    checkCnt = 0;
                }
            }
            else
            {
                break;
            }
        }
        else // Non Phone level test
        {
            if (((freqDataL[0] <= highFreq && freqDataL[0] >= lowFreq) && (magDataL[0] <= magUpper && magDataL[0] >= magLower)) && ((freqDataR[0] <= highFreq && freqDataR[0] >= lowFreq) && (magDataR[0] <= magUpper && magDataR[0] >= magLower)))
            {
                checkCnt ++;
                if (checkCnt >= 5)
                {
                    snprintf(hds->info, sizeof(hds->info), "Check freq pass.\n");
                    ALOGD(" @ info : %s", hds->info);
                    break;
                }
            }
            else
            {
                checkCnt = 0;
            }

            if (hds->exit_thd)
            {
                break;
            }
        }
    }

    // Log and ATA Return
    if (hds->isPhoneTest)
    {
        //CH2 Log
        return_data.headsetR.freqL = freqDataL[0];
        return_data.headsetR.freqR = freqDataR[0];
        return_data.headsetR.amplL = magDataL[0];
        return_data.headsetR.amplR = magDataR[0];
        ALOGD(TAG "ATA Return Data[Headset-L]: [Mic1]Freq = %d, Amp = %d, [Mic2]Freq = %d, Amp = %d", return_data.headsetL.freqL, return_data.headsetL.amplL, return_data.headsetL.freqR, return_data.headsetL.amplR);
        ALOGD(TAG "ATA Return Data[Headset-R]: [Mic1]Freq = %d, Amp = %d, [Mic2]Freq = %d, Amp = %d", return_data.headsetR.freqL, return_data.headsetR.amplL, return_data.headsetR.freqR, return_data.headsetR.amplR);
    }
    else
    {
        return_data.headset.freqL = freqDataL[0];
        return_data.headset.freqR = freqDataR[0];
        return_data.headset.amplL = magDataL[0];
        return_data.headset.amplR = magDataR[0];
        ALOGD(TAG "ATA Return Data: FreqL = %d, FreqR = %d, AmpL = %d, AmpR = %d", return_data.headset.freqL, return_data.headset.freqR, return_data.headset.amplL, return_data.headset.amplR);
    }

    ALOGD(TAG "%s: Stop", __FUNCTION__);
    pthread_exit(NULL); // thread exit
    return NULL;
}
コード例 #15
0
//#define WRITEOVER
void *ReadRoutine(void *hdl)
{
    AudioVUnlockRingBuf *ringBuf_in;
    AudioVUnlockRingBuf *ringBuf_out;
    int32_t readAmount;
    int32_t rwfailcount = 0;
    AudioVUnlockDL *VInstance = AudioVUnlockDL::getInstance();
    char *tempbuffer  = new char[VOICE_UNLOCK_RING_BUFFER_SIZE];
    char *tempSRCbuffer = new char[6000];
    uint32_t dataread = 0;
    int32_t datawritten = 0;
    SXLOGD(" [ReadRoutine] start");
    // defaut setting of thread init
    pthread_mutex_lock(&mVUnlockReadMutex);
    VInstance->mReadThreadExit = false;
    VInstance->mReadThreadActive = true;
    pthread_mutex_unlock(&mVUnlockReadMutex);

    ringBuf_in = (AudioVUnlockRingBuf *) & (VInstance->mRingBufIn);
    ringBuf_out = (AudioVUnlockRingBuf *) & (VInstance->mRingBufOut);

    if (VInstance == NULL || ringBuf_in == NULL || ringBuf_out == NULL)
    {
        SXLOGD(" [ReadRoutine] Buffer NULL,  Exit");
        pthread_mutex_lock(&mVUnlockReadMutex);
        VInstance->mReadThreadExit = true;
        VInstance->mReadThreadActive = false;
        pthread_mutex_unlock(&mVUnlockReadMutex);
    }

#ifdef MTK_AUDIO_ADJUST_PRIORITY
    int result = -1;
    // if set priority false , force to set priority
    if (result == -1)
    {
        struct sched_param sched_p;
        sched_getparam(0, &sched_p);
        sched_p.sched_priority = RTPM_PRIO_AUDIO_I2S;
        if (0 != sched_setscheduler(0, SCHED_RR, &sched_p))
        {
            SXLOGE("[%s] failed, errno: %d", __func__, errno);
        }
        else
        {
            sched_p.sched_priority = RTPM_PRIO_AUDIO_I2S;
            sched_getparam(0, &sched_p);
            SXLOGD("sched_setscheduler ok, priority: %d", sched_p.sched_priority);
        }
    }
#endif

    while (!VInstance->mReadThreadExit)
    {
        // Clear DL time if remaining data is pushed.
        if (VInstance->mDLtime.tv_nsec != 0 && VInstance->mNewDLtime.tv_sec  != 0)
        {
            if (VInstance->mInRemaining == 0 && VInstance->mOutRemaining == 0)
            {
                VInstance->mDLtime.tv_sec  = 0;
                VInstance->mDLtime.tv_nsec = 0;
                //SXLOGV("[ReadRoutine] All Data from last playback pushed");
            }
        }
        // switch DL time to new DL time
        if (VInstance->mDLtime.tv_sec == 0 && VInstance->mNewDLtime.tv_sec  != 0)
        {
            VInstance->mDLtime.tv_sec = VInstance->mNewDLtime.tv_sec ;
            VInstance->mDLtime.tv_nsec = VInstance->mNewDLtime.tv_nsec;
            VInstance->mNewDLtime.tv_sec  = 0;
            VInstance->mNewDLtime.tv_nsec = 0;
            SXLOGV("[ReadRoutine] switch to new DL time %d %d", VInstance->mDLtime.tv_sec, VInstance->mDLtime.tv_nsec);
        }

        uint32_t readsz = ringBuf_in->GetBufDataSz();
        dataread = ringBuf_in->ReadWithoutAdvance(tempbuffer, readsz);
        if (VInstance->mInRemaining != 0)
        {
            dataread = dataread > VInstance->mInRemaining ? VInstance->mInRemaining : dataread;
        }
        if (dataread <= 0 || VInstance->mDLtime.tv_sec == 0) // do not read data if mDLtime is ready.
        {
            if (VInstance->StreamOutStandBy() && ringBuf_out->GetBufDataSz() == 0)
            {
                //SXLOGV("[ReadRoutine]  Standby, and all data from last playback is pushed");
                VInstance->mDLtime.tv_sec = 0;
                VInstance->mDLtime.tv_nsec = 0;
            }
            //SXLOGV("[ReadRoutine] No data from stream out, sleep");
            usleep(30 * 1000);
        }
        else
        {
            //do SRC
            uint32_t dataproduced = ringBuf_out->GetBufSpace();
            dataproduced = dataproduced > 6000 ? 6000 : dataproduced;
            int32_t dataConsumed = VInstance->DoSRC((uint8_t *) tempbuffer, &dataread , (uint8_t *) tempSRCbuffer, &dataproduced);

#ifdef DUMP_VPW_StreamIn_DATA
            //VInstance->DumpData(tempSRCbuffer, dataproduced);
            if (VInstance->mOutFile_1 != NULL)
            {
               VInstance->mOutFile_1 = fopen("/sdcard/audio_dump/VPW_SRC.pcm", "ab+");
                fwrite(tempSRCbuffer, sizeof(char), dataproduced, VInstance->mOutFile_1);
                fclose(VInstance->mOutFile_1);
            }
#endif
            if (dataConsumed > 0)
            {
                datawritten = ringBuf_out->Write(tempSRCbuffer, dataproduced);
                SXLOGV("[ReadRoutine] write to ring out, datawritten %d", datawritten);
            }
            else
            {
                datawritten = 0;
            }
            if (datawritten <= 0) //  write fail
            {
                rwfailcount++;
                if (rwfailcount > 100)
                {
                    SXLOGD("[ReadRoutine] Fail, write fail");
                    break;
                }
                SXLOGD("[ReadRoutine] No space to write, sleep");
                usleep(10 * 1000); //10ms
            }
            else//advance read pointer according to data actually write to output buffer
            {
                ringBuf_in->AdvanceReadPointer((uint32_t)dataConsumed);
                if (VInstance->mInRemaining != 0)
                {
                    SXLOGV("[ReadRoutine] last playback in buffer remaining %d", VInstance->mInRemaining);
                    VInstance->mInRemaining -= dataConsumed;
                    VInstance->mOutRemaining +=  datawritten;
                }
                ringBuf_out->SignalBufData();
                SXLOGV("[ReadRoutine] advance Read poniter %d " , (uint32_t)dataConsumed);
                rwfailcount = 0;
            }
        }
    }
    delete tempbuffer;
    delete tempSRCbuffer;
    SXLOGD("[ReadRoutine] exit ");

    VInstance->ClearState(VPWStreamIn_READ_START);

    SXLOGD("stop and signal ReadRefFromRing to stop");
    ringBuf_out->SignalBufData();

    int cnt_val = 50;
    while ((VInstance->mReadFunctionActive == true) && (cnt_val > 0))
    {
        SXLOGD("[ReadRoutine]Signal ReadRefFromRing to stop and wait (%d) ", cnt_val);
        cnt_val--;
        ringBuf_out->SignalBufData();
        usleep(1000 * 10);
    }

    pthread_mutex_lock(&mVUnlockReadMutex);
    VInstance->mReadThreadExit = true;
    VInstance->mReadThreadActive = false;
    pthread_mutex_unlock(&mVUnlockReadMutex);
    return 0;
}
コード例 #16
0
status_t MyVorbisExtractor::seekToTime(int64_t timeUs) {
#ifdef MTK_AOSP_ENHANCEMENT
    if(timeUs == 0)
        return seekToOffset(0);
    if (isCachingDataSource())
    {
        off64_t pos = timeUs * approxBitrate() / 8000000ll;
        SXLOGV("seeking to offset %lld", pos);
        return seekToOffset(pos);
    }
    if (mTableOfContents.isEmpty() || (mTocDone == false)) {
    	  // Perform seekto accurate page.
    	  uint64_t ts1,ts2;
    	  if(findGranulePositionofPage(mFirstDataOffset,&ts1) != OK)
    	  	return seekToOffset(0);
    	  if(findGranulePositionofPage(mFileSize,&ts2) != OK)
    	  	return seekToOffset(0);
    	  SXLOGD("bitrate seek--pos:%lld,ts1:%lld,ts2:%lld",timeUs * mVi.rate /1000000,ts1,ts2);
        off64_t pos = findAccuratePageOffset((uint64_t)(timeUs * mVi.rate /1000000),mFirstDataOffset,mFileSize);
#else
    if (mTableOfContents.isEmpty()) {
        // Perform approximate seeking based on avg. bitrate.

        off64_t pos = timeUs * approxBitrate() / 8000000ll;
#endif
        ALOGV("seeking to offset %lld", pos);
        return seekToOffset(pos);
    }

    size_t left = 0;
    size_t right_plus_one = mTableOfContents.size();
    while (left < right_plus_one) {
        size_t center = left + (right_plus_one - left) / 2;

        const TOCEntry &entry = mTableOfContents.itemAt(center);

        if (timeUs < entry.mTimeUs) {
            right_plus_one = center;
        } else if (timeUs > entry.mTimeUs) {
            left = center + 1;
        } else {
            left = center;
            break;
        }
    }

    if (left == mTableOfContents.size()) {
        --left;
    }
    
#ifndef MTK_AOSP_ENHANCEMENT

    const TOCEntry &entry = mTableOfContents.itemAt(left);

    ALOGV("seeking to entry %zu / %zu at offset %lld",
         left, mTableOfContents.size(), entry.mPageOffset);

    return seekToOffset(entry.mPageOffset);
#else
   if(mTableOfContents.itemAt(mTableOfContents.size()-1).mTimeUs <= timeUs)
   	 return seekToOffset(mTableOfContents.itemAt(mTableOfContents.size()-1).mPageOffset);
    off64_t os = 0,oe = 0;
    for(size_t i = left ; i < mTableOfContents.size() ;i ++)
    {
    	  if(mTableOfContents.itemAt(i).mTimeUs > timeUs)
      	  {
      	  	oe = mTableOfContents.itemAt(i).mPageOffset;
      	  	break;
      	  }
      	else if(mTableOfContents.itemAt(i).mTimeUs == timeUs)
      		return seekToOffset(mTableOfContents.itemAt(left).mPageOffset);
    }
    for(size_t i = left ; (i >= 0) && (i < mTableOfContents.size()) ;i --)
    {
    	  if(mTableOfContents.itemAt(i).mTimeUs < timeUs)
      	  {
      	  	os = mTableOfContents.itemAt(i).mPageOffset;
      	  	break;
      	  }
      	else if(mTableOfContents.itemAt(i).mTimeUs == timeUs)
      		return seekToOffset(mTableOfContents.itemAt(left).mPageOffset);
    }
    /*for(size_t i = 0 ; i< mTableOfContents.size() ;i ++)
    {
    	uint64_t ts;
      findGranulePositionofPage(mTableOfContents.itemAt(i).mPageOffset,&ts);
    	SXLOGD("mTableOfContents.itemAt(%d)--mPageOffset:%lld,mTimeUs:%lld,ts:%lld",i,mTableOfContents.itemAt(i).mPageOffset,mTableOfContents.itemAt(i).mTimeUs,ts);
    }*/
    uint64_t ts1,ts2,ts;
    findGranulePositionofPage(os,&ts1);
    findGranulePositionofPage(oe,&ts2);
    off64_t pos = findAccuratePageOffset((uint64_t)(timeUs * mVi.rate /1000000),os,oe);
    findGranulePositionofPage(pos,&ts);
    SXLOGD("seektable seek--pos:%lld,ts1:%lld,ts2:%lld,pos:%lld,ts:%lld",timeUs * mVi.rate /1000000,ts1,ts2,pos,ts);
    return seekToOffset(pos);	
#endif    
}

#ifdef MTK_AOSP_ENHANCEMENT
status_t MyVorbisExtractor::findNextPage_l(
        off64_t startOffset, off64_t *pageOffset) {
    *pageOffset = startOffset;

    char signature[2048];

    for (;;) {
      ssize_t n = mSource->readAt(*pageOffset, &signature, 2000);

        if (n < 4) {
            *pageOffset = 0;

            return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM;
        }
        int i = 0;
        int step = n-4;
        while(i<=step)
        {
            if (!memcmp(&signature[i], "OggS", 4) && ((*pageOffset + i) > startOffset)) {
                if ((*pageOffset + i) > startOffset) {
                    SXLOGV("skipped %lld bytes of junk to reach next frame",
                         (*pageOffset + i) - startOffset);
                }
                *pageOffset += i;
                return OK;
            }
            
            i++;
         }
        *pageOffset += n;    
    }
}
コード例 #17
0
AMRExtractor::AMRExtractor(const sp<DataSource> &source)
    : mDataSource(source),
      mInitCheck(NO_INIT),
      mOffsetTableLength(0) {
    String8 mimeType;
    float confidence;
    if (!SniffAMR(mDataSource, &mimeType, &confidence, NULL)) {
        return;
    }

    mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB);

    mMeta = new MetaData;
    mMeta->setCString(
            kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
                                  : MEDIA_MIMETYPE_AUDIO_AMR_NB);

    mMeta->setInt32(kKeyChannelCount, 1);
    mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000);

    off64_t offset = mIsWide ? 9 : 6;
    off64_t streamSize;
    size_t frameSize, numFrames = 0;
    int64_t duration = 0;
#ifdef MTK_AOSP_ENHANCEMENT

    status_t ret = 0;
    bool streamingFlag = mDataSource->flags() & DataSource::kIsCachingDataSource;
    char *pData = new char [Buffer_Count_Readed];
    ssize_t dataLen = 0;
    size_t dataOffset = 0;
    SXLOGD("AMRExtractor--is streaming flag=%d, pData:0x%x", streamingFlag, pData);
#endif

    if (mDataSource->getSize(&streamSize) == OK) {
         while (offset < streamSize) {
#ifdef MTK_AOSP_ENHANCEMENT

            if (pData) {
                if (dataLen==0) {
                    dataLen = mDataSource->readAt(offset, (void *)pData, Buffer_Count_Readed);
		    if (dataLen < 0) {
                         return;
		    } 
                    dataOffset = 0;
                }
                ret = getFrameSizeByOffset_MMIO((uint8_t *)pData, dataLen, dataOffset, offset, mIsWide, &frameSize);
                if (ret==NO_MEMORY) {
                    dataLen = 0;
                    continue;
                }
            }else {
                ret = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
            }
            if (ret==ERROR_END_OF_STREAM) {
                break;
            }else if(ret!=OK) {
                if (pData) delete [] pData;
                pData = 0;
                SXLOGD("AMRExtractor--getFrameSizeByOffset is not ok!");
                return;
            }
#else
            if (getFrameSizeByOffset(source, offset, mIsWide, &frameSize) != OK) {
                return;
            }
#endif
            if ((numFrames % 50 == 0) && (numFrames / 50 < OFFSET_TABLE_LEN)) {
                CHECK_EQ(mOffsetTableLength, numFrames / 50);
                mOffsetTable[mOffsetTableLength] = offset - (mIsWide ? 9: 6);
                mOffsetTableLength ++;
            }
#ifdef MTK_AOSP_ENHANCEMENT

            else if(streamingFlag&&(numFrames>=50*OFFSET_TABLE_LEN)) {
                duration += 20000*(streamSize - offset)/((offset - (mIsWide ? 9: 6))/(off64_t)numFrames);
                SXLOGV("AMRExtractor--end duration=%lld, frame size = %lld", duration, (offset - (mIsWide ? 9: 6))/(off64_t)numFrames);
                break;
            }
#endif
            offset += frameSize;
            duration += 20000;  // Each frame is 20ms
            numFrames ++;
        }

        mMeta->setInt64(kKeyDuration, duration);
    }
#ifdef MTK_AOSP_ENHANCEMENT

    if (pData) delete [] pData;
    pData = 0;
    SXLOGD("AMRExtractor--constructor out -");
#endif
    mInitCheck = OK;
}