AMRWriter.cpp revision 2dec2b5be2056c6d9428897dc672185872d30d17
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 17e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/AMRWriter.h> 18e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 19e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaBuffer.h> 20e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaDebug.h> 21e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaDefs.h> 22e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaErrors.h> 23e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaSource.h> 24e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MetaData.h> 25d599cd4573b5a2d5914c5040e0565ef866749b77James Dong#include <media/mediarecorder.h> 26e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 27e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubernamespace android { 28e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 29e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::AMRWriter(const char *filename) 30e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber : mFile(fopen(filename, "wb")), 31e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mInitCheck(mFile != NULL ? OK : NO_INIT), 32a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 33a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 34a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 35e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 36e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 37e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::AMRWriter(int fd) 38e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber : mFile(fdopen(fd, "wb")), 39e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mInitCheck(mFile != NULL ? OK : NO_INIT), 40a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mStarted(false), 41a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused(false), 42a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed(false) { 43e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 44e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 45e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAMRWriter::~AMRWriter() { 46e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mStarted) { 47e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber stop(); 48e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 49e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 50e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mFile != NULL) { 51e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber fclose(mFile); 52e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mFile = NULL; 53e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 54e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 55e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 56e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::initCheck() const { 57e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 58e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 59e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 60e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AMRWriter::addSource(const sp<MediaSource> &source) { 61e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 62e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 63e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 64e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 65e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mSource != NULL) { 66e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber // AMR files only support a single track of audio. 67e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 68e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 69e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 70e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber sp<MetaData> meta = source->getFormat(); 71e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 72e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *mime; 73e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 74e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 75e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber bool isWide = false; 76e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 77e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber isWide = true; 78e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 79e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_UNSUPPORTED; 80e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 81e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 82e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t channelCount; 83e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber int32_t sampleRate; 84e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); 85e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(channelCount, 1); 86e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 87e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber CHECK_EQ(sampleRate, (isWide ? 16000 : 8000)); 88e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 89e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mSource = source; 90e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 91e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber const char *kHeader = isWide ? "#!AMR-WB\n" : "#!AMR\n"; 92e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber size_t n = strlen(kHeader); 93e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (fwrite(kHeader, 1, n, mFile) != n) { 94e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return ERROR_IO; 95e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 96e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 97e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 98e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 99e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1002dec2b5be2056c6d9428897dc672185872d30d17James Dongstatus_t AMRWriter::start(MetaData *params) { 101e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mInitCheck != OK) { 102e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 103e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 104e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 105a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mSource == NULL) { 106e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 107e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 108e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 109a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mStarted && mPaused) { 110a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = false; 111a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = true; 112a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 113a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } else if (mStarted) { 114a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong // Already started, does nothing 115a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 116a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 117a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 118e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber status_t err = mSource->start(); 119e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 120e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 121e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return err; 122e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 123e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 124e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_t attr; 125e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_init(&attr); 126e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 127e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1282dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = false; 129e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mDone = false; 130e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 131e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_create(&mThread, &attr, ThreadWrapper, this); 132e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_attr_destroy(&attr); 133e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 134e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = true; 135e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 136e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 137e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 138e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 139a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dongvoid AMRWriter::pause() { 140a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (!mStarted) { 141a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return; 142a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 143a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mPaused = true; 144a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong} 145a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 146e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubervoid AMRWriter::stop() { 147ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber if (!mStarted) { 148ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber return; 149e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 150e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 151ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber mDone = true; 152ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber 153e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber void *dummy; 154e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber pthread_join(mThread, &dummy); 155e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 156e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mSource->stop(); 157e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 158e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = false; 159e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 160e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 161d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileSizeLimit() { 162d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeLimitBytes == 0) { 163d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 164d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 165d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedSizeBytes >= mMaxFileSizeLimitBytes; 166d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 167d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 168d599cd4573b5a2d5914c5040e0565ef866749b77James Dongbool AMRWriter::exceedsFileDurationLimit() { 169d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationLimitUs == 0) { 170d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return false; 171d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 172d599cd4573b5a2d5914c5040e0565ef866749b77James Dong return mEstimatedDurationUs >= mMaxFileDurationLimitUs; 173d599cd4573b5a2d5914c5040e0565ef866749b77James Dong} 174d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 175e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber// static 176e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubervoid *AMRWriter::ThreadWrapper(void *me) { 177e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber static_cast<AMRWriter *>(me)->threadFunc(); 178e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 179e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return NULL; 180e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 181e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 182e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubervoid AMRWriter::threadFunc() { 183d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = 0; 184d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes = 0; 185f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong bool stoppedPrematurely = true; 186a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t previousPausedDurationUs = 0; 187a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong int64_t maxTimestampUs = 0; 188a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 189ebe87f32e442c9a8fb2931632311d6c5a126eddbAndreas Huber while (!mDone) { 190e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber MediaBuffer *buffer; 191e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber status_t err = mSource->read(&buffer); 192e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 193e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err != OK) { 194e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 195e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 196e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 197a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mPaused) { 198a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer->release(); 199a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong buffer = NULL; 200a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong continue; 201a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 202a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 203d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedSizeBytes += buffer->range_length(); 204d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileSizeLimit()) { 205d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 206d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 207d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 208d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 209d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 210d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 211d599cd4573b5a2d5914c5040e0565ef866749b77James Dong int64_t timestampUs; 212d599cd4573b5a2d5914c5040e0565ef866749b77James Dong CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 213d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (timestampUs > mEstimatedDurationUs) { 214d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mEstimatedDurationUs = timestampUs; 215d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 216a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mResumed) { 217a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong previousPausedDurationUs += (timestampUs - maxTimestampUs - 20000); 218a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mResumed = false; 219a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 220a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs -= previousPausedDurationUs; 221a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong LOGV("time stamp: %lld, previous paused duration: %lld", 222a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong timestampUs, previousPausedDurationUs); 223a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (timestampUs > maxTimestampUs) { 224a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong maxTimestampUs = timestampUs; 225a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 226a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 227d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (exceedsFileDurationLimit()) { 228d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer->release(); 229d599cd4573b5a2d5914c5040e0565ef866749b77James Dong buffer = NULL; 230d599cd4573b5a2d5914c5040e0565ef866749b77James Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 231d599cd4573b5a2d5914c5040e0565ef866749b77James Dong break; 232d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 233e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber ssize_t n = fwrite( 234e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(), 235e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1, 236e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber buffer->range_length(), 237e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mFile); 238e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 239e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (n < (ssize_t)buffer->range_length()) { 240b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 241b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 242b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 243e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber break; 244e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 245b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 246f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong // XXX: How to tell it is stopped prematurely? 247f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong if (stoppedPrematurely) { 248f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong stoppedPrematurely = false; 249f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 250f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 251b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer->release(); 252b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber buffer = NULL; 253e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 2542dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 255f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong if (stoppedPrematurely) { 256f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_STOP_PREMATURELY, 0); 257f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong } 258f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong 259f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong fflush(mFile); 260f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong fclose(mFile); 261f0ce2fb0c7bf3a414279e5aba61105f3d9025c0eJames Dong mFile = NULL; 2622dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mReachedEOS = true; 2632dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 2642dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 2652dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huberbool AMRWriter::reachedEOS() { 2662dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return mReachedEOS; 267e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 268e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 269e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} // namespace android 270