| Index: talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java
|
| diff --git a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java
|
| index 988d62a3ff4622786aad0c1ab37ca6384324d93a..0eac0913bad2f9de2c77a243e9b4ee3da7167375 100644
|
| --- a/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java
|
| +++ b/talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java
|
| @@ -61,7 +61,7 @@ public class MediaCodecVideoEncoder {
|
|
|
| private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000; // Timeout for codec releasing.
|
| private static final int DEQUEUE_TIMEOUT = 0; // Non-blocking, no wait.
|
| - // Active running encoder instance. Set in initDecode() (called from native code)
|
| + // Active running encoder instance. Set in initEncode() (called from native code)
|
| // and reset to null in release() call.
|
| private static MediaCodecVideoEncoder runningInstance = null;
|
| private static MediaCodecVideoEncoderErrorCallback errorCallback = null;
|
| @@ -102,15 +102,12 @@ public class MediaCodecVideoEncoder {
|
| CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
|
| COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m
|
| };
|
| - private int colorFormat;
|
| - // Video encoder type.
|
| private VideoCodecType type;
|
| + private int colorFormat; // Used by native code.
|
| +
|
| // SPS and PPS NALs (Config frame) for H.264.
|
| private ByteBuffer configData = null;
|
|
|
| - private MediaCodecVideoEncoder() {
|
| - }
|
| -
|
| // MediaCodec error handler - invoked when critical error happens which may prevent
|
| // further use of media codec API. Now it means that one of media codec instances
|
| // is hanging and can no longer be used in the next call.
|
| @@ -237,16 +234,14 @@ public class MediaCodecVideoEncoder {
|
| }
|
| }
|
|
|
| - // Return the array of input buffers, or null on failure.
|
| - private ByteBuffer[] initEncode(
|
| - VideoCodecType type, int width, int height, int kbps, int fps) {
|
| + // Returns false if the hardware encoder currently can't be used.
|
| + boolean initEncode(VideoCodecType type, int width, int height, int kbps, int fps) {
|
| Logging.d(TAG, "Java initEncode: " + type + " : " + width + " x " + height +
|
| - ". @ " + kbps + " kbps. Fps: " + fps +
|
| - ". Color: 0x" + Integer.toHexString(colorFormat));
|
| + ". @ " + kbps + " kbps. Fps: " + fps + ".");
|
| +
|
| if (mediaCodecThread != null) {
|
| throw new RuntimeException("Forgot to release()?");
|
| }
|
| - this.type = type;
|
| EncoderProperties properties = null;
|
| String mime = null;
|
| int keyFrameIntervalSec = 0;
|
| @@ -263,6 +258,9 @@ public class MediaCodecVideoEncoder {
|
| throw new RuntimeException("Can not find HW encoder for " + type);
|
| }
|
| runningInstance = this; // Encoder is now running and can be queried for stack traces.
|
| + colorFormat = properties.colorFormat;
|
| + Logging.d(TAG, "Color format: " + colorFormat);
|
| +
|
| mediaCodecThread = Thread.currentThread();
|
| try {
|
| MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
|
| @@ -273,26 +271,32 @@ public class MediaCodecVideoEncoder {
|
| format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec);
|
| Logging.d(TAG, " Format: " + format);
|
| mediaCodec = createByCodecName(properties.codecName);
|
| + this.type = type;
|
| if (mediaCodec == null) {
|
| Logging.e(TAG, "Can not create media encoder");
|
| - return null;
|
| + return false;
|
| }
|
| mediaCodec.configure(
|
| format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
| +
|
| mediaCodec.start();
|
| - colorFormat = properties.colorFormat;
|
| outputBuffers = mediaCodec.getOutputBuffers();
|
| - ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
|
| - Logging.d(TAG, "Input buffers: " + inputBuffers.length +
|
| - ". Output buffers: " + outputBuffers.length);
|
| - return inputBuffers;
|
| + Logging.d(TAG, "Output buffers: " + outputBuffers.length);
|
| +
|
| } catch (IllegalStateException e) {
|
| Logging.e(TAG, "initEncode failed", e);
|
| - return null;
|
| + return false;
|
| }
|
| + return true;
|
| + }
|
| +
|
| + ByteBuffer[] getInputBuffers() {
|
| + ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
|
| + Logging.d(TAG, "Input buffers: " + inputBuffers.length);
|
| + return inputBuffers;
|
| }
|
|
|
| - private boolean encode(
|
| + boolean encodeBuffer(
|
| boolean isKeyframe, int inputBuffer, int size,
|
| long presentationTimestampUs) {
|
| checkOnMediaCodecThread();
|
| @@ -312,12 +316,12 @@ public class MediaCodecVideoEncoder {
|
| return true;
|
| }
|
| catch (IllegalStateException e) {
|
| - Logging.e(TAG, "encode failed", e);
|
| + Logging.e(TAG, "encodeBuffer failed", e);
|
| return false;
|
| }
|
| }
|
|
|
| - private void release() {
|
| + void release() {
|
| Logging.d(TAG, "Java releaseEncoder");
|
| checkOnMediaCodecThread();
|
|
|
| @@ -374,7 +378,7 @@ public class MediaCodecVideoEncoder {
|
|
|
| // Dequeue an input buffer and return its index, -1 if no input buffer is
|
| // available, or -2 if the codec is no longer operative.
|
| - private int dequeueInputBuffer() {
|
| + int dequeueInputBuffer() {
|
| checkOnMediaCodecThread();
|
| try {
|
| return mediaCodec.dequeueInputBuffer(DEQUEUE_TIMEOUT);
|
| @@ -385,7 +389,7 @@ public class MediaCodecVideoEncoder {
|
| }
|
|
|
| // Helper struct for dequeueOutputBuffer() below.
|
| - private static class OutputBufferInfo {
|
| + static class OutputBufferInfo {
|
| public OutputBufferInfo(
|
| int index, ByteBuffer buffer,
|
| boolean isKeyFrame, long presentationTimestampUs) {
|
| @@ -395,15 +399,15 @@ public class MediaCodecVideoEncoder {
|
| this.presentationTimestampUs = presentationTimestampUs;
|
| }
|
|
|
| - private final int index;
|
| - private final ByteBuffer buffer;
|
| - private final boolean isKeyFrame;
|
| - private final long presentationTimestampUs;
|
| + public final int index;
|
| + public final ByteBuffer buffer;
|
| + public final boolean isKeyFrame;
|
| + public final long presentationTimestampUs;
|
| }
|
|
|
| // Dequeue and return an output buffer, or null if no output is ready. Return
|
| // a fake OutputBufferInfo with index -1 if the codec is no longer operable.
|
| - private OutputBufferInfo dequeueOutputBuffer() {
|
| + OutputBufferInfo dequeueOutputBuffer() {
|
| checkOnMediaCodecThread();
|
| try {
|
| MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
|
| @@ -472,7 +476,7 @@ public class MediaCodecVideoEncoder {
|
|
|
| // Release a dequeued output buffer back to the codec for re-use. Return
|
| // false if the codec is no longer operable.
|
| - private boolean releaseOutputBuffer(int index) {
|
| + boolean releaseOutputBuffer(int index) {
|
| checkOnMediaCodecThread();
|
| try {
|
| mediaCodec.releaseOutputBuffer(index, false);
|
|
|