1 /*
2 * Copyright 2021, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "CodecSeeding"
19 #include <utils/Log.h>
20
21 #include <string>
22
23 #include "CodecProperties.h"
24
25 namespace android {
26 namespace mediaformatshaper {
27
28 /*
29 * a block of pre-loaded tunings for codecs.
30 *
31 * things the library seeds into the codecproperties based
32 * on the mediaType.
33 * XXX: parsing from a file is likely better than embedding in code.
34 */
35 typedef struct {
36 bool overrideable;
37 const char *key;
38 const char *value;
39 } preloadTuning_t;
40
41 typedef struct {
42 const char *mediaType;
43 preloadTuning_t *features;
44 } preloadTunings_t;
45
46 /*
47 * bpp == bits per pixel per second, for 30fps.
48 */
49
50 static preloadTuning_t featuresAvc[] = {
51 {true, "vq-target-bpp", "0"},
52 {true, "vq-target-bpp-1080p", "1.90"},
53 {true, "vq-target-bpp-720p", "2.25"},
54 {true, "vq-target-bpp-540p", "2.65"},
55 {true, "vq-target-bpp-480p", "3.00"},
56 {true, "vq-target-bpp-320x240", "0"},
57 {true, "vq-target-qpmax", "-1"},
58 {true, "vq-target-qpmax-1080p", "45"},
59 {true, "vq-target-qpmax-720p", "43"},
60 {true, "vq-target-qpmax-540p", "42"},
61 {true, "vq-target-qpmax-480p", "38"},
62 {true, "vq-bitrate-phaseout", "1.75"},
63 {true, "vq-boost-missing-qp", "0.20"},
64 {true, nullptr, 0}
65 };
66
67 static preloadTuning_t featuresHevc[] = {
68 {true, "vq-target-bpp", "0"},
69 {true, "vq-target-bpp-1080p", "1.50"},
70 {true, "vq-target-bpp-720p", "1.80"},
71 {true, "vq-target-bpp-540p", "2.10"},
72 {true, "vq-target-bpp-480p", "2.30"},
73 {true, "vq-target-bpp-320x240", "0"},
74 {true, "vq-target-qpmax", "-1"},
75 {true, "vq-target-qpmax-1080p", "45"},
76 {true, "vq-target-qpmax-720p", "44"},
77 {true, "vq-target-qpmax-540p", "43"},
78 {true, "vq-target-qpmax-480p", "42"},
79 {true, "vq-bitrate-phaseout", "1.75"},
80 {true, "vq-boost-missing-qp", "0.20"},
81 {true, nullptr, 0}
82 };
83
84 static preloadTuning_t featuresGenericVideo[] = {
85 // 0 == off
86 {true, "vq-target-bpp", "0"},
87 {true, nullptr, 0}
88 };
89
90 static preloadTunings_t preloadTunings[] = {
91 { "video/avc", featuresAvc},
92 { "video/hevc", &featuresHevc[0]},
93
94 // wildcard for any video format not already captured
95 { "video/*", &featuresGenericVideo[0]},
96
97 { nullptr, nullptr}
98 };
99
addMediaDefaults(bool overrideable)100 void CodecProperties::addMediaDefaults(bool overrideable) {
101 ALOGD("Seed: codec %s, mediatype %s, overrideable %d",
102 mName.c_str(), mMediaType.c_str(), overrideable);
103
104 // load me up with initial configuration data
105 int count = 0;
106 for (int i = 0; ; i++) {
107 preloadTunings_t *p = &preloadTunings[i];
108 if (p->mediaType == nullptr) {
109 break;
110 }
111 bool found = false;
112 if (strcmp(p->mediaType, mMediaType.c_str()) == 0) {
113 found = true;
114 }
115 const char *r;
116 if (!found && (r = strchr(p->mediaType, '*')) != NULL) {
117 // wildcard; check the prefix
118 size_t len = r - p->mediaType;
119 if (strncmp(p->mediaType, mMediaType.c_str(), len) == 0) {
120 found = true;
121 }
122 }
123
124 if (!found) {
125 continue;
126 }
127 ALOGV("seeding from mediaType '%s'", p->mediaType);
128
129 // walk through, filling things
130 if (p->features != nullptr) {
131 for (int j=0;; j++) {
132 preloadTuning_t *q = &p->features[j];
133 if (q->key == nullptr) {
134 break;
135 }
136 if (q->overrideable != overrideable) {
137 continue;
138 }
139 setTuningValue(q->key, q->value);
140 count++;
141 }
142 break;
143 }
144 }
145 ALOGV("loaded %d preset values", count);
146 }
147
148 // a chance, as we create the codec to inject any default behaviors we want.
149 // XXX: consider whether we need pre/post or just post. it affects what can be
150 // overridden by way of the codec XML
151 //
Seed()152 void CodecProperties::Seed() {
153 ALOGV("Seed: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str());
154 addMediaDefaults(true);
155 }
156
Finish()157 void CodecProperties::Finish() {
158 ALOGV("Finish: for codec %s, mediatype %s", mName.c_str(), mMediaType.c_str());
159 addMediaDefaults(false);
160 }
161
162 } // namespace mediaformatshaper
163 } // namespace android
164
165