Skip to content

Commit

Permalink
Add GPUImageMovieWriter class
Browse files Browse the repository at this point in the history
Adapted code from Grafika (https://github.com/google/grafika) to support
real-time video filtering;
support API>=18 only;
resolve cats-oss#25.
  • Loading branch information
yiwenlu66 committed Aug 7, 2016
1 parent b0ec8fa commit a255aeb
Show file tree
Hide file tree
Showing 10 changed files with 1,622 additions and 8 deletions.
4 changes: 2 additions & 2 deletions library/src/jp/co/cyberagent/android/gpuimage/GPUImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
*/
public class GPUImage {
private final Context mContext;
private final GPUImageRenderer mRenderer;
private GLSurfaceView mGlSurfaceView;
protected GPUImageRenderer mRenderer;
protected GLSurfaceView mGlSurfaceView;
private GPUImageFilter mFilter;
private Bitmap mCurrentBitmap;
private ScaleType mScaleType = ScaleType.CENTER_CROP;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2016 Peter Lu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package jp.co.cyberagent.android.gpuimage;

import android.content.Context;

import java.io.File;

public class GPUImageMovieWriter extends GPUImage {

public final static int RECORDING_OFF = 0;
public final static int RECORDING_ON = 1;

private int mRecordingState = RECORDING_OFF;

public GPUImageMovieWriter(final Context context, final File outputFile) {
super(context);
mRenderer = new GPUImageMovieWriterRenderer(new GPUImageFilter(), outputFile);
mRecordingState = RECORDING_OFF;
}

public int toggleRecording() {
if (mRecordingState == RECORDING_OFF) {
((GPUImageMovieWriterRenderer)mRenderer).changeRecordingState(true);
mRecordingState = RECORDING_ON;
} else {
((GPUImageMovieWriterRenderer)mRenderer).changeRecordingState(false);
mRecordingState = RECORDING_OFF;
}
return mRecordingState;
}

public void setOutputResolution(int width, int height) {
((GPUImageMovieWriterRenderer)mRenderer).setOutputResolution(width, height);
}

public void setOutputBitrate(int bitrate) {
((GPUImageMovieWriterRenderer)mRenderer).setOutputBitrate(bitrate);
}

public int getRecordingState() {
return mRecordingState;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2016 Peter Lu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package jp.co.cyberagent.android.gpuimage;

import android.opengl.EGL14;

import java.io.File;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class GPUImageMovieWriterRenderer extends GPUImageRenderer {

public static final int RECORDING_OFF = 0;
public static final int RECORDING_ON = 1;
public static final int RECORDING_RESUMED = 2;

private TextureMovieEncoder mVideoEncoder;
private boolean mIsRecordingEnabled = false;
private int mRecordingStatus = RECORDING_OFF;
private File mOutputFile = null;
private int mOutputWidth = 480;
private int mOutoutHeight = 640;
private int mOutputBitrate = 1000000;

public void changeRecordingState(boolean isRecording) {
mIsRecordingEnabled = isRecording;
}

public GPUImageMovieWriterRenderer(GPUImageFilter filter, File outputFile) {
super(filter);
mOutputFile = outputFile;
if (mVideoEncoder == null) {
mVideoEncoder = new TextureMovieEncoder(mFilter);
}
}

@Override
public void onSurfaceCreated(final GL10 gl, final EGLConfig config) {
super.onSurfaceCreated(gl, config);
mRecordingStatus = mIsRecordingEnabled ? RECORDING_RESUMED : RECORDING_OFF;
}

@Override
public void onDrawFrame(final GL10 gl) {
super.onDrawFrame(gl);
if (mIsRecordingEnabled) {
switch (mRecordingStatus) {
case RECORDING_OFF:
mVideoEncoder.startRecording(new TextureMovieEncoder.EncoderConfig(
mOutputFile, mOutputWidth, mOutoutHeight, mOutputBitrate, EGL14.eglGetCurrentContext()
));
mRecordingStatus = RECORDING_ON;
break;
case RECORDING_RESUMED:
mVideoEncoder.updateSharedContext(EGL14.eglGetCurrentContext());
mRecordingStatus = RECORDING_ON;
break;
case RECORDING_ON:
break;
default:
throw new RuntimeException("unknown status: " + mRecordingStatus);
}
} else {
switch (mRecordingStatus) {
case RECORDING_ON:
case RECORDING_RESUMED:
mVideoEncoder.stopRecording();
mRecordingStatus = RECORDING_OFF;
break;
case RECORDING_OFF:
break;
default:
throw new RuntimeException("unknown status: " + mRecordingStatus);
}
}
mVideoEncoder.setTextureId(mGLTextureId);
mVideoEncoder.frameAvailable(mSurfaceTexture);
}

@Override
protected void adjustImageScaling() {
super.adjustImageScaling();
if (mVideoEncoder == null) {
// this may be called before the child constructor
mVideoEncoder = new TextureMovieEncoder(mFilter);
}
mVideoEncoder.setGLCubeBuffer(mGLCubeBuffer);
mVideoEncoder.setGLTextureBuffer(mGLTextureBuffer);
}

@Override
public void setFilter(GPUImageFilter filter) {
super.setFilter(filter);
mVideoEncoder.setFilter(filter);
}

public void setOutputResolution(int width, int height) {
mOutputWidth = width;
mOutoutHeight = height;
}

public void setOutputBitrate(int bitrate) {
mOutputBitrate = bitrate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ public class GPUImageRenderer implements Renderer, PreviewCallback {
1.0f, 1.0f,
};

private GPUImageFilter mFilter;
protected GPUImageFilter mFilter;

public final Object mSurfaceChangedWaiter = new Object();

private int mGLTextureId = NO_IMAGE;
private SurfaceTexture mSurfaceTexture = null;
private final FloatBuffer mGLCubeBuffer;
private final FloatBuffer mGLTextureBuffer;
protected int mGLTextureId = NO_IMAGE;
protected SurfaceTexture mSurfaceTexture = null;
protected final FloatBuffer mGLCubeBuffer;
protected final FloatBuffer mGLTextureBuffer;
private IntBuffer mGLRgbBuffer;

private int mOutputWidth;
Expand Down Expand Up @@ -267,7 +267,7 @@ protected int getFrameHeight() {
return mOutputHeight;
}

private void adjustImageScaling() {
protected void adjustImageScaling() {
float outputWidth = mOutputWidth;
float outputHeight = mOutputHeight;
if (mRotation == Rotation.ROTATION_270 || mRotation == Rotation.ROTATION_90) {
Expand Down
Loading

0 comments on commit a255aeb

Please sign in to comment.