Bug 1039182 - Add GraphicBuffer interface into MediaCodecProxy. r=sotaro

This commit is contained in:
Bruce Sun 2014-09-11 10:15:17 +08:00
Родитель 0f85a12a74
Коммит ad467d66d7
2 изменённых файлов: 103 добавлений и 0 удалений

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

@ -18,6 +18,62 @@
#define TIMEOUT_DEQUEUE_INPUTBUFFER_MS 1000000ll
namespace android {
// General Template: MediaCodec::getOutputGraphicBufferFromIndex(...)
template <typename T, bool InterfaceSupported>
struct OutputGraphicBufferStub
{
static status_t GetOutputGraphicBuffer(T *aMediaCodec,
size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
return ERROR_UNSUPPORTED;
}
};
// Class Template Specialization: MediaCodec::getOutputGraphicBufferFromIndex(...)
template <typename T>
struct OutputGraphicBufferStub<T, true>
{
static status_t GetOutputGraphicBuffer(T *aMediaCodec,
size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
if (aMediaCodec == nullptr || aGraphicBuffer == nullptr) {
return BAD_VALUE;
}
*aGraphicBuffer = aMediaCodec->getOutputGraphicBufferFromIndex(aIndex);
return OK;
}
};
// Wrapper class to handle interface-difference of MediaCodec.
struct MediaCodecInterfaceWrapper
{
typedef int8_t Supported;
typedef int16_t Unsupported;
template <typename T>
static auto TestOutputGraphicBuffer(T *aMediaCodec) -> decltype(aMediaCodec->getOutputGraphicBufferFromIndex(0), Supported());
template <typename T>
static auto TestOutputGraphicBuffer(...) -> Unsupported;
// SFINAE: Substitution Failure Is Not An Error
static const bool OutputGraphicBufferSupported = sizeof(TestOutputGraphicBuffer<MediaCodec>(nullptr)) == sizeof(Supported);
// Class Template Specialization
static OutputGraphicBufferStub<MediaCodec, OutputGraphicBufferSupported> sOutputGraphicBufferStub;
// Wrapper Function
static status_t GetOutputGraphicBuffer(MediaCodec *aMediaCodec,
size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
return sOutputGraphicBufferStub.GetOutputGraphicBuffer(aMediaCodec, aIndex, aGraphicBuffer);
}
};
sp<MediaCodecProxy>
MediaCodecProxy::CreateByType(sp<ALooper> aLooper,
const char *aMime,
@ -363,6 +419,37 @@ MediaCodecProxy::requestActivityNotification(const sp<AMessage> &aNotify)
mCodec->requestActivityNotification(aNotify);
}
status_t
MediaCodecProxy::getOutputGraphicBufferFromIndex(size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
// Read Lock for mCodec
RWLock::AutoRLock arl(mCodecLock);
if (mCodec == nullptr) {
return NO_INIT;
}
return MediaCodecInterfaceWrapper::GetOutputGraphicBuffer(mCodec.get(), aIndex, aGraphicBuffer);
}
status_t
MediaCodecProxy::getCapability(uint32_t *aCapability)
{
if (aCapability == nullptr) {
return BAD_VALUE;
}
uint32_t capability = kEmptyCapability;
if (MediaCodecInterfaceWrapper::OutputGraphicBufferSupported) {
capability |= kCanExposeGraphicBuffer;
}
*aCapability = capability;
return OK;
}
// Called on a Binder thread
void
MediaCodecProxy::resourceReserved()

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

@ -40,9 +40,15 @@ public:
virtual void codecCanceled() = 0;
};
enum Capability {
kEmptyCapability = 0x00000000,
kCanExposeGraphicBuffer = 0x00000001,
};
enum {
kKeyBufferIndex = 'bfin',
};
// Check whether MediaCodec has been allocated.
bool allocated() const;
@ -112,6 +118,14 @@ public:
// 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);
@ -120,6 +134,7 @@ public:
bool IsWaitingResources();
bool IsDormantNeeded();
void ReleaseMediaResources();
protected:
virtual ~MediaCodecProxy();
@ -165,6 +180,7 @@ private:
// MediaCodec instance
mutable RWLock mCodecLock;
sp<MediaCodec> mCodec;
//MediaCodec buffers to hold input/output data.
Vector<sp<ABuffer> > mInputBuffers;
Vector<sp<ABuffer> > mOutputBuffers;