stagefright: link CCodec directly with libstagefright

Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
Bug: 136283874
Change-Id: I7562c7770750baa733bca83a7f65f5ac0bd1b887
gugelfrei
Wonsik Kim 5 years ago
parent 1bd7d37742
commit 155d5cbd00

@ -30,6 +30,8 @@ cc_library {
name: "libstagefright_bufferpool@2.0.1",
defaults: ["libstagefright_bufferpool@2.0-default"],
vendor_available: true,
// TODO: b/147147992
double_loadable: true,
cflags: [
"-DBUFFERPOOL_CLONE_HANDLES",
],
@ -40,6 +42,8 @@ cc_library {
name: "libstagefright_bufferpool@2.0",
defaults: ["libstagefright_bufferpool@2.0-default"],
vendor_available: true,
// TODO: b/147147992
double_loadable: true,
vndk: {
enabled: true,
},

@ -10,6 +10,7 @@ cc_library_shared {
vndk: {
enabled: true,
},
double_loadable: true,
srcs: ["C2.cpp"],

@ -1,6 +1,8 @@
cc_library_shared {
name: "libsfplugin_ccodec",
export_include_dirs: ["include"],
srcs: [
"C2OMXNode.cpp",
"CCodec.cpp",
@ -11,7 +13,6 @@ cc_library_shared {
"Codec2InfoBuilder.cpp",
"PipelineWatcher.cpp",
"ReflectedParamUpdater.cpp",
"SkipCutBuffer.cpp",
],
cflags: [
@ -32,6 +33,7 @@ cc_library_shared {
"android.hardware.media.omx@1.0",
"libbase",
"libbinder",
"libcodec2",
"libcodec2_client",
"libcodec2_vndk",
"libcutils",
@ -51,6 +53,11 @@ cc_library_shared {
"libutils",
],
export_shared_lib_headers: [
"libcodec2",
"libcodec2_client",
],
sanitize: {
cfi: true,
misc_undefined: [

@ -40,13 +40,14 @@
#include <media/openmax/OMX_IndexExt.h>
#include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
#include <media/stagefright/omx/OmxGraphicBufferSource.h>
#include <media/stagefright/CCodec.h>
#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/PersistentSurface.h>
#include "C2OMXNode.h"
#include "CCodec.h"
#include "CCodecBufferChannel.h"
#include "CCodecConfig.h"
#include "InputSurfaceWrapper.h"
extern "C" android::PersistentSurface *CreateInputSurface();
@ -59,6 +60,7 @@ using android::base::StringPrintf;
using ::android::hardware::media::c2::V1_0::IInputSurface;
typedef hardware::media::omx::V1_0::IGraphicBufferSource HGraphicBufferSource;
typedef CCodecConfig Config;
namespace {
@ -571,7 +573,8 @@ private:
// CCodec
CCodec::CCodec()
: mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))) {
: mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))),
mConfig(new CCodecConfig) {
}
CCodec::~CCodec() {
@ -662,7 +665,8 @@ void CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) {
}
// initialize config here in case setParameters is called prior to configure
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
status_t err = config->initialize(mClient, comp);
if (err != OK) {
ALOGW("Failed to initialize configuration support");
@ -736,7 +740,8 @@ void CCodec::configure(const sp<AMessage> &msg) {
setSurface(surface);
}
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
config->mUsingSurface = surface != nullptr;
// Enforce required parameters
@ -1052,7 +1057,8 @@ void CCodec::configure(const sp<AMessage> &msg) {
return;
}
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat);
}
@ -1126,7 +1132,8 @@ void CCodec::createInputSurface() {
sp<AMessage> outputFormat;
uint64_t usage = 0;
{
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
inputFormat = config->mInputFormat;
outputFormat = config->mOutputFormat;
usage = config->mISConfig ? config->mISConfig->mUsage : 0;
@ -1170,7 +1177,8 @@ void CCodec::createInputSurface() {
}
status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) {
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
config->mUsingSurface = true;
// we are now using surface - apply default color aspects to input format - as well as
@ -1215,7 +1223,8 @@ void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
sp<AMessage> outputFormat;
uint64_t usage = 0;
{
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
inputFormat = config->mInputFormat;
outputFormat = config->mOutputFormat;
usage = config->mISConfig ? config->mISConfig->mUsage : 0;
@ -1291,7 +1300,8 @@ void CCodec::start() {
sp<AMessage> outputFormat;
status_t err2 = OK;
{
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
inputFormat = config->mInputFormat;
outputFormat = config->mOutputFormat;
if (config->mInputSurface) {
@ -1377,7 +1387,8 @@ void CCodec::stop() {
}
{
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
if (config->mInputSurface) {
config->mInputSurface->disconnect();
config->mInputSurface = nullptr;
@ -1425,7 +1436,8 @@ void CCodec::initiateRelease(bool sendCallback /* = true */) {
}
if (clearInputSurfaceIfNeeded) {
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
if (config->mInputSurface) {
config->mInputSurface->disconnect();
config->mInputSurface = nullptr;
@ -1583,7 +1595,8 @@ void CCodec::signalSetParameters(const sp<AMessage> &msg) {
params->removeEntryAt(params->findEntryByName(KEY_BIT_RATE));
}
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
/**
* Handle input surface parameters
@ -1642,7 +1655,8 @@ void CCodec::signalRequestIDRFrame() {
comp = state->comp;
}
ALOGV("request IDR");
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
std::vector<std::unique_ptr<C2Param>> params;
params.push_back(
std::make_unique<C2StreamRequestSyncFrameTuning::output>(0u, true));
@ -1661,7 +1675,8 @@ void CCodec::onInputBufferDone(uint64_t frameIndex, size_t arrayIndex) {
mChannel->onInputBufferDone(frameIndex, arrayIndex);
if (arrayIndex == 0) {
// We always put no more than one buffer per work, if we use an input surface.
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
if (config->mInputSurface) {
config->mInputSurface->onInputBufferDone(frameIndex);
}
@ -1738,7 +1753,8 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
}
// handle configuration changes in work done
Mutexed<Config>::Locked config(mConfig);
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
bool changed = false;
Config::Watcher<C2StreamInitDataInfo::output> initData =
config->watch<C2StreamInitDataInfo::output>();
@ -1867,14 +1883,8 @@ void CCodec::initiateReleaseIfStuck() {
mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
}
} // namespace android
extern "C" android::CodecBase *CreateCodec() {
return new android::CCodec;
}
// Create Codec 2.0 input surface
extern "C" android::PersistentSurface *CreateInputSurface() {
// static
PersistentSurface *CCodec::CreateInputSurface() {
using namespace android;
using ::android::hardware::media::omx::V1_0::implementation::TWGraphicBufferSource;
// Attempt to create a Codec2's input surface.
@ -1901,3 +1911,5 @@ extern "C" android::PersistentSurface *CreateInputSurface() {
inputSurface->getHalInterface()));
}
} // namespace android

@ -41,12 +41,12 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SkipCutBuffer.h>
#include <media/MediaCodecBuffer.h>
#include <system/window.h>
#include "CCodecBufferChannel.h"
#include "Codec2Buffer.h"
#include "SkipCutBuffer.h"
namespace android {

@ -22,6 +22,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SkipCutBuffer.h>
#include "CCodecBuffers.h"

@ -25,10 +25,11 @@
#include <media/MediaCodecBuffer.h>
#include "Codec2Buffer.h"
#include "SkipCutBuffer.h"
namespace android {
class SkipCutBuffer;
constexpr size_t kLinearBufferSize = 1048576;
// This can fit 4K RGBA frame, and most likely client won't need more than this.
constexpr size_t kMaxLinearBufferSize = 4096 * 2304 * 4;

@ -43,13 +43,12 @@
#include <codec2/hidl/client.h>
#include <cutils/native_handle.h>
#include <media/omx/1.0/WOmxNode.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/foundation/ALookup.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
#include "Codec2InfoBuilder.h"
#include <media/stagefright/Codec2InfoBuilder.h>
#include <media/stagefright/MediaCodecConstants.h>
namespace android {

@ -1,206 +0,0 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "SkipCutBuffer"
#include <utils/Log.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBuffer.h>
#include "SkipCutBuffer.h"
namespace android {
SkipCutBuffer::SkipCutBuffer(size_t skip, size_t cut, size_t num16BitChannels) {
mWriteHead = 0;
mReadHead = 0;
mCapacity = 0;
mCutBuffer = nullptr;
if (num16BitChannels == 0 || num16BitChannels > INT32_MAX / 2) {
ALOGW("# channels out of range: %zu, using passthrough instead", num16BitChannels);
return;
}
size_t frameSize = num16BitChannels * 2;
if (skip > INT32_MAX / frameSize || cut > INT32_MAX / frameSize
|| cut * frameSize > INT32_MAX - 4096) {
ALOGW("out of range skip/cut: %zu/%zu, using passthrough instead",
skip, cut);
return;
}
skip *= frameSize;
cut *= frameSize;
mFrontPadding = mSkip = skip;
mBackPadding = cut;
mCapacity = cut + 4096;
mCutBuffer = new (std::nothrow) char[mCapacity];
ALOGV("skipcutbuffer %zu %zu %d", skip, cut, mCapacity);
}
SkipCutBuffer::~SkipCutBuffer() {
delete[] mCutBuffer;
}
void SkipCutBuffer::submit(MediaBuffer *buffer) {
if (mCutBuffer == nullptr) {
// passthrough mode
return;
}
int32_t offset = buffer->range_offset();
int32_t buflen = buffer->range_length();
// drop the initial data from the buffer if needed
if (mFrontPadding > 0) {
// still data left to drop
int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
offset += to_drop;
buflen -= to_drop;
buffer->set_range(offset, buflen);
mFrontPadding -= to_drop;
}
// append data to cutbuffer
char *src = ((char*) buffer->data()) + offset;
write(src, buflen);
// the mediabuffer is now empty. Fill it from cutbuffer, always leaving
// at least mBackPadding bytes in the cutbuffer
char *dst = (char*) buffer->data();
size_t copied = read(dst, buffer->size());
buffer->set_range(0, copied);
}
template <typename T>
void SkipCutBuffer::submitInternal(const sp<T>& buffer) {
if (mCutBuffer == nullptr) {
// passthrough mode
return;
}
int32_t offset = buffer->offset();
int32_t buflen = buffer->size();
// drop the initial data from the buffer if needed
if (mFrontPadding > 0) {
// still data left to drop
int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
offset += to_drop;
buflen -= to_drop;
buffer->setRange(offset, buflen);
mFrontPadding -= to_drop;
}
// append data to cutbuffer
char *src = (char*) buffer->data();
write(src, buflen);
// the mediabuffer is now empty. Fill it from cutbuffer, always leaving
// at least mBackPadding bytes in the cutbuffer
char *dst = (char*) buffer->base();
size_t copied = read(dst, buffer->capacity());
buffer->setRange(0, copied);
}
void SkipCutBuffer::submit(const sp<ABuffer>& buffer) {
submitInternal(buffer);
}
void SkipCutBuffer::submit(const sp<MediaCodecBuffer>& buffer) {
submitInternal(buffer);
}
void SkipCutBuffer::clear() {
mWriteHead = mReadHead = 0;
mFrontPadding = mSkip;
}
void SkipCutBuffer::write(const char *src, size_t num) {
int32_t sizeused = (mWriteHead - mReadHead);
if (sizeused < 0) sizeused += mCapacity;
// Everything must fit. Make sure the buffer is a little larger than needed,
// so there is no ambiguity as to whether mWriteHead == mReadHead means buffer
// full or empty
size_t available = mCapacity - sizeused - 32;
if (available < num) {
int32_t newcapacity = mCapacity + (num - available);
char * newbuffer = new char[newcapacity];
memcpy(newbuffer, mCutBuffer, mCapacity);
delete [] mCutBuffer;
mCapacity = newcapacity;
mCutBuffer = newbuffer;
ALOGV("reallocated buffer at size %d", newcapacity);
}
size_t copyfirst = (mCapacity - mWriteHead);
if (copyfirst > num) copyfirst = num;
if (copyfirst) {
memcpy(mCutBuffer + mWriteHead, src, copyfirst);
num -= copyfirst;
src += copyfirst;
mWriteHead += copyfirst;
CHECK_LE(mWriteHead, mCapacity);
if (mWriteHead == mCapacity) mWriteHead = 0;
if (num) {
memcpy(mCutBuffer, src, num);
mWriteHead += num;
}
}
}
size_t SkipCutBuffer::read(char *dst, size_t num) {
int32_t available = (mWriteHead - mReadHead);
if (available < 0) available += mCapacity;
available -= mBackPadding;
if (available <=0) {
return 0;
}
if (available < int32_t(num)) {
num = available;
}
size_t copyfirst = (mCapacity - mReadHead);
if (copyfirst > num) copyfirst = num;
if (copyfirst) {
memcpy(dst, mCutBuffer + mReadHead, copyfirst);
num -= copyfirst;
dst += copyfirst;
mReadHead += copyfirst;
CHECK_LE(mReadHead, mCapacity);
if (mReadHead == mCapacity) mReadHead = 0;
if (num) {
memcpy(dst, mCutBuffer, num);
mReadHead += num;
}
}
return available;
}
size_t SkipCutBuffer::size() {
int32_t available = (mWriteHead - mReadHead);
if (available < 0) available += mCapacity;
return available;
}
} // namespace android

@ -1,67 +0,0 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SKIP_CUT_BUFFER_H_
#define SKIP_CUT_BUFFER_H_
#include <media/MediaCodecBuffer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/foundation/ABuffer.h>
namespace android {
/**
* utility class to cut the start and end off a stream of data in MediaBuffers
*
*/
class SkipCutBuffer: public RefBase {
public:
// 'skip' is the number of frames to skip from the beginning
// 'cut' is the number of frames to cut from the end
// 'num16BitChannels' is the number of channels, which are assumed to be 16 bit wide each
SkipCutBuffer(size_t skip, size_t cut, size_t num16Channels);
// Submit one MediaBuffer for skipping and cutting. This may consume all or
// some of the data in the buffer, or it may add data to it.
// After this, the caller should continue processing the buffer as usual.
void submit(MediaBuffer *buffer);
void submit(const sp<ABuffer>& buffer); // same as above, but with an ABuffer
void submit(const sp<MediaCodecBuffer>& buffer); // same as above, but with an ABuffer
void clear();
size_t size(); // how many bytes are currently stored in the buffer
protected:
virtual ~SkipCutBuffer();
private:
void write(const char *src, size_t num);
size_t read(char *dst, size_t num);
template <typename T>
void submitInternal(const sp<T>& buffer);
int32_t mSkip;
int32_t mFrontPadding;
int32_t mBackPadding;
int32_t mWriteHead;
int32_t mReadHead;
int32_t mCapacity;
char* mCutBuffer;
DISALLOW_EVIL_CONSTRUCTORS(SkipCutBuffer);
};
} // namespace android
#endif // OMX_CODEC_H_

@ -36,12 +36,11 @@
#include <hardware/gralloc.h>
#include <nativebase/nativebase.h>
#include "CCodecConfig.h"
namespace android {
class CCodecBufferChannel;
class InputSurfaceWrapper;
struct CCodecConfig;
struct MediaCodecInfo;
class CCodec : public CodecBase {
@ -69,6 +68,8 @@ public:
void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems);
void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex);
static PersistentSurface *CreateInputSurface();
protected:
virtual ~CCodec();
@ -173,7 +174,7 @@ private:
Mutexed<NamedTimePoint> mDeadline;
typedef CCodecConfig Config;
Mutexed<Config> mConfig;
Mutexed<std::unique_ptr<CCodecConfig>> mConfig;
Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
friend class CCodecCallbackImpl;

@ -1,6 +1,7 @@
cc_library_shared {
name: "libsfplugin_ccodec_utils",
vendor_available: true,
double_loadable: true,
srcs: [
"Codec2BufferUtils.cpp",

@ -14,6 +14,8 @@ cc_library_headers {
cc_library_shared {
name: "libcodec2_vndk",
vendor_available: true,
// TODO: b/147147883
double_loadable: true,
srcs: [
"C2AllocatorBlob.cpp",

@ -53,6 +53,7 @@ cc_library_shared {
"CodecBase.cpp",
"FrameRenderTracker.cpp",
"MediaCodecListWriter.cpp",
"SkipCutBuffer.cpp",
],
cflags: [
@ -62,6 +63,7 @@ cc_library_shared {
header_libs: [
"libmediadrm_headers",
"media_ndk_headers",
],
shared_libs: [
@ -69,6 +71,7 @@ cc_library_shared {
"libhidlallocatorutils",
"liblog",
"libmedia_codeclist",
"libmedia_omx",
"libstagefright_foundation",
"libui",
"libutils",
@ -212,9 +215,7 @@ cc_library {
"RemoteMediaExtractor.cpp",
"RemoteMediaSource.cpp",
"SimpleDecodingSource.cpp",
"SkipCutBuffer.cpp",
"StagefrightMediaScanner.cpp",
"StagefrightPluginLoader.cpp",
"SurfaceUtils.cpp",
"ThrottledSource.cpp",
"Utils.cpp",
@ -244,6 +245,7 @@ cc_library {
"libui",
"libutils",
"libmedia_helper",
"libsfplugin_ccodec",
"libstagefright_codecbase",
"libstagefright_foundation",
"libstagefright_omx_utils",

@ -22,7 +22,6 @@
#include <stdlib.h>
#include "include/SoftwareRenderer.h"
#include "StagefrightPluginLoader.h"
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
@ -51,6 +50,7 @@
#include <media/stagefright/ACodec.h>
#include <media/stagefright/BatteryChecker.h>
#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/CCodec.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
@ -538,9 +538,7 @@ sp<MediaCodec> MediaCodec::CreateByComponentName(
// static
sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
// allow plugin to create surface
sp<PersistentSurface> pluginSurface =
StagefrightPluginLoader::GetCCodecInstance()->createInputSurface();
sp<PersistentSurface> pluginSurface = CCodec::CreateInputSurface();
if (pluginSurface != nullptr) {
return pluginSurface;
}
@ -969,7 +967,7 @@ void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err)
}
static CodecBase *CreateCCodec() {
return StagefrightPluginLoader::GetCCodecInstance()->createCodec();
return new CCodec;
}
//static

@ -19,7 +19,6 @@
#include <utils/Log.h>
#include "MediaCodecListOverrides.h"
#include "StagefrightPluginLoader.h"
#include <binder/IServiceManager.h>
@ -30,11 +29,14 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
#include <media/stagefright/CCodec.h>
#include <media/stagefright/Codec2InfoBuilder.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/OmxInfoBuilder.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h>
#include <media/stagefright/PersistentSurface.h>
#include <sys/stat.h>
#include <utils/threads.h>
@ -86,8 +88,7 @@ std::unique_ptr<MediaCodecListBuilderBase> sCodec2InfoBuilder;
MediaCodecListBuilderBase *GetCodec2InfoBuilder() {
Mutex::Autolock _l(sCodec2InfoBuilderMutex);
if (!sCodec2InfoBuilder) {
sCodec2InfoBuilder.reset(
StagefrightPluginLoader::GetCCodecInstance()->createBuilder());
sCodec2InfoBuilder.reset(new Codec2InfoBuilder);
}
return sCodec2InfoBuilder.get();
}
@ -96,8 +97,7 @@ std::vector<MediaCodecListBuilderBase *> GetBuilders() {
std::vector<MediaCodecListBuilderBase *> builders;
// if plugin provides the input surface, we cannot use OMX video encoders.
// In this case, rely on plugin to provide list of OMX codecs that are usable.
sp<PersistentSurface> surfaceTest =
StagefrightPluginLoader::GetCCodecInstance()->createInputSurface();
sp<PersistentSurface> surfaceTest = CCodec::CreateInputSurface();
if (surfaceTest == nullptr) {
ALOGD("Allowing all OMX codecs");
builders.push_back(&sOmxInfoBuilder);

@ -1,104 +0,0 @@
/*
* Copyright 2018, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "StagefrightPluginLoader"
#include <utils/Log.h>
#include <android-base/properties.h>
#include <dlfcn.h>
#include "StagefrightPluginLoader.h"
namespace android {
/* static */ Mutex StagefrightPluginLoader::sMutex;
/* static */ std::unique_ptr<StagefrightPluginLoader> StagefrightPluginLoader::sInstance;
namespace /* unnamed */ {
constexpr const char kCCodecPluginPath[] = "libsfplugin_ccodec.so";
} // unnamed namespace
StagefrightPluginLoader::StagefrightPluginLoader(const char *libPath) {
if (android::base::GetIntProperty("debug.stagefright.ccodec", 1) == 0) {
ALOGD("CCodec is disabled.");
return;
}
mLibHandle = dlopen(libPath, RTLD_NOW | RTLD_NODELETE);
if (mLibHandle == nullptr) {
ALOGD("Failed to load library: %s (%s)", libPath, dlerror());
return;
}
mCreateCodec = (CodecBase::CreateCodecFunc)dlsym(mLibHandle, "CreateCodec");
if (mCreateCodec == nullptr) {
ALOGD("Failed to find symbol: CreateCodec (%s)", dlerror());
}
mCreateBuilder = (MediaCodecListBuilderBase::CreateBuilderFunc)dlsym(
mLibHandle, "CreateBuilder");
if (mCreateBuilder == nullptr) {
ALOGD("Failed to find symbol: CreateBuilder (%s)", dlerror());
}
mCreateInputSurface = (CodecBase::CreateInputSurfaceFunc)dlsym(
mLibHandle, "CreateInputSurface");
if (mCreateInputSurface == nullptr) {
ALOGD("Failed to find symbol: CreateInputSurface (%s)", dlerror());
}
}
StagefrightPluginLoader::~StagefrightPluginLoader() {
if (mLibHandle != nullptr) {
ALOGV("Closing handle");
dlclose(mLibHandle);
}
}
CodecBase *StagefrightPluginLoader::createCodec() {
if (mLibHandle == nullptr || mCreateCodec == nullptr) {
ALOGD("Handle or CreateCodec symbol is null");
return nullptr;
}
return mCreateCodec();
}
MediaCodecListBuilderBase *StagefrightPluginLoader::createBuilder() {
if (mLibHandle == nullptr || mCreateBuilder == nullptr) {
ALOGD("Handle or CreateBuilder symbol is null");
return nullptr;
}
return mCreateBuilder();
}
PersistentSurface *StagefrightPluginLoader::createInputSurface() {
if (mLibHandle == nullptr || mCreateInputSurface == nullptr) {
ALOGD("Handle or CreateInputSurface symbol is null");
return nullptr;
}
return mCreateInputSurface();
}
//static
const std::unique_ptr<StagefrightPluginLoader> &StagefrightPluginLoader::GetCCodecInstance() {
Mutex::Autolock _l(sMutex);
if (!sInstance) {
ALOGV("Loading library");
sInstance.reset(new StagefrightPluginLoader(kCCodecPluginPath));
}
return sInstance;
}
} // namespace android

@ -1,51 +0,0 @@
/*
* Copyright 2018, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef STAGEFRIGHT_PLUGIN_LOADER_H_
#define STAGEFRIGHT_PLUGIN_LOADER_H_
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/MediaCodecListWriter.h>
#include <media/stagefright/PersistentSurface.h>
#include <utils/Mutex.h>
namespace android {
class StagefrightPluginLoader {
public:
static const std::unique_ptr<StagefrightPluginLoader> &GetCCodecInstance();
~StagefrightPluginLoader();
CodecBase *createCodec();
MediaCodecListBuilderBase *createBuilder();
PersistentSurface *createInputSurface();
private:
explicit StagefrightPluginLoader(const char *libPath);
static Mutex sMutex;
static std::unique_ptr<StagefrightPluginLoader> sInstance;
void *mLibHandle{nullptr};
CodecBase::CreateCodecFunc mCreateCodec{nullptr};
MediaCodecListBuilderBase::CreateBuilderFunc mCreateBuilder{nullptr};
CodecBase::CreateInputSurfaceFunc mCreateInputSurface{nullptr};
};
} // namespace android
#endif // STAGEFRIGHT_PLUGIN_LOADER_H_

@ -4,6 +4,7 @@ cc_library_shared {
vndk: {
enabled: true,
},
double_loadable: true,
srcs: [
"OMXMaster.cpp",

@ -10,6 +10,7 @@ cc_library_shared {
vndk: {
enabled: true,
},
double_loadable: true,
srcs: [
"MediaCodecsXmlParser.cpp",

Loading…
Cancel
Save