Bug 1320618 - Check if codec supports adaptive playback to determine the decoder support recycling or not. r=jolin

MozReview-Commit-ID: C3pI9NCUgiP

--HG--
extra : rebase_source : c9da5d21ee76e660ea5a18f77b1ea6bccd14286d
This commit is contained in:
James Cheng 2016-11-30 16:30:16 +08:00
Родитель b75421fe79
Коммит 2fca45e7dc
10 изменённых файлов: 84 добавлений и 17 удалений

Просмотреть файл

@ -123,7 +123,7 @@ public:
return NS_OK;
}
bool SupportDecoderRecycling() const override { return true; }
bool SupportDecoderRecycling() const override { return mIsCodecSupportAdaptivePlayback; }
protected:
layers::ImageContainer* mImageContainer;
@ -383,11 +383,15 @@ MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
}
// Check if the video codec supports adaptive playback or not.
if (aSurface && java::HardwareCodecCapabilityUtils::CheckSupportsAdaptivePlayback(
mDecoder, nsCString(TranslateMimeType(mMimeType)))) {
// TODO: may need to find a way to not use hard code to decide the max w/h.
mFormat->SetInteger(MediaFormat::KEY_MAX_WIDTH, 1920);
mFormat->SetInteger(MediaFormat::KEY_MAX_HEIGHT, 1080);
if (aSurface) {
mIsCodecSupportAdaptivePlayback =
java::HardwareCodecCapabilityUtils::CheckSupportsAdaptivePlayback(mDecoder,
nsCString(TranslateMimeType(mMimeType)));
if (mIsCodecSupportAdaptivePlayback) {
// TODO: may need to find a way to not use hard code to decide the max w/h.
mFormat->SetInteger(MediaFormat::KEY_MAX_WIDTH, 1920);
mFormat->SetInteger(MediaFormat::KEY_MAX_HEIGHT, 1080);
}
}
MediaCrypto::LocalRef crypto = MediaDrmProxy::GetMediaCrypto(mDrmStubId);

Просмотреть файл

@ -128,6 +128,8 @@ protected:
std::deque<media::TimeUnit> mDurations;
nsString mDrmStubId;
bool mIsCodecSupportAdaptivePlayback = false;
};
} // namespace mozilla

Просмотреть файл

@ -221,7 +221,7 @@ public:
if (mJavaDecoder == nullptr) {
return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
}
mIsCodecSupportAdaptivePlayback = mJavaDecoder->IsAdaptivePlaybackSupported();
mInputDurations.Clear();
return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
@ -245,7 +245,7 @@ public:
mInputDurations.Put(aSample->mDuration);
}
bool SupportDecoderRecycling() const override { return true; }
bool SupportDecoderRecycling() const override { return mIsCodecSupportAdaptivePlayback; }
private:
class DurationQueue {
@ -281,6 +281,7 @@ private:
const VideoInfo& mConfig;
RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
DurationQueue mInputDurations;
bool mIsCodecSupportAdaptivePlayback = false;
};
class RemoteAudioDecoder final : public RemoteDataDecoder

Просмотреть файл

