blob: 451f772f093395899caeeb688471233e8166f9cc [file] [log] [blame]
/*
* 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