1/*
2* Copyright (c) 2015 Intel Corporation.  All rights reserved.
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
18#ifndef MEDIA_RESOURCE_ARBITRATOR_H_
19#define MEDIA_RESOURCE_ARBITRATOR_H_
20
21#include <unistd.h>
22#include <string.h>
23#include <utils/KeyedVector.h>
24#include <utils/Vector.h>
25
26#define MAX_BUFFER_SIZE (20 * 1024)
27
28using namespace android;
29
30// This error type keeps align with the OMX error type
31typedef enum _ArbitratorErrorType {
32    ArbitratorErrorNone = 0,
33
34    /** There were insufficient resources to perform the requested operation */
35    ArbitratorErrorInsufficientResources = 0x80001000,
36
37    /** There was an error, but the cause of the error could not be determined */
38    ArbitratorErrorUndefined = 0x80001001
39} ArbitratorErrorType;
40
41
42typedef enum _ResolutionType {
43    Resolution_CIF = 0,
44    Resolution_480,
45    Resolution_720,
46    Resolution_1080,
47    Resolution_2K,
48    Resolution_4K,
49    Resolution_MAX
50} ResolutionType;
51
52
53typedef enum _CodecType {
54    CODEC_TYPE_AVC = 0,
55    CODEC_TYPE_HEVC,
56    CODEC_TYPE_VP8,
57    CODEC_TYPE_VP9,
58    CODEC_TYPE_MPEG4,
59    CODEC_TYPE_MPEG2,
60    CODEC_TYPE_H263,
61    CODEC_TYPE_VC1,
62    CODEC_TYPE_WMV,
63    CODEC_TYPE_MAX
64} CodecType;
65
66
67typedef struct _CodecInfo {
68    CodecType codecType;
69    bool isEncoder;
70    bool isSecured;
71    ResolutionType resolution;
72    uint frameRate;
73} CodecInfo;
74
75
76typedef struct _CodecLimitInfo {
77    CodecInfo codecInfo;
78    int instanceLimit;
79} CodecLimitInfo;
80
81
82typedef struct _LivingDecodersTable {
83    Vector<CodecInfo> livingDecoders;
84    uint maxResolution;
85    uint maxFrameRate;
86} LivingDecodersTable;
87
88
89typedef struct _LivingEncodersTable {
90    Vector<CodecInfo> livingEncoders;
91    uint maxResolution;
92    uint maxFrameRate;
93} LivingEncodersTable;
94
95
96class MediaResourceArbitrator {
97public:
98    MediaResourceArbitrator ();
99    ~MediaResourceArbitrator ();
100
101    /* Initialize the arbitrator.
102       Parse the config XML file if given. */
103    ArbitratorErrorType Config(const char* configFilePath);
104
105    /* Check if the resource limitation is hit and
106       it is under full load status. In such status, there
107       is no room to instantiate codec anymore. */
108    bool CheckIfFullLoad(bool isEncoder);
109
110    /* Add codec in the pool.
111       Resolution and frame rate must be provided.
112       This is not necessarily be called when codec instance
113       is constructed when the resolution and frame rate are
114       not known yet.
115       This may be called when codec is configured,
116       for example in OMX set parameter, etc.
117       Return value is expected to be as one of:
118           ArbitratorErrorNone,
119           ArbitratorErrorInsufficientResources
120     */
121    ArbitratorErrorType AddResource(/* in */  CodecType codecType,
122                                    /* in */  bool isEncoder,
123                                    /* in */  bool isSecured,
124                                    /* in */  ResolutionType resolution,
125                                    /* in */  uint frameRate);
126
127    /* Remove codec in the pool.*/
128    ArbitratorErrorType RemoveResource(CodecType codecType,
129                                       bool isEncoder,
130                                       bool isSecured,
131                                       ResolutionType resolution,
132                                       uint frameRate);
133
134    uint GetLivingCodecsNum(void);
135
136    // XML function
137    void ParseXMLFile(FILE* fp);
138    static void startElement(void *userData, const char *name, const char **atts);
139    static void endElement(void *userData, const char *name);
140    void getConfigData(const char *name, const char **atts);
141
142private:
143    // a global table stores all codec limit info
144    Vector<CodecLimitInfo> mDecoderLimitInfos;
145    Vector<CodecLimitInfo> mEncoderLimitInfos;
146
147    // a global talbe stores all living codec info
148    LivingDecodersTable mLivingDecodersTable;
149    LivingEncodersTable mLivingEncodersTable;
150
151    // arbitrator lock
152    pthread_mutex_t mArbitratorLock;
153
154    // indicate whether it is under full load status
155    bool mIsEncoderUnderFullLoad;
156    bool mIsDecoderUnderFullLoad;
157
158    KeyedVector <const char*, CodecType> mCodecNameTypeMap;
159    KeyedVector <const char*, ResolutionType> mResolutionNameTypeMap;
160
161    static const int mBufSize = MAX_BUFFER_SIZE;
162    // indicate XML parser is parsing a codec tag
163    bool mIfParsingCodec;
164    CodecLimitInfo mParsingCodecLimitInfo;
165
166    ArbitratorErrorType ArbitrateFullLoad(CodecInfo& codec);
167
168    bool CheckCodecMatched(const CodecInfo& sourceCodec,
169                           const CodecInfo& targetCodec);
170
171    void SetupDefaultCodecLimitation(void);
172    void InitializeCodecNameTypeMap();
173    void InitializeResolutionNameTypeMap();
174    void DumpCodecTypeFromVector(void);
175    CodecType MapCodecTypeFromName(const char* name);
176    ResolutionType MapResolutionTypeFromName(const char* name);
177};
178
179#endif /* MEDIA_RESOURCE_ARBITRATOR_H_ */
180