107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber/* 207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * Copyright (C) 2010 The Android Open Source Project 307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * 407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * you may not use this file except in compliance with the License. 607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * You may obtain a copy of the License at 707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * 807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * 1007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * Unless required by applicable law or agreed to in writing, software 1107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * See the License for the specific language governing permissions and 1407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * limitations under the License. 1507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber */ 1607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 1707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/AMRWriter.h> 1807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaBuffer.h> 1907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaDebug.h> 2007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaDefs.h> 2107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaErrors.h> 2207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaSource.h> 2307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MetaData.h> 241824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong#include <media/mediarecorder.h> 25c67acb2b2890eee013de97b819687511f9551b51James Dong#include <sys/prctl.h> 26c67acb2b2890eee013de97b819687511f9551b51James Dong#include <sys/resource.h> 2707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 2807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Hubernamespace android { 2907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 3007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas HuberAMRWriter::AMRWriter(const char *filename) 3107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber : mFile(fopen(filename, "wb")), 3207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mInitCheck(mFile != NULL ? OK : NO_INIT), 3308c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mStarted(false), 3408c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mPaused(false), 3508c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mResumed(false) { 3607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 3707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 3807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas HuberAMRWriter::AMRWriter(int fd) 3907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber : mFile(fdopen(fd, "wb")), 4007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mInitCheck(mFile != NULL ? OK : NO_INIT), 4108c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mStarted(false), 4208c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mPaused(false), 4308c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mResumed(false) { 4407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 4507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 4607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas HuberAMRWriter::~AMRWriter() { 4707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (mStarted) { 4807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber stop(); 4907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 5007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 5107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (mFile != NULL) { 5207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber fclose(mFile); 5307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mFile = NULL; 5407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 5507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 5607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 5707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huberstatus_t AMRWriter::initCheck() const { 5807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return mInitCheck; 5907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 6007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 6107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huberstatus_t AMRWriter::addSource(const sp<MediaSource> &source) { 6207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (mInitCheck != OK) { 6307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return mInitCheck; 6407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 6507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 6607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (mSource != NULL) { 6707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber // AMR files only support a single track of audio. 6807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return UNKNOWN_ERROR; 6907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 7007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 7107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber sp<MetaData> meta = source->getFormat(); 7207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 7307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber const char *mime; 7407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 7507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 7607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber bool isWide = false; 7707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 7807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber isWide = true; 7907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 8007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return ERROR_UNSUPPORTED; 8107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 8207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 8307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber int32_t channelCount; 8407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber int32_t sampleRate; 8507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); 8607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber CHECK_EQ(channelCount, 1); 8707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 8807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber CHECK_EQ(sampleRate, (isWide ? 16000 : 8000)); 8907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 9007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mSource = source; 9107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 9207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber const char *kHeader = isWide ? "#!AMR-WB\n" : "#!AMR\n"; 9307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber size_t n = strlen(kHeader); 9407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (fwrite(kHeader, 1, n, mFile) != n) { 9507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return ERROR_IO; 9607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 9707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 9807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return OK; 9907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 10007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 1016feaa46496bae85adbe10e84611592612f898081James Dongstatus_t AMRWriter::start(MetaData *params) { 10207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (mInitCheck != OK) { 10307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return mInitCheck; 10407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 10507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 10608c7473ce9b601e170fd79c530f106bf74277a0fJames Dong if (mSource == NULL) { 10707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return UNKNOWN_ERROR; 10807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 10907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 11008c7473ce9b601e170fd79c530f106bf74277a0fJames Dong if (mStarted && mPaused) { 11108c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mPaused = false; 11208c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mResumed = true; 11308c7473ce9b601e170fd79c530f106bf74277a0fJames Dong return OK; 11408c7473ce9b601e170fd79c530f106bf74277a0fJames Dong } else if (mStarted) { 11508c7473ce9b601e170fd79c530f106bf74277a0fJames Dong // Already started, does nothing 11608c7473ce9b601e170fd79c530f106bf74277a0fJames Dong return OK; 11708c7473ce9b601e170fd79c530f106bf74277a0fJames Dong } 11808c7473ce9b601e170fd79c530f106bf74277a0fJames Dong 11907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber status_t err = mSource->start(); 12007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 12107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (err != OK) { 12207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return err; 12307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 12407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 12507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber pthread_attr_t attr; 12607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber pthread_attr_init(&attr); 12707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 12807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 129996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mReachedEOS = false; 13007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mDone = false; 13107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 13207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber pthread_create(&mThread, &attr, ThreadWrapper, this); 13307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber pthread_attr_destroy(&attr); 13407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 13507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mStarted = true; 13607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 13707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber return OK; 13807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 13907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 140d036662470ceb6b20b0591b7d4123f2db911536dJames Dongstatus_t AMRWriter::pause() { 14108c7473ce9b601e170fd79c530f106bf74277a0fJames Dong if (!mStarted) { 142d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 14308c7473ce9b601e170fd79c530f106bf74277a0fJames Dong } 14408c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mPaused = true; 145d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 14608c7473ce9b601e170fd79c530f106bf74277a0fJames Dong} 14708c7473ce9b601e170fd79c530f106bf74277a0fJames Dong 148d036662470ceb6b20b0591b7d4123f2db911536dJames Dongstatus_t AMRWriter::stop() { 149e2018ca9ff9234876bb5ba63d2f51b72396c5fcaAndreas Huber if (!mStarted) { 150d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 15107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 15207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 153e2018ca9ff9234876bb5ba63d2f51b72396c5fcaAndreas Huber mDone = true; 154e2018ca9ff9234876bb5ba63d2f51b72396c5fcaAndreas Huber 15507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber void *dummy; 15607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber pthread_join(mThread, &dummy); 15707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 158d036662470ceb6b20b0591b7d4123f2db911536dJames Dong status_t err = (status_t) dummy; 159d036662470ceb6b20b0591b7d4123f2db911536dJames Dong { 160d036662470ceb6b20b0591b7d4123f2db911536dJames Dong status_t status = mSource->stop(); 161d036662470ceb6b20b0591b7d4123f2db911536dJames Dong if (err == OK && 162d036662470ceb6b20b0591b7d4123f2db911536dJames Dong (status != OK && status != ERROR_END_OF_STREAM)) { 163d036662470ceb6b20b0591b7d4123f2db911536dJames Dong err = status; 164d036662470ceb6b20b0591b7d4123f2db911536dJames Dong } 165d036662470ceb6b20b0591b7d4123f2db911536dJames Dong } 16607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 16707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mStarted = false; 168d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return err; 16907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 17007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 1711824486e044f4f09640fbd7bef74a20e4efb35aeJames Dongbool AMRWriter::exceedsFileSizeLimit() { 1721824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong if (mMaxFileSizeLimitBytes == 0) { 1731824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong return false; 1741824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong } 1751824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes; 1761824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong} 1771824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong 1781824486e044f4f09640fbd7bef74a20e4efb35aeJames Dongbool AMRWriter::exceedsFileDurationLimit() { 1791824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong if (mMaxFileDurationLimitUs == 0) { 1801824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong return false; 1811824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong } 1821824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong return mEstimatedDurationUs >= mMaxFileDurationLimitUs; 1831824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong} 1841824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong 18507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber// static 18607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Hubervoid *AMRWriter::ThreadWrapper(void *me) { 187d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return (void *) static_cast<AMRWriter *>(me)->threadFunc(); 18807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 18907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 190d036662470ceb6b20b0591b7d4123f2db911536dJames Dongstatus_t AMRWriter::threadFunc() { 1911824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong mEstimatedDurationUs = 0; 1921824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong mEstimatedSizeBytes = 0; 19368510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong bool stoppedPrematurely = true; 19408c7473ce9b601e170fd79c530f106bf74277a0fJames Dong int64_t previousPausedDurationUs = 0; 19508c7473ce9b601e170fd79c530f106bf74277a0fJames Dong int64_t maxTimestampUs = 0; 196d036662470ceb6b20b0591b7d4123f2db911536dJames Dong status_t err = OK; 19708c7473ce9b601e170fd79c530f106bf74277a0fJames Dong 198c67acb2b2890eee013de97b819687511f9551b51James Dong prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0); 199e2018ca9ff9234876bb5ba63d2f51b72396c5fcaAndreas Huber while (!mDone) { 20007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber MediaBuffer *buffer; 201d036662470ceb6b20b0591b7d4123f2db911536dJames Dong err = mSource->read(&buffer); 20207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 20307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (err != OK) { 20407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber break; 20507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 20607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 20708c7473ce9b601e170fd79c530f106bf74277a0fJames Dong if (mPaused) { 20808c7473ce9b601e170fd79c530f106bf74277a0fJames Dong buffer->release(); 20908c7473ce9b601e170fd79c530f106bf74277a0fJames Dong buffer = NULL; 21008c7473ce9b601e170fd79c530f106bf74277a0fJames Dong continue; 21108c7473ce9b601e170fd79c530f106bf74277a0fJames Dong } 21208c7473ce9b601e170fd79c530f106bf74277a0fJames Dong 2131824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong mEstimatedSizeBytes += buffer->range_length(); 2141824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong if (exceedsFileSizeLimit()) { 2151824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong buffer->release(); 2161824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong buffer = NULL; 2171824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 2181824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong break; 2191824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong } 2201824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong 2211824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong int64_t timestampUs; 2221824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 2231824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong if (timestampUs > mEstimatedDurationUs) { 2241824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong mEstimatedDurationUs = timestampUs; 2251824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong } 22608c7473ce9b601e170fd79c530f106bf74277a0fJames Dong if (mResumed) { 22708c7473ce9b601e170fd79c530f106bf74277a0fJames Dong previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); 22808c7473ce9b601e170fd79c530f106bf74277a0fJames Dong mResumed = false; 22908c7473ce9b601e170fd79c530f106bf74277a0fJames Dong } 23008c7473ce9b601e170fd79c530f106bf74277a0fJames Dong timestampUs -= previousPausedDurationUs; 23108c7473ce9b601e170fd79c530f106bf74277a0fJames Dong LOGV("time stamp: %lld, previous paused duration: %lld", 23208c7473ce9b601e170fd79c530f106bf74277a0fJames Dong timestampUs, previousPausedDurationUs); 23308c7473ce9b601e170fd79c530f106bf74277a0fJames Dong if (timestampUs > maxTimestampUs) { 23408c7473ce9b601e170fd79c530f106bf74277a0fJames Dong maxTimestampUs = timestampUs; 23508c7473ce9b601e170fd79c530f106bf74277a0fJames Dong } 23608c7473ce9b601e170fd79c530f106bf74277a0fJames Dong 2371824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong if (exceedsFileDurationLimit()) { 2381824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong buffer->release(); 2391824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong buffer = NULL; 2401824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 2411824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong break; 2421824486e044f4f09640fbd7bef74a20e4efb35aeJames Dong } 24307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber ssize_t n = fwrite( 24407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(), 24507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 1, 24607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber buffer->range_length(), 24707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber mFile); 24807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 24907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber if (n < (ssize_t)buffer->range_length()) { 250259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber buffer->release(); 251259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber buffer = NULL; 252259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber 25307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber break; 25407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 255259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber 25668510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong // XXX: How to tell it is stopped prematurely? 25768510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong if (stoppedPrematurely) { 25868510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong stoppedPrematurely = false; 25968510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong } 26068510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong 261259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber buffer->release(); 262259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber buffer = NULL; 26307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber } 264996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 26568510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong if (stoppedPrematurely) { 26609936ed19263854e937198af03d9805a8b669ca1James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_COMPLETION_STATUS, UNKNOWN_ERROR); 26768510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong } 26868510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong 26968510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong fflush(mFile); 27068510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong fclose(mFile); 27168510e60f9671ee08f3cc18bd93400cafb7703bbJames Dong mFile = NULL; 272996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mReachedEOS = true; 273d036662470ceb6b20b0591b7d4123f2db911536dJames Dong if (err == ERROR_END_OF_STREAM) { 274d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 275d036662470ceb6b20b0591b7d4123f2db911536dJames Dong } 276d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return err; 277996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber} 278996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 279996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huberbool AMRWriter::reachedEOS() { 280996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return mReachedEOS; 28107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} 28207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber 28307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber} // namespace android 284