зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1265755 - Support encoder case for CodecProxy; r=jolin
MozReview-Commit-ID: 4cEZQs8spo7 --HG-- extra : rebase_source : 33989d576cbd15194c5d740745fd5ddf35958346
This commit is contained in:
Родитель
0d0b538b3e
Коммит
8c7e3d6e57
|
@ -196,7 +196,8 @@ public:
|
|||
JavaCallbacksSupport::AttachNative(
|
||||
mJavaCallbacks, mozilla::MakeUnique<CallbacksSupport>(this));
|
||||
|
||||
mJavaDecoder = CodecProxy::Create(mFormat,
|
||||
mJavaDecoder = CodecProxy::Create(false, // false indicates to create a decoder and true denotes encoder
|
||||
mFormat,
|
||||
mSurfaceTexture->JavaSurface(),
|
||||
mJavaCallbacks,
|
||||
mDrmStubId);
|
||||
|
@ -276,7 +277,7 @@ public:
|
|||
mJavaCallbacks, mozilla::MakeUnique<CallbacksSupport>(this));
|
||||
|
||||
mJavaDecoder =
|
||||
CodecProxy::Create(mFormat, nullptr, mJavaCallbacks, mDrmStubId);
|
||||
CodecProxy::Create(false, mFormat, nullptr, mJavaCallbacks, mDrmStubId);
|
||||
if (mJavaDecoder == nullptr) {
|
||||
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
|
||||
__func__);
|
||||
|
|
|
@ -24,4 +24,5 @@ interface ICodec {
|
|||
oneway void queueInput(in Sample sample);
|
||||
|
||||
oneway void releaseOutput(in Sample sample, in boolean render);
|
||||
oneway void setRates(in int newBitRate);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public interface AsyncCodec {
|
|||
public abstract ByteBuffer getInputBuffer(int index);
|
||||
public abstract ByteBuffer getOutputBuffer(int index);
|
||||
public abstract void queueInputBuffer(int index, int offset, int size, long presentationTimeUs, int flags);
|
||||
public abstract void setRates(int newBitRate);
|
||||
public abstract void queueSecureInputBuffer(int index, int offset, CryptoInfo info, long presentationTimeUs, int flags);
|
||||
public abstract void releaseOutputBuffer(int index, boolean render);
|
||||
}
|
||||
|
|
|
@ -339,7 +339,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
if (DEBUG) { Log.d(LOGTAG, "configure " + this); }
|
||||
|
||||
MediaFormat fmt = format.asFormat();
|
||||
String codecName = getDecoderForFormat(fmt);
|
||||
String codecName = getCodecForFormat(fmt, flags == MediaCodec.CONFIGURE_FLAG_ENCODE ? true : false);
|
||||
if (codecName == null) {
|
||||
Log.e(LOGTAG, "FAIL: cannot find codec");
|
||||
return false;
|
||||
|
@ -401,7 +401,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
mCodec = null;
|
||||
}
|
||||
|
||||
private String getDecoderForFormat(MediaFormat format) {
|
||||
private String getCodecForFormat(MediaFormat format, boolean isEncoder) {
|
||||
String mime = format.getString(MediaFormat.KEY_MIME);
|
||||
if (mime == null) {
|
||||
return null;
|
||||
|
@ -409,7 +409,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
int numCodecs = MediaCodecList.getCodecCount();
|
||||
for (int i = 0; i < numCodecs; i++) {
|
||||
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
|
||||
if (info.isEncoder()) {
|
||||
if (info.isEncoder() == !isEncoder) {
|
||||
continue;
|
||||
}
|
||||
String[] types = info.getSupportedTypes();
|
||||
|
@ -493,6 +493,15 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
mInputProcessor.onSample(sample);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setRates(int newBitRate) {
|
||||
try {
|
||||
mCodec.setRates(newBitRate);
|
||||
} catch (Exception e) {
|
||||
reportError(Error.FATAL, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void releaseOutput(Sample sample, boolean render) {
|
||||
try {
|
||||
|
|
|
@ -27,6 +27,7 @@ public final class CodecProxy {
|
|||
private static final boolean DEBUG = false;
|
||||
|
||||
private ICodec mRemote;
|
||||
private boolean mIsEncoder;
|
||||
private FormatParam mFormat;
|
||||
private Surface mOutputSurface;
|
||||
private CallbacksForwarder mCallbacks;
|
||||
|
@ -102,21 +103,24 @@ public final class CodecProxy {
|
|||
}
|
||||
|
||||
@WrapForJNI
|
||||
public static CodecProxy create(MediaFormat format,
|
||||
public static CodecProxy create(boolean isEncoder,
|
||||
MediaFormat format,
|
||||
Surface surface,
|
||||
Callbacks callbacks,
|
||||
String drmStubId) {
|
||||
return RemoteManager.getInstance().createCodec(format, surface, callbacks, drmStubId);
|
||||
return RemoteManager.getInstance().createCodec(isEncoder, format, surface, callbacks, drmStubId);
|
||||
}
|
||||
|
||||
public static CodecProxy createCodecProxy(MediaFormat format,
|
||||
public static CodecProxy createCodecProxy(boolean isEncoder,
|
||||
MediaFormat format,
|
||||
Surface surface,
|
||||
Callbacks callbacks,
|
||||
String drmStubId) {
|
||||
return new CodecProxy(format, surface, callbacks, drmStubId);
|
||||
return new CodecProxy(isEncoder, format, surface, callbacks, drmStubId);
|
||||
}
|
||||
|
||||
private CodecProxy(MediaFormat format, Surface surface, Callbacks callbacks, String drmStubId) {
|
||||
private CodecProxy(boolean isEncoder, MediaFormat format, Surface surface, Callbacks callbacks, String drmStubId) {
|
||||
mIsEncoder = isEncoder;
|
||||
mFormat = new FormatParam(format);
|
||||
mOutputSurface = surface;
|
||||
mRemoteDrmStubId = drmStubId;
|
||||
|
@ -126,7 +130,7 @@ public final class CodecProxy {
|
|||
boolean init(ICodec remote) {
|
||||
try {
|
||||
remote.setCallbacks(mCallbacks);
|
||||
if (!remote.configure(mFormat, mOutputSurface, 0, mRemoteDrmStubId)) {
|
||||
if (!remote.configure(mFormat, mOutputSurface, mIsEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0, mRemoteDrmStubId)) {
|
||||
return false;
|
||||
}
|
||||
remote.start();
|
||||
|
@ -257,6 +261,32 @@ public final class CodecProxy {
|
|||
return true;
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public synchronized boolean setRates(int newBitRate) {
|
||||
if (!mIsEncoder) {
|
||||
Log.w(LOGTAG, "this api is encoder-only");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 19) {
|
||||
Log.w(LOGTAG, "this api was added in API level 19");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mRemote == null) {
|
||||
Log.w(LOGTAG, "codec already ended");
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
mRemote.setRates(newBitRate);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOGTAG, "remote fail to set rates:" + newBitRate);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public synchronized boolean releaseOutput(Sample sample, boolean render) {
|
||||
if (!mSurfaceOutputs.remove(sample)) {
|
||||
|
|
|
@ -19,6 +19,11 @@ import java.nio.ByteBuffer;
|
|||
* <li>{@link MediaFormat#KEY_HEIGHT}</li>
|
||||
* <li>{@link MediaFormat#KEY_CHANNEL_COUNT}</li>
|
||||
* <li>{@link MediaFormat#KEY_SAMPLE_RATE}</li>
|
||||
* <li>{@link MediaFormat#KEY_BIT_RATE}</li>
|
||||
* <li>{@link MediaFormat#KEY_BITRATE_MODE}</li>
|
||||
* <li>{@link MediaFormat#KEY_COLOR_FORMAT}</li>
|
||||
* <li>{@link MediaFormat#KEY_FRAME_RATE}</li>
|
||||
* <li>{@link MediaFormat#KEY_I_FRAME_INTERVAL}</li>
|
||||
* <li>"csd-0"</li>
|
||||
* <li>"csd-1"</li>
|
||||
* </ul>
|
||||
|
@ -94,6 +99,26 @@ public final class FormatParam implements Parcelable {
|
|||
mFormat.setByteBuffer(KEY_CONFIG_1,
|
||||
ByteBuffer.wrap(bundle.getByteArray((KEY_CONFIG_1))));
|
||||
}
|
||||
if (bundle.containsKey(MediaFormat.KEY_BIT_RATE)) {
|
||||
mFormat.setInteger(MediaFormat.KEY_BIT_RATE,
|
||||
bundle.getInt(MediaFormat.KEY_BIT_RATE));
|
||||
}
|
||||
if (bundle.containsKey(MediaFormat.KEY_BITRATE_MODE)) {
|
||||
mFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
|
||||
bundle.getInt(MediaFormat.KEY_BITRATE_MODE));
|
||||
}
|
||||
if (bundle.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
|
||||
mFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
|
||||
bundle.getInt(MediaFormat.KEY_COLOR_FORMAT));
|
||||
}
|
||||
if (bundle.containsKey(MediaFormat.KEY_FRAME_RATE)) {
|
||||
mFormat.setInteger(MediaFormat.KEY_FRAME_RATE,
|
||||
bundle.getInt(MediaFormat.KEY_FRAME_RATE));
|
||||
}
|
||||
if (bundle.containsKey(MediaFormat.KEY_I_FRAME_INTERVAL)) {
|
||||
mFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
|
||||
bundle.getInt(MediaFormat.KEY_I_FRAME_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -128,6 +153,21 @@ public final class FormatParam implements Parcelable {
|
|||
bundle.putByteArray(KEY_CONFIG_1,
|
||||
Sample.byteArrayFromBuffer(bytes, 0, bytes.capacity()));
|
||||
}
|
||||
if (mFormat.containsKey(MediaFormat.KEY_BIT_RATE)) {
|
||||
bundle.putInt(MediaFormat.KEY_BIT_RATE, mFormat.getInteger(MediaFormat.KEY_BIT_RATE));
|
||||
}
|
||||
if (mFormat.containsKey(MediaFormat.KEY_BITRATE_MODE)) {
|
||||
bundle.putInt(MediaFormat.KEY_BITRATE_MODE, mFormat.getInteger(MediaFormat.KEY_BITRATE_MODE));
|
||||
}
|
||||
if (mFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
|
||||
bundle.putInt(MediaFormat.KEY_COLOR_FORMAT, mFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT));
|
||||
}
|
||||
if (mFormat.containsKey(MediaFormat.KEY_FRAME_RATE)) {
|
||||
bundle.putInt(MediaFormat.KEY_FRAME_RATE, mFormat.getInteger(MediaFormat.KEY_FRAME_RATE));
|
||||
}
|
||||
if (mFormat.containsKey(MediaFormat.KEY_I_FRAME_INTERVAL)) {
|
||||
bundle.putInt(MediaFormat.KEY_I_FRAME_INTERVAL, mFormat.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL));
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import android.os.Handler;
|
|||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
|
@ -332,12 +333,27 @@ final class JellyBeanAsyncCodec implements AsyncCodec {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setRates(int newBitRate) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 19) {
|
||||
Bundle params = new Bundle();
|
||||
params.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, newBitRate * 1000);
|
||||
mCodec.setParameters(params);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void queueInputBuffer(int index, int offset, int size, long presentationTimeUs, int flags) {
|
||||
assertCallbacks();
|
||||
|
||||
mInputEnded = (flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
|
||||
|
||||
if ((android.os.Build.VERSION.SDK_INT >= 19) && ((flags & MediaCodec.BUFFER_FLAG_KEY_FRAME) != 0)) {
|
||||
Bundle params = new Bundle();
|
||||
params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
|
||||
mCodec.setParameters(params);
|
||||
}
|
||||
|
||||
try {
|
||||
mCodec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
|
||||
} catch (IllegalStateException e) {
|
||||
|
|
|
@ -109,7 +109,8 @@ public final class RemoteManager implements IBinder.DeathRecipient {
|
|||
return mConnection.connect();
|
||||
}
|
||||
|
||||
public synchronized CodecProxy createCodec(MediaFormat format,
|
||||
public synchronized CodecProxy createCodec(boolean isEncoder,
|
||||
MediaFormat format,
|
||||
Surface surface,
|
||||
CodecProxy.Callbacks callbacks,
|
||||
String drmStubId) {
|
||||
|
@ -119,7 +120,7 @@ public final class RemoteManager implements IBinder.DeathRecipient {
|
|||
}
|
||||
try {
|
||||
ICodec remote = mRemote.createCodec();
|
||||
CodecProxy proxy = CodecProxy.createCodecProxy(format, surface, callbacks, drmStubId);
|
||||
CodecProxy proxy = CodecProxy.createCodecProxy(isEncoder, format, surface, callbacks, drmStubId);
|
||||
if (proxy.init(remote)) {
|
||||
mProxies.add(proxy);
|
||||
return proxy;
|
||||
|
|
|
@ -184,9 +184,9 @@ const char CodecProxy::name[] =
|
|||
constexpr char CodecProxy::Create_t::name[];
|
||||
constexpr char CodecProxy::Create_t::signature[];
|
||||
|
||||
auto CodecProxy::Create(mozilla::jni::Object::Param a0, mozilla::jni::Object::Param a1, mozilla::jni::Object::Param a2, mozilla::jni::String::Param a3) -> CodecProxy::LocalRef
|
||||
auto CodecProxy::Create(bool a0, mozilla::jni::Object::Param a1, mozilla::jni::Object::Param a2, mozilla::jni::Object::Param a3, mozilla::jni::String::Param a4) -> CodecProxy::LocalRef
|
||||
{
|
||||
return mozilla::jni::Method<Create_t>::Call(CodecProxy::Context(), nullptr, a0, a1, a2, a3);
|
||||
return mozilla::jni::Method<Create_t>::Call(CodecProxy::Context(), nullptr, a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
constexpr char CodecProxy::Flush_t::name[];
|
||||
|
@ -229,6 +229,14 @@ auto CodecProxy::ReleaseOutput(mozilla::jni::Object::Param a0, bool a1) const ->
|
|||
return mozilla::jni::Method<ReleaseOutput_t>::Call(CodecProxy::mCtx, nullptr, a0, a1);
|
||||
}
|
||||
|
||||
constexpr char CodecProxy::SetRates_t::name[];
|
||||
constexpr char CodecProxy::SetRates_t::signature[];
|
||||
|
||||
auto CodecProxy::SetRates(int32_t a0) const -> bool
|
||||
{
|
||||
return mozilla::jni::Method<SetRates_t>::Call(CodecProxy::mCtx, nullptr, a0);
|
||||
}
|
||||
|
||||
const char CodecProxy::NativeCallbacks::name[] =
|
||||
"org/mozilla/gecko/media/CodecProxy$NativeCallbacks";
|
||||
|
||||
|
|
|
@ -668,13 +668,14 @@ public:
|
|||
typedef CodecProxy::LocalRef ReturnType;
|
||||
typedef CodecProxy::Param SetterType;
|
||||
typedef mozilla::jni::Args<
|
||||
bool,
|
||||
mozilla::jni::Object::Param,
|
||||
mozilla::jni::Object::Param,
|
||||
mozilla::jni::Object::Param,
|
||||
mozilla::jni::String::Param> Args;
|
||||
static constexpr char name[] = "create";
|
||||
static constexpr char signature[] =
|
||||
"(Landroid/media/MediaFormat;Landroid/view/Surface;Lorg/mozilla/gecko/media/CodecProxy$Callbacks;Ljava/lang/String;)Lorg/mozilla/gecko/media/CodecProxy;";
|
||||
"(ZLandroid/media/MediaFormat;Landroid/view/Surface;Lorg/mozilla/gecko/media/CodecProxy$Callbacks;Ljava/lang/String;)Lorg/mozilla/gecko/media/CodecProxy;";
|
||||
static const bool isStatic = true;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
|
@ -684,7 +685,7 @@ public:
|
|||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
static auto Create(mozilla::jni::Object::Param, mozilla::jni::Object::Param, mozilla::jni::Object::Param, mozilla::jni::String::Param) -> CodecProxy::LocalRef;
|
||||
static auto Create(bool, mozilla::jni::Object::Param, mozilla::jni::Object::Param, mozilla::jni::Object::Param, mozilla::jni::String::Param) -> CodecProxy::LocalRef;
|
||||
|
||||
struct Flush_t {
|
||||
typedef CodecProxy Owner;
|
||||
|
@ -786,6 +787,26 @@ public:
|
|||
|
||||
auto ReleaseOutput(mozilla::jni::Object::Param, bool) const -> bool;
|
||||
|
||||
struct SetRates_t {
|
||||
typedef CodecProxy Owner;
|
||||
typedef bool ReturnType;
|
||||
typedef bool SetterType;
|
||||
typedef mozilla::jni::Args<
|
||||
int32_t> Args;
|
||||
static constexpr char name[] = "setRates";
|
||||
static constexpr char signature[] =
|
||||
"(I)Z";
|
||||
static const bool isStatic = false;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::ANY;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
auto SetRates(int32_t) const -> bool;
|
||||
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::ANY;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче