194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber/*
294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * Copyright 2013, The Android Open Source Project
394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber *
494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * you may not use this file except in compliance with the License.
694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * You may obtain a copy of the License at
794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber *
894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber *
1094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * Unless required by applicable law or agreed to in writing, software
1194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * See the License for the specific language governing permissions and
1494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber * limitations under the License.
1594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber */
1694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
1794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber//#define LOG_NDEBUG 0
1894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#define LOG_TAG "VideoFormats"
1994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#include <utils/Log.h>
2094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
2194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#include "VideoFormats.h"
2294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
2394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
2594a483bf2bd699275673d9cd57cb125d48572f30Andreas Hubernamespace android {
2694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
27308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang// static
28308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangconst VideoFormats::config_t VideoFormats::mResolutionTable[][32] = {
29aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    {
30aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        // CEA Resolutions
31aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 640, 480, 60, false, 0, 0},
32aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 720, 480, 60, false, 0, 0},
33aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 720, 480, 60, true, 0, 0},
34aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 720, 576, 50, false, 0, 0},
35aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 720, 576, 50, true, 0, 0},
36aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 720, 30, false, 0, 0},
37aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 720, 60, false, 0, 0},
38aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 30, false, 0, 0},
39aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 60, false, 0, 0},
40aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 60, true, 0, 0},
41aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 720, 25, false, 0, 0},
42aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 720, 50, false, 0, 0},
43aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 25, false, 0, 0},
44aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 50, false, 0, 0},
45aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 50, true, 0, 0},
46aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 720, 24, false, 0, 0},
47aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1080, 24, false, 0, 0},
48aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
49aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
50aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
51aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
52aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
53aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
54aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
55aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
56aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
57aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
58aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
59aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
60aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
61aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
62aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
63aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    },
64aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    {
65aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        // VESA Resolutions
66aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 800, 600, 30, false, 0, 0},
67aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 800, 600, 60, false, 0, 0},
68aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1024, 768, 30, false, 0, 0},
69aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1024, 768, 60, false, 0, 0},
70aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1152, 864, 30, false, 0, 0},
71aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1152, 864, 60, false, 0, 0},
72aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 768, 30, false, 0, 0},
73aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 768, 60, false, 0, 0},
74aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 800, 30, false, 0, 0},
75aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 800, 60, false, 0, 0},
76aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1360, 768, 30, false, 0, 0},
77aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1360, 768, 60, false, 0, 0},
78aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1366, 768, 30, false, 0, 0},
79aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1366, 768, 60, false, 0, 0},
80aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 1024, 30, false, 0, 0},
81aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1280, 1024, 60, false, 0, 0},
82aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1400, 1050, 30, false, 0, 0},
83aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1400, 1050, 60, false, 0, 0},
84aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1440, 900, 30, false, 0, 0},
85aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1440, 900, 60, false, 0, 0},
86aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1600, 900, 30, false, 0, 0},
87aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1600, 900, 60, false, 0, 0},
88aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1600, 1200, 30, false, 0, 0},
89aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1600, 1200, 60, false, 0, 0},
90aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1680, 1024, 30, false, 0, 0},
91aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1680, 1024, 60, false, 0, 0},
92aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1680, 1050, 30, false, 0, 0},
93aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1680, 1050, 60, false, 0, 0},
94aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1200, 30, false, 0, 0},
95aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 1920, 1200, 60, false, 0, 0},
96aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
97aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
98aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    },
99aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    {
100aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        // HH Resolutions
101aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 800, 480, 30, false, 0, 0},
102aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 800, 480, 60, false, 0, 0},
103aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 854, 480, 30, false, 0, 0},
104aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 854, 480, 60, false, 0, 0},
105aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 864, 480, 30, false, 0, 0},
106aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 864, 480, 60, false, 0, 0},
107aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 640, 360, 30, false, 0, 0},
108aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 640, 360, 60, false, 0, 0},
109aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 960, 540, 30, false, 0, 0},
110aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 960, 540, 60, false, 0, 0},
111aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 848, 480, 30, false, 0, 0},
112aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 848, 480, 60, false, 0, 0},
113aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
114aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
115aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
116aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
117aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
118aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
119aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
120aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
121aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
122aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
123aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
124aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
125aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
126aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
127aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
128aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
129aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
130aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
131aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
132aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        { 0, 0, 0, false, 0, 0},
133aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    }
134aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang};
135aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang
13694a483bf2bd699275673d9cd57cb125d48572f30Andreas HuberVideoFormats::VideoFormats() {
137308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    memcpy(mConfigs, mResolutionTable, sizeof(mConfigs));
138308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
13994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    for (size_t i = 0; i < kNumResolutionTypes; ++i) {
14094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        mResolutionEnabled[i] = 0;
14194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
14294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
14394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    setNativeResolution(RESOLUTION_CEA, 0);  // default to 640x480 p60
14494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
14594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
14694a483bf2bd699275673d9cd57cb125d48572f30Andreas Hubervoid VideoFormats::setNativeResolution(ResolutionType type, size_t index) {
14794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK_LT(type, kNumResolutionTypes);
14894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL));
14994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
15094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    mNativeType = type;
15194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    mNativeIndex = index;
15294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
15394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    setResolutionEnabled(type, index);
15494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
15594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
15694a483bf2bd699275673d9cd57cb125d48572f30Andreas Hubervoid VideoFormats::getNativeResolution(
15794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ResolutionType *type, size_t *index) const {
15894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    *type = mNativeType;
15994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    *index = mNativeIndex;
16094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
16194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
16294a483bf2bd699275673d9cd57cb125d48572f30Andreas Hubervoid VideoFormats::disableAll() {
16394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    for (size_t i = 0; i < kNumResolutionTypes; ++i) {
16494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        mResolutionEnabled[i] = 0;
165aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        for (size_t j = 0; j < 32; j++) {
166aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            mConfigs[i][j].profile = mConfigs[i][j].level = 0;
167aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        }
16894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
16994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
17094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
17194a483bf2bd699275673d9cd57cb125d48572f30Andreas Hubervoid VideoFormats::enableAll() {
17294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    for (size_t i = 0; i < kNumResolutionTypes; ++i) {
17394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        mResolutionEnabled[i] = 0xffffffff;
174aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        for (size_t j = 0; j < 32; j++) {
175aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            mConfigs[i][j].profile = (1ul << PROFILE_CBP);
176aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            mConfigs[i][j].level = (1ul << LEVEL_31);
177aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        }
17894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
17994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
18094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
1811ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhangvoid VideoFormats::enableResolutionUpto(
1821ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang        ResolutionType type, size_t index,
1831ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang        ProfileType profile, LevelType level) {
1841ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    size_t width, height, fps, score;
1851ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    bool interlaced;
1861ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    if (!GetConfiguration(type, index, &width, &height,
1871ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang            &fps, &interlaced)) {
1881ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang        ALOGE("Maximum resolution not found!");
1891ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang        return;
1901ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    }
1911ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    score = width * height * fps * (!interlaced + 1);
1921ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    for (size_t i = 0; i < kNumResolutionTypes; ++i) {
1931ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang        for (size_t j = 0; j < 32; j++) {
1941ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang            if (GetConfiguration((ResolutionType)i, j,
1951ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang                    &width, &height, &fps, &interlaced)
1961ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang                    && score >= width * height * fps * (!interlaced + 1)) {
1971ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang                setResolutionEnabled((ResolutionType)i, j);
1981ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang                setProfileLevel((ResolutionType)i, j, profile, level);
1991ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang            }
2001ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang        }
2011ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang    }
2021ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang}
2031ad3eb9441eb509c792c61aa0181b0e74dbe9984Chong Zhang
20494a483bf2bd699275673d9cd57cb125d48572f30Andreas Hubervoid VideoFormats::setResolutionEnabled(
20594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ResolutionType type, size_t index, bool enabled) {
20694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK_LT(type, kNumResolutionTypes);
20794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL));
20894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
20994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (enabled) {
21094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        mResolutionEnabled[type] |= (1ul << index);
211308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        mConfigs[type][index].profile = (1ul << PROFILE_CBP);
212308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        mConfigs[type][index].level = (1ul << LEVEL_31);
21394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    } else {
21494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        mResolutionEnabled[type] &= ~(1ul << index);
215308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        mConfigs[type][index].profile = 0;
216308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        mConfigs[type][index].level = 0;
21794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
21894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
21994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
220308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid VideoFormats::setProfileLevel(
221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ResolutionType type, size_t index,
222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ProfileType profile, LevelType level) {
223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK_LT(type, kNumResolutionTypes);
224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL));
225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mConfigs[type][index].profile = (1ul << profile);
227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mConfigs[type][index].level = (1ul << level);
228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang}
229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid VideoFormats::getProfileLevel(
231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ResolutionType type, size_t index,
232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ProfileType *profile, LevelType *level) const{
233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK_LT(type, kNumResolutionTypes);
234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL));
235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int i, bestProfile = -1, bestLevel = -1;
237308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
238308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    for (i = 0; i < kNumProfileTypes; ++i) {
239308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (mConfigs[type][index].profile & (1ul << i)) {
240308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            bestProfile = i;
241308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
242308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
243308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
244308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    for (i = 0; i < kNumLevelTypes; ++i) {
245308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (mConfigs[type][index].level & (1ul << i)) {
246308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            bestLevel = i;
247308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
248308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
249308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
250308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (bestProfile == -1 || bestLevel == -1) {
251ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGE("Profile or level not set for resolution type %d, index %zu",
252ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                type, index);
253308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        bestProfile = PROFILE_CBP;
254308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        bestLevel = LEVEL_31;
255308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
256308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
257308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    *profile = (ProfileType) bestProfile;
258308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    *level = (LevelType) bestLevel;
259308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang}
260308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
26194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberbool VideoFormats::isResolutionEnabled(
26294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ResolutionType type, size_t index) const {
26394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK_LT(type, kNumResolutionTypes);
26494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(GetConfiguration(type, index, NULL, NULL, NULL, NULL));
26594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
26694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    return mResolutionEnabled[type] & (1ul << index);
26794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
26894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
26994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber// static
27094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberbool VideoFormats::GetConfiguration(
27194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ResolutionType type,
27294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        size_t index,
27394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        size_t *width, size_t *height, size_t *framesPerSecond,
27494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool *interlaced) {
27594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK_LT(type, kNumResolutionTypes);
27694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
27794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (index >= 32) {
27894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        return false;
27994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
28094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
281308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    const config_t *config = &mResolutionTable[type][index];
28294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
28394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (config->width == 0) {
28494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        return false;
28594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
28694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
28794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (width) {
28894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        *width = config->width;
28994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
29094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
29194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (height) {
29294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        *height = config->height;
29394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
29494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
29594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (framesPerSecond) {
29694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        *framesPerSecond = config->framesPerSecond;
29794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
29894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
29994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (interlaced) {
30094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        *interlaced = config->interlaced;
30194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
30294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
30394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    return true;
30494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
30594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
306aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhangbool VideoFormats::parseH264Codec(const char *spec) {
307aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    unsigned profile, level, res[3];
308aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang
309aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    if (sscanf(
310aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            spec,
311aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            "%02x %02x %08X %08X %08X",
312aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            &profile,
313aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            &level,
314aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            &res[0],
315aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            &res[1],
316aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            &res[2]) != 5) {
317aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        return false;
318aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    }
319aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang
320aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    for (size_t i = 0; i < kNumResolutionTypes; ++i) {
321aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        for (size_t j = 0; j < 32; ++j) {
322aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            if (res[i] & (1ul << j)){
323aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang                mResolutionEnabled[i] |= (1ul << j);
324aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang                if (profile > mConfigs[i][j].profile) {
325308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    // prefer higher profile (even if level is lower)
326aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang                    mConfigs[i][j].profile = profile;
327308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mConfigs[i][j].level = level;
328308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                } else if (profile == mConfigs[i][j].profile &&
329308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                           level > mConfigs[i][j].level) {
330308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mConfigs[i][j].level = level;
331aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang                }
332aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang            }
333aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        }
334aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    }
335aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang
336aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    return true;
337aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang}
338aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang
339308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang// static
340308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangbool VideoFormats::GetProfileLevel(
341308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ProfileType profile, LevelType level, unsigned *profileIdc,
342308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        unsigned *levelIdc, unsigned *constraintSet) {
343308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK_LT(profile, kNumProfileTypes);
344308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK_LT(level, kNumLevelTypes);
345308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
346308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    static const unsigned kProfileIDC[kNumProfileTypes] = {
347308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        66,     // PROFILE_CBP
348308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        100,    // PROFILE_CHP
349308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    };
350308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
351308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    static const unsigned kLevelIDC[kNumLevelTypes] = {
352308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        31,     // LEVEL_31
353308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        32,     // LEVEL_32
354308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        40,     // LEVEL_40
355308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        41,     // LEVEL_41
356308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        42,     // LEVEL_42
357308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    };
358308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
359308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    static const unsigned kConstraintSet[kNumProfileTypes] = {
360308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        0xc0,   // PROFILE_CBP
361308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        0x0c,   // PROFILE_CHP
362308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    };
363308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (profileIdc) {
365308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        *profileIdc = kProfileIDC[profile];
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
367308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
368308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (levelIdc) {
369308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        *levelIdc = kLevelIDC[level];
370308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
371308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
372308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (constraintSet) {
373308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        *constraintSet = kConstraintSet[profile];
374308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
375308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
376308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    return true;
377308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang}
378308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
37994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberbool VideoFormats::parseFormatSpec(const char *spec) {
38094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK_EQ(kNumResolutionTypes, 3);
38194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
382308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    disableAll();
383308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
38494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    unsigned native, dummy;
385aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    size_t size = strlen(spec);
386aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    size_t offset = 0;
38794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
388aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    if (sscanf(spec, "%02x %02x ", &native, &dummy) != 2) {
38994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        return false;
39094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
39194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
392aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    offset += 6; // skip native and preferred-display-mode-supported
393aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    CHECK_LE(offset + 58, size);
394aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    while (offset < size) {
395aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        parseH264Codec(spec + offset);
396aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang        offset += 60; // skip H.264-codec + ", "
397aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang    }
398aef5c98cd3f67e0209e1fa28489078e9f40d6f46Chong Zhang
39994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    mNativeIndex = native >> 3;
40094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    mNativeType = (ResolutionType)(native & 7);
40194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
4020182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber    bool success;
40394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (mNativeType >= kNumResolutionTypes) {
4040182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber        success = false;
4050182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber    } else {
4060182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber        success = GetConfiguration(
4070182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber                mNativeType, mNativeIndex, NULL, NULL, NULL, NULL);
40894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
40994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
4100182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber    if (!success) {
4110182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber        ALOGW("sink advertised an illegal native resolution, fortunately "
4120182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber              "this value is ignored for the time being...");
4130182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber    }
4140182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber
4150182f9acca6f873ee127898e408cf75cc316c3eaAndreas Huber    return true;
41694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
41794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
4185abf87f9af48149972eeb851ecaea679911da040Andreas HuberAString VideoFormats::getFormatSpec(bool forM4Message) const {
41994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK_EQ(kNumResolutionTypes, 3);
42094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
42194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    // wfd_video_formats:
42294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    // 1 byte "native"
42394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    // 1 byte "preferred-display-mode-supported" 0 or 1
42494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    // one or more avc codec structures
42594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   1 byte profile
42694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   1 byte level
42794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   4 byte CEA mask
42894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   4 byte VESA mask
42994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   4 byte HH mask
43094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   1 byte latency
43194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   2 byte min-slice-slice
43294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   2 byte slice-enc-params
43394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   1 byte framerate-control-support
43494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   max-hres (none or 2 byte)
43594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    //   max-vres (none or 2 byte)
43694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
437a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes    return AStringPrintf(
438308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            "%02x 00 %02x %02x %08x %08x %08x 00 0000 0000 00 none none",
4395abf87f9af48149972eeb851ecaea679911da040Andreas Huber            forM4Message ? 0x00 : ((mNativeIndex << 3) | mNativeType),
440308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mConfigs[mNativeType][mNativeIndex].profile,
441308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mConfigs[mNativeType][mNativeIndex].level,
44294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            mResolutionEnabled[0],
44394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            mResolutionEnabled[1],
44494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            mResolutionEnabled[2]);
44594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
44694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
44794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber// static
44894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberbool VideoFormats::PickBestFormat(
44994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        const VideoFormats &sinkSupported,
45094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        const VideoFormats &sourceSupported,
45194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ResolutionType *chosenType,
452308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        size_t *chosenIndex,
453308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ProfileType *chosenProfile,
454308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        LevelType *chosenLevel) {
4555abf87f9af48149972eeb851ecaea679911da040Andreas Huber#if 0
4565abf87f9af48149972eeb851ecaea679911da040Andreas Huber    // Support for the native format is a great idea, the spec includes
4575abf87f9af48149972eeb851ecaea679911da040Andreas Huber    // these features, but nobody supports it and the tests don't validate it.
4585abf87f9af48149972eeb851ecaea679911da040Andreas Huber
45994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    ResolutionType nativeType;
46094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    size_t nativeIndex;
46194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    sinkSupported.getNativeResolution(&nativeType, &nativeIndex);
46294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (sinkSupported.isResolutionEnabled(nativeType, nativeIndex)) {
46394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        if (sourceSupported.isResolutionEnabled(nativeType, nativeIndex)) {
46494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            ALOGI("Choosing sink's native resolution");
46594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            *chosenType = nativeType;
46694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            *chosenIndex = nativeIndex;
46794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            return true;
46894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
46994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    } else {
47094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ALOGW("Sink advertised native resolution that it doesn't "
47194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber              "actually support... ignoring");
47294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
47394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
47494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    sourceSupported.getNativeResolution(&nativeType, &nativeIndex);
47594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (sourceSupported.isResolutionEnabled(nativeType, nativeIndex)) {
47694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        if (sinkSupported.isResolutionEnabled(nativeType, nativeIndex)) {
47794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            ALOGI("Choosing source's native resolution");
47894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            *chosenType = nativeType;
47994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            *chosenIndex = nativeIndex;
48094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            return true;
48194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
48294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    } else {
48394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        ALOGW("Source advertised native resolution that it doesn't "
48494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber              "actually support... ignoring");
48594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
4865abf87f9af48149972eeb851ecaea679911da040Andreas Huber#endif
48794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
48894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    bool first = true;
48994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    uint32_t bestScore = 0;
49094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    size_t bestType = 0;
49194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    size_t bestIndex = 0;
49294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    for (size_t i = 0; i < kNumResolutionTypes; ++i) {
49394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        for (size_t j = 0; j < 32; ++j) {
49494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            size_t width, height, framesPerSecond;
49594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            bool interlaced;
49694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            if (!GetConfiguration(
49794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                        (ResolutionType)i,
49894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                        j,
49994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                        &width, &height, &framesPerSecond, &interlaced)) {
50094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                break;
50194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            }
50294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
50394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            if (!sinkSupported.isResolutionEnabled((ResolutionType)i, j)
50494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                    || !sourceSupported.isResolutionEnabled(
50594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                        (ResolutionType)i, j)) {
50694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                continue;
50794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            }
50894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
509ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            ALOGV("type %zu, index %zu, %zu x %zu %c%zu supported",
51094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                  i, j, width, height, interlaced ? 'i' : 'p', framesPerSecond);
51194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
51294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            uint32_t score = width * height * framesPerSecond;
51394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            if (!interlaced) {
51494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                score *= 2;
51594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            }
51694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
51794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            if (first || score > bestScore) {
51894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                bestScore = score;
51994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                bestType = i;
52094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                bestIndex = j;
52194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
52294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                first = false;
52394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            }
52494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
52594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
52694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
52794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (first) {
52894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        return false;
52994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
53094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
53194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    *chosenType = (ResolutionType)bestType;
53294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    *chosenIndex = bestIndex;
53394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
534308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Pick the best profile/level supported by both sink and source.
535308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    ProfileType srcProfile, sinkProfile;
536308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    LevelType srcLevel, sinkLevel;
537308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    sourceSupported.getProfileLevel(
538308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        (ResolutionType)bestType, bestIndex,
539308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        &srcProfile, &srcLevel);
540308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    sinkSupported.getProfileLevel(
541308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        (ResolutionType)bestType, bestIndex,
542308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        &sinkProfile, &sinkLevel);
543308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    *chosenProfile = srcProfile < sinkProfile ? srcProfile : sinkProfile;
544308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    *chosenLevel = srcLevel < sinkLevel ? srcLevel : sinkLevel;
545308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
54694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    return true;
54794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}
54894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
54994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber}  // namespace android
55094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
551