зеркало из https://github.com/mozilla/gecko-dev.git
184 строки
6.1 KiB
C++
184 строки
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
|