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(const char *filename) 35674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(-1), 36674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck(NO_INIT), 37a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 38a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 39a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 40674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong 41af8e8aa1ada2948972555592570ec9ad90cbf372Nick Kralevich mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); 42674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd >= 0) { 43674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck = OK; 44674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong } 45e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 46e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 47e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::AMRWriter(int fd) 48674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(dup(fd)), 49674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck(mFd < 0? NO_INIT: OK), 50a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 51a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 52a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 53e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 54e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 55e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::~AMRWriter() { 56e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mStarted) { 578bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dong reset(); 58e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 59e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 60674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd != -1) { 61674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 62674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 63e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 64e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 65e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 66e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::initCheck() const { 67e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 68e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 69e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 70e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::addSource(const sp<MediaSource> &source) { 71e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 72e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 73e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 74e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 75e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mSource != NULL) { 76e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber // AMR files only support a single track of audio. 77e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 78e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 79e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 80e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber sp<MetaData> meta = source->getFormat(); 81e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 82e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *mime; 83e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 84e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 85e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber bool isWide = false; 86e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 87e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber isWide = true; 88e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 89e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_UNSUPPORTED; 90e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 91e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 92e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t channelCount; 93e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t sampleRate; 94e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); 95e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(channelCount, 1); 96e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 97e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(sampleRate, (isWide ? 16000 : 8000)); 98e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 99e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mSource = source; 100e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 101e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *kHeader = isWide ? "#!AMR-WB\n" : "#!AMR\n"; 102674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong ssize_t n = strlen(kHeader); 103c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (write(mFd, kHeader, n) != n) { 104e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_IO; 105e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 106e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 107e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 108e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 109e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 11084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t AMRWriter::start(MetaData * /* params */) { 111e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 112e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 113e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 114e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 115a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mSource == NULL) { 116e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 117e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 118e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 119a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mStarted && mPaused) { 120a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = false; 121a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = true; 122a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 123a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } else if (mStarted) { 124a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong // Already started, does nothing 125a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 126a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 127a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 128e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber status_t err = mSource->start(); 129e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 130e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 131e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return err; 132e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 133e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 134e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_t attr; 135e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_init(&attr); 136e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 137e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1382dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = false; 139e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mDone = false; 140e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 141e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_create(&mThread, &attr, ThreadWrapper, this); 142e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_destroy(&attr); 143e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 144e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = true; 145e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 146e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 147e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 148e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 14937187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t AMRWriter::pause() { 150a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (!mStarted) { 15137187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 152a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 153a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = true; 15437187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 155a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong} 156a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 1578bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dongstatus_t AMRWriter::reset() { 158ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber if (!mStarted) { 15937187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 160e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 161e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 162ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber mDone = true; 163ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber 164e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber void *dummy; 165e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_join(mThread, &dummy); 166e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 167377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy)); 16837187916a486504acaf83bea30147eb5fbf46ae5James Dong { 16937187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t status = mSource->stop(); 17037187916a486504acaf83bea30147eb5fbf46ae5James Dong if (err == OK && 17137187916a486504acaf83bea30147eb5fbf46ae5James Dong (status != OK && status != ERROR_END_OF_STREAM)) { 17237187916a486504acaf83bea30147eb5fbf46ae5James Dong err = status; 17337187916a486504acaf83bea30147eb5fbf46ae5James Dong } 17437187916a486504acaf83bea30147eb5fbf46ae5James Dong } 175e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 176e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = false; 17737187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 178e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 179e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 180d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileSizeLimit() { 181d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeLimitBytes == 0) { 182d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 183d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 184d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes; 185d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 186d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 187d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileDurationLimit() { 188d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationLimitUs == 0) { 189d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 190d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 191d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedDurationUs >= mMaxFileDurationLimitUs; 192d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 193d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 194e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber// static 195e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubervoid *AMRWriter::ThreadWrapper(void *me) { 196377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT return (void *)(uintptr_t) static_cast<AMRWriter *>(me)->threadFunc(); 197e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 198e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 19937187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t AMRWriter::threadFunc() { 200d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = 0; 201d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes = 0; 202f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong bool stoppedPrematurely = true; 203a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t previousPausedDurationUs = 0; 204a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t maxTimestampUs = 0; 20537187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t err = OK; 206a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 207a6f61fc8e3d06373c17f0a38ff600e2b71c414faJames Dong prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0); 208ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber while (!mDone) { 209e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber MediaBuffer *buffer; 21037187916a486504acaf83bea30147eb5fbf46ae5James Dong err = mSource->read(&buffer); 211e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 212e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 213e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 214e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 215e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 216a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mPaused) { 217a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer->release(); 218a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer = NULL; 219a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong continue; 220a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 221a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 222d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes += buffer->range_length(); 223d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileSizeLimit()) { 224d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 225d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 226d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 227d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 228d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 229d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 230d599cd4573b5a2d5914c5040e0565ef866749b77James Dong int64_t timestampUs; 231d599cd4573b5a2d5914c5040e0565ef866749b77James Dong CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 232d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (timestampUs > mEstimatedDurationUs) { 233d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = timestampUs; 234d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 235a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mResumed) { 236a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); 237a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = false; 238a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 239a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs -= previousPausedDurationUs; 240a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("time stamp: %" PRId64 ", previous paused duration: %" PRId64, 241a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs, previousPausedDurationUs); 242a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (timestampUs > maxTimestampUs) { 243a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong maxTimestampUs = timestampUs; 244a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 245a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 246d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileDurationLimit()) { 247d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 248d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 249d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 250d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 251d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 252c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong ssize_t n = write(mFd, 253c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong (const uint8_t *)buffer->data() + buffer->range_offset(), 254c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong buffer->range_length()); 255e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 256e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (n < (ssize_t)buffer->range_length()) { 257b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 258b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 259fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong err = ERROR_IO; 260fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong break; 261fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong } 262b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 263fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong if (err != OK) { 264e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 265e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 266b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 267f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong if (stoppedPrematurely) { 268f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong stoppedPrematurely = false; 269f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 270f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 271b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 272b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 273e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 2742dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 275fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong if ((err == OK || err == ERROR_END_OF_STREAM) && stoppedPrematurely) { 276fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong err = ERROR_MALFORMED; 277f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 278f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 279674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 280674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 2812dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = true; 28237187916a486504acaf83bea30147eb5fbf46ae5James Dong if (err == ERROR_END_OF_STREAM) { 28337187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 28437187916a486504acaf83bea30147eb5fbf46ae5James Dong } 28537187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 2862dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 2872dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 2882dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huberbool AMRWriter::reachedEOS() { 2892dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return mReachedEOS; 290e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 291e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 292e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} // namespace android 293