gecko-dev/dom/media/omx/MediaCodecProxy.h

184 lines
6.1 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MEDIA_CODEC_PROXY_H
#define MEDIA_CODEC_PROXY_H
#include <nsString.h>
#include <stagefright/MediaCodec.h>
#include <stagefright/MediaBuffer.h>
#include <utils/threads.h>
#include "mozilla/media/MediaSystemResourceClient.h"
#include "mozilla/Monitor.h"
#include "mozilla/MozPromise.h"
#include "mozilla/RefPtr.h"
namespace android {
// This class is intended to be a proxy for MediaCodec with codec resource
// management. Basically user can use it like MediaCodec, but need to handle
// the listener when Codec is reserved for Async case. A good example is
// MediaCodecReader.cpp. Another useage is to use configure(), Prepare(),
// Input(), and Output(). It is used in GonkVideoDecoderManager.cpp which
// doesn't need to handle the buffers for codec.
class MediaCodecProxy : public RefBase
, public mozilla::MediaSystemResourceReservationListener
{
public:
typedef mozilla::MozPromise<bool /* aIgnored */, bool /* aIgnored */, /* IsExclusive = */ true> CodecPromise;
enum Capability {
kEmptyCapability = 0x00000000,
kCanExposeGraphicBuffer = 0x00000001,
};
enum {
kKeyBufferIndex = 'bfin',
};
// Check whether MediaCodec has been allocated.
bool allocated() const;
// Static MediaCodec methods
// Only support MediaCodec::CreateByType()
static sp<MediaCodecProxy> CreateByType(sp<ALooper> aLooper,
const char *aMime,
bool aEncoder);
// MediaCodec methods
status_t configure(const sp<AMessage> &aFormat,
const sp<Surface> &aNativeWindow,
const sp<ICrypto> &aCrypto,
uint32_t aFlags);
status_t start();
status_t stop();
status_t release();
status_t flush();
status_t queueInputBuffer(size_t aIndex,
size_t aOffset,
size_t aSize,
int64_t aPresentationTimeUs,
uint32_t aFlags,
AString *aErrorDetailMessage=nullptr);
status_t queueSecureInputBuffer(size_t aIndex,
size_t aOffset,
const CryptoPlugin::SubSample *aSubSamples,
size_t aNumSubSamples,
const uint8_t aKey[16],
const uint8_t aIV[16],
CryptoPlugin::Mode aMode,
int64_t aPresentationTimeUs,
uint32_t aFlags,
AString *aErrorDetailMessage=nullptr);
status_t dequeueInputBuffer(size_t *aIndex,
int64_t aTimeoutUs=INT64_C(0));
status_t dequeueOutputBuffer(size_t *aIndex,
size_t *aOffset,
size_t *aSize,
int64_t *aPresentationTimeUs,
uint32_t *aFlags,
int64_t aTimeoutUs=INT64_C(0));
status_t renderOutputBufferAndRelease(size_t aIndex);
status_t releaseOutputBuffer(size_t aIndex);
status_t signalEndOfInputStream();
status_t getOutputFormat(sp<AMessage> *aFormat) const;
status_t getInputBuffers(Vector<sp<ABuffer>> *aBuffers) const;
status_t getOutputBuffers(Vector<sp<ABuffer>> *aBuffers) const;
// Notification will be posted once there "is something to do", i.e.
// an input/output buffer has become available, a format change is
// pending, an error is pending.
void requestActivityNotification(const sp<AMessage> &aNotify);
status_t getOutputGraphicBufferFromIndex(size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer);
status_t getCapability(uint32_t *aCapability);
// Utility functions
// If aData is null, will notify decoder input EOS
status_t Input(const uint8_t* aData, uint32_t aDataSize,
int64_t aTimestampUsecs, uint64_t flags, int64_t aTimeoutUs = 0);
status_t Output(MediaBuffer** aBuffer, int64_t aTimeoutUs);
bool Prepare();
void ReleaseMediaResources();
// This updates mOutputBuffer when receiving INFO_OUTPUT_BUFFERS_CHANGED event.
bool UpdateOutputBuffers();
void ReleaseMediaBuffer(MediaBuffer* abuffer);
// It allocates audio MediaCodec synchronously.
bool AllocateAudioMediaCodec();
// It allocates video MediaCodec asynchronously.
RefPtr<CodecPromise> AsyncAllocateVideoMediaCodec();
// Free the OMX codec so others can allocate it.
void ReleaseMediaCodec();
protected:
virtual ~MediaCodecProxy();
// MediaResourceReservationListener
void ResourceReserved() override;
void ResourceReserveFailed() override;
private:
// Forbidden
MediaCodecProxy() = delete;
MediaCodecProxy(const MediaCodecProxy &) = delete;
const MediaCodecProxy &operator=(const MediaCodecProxy &) = delete;
// Constructor for MediaCodecProxy::CreateByType
MediaCodecProxy(sp<ALooper> aLooper,
const char *aMime,
bool aEncoder);
// Allocate Codec Resource
bool allocateCodec();
// Release Codec Resource
void releaseCodec();
// MediaCodec Parameter
sp<ALooper> mCodecLooper;
nsCString mCodecMime;
bool mCodecEncoder;
mozilla::MozPromiseHolder<CodecPromise> mCodecPromise;
// When mPromiseMonitor is held, mResourceClient's functions should not be called.
mozilla::Monitor mPromiseMonitor;
// Media Resource Management
RefPtr<mozilla::MediaSystemResourceClient> mResourceClient;
// MediaCodec instance
mutable RWLock mCodecLock;
sp<MediaCodec> mCodec;
//MediaCodec buffers to hold input/output data.
Vector<sp<ABuffer> > mInputBuffers;
Vector<sp<ABuffer> > mOutputBuffers;
};
} // namespace android
#endif // MEDIA_CODEC_PROXY_H