/* * 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 #include #include #include #include "CodecProperties.h" #include "VideoShaper.h" #include "VQops.h" #include 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