2014-07-11 03:01:30 +00:00
|
|
|
/* -*- 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>
|
2014-08-07 10:19:10 +00:00
|
|
|
#include <stagefright/MediaBuffer.h>
|
2014-07-11 03:01:30 +00:00
|
|
|
#include <utils/threads.h>
|
|
|
|
#include "MediaResourceHandler.h"
|
|
|
|
|
|
|
|
namespace android {
|
2014-08-07 10:19:10 +00:00
|
|
|
// 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.
|
2014-07-11 03:01:30 +00:00
|
|
|
class MediaCodecProxy : public MediaResourceHandler::ResourceListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/* Codec resource notification listener.
|
|
|
|
* All functions are called on the Binder thread.
|
|
|
|
*/
|
|
|
|
struct CodecResourceListener : public virtual RefBase {
|
|
|
|
/* The codec resource is reserved and can be granted.
|
|
|
|
* The client can allocate the requested resource.
|
|
|
|
*/
|
|
|
|
virtual void codecReserved() = 0;
|
|
|
|
/* The codec resource is not reserved any more.
|
|
|
|
* The client should release the resource as soon as possible if the
|
|
|
|
* resource is still being held.
|
|
|
|
*/
|
|
|
|
virtual void codecCanceled() = 0;
|
|
|
|
};
|
|
|
|
|
2014-09-11 02:15:17 +00:00
|
|
|
enum Capability {
|
|
|
|
kEmptyCapability = 0x00000000,
|
|
|
|
kCanExposeGraphicBuffer = 0x00000001,
|
|
|
|
};
|
|
|
|
|
2014-08-07 10:19:10 +00:00
|
|
|
enum {
|
|
|
|
kKeyBufferIndex = 'bfin',
|
|
|
|
};
|
2014-09-11 02:15:17 +00:00
|
|
|
|
2014-07-11 03:01:30 +00:00
|
|
|
// 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,
|
|
|
|
bool aAsync=false,
|
|
|
|
wp<CodecResourceListener> aListener=nullptr);
|
|
|
|
|
|
|
|
// 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);
|
2014-09-11 02:15:17 +00:00
|
|
|
|
|
|
|
status_t getOutputGraphicBufferFromIndex(size_t aIndex,
|
|
|
|
sp<GraphicBuffer> *aGraphicBuffer);
|
|
|
|
|
|
|
|
status_t getCapability(uint32_t *aCapability);
|
|
|
|
|
|
|
|
// Utility functions
|
|
|
|
|
2014-08-21 06:22:39 +00:00
|
|
|
// If aData is null, will notify decoder input EOS
|
2014-08-07 10:19:10 +00:00
|
|
|
status_t Input(const uint8_t* aData, uint32_t aDataSize,
|
|
|
|
int64_t aTimestampUsecs, uint64_t flags);
|
|
|
|
status_t Output(MediaBuffer** aBuffer, int64_t aTimeoutUs);
|
|
|
|
bool Prepare();
|
|
|
|
bool IsWaitingResources();
|
|
|
|
bool IsDormantNeeded();
|
2014-12-16 03:25:00 +00:00
|
|
|
void RequestMediaResources();
|
2014-08-07 10:19:10 +00:00
|
|
|
void ReleaseMediaResources();
|
2014-11-16 18:07:00 +00:00
|
|
|
// This updates mOutputBuffer when receiving INFO_OUTPUT_BUFFERS_CHANGED event.
|
|
|
|
bool UpdateOutputBuffers();
|
2014-09-11 02:15:17 +00:00
|
|
|
|
2014-11-12 09:34:21 +00:00
|
|
|
void ReleaseMediaBuffer(MediaBuffer* abuffer);
|
|
|
|
|
2014-07-11 03:01:30 +00:00
|
|
|
protected:
|
|
|
|
virtual ~MediaCodecProxy();
|
|
|
|
|
|
|
|
// MediaResourceHandler::EventListener::resourceReserved()
|
|
|
|
virtual void resourceReserved();
|
|
|
|
// MediaResourceHandler::EventListener::resourceCanceled()
|
|
|
|
virtual void resourceCanceled();
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Forbidden
|
2015-01-06 23:35:02 +00:00
|
|
|
MediaCodecProxy() = delete;
|
|
|
|
MediaCodecProxy(const MediaCodecProxy &) = delete;
|
|
|
|
const MediaCodecProxy &operator=(const MediaCodecProxy &) = delete;
|
2014-07-11 03:01:30 +00:00
|
|
|
|
|
|
|
// Constructor for MediaCodecProxy::CreateByType
|
|
|
|
MediaCodecProxy(sp<ALooper> aLooper,
|
|
|
|
const char *aMime,
|
|
|
|
bool aEncoder,
|
|
|
|
bool aAsync,
|
|
|
|
wp<CodecResourceListener> aListener);
|
|
|
|
|
|
|
|
// Request Resource
|
|
|
|
bool requestResource();
|
|
|
|
// Cancel Resource
|
|
|
|
void cancelResource();
|
|
|
|
|
|
|
|
// Allocate Codec Resource
|
|
|
|
bool allocateCodec();
|
|
|
|
// Release Codec Resource
|
|
|
|
void releaseCodec();
|
|
|
|
|
|
|
|
// MediaCodec Parameter
|
|
|
|
sp<ALooper> mCodecLooper;
|
|
|
|
nsCString mCodecMime;
|
|
|
|
bool mCodecEncoder;
|
|
|
|
|
|
|
|
// Codec Resource Notification Listener
|
|
|
|
wp<CodecResourceListener> mListener;
|
|
|
|
|
|
|
|
// Media Resource Management
|
|
|
|
sp<MediaResourceHandler> mResourceHandler;
|
|
|
|
|
|
|
|
// MediaCodec instance
|
|
|
|
mutable RWLock mCodecLock;
|
|
|
|
sp<MediaCodec> mCodec;
|
2014-09-11 02:15:17 +00:00
|
|
|
|
2014-08-07 10:19:10 +00:00
|
|
|
//MediaCodec buffers to hold input/output data.
|
|
|
|
Vector<sp<ABuffer> > mInputBuffers;
|
|
|
|
Vector<sp<ABuffer> > mOutputBuffers;
|
|
|
|
|
2014-07-11 03:01:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace android
|
|
|
|
|
|
|
|
#endif // MEDIA_CODEC_PROXY_H
|