aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java')
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java115
1 files changed, 30 insertions, 85 deletions
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java b/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
index ca97a91a..37ae4022 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
@@ -21,7 +21,6 @@ import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
-import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
@@ -32,9 +31,7 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer.BufferReason;
import java.io.IOException;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
@@ -49,13 +46,11 @@ public class SampleChunkIoHelper implements Handler.Callback {
private static final int MSG_OPEN_READ = 1;
private static final int MSG_OPEN_WRITE = 2;
- private static final int MSG_CLOSE_READ = 3;
- private static final int MSG_CLOSE_WRITE = 4;
- private static final int MSG_READ = 5;
- private static final int MSG_WRITE = 6;
- private static final int MSG_RELEASE = 7;
+ private static final int MSG_CLOSE_WRITE = 3;
+ private static final int MSG_READ = 4;
+ private static final int MSG_WRITE = 5;
+ private static final int MSG_RELEASE = 6;
- private final long mSampleChunkDurationUs;
private final int mTrackCount;
private final List<String> mIds;
private final List<MediaFormat> mMediaFormats;
@@ -67,11 +62,9 @@ public class SampleChunkIoHelper implements Handler.Callback {
private Handler mIoHandler;
private final ConcurrentLinkedQueue<SampleHolder> mReadSampleBuffers[];
private final ConcurrentLinkedQueue<SampleHolder> mHandlerReadSampleBuffers[];
- private final long[] mWriteIndexEndPositionUs;
- private final long[] mWriteChunkEndPositionUs;
+ private final long[] mWriteEndPositionUs;
private final SampleChunk.IoState[] mReadIoStates;
private final SampleChunk.IoState[] mWriteIoStates;
- private final Set<Integer> mSelectedTracks = new ArraySet<>();
private long mBufferDurationUs = 0;
private boolean mWriteEnded;
private boolean mErrorNotified;
@@ -136,20 +129,11 @@ public class SampleChunkIoHelper implements Handler.Callback {
mReadSampleBuffers = new ConcurrentLinkedQueue[mTrackCount];
mHandlerReadSampleBuffers = new ConcurrentLinkedQueue[mTrackCount];
- mWriteIndexEndPositionUs = new long[mTrackCount];
- mWriteChunkEndPositionUs = new long[mTrackCount];
+ mWriteEndPositionUs = new long[mTrackCount];
mReadIoStates = new SampleChunk.IoState[mTrackCount];
mWriteIoStates = new SampleChunk.IoState[mTrackCount];
-
- // Small chunk duration for live playback will give more fine grained storage usage
- // and eviction handling for trickplay.
- mSampleChunkDurationUs =
- bufferReason == RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK ?
- RecordingSampleBuffer.MIN_SEEK_DURATION_US :
- RecordingSampleBuffer.RECORDING_CHUNK_DURATION_US;
for (int i = 0; i < mTrackCount; ++i) {
- mWriteIndexEndPositionUs[i] = RecordingSampleBuffer.MIN_SEEK_DURATION_US;
- mWriteChunkEndPositionUs[i] = mSampleChunkDurationUs;
+ mWriteEndPositionUs[i] = RecordingSampleBuffer.CHUNK_DURATION_US;
mReadIoStates[i] = new SampleChunk.IoState();
mWriteIoStates[i] = new SampleChunk.IoState();
}
@@ -220,15 +204,6 @@ public class SampleChunkIoHelper implements Handler.Callback {
}
/**
- * Closes read from the specified track.
- *
- * @param index track index
- */
- public void closeRead(int index) {
- mIoHandler.sendMessage(mIoHandler.obtainMessage(MSG_CLOSE_READ, index));
- }
-
- /**
* Notifies writes are finished.
*/
public void closeWrite() {
@@ -254,19 +229,21 @@ public class SampleChunkIoHelper implements Handler.Callback {
try {
if (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING && mTrackCount > 0) {
// Saves meta information for recording.
- List<BufferManager.TrackFormat> audios = new LinkedList<>();
- List<BufferManager.TrackFormat> videos = new LinkedList<>();
+ Pair<String, android.media.MediaFormat> audio = null, video = null;
for (int i = 0; i < mTrackCount; ++i) {
android.media.MediaFormat format =
mMediaFormats.get(i).getFrameworkMediaFormatV16();
format.setLong(android.media.MediaFormat.KEY_DURATION, mBufferDurationUs);
- if (MimeTypes.isAudio(mMediaFormats.get(i).mimeType)) {
- audios.add(new BufferManager.TrackFormat(mIds.get(i), format));
- } else if (MimeTypes.isVideo(mMediaFormats.get(i).mimeType)) {
- videos.add(new BufferManager.TrackFormat(mIds.get(i), format));
+ if (audio == null && MimeTypes.isAudio(mMediaFormats.get(i).mimeType)) {
+ audio = new Pair<>(mIds.get(i), format);
+ } else if (video == null && MimeTypes.isVideo(mMediaFormats.get(i).mimeType)) {
+ video = new Pair<>(mIds.get(i), format);
+ }
+ if (audio != null && video != null) {
+ break;
}
}
- mBufferManager.writeMetaFiles(audios, videos);
+ mBufferManager.writeMetaFiles(audio, video);
}
} finally {
mBufferManager.release();
@@ -288,9 +265,6 @@ public class SampleChunkIoHelper implements Handler.Callback {
case MSG_OPEN_WRITE:
doOpenWrite((int) message.obj);
return true;
- case MSG_CLOSE_READ:
- doCloseRead((int) message.obj);
- return true;
case MSG_CLOSE_WRITE:
doCloseWrite();
return true;
@@ -317,16 +291,14 @@ public class SampleChunkIoHelper implements Handler.Callback {
private void doOpenRead(IoParams params) throws IOException {
int index = params.index;
mIoHandler.removeMessages(MSG_READ, index);
- Pair<SampleChunk, Integer> readPosition =
- mBufferManager.getReadFile(mIds.get(index), params.positionUs);
- if (readPosition == null) {
+ SampleChunk chunk = mBufferManager.getReadFile(mIds.get(index), params.positionUs);
+ if (chunk == null) {
String errorMessage = "Chunk ID:" + mIds.get(index) + " pos:" + params.positionUs
+ "is not found";
- SoftPreconditions.checkNotNull(readPosition, TAG, errorMessage);
+ SoftPreconditions.checkNotNull(chunk, TAG, errorMessage);
throw new IOException(errorMessage);
}
- mSelectedTracks.add(index);
- mReadIoStates[index].openRead(readPosition.first, (long) readPosition.second);
+ mReadIoStates[index].openRead(chunk);
if (mHandlerReadSampleBuffers[index] != null) {
SampleHolder sample;
while ((sample = mHandlerReadSampleBuffers[index].poll()) != null) {
@@ -338,22 +310,10 @@ public class SampleChunkIoHelper implements Handler.Callback {
}
private void doOpenWrite(int index) throws IOException {
- SampleChunk chunk = mBufferManager.createNewWriteFileIfNeeded(mIds.get(index), 0,
- mSamplePool, null, 0);
+ SampleChunk chunk = mBufferManager.createNewWriteFile(mIds.get(index), 0, mSamplePool);
mWriteIoStates[index].openWrite(chunk);
}
- private void doCloseRead(int index) {
- mSelectedTracks.remove(index);
- if (mHandlerReadSampleBuffers[index] != null) {
- SampleHolder sample;
- while ((sample = mHandlerReadSampleBuffers[index].poll()) != null) {
- mSamplePool.releaseSample(sample);
- }
- }
- mIoHandler.removeMessages(MSG_READ, index);
- }
-
private void doRead(int index) throws IOException {
mIoHandler.removeMessages(MSG_READ, index);
if (mHandlerReadSampleBuffers[index].size() >= MAX_READ_BUFFER_SAMPLES) {
@@ -397,21 +357,13 @@ public class SampleChunkIoHelper implements Handler.Callback {
if (sample.timeUs > mBufferDurationUs) {
mBufferDurationUs = sample.timeUs;
}
- if (sample.timeUs >= mWriteIndexEndPositionUs[index]) {
- SampleChunk currentChunk = sample.timeUs >= mWriteChunkEndPositionUs[index] ?
- null : mWriteIoStates[params.index].getChunk();
- int currentOffset = (int) mWriteIoStates[params.index].getOffset();
- nextChunk = mBufferManager.createNewWriteFileIfNeeded(
- mIds.get(index), mWriteIndexEndPositionUs[index], mSamplePool,
- currentChunk, currentOffset);
- mWriteIndexEndPositionUs[index] =
- ((sample.timeUs / RecordingSampleBuffer.MIN_SEEK_DURATION_US) + 1) *
- RecordingSampleBuffer.MIN_SEEK_DURATION_US;
- if (nextChunk != null) {
- mWriteChunkEndPositionUs[index] =
- ((sample.timeUs / mSampleChunkDurationUs) + 1)
- * mSampleChunkDurationUs;
- }
+
+ if (sample.timeUs >= mWriteEndPositionUs[index]) {
+ nextChunk = mBufferManager.createNewWriteFile(mIds.get(index),
+ mWriteEndPositionUs[index], mSamplePool);
+ mWriteEndPositionUs[index] =
+ ((sample.timeUs / RecordingSampleBuffer.CHUNK_DURATION_US) + 1) *
+ RecordingSampleBuffer.CHUNK_DURATION_US;
}
}
mWriteIoStates[params.index].write(params.sample, nextChunk);
@@ -439,22 +391,15 @@ public class SampleChunkIoHelper implements Handler.Callback {
mIoHandler.removeCallbacksAndMessages(null);
mFinished = true;
conditionVariable.open();
- mSelectedTracks.clear();
}
private void releaseEvictedChunks() {
- if (mBufferReason != RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK
- || mSelectedTracks.isEmpty()) {
+ if (mBufferReason != RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK) {
return;
}
- long currentStartPositionUs = Long.MAX_VALUE;
- for (int trackIndex : mSelectedTracks) {
- currentStartPositionUs = Math.min(currentStartPositionUs,
- mReadIoStates[trackIndex].getStartPositionUs());
- }
for (int i = 0; i < mTrackCount; ++i) {
long evictEndPositionUs = Math.min(mBufferManager.getStartPositionUs(mIds.get(i)),
- currentStartPositionUs);
+ mReadIoStates[i].getStartPositionUs());
mBufferManager.evictChunks(mIds.get(i), evictEndPositionUs);
}
}