Skip to content

Commit

Permalink
Correct ScreenRecorder signalStop()
Browse files Browse the repository at this point in the history
  • Loading branch information
yrom committed Dec 5, 2017
1 parent 7bdf6f1 commit 951f702
Showing 1 changed file with 48 additions and 26 deletions.
74 changes: 48 additions & 26 deletions app/src/main/java/net/yrom/screenrecorder/ScreenRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
public class ScreenRecorder {
private static final String TAG = "ScreenRecorder";
private static final boolean VERBOSE = false;
private static final int INVALID_INDEX = -1;
static final String VIDEO_AVC = MIMETYPE_VIDEO_AVC; // H.264 Advanced Video Coding
static final String AUDIO_AAC = MIMETYPE_AUDIO_AAC; // H.264 Advanced Audio Coding
private int mWidth;
Expand All @@ -53,7 +54,7 @@ public class ScreenRecorder {
private MicRecorder mAudioEncoder;

private MediaFormat mVideoOutputFormat = null, mAudioOutputFormat = null;
private int mVideoTrackIndex = -1, mAudioTrackIndex = -1;
private int mVideoTrackIndex = INVALID_INDEX, mAudioTrackIndex = INVALID_INDEX;
private MediaMuxer mMuxer;
private boolean mMuxerStarted = false;

Expand Down Expand Up @@ -101,7 +102,7 @@ public final void quit() {
if (!mIsRunning.get()) {
release();
} else {
signalStop();
signalStop(false);
}

}
Expand Down Expand Up @@ -134,6 +135,7 @@ interface Callback {
private static final int MSG_STOP = 1;
private static final int MSG_ERROR = 2;
private static final int STOP_WITH_EOS = 1;

private class CallbackHandler extends Handler {
CallbackHandler(Looper looper) {
super(looper);
Expand Down Expand Up @@ -168,10 +170,16 @@ public void handleMessage(Message msg) {
private void signalEndOfStream() {
MediaCodec.BufferInfo eos = new MediaCodec.BufferInfo();
ByteBuffer buffer = ByteBuffer.allocate(0);
eos.set(0, 0,0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
eos.set(0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
if (VERBOSE) Log.i(TAG, "Signal EOS to muxer ");
writeSampleData(mVideoTrackIndex, eos, buffer);
writeSampleData(mAudioTrackIndex, eos, buffer);
if (mVideoTrackIndex != INVALID_INDEX) {
writeSampleData(mVideoTrackIndex, eos, buffer);
}
if (mAudioTrackIndex != INVALID_INDEX) {
writeSampleData(mAudioTrackIndex, eos, buffer);
}
mVideoTrackIndex = INVALID_INDEX;
mAudioTrackIndex = INVALID_INDEX;
}

private void record() {
Expand Down Expand Up @@ -205,7 +213,7 @@ private void muxVideo(int index, MediaCodec.BufferInfo buffer) {
Log.w(TAG, "muxVideo: Already stopped!");
return;
}
if (!mMuxerStarted) {
if (!mMuxerStarted || mVideoTrackIndex == INVALID_INDEX) {
mPendingVideoEncoderBufferIndices.add(index);
mPendingVideoEncoderBufferInfos.add(buffer);
return;
Expand All @@ -214,9 +222,11 @@ private void muxVideo(int index, MediaCodec.BufferInfo buffer) {
writeSampleData(mVideoTrackIndex, buffer, encodedData);
mVideoEncoder.releaseOutputBuffer(index);
if ((buffer.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
if (VERBOSE) Log.d(TAG, "Stop encoder and muxer, since the buffer has been marked with EOS");
if (VERBOSE)
Log.d(TAG, "Stop encoder and muxer, since the buffer has been marked with EOS");
// send release msg
signalStop();
mVideoTrackIndex = INVALID_INDEX;
signalStop(true);
}
}

Expand All @@ -226,7 +236,7 @@ private void muxAudio(int index, MediaCodec.BufferInfo buffer) {
Log.w(TAG, "muxAudio: Already stopped!");
return;
}
if (!mMuxerStarted) {
if (!mMuxerStarted || mAudioTrackIndex == INVALID_INDEX) {
mPendingAudioEncoderBufferIndices.add(index);
mPendingAudioEncoderBufferInfos.add(buffer);
return;
Expand All @@ -236,10 +246,13 @@ private void muxAudio(int index, MediaCodec.BufferInfo buffer) {
writeSampleData(mAudioTrackIndex, buffer, encodedData);
mAudioEncoder.releaseOutputBuffer(index);
if ((buffer.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
if (VERBOSE) Log.d(TAG, "Stop encoder and muxer, since the buffer has been marked with EOS");
signalStop();
if (VERBOSE)
Log.d(TAG, "Stop encoder and muxer, since the buffer has been marked with EOS");
mAudioTrackIndex = INVALID_INDEX;
signalStop(true);
}
}

private void writeSampleData(int track, MediaCodec.BufferInfo buffer, ByteBuffer encodedData) {
if ((buffer.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// The codec config data was pulled out and fed to the muxer when we got
Expand All @@ -253,14 +266,17 @@ private void writeSampleData(int track, MediaCodec.BufferInfo buffer, ByteBuffer
if (VERBOSE) Log.d(TAG, "info.size == 0, drop it.");
encodedData = null;
} else {
if (track == mVideoTrackIndex) {
resetVideoPts(buffer);
} else if (track == mAudioTrackIndex) {
resetAudioPts(buffer);
if (buffer.presentationTimeUs != 0) { // maybe 0 if eos
if (track == mVideoTrackIndex) {
resetVideoPts(buffer);
} else if (track == mAudioTrackIndex) {
resetAudioPts(buffer);
}
}
if (VERBOSE) Log.d(TAG, "[" + Thread.currentThread().getId() + "] Got buffer, track=" + track
+ ", info: size=" + buffer.size
+ ", presentationTimeUs=" + buffer.presentationTimeUs);
if (VERBOSE)
Log.d(TAG, "[" + Thread.currentThread().getId() + "] Got buffer, track=" + track
+ ", info: size=" + buffer.size
+ ", presentationTimeUs=" + buffer.presentationTimeUs);
if (!eos && mCallback != null) {
mCallback.onRecording(buffer.presentationTimeUs);
}
Expand All @@ -269,7 +285,8 @@ private void writeSampleData(int track, MediaCodec.BufferInfo buffer, ByteBuffer
encodedData.position(buffer.offset);
encodedData.limit(buffer.offset + buffer.size);
mMuxer.writeSampleData(track, encodedData, buffer);
if (VERBOSE) Log.i(TAG, "Sent " + buffer.size + " bytes to MediaMuxer on track " + track);
if (VERBOSE)
Log.i(TAG, "Sent " + buffer.size + " bytes to MediaMuxer on track " + track);
}
}

Expand All @@ -283,6 +300,7 @@ private void resetAudioPts(MediaCodec.BufferInfo buffer) {
buffer.presentationTimeUs -= mAudioPtsOffset;
}
}

private void resetVideoPts(MediaCodec.BufferInfo buffer) {
if (mVideoPtsOffset == 0) {
mVideoPtsOffset = buffer.presentationTimeUs;
Expand All @@ -297,7 +315,8 @@ private void resetVideoOutputFormat(MediaFormat newFormat) {
if (mVideoTrackIndex >= 0 || mMuxerStarted) {
throw new IllegalStateException("output format already changed!");
}
if (VERBOSE) Log.i(TAG, "Video output format changed.\n New format: " + newFormat.toString());
if (VERBOSE)
Log.i(TAG, "Video output format changed.\n New format: " + newFormat.toString());
mVideoOutputFormat = newFormat;
}

Expand All @@ -306,7 +325,8 @@ private void resetAudioOutputFormat(MediaFormat newFormat) {
if (mAudioTrackIndex >= 0 || mMuxerStarted) {
throw new IllegalStateException("output format already changed!");
}
if (VERBOSE) Log.i(TAG, "Audio output format changed.\n New format: " + newFormat.toString());
if (VERBOSE)
Log.i(TAG, "Audio output format changed.\n New format: " + newFormat.toString());
mAudioOutputFormat = newFormat;
}

Expand Down Expand Up @@ -375,7 +395,8 @@ private void prepareAudioEncoder() throws IOException {

@Override
public void onOutputBufferAvailable(BaseEncoder codec, int index, MediaCodec.BufferInfo info) {
if (VERBOSE) Log.i(TAG, "[" + Thread.currentThread().getId() + "] AudioEncoder output buffer available: index=" + index);
if (VERBOSE)
Log.i(TAG, "[" + Thread.currentThread().getId() + "] AudioEncoder output buffer available: index=" + index);
try {
muxAudio(index, info);
} catch (Exception e) {
Expand All @@ -386,7 +407,8 @@ public void onOutputBufferAvailable(BaseEncoder codec, int index, MediaCodec.Buf

@Override
public void onOutputFormatChanged(BaseEncoder codec, MediaFormat format) {
if (VERBOSE) Log.d(TAG, "[" + Thread.currentThread().getId() + "] AudioEncoder returned new format " + format);
if (VERBOSE)
Log.d(TAG, "[" + Thread.currentThread().getId() + "] AudioEncoder returned new format " + format);
resetAudioOutputFormat(format);
startMuxerIfReady();
}
Expand All @@ -404,8 +426,8 @@ public void onError(Encoder codec, Exception e) {
mAudioEncoder.prepare();
}

private void signalStop() {
Message msg = Message.obtain(mHandler, MSG_STOP, STOP_WITH_EOS, 0);
private void signalStop(boolean stopWithEOS) {
Message msg = Message.obtain(mHandler, MSG_STOP, stopWithEOS ? STOP_WITH_EOS : 0, 0);
mHandler.sendMessageAtFrontOfQueue(msg);
}

Expand Down Expand Up @@ -439,7 +461,7 @@ private void release() {
}

mVideoOutputFormat = mAudioOutputFormat = null;
mVideoTrackIndex = mAudioTrackIndex = -1;
mVideoTrackIndex = mAudioTrackIndex = INVALID_INDEX;
mMuxerStarted = false;

if (mWorker != null) {
Expand Down

0 comments on commit 951f702

Please sign in to comment.