You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.8 KiB
165 lines
4.8 KiB
4 months ago
|
/*
|
||
|
* Copyright 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 "CodecSeeding"
|
||
|
#include <utils/Log.h>
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
#include "CodecProperties.h"
|
||
|
|
||
|
namespace android {
|
||
|
namespace mediaformatshaper {
|
||
|
|
||
|
/*
|
||
|
* a block of pre-loaded tunings for codecs.
|
||
|
*
|
||
|
* things the library seeds into the codecproperties based
|
||
|
* on the mediaType.
|
||
|
* XXX: parsing from a file is likely better than embedding in code.
|
||
|
*/
|
||
|
typedef struct {
|
||
|
bool overrideable;
|
||
|
const char *key;
|
||
|
const char *value;
|
||
|
} preloadTuning_t;
|
||
|
|
||
|
typedef struct {
|
||
|
const char *mediaType;
|
||
|
preloadTuning_t *features;
|
||
|
} preloadTunings_t;
|
||
|
|
||
|
/*
|
||
|
* bpp == bits per pixel per second, for 30fps.
|
||
|
*/
|
||
|
|
||
|
static preloadTuning_t featuresAvc[] = {
|
||
|
{true, "vq-target-bpp", "0"},
|
||
|
{true, "vq-target-bpp-1080p", "1.90"},
|
||
|
{true, "vq-target-bpp-720p", "2.25"},
|
||
|
{true, "vq-target-bpp-540p", "2.65"},
|
||
|
{true, "vq-target-bpp-480p", "3.00"},
|
||
|
{true, "vq-target-bpp-320x240", "0"},
|
||
|
{true, "vq-target-qpmax", "-1"},
|
||
|
{true, "vq-target-qpmax-1080p", "45"},
|
||
|
{true, "vq-target-qpmax-720p", "43"},
|
||
|
{true, "vq-target-qpmax-540p", "42"},
|
||
|
{true, "vq-target-qpmax-480p", "38"},
|
||
|
{true, "vq-bitrate-phaseout", "1.75"},
|
||
|
{true, "vq-boost-missing-qp", "0.20"},
|
||
|
{true, nullptr, 0}
|
||
|
};
|
||
|
|
||
|
static preloadTuning_t featuresHevc[] = {
|
||
|
{true, "vq-target-bpp", "0"},
|
||
|
{true, "vq-target-bpp-1080p", "1.50"},
|
||
|
{true, "vq-target-bpp-720p", "1.80"},
|
||
|
{true, "vq-target-bpp-540p", "2.10"},
|
||
|
{true, "vq-target-bpp-480p", "2.30"},
|
||
|
{true, "vq-target-bpp-320x240", "0"},
|
||
|
{true, "vq-target-qpmax", "-1"},
|
||
|
{true, "vq-target-qpmax-1080p", "45"},
|
||
|
{true, "vq-target-qpmax-720p", "44"},
|
||
|
{true, "vq-target-qpmax-540p", "43"},
|
||
|
{true, "vq-target-qpmax-480p", "42"},
|
||
|
{true, "vq-bitrate-phaseout", "1.75"},
|
||
|
{true, "vq-boost-missing-qp", "0.20"},
|
||
|
{true, nullptr, 0}
|
||
|
};
|
||
|
|
||
|
static preloadTuning_t featuresGenericVideo[] = {
|
||
|
// 0 == off
|
||
|
{true, "vq-target-bpp", "0"},
|
||
|
{true, nullptr, 0}
|
||
|
};
|
||
|
|
||
|
static preloadTunings_t preloadTunings[] = {
|
||
|
{ "video/avc", featuresAvc},
|
||
|
{ "video/hevc", &featuresHevc[0]},
|
||
|
|
||
|
// wildcard for any video format not already captured
|
||
|
{ "video/*", &featuresGenericVideo[0]},
|
||
|
|
||
|
{ nullptr, nullptr}
|
||
|
};
|
||
|
|
||
|
void CodecProperties::addMediaDefaults(bool overrideable) {
|
||
|
ALOGD("Seed: codec %s, mediatype %s, overrideable %d",
|
||
|
mName.c_str(), mMediaType.c_str(), overrideable);
|
||
|
|
||
|
// load me up with initial configuration data
|
||
|
int count = 0;
|
||
|
for (int i = 0; ; i++) {
|
||
|
preloadTunings_t *p = &preloadTunings[i];
|
||
|
if (p->mediaType == nullptr) {
|
||
|
break;
|
||
|
}
|
||
|
bool found = false;
|
||
|
if (strcmp(p->mediaType, mMediaType.c_str()) == 0) {
|
||
|
found = true;
|
||
|
}
|
||
|
const char *r;
|
||
|
if (!found && (r = strchr(p->mediaType, '*')) != NULL) {
|
||
|
// wildcard; check the prefix
|
||
|
size_t len = r - p->mediaType;
|
||
|
if (strncmp(p->mediaType, mMediaType.c_str(), len) == 0) {
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!found) {
|
||
|
continue;
|
||
|
}
|
||
|
ALOGV("seeding from mediaType '%s'", p->mediaType);
|
||
|
|
||
|
// walk through, filling things
|
||
|
if (p->features != nullptr) {
|
||
|
for (int j=0;; j++) {
|
||
|
preloadTuning_t *q = &p->features[j];
|
||
|
if (q->key == nullptr) {
|
||
|
break;
|
||
|
}
|
||
|
if (q->overrideable != overrideable) {
|
||
|
continue;
|
||
|
}
|
||
|
setTuningValue(q->key, q->value);
|
||
|
count++;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
ALOGV("loaded %d preset values", count);
|
||
|
}
|
||
|
|
||
|
// a chance, as we create the codec to inject any default behaviors we want.
|
||
|
// XXX: consider whether we need pre/post or just post. it affects what can be
|
||
|
// overridden by way of the codec XML
|
||
|
//
|
||
|
void CodecProperties::Seed() {
|
||
|
ALOGV("Seed: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str());
|
||
|
addMediaDefaults(true);
|
||
|
}
|
||
|
|
||
|
void CodecProperties::Finish() {
|
||
|
ALOGV("Finish: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str());
|
||
|
addMediaDefaults(false);
|
||
|
}
|
||
|
|
||
|
} // namespace mediaformatshaper
|
||
|
} // namespace android
|
||
|
|