summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2011-02-09 14:00:55 -0800
committerJames Dong <jdong@google.com>2011-02-09 15:44:32 -0800
commitfcac8fa9421f442f024018628a6042d7a14fbfb0 (patch)
tree329336bc5a1c31ac94737aa4e25a992a0b87f482 /media
parent722555f01ace262c2aba9e1ca5d9794ce30c564f (diff)
downloadframeworks_av-fcac8fa9421f442f024018628a6042d7a14fbfb0.zip
frameworks_av-fcac8fa9421f442f024018628a6042d7a14fbfb0.tar.gz
frameworks_av-fcac8fa9421f442f024018628a6042d7a14fbfb0.tar.bz2
Reduce blocking time in file write
bug - 3418787 Change-Id: I4723662bf46ed07271be8468f84ae5d93cb793fa
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/MPEG4Writer.cpp86
1 files changed, 49 insertions, 37 deletions
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index d1a497f..b11789d 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1122,41 +1122,41 @@ void MPEG4Writer::bufferChunk(const Chunk& chunk) {
CHECK("Received a chunk for a unknown track" == 0);
}
-void MPEG4Writer::writeFirstChunk(ChunkInfo* info) {
- LOGV("writeFirstChunk: %p", info->mTrack);
-
- List<Chunk>::iterator chunkIt = info->mChunks.begin();
- for (List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin();
- it != chunkIt->mSamples.end(); ++it) {
-
- off64_t offset = info->mTrack->isAvc()
- ? addLengthPrefixedSample_l(*it)
- : addSample_l(*it);
- if (it == chunkIt->mSamples.begin()) {
- info->mTrack->addChunkOffset(offset);
+void MPEG4Writer::writeChunkToFile(Chunk* chunk) {
+ LOGV("writeChunkToFile: %lld from %s track",
+ chunk.mTimestampUs, chunk.mTrack->isAudio()? "audio": "video");
+
+ int32_t isFirstSample = true;
+ while (!chunk->mSamples.empty()) {
+ List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
+
+ off64_t offset = chunk->mTrack->isAvc()
+ ? addLengthPrefixedSample_l(*it)
+ : addSample_l(*it);
+
+ if (isFirstSample) {
+ chunk->mTrack->addChunkOffset(offset);
+ isFirstSample = false;
}
- }
- // Done with the current chunk.
- // Release all the samples in this chunk.
- while (!chunkIt->mSamples.empty()) {
- List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin();
(*it)->release();
(*it) = NULL;
- chunkIt->mSamples.erase(it);
+ chunk->mSamples.erase(it);
}
- chunkIt->mSamples.clear();
- info->mChunks.erase(chunkIt);
+ chunk->mSamples.clear();
}
-void MPEG4Writer::writeChunks() {
- LOGV("writeChunks");
+void MPEG4Writer::writeAllChunks() {
+ LOGV("writeAllChunks");
size_t outstandingChunks = 0;
while (!mChunkInfos.empty()) {
List<ChunkInfo>::iterator it = mChunkInfos.begin();
while (!it->mChunks.empty()) {
- CHECK_EQ(OK, writeOneChunk());
- ++outstandingChunks;
+ Chunk chunk;
+ if (findChunkToWrite(&chunk)) {
+ writeChunkToFile(&chunk);
+ ++outstandingChunks;
+ }
}
it->mTrack = NULL;
mChunkInfos.erase(it);
@@ -1165,8 +1165,8 @@ void MPEG4Writer::writeChunks() {
LOGD("%d chunks are written in the last batch", outstandingChunks);
}
-status_t MPEG4Writer::writeOneChunk() {
- LOGV("writeOneChunk");
+bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
+ LOGV("findChunkToWrite");
// Find the smallest timestamp, and write that chunk out
// XXX: What if some track is just too slow?
@@ -1185,38 +1185,50 @@ status_t MPEG4Writer::writeOneChunk() {
if (track == NULL) {
LOGV("Nothing to be written after all");
- return OK;
+ return false;
}
if (mIsFirstChunk) {
mIsFirstChunk = false;
}
+
for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
it != mChunkInfos.end(); ++it) {
if (it->mTrack == track) {
- writeFirstChunk(&(*it));
+ *chunk = *(it->mChunks.begin());
+ it->mChunks.erase(it->mChunks.begin());
+ CHECK_EQ(chunk->mTrack, track);
+ return true;
}
}
- return OK;
+
+ return false;
}
void MPEG4Writer::threadFunc() {
LOGV("threadFunc");
prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
+
+ Mutex::Autolock autoLock(mLock);
while (!mDone) {
- {
- Mutex::Autolock autolock(mLock);
+ Chunk chunk;
+ bool chunkFound = false;
+
+ while (!mDone && !(chunkFound = findChunkToWrite(&chunk))) {
mChunkReadyCondition.wait(mLock);
- CHECK_EQ(writeOneChunk(), OK);
}
- }
- {
- // Write ALL samples
- Mutex::Autolock autolock(mLock);
- writeChunks();
+ // Actual write without holding the lock in order to
+ // reduce the blocking time for media track threads.
+ if (chunkFound) {
+ mLock.unlock();
+ writeChunkToFile(&chunk);
+ mLock.lock();
+ }
}
+
+ writeAllChunks();
}
status_t MPEG4Writer::startWriterThread() {