status_t AACWriter::threadFunc() { mEstimatedDurationUs = 0; mEstimatedSizeBytes = 0; int64_t previousPausedDurationUs = 0; int64_t maxTimestampUs = 0; status_t err = OK; prctl(PR_SET_NAME, (unsigned long)"AACWriterThread", 0, 0, 0); while (!mDone && err == OK) { MediaBuffer *buffer; err = mSource->read(&buffer); if (err != OK) { break; } if (mPaused) { buffer->release(); buffer = NULL; continue; } mEstimatedSizeBytes += kAdtsHeaderLength + buffer->range_length(); if (exceedsFileSizeLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); break; } int32_t isCodecSpecific = 0; if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecSpecific) && isCodecSpecific) { ALOGV("Drop codec specific info buffer"); buffer->release(); buffer = NULL; continue; } int64_t timestampUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } if (mResumed) { previousPausedDurationUs += (timestampUs - maxTimestampUs - mFrameDurationUs); mResumed = false; } timestampUs -= previousPausedDurationUs; ALOGV("time stamp: %lld, previous paused duration: %lld", timestampUs, previousPausedDurationUs); if (timestampUs > maxTimestampUs) { maxTimestampUs = timestampUs; } if (exceedsFileDurationLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); break; } // Each output AAC audio frame to the file contains // 1. an ADTS header, followed by // 2. the compressed audio data. ssize_t dataLength = buffer->range_length(); uint8_t *data = (uint8_t *)buffer->data() + buffer->range_offset(); if (writeAdtsHeader(kAdtsHeaderLength + dataLength) != OK || dataLength != write(mFd, data, dataLength)) { err = ERROR_IO; } buffer->release(); buffer = NULL; } close(mFd); mFd = -1; mReachedEOS = true; if (err == ERROR_END_OF_STREAM) { return OK; } return err; }
status_t AMRWriter::threadFunc() { mEstimatedDurationUs = 0; mEstimatedSizeBytes = 0; bool stoppedPrematurely = true; int64_t previousPausedDurationUs = 0; int64_t maxTimestampUs = 0; status_t err = OK; prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0); while (!mDone) { MediaBuffer *buffer; err = mSource->read(&buffer); if (err != OK) { break; } if (mPaused) { buffer->release(); buffer = NULL; continue; } mEstimatedSizeBytes += buffer->range_length(); if (exceedsFileSizeLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); break; } int64_t timestampUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } if (mResumed) { previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); mResumed = false; } timestampUs -= previousPausedDurationUs; ALOGV("time stamp: %lld, previous paused duration: %lld", timestampUs, previousPausedDurationUs); if (timestampUs > maxTimestampUs) { maxTimestampUs = timestampUs; } if (exceedsFileDurationLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); break; } ssize_t n = write(mFd, (const uint8_t *)buffer->data() + buffer->range_offset(), buffer->range_length()); if (n < (ssize_t)buffer->range_length()) { buffer->release(); buffer = NULL; break; } // XXX: How to tell it is stopped prematurely? if (stoppedPrematurely) { stoppedPrematurely = false; } buffer->release(); buffer = NULL; } if (stoppedPrematurely) { notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR); } close(mFd); mFd = -1; mReachedEOS = true; if ((err == ERROR_END_OF_STREAM)||(err = -ETIMEDOUT)) { return OK; } return err; }
status_t ExtendedWriter::threadFunc() { mEstimatedDurationUs = 0; mEstimatedSizeBytes = 0; bool stoppedPrematurely = true; int64_t previousPausedDurationUs = 0; int64_t maxTimestampUs = 0; status_t err = OK; pid_t tid = gettid(); androidSetThreadPriority(tid, ANDROID_PRIORITY_AUDIO); prctl(PR_SET_NAME, (unsigned long)"ExtendedWriter", 0, 0, 0); while (!mDone) { MediaBuffer *buffer; err = mSource->read(&buffer); if (err != OK) { break; } if (mPaused) { buffer->release(); buffer = NULL; continue; } mEstimatedSizeBytes += buffer->range_length(); if (exceedsFileSizeLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); break; } int64_t timestampUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } if (mResumed) { previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); mResumed = false; } timestampUs -= previousPausedDurationUs; ALOGV("time stamp: %lld, previous paused duration: %lld", timestampUs, previousPausedDurationUs); if (timestampUs > maxTimestampUs) { maxTimestampUs = timestampUs; } if (exceedsFileDurationLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); break; } ssize_t n = fwrite( (const uint8_t *)buffer->data() + buffer->range_offset(), 1, buffer->range_length(), mFile); mOffset += n; if (n < (ssize_t)buffer->range_length()) { buffer->release(); buffer = NULL; break; } // XXX: How to tell it is stopped prematurely? if (stoppedPrematurely) { stoppedPrematurely = false; } buffer->release(); buffer = NULL; } if (stoppedPrematurely) { notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR); } if ( mFormat == AUDIO_FORMAT_QCELP ) { writeQCPHeader( ); } else if ( mFormat == AUDIO_FORMAT_EVRC ) { writeEVRCHeader( ); } fflush(mFile); fclose(mFile); mFile = NULL; mReachedEOS = true; if (err == ERROR_END_OF_STREAM || (err == -ETIMEDOUT)) { return OK; } return err; }
status_t OggWriter::threadFunc() { mEstimatedDurationUs = 0; mEstimatedSizeBytes = 0; bool stoppedPrematurely = true; int64_t previousPausedDurationUs = 0; int64_t maxTimestampUs = 0; status_t err = OK; int64_t ltotalSize = 0; int64_t timestampUs = 0; // int64_t tsUsPauseBeg = 0; int64_t tsUsPauseEnd = 0; //paused sample count int64_t smpPaused = 0; // prctl(PR_SET_NAME, (unsigned long)"OggWriter", 0, 0, 0); //struct sched_param param; //param.sched_priority = RTPM_PRIO_OMX_AUDIO; //sched_setscheduler(0, SCHED_RR, ¶m); //androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); //while (!mDone) { while (1 == 1) { MediaBuffer *buffer = NULL; MediaBuffer *buffer1 = NULL; if (mDone) { buffer = new MediaBuffer(0); buffer1 = buffer; } LOGV("OggWriter::threadFunc:mSource->read+:buffer=%p,buffer1=%p", buffer, buffer1); err = mSource->read(&buffer); LOGV("OggWriter::threadFunc:mSource->read-,err=%d,buffer=%p", err, buffer); if (err != OK) { break; } LOGV("OggWriter::threadFunc:buffer->range_length()=%d", buffer->range_length()); //buffer->range_length() == 0, ogg encoder SWIP caching data if (mPaused || buffer->range_length() == 0) { //mtk80721 deal pause time error+ if (mPaused && mPausedflag) { buffer->meta_data()->findInt64(kKeyTime, &tsUsPauseBeg); LOGD("OggWriter::threadFunc,pausetime=%d,tsUsPauseBeg=%lld", iPausedTime, tsUsPauseBeg); mPausedflag = false; } //- if (buffer->range_length() > 0) { //not vorbis header data should be released if (memcmp(buffer->data() + 29, "vorbis", 6) != 0) { buffer->release(); buffer = NULL; continue; } else { LOGD("ogg header:buffer=%p,size=%d", buffer, buffer->range_length()); } } else { buffer->release(); buffer = NULL; continue; } } mEstimatedSizeBytes += buffer->range_length(); if (exceedsFileSizeLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); break; } CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); if (timestampUs > 0) { if (timestampUs > mEstimatedDurationUs) { mEstimatedDurationUs = timestampUs; } if (mResumed) { //mtk80721 deal pause time error+ buffer->meta_data()->findInt64(kKeyTime, &tsUsPauseEnd); LOGD("previousPausedDurationUs =%lld,pausetime=%d,tsUsPauseBeg=%lld,tsUsPauseEnd=%lld", previousPausedDurationUs, iPausedTime, tsUsPauseBeg, tsUsPauseEnd); previousPausedDurationUs = previousPausedDurationUs + (tsUsPauseEnd - tsUsPauseBeg); smpPaused = previousPausedDurationUs * mSampleRate / 1000000ll; LOGD("previousPausedDurationUs =%lld,samplecount=%lld", previousPausedDurationUs, smpPaused); //previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); //- mResumed = false; } timestampUs -= previousPausedDurationUs; LOGV("time stamp: %lld, previous paused duration: %lld", timestampUs, previousPausedDurationUs); if (timestampUs > maxTimestampUs) { maxTimestampUs = timestampUs; } } if (exceedsFileDurationLimit()) { buffer->release(); buffer = NULL; notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); break; } LOGV("OggWriter::threadFunc:fwrite"); //write timestamp uint8_t *ptimestamp = (uint8_t *)buffer->data() + buffer->range_offset() + 6; uint64_t ts = U64LE_AT(ptimestamp); if (smpPaused > 0) { ts -= smpPaused; memcpy(ptimestamp, &ts, sizeof(int64_t)); } ssize_t n = fwrite( (const uint8_t *)buffer->data() + buffer->range_offset(), 1, buffer->range_length(), mFile); ltotalSize += n; if (n < (ssize_t)buffer->range_length()) { buffer->release(); buffer = NULL; break; } // XXX: How to tell it is stopped prematurely? if (stoppedPrematurely) { stoppedPrematurely = false; } LOGV("OggWriter::threadFunc:buffer->release:buffer=%p", buffer); buffer->release(); buffer = NULL; } if (stoppedPrematurely) { notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR); } /* // int bitrate = ltotalSize / (timestampUs/1E6) * 8; LOGV("ltotalSize=%lld, timestampUs=%lld, bitrate=%d",ltotalSize, timestampUs, bitrate); //seek to the bitrate field fseek(mFile, 44, SEEK_SET); // max bitrate fwrite(&bitrate, 1, sizeof(int), mFile); // nominal bitrate fwrite(&bitrate, 1, sizeof(int), mFile); // min bitrate fwrite(&bitrate, 1, sizeof(int), mFile); */ fflush(mFile); fclose(mFile); mFile = NULL; mReachedEOS = true; if (err == ERROR_END_OF_STREAM) { return OK; } return err; }