Simplify encoders Config

pull/506/head
Mattia Iavarone 6 years ago
parent 1d8b8d0ea2
commit 0ee63bebfb
  1. 31
      cameraview/src/main/java/com/otaliastudios/cameraview/video/SnapshotVideoRecorder.java
  2. 26
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/AudioMediaEncoder.java
  3. 2
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/MediaEncoder.java
  4. 56
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/TextureMediaEncoder.java
  5. 30
      cameraview/src/main/java/com/otaliastudios/cameraview/video/encoding/VideoMediaEncoder.java

@ -118,22 +118,29 @@ public class SnapshotVideoRecorder extends VideoRecorder implements RendererFram
case DEVICE_DEFAULT: type = "video/avc"; break; case DEVICE_DEFAULT: type = "video/avc"; break;
} }
LOG.w("Creating frame encoder. Rotation:", mResult.rotation); LOG.w("Creating frame encoder. Rotation:", mResult.rotation);
TextureMediaEncoder.Config config = new TextureMediaEncoder.Config(width, height, TextureMediaEncoder.Config videoConfig = new TextureMediaEncoder.Config();
mResult.videoBitRate, videoConfig.width = width;
mResult.videoFrameRate, videoConfig.height = height;
mResult.rotation, videoConfig.bitRate = mResult.videoBitRate;
type, mTextureId, videoConfig.frameRate = mResult.videoFrameRate;
scaleX, scaleY, videoConfig.rotation = mResult.rotation;
EGL14.eglGetCurrentContext(), videoConfig.mimeType = type;
mHasOverlay ? mOverlayTextureId : TextureMediaEncoder.NO_TEXTURE, videoConfig.textureId = mTextureId;
mOverlayRotation videoConfig.scaleX = scaleX;
); videoConfig.scaleY = scaleY;
TextureMediaEncoder videoEncoder = new TextureMediaEncoder(config); videoConfig.eglContext = EGL14.eglGetCurrentContext();
if (mHasOverlay) {
videoConfig.overlayTextureId = mOverlayTextureId;
videoConfig.overlayRotation = mOverlayRotation;
}
TextureMediaEncoder videoEncoder = new TextureMediaEncoder(videoConfig);
// Audio // Audio
AudioMediaEncoder audioEncoder = null; AudioMediaEncoder audioEncoder = null;
if (mResult.audio == Audio.ON) { if (mResult.audio == Audio.ON) {
audioEncoder = new AudioMediaEncoder(new AudioMediaEncoder.Config(mResult.audioBitRate)); AudioMediaEncoder.Config audioConfig = new AudioMediaEncoder.Config();
audioConfig.bitRate = mResult.audioBitRate;
audioEncoder = new AudioMediaEncoder(audioConfig);
} }
// Engine // Engine

