Restore output bitrate

pull/374/head
Mattia Iavarone 7 years ago
parent 0a85fc4d4e
commit b4383d1871
  1. 19
      cameraview/src/main/gles/com/otaliastudios/cameraview/AudioMediaEncoder.java
  2. 2
      cameraview/src/main/gles/com/otaliastudios/cameraview/MediaEncoder.java
  3. 4
      cameraview/src/main/gles/com/otaliastudios/cameraview/MediaEncoderEngine.java
  4. 2
      cameraview/src/main/gles/com/otaliastudios/cameraview/VideoMediaEncoder.java
  5. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/SnapshotVideoRecorder.java

@ -55,11 +55,18 @@ class AudioMediaEncoder extends MediaEncoder {
private AudioEncodingHandler mEncoder; private AudioEncodingHandler mEncoder;
private AudioRecordingThread mRecorder; private AudioRecordingThread mRecorder;
private ByteBufferPool mByteBufferPool; private ByteBufferPool mByteBufferPool;
private Config mConfig;
// TODO add options static class Config {
static class Config { } int bitRate;
Config(int bitRate) {
this.bitRate = bitRate;
}
}
AudioMediaEncoder(@NonNull Config config) { } AudioMediaEncoder(@NonNull Config config) {
mConfig = config;
}
@NonNull @NonNull
@Override @Override
@ -73,7 +80,7 @@ class AudioMediaEncoder extends MediaEncoder {
final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLING_FREQUENCY, CHANNELS_COUNT); final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLING_FREQUENCY, CHANNELS_COUNT);
audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
audioFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, CHANNELS); audioFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, CHANNELS);
audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE); audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, mConfig.bitRate);
audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNELS_COUNT); audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNELS_COUNT);
try { try {
mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE); mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
@ -116,8 +123,8 @@ class AudioMediaEncoder extends MediaEncoder {
} }
@Override @Override
int getBitRate() { int getEncodedBitRate() {
return BIT_RATE; return mConfig.bitRate;
} }
class AudioRecordingThread extends Thread { class AudioRecordingThread extends Thread {

@ -328,5 +328,5 @@ abstract class MediaEncoder {
private long mStartPresentationTimeUs = Long.MIN_VALUE; private long mStartPresentationTimeUs = Long.MIN_VALUE;
private long mLastPresentationTimeUs = 0; private long mLastPresentationTimeUs = 0;
abstract int getBitRate(); abstract int getEncodedBitRate();
} }

@ -1,6 +1,5 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import android.media.MediaCodec;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.media.MediaMuxer; import android.media.MediaMuxer;
import android.os.Build; import android.os.Build;
@ -10,7 +9,6 @@ import androidx.annotation.RequiresApi;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@ -58,7 +56,7 @@ class MediaEncoderEngine {
// This is really naive & probably not accurate, but... // This is really naive & probably not accurate, but...
int bitRate = 0; int bitRate = 0;
for (MediaEncoder encoder : mEncoders) { for (MediaEncoder encoder : mEncoders) {
bitRate += encoder.getBitRate(); bitRate += encoder.getEncodedBitRate();
} }
int bytePerSecond = bitRate / 8; int bytePerSecond = bitRate / 8;
long sizeMaxDuration = (maxSize / bytePerSecond) * 1000L; long sizeMaxDuration = (maxSize / bytePerSecond) * 1000L;

@ -99,7 +99,7 @@ abstract class VideoMediaEncoder<C extends VideoMediaEncoder.Config> extends Med
} }
@Override @Override
int getBitRate() { int getEncodedBitRate() {
return mConfig.bitRate; return mConfig.bitRate;
} }
} }

@ -20,6 +20,7 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
private static final int DEFAULT_VIDEO_FRAMERATE = 30; private static final int DEFAULT_VIDEO_FRAMERATE = 30;
private static final int DEFAULT_VIDEO_BITRATE = 1000000; private static final int DEFAULT_VIDEO_BITRATE = 1000000;
private static final int DEFAULT_AUDIO_BITRATE = 64000;
private static final int STATE_RECORDING = 0; private static final int STATE_RECORDING = 0;
private static final int STATE_NOT_RECORDING = 1; private static final int STATE_NOT_RECORDING = 1;
@ -57,8 +58,13 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
@Override @Override
public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY) { public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY) {
if (mCurrentState == STATE_NOT_RECORDING && mDesiredState == STATE_RECORDING) { if (mCurrentState == STATE_NOT_RECORDING && mDesiredState == STATE_RECORDING) {
// Set default options
if (mResult.videoBitRate <= 0) mResult.videoBitRate = DEFAULT_VIDEO_BITRATE;
if (mResult.videoFrameRate <= 0) mResult.videoFrameRate = DEFAULT_VIDEO_FRAMERATE;
if (mResult.audioBitRate <= 0) mResult.audioBitRate = DEFAULT_AUDIO_BITRATE;
// Video. Ensure width and height are divisible by 2, as I have read somewhere.
Size size = mResult.getSize(); Size size = mResult.getSize();
// Ensure width and height are divisible by 2, as I have read somewhere.
int width = size.getWidth(); int width = size.getWidth();
int height = size.getHeight(); int height = size.getHeight();
width = width % 2 == 0 ? width : width + 1; width = width % 2 == 0 ? width : width + 1;
@ -69,8 +75,6 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
case H_264: type = "video/avc"; break; // MediaFormat.MIMETYPE_VIDEO_AVC: case H_264: type = "video/avc"; break; // MediaFormat.MIMETYPE_VIDEO_AVC:
case DEVICE_DEFAULT: type = "video/avc"; break; case DEVICE_DEFAULT: type = "video/avc"; break;
} }
if (mResult.videoBitRate <= 0) mResult.videoBitRate = DEFAULT_VIDEO_BITRATE;
if (mResult.videoFrameRate <= 0) mResult.videoFrameRate = DEFAULT_VIDEO_FRAMERATE;
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 config = new TextureMediaEncoder.Config(width, height,
mResult.videoBitRate, mResult.videoBitRate,
@ -83,11 +87,13 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
); );
TextureMediaEncoder videoEncoder = new TextureMediaEncoder(config); TextureMediaEncoder videoEncoder = new TextureMediaEncoder(config);
// Audio
AudioMediaEncoder audioEncoder = null; AudioMediaEncoder audioEncoder = null;
if (mResult.audio == Audio.ON) { if (mResult.audio == Audio.ON) {
audioEncoder = new AudioMediaEncoder(new AudioMediaEncoder.Config()); audioEncoder = new AudioMediaEncoder(new AudioMediaEncoder.Config(mResult.audioBitRate));
mResult.audioBitRate = AudioMediaEncoder.BIT_RATE;
} }
// Engine
mEncoderEngine = new MediaEncoderEngine(mResult.file, videoEncoder, audioEncoder, mEncoderEngine = new MediaEncoderEngine(mResult.file, videoEncoder, audioEncoder,
mResult.maxDuration, mResult.maxSize, SnapshotVideoRecorder.this); mResult.maxDuration, mResult.maxSize, SnapshotVideoRecorder.this);
mEncoderEngine.start(); mEncoderEngine.start();

Loading…
Cancel
Save