aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java')
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java116
1 files changed, 24 insertions, 92 deletions
diff --git a/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java b/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
index 0be29f25..6ec55e4f 100644
--- a/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
+++ b/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
@@ -33,17 +33,13 @@ import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.util.Log;
-import android.util.Pair;
-import com.google.android.exoplayer.C;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.recording.RecordingCapability;
import com.android.tv.dvr.DvrStorageStatusManager;
-import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.RecordedProgram;
import com.android.tv.tuner.DvbDeviceAccessor;
import com.android.tv.tuner.data.PsipData;
-import com.android.tv.tuner.data.PsipData.EitItem;
-import com.android.tv.tuner.data.Track.AtscCaptionTrack;
import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.exoplayer.ExoPlayerSampleExtractor;
import com.android.tv.tuner.exoplayer.SampleExtractor;
@@ -57,10 +53,10 @@ import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
@@ -75,7 +71,6 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
private static final String SORT_BY_TIME = TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS
+ ", " + TvContract.Programs.COLUMN_CHANNEL_ID + ", "
+ TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS;
- private static final long TUNING_RETRY_INTERVAL_MS = TimeUnit.SECONDS.toMillis(4);
private static final long STORAGE_MONITOR_INTERVAL_MS = TimeUnit.SECONDS.toMillis(4);
private static final long MIN_PARTIAL_RECORDING_DURATION_MS = TimeUnit.SECONDS.toMillis(10);
private static final long PREPARE_RECORDER_POLL_MS = 50;
@@ -85,23 +80,20 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
private static final int MSG_STOP_RECORDING = 4;
private static final int MSG_MONITOR_STORAGE_STATUS = 5;
private static final int MSG_RELEASE = 6;
- private static final int MSG_UPDATE_CC_INFO = 7;
private final RecordingCapability mCapabilities;
public RecordingCapability getCapabilities() {
return mCapabilities;
}
- @IntDef({STATE_IDLE, STATE_TUNING, STATE_TUNED, STATE_RECORDING})
+ @IntDef({STATE_IDLE, STATE_TUNED, STATE_RECORDING})
@Retention(RetentionPolicy.SOURCE)
public @interface DvrSessionState {}
private static final int STATE_IDLE = 1;
- private static final int STATE_TUNING = 2;
- private static final int STATE_TUNED = 3;
- private static final int STATE_RECORDING = 4;
+ private static final int STATE_TUNED = 2;
+ private static final int STATE_RECORDING = 3;
private static final long CHANNEL_ID_NONE = -1;
- private static final int MAX_TUNING_RETRY = 6;
private final Context mContext;
private final ChannelDataManager mChannelDataManager;
@@ -116,16 +108,13 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
private long mRecordStartTime;
private long mRecordEndTime;
private boolean mRecorderRunning;
+ private BufferManager mBufferManager;
private SampleExtractor mRecorder;
private final TunerRecordingSession mSession;
@DvrSessionState private int mSessionState = STATE_IDLE;
private final String mInputId;
private Uri mProgramUri;
- private PsipData.EitItem mCurrenProgram;
- private List<AtscCaptionTrack> mCaptionTracks;
- private DvrStorageManager mDvrStorageManager;
-
public TunerRecordingSessionWorker(Context context, String inputId,
ChannelDataManager dataManager, TunerRecordingSession session) {
mRandom.setSeed(System.nanoTime());
@@ -168,7 +157,6 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
if (mChannel == null || mChannel.compareTo(channel) != 0) {
return;
}
- mHandler.obtainMessage(MSG_UPDATE_CC_INFO, new Pair<>(channel, items)).sendToTarget();
mChannelDataManager.notifyEventDetected(channel, items);
}
@@ -190,7 +178,7 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
@MainThread
public void tune(Uri channelUri) {
mHandler.removeCallbacksAndMessages(null);
- mHandler.obtainMessage(MSG_TUNE, 0, 0, channelUri).sendToTarget();
+ mHandler.obtainMessage(MSG_TUNE, channelUri).sendToTarget();
}
/**
@@ -223,22 +211,11 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
switch (msg.what) {
case MSG_TUNE: {
Uri channelUri = (Uri) msg.obj;
- int retryCount = msg.arg1;
if (DEBUG) Log.d(TAG, "Tune to " + channelUri);
if (doTune(channelUri)) {
- if (mSessionState == STATE_TUNED) {
- mSession.onTuned(channelUri);
- } else {
- Log.w(TAG, "Tuner stream cannot be created due to resource shortage.");
- if (retryCount < MAX_TUNING_RETRY) {
- Message tuneMsg =
- mHandler.obtainMessage(MSG_TUNE, retryCount + 1, 0, channelUri);
- mHandler.sendMessageDelayed(tuneMsg, TUNING_RETRY_INTERVAL_MS);
- } else {
- mSession.onError(TvInputManager.RECORDING_ERROR_RESOURCE_BUSY);
- reset();
- }
- }
+ mSession.onTuned(channelUri);
+ } else {
+ reset();
}
return true;
}
@@ -304,12 +281,6 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
mHandler.getLooper().quitSafely();
return true;
}
- case MSG_UPDATE_CC_INFO: {
- Pair<TunerChannel, List<EitItem>> pair =
- (Pair<TunerChannel, List<EitItem>>) msg.obj;
- updateCaptionTracks(pair.first, pair.second);
- return true;
- }
}
return false;
}
@@ -339,17 +310,20 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
mRecorder.release();
mRecorder = null;
}
+ if (mBufferManager != null) {
+ mBufferManager.close();
+ mBufferManager = null;
+ }
if (mTunerSource != null) {
mSourceManager.releaseDataSource(mTunerSource);
mTunerSource = null;
}
- mDvrStorageManager = null;
mSessionState = STATE_IDLE;
mRecorderRunning = false;
}
private boolean doTune(Uri channelUri) {
- if (mSessionState != STATE_IDLE && mSessionState != STATE_TUNING) {
+ if (mSessionState != STATE_IDLE) {
mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
Log.e(TAG, "Tuning was requested from wrong status.");
return false;
@@ -359,10 +333,6 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
Log.w(TAG, "Failed to start recording. Couldn't find the channel for " + mChannel);
return false;
- } else if (mChannel.isRecordingProhibited()) {
- mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
- Log.w(TAG, "Failed to start recording. Not a recordable channel: " + mChannel);
- return false;
}
if (!mDvrStorageStatusManager.isStorageSufficient()) {
mSession.onError(TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
@@ -371,9 +341,9 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
}
mTunerSource = mSourceManager.createDataSource(mContext, mChannel, this);
if (mTunerSource == null) {
- // Retry tuning in this case.
- mSessionState = STATE_TUNING;
- return true;
+ mSession.onError(TvInputManager.RECORDING_ERROR_RESOURCE_BUSY);
+ Log.w(TAG, "Tuner stream cannot be created due to resource shortage.");
+ return false;
}
mSessionState = STATE_TUNED;
return true;
@@ -395,10 +365,10 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
}
// Since tuning might be happened a while ago, shifts the start position of tuned source.
mTunerSource.shiftStartPosition(mTunerSource.getBufferedPosition());
+ mBufferManager = new BufferManager(new DvrStorageManager(mStorageDir, true));
mRecordStartTime = System.currentTimeMillis();
- mDvrStorageManager = new DvrStorageManager(mStorageDir, true);
- mRecorder = new ExoPlayerSampleExtractor(Uri.EMPTY, mTunerSource,
- new BufferManager(mDvrStorageManager), this, true);
+ mRecorder = new ExoPlayerSampleExtractor(Uri.EMPTY, mTunerSource, mBufferManager, this,
+ true);
mRecorder.setOnCompletionListener(this, mHandler);
mProgramUri = programUri;
mSessionState = STATE_RECORDING;
@@ -422,34 +392,6 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
Log.i(TAG, "Recording stopped");
}
- private void updateCaptionTracks(TunerChannel channel, List<PsipData.EitItem> items) {
- if (mChannel == null || channel == null || mChannel.compareTo(channel) != 0
- || items == null || items.isEmpty()) {
- return;
- }
- PsipData.EitItem currentProgram = getCurrentProgram(items);
- if (currentProgram == null || !currentProgram.hasCaptionTrack()
- || mCurrenProgram != null && mCurrenProgram.compareTo(currentProgram) == 0) {
- return;
- }
- mCurrenProgram = currentProgram;
- mCaptionTracks = new ArrayList<>(currentProgram.getCaptionTracks());
- if (DEBUG) {
- Log.d(TAG, "updated " + mCaptionTracks.size() + " caption tracks for "
- + currentProgram);
- }
- }
-
- private PsipData.EitItem getCurrentProgram(List<PsipData.EitItem> items) {
- for (PsipData.EitItem item : items) {
- if (mRecordStartTime >= item.getStartTimeUtcMillis()
- && mRecordStartTime < item.getEndTimeUtcMillis()) {
- return item;
- }
- }
- return null;
- }
-
private static class Program {
private final long mChannelId;
private final String mTitle;
@@ -624,25 +566,15 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
return;
}
Log.i(TAG, "recording finished " + (success ? "completely" : "partially"));
- long recordEndTime =
- (lastExtractedPositionUs == C.UNKNOWN_TIME_US)
- ? System.currentTimeMillis()
- : mRecordStartTime + lastExtractedPositionUs / 1000;
- Uri uri =
- insertRecordedProgram(
- getRecordedProgram(),
- mChannel.getChannelId(),
- Uri.fromFile(mStorageDir).toString(),
- 1024 * 1024,
- mRecordStartTime,
- recordEndTime);
+ Uri uri = insertRecordedProgram(getRecordedProgram(), mChannel.getChannelId(),
+ Uri.fromFile(mStorageDir).toString(), 1024 * 1024, mRecordStartTime,
+ mRecordStartTime + TimeUnit.MICROSECONDS.toMillis(lastExtractedPositionUs));
if (uri == null) {
new DeleteRecordingTask().execute(mStorageDir);
mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
Log.e(TAG, "Inserting a recording to DB failed");
return;
}
- mDvrStorageManager.writeCaptionInfoFiles(mCaptionTracks);
mSession.onRecordFinished(uri);
}