int AmSuperPlayer::initThread() { { // Mutex::Autolock l(mMutex); mRenderTid = myTid(); mCondition.signal(); } mPlayer=CreatePlayer(); if (mPlayer!=NULL && mNotify!=NULL) { int i; Mutex::Autolock N(mNotifyMutex); for(i=0;i<oldmsg_num;i++){ mNotify(mCookie, oldmsg[i].msg,oldmsg[i].ext1,oldmsg[i].ext2); } oldmsg_num=0; subplayer_inited=true; }else{ if(mNotify!=NULL) mNotify(mCookie, MEDIA_ERROR,MEDIA_ERROR_UNKNOWN,-1); } Mutex::Autolock l(mMutex); mRenderTid = -1; mCondition.signal(); TRACE(); return 0; }
int MidiFile::render() { EAS_RESULT result = EAS_FAILURE; EAS_I32 count; int temp; bool audioStarted = false; LOGV("MidiFile::render"); // allocate render buffer mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS]; if (!mAudioBuffer) { LOGE("mAudioBuffer allocate failed"); goto threadExit; } // signal main thread that we started { Mutex::Autolock l(mMutex); mTid = myTid(); LOGV("render thread(%d) signal", mTid); mCondition.signal(); } while (1) { mMutex.lock(); // nothing to render, wait for client thread to wake us up while (!mRender && !mExit) { LOGV("MidiFile::render - signal wait"); mCondition.wait(mMutex); LOGV("MidiFile::render - signal rx'd"); } if (mExit) { mMutex.unlock(); break; } // render midi data into the input buffer //LOGV("MidiFile::render - rendering audio"); int num_output = 0; EAS_PCM* p = mAudioBuffer; for (int i = 0; i < NUM_BUFFERS; i++) { result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count); if (result != EAS_SUCCESS) { LOGE("EAS_Render returned %ld", result); } p += count * pLibConfig->numChannels; num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM); } // update playback state and position // LOGV("MidiFile::render - updating state"); EAS_GetLocation(mEasData, mEasHandle, &mPlayTime); EAS_State(mEasData, mEasHandle, &mState); mMutex.unlock(); // create audio output track if necessary if (!mAudioSink->ready()) { LOGV("MidiFile::render - create output track"); if (createOutputTrack() != NO_ERROR) goto threadExit; } // Write data to the audio hardware // LOGV("MidiFile::render - writing to audio output"); if ((temp = mAudioSink->write(mAudioBuffer, num_output)) < 0) { LOGE("Error in writing:%d",temp); return temp; } // start audio output if necessary if (!audioStarted) { //LOGV("MidiFile::render - starting audio"); mAudioSink->start(); audioStarted = true; } // still playing? if ((mState == EAS_STATE_STOPPED) || (mState == EAS_STATE_ERROR) || (mState == EAS_STATE_PAUSED)) { switch(mState) { case EAS_STATE_STOPPED: { LOGV("MidiFile::render - stopped"); sendEvent(MEDIA_PLAYBACK_COMPLETE); break; } case EAS_STATE_ERROR: { LOGE("MidiFile::render - error"); sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN); break; } case EAS_STATE_PAUSED: LOGV("MidiFile::render - paused"); break; default: break; } mAudioSink->stop(); audioStarted = false; mRender = false; } } threadExit: mAudioSink.clear(); if (mAudioBuffer) { delete [] mAudioBuffer; mAudioBuffer = NULL; } mMutex.lock(); mTid = -1; mCondition.signal(); mMutex.unlock(); return result; }
//------------------------------------------------------------------------------------------------- int JetPlayer::render() { EAS_RESULT result = EAS_FAILURE; EAS_I32 count; int temp; bool audioStarted = false; LOGV("JetPlayer::render(): entering"); // allocate render buffer mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS]; if (!mAudioBuffer) { LOGE("JetPlayer::render(): mAudioBuffer allocate failed"); goto threadExit; } // signal main thread that we started { Mutex::Autolock l(mMutex); mTid = myTid(); LOGV("JetPlayer::render(): render thread(%d) signal", mTid); mCondition.signal(); } while (1) { mMutex.lock(); // [[[[[[[[ LOCK --------------------------------------- if (mEasData == NULL) { mMutex.unlock(); LOGV("JetPlayer::render(): NULL EAS data, exiting render."); goto threadExit; } // nothing to render, wait for client thread to wake us up while (!mRender) { LOGV("JetPlayer::render(): signal wait"); if (audioStarted) { mAudioTrack->pause(); // we have to restart the playback once we start rendering again audioStarted = false; } mCondition.wait(mMutex); LOGV("JetPlayer::render(): signal rx'd"); } // render midi data into the input buffer int num_output = 0; EAS_PCM* p = mAudioBuffer; for (int i = 0; i < MIX_NUM_BUFFERS; i++) { result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count); if (result != EAS_SUCCESS) { LOGE("JetPlayer::render(): EAS_Render returned error %ld", result); } p += count * pLibConfig->numChannels; num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM); // send events that were generated (if any) to the event callback fireEventsFromJetQueue(); } // update playback state //LOGV("JetPlayer::render(): updating state"); JET_Status(mEasData, &mJetStatus); fireUpdateOnStatusChange(); mPaused = mJetStatus.paused; mMutex.unlock(); // UNLOCK ]]]]]]]] ----------------------------------- // check audio output track if (mAudioTrack == NULL) { LOGE("JetPlayer::render(): output AudioTrack was not created"); goto threadExit; } // Write data to the audio hardware //LOGV("JetPlayer::render(): writing to audio output"); if ((temp = mAudioTrack->write(mAudioBuffer, num_output)) < 0) { LOGE("JetPlayer::render(): Error in writing:%d",temp); return temp; } // start audio output if necessary if (!audioStarted) { LOGV("JetPlayer::render(): starting audio playback"); mAudioTrack->start(); audioStarted = true; } }//while (1) threadExit: if (mAudioTrack) { mAudioTrack->stop(); mAudioTrack->flush(); } if (mAudioBuffer) { delete [] mAudioBuffer; mAudioBuffer = NULL; } mMutex.lock(); mTid = -1; mCondition.signal(); mMutex.unlock(); return result; }
status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; char buffer[SIZE]; String8 result; if (checkCallingPermission(String16("android.permission.DUMP")) == false) { snprintf(buffer, SIZE, "Permission Denial: " "can't dump MediaPlayerService from pid=%d, uid=%d\n", IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); result.append(buffer); } else { Mutex::Autolock lock(mLock); for (int i = 0, n = mClients.size(); i < n; ++i) { sp<Client> c = mClients[i].promote(); if (c != 0) c->dump(fd, args); } result.append(" Files opened and/or mapped:\n"); snprintf(buffer, SIZE, "/proc/%d/maps", myTid()); FILE *f = fopen(buffer, "r"); if (f) { while (!feof(f)) { fgets(buffer, SIZE, f); if (strstr(buffer, " /sdcard/") || strstr(buffer, " /system/sounds/") || strstr(buffer, " /system/media/")) { result.append(" "); result.append(buffer); } } fclose(f); } else { result.append("couldn't open "); result.append(buffer); result.append("\n"); } snprintf(buffer, SIZE, "/proc/%d/fd", myTid()); DIR *d = opendir(buffer); if (d) { struct dirent *ent; while((ent = readdir(d)) != NULL) { if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) { snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name); struct stat s; if (lstat(buffer, &s) == 0) { if ((s.st_mode & S_IFMT) == S_IFLNK) { char linkto[256]; int len = readlink(buffer, linkto, sizeof(linkto)); if(len > 0) { if(len > 255) { linkto[252] = '.'; linkto[253] = '.'; linkto[254] = '.'; linkto[255] = 0; } else { linkto[len] = 0; } if (strstr(linkto, "/sdcard/") == linkto || strstr(linkto, "/system/sounds/") == linkto || strstr(linkto, "/system/media/") == linkto) { result.append(" "); result.append(buffer); result.append(" -> "); result.append(linkto); result.append("\n"); } } } else { result.append(" unexpected type for "); result.append(buffer); result.append("\n"); } } } } closedir(d); } else { result.append("couldn't open "); result.append(buffer); result.append("\n"); } #if defined(__arm__) bool dumpMem = false; for (size_t i = 0; i < args.size(); i++) { if (args[i] == String16("-m")) { dumpMem = true; } } if (dumpMem) { memStatus(fd, args); } #endif } write(fd, result.string(), result.size()); return NO_ERROR; }