Bug 1239607 - Collect codec info using MediaCodecList instead of OMXCodec. r=sotaro

This commit is contained in:
John Lin 2016-01-26 18:58:00 +01:00
parent 3051cd7932
commit 7db6a63ed3
3 changed files with 101 additions and 53 deletions

View File

@ -748,6 +748,7 @@ media/stagefright/foundation/hexdump.h
media/stagefright/MediaBuffer.h media/stagefright/MediaBuffer.h
media/stagefright/MediaBufferGroup.h media/stagefright/MediaBufferGroup.h
media/stagefright/MediaCodec.h media/stagefright/MediaCodec.h
media/stagefright/MediaCodecList.h
media/stagefright/MediaCodecSource.h media/stagefright/MediaCodecSource.h
media/stagefright/MediaDefs.h media/stagefright/MediaDefs.h
media/stagefright/MediaErrors.h media/stagefright/MediaErrors.h

View File

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "OmxDataDecoder.h" #include "OmxDataDecoder.h"
#include "OmxPromiseLayer.h"
#include "GonkOmxPlatformLayer.h" #include "GonkOmxPlatformLayer.h"
#include "MediaInfo.h" #include "MediaInfo.h"
#include "ImageContainer.h" #include "ImageContainer.h"
@ -16,7 +15,7 @@
#include <binder/MemoryDealer.h> #include <binder/MemoryDealer.h>
#include <media/IOMX.h> #include <media/IOMX.h>
#include <utils/List.h> #include <utils/List.h>
#include <media/stagefright/OMXCodec.h> #include <media/stagefright/MediaCodecList.h>
#include <cutils/properties.h> #include <cutils/properties.h>
extern mozilla::LogModule* GetPDMLog(); extern mozilla::LogModule* GetPDMLog();
@ -39,7 +38,10 @@ namespace mozilla {
extern void GetPortIndex(nsTArray<uint32_t>& aPortIndex); extern void GetPortIndex(nsTArray<uint32_t>& aPortIndex);
bool IsSoftwareCodec(const char* aComponentName) { // In Gonk, the software component name has prefix "OMX.google". It needs to
// have a way to use hardware codec first.
bool IsSoftwareCodec(const char* aComponentName)
{
nsAutoCString str(aComponentName); nsAutoCString str(aComponentName);
return (str.Find(NS_LITERAL_CSTRING("OMX.google.")) == -1 ? false : true); return (str.Find(NS_LITERAL_CSTRING("OMX.google.")) == -1 ? false : true);
} }
@ -134,7 +136,7 @@ protected:
RefPtr<TaskQueue> mTaskQueue; RefPtr<TaskQueue> mTaskQueue;
// TODO: // TODO:
// we should combine both event handlers into one. And we should provide // we should combine both event handlers into one. And we should provide
// an unified way for event handling in OmxPlatforLayer class. // an unified way for event handling in OmxPlatformLayer class.
RefPtr<OmxPromiseLayer> mPromiseLayer; RefPtr<OmxPromiseLayer> mPromiseLayer;
RefPtr<OmxDataDecoder> mClient; RefPtr<OmxDataDecoder> mClient;
}; };
@ -344,8 +346,6 @@ GonkOmxPlatformLayer::GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder,
: mTaskQueue(aTaskQueue) : mTaskQueue(aTaskQueue)
, mImageContainer(aImageContainer) , mImageContainer(aImageContainer)
, mNode(0) , mNode(0)
, mQuirks(0)
, mUsingHardwareCodec(false)
{ {
mOmxObserver = new GonkOmxObserver(mTaskQueue, aPromiseLayer, aDataDecoder); mOmxObserver = new GonkOmxObserver(mTaskQueue, aPromiseLayer, aDataDecoder);
} }
@ -379,8 +379,7 @@ GonkOmxPlatformLayer::AllocateOmxBuffer(OMX_DIRTYPE aType,
// Configure video output GraphicBuffer for video decoding acceleration. // Configure video output GraphicBuffer for video decoding acceleration.
bool useGralloc = false; bool useGralloc = false;
if ((aType == OMX_DirOutput) && if (aType == OMX_DirOutput && mQuirks.test(kRequiresAllocateBufferOnOutputPorts) &&
(mQuirks & OMXCodec::kRequiresAllocateBufferOnOutputPorts) &&
(def.eDomain == OMX_PortDomainVideo)) { (def.eDomain == OMX_PortDomainVideo)) {
if (NS_FAILED(EnableOmxGraphicBufferPort(def))) { if (NS_FAILED(EnableOmxGraphicBufferPort(def))) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -422,8 +421,8 @@ GonkOmxPlatformLayer::AllocateOmxBuffer(OMX_DIRTYPE aType,
sp<IMemory> mem = mMemoryDealer[aType]->allocate(def.nBufferSize); sp<IMemory> mem = mMemoryDealer[aType]->allocate(def.nBufferSize);
MOZ_ASSERT(mem.get()); MOZ_ASSERT(mem.get());
if ((mQuirks & OMXCodec::kRequiresAllocateBufferOnInputPorts && aType == OMX_DirInput) || if ((mQuirks.test(kRequiresAllocateBufferOnInputPorts) && aType == OMX_DirInput) ||
(mQuirks & OMXCodec::kRequiresAllocateBufferOnOutputPorts && aType == OMX_DirOutput)) { (mQuirks.test(kRequiresAllocateBufferOnOutputPorts) && aType == OMX_DirOutput)) {
// Buffer is lived remotely. We allocate a local OMX_BUFFERHEADERTYPE // Buffer is lived remotely. We allocate a local OMX_BUFFERHEADERTYPE
// as the mirror of the remote OMX_BUFFERHEADERTYPE. // as the mirror of the remote OMX_BUFFERHEADERTYPE.
st = mOmx->allocateBufferWithBackup(mNode, aType, mem, &bufferID); st = mOmx->allocateBufferWithBackup(mNode, aType, mem, &bufferID);
@ -533,38 +532,14 @@ GonkOmxPlatformLayer::InitOmxToStateLoaded(const TrackInfo* aInfo)
return OMX_ErrorUndefined; return OMX_ErrorUndefined;
} }
bool useHardwareCodecOnly = false;
// H264 and H263 has different profiles, software codec doesn't support high profile.
// So we use hardware codec only.
if (!IsInEmulator() &&
(mInfo->mMimeType.EqualsLiteral("video/avc") ||
mInfo->mMimeType.EqualsLiteral("video/mp4") ||
mInfo->mMimeType.EqualsLiteral("video/mp4v-es") ||
mInfo->mMimeType.EqualsLiteral("video/3gp"))) {
useHardwareCodecOnly = true;
}
LOG("find componenet for mime type %s", mInfo->mMimeType.Data()); LOG("find componenet for mime type %s", mInfo->mMimeType.Data());
// In Gonk, the software component name has prefix "OMX.google". It needs to
// have a way to use hardware codec first.
android::Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
nsTArray<const char*> components;
OMXCodec::findMatchingCodecs(mInfo->mMimeType.Data(),
0,
nullptr,
0,
&matchingCodecs);
for (uint32_t i = 0; i < matchingCodecs.size(); i++) {
components.AppendElement(matchingCodecs.itemAt(i).mName.string());
}
for (auto name : components) { nsTArray<ComponentInfo> components;
if (IsSoftwareCodec(name) && useHardwareCodecOnly) { if (FindComponents(mInfo->mMimeType, &components)) {
continue; for (auto comp : components) {
} if (LoadComponent(comp)) {
if (LoadComponent(name)) { return OMX_ErrorNone;
return OMX_ErrorNone; }
} }
} }
@ -606,13 +581,15 @@ GonkOmxPlatformLayer::InitOmxParameter(T* aParam)
} }
bool bool
GonkOmxPlatformLayer::LoadComponent(const char* aName) GonkOmxPlatformLayer::LoadComponent(const ComponentInfo& aComponent)
{ {
status_t err = mOmx->allocateNode(aName, mOmxObserver, &mNode); status_t err = mOmx->allocateNode(aComponent.mName, mOmxObserver, &mNode);
if (err == OK) { if (err == OK) {
OMXCodec::findCodecQuirks(aName, &mQuirks); mQuirks = aComponent.mQuirks;
LOG("Load OpenMax component %s, quirks %x, live locally %d", LOG("Load OpenMax component %s, alloc input %d, alloc output %d, live locally %d",
aName, mQuirks, mOmx->livesLocally(mNode, getpid())); aComponent.mName, mQuirks.test(kRequiresAllocateBufferOnInputPorts),
mQuirks.test(kRequiresAllocateBufferOnOutputPorts),
mOmx->livesLocally(mNode, getpid()));
return true; return true;
} }
return false; return false;
@ -630,4 +607,56 @@ GonkOmxPlatformLayer::GetTrackInfo()
return mInfo; return mInfo;
} }
bool
GonkOmxPlatformLayer::FindComponents(const nsACString& aMimeType,
nsTArray<ComponentInfo>* aComponents)
{
static const MediaCodecList* codecs = MediaCodecList::getInstance();
bool useHardwareCodecOnly = false;
// H264 and H263 has different profiles, software codec doesn't support high profile.
// So we use hardware codec only.
if (!IsInEmulator() &&
(aMimeType.EqualsLiteral("video/avc") ||
aMimeType.EqualsLiteral("video/mp4") ||
aMimeType.EqualsLiteral("video/mp4v-es") ||
aMimeType.EqualsLiteral("video/3gp"))) {
useHardwareCodecOnly = true;
}
size_t start = 0;
bool found = false;
while (true) {
ssize_t index = codecs->findCodecByType(aMimeType.Data(),
false /* encoder */,
start);
if (index < 0) {
break;
}
start = index + 1;
const char* name = codecs->getCodecName(index);
if (IsSoftwareCodec(name) && useHardwareCodecOnly) {
continue;
}
found = true;
if (!aComponents) {
continue;
}
ComponentInfo* comp = aComponents->AppendElement();
comp->mName = name;
if (codecs->codecHasQuirk(index, "requires-allocate-on-input-ports")) {
comp->mQuirks.set(kRequiresAllocateBufferOnInputPorts);
}
if (codecs->codecHasQuirk(index, "requires-allocate-on-output-ports")) {
comp->mQuirks.set(kRequiresAllocateBufferOnOutputPorts);
}
}
return found;
}
} // mozilla } // mozilla

View File

@ -9,11 +9,16 @@
#pragma GCC visibility push(default) #pragma GCC visibility push(default)
#include "OmxPlatformLayer.h" #include <bitset>
#include "OMX_Component.h"
#include <utils/RefBase.h> #include <utils/RefBase.h>
#include <media/stagefright/OMXClient.h> #include <media/stagefright/OMXClient.h>
#include "mozilla/layers/TextureClientRecycleAllocator.h"
#include "OMX_Component.h"
#include "OmxPlatformLayer.h"
class nsACString;
namespace android { namespace android {
class IMemory; class IMemory;
@ -105,6 +110,18 @@ public:
class GonkOmxPlatformLayer : public OmxPlatformLayer { class GonkOmxPlatformLayer : public OmxPlatformLayer {
public: public:
enum {
kRequiresAllocateBufferOnInputPorts = 0,
kRequiresAllocateBufferOnOutputPorts,
QUIRKS,
};
typedef std::bitset<QUIRKS> Quirks;
struct ComponentInfo {
const char* mName;
Quirks mQuirks;
};
GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder, GonkOmxPlatformLayer(OmxDataDecoder* aDataDecoder,
OmxPromiseLayer* aPromiseLayer, OmxPromiseLayer* aPromiseLayer,
TaskQueue* aTaskQueue, TaskQueue* aTaskQueue,
@ -141,6 +158,9 @@ public:
// to one function. // to one function.
template<class T> void InitOmxParameter(T* aParam); template<class T> void InitOmxParameter(T* aParam);
static bool FindComponents(const nsACString& aMimeType,
nsTArray<ComponentInfo>* aComponents = nullptr);
protected: protected:
friend GonkBufferData; friend GonkBufferData;
@ -155,7 +175,7 @@ protected:
nsresult EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef); nsresult EnableOmxGraphicBufferPort(OMX_PARAM_PORTDEFINITIONTYPE& aDef);
bool LoadComponent(const char* aName); bool LoadComponent(const ComponentInfo& aComponent);
friend class GonkOmxObserver; friend class GonkOmxObserver;
@ -174,11 +194,9 @@ protected:
android::OMXClient mOmxClient; android::OMXClient mOmxClient;
uint32_t mQuirks;
bool mUsingHardwareCodec;
const TrackInfo* mInfo; const TrackInfo* mInfo;
Quirks mQuirks;
}; };
} }