AMRWriter.cpp revision fa514f007bd144eb99cdd68f2fe5302a4508db28
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 17f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 18e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/AMRWriter.h> 19e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaBuffer.h> 20e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaDefs.h> 21e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaErrors.h> 22e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaSource.h> 23e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MetaData.h> 24d599cd4573b5a2d5914c5040e0565ef866749b77James Dong#include <media/mediarecorder.h> 25a6f61fc8e3d06373c17f0a38ff600e2b71c414faJames Dong#include <sys/prctl.h> 26674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <sys/types.h> 27674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <sys/stat.h> 28674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong#include <fcntl.h> 29e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 30e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubernamespace android { 31e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 32e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::AMRWriter(const char *filename) 33674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(-1), 34674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck(NO_INIT), 35a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 36a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 37a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 38674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong 39af8e8aa1ada2948972555592570ec9ad90cbf372Nick Kralevich mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); 40674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd >= 0) { 41674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck = OK; 42674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong } 43e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 44e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 45e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::AMRWriter(int fd) 46674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong : mFd(dup(fd)), 47674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mInitCheck(mFd < 0? NO_INIT: OK), 48a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 49a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 50a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 51e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 52e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 53e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::~AMRWriter() { 54e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mStarted) { 558bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dong reset(); 56e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 57e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 58674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong if (mFd != -1) { 59674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 60674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 61e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 62e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 63e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 64e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::initCheck() const { 65e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 66e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 67e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 68e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::addSource(const sp<MediaSource> &source) { 69e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 70e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 71e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 72e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 73e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mSource != NULL) { 74e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber // AMR files only support a single track of audio. 75e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 76e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 77e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 78e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber sp<MetaData> meta = source->getFormat(); 79e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 80e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *mime; 81e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 82e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 83e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber bool isWide = false; 84e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 85e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber isWide = true; 86e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 87e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_UNSUPPORTED; 88e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 89e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 90e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t channelCount; 91e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t sampleRate; 92e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); 93e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(channelCount, 1); 94e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 95e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(sampleRate, (isWide ? 16000 : 8000)); 96e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 97e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mSource = source; 98e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 99e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *kHeader = isWide ? "#!AMR-WB\n" : "#!AMR\n"; 100674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong ssize_t n = strlen(kHeader); 101c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (write(mFd, kHeader, n) != n) { 102e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_IO; 103e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 104e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 105e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 106e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 107e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1082dec2b5be2056c6d9428897dc672185872d30d17James Dongstatus_t AMRWriter::start(MetaData *params) { 109e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 110e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 111e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 112e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 113a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mSource == NULL) { 114e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 115e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 116e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 117a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mStarted && mPaused) { 118a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = false; 119a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = true; 120a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 121a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } else if (mStarted) { 122a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong // Already started, does nothing 123a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 124a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 125a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 126e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber status_t err = mSource->start(); 127e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 128e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 129e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return err; 130e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 131e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 132e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_t attr; 133e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_init(&attr); 134e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 135e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1362dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = false; 137e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mDone = false; 138e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 139e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_create(&mThread, &attr, ThreadWrapper, this); 140e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_destroy(&attr); 141e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 142e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = true; 143e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 144e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 145e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 146e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 14737187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t AMRWriter::pause() { 148a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (!mStarted) { 14937187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 150a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 151a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = true; 15237187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 153a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong} 154a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 1558bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dongstatus_t AMRWriter::reset() { 156ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber if (!mStarted) { 15737187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 158e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 159e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 160ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber mDone = true; 161ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber 162e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber void *dummy; 163e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_join(mThread, &dummy); 164e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 16537187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t err = (status_t) dummy; 16637187916a486504acaf83bea30147eb5fbf46ae5James Dong { 16737187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t status = mSource->stop(); 16837187916a486504acaf83bea30147eb5fbf46ae5James Dong if (err == OK && 16937187916a486504acaf83bea30147eb5fbf46ae5James Dong (status != OK && status != ERROR_END_OF_STREAM)) { 17037187916a486504acaf83bea30147eb5fbf46ae5James Dong err = status; 17137187916a486504acaf83bea30147eb5fbf46ae5James Dong } 17237187916a486504acaf83bea30147eb5fbf46ae5James Dong } 173e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 174e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = false; 17537187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 176e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 177e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 178d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileSizeLimit() { 179d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeLimitBytes == 0) { 180d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 181d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 182d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes; 183d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 184d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 185d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileDurationLimit() { 186d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationLimitUs == 0) { 187d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 188d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 189d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedDurationUs >= mMaxFileDurationLimitUs; 190d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 191d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 192e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber// static 193e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubervoid *AMRWriter::ThreadWrapper(void *me) { 19437187916a486504acaf83bea30147eb5fbf46ae5James Dong return (void *) static_cast<AMRWriter *>(me)->threadFunc(); 195e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 196e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 19737187916a486504acaf83bea30147eb5fbf46ae5James Dongstatus_t AMRWriter::threadFunc() { 198d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = 0; 199d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes = 0; 200f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong bool stoppedPrematurely = true; 201a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t previousPausedDurationUs = 0; 202a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t maxTimestampUs = 0; 20337187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t err = OK; 204a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 205a6f61fc8e3d06373c17f0a38ff600e2b71c414faJames Dong prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0); 206ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber while (!mDone) { 207e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber MediaBuffer *buffer; 20837187916a486504acaf83bea30147eb5fbf46ae5James Dong err = mSource->read(&buffer); 209e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 210e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 211e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 212e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 213e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 214a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mPaused) { 215a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer->release(); 216a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer = NULL; 217a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong continue; 218a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 219a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 220d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes += buffer->range_length(); 221d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileSizeLimit()) { 222d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 223d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 224d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 225d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 226d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 227d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 228d599cd4573b5a2d5914c5040e0565ef866749b77James Dong int64_t timestampUs; 229d599cd4573b5a2d5914c5040e0565ef866749b77James Dong CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 230d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (timestampUs > mEstimatedDurationUs) { 231d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = timestampUs; 232d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 233a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mResumed) { 234a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); 235a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = false; 236a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 237a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs -= previousPausedDurationUs; 2383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("time stamp: %lld, previous paused duration: %lld", 239a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs, previousPausedDurationUs); 240a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (timestampUs > maxTimestampUs) { 241a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong maxTimestampUs = timestampUs; 242a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 243a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 244d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileDurationLimit()) { 245d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 246d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 247d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 248d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 249d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 250c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong ssize_t n = write(mFd, 251c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong (const uint8_t *)buffer->data() + buffer->range_offset(), 252c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong buffer->range_length()); 253e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 254e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (n < (ssize_t)buffer->range_length()) { 255b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 256b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 257fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong err = ERROR_IO; 258fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong break; 259fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong } 260b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 261fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong if (err != OK) { 262e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 263e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 264b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 265f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong if (stoppedPrematurely) { 266f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong stoppedPrematurely = false; 267f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 268f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 269b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 270b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 271e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 2722dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 273fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong if ((err == OK || err == ERROR_END_OF_STREAM) && stoppedPrematurely) { 274fa514f007bd144eb99cdd68f2fe5302a4508db28James Dong err = ERROR_MALFORMED; 275f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 276f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 277674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong close(mFd); 278674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mFd = -1; 2792dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = true; 28037187916a486504acaf83bea30147eb5fbf46ae5James Dong if (err == ERROR_END_OF_STREAM) { 28137187916a486504acaf83bea30147eb5fbf46ae5James Dong return OK; 28237187916a486504acaf83bea30147eb5fbf46ae5James Dong } 28337187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 2842dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 2852dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 2862dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huberbool AMRWriter::reachedEOS() { 2872dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return mReachedEOS; 288e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 289e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 290e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} // namespace android 291