void SoundChannel::stop() { { Mutex::Autolock lock(&mLock); stop_l(); } mSoundPool->done(this); }
status_t CedarXPlayer::stop() { LOGV("CedarXPlayer::stop"); if(mPlayer != NULL) { mPlayer->control(mPlayer, CDX_CMD_STOP_ASYNC, 0, 0); } stop_l(); if(this->display_3d_mode == CEDARX_DISPLAY_3D_MODE_3D) { set3DMode(CEDARV_3D_MODE_NONE, CEDARX_DISPLAY_3D_MODE_2D); } this->_3d_mode = CEDARV_3D_MODE_NONE; this->display_3d_mode = CEDARX_DISPLAY_3D_MODE_2D; this->anaglagh_en = 0; this->anaglagh_type = 0; this->wait_anaglagh_display_change = 0; //* need to reset the display? //* TODO. return OK; }
// call with sound pool lock held void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, float rightVolume, int priority, int loop, float rate) { sp<AudioTrack> oldTrack; sp<AudioTrack> newTrack; status_t status; { // scope for the lock Mutex::Autolock lock(&mLock); ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," " priority=%d, loop=%d, rate=%f", this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, priority, loop, rate); // if not idle, this voice is being stolen if (mState != IDLE) { ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); stop_l(); return; } // initialize track size_t afFrameCount; uint32_t afSampleRate; audio_stream_type_t streamType = mSoundPool->streamType(); if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { afFrameCount = kDefaultFrameCount; } if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { afSampleRate = kDefaultSampleRate; } int numChannels = sample->numChannels(); uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; uint32_t frameCount = 0; if (loop) { frameCount = sample->size()/numChannels/ ((sample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); } #ifndef USE_SHARED_MEM_BUFFER // Ensure minimum audio buffer size in case of short looped sample if(frameCount < totalFrames) { frameCount = totalFrames; } #endif // mToggle toggles each time a track is started on a given channel. // The toggle is concatenated with the SoundChannel address and passed to AudioTrack // as callback user data. This enables the detection of callbacks received from the old // audio track while the new one is being started and avoids processing them with // wrong audio audio buffer size (mAudioBufferSize) unsigned long toggle = mToggle ^ 1; void *userData = (void *)((unsigned long)this | toggle); uint32_t channels = (numChannels == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO; // do not create a new audio track if current track is compatible with sample parameters #ifdef USE_SHARED_MEM_BUFFER newTrack = new AudioTrack(streamType, sampleRate, sample->format(), channels, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData); #else newTrack = new AudioTrack(streamType, sampleRate, sample->format(), channels, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, bufferFrames); #endif oldTrack = mAudioTrack; status = newTrack->initCheck(); if (status != NO_ERROR) { ALOGE("Error creating AudioTrack"); goto exit; } ALOGV("setVolume %p", newTrack.get()); newTrack->setVolume(leftVolume, rightVolume); newTrack->setLoop(0, frameCount, loop); // From now on, AudioTrack callbacks received with previous toggle value will be ignored. mToggle = toggle; mAudioTrack = newTrack; mPos = 0; mSample = sample; mChannelID = nextChannelID; mPriority = priority; mLoop = loop; mLeftVolume = leftVolume; mRightVolume = rightVolume; mNumChannels = numChannels; mRate = rate; clearNextEvent(); mState = PLAYING; mAudioTrack->start(); mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); } exit: ALOGV("delete oldTrack %p", oldTrack.get()); if (status != NO_ERROR) { mAudioTrack.clear(); } }
int CedarXPlayer::CedarXPlayerCallback(int event, void *info) { int ret = 0; int *para = (int*)info; //LOGV("----------CedarXPlayerCallback event:%d info:%p\n", event, info); switch (event) { case CDX_EVENT_PLAYBACK_COMPLETE: mFlags &= ~PLAYING; mFlags |= AT_EOS; stop_l(); //for gallery break; case CDX_EVENT_VIDEORENDERINIT: StagefrightVideoRenderInit(para[0], para[1], para[2], (void *)para[3]); break; case CDX_EVENT_VIDEORENDERDATA: StagefrightVideoRenderData((void*)para[0],para[1]); break; case CDX_EVENT_VIDEORENDEREXIT: StagefrightVideoRenderExit(); break; case CDX_EVENT_VIDEORENDERGETDISPID: *((int*)para) = StagefrightVideoRenderGetFrameID(); break; case CDX_EVENT_AUDIORENDERINIT: StagefrightAudioRenderInit(para[0], para[1], para[2]); break; case CDX_EVENT_AUDIORENDEREXIT: StagefrightAudioRenderExit(0); break; case CDX_EVENT_AUDIORENDERDATA: ret = StagefrightAudioRenderData((void*)para[0],para[1]); break; case CDX_EVENT_AUDIORENDERGETSPACE: ret = StagefrightAudioRenderGetSpace(); break; case CDX_EVENT_AUDIORENDERGETDELAY: ret = StagefrightAudioRenderGetDelay(); break; case CDX_EVENT_AUDIORENDERFLUSHCACHE: ret = StagefrightAudioRenderFlushCache(); break; case CDX_MEDIA_INFO_BUFFERING_START: LOGV("MEDIA_INFO_BUFFERING_START"); notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START); break; case CDX_MEDIA_INFO_BUFFERING_END: LOGV("MEDIA_INFO_BUFFERING_END ..."); notifyListener_l(MEDIA_BUFFERING_UPDATE, 0);//clear buffer scroll usleep(1000); notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END); break; case CDX_MEDIA_BUFFERING_UPDATE: { int64_t positionUs; int progress = (int)para; progress = progress > 100 ? 100 : progress; getPosition(&positionUs); if(mDurationUs > 0) { progress = (int)((positionUs + (mDurationUs - positionUs) * progress / 100) * 100 / mDurationUs); LOGV("MEDIA_INFO_BUFFERING_UPDATE: %d %lld", (int)progress, positionUs); notifyListener_l(MEDIA_BUFFERING_UPDATE, (int)progress); } break; } case CDX_MEDIA_WHOLE_BUFFERING_UPDATE: notifyListener_l(MEDIA_BUFFERING_UPDATE, (int)para); break; case CDX_EVENT_PREPARED: finishAsyncPrepare_l((int)para); break; case CDX_EVENT_SEEK_COMPLETE: finishSeek_l(0); break; case CDX_EVENT_NATIVE_SUSPEND: LOGV("receive CDX_EVENT_NATIVE_SUSPEND"); ret = nativeSuspend(); break; // case CDX_MEDIA_INFO_SRC_3D_MODE: // { // cdx_3d_mode_e tmp_3d_mode; // tmp_3d_mode = *((cdx_3d_mode_e *)info); // LOGV("source 3d mode get from parser is %d", tmp_3d_mode); // notifyListener_l(MEDIA_INFO_SRC_3D_MODE, tmp_3d_mode); // } // break; default: break; } return ret; }