165 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
/*
 | 
						|
 * 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
 | 
						|
 |