1e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber/* 2e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * Copyright (C) 2010 The Android Open Source Project 3e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * 4e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * you may not use this file except in compliance with the License. 6e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * You may obtain a copy of the License at 7e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * 8e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * 10e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * Unless required by applicable law or agreed to in writing, software 11e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * See the License for the specific language governing permissions and 14e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * limitations under the License. 15e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber */ 16e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <fcntl.h> 18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 19a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <sys/prctl.h> 20a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <sys/stat.h> 21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <sys/types.h> 22a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 23f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 24e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/AMRWriter.h> 25e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaBuffer.h> 26e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaDefs.h> 27e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaErrors.h> 28e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaSource.h> 29e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MetaData.h> 30d599cd4573b5a2d5914c5040e0565ef866749b77James Dong#include <media/mediarecorder.h> 31e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 32e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubernamespace android { 33e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 34e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::AMRWriter(int fd) 35674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(dup(fd)), 36674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck(mFd < 0? NO_INIT: OK), 37a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 38a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 39a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 40e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 41e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 42e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::~AMRWriter() { 43e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mStarted) { 448bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dong reset(); 45e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 46e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 47674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd != -1) { 48674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 49674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 50e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 51e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 52e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 53e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::initCheck() const { 54e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 55e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 56e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 57b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatus_t AMRWriter::addSource(const sp<IMediaSource> &source) { 58e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 59e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 60e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 61e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 62e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mSource != NULL) { 63e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber // AMR files only support a single track of audio. 64e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 65e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 66e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 67e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber sp<MetaData> meta = source->getFormat(); 68e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 69e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *mime; 70e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 71e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 72e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber bool isWide = false; 73e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 74e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber isWide = true; 75e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 76e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_UNSUPPORTED; 77e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 78e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 79e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t channelCount; 80e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t sampleRate; 81e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); 82e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(channelCount, 1); 83e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 84e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(sampleRate, (isWide ? 16000 : 8000)); 85e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 86e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mSource = source; 87e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 88e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *kHeader = isWide ? "#!AMR-WB\n" : "#!AMR\n"; 89674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong ssize_t n = strlen(kHeader); 90c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (write(mFd, kHeader, n) != n) { 91e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_IO; 92e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 93e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 94e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 95e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 96e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 9784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t AMRWriter::start(MetaData * /* params */) { 98e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 99e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 100e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 101e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 102a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mSource == NULL) { 103e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 104e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 105e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 106a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mStarted && mPaused) { 107a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = false; 108a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = true; 109a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 110a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } else if (mStarted) { 111a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong // Already started, does nothing 112a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 113a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 114a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 115e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber status_t err = mSource->start(); 116e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 117e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 118e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return err; 119e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 120e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 121e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_t attr; 122e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_init(&attr); 123e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 124e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1252dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = false; 126e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mDone = false; 127e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 128e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_create(&mThread, &attr, ThreadWrapper, this); 129e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_destroy(&attr); 130e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 131e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = true; 132e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 133e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 134e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 135e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 13637187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t AMRWriter::pause() { 137a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (!mStarted) { 13837187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 139a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 140a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = true; 14137187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 142a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong} 143a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 1448bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dongstatus_t AMRWriter::reset() { 145ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber if (!mStarted) { 14637187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 147e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 148e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 149ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber mDone = true; 150ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber 151e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber void *dummy; 152e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_join(mThread, &dummy); 153e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 154377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy)); 15537187916a486504acaf83bea30147eb5fbf46ae5James Dong { 15637187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t status = mSource->stop(); 15737187916a486504acaf83bea30147eb5fbf46ae5James Dong if (err == OK && 15837187916a486504acaf83bea30147eb5fbf46ae5James Dong (status != OK && status != ERROR_END_OF_STREAM)) { 15937187916a486504acaf83bea30147eb5fbf46ae5James Dong err = status; 16037187916a486504acaf83bea30147eb5fbf46ae5James Dong } 16137187916a486504acaf83bea30147eb5fbf46ae5James Dong } 162e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 163e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = false; 16437187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 165e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 166e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 167d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileSizeLimit() { 168d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeLimitBytes == 0) { 169d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 170d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 171d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes; 172d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 173d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 174d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileDurationLimit() { 175d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationLimitUs == 0) { 176d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 177d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 178d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedDurationUs >= mMaxFileDurationLimitUs; 179d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 180d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 181e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber// static 182e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubervoid *AMRWriter::ThreadWrapper(void *me) { 183377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT return (void *)(uintptr_t) static_cast<AMRWriter *>(me)->threadFunc(); 184e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 185e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 18637187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t AMRWriter::threadFunc() { 187d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = 0; 188d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes = 0; 189f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong bool stoppedPrematurely = true; 190a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t previousPausedDurationUs = 0; 191a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t maxTimestampUs = 0; 19237187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t err = OK; 193a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 194a6f61fc8e3d06373c17f0a38ff600e2b71c414faJames Dong prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0); 195ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber while (!mDone) { 196e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber MediaBuffer *buffer; 19737187916a486504acaf83bea30147eb5fbf46ae5James Dong err = mSource->read(&buffer); 198e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 199e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 200e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 201e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 202e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 203a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mPaused) { 204a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer->release(); 205a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer = NULL; 206a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong continue; 207a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 208a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 209d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes += buffer->range_length(); 210d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileSizeLimit()) { 211d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 212d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 213d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 214d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 215d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 216d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 217d599cd4573b5a2d5914c5040e0565ef866749b77James Dong int64_t timestampUs; 218d599cd4573b5a2d5914c5040e0565ef866749b77James Dong CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 219d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (timestampUs > mEstimatedDurationUs) { 220d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = timestampUs; 221d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 222a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mResumed) { 223a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); 224a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = false; 225a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 226a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs -= previousPausedDurationUs; 227a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("time stamp: %" PRId64 ", previous paused duration: %" PRId64, 228a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs, previousPausedDurationUs); 229a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (timestampUs > maxTimestampUs) { 230a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong maxTimestampUs = timestampUs; 231a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 232a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 233d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileDurationLimit()) { 234d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 235d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 236d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 237d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 238d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 239c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong ssize_t n = write(mFd, 240c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong (const uint8_t *)buffer->data() + buffer->range_offset(), 241c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong buffer->range_length()); 242e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 243e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (n < (ssize_t)buffer->range_length()) { 244b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 245b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 246fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong err = ERROR_IO; 247fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong break; 248fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong } 249b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 250fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong if (err != OK) { 251e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 252e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 253b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 254f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong if (stoppedPrematurely) { 255f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong stoppedPrematurely = false; 256f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 257f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 258b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 259b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 260e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 2612dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 262fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong if ((err == OK || err == ERROR_END_OF_STREAM) && stoppedPrematurely) { 263fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong err = ERROR_MALFORMED; 264f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 265f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 266674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 267674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 2682dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = true; 26937187916a486504acaf83bea30147eb5fbf46ae5James Dong if (err == ERROR_END_OF_STREAM) { 27037187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 27137187916a486504acaf83bea30147eb5fbf46ae5James Dong } 27237187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 2732dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 2742dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 2752dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huberbool AMRWriter::reachedEOS() { 2762dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return mReachedEOS; 277e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 278e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 279e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} // namespace android 280