204 lines
5.4 KiB
C++
204 lines
5.4 KiB
C++
/*
|
|
* Copyright (C) 2021 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 "FormatShaper"
|
|
#include <utils/Log.h>
|
|
|
|
#include <string>
|
|
#include <inttypes.h>
|
|
|
|
#include <media/NdkMediaFormat.h>
|
|
|
|
#include "CodecProperties.h"
|
|
#include "VideoShaper.h"
|
|
#include "VQops.h"
|
|
|
|
#include <media/formatshaper/FormatShaper.h>
|
|
|
|
namespace android {
|
|
namespace mediaformatshaper {
|
|
|
|
//
|
|
// Caller retains ownership of and responsibility for inFormat
|
|
//
|
|
|
|
//
|
|
// the interface to the outside
|
|
//
|
|
|
|
int shapeFormat(shaperHandle_t shaper, AMediaFormat* inFormat, int flags) {
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr) {
|
|
return -1;
|
|
}
|
|
if (!codec->isRegistered()) {
|
|
return -1;
|
|
}
|
|
|
|
// run through the list of possible transformations
|
|
//
|
|
|
|
std::string mediaType = codec->getMediaType();
|
|
if (strncmp(mediaType.c_str(), "video/", 6) == 0) {
|
|
// video specific shaping
|
|
(void) videoShaper(codec, inFormat, flags);
|
|
|
|
} else if (strncmp(mediaType.c_str(), "audio/", 6) == 0) {
|
|
// audio specific shaping
|
|
|
|
} else {
|
|
ALOGV("unknown mediatype '%s', left untouched", mediaType.c_str());
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int setMap(shaperHandle_t shaper, const char *kind, const char *key, const char *value) {
|
|
ALOGV("setMap: kind %s key %s -> value %s", kind, key, value);
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr) {
|
|
return -1;
|
|
}
|
|
// must not yet be registered
|
|
if (codec->isRegistered()) {
|
|
return -1;
|
|
}
|
|
|
|
codec->setMapping(kind, key, value);
|
|
return 0;
|
|
}
|
|
|
|
int setFeature(shaperHandle_t shaper, const char *feature, int value) {
|
|
ALOGV("set_feature: feature %s value %d", feature, value);
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr) {
|
|
return -1;
|
|
}
|
|
// must not yet be registered
|
|
if (codec->isRegistered()) {
|
|
return -1;
|
|
}
|
|
|
|
// save a map of all features
|
|
codec->setFeatureValue(feature, value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int setTuning(shaperHandle_t shaper, const char *tuning, const char *value) {
|
|
ALOGV("setTuning: tuning %s value %s", tuning, value);
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr) {
|
|
return -1;
|
|
}
|
|
// must not yet be registered
|
|
if (codec->isRegistered()) {
|
|
return -1;
|
|
}
|
|
|
|
// save a map of all features
|
|
codec->setTuningValue(tuning, value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* The routines that manage finding, creating, and registering the shapers.
|
|
*/
|
|
|
|
shaperHandle_t findShaper(const char *codecName, const char *mediaType) {
|
|
CodecProperties *codec = findCodec(codecName, mediaType);
|
|
return (shaperHandle_t) codec;
|
|
}
|
|
|
|
shaperHandle_t createShaper(const char *codecName, const char *mediaType) {
|
|
CodecProperties *codec = new CodecProperties(codecName, mediaType);
|
|
if (codec != nullptr) {
|
|
codec->Seed();
|
|
}
|
|
return (shaperHandle_t) codec;
|
|
}
|
|
|
|
shaperHandle_t registerShaper(shaperHandle_t shaper, const char *codecName, const char *mediaType) {
|
|
ALOGV("registerShaper(handle, codecName %s, mediaType %s", codecName, mediaType);
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr) {
|
|
return nullptr;
|
|
}
|
|
// must not yet be registered
|
|
if (codec->isRegistered()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// any final cleanup for the parameters. This allows us to override
|
|
// bad parameters from a devices XML file.
|
|
codec->Finish();
|
|
|
|
// may return a different codec, if we lost a race.
|
|
// if so, registerCodec() reclaims the one we tried to register for us.
|
|
codec = registerCodec(codec, codecName, mediaType);
|
|
return (shaperHandle_t) codec;
|
|
}
|
|
|
|
// mapping & unmapping
|
|
// give me the mappings for 'kind'.
|
|
// kind==null (or empty string), means *all* mappings
|
|
|
|
const char **getMappings(shaperHandle_t shaper, const char *kind) {
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr)
|
|
return nullptr;
|
|
if (kind == nullptr)
|
|
kind = "";
|
|
|
|
return codec->getMappings(kind, /* reverse */ false);
|
|
}
|
|
|
|
const char **getReverseMappings(shaperHandle_t shaper, const char *kind) {
|
|
CodecProperties *codec = (CodecProperties*) shaper;
|
|
if (codec == nullptr)
|
|
return nullptr;
|
|
if (kind == nullptr)
|
|
kind = "";
|
|
|
|
return codec->getMappings(kind, /* reverse */ true);
|
|
}
|
|
|
|
|
|
// the system grabs this structure
|
|
__attribute__ ((visibility ("default")))
|
|
extern "C" FormatShaperOps_t shaper_ops = {
|
|
.version = SHAPER_VERSION_V1,
|
|
|
|
.findShaper = findShaper,
|
|
.createShaper = createShaper,
|
|
.setMap = setMap,
|
|
.setFeature = setFeature,
|
|
.registerShaper = registerShaper,
|
|
|
|
.shapeFormat = shapeFormat,
|
|
.getMappings = getMappings,
|
|
.getReverseMappings = getReverseMappings,
|
|
|
|
.setTuning = setTuning,
|
|
};
|
|
|
|
} // namespace mediaformatshaper
|
|
} // namespace android
|
|
|