mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-10 11:54:40 +00:00
221 lines
5.9 KiB
C++
221 lines
5.9 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/. */
|
|
|
|
#include "I420ColorConverterHelper.h"
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#include "mozilla/Logging.h"
|
|
|
|
mozilla::LazyLogModule gI420ColorConverterHelperLog("I420ColorConverterHelper");
|
|
#define LOG(msg...) MOZ_LOG(gI420ColorConverterHelperLog, mozilla::LogLevel::Warning, (msg))
|
|
|
|
namespace android {
|
|
|
|
I420ColorConverterHelper::I420ColorConverterHelper()
|
|
: mHandle(nullptr)
|
|
, mConverter({nullptr, nullptr, nullptr, nullptr, nullptr})
|
|
{
|
|
}
|
|
|
|
I420ColorConverterHelper::~I420ColorConverterHelper()
|
|
{
|
|
RWLock::AutoWLock awl(mLock);
|
|
unloadLocked();
|
|
}
|
|
|
|
// Prerequisite: a writer-lock should be held
|
|
bool
|
|
I420ColorConverterHelper::loadLocked()
|
|
{
|
|
if (loadedLocked()) {
|
|
return true;
|
|
}
|
|
unloadLocked();
|
|
|
|
// Open the shared library
|
|
mHandle = dlopen("libI420colorconvert.so", RTLD_NOW);
|
|
if (mHandle == nullptr) {
|
|
LOG("libI420colorconvert.so not found");
|
|
return false;
|
|
}
|
|
|
|
// Find the entry point
|
|
// Pointer to function with signature
|
|
// void getI420ColorConverter(II420ColorConverter *converter)
|
|
typedef int (* getConverterFn)(II420ColorConverter *converter);
|
|
getConverterFn getI420ColorConverter =
|
|
(getConverterFn) dlsym(mHandle, "getI420ColorConverter");
|
|
if (getI420ColorConverter == nullptr) {
|
|
LOG("Cannot load getI420ColorConverter from libI420colorconvert.so");
|
|
unloadLocked();
|
|
return false;
|
|
}
|
|
|
|
// Fill the function pointers.
|
|
getI420ColorConverter(&mConverter);
|
|
if (mConverter.getDecoderOutputFormat == nullptr ||
|
|
mConverter.convertDecoderOutputToI420 == nullptr ||
|
|
mConverter.getEncoderInputFormat == nullptr ||
|
|
mConverter.convertI420ToEncoderInput == nullptr ||
|
|
mConverter.getEncoderInputBufferInfo == nullptr) {
|
|
LOG("Failed to initialize I420 color converter");
|
|
unloadLocked();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Prerequisite: a reader-lock or a writer-lock should be held
|
|
bool
|
|
I420ColorConverterHelper::loadedLocked() const
|
|
{
|
|
if (mHandle == nullptr ||
|
|
mConverter.getDecoderOutputFormat == nullptr ||
|
|
mConverter.convertDecoderOutputToI420 == nullptr ||
|
|
mConverter.getEncoderInputFormat == nullptr ||
|
|
mConverter.convertI420ToEncoderInput == nullptr ||
|
|
mConverter.getEncoderInputBufferInfo == nullptr) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Prerequisite: a writer-lock should be held
|
|
void
|
|
I420ColorConverterHelper::unloadLocked()
|
|
{
|
|
if (mHandle != nullptr) {
|
|
dlclose(mHandle);
|
|
}
|
|
mHandle = nullptr;
|
|
mConverter.getDecoderOutputFormat = nullptr;
|
|
mConverter.convertDecoderOutputToI420 = nullptr;
|
|
mConverter.getEncoderInputFormat = nullptr;
|
|
mConverter.convertI420ToEncoderInput = nullptr;
|
|
mConverter.getEncoderInputBufferInfo = nullptr;
|
|
}
|
|
|
|
bool
|
|
I420ColorConverterHelper::ensureLoaded()
|
|
{
|
|
{
|
|
RWLock::AutoRLock arl(mLock);
|
|
// Check whether the library has been loaded or not.
|
|
if (loadedLocked()) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
{
|
|
RWLock::AutoWLock awl(mLock);
|
|
// Check whether the library has been loaded or not on other threads.
|
|
if (loadedLocked()) {
|
|
return true;
|
|
}
|
|
|
|
// Reload the library
|
|
unloadLocked();
|
|
if (loadLocked()) {
|
|
return true;
|
|
}
|
|
|
|
// Reset the library
|
|
unloadLocked();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int
|
|
I420ColorConverterHelper::getDecoderOutputFormat()
|
|
{
|
|
if (!ensureLoaded()) {
|
|
return -1;
|
|
}
|
|
|
|
RWLock::AutoRLock arl(mLock);
|
|
if (mConverter.getDecoderOutputFormat != nullptr) {
|
|
return mConverter.getDecoderOutputFormat();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
I420ColorConverterHelper::convertDecoderOutputToI420(
|
|
void* decoderBits, int decoderWidth, int decoderHeight,
|
|
ARect decoderRect, void* dstBits)
|
|
{
|
|
if (!ensureLoaded()) {
|
|
return -1;
|
|
}
|
|
|
|
RWLock::AutoRLock arl(mLock);
|
|
if (mConverter.convertDecoderOutputToI420 != nullptr) {
|
|
return mConverter.convertDecoderOutputToI420(decoderBits,
|
|
decoderWidth, decoderHeight, decoderRect, dstBits);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
I420ColorConverterHelper::getEncoderInputFormat()
|
|
{
|
|
if (!ensureLoaded()) {
|
|
return -1;
|
|
}
|
|
|
|
RWLock::AutoRLock arl(mLock);
|
|
if (mConverter.getEncoderInputFormat != nullptr) {
|
|
return mConverter.getEncoderInputFormat();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
I420ColorConverterHelper::convertI420ToEncoderInput(void* aSrcBits,
|
|
int aSrcWidth,
|
|
int aSrcHeight,
|
|
int aEncoderWidth,
|
|
int aEncoderHeight,
|
|
ARect aEncoderRect,
|
|
void* aEncoderBits)
|
|
{
|
|
if (!ensureLoaded()) {
|
|
return -1;
|
|
}
|
|
|
|
RWLock::AutoRLock arl(mLock);
|
|
if (mConverter.convertI420ToEncoderInput != nullptr) {
|
|
return mConverter.convertI420ToEncoderInput(aSrcBits, aSrcWidth, aSrcHeight,
|
|
aEncoderWidth, aEncoderHeight, aEncoderRect, aEncoderBits);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
I420ColorConverterHelper::getEncoderInputBufferInfo(int aSrcWidth,
|
|
int aSrcHeight,
|
|
int* aEncoderWidth,
|
|
int* aEncoderHeight,
|
|
ARect* aEncoderRect,
|
|
int* aEncoderBufferSize)
|
|
{
|
|
if (!ensureLoaded()) {
|
|
return -1;
|
|
}
|
|
|
|
RWLock::AutoRLock arl(mLock);
|
|
if (mConverter.getEncoderInputBufferInfo != nullptr) {
|
|
return mConverter.getEncoderInputBufferInfo(aSrcWidth, aSrcHeight,
|
|
aEncoderWidth, aEncoderHeight, aEncoderRect, aEncoderBufferSize);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
} // namespace android
|