@ -14,6 +14,7 @@ import org.mozilla.gecko.media.Sample;
interface ICodec {
void setCallbacks(in ICodecCallbacks callbacks);
boolean configure(in FormatParam format, inout Surface surface, int flags, in String drmStubId);
boolean isAdaptivePlaybackSupported();
oneway void start();
oneway void stop();
oneway void flush();

Просмотреть файл

@ -25,6 +25,7 @@ public interface AsyncCodec {
public abstract void setCallbacks(Callbacks callbacks, Handler handler);
public abstract void configure(MediaFormat format, Surface surface, MediaCrypto crypto, int flags);
public abstract boolean isAdaptivePlaybackSupported(String mimeType);
public abstract void start();
public abstract void stop();
public abstract void flush();

Просмотреть файл

@ -203,6 +203,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
private volatile boolean mFlushing = false;
private SamplePool mSamplePool;
private Queue<Sample> mSentOutputs = new ConcurrentLinkedQueue<>();
// Value will be updated after configure called.
private volatile boolean mIsAdaptivePlaybackSupported = false;
public synchronized void setCallbacks(ICodecCallbacks callbacks) throws RemoteException {
mCallbacks = callbacks;
@ -254,6 +256,19 @@ import java.util.concurrent.ConcurrentLinkedQueue;
}
codec.setCallbacks(new Callbacks(mCallbacks), null);
// Video decoder should config with adaptive playback capability.
if (surface != null) {
mIsAdaptivePlaybackSupported = codec.isAdaptivePlaybackSupported(
fmt.getString(MediaFormat.KEY_MIME));
if (mIsAdaptivePlaybackSupported) {
if (DEBUG) Log.d(LOGTAG, "codec supports adaptive playback = " + mIsAdaptivePlaybackSupported);
// TODO: may need to find a way to not use hard code to decide the max w/h.
fmt.setInteger(MediaFormat.KEY_MAX_WIDTH, 1920);
fmt.setInteger(MediaFormat.KEY_MAX_HEIGHT, 1080);
}
}
codec.configure(fmt, surface, crypto, flags);
mCodec = codec;
mInputProcessor = new InputProcessor();
@ -267,6 +282,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
}
}
@Override
public synchronized boolean isAdaptivePlaybackSupported() {
return mIsAdaptivePlaybackSupported;
}
private void releaseCodec() {
mInputProcessor.reset();
try {

Просмотреть файл

@ -130,6 +130,21 @@ public final class CodecProxy {
}
}
@WrapForJNI
public synchronized boolean isAdaptivePlaybackSupported()
{
if (mRemote == null) {
Log.e(LOGTAG, "cannot check isAdaptivePlaybackSupported with an ended codec");
return false;
}
try {
return mRemote.isAdaptivePlaybackSupported();
} catch (RemoteException e) {
e.printStackTrace();
return false;
}
}
@WrapForJNI
public synchronized boolean input(ByteBuffer bytes, BufferInfo info, CryptoInfo cryptoInfo) {
if (mRemote == null) {

Просмотреть файл

@ -298,18 +298,14 @@ final class JellyBeanAsyncCodec implements AsyncCodec {
public void configure(MediaFormat format, Surface surface, MediaCrypto crypto, int flags) {
assertCallbacks();
// Video decoder should config with adaptive playback capability.
if (surface != null) {
if (HardwareCodecCapabilityUtils.checkSupportsAdaptivePlayback(
mCodec, format.getString(MediaFormat.KEY_MIME))) {
// TODO: may need to find a way to not use hard code to decide the max w/h.
format.setInteger(MediaFormat.KEY_MAX_WIDTH, 1920);
format.setInteger(MediaFormat.KEY_MAX_HEIGHT, 1080);
}
}
mCodec.configure(format, surface, crypto, flags);
}
@Override
public boolean isAdaptivePlaybackSupported(String mimeType) {
return HardwareCodecCapabilityUtils.checkSupportsAdaptivePlayback(mCodec, mimeType);
}
private void assertCallbacks() {
if (mCallbackSender == null) {
throw new IllegalStateException(LOGTAG + ": callback must be supplied with setCallbacks().");

Просмотреть файл

@ -205,6 +205,14 @@ auto CodecProxy::Input(mozilla::jni::ByteBuffer::Param a0, mozilla::jni::Object:
return mozilla::jni::Method<Input_t>::Call(CodecProxy::mCtx, nullptr, a0, a1, a2);
}
constexpr char CodecProxy::IsAdaptivePlaybackSupported_t::name[];
constexpr char CodecProxy::IsAdaptivePlaybackSupported_t::signature[];
auto CodecProxy::IsAdaptivePlaybackSupported() const -> bool
{
return mozilla::jni::Method<IsAdaptivePlaybackSupported_t>::Call(CodecProxy::mCtx, nullptr);
}
constexpr char CodecProxy::Release_t::name[];
constexpr char CodecProxy::Release_t::signature[];

Просмотреть файл

@ -727,6 +727,25 @@ public:
auto Input(mozilla::jni::ByteBuffer::Param, mozilla::jni::Object::Param, mozilla::jni::Object::Param) const -> bool;
struct IsAdaptivePlaybackSupported_t {
typedef CodecProxy Owner;
typedef bool ReturnType;
typedef bool SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "isAdaptivePlaybackSupported";
static constexpr char signature[] =
"()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 IsAdaptivePlaybackSupported() const -> bool;
struct Release_t {
typedef CodecProxy Owner;
typedef bool ReturnType;