Create the VideoEncoderFactory and implement it.
Adds the VideoEncoderFactory interface and implements it for use with HardwareVideoEncoder. This uses MediaCodecVideoEncoder's initialization code as an example. BUG=webrtc:7760 Change-Id: I9fbc93ce9ac4ad866750a4386c4f15e800a3073e Reviewed-on: https://chromium-review.googlesource.com/530063 Commit-Queue: Bjorn Mellem <mellem@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> Cr-Commit-Position: refs/heads/master@{#18636}
This commit is contained in:
@ -48,15 +48,8 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000;
|
||||
private static final int DEQUEUE_OUTPUT_BUFFER_TIMEOUT_US = 100000;
|
||||
|
||||
// TODO(mellem): Maybe move mime types to the factory or a common location.
|
||||
private static final String VP8_MIME_TYPE = "video/x-vnd.on2.vp8";
|
||||
private static final String VP9_MIME_TYPE = "video/x-vnd.on2.vp9";
|
||||
private static final String H264_MIME_TYPE = "video/avc";
|
||||
private static final Set<String> SUPPORTED_MIME_TYPES =
|
||||
new HashSet<>(Arrays.asList(VP8_MIME_TYPE, VP9_MIME_TYPE, H264_MIME_TYPE));
|
||||
|
||||
private final String codecName;
|
||||
private final String mimeType;
|
||||
private final VideoCodecType codecType;
|
||||
private final int colorFormat;
|
||||
private final ColorFormat inputColorFormat;
|
||||
// Base interval for generating key frames.
|
||||
@ -94,27 +87,23 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
private ByteBuffer configBuffer = null;
|
||||
|
||||
/**
|
||||
* Creates a new HardwareVideoEncoder with the given codecName, mimeType, colorFormat, key frame
|
||||
* Creates a new HardwareVideoEncoder with the given codecName, codecType, colorFormat, key frame
|
||||
* intervals, and bitrateAdjuster.
|
||||
*
|
||||
* @param codecName the hardware codec implementation to use
|
||||
* @param mimeType MIME type of the codec's output; must be one of "video/x-vnd.on2.vp8",
|
||||
* "video/x-vnd.on2.vp9", or "video/avc"
|
||||
* @param codecType the type of the given video codec (eg. VP8, VP9, or H264)
|
||||
* @param colorFormat color format used by the input buffer
|
||||
* @param keyFrameIntervalSec interval in seconds between key frames; used to initialize the codec
|
||||
* @param forceKeyFrameIntervalMs interval at which to force a key frame if one is not requested;
|
||||
* used to reduce distortion caused by some codec implementations
|
||||
* @param bitrateAdjuster algorithm used to correct codec implementations that do not produce the
|
||||
* desired bitrates
|
||||
* @throws IllegalArgumentException if either mimeType or colorFormat is unsupported
|
||||
* @throws IllegalArgumentException if colorFormat is unsupported
|
||||
*/
|
||||
public HardwareVideoEncoder(String codecName, String mimeType, int colorFormat,
|
||||
public HardwareVideoEncoder(String codecName, VideoCodecType codecType, int colorFormat,
|
||||
int keyFrameIntervalSec, int forceKeyFrameIntervalMs, BitrateAdjuster bitrateAdjuster) {
|
||||
if (!SUPPORTED_MIME_TYPES.contains(mimeType)) {
|
||||
throw new IllegalArgumentException("Unsupported MIME type: " + mimeType);
|
||||
}
|
||||
this.codecName = codecName;
|
||||
this.mimeType = mimeType;
|
||||
this.codecType = codecType;
|
||||
this.colorFormat = colorFormat;
|
||||
this.inputColorFormat = ColorFormat.valueOf(colorFormat);
|
||||
this.keyFrameIntervalSec = keyFrameIntervalSec;
|
||||
@ -150,7 +139,7 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
return VideoCodecStatus.ERROR;
|
||||
}
|
||||
try {
|
||||
MediaFormat format = MediaFormat.createVideoFormat(mimeType, width, height);
|
||||
MediaFormat format = MediaFormat.createVideoFormat(codecType.mimeType(), width, height);
|
||||
format.setInteger(MediaFormat.KEY_BIT_RATE, adjustedBitrate);
|
||||
format.setInteger(KEY_BITRATE_MODE, VIDEO_ControlRateConstant);
|
||||
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
|
||||
@ -369,7 +358,7 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
|
||||
ByteBuffer frameBuffer;
|
||||
boolean isKeyFrame = (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0;
|
||||
if (isKeyFrame && mimeType.equals(H264_MIME_TYPE)) {
|
||||
if (isKeyFrame && codecType == VideoCodecType.H264) {
|
||||
Logging.d(TAG,
|
||||
"Prepending config frame of size " + configBuffer.capacity()
|
||||
+ " to output buffer with offset " + info.offset + ", size " + info.size);
|
||||
|
||||
85
webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java
Normal file
85
webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.webrtc.VideoFrame.I420Buffer;
|
||||
|
||||
/** Implementation of an I420 VideoFrame buffer. */
|
||||
class I420BufferImpl implements VideoFrame.I420Buffer {
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final int strideUV;
|
||||
private final ByteBuffer y;
|
||||
private final ByteBuffer u;
|
||||
private final ByteBuffer v;
|
||||
|
||||
I420BufferImpl(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.strideUV = (width + 1) / 2;
|
||||
int halfHeight = (height + 1) / 2;
|
||||
this.y = ByteBuffer.allocateDirect(width * height);
|
||||
this.u = ByteBuffer.allocateDirect(strideUV * halfHeight);
|
||||
this.v = ByteBuffer.allocateDirect(strideUV * halfHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer getDataY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer getDataU() {
|
||||
return u;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer getDataV() {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStrideY() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStrideU() {
|
||||
return strideUV;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStrideV() {
|
||||
return strideUV;
|
||||
}
|
||||
|
||||
@Override
|
||||
public I420Buffer toI420() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retain() {}
|
||||
|
||||
@Override
|
||||
public void release() {}
|
||||
}
|
||||
28
webrtc/sdk/android/src/java/org/webrtc/VideoCodecType.java
Normal file
28
webrtc/sdk/android/src/java/org/webrtc/VideoCodecType.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
/** Enumeration of supported video codec types. */
|
||||
enum VideoCodecType {
|
||||
VP8("video/x-vnd.on2.vp8"),
|
||||
VP9("video/x-vnd.on2.vp9"),
|
||||
H264("video/avc");
|
||||
|
||||
private final String mimeType;
|
||||
|
||||
private VideoCodecType(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
String mimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user