Ensure first frame is a sync one

pull/530/head
Mattia Iavarone 6 years ago
parent 116404a371
commit 72af5b65ca
  1. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/MediaEncoder.java
  2. 30
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/VideoMediaEncoder.java

@ -391,7 +391,7 @@ public abstract class MediaEncoder {
*/ */
@SuppressLint("LogNotTimber") @SuppressLint("LogNotTimber")
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected void drainOutput(boolean drainAll) { protected final void drainOutput(boolean drainAll) {
LOG.i(mName, "DRAINING - EOS:", drainAll); LOG.i(mName, "DRAINING - EOS:", drainAll);
if (mMediaCodec == null) { if (mMediaCodec == null) {
LOG.e("drain() was called before prepare() or after releasing."); LOG.e("drain() was called before prepare() or after releasing.");
@ -455,7 +455,7 @@ public abstract class MediaEncoder {
buffer.info = mBufferInfo; buffer.info = mBufferInfo;
buffer.trackIndex = mTrackIndex; buffer.trackIndex = mTrackIndex;
buffer.data = encodedData; buffer.data = encodedData;
mController.write(mOutputBufferPool, buffer); onWriteOutput(mOutputBufferPool, buffer);
} }
mMediaCodec.releaseOutputBuffer(encoderStatus, false); mMediaCodec.releaseOutputBuffer(encoderStatus, false);
@ -483,6 +483,11 @@ public abstract class MediaEncoder {
} }
} }
@CallSuper
protected void onWriteOutput(@NonNull OutputBufferPool pool, @NonNull OutputBuffer buffer) {
mController.write(pool, buffer);
}
protected abstract int getEncodedBitRate(); protected abstract int getEncodedBitRate();
/** /**

@ -43,6 +43,8 @@ abstract class VideoMediaEncoder<C extends VideoConfig> extends MediaEncoder {
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected int mFrameNumber = -1; protected int mFrameNumber = -1;
private boolean mSyncFrameFound = false;
VideoMediaEncoder(@NonNull C config) { VideoMediaEncoder(@NonNull C config) {
super("VideoEncoder"); super("VideoEncoder");
mConfig = config; mConfig = config;
@ -92,6 +94,34 @@ abstract class VideoMediaEncoder<C extends VideoConfig> extends MediaEncoder {
drainOutput(true); drainOutput(true);
} }
/**
* The first frame that we write MUST have the BUFFER_FLAG_SYNC_FRAME flag set.
* It sometimes doesn't because we might drop some frames in {@link #drainOutput(boolean)},
* basically if, at the time, the muxer was not started yet, due to Audio setup being slow.
*
* We can't add the BUFFER_FLAG_SYNC_FRAME flag to the first frame just because we'd like to.
* But we can drop frames until we get a sync one.
*
* @param pool the buffer pool
* @param buffer the buffer
*/
@SuppressWarnings("StatementWithEmptyBody")
@Override
protected void onWriteOutput(@NonNull OutputBufferPool pool, @NonNull OutputBuffer buffer) {
if (!mSyncFrameFound) {
int flag = MediaCodec.BUFFER_FLAG_SYNC_FRAME;
boolean hasFlag = (buffer.info.flags & flag) != 0;
if (hasFlag) {
mSyncFrameFound = true;
super.onWriteOutput(pool, buffer);
} else {
// drop this.
}
} else {
super.onWriteOutput(pool, buffer);
}
}
@Override @Override
protected int getEncodedBitRate() { protected int getEncodedBitRate() {
return mConfig.bitRate; return mConfig.bitRate;

Loading…
Cancel
Save