@ -73,15 +73,19 @@ public class AudioMediaEncoder extends MediaEncoder {
private Config mConfig; private Config mConfig;
public static class Config { public static class Config {
int bitRate; public int bitRate;
public Config(int bitRate) {
this.bitRate = bitRate; @NonNull
private Config copy() {
Config config = new Config();
config.bitRate = this.bitRate;
return config;
} }
} }
public AudioMediaEncoder(@NonNull Config config) { public AudioMediaEncoder(@NonNull Config config) {
super("AudioEncoder"); super("AudioEncoder");
mConfig = config; mConfig = config.copy();
} }
@EncoderThread @EncoderThread
@ -111,10 +115,6 @@ public class AudioMediaEncoder extends MediaEncoder {
mRecorder.start(); mRecorder.start();
} }
@EncoderThread
@Override
void onEvent(@NonNull String event, @Nullable Object data) { }
@EncoderThread @EncoderThread
@Override @Override
void onStop() { void onStop() {
@ -138,7 +138,7 @@ public class AudioMediaEncoder extends MediaEncoder {
return mConfig.bitRate; return mConfig.bitRate;
} }
class AudioRecordingThread extends Thread { private class AudioRecordingThread extends Thread {
private AudioRecord mAudioRecord; private AudioRecord mAudioRecord;
private ByteBuffer mCurrentBuffer; private ByteBuffer mCurrentBuffer;
@ -287,9 +287,11 @@ public class AudioMediaEncoder extends MediaEncoder {
} }
void sendInputBuffer(ByteBuffer buffer, long presentationTimeUs, boolean endOfStream) { void sendInputBuffer(ByteBuffer buffer, long presentationTimeUs, boolean endOfStream) {
int presentation1 = (int) (presentationTimeUs >> 32); sendMessage(obtainMessage(
int presentation2 = (int) (presentationTimeUs); endOfStream ? 1 : 0,
sendMessage(obtainMessage(endOfStream ? 1 : 0, presentation1, presentation2, buffer)); (int) (presentationTimeUs >> 32),
(int) (presentationTimeUs),
buffer));
} }
@Override @Override

@ -256,7 +256,7 @@ abstract class MediaEncoder {
* @param data object * @param data object
*/ */
@EncoderThread @EncoderThread
abstract void onEvent(@NonNull String event, @Nullable Object data); void onEvent(@NonNull String event, @Nullable Object data) {};
/** /**
* Stop recording. This involves signaling the end of stream and draining * Stop recording. This involves signaling the end of stream and draining

@ -24,37 +24,31 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureMediaEncoder.C
private static final CameraLogger LOG = CameraLogger.create(TAG); private static final CameraLogger LOG = CameraLogger.create(TAG);
public final static String FRAME_EVENT = "frame"; public final static String FRAME_EVENT = "frame";
public final static int NO_TEXTURE = Integer.MIN_VALUE; private final static int NO_TEXTURE = Integer.MIN_VALUE;
public static class Config extends VideoMediaEncoder.Config { public static class Config extends VideoMediaEncoder.Config {
int textureId; public int textureId = NO_TEXTURE;
int overlayTextureId; public int overlayTextureId = NO_TEXTURE;
float scaleX; public int overlayRotation;
float scaleY; public float scaleX;
EGLContext eglContext; public float scaleY;
int transformRotation; public EGLContext eglContext;
int overlayTransformRotation;
@NonNull
public Config(int width, int height, private Config copy() {
int bitRate, int frameRate, Config copy = new Config();
int rotation, @NonNull String mimeType, copy(copy);
int textureId, copy.textureId = this.textureId;
float scaleX, float scaleY, copy.overlayTextureId = this.overlayTextureId;
@NonNull EGLContext eglContext, copy.overlayRotation = this.overlayRotation;
int overlayTextureId, int overlayRotation) { copy.scaleX = this.scaleX;
// We rotate the texture using transformRotation. Pass rotation=0 to super so that copy.scaleY = this.scaleY;
// no rotation metadata is written into the output file. copy.eglContext = this.eglContext;
super(width, height, bitRate, frameRate, 0, mimeType); return copy;
this.transformRotation = rotation;
this.textureId = textureId;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.eglContext = eglContext;
this.overlayTextureId = overlayTextureId;
this.overlayTransformRotation = overlayRotation;
} }
} }
private int mTransformRotation;
private EglCore mEglCore; private EglCore mEglCore;
private EglWindowSurface mWindow; private EglWindowSurface mWindow;
private EglViewport mViewport; private EglViewport mViewport;
@ -66,7 +60,7 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureMediaEncoder.C
}); });
public TextureMediaEncoder(@NonNull Config config) { public TextureMediaEncoder(@NonNull Config config) {
super(config); super(config.copy());
} }
public static class TextureFrame { public static class TextureFrame {
@ -92,6 +86,10 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureMediaEncoder.C
@EncoderThread @EncoderThread
@Override @Override
void onPrepare(@NonNull MediaEncoderEngine.Controller controller, long maxLengthMillis) { void onPrepare(@NonNull MediaEncoderEngine.Controller controller, long maxLengthMillis) {
// We rotate the texture using transformRotation. Pass rotation=0 to super so that
// no rotation metadata is written into the output file.
mTransformRotation = mConfig.rotation;
mConfig.rotation = 0;
super.onPrepare(controller, maxLengthMillis); super.onPrepare(controller, maxLengthMillis);
mEglCore = new EglCore(mConfig.eglContext, EglCore.FLAG_RECORDABLE); mEglCore = new EglCore(mConfig.eglContext, EglCore.FLAG_RECORDABLE);
mWindow = new EglWindowSurface(mEglCore, mSurface, true); mWindow = new EglWindowSurface(mEglCore, mSurface, true);
@ -132,13 +130,13 @@ public class TextureMediaEncoder extends VideoMediaEncoder<TextureMediaEncoder.C
// Rotation also takes place with respect to the origin (the Z axis), so we must // Rotation also takes place with respect to the origin (the Z axis), so we must
// translate to origin, rotate, then back to where we were. // translate to origin, rotate, then back to where we were.
Matrix.translateM(transform, 0, 0.5F, 0.5F, 0); Matrix.translateM(transform, 0, 0.5F, 0.5F, 0);
Matrix.rotateM(transform, 0, mConfig.transformRotation, 0, 0, 1); Matrix.rotateM(transform, 0, mTransformRotation, 0, 0, 1);
Matrix.translateM(transform, 0, -0.5F, -0.5F, 0); Matrix.translateM(transform, 0, -0.5F, -0.5F, 0);
boolean hasOverlay = mConfig.overlayTextureId != NO_TEXTURE; boolean hasOverlay = mConfig.overlayTextureId != NO_TEXTURE;
if (hasOverlay) { if (hasOverlay) {
Matrix.translateM(overlayTransform, 0, 0.5F, 0.5F, 0); Matrix.translateM(overlayTransform, 0, 0.5F, 0.5F, 0);
Matrix.rotateM(overlayTransform, 0, mConfig.overlayTransformRotation, 0, 0, 1); Matrix.rotateM(overlayTransform, 0, mConfig.overlayRotation, 0, 0, 1);
Matrix.translateM(overlayTransform, 0, -0.5F, -0.5F, 0); Matrix.translateM(overlayTransform, 0, -0.5F, -0.5F, 0);
} }

@ -43,21 +43,21 @@ abstract class VideoMediaEncoder<C extends VideoMediaEncoder.Config> extends Med
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected int mFrameNum = -1; protected int mFrameNum = -1;
static class Config { protected static class Config {
int width; public int width;
int height; public int height;
int bitRate; public int bitRate;
int frameRate; public int frameRate;
int rotation; public int rotation;
String mimeType; public String mimeType;
Config(int width, int height, int bitRate, int frameRate, int rotation, @NonNull String mimeType) { protected <C extends Config> void copy(@NonNull C output) {
this.width = width; output.width = this.width;
this.height = height; output.height = this.height;
this.bitRate = bitRate; output.bitRate = this.bitRate;
this.frameRate = frameRate; output.frameRate = this.frameRate;
this.rotation = rotation; output.rotation = this.rotation;
this.mimeType = mimeType; output.mimeType = this.mimeType;
} }
} }

Loading…
Cancel
